bool SMessageCoder::encode( const char *inbuf, size_t insize, char *outbuf, size_t *outsize ) { // encode will append 1 byte delimiter if (*outsize < insize + 1) { return false; } size_t outidx = 0; for (size_t i = 0; i < insize; ++i) { int escape = !!needEscape(inbuf[i]); // escape will cost 1 more extra byte // outsize will minus 1 for delimiter // if out buffer is not big enough // insize * 2 is a good option if (outidx + escape >= *outsize - 1) { return false; } if (escape) { outbuf[outidx++] = m_escaper; } outbuf[outidx++] = inbuf[i]; } outbuf[outidx++] = m_delimiter; *outsize = outidx; return true; }
/* COMMAND "escape": this function applies the URI escaping rules defined in * section 2 of [RFC 3986] to the string supplied as 's'. * The effect of the function is to escape a set of identified characters in * the string. Each such character is replaced in the string by an escape * sequence, which is formed by encoding the character as a sequence of octets * in UTF-8, and then reprensenting each of these octets in the form %HH. * * All characters are escaped other than: * [a-z], [A-Z], [0-9], "#", "-", "_", ".", "!", "~", "*", "'", "(", ")" * * This function must always generate hexadecimal values using the upper-case * letters A-F. * * SIGNATURE: escape(str) : str; */ str escape_str(str *retval, str s) { int x, y; str res; if (!s) throw(ILLARG, "url.escape", "url missing"); if (!( res = (str) GDKmalloc( strlen(s) * 3 ) )) throw(MAL, "url.escape", "malloc failed"); for (x = 0, y = 0; s[x]; ++x, ++y) { if (needEscape(s[x])) { if (s[x] == ' ') { res[y] = '+'; } else { sprintf(res+y, "%%%2x", s[x]); y += 2; } } else { res[y] = s[x]; } } res[y] = '\0'; *retval = GDKrealloc(res, strlen(res)+1); return MAL_SUCCEED; }