Author: mturk Date: Sat Dec 12 07:54:15 2009 New Revision: 889894 URL: http://svn.apache.org/viewvc?rev=889894&view=rev Log: Add wide version of sbuf
Modified: commons/sandbox/runtime/trunk/src/main/native/include/acr_sbuf.h commons/sandbox/runtime/trunk/src/main/native/shared/sbuf.c Modified: commons/sandbox/runtime/trunk/src/main/native/include/acr_sbuf.h URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/include/acr_sbuf.h?rev=889894&r1=889893&r2=889894&view=diff ============================================================================== --- commons/sandbox/runtime/trunk/src/main/native/include/acr_sbuf.h (original) +++ commons/sandbox/runtime/trunk/src/main/native/include/acr_sbuf.h Sat Dec 12 07:54:15 2009 @@ -72,6 +72,15 @@ int s_flags; /* flags */ }; +typedef struct acr_wbuf_t acr_wbuf_t; + +struct acr_wbuf_t { + wchar_t *s_buf; /* storage buffer */ + size_t s_size; /* size of storage buffer */ + size_t s_len; /* current length of string */ + int s_flags; /* flags */ +}; + /** * Sbuf API functions */ @@ -87,6 +96,7 @@ int acr_sbuf_printf(acr_sbuf_t *, const char *, ...); int acr_sbuf_vprintf(acr_sbuf_t *, const char *, va_list); int acr_sbuf_putc(acr_sbuf_t *, int); +int acr_sbuf_putb(acr_sbuf_t *, int); int acr_sbuf_rtrim(acr_sbuf_t *); char *acr_sbuf_ltrim(acr_sbuf_t *); char *acr_sbuf_trim(acr_sbuf_t *); @@ -97,6 +107,27 @@ int acr_sbuf_done(acr_sbuf_t *); void acr_sbuf_delete(acr_sbuf_t *); +acr_wbuf_t *acr_wbuf_new(acr_wbuf_t *, wchar_t *, size_t, int); +#define acr_wbuf_new_auto() \ + acr_wbuf_new(NULL, NULL, 0, ACR_SBUF_AUTOEXTEND) +void acr_wbuf_clear(acr_wbuf_t *); +int acr_wbuf_setpos(acr_wbuf_t *, size_t); +int acr_wbuf_bcat(acr_wbuf_t *, const void *, size_t); +int acr_wbuf_bcpy(acr_wbuf_t *, const void *, size_t); +int acr_wbuf_cat(acr_wbuf_t *, const wchar_t *); +int acr_wbuf_cpy(acr_wbuf_t *, const wchar_t *); +int acr_wbuf_putc(acr_wbuf_t *, int); +int acr_wbuf_putb(acr_wbuf_t *, int); +int acr_wbuf_rtrim(acr_wbuf_t *); +wchar_t *acr_wbuf_ltrim(acr_wbuf_t *); +wchar_t *acr_wbuf_trim(acr_wbuf_t *); +int acr_wbuf_overflowed(acr_wbuf_t *); +void acr_wbuf_finish(acr_wbuf_t *); +wchar_t *acr_wbuf_data(acr_wbuf_t *); +size_t acr_wbuf_len(acr_wbuf_t *); +int acr_wbuf_done(acr_wbuf_t *); +void acr_wbuf_delete(acr_wbuf_t *); + #ifdef __cplusplus } #endif Modified: commons/sandbox/runtime/trunk/src/main/native/shared/sbuf.c URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/shared/sbuf.c?rev=889894&r1=889893&r2=889894&view=diff ============================================================================== --- commons/sandbox/runtime/trunk/src/main/native/shared/sbuf.c (original) +++ commons/sandbox/runtime/trunk/src/main/native/shared/sbuf.c Sat Dec 12 07:54:15 2009 @@ -344,6 +344,23 @@ } /* + * Append a character to an sbuf allowing NUL. + */ +int +acr_sbuf_putb(acr_sbuf_t *s, int c) +{ + + if (SBUF_HASOVERFLOWED(s)) + return -1; + if (!SBUF_HASROOM(s) && acr_sbuf_extend(s, 1) < 0) { + SBUF_SETFLAG(s, ACR_SBUF_OVERFLOWED); + return -1; + } + s->s_buf[s->s_len++] = (char)(c & 0xFF); + return 0; +} + +/* * Trim whitespace characters from end of an sbuf. */ int @@ -470,3 +487,345 @@ { return SBUF_ISFINISHED(s); } + +/* Wide char version of sbuf + */ + +/* + * Extend an sbuf. + */ +static int +acr_wbuf_extend(acr_wbuf_t *s, size_t addlen) +{ + wchar_t *newbuf; + size_t newsize; + + if (!SBUF_CANEXTEND(s)) + return -1; + + newsize = acr_sbuf_extendsize(s->s_size + addlen); + newbuf = x_malloc(newsize * sizeof(wchar_t)); + if (newbuf == NULL) + return -1; + memcpy(newbuf, s->s_buf, s->s_size * sizeof(wchar_t)); + if (SBUF_ISDYNAMIC(s)) + x_free(s->s_buf); + else + SBUF_SETFLAG(s, ACR_SBUF_DYNAMIC); + s->s_buf = newbuf; + s->s_size = newsize; + + return 0; +} + +/* + * Initialize an sbuf. + * If buf is non-NULL, it points to a static or already-allocated string + * big enough to hold at least length characters. + */ +acr_wbuf_t * +acr_wbuf_new(acr_wbuf_t *s, wchar_t *buf, size_t length, int flags) +{ + + if ((flags & ~ACR_SBUF_USRFLAGMSK)) { + ACR_SET_OS_ERROR(ACR_EINVAL); + return NULL; + } + flags &= ACR_SBUF_USRFLAGMSK; + if (s == NULL) { + s = s_calloc(acr_wbuf_t, 1); + if (s == NULL) + return NULL; + s->s_flags = flags; + SBUF_SETFLAG(s, ACR_SBUF_DYNSTRUCT); + } else { + memset(s, 0, sizeof(acr_wbuf_t)); + s->s_flags = flags; + } + s->s_size = length; + if (buf) { + s->s_buf = buf; + return s; + } + if (flags & ACR_SBUF_AUTOEXTEND) + s->s_size = acr_sbuf_extendsize(s->s_size); + s->s_buf = x_malloc(s->s_size * sizeof(wchar_t)); + if (s->s_buf == NULL) { + if (SBUF_ISDYNSTRUCT(s)) + x_free(s); + return NULL; + } + SBUF_SETFLAG(s, ACR_SBUF_DYNAMIC); + return s; +} + +/* + * Clear an sbuf and reset its position. + */ +void +acr_wbuf_clear(acr_wbuf_t *s) +{ + + /* don't care if it's finished or not */ + + SBUF_CLRFLAG(s, ACR_SBUF_FINISHED); + SBUF_CLRFLAG(s, ACR_SBUF_OVERFLOWED); + s->s_len = 0; +} + +/* + * Set the sbuf's end position to an arbitrary value. + * Effectively truncates the sbuf at the new position. + */ +int +acr_wbuf_setpos(acr_wbuf_t *s, size_t pos) +{ + + if (pos >= s->s_size) { + ACR_SET_OS_ERROR(ACR_EINVAL); + return -1; + } + if (pos > s->s_len) + return -1; + s->s_len = pos; + return 0; +} + +/* + * Append a byte string to an sbuf. + */ +int +acr_wbuf_bcat(acr_wbuf_t *s, const void *buf, size_t len) +{ + const wchar_t *str = (const wchar_t *)buf; + + if (SBUF_HASOVERFLOWED(s)) + return -1; + for (; len; len--) { + if (!SBUF_HASROOM(s) && acr_wbuf_extend(s, len) < 0) + break; + s->s_buf[s->s_len++] = *str++; + } + if (len) { + SBUF_SETFLAG(s, ACR_SBUF_OVERFLOWED); + return -1; + } + return 0; +} + +/* + * Copy a byte string into an sbuf. + */ +int +acr_wbuf_bcpy(acr_wbuf_t *s, const void *buf, size_t len) +{ + + acr_wbuf_clear(s); + return acr_wbuf_bcat(s, buf, len); +} + +/* + * Append a string to an sbuf. + */ +int +acr_wbuf_cat(acr_wbuf_t *s, const wchar_t *str) +{ + + if (SBUF_HASOVERFLOWED(s)) + return -1; + if (!str || !*str) { + /* Nothing to do. + * Empty strings cannot be added. + * We use finish() for that + */ + return 0; + } + while (*str) { + if (!SBUF_HASROOM(s) && acr_wbuf_extend(s, wcslen(str)) < 0) + break; + s->s_buf[s->s_len++] = *str++; + } + if (*str) { + SBUF_SETFLAG(s, ACR_SBUF_OVERFLOWED); + return -1; + } + return 0; +} + +/* + * Copy a string into an sbuf. + */ +int +acr_wbuf_cpy(acr_wbuf_t *s, const wchar_t *str) +{ + + acr_wbuf_clear(s); + return acr_wbuf_cat(s, str); +} + +/* + * Append a character to an sbuf. + */ +int +acr_wbuf_putc(acr_wbuf_t *s, int c) +{ + + if (SBUF_HASOVERFLOWED(s)) + return -1; + if (c == 0) { + /* Nothing to add */ + return 0; + } + if (!SBUF_HASROOM(s) && acr_wbuf_extend(s, 1) < 0) { + SBUF_SETFLAG(s, ACR_SBUF_OVERFLOWED); + return -1; + } + s->s_buf[s->s_len++] = (wchar_t)c; + return 0; +} + +/* + * Append a character to an sbuf allowing NUL. + */ +int +acr_wbuf_putb(acr_wbuf_t *s, int c) +{ + + if (SBUF_HASOVERFLOWED(s)) + return -1; + if (!SBUF_HASROOM(s) && acr_wbuf_extend(s, 1) < 0) { + SBUF_SETFLAG(s, ACR_SBUF_OVERFLOWED); + return -1; + } + s->s_buf[s->s_len++] = (wchar_t)c; + return 0; +} + +/* + * Trim whitespace characters from end of an sbuf. + */ +int +acr_wbuf_rtrim(acr_wbuf_t *s) +{ + + if (SBUF_HASOVERFLOWED(s)) + return -1; + + while (s->s_len && iswspace(s->s_buf[s->s_len-1])) + --s->s_len; + + return 0; +} + +/* + * Return pointer to the first non white space character + * in sbuf. The acr_sbuf_finish must be called before this + * function + */ +wchar_t * +acr_wbuf_ltrim(acr_wbuf_t *s) +{ + + wchar_t *p = s->s_buf; + + if (SBUF_HASOVERFLOWED(s)) + return NULL; + if (!SBUF_ISFINISHED(s)) + return p; + while (*p && iswspace(*p)) + p++; + + return p; +} + +/* + * Trim the sbuf. + */ +wchar_t * +acr_wbuf_trim(acr_wbuf_t *s) +{ + + wchar_t *p = s->s_buf; + + acr_wbuf_rtrim(s); + acr_wbuf_finish(s); + + while (*p && iswspace(*p)) + p++; + + return p; +} + +/* + * Check if an sbuf overflowed + */ +int +acr_wbuf_overflowed(acr_wbuf_t *s) +{ + + return SBUF_HASOVERFLOWED(s); +} + +/* + * Finish off an sbuf. + */ +void +acr_wbuf_finish(acr_wbuf_t *s) +{ + + s->s_buf[s->s_len] = L'\0'; + + SBUF_CLRFLAG(s, ACR_SBUF_OVERFLOWED); + SBUF_SETFLAG(s, ACR_SBUF_FINISHED); +} + +/* + * Return a pointer to the sbuf data. + */ +wchar_t * +acr_wbuf_data(acr_wbuf_t *s) +{ + + return s->s_buf; +} + +/* + * Return the length of the sbuf data. + */ +size_t +acr_wbuf_len(acr_wbuf_t *s) +{ + + /* don't care if it's finished or not */ + if (SBUF_HASOVERFLOWED(s)) + return 0; + return s->s_len; +} + +/* + * Clear an sbuf, free its buffer if necessary. + */ +void +acr_wbuf_delete(acr_wbuf_t *s) +{ + int isdyn; + + /* don't care if it's finished or not */ + if (SBUF_ISDYNAMIC(s)) + x_free(s->s_buf); + isdyn = SBUF_ISDYNSTRUCT(s); + if (isdyn) + x_free(s); + else + memset(s, 0, sizeof(*s)); +} + +/* + * Check if an sbuf has been finished. + */ +int +acr_wbuf_done(acr_wbuf_t *s) +{ + return SBUF_ISFINISHED(s); +} +