diff --git a/ChangeLog b/ChangeLog index 76d8811262..83612fdca8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +Mon Dec 17 10:01:00 UTC 2007 Richard W.M. Jones + + Add extra utility functions to buf.c + * src/buf.c, src/buf.h: Added utility functions + virBufferURIEncodeString and virBufferAddChar to the + buffer module. + Sat Dec 15 12:12:14 EST 2007 Daniel P. Berrange * src/libvirt.c: Return error code if passed unsupported diff --git a/src/buf.c b/src/buf.c index e26f1d539c..5f580277c9 100644 --- a/src/buf.c +++ b/src/buf.c @@ -16,6 +16,8 @@ #include #include #include +#include + #include "buf.h" /** @@ -49,7 +51,7 @@ virBufferGrow(virBufferPtr buf, unsigned int len) /** * virBufferAdd: - * @buf: the buffer to dump + * @buf: the buffer to add to * @str: the string * @len: the number of bytes to add * @@ -78,13 +80,41 @@ virBufferAdd(virBufferPtr buf, const char *str, int len) return (-1); } } - /* XXX: memmove() is 2x slower than memcpy(), do we really need it? */ - memmove(&buf->content[buf->use], str, len); + + memcpy (&buf->content[buf->use], str, len); buf->use += len; buf->content[buf->use] = 0; return (0); } +/** + * virBufferAddChar: + * @buf: the buffer to add to + * @c: the character to add + * + * Add a single character 'c' to a buffer. + * + * Returns 0 if successful, -1 in the case of error. + */ +int +virBufferAddChar (virBufferPtr buf, char c) +{ + unsigned int needSize; + + if (buf == NULL) + return -1; + + needSize = buf->use + 2; + if (needSize > buf->size) + if (!virBufferGrow (buf, needSize - buf->use)) + return -1; + + buf->content[buf->use++] = c; + buf->content[buf->use] = 0; + + return 0; +} + /** * virBufferNew: * @size: creation size in bytes @@ -266,6 +296,56 @@ virBufferEscapeString(virBufferPtr buf, const char *format, const char *str) return (0); } +/** + * virBufferURIEncodeString: + * @buf: the buffer to append to + * @str: the string argument which will be URI-encoded + * + * Append the string to the buffer. The string will be URI-encoded + * during the append (ie any non alpha-numeric characters are replaced + * with '%xx' hex sequences). + * + * Returns 0 successful, -1 in case of internal or API error. + */ +int +virBufferURIEncodeString (virBufferPtr buf, const char *str) +{ + int grow_size = 0; + const char *p; + unsigned char uc; + const char *hex = "0123456789abcdef"; + + for (p = str; *p; ++p) { + /* This may not work on EBCDIC. */ + if ((*p >= 'a' && *p <= 'z') || + (*p >= 'A' && *p <= 'Z') || + (*p >= '0' && *p <= '9')) + grow_size++; + else + grow_size += 3; /* %ab */ + } + + if (virBufferGrow (buf, grow_size) == -1) + return -1; + + for (p = str; *p; ++p) { + /* This may not work on EBCDIC. */ + if ((*p >= 'a' && *p <= 'z') || + (*p >= 'A' && *p <= 'Z') || + (*p >= '0' && *p <= '9')) + buf->content[buf->use++] = *p; + else { + uc = (unsigned char) *p; + buf->content[buf->use++] = '%'; + buf->content[buf->use++] = hex[uc >> 4]; + buf->content[buf->use++] = hex[uc & 0xf]; + } + } + + buf->content[buf->use] = '\0'; + return 0; +} + /** * virBufferStrcat: * @buf: the buffer to dump diff --git a/src/buf.h b/src/buf.h index d4c201a84a..8826617fe6 100644 --- a/src/buf.h +++ b/src/buf.h @@ -30,9 +30,11 @@ virBufferPtr virBufferNew(unsigned int size); void virBufferFree(virBufferPtr buf); char *virBufferContentAndFree(virBufferPtr buf); int virBufferAdd(virBufferPtr buf, const char *str, int len); +int virBufferAddChar(virBufferPtr buf, char c); int virBufferVSprintf(virBufferPtr buf, const char *format, ...) ATTRIBUTE_FORMAT(printf, 2, 3); int virBufferStrcat(virBufferPtr buf, ...); int virBufferEscapeString(virBufferPtr buf, const char *format, const char *str); +int virBufferURIEncodeString (virBufferPtr buf, const char *str); #endif /* __VIR_BUFFER_H__ */