/libzdb-2.8.1/src/util/StringBuffer.c
# · C · 197 lines · 130 code · 44 blank · 23 comment · 25 complexity · 3f4a209fb9ee58ef38550a62af54b26d MD5 · raw file
- /*
- * Copyright (C) 2004-2011 Tildeslash Ltd. All rights reserved.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- #include "Config.h"
- #include <stdio.h>
- #include <string.h>
- #include <ctype.h>
- #include "StringBuffer.h"
- /**
- * Implementation of the StringBuffer interface.
- *
- * @file
- */
- /* ----------------------------------------------------------- Definitions */
- #define T StringBuffer_T
- struct T {
- int used;
- int length;
- uchar_t *buffer;
- };
- /* ------------------------------------------------------- Private methods */
- static inline void doAppend(T S, const char *s, va_list ap) {
- va_list ap_copy;
- while (true) {
- va_copy(ap_copy, ap);
- int n = vsnprintf(S->buffer + S->used, S->length - S->used, s, ap_copy);
- va_end(ap_copy);
- if (n > -1 && (S->used + n) < S->length) {
- S->used += n;
- break;
- }
- if (n > -1)
- S->length += STRLEN + n;
- else
- S->length *= 2;
- RESIZE(S->buffer, S->length + 1);
- }
- }
- /* Replace all occurences of ? in this string buffer with prefix[0..99] */
- static int StringBuffer_prepareSQL(T S, char prefix) {
- int n, i;
- for (n = i = 0; S->buffer[i]; i++) if (S->buffer[i] == '?') n++;
- if (n > 99)
- THROW(SQLException, "Max 99 parameters are allowed in a prepared statement. Found %d parameters in statement", n);
- else if (n) {
- int j, xl;
- char x[3] = {prefix};
- int required = (n * 2) + S->used;
- if (required >= S->length) {
- S->length = required;
- RESIZE(S->buffer, S->length);
- }
- for (i = 0, j = 1; (j <= n); i++) {
- if (S->buffer[i] == '?') {
- if(j<10){xl=2;x[1]=j+'0';}else{xl=3;x[1]=(j/10)+'0';x[2]=(j%10)+'0';}
- memmove(S->buffer + i + xl, S->buffer + i + 1, (S->used - (i + 1)));
- memmove(S->buffer + i, x, xl);
- S->used += xl - 1;
- j++;
- }
- }
- S->buffer[S->used] = 0;
- }
- return n;
- }
- /* ----------------------------------------------------- Protected methods */
- #ifdef PACKAGE_PROTECTED
- #pragma GCC visibility push(hidden)
- #endif
- T StringBuffer_new(const char *s) {
- T S;
- NEW(S);
- S->used = 0;
- S->length = STRLEN;
- S->buffer = ALLOC(STRLEN + 1);
- return StringBuffer_append(S, "%s", s);
- }
- T StringBuffer_create(int hint) {
- T S;
- if (hint <= 0)
- THROW(AssertException, "Illegal hint value");
- NEW(S);
- S->used = 0;
- S->length = hint;
- S->buffer = ALLOC(hint + 1);
- *S->buffer = 0;
- return S;
- }
- void StringBuffer_free(T *S) {
- assert(S && *S);
- FREE((*S)->buffer);
- FREE(*S);
- }
- T StringBuffer_append(T S, const char *s, ...) {
- assert(S);
- if (s && *s) {
- va_list ap;
- va_start(ap, s);
- doAppend(S, s, ap);
- va_end(ap);
- }
- return S;
- }
- T StringBuffer_vappend(T S, const char *s, va_list ap) {
- assert(S);
- if (s && *s) {
- va_list ap_copy;
- va_copy(ap_copy, ap);
- doAppend(S, s, ap_copy);
- va_end(ap_copy);
- }
- return S;
- }
- int StringBuffer_length(T S) {
- assert(S);
- return S->used;
- }
- void StringBuffer_clear(T S) {
- assert(S);
- S->used = 0;
- *S->buffer = 0;
- }
- const char *StringBuffer_toString(T S) {
- assert(S);
- return S->buffer;
- }
- int StringBuffer_prepare4postgres(T S) {
- assert(S);
- return StringBuffer_prepareSQL(S, '$');
- }
- int StringBuffer_prepare4oracle(T S) {
- assert(S);
- return StringBuffer_prepareSQL(S, ':');
- }
- void StringBuffer_removeTrailingSemicolon(T S) {
- assert(S);
- while (S->used && ((S->buffer[S->used - 1] == ';') || isspace(S->buffer[S->used - 1])))
- S->buffer[--S->used] = 0;
- }
- #ifdef PACKAGE_PROTECTED
- #pragma GCC visibility pop
- #endif