strbuf: add strbuf_add*_urlencode

This just follows the rfc3986 rules for percent-encoding url data into a strbuf. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Jeff King committed Dec 10, 2011 at 05:34 UTC c505116b91d3c92f0c3066cb9806773d2df11088
2 files changed +42
strbuf.c
+37
@@ -397,3 +397,40 @@ int strbuf_read_file(struct strbuf *sb, const char *path, size_t hint)
397
398 return len;
399 }
400 +
401 +static int is_rfc3986_reserved(char ch)
402 +{
403 + switch (ch) {
404 + case '!': case '*': case '\'': case '(': case ')': case ';':
405 + case ':': case '@': case '&': case '=': case '+': case '$':
406 + case ',': case '/': case '?': case '#': case '[': case ']':
407 + return 1;
408 + }
409 + return 0;
410 +}
411 +
412 +static int is_rfc3986_unreserved(char ch)
413 +{
414 + return isalnum(ch) ||
415 + ch == '-' || ch == '_' || ch == '.' || ch == '~';
416 +}
417 +
418 +void strbuf_add_urlencode(struct strbuf *sb, const char *s, size_t len,
419 + int reserved)
420 +{
421 + strbuf_grow(sb, len);
422 + while (len--) {
423 + char ch = *s++;
424 + if (is_rfc3986_unreserved(ch) ||
425 + (!reserved && is_rfc3986_reserved(ch)))
426 + strbuf_addch(sb, ch);
427 + else
428 + strbuf_addf(sb, "%%%02x", ch);
429 + }
430 +}
431 +
432 +void strbuf_addstr_urlencode(struct strbuf *sb, const char *s,
433 + int reserved)
434 +{
435 + strbuf_add_urlencode(sb, s, strlen(s), reserved);
436 +}
strbuf.h
+5
@@ -115,4 +115,9 @@ extern int launch_editor(const char *path, struct strbuf *buffer, const char *co
115 extern int strbuf_branchname(struct strbuf *sb, const char *name);
116 extern int strbuf_check_branch_ref(struct strbuf *sb, const char *name);
117
118 +extern void strbuf_add_urlencode(struct strbuf *, const char *, size_t,
119 + int reserved);
120 +extern void strbuf_addstr_urlencode(struct strbuf *, const char *,
121 + int reserved);
122 +
123 #endif /* STRBUF_H */