Eliminate open coding of ast_str
authorTilghman Lesher <tilghman@meg.abyt.es>
Sun, 24 Aug 2008 16:23:15 +0000 (16:23 +0000)
committerTilghman Lesher <tilghman@meg.abyt.es>
Sun, 24 Aug 2008 16:23:15 +0000 (16:23 +0000)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@139704 65c4cc65-6c06-0410-ace0-fbb531ad65f3

cdr/cdr_pgsql.c

index 3f518cc..df929ce 100644 (file)
@@ -76,11 +76,8 @@ static AST_RWLIST_HEAD_STATIC(psql_columns, columns);
 #define LENGTHEN_BUF1(size)                                                                                                            \
                        do {                                                                                                                            \
                                /* Lengthen buffer, if necessary */                                                             \
-                               if ((newsize = lensql + (size) + 3) > sizesql) {        \
-                                       if ((tmp = ast_realloc(sql, (newsize / 512 + 1) * 512))) {      \
-                                               sql = tmp;                                                                                              \
-                                               sizesql = (newsize / 512 + 1) * 512;                                    \
-                                       } else {                                                                                                        \
+                               if (sql->used + size + 1 > sql->len) {  \
+                                       if (ast_str_make_space(&sql, ((sql->len + size + 1) / 512 + 1) * 512) != 0) {   \
                                                ast_log(LOG_ERROR, "Unable to allocate sufficient memory.  Insert CDR failed.\n"); \
                                                ast_free(sql);                                                                                  \
                                                ast_free(sql2);                                                                                 \
@@ -92,11 +89,8 @@ static AST_RWLIST_HEAD_STATIC(psql_columns, columns);
 
 #define LENGTHEN_BUF2(size)                                                                                                            \
                        do {                                                                                                                            \
-                               if ((newsize = lensql2 + (size) + 3) > sizesql2) {                              \
-                                       if ((tmp = ast_realloc(sql2, (newsize / 512 + 1) * 512))) {     \
-                                               sql2 = tmp;                                                                                             \
-                                               sizesql2 = (newsize / 512 + 1) * 512;                                   \
-                                       } else {                                                                                                        \
+                               if (sql2->used + size + 1 > sql2->len) {                                \
+                                       if (ast_str_make_space(&sql2, ((sql2->len + size + 3) / 512 + 1) * 512) != 0) { \
                                                ast_log(LOG_ERROR, "Unable to allocate sufficient memory.  Insert CDR failed.\n");      \
                                                ast_free(sql);                                                                                  \
                                                ast_free(sql2);                                                                                 \
@@ -129,12 +123,21 @@ static int pgsql_log(struct ast_cdr *cdr)
 
        if (connected) {
                struct columns *cur;
-               int lensql, lensql2, sizesql = maxsize, sizesql2 = maxsize2, newsize;
-               char *sql = ast_calloc(sizeof(char), sizesql), *sql2 = ast_calloc(sizeof(char), sizesql2), *tmp, *value;
-               char buf[257], escapebuf[513];
+               struct ast_str *sql = ast_str_create(maxsize), *sql2 = ast_str_create(maxsize2);
+               char buf[257], escapebuf[513], *value;
   
-               lensql = snprintf(sql, sizesql, "INSERT INTO %s (", table);
-               lensql2 = snprintf(sql2, sizesql2, " VALUES (");
+               if (!sql || !sql2) {
+                       if (sql) {
+                               ast_free(sql);
+                       }
+                       if (sql2) {
+                               ast_free(sql2);
+                       }
+                       return -1;
+               }
+
+               ast_str_set(&sql, 0, "INSERT INTO %s (", table);
+               ast_str_set(&sql2, 0, " VALUES (");
   
                AST_RWLIST_RDLOCK(&psql_columns);
                AST_RWLIST_TRAVERSE(&psql_columns, cur, list) {
@@ -147,83 +150,85 @@ static int pgsql_log(struct ast_cdr *cdr)
                                if (cur->notnull && !cur->hasdefault) {
                                        /* Field is NOT NULL (but no default), must include it anyway */
                                        LENGTHEN_BUF1(strlen(cur->name) + 2);
-                                       lensql += snprintf(sql + lensql, sizesql - lensql, "\"%s\",", cur->name);
+                                       ast_str_append(&sql, 0, "\"%s\",", cur->name);
                                        LENGTHEN_BUF2(3);
-                                       strcat(sql2, "'',");
-                                       lensql2 += 3;
+                                       ast_str_append(&sql2, 0, "'',");
                                }
                                continue;
                        }
                        
                        LENGTHEN_BUF1(strlen(cur->name) + 2);
-                       lensql += snprintf(sql + lensql, sizesql - lensql, "\"%s\",", cur->name);
+                       ast_str_append(&sql, 0, "\"%s\",", cur->name);
 
                        if (strcmp(cur->name, "start") == 0 || strcmp(cur->name, "calldate") == 0) {
                                if (strncmp(cur->type, "int", 3) == 0) {
                                        LENGTHEN_BUF2(12);
-                                       lensql2 += snprintf(sql2 + lensql2, sizesql2 - lensql2, "%ld", cdr->start.tv_sec);
+                                       ast_str_append(&sql2, 0, "%ld", cdr->start.tv_sec);
                                } else if (strncmp(cur->type, "float", 5) == 0) {
                                        LENGTHEN_BUF2(30);
-                                       lensql2 += snprintf(sql2 + lensql2, sizesql2 - lensql2, "%f", (double)cdr->start.tv_sec + (double)cdr->start.tv_usec / 1000000.0);
+                                       ast_str_append(&sql2, 0, "%f", (double)cdr->start.tv_sec + (double)cdr->start.tv_usec / 1000000.0);
                                } else {
                                        /* char, hopefully */
                                        LENGTHEN_BUF2(30);
                                        ast_localtime(&cdr->start, &tm, NULL);
-                                       lensql2 += ast_strftime(sql2 + lensql2, sizesql2 - lensql2, DATE_FORMAT, &tm);
+                                       ast_strftime(buf, sizeof(buf), DATE_FORMAT, &tm);
+                                       ast_str_append(&sql2, 0, "%s", buf);
                                }
                        } else if (strcmp(cur->name, "answer") == 0) {
                                if (strncmp(cur->type, "int", 3) == 0) {
                                        LENGTHEN_BUF2(12);
-                                       lensql2 += snprintf(sql2 + lensql2, sizesql2 - lensql2, "%ld", cdr->answer.tv_sec);
+                                       ast_str_append(&sql2, 0, "%ld", cdr->answer.tv_sec);
                                } else if (strncmp(cur->type, "float", 5) == 0) {
                                        LENGTHEN_BUF2(30);
-                                       lensql2 += snprintf(sql2 + lensql2, sizesql2 - lensql2, "%f", (double)cdr->answer.tv_sec + (double)cdr->answer.tv_usec / 1000000.0);
+                                       ast_str_append(&sql2, 0, "%f", (double)cdr->answer.tv_sec + (double)cdr->answer.tv_usec / 1000000.0);
                                } else {
                                        /* char, hopefully */
                                        LENGTHEN_BUF2(30);
                                        ast_localtime(&cdr->start, &tm, NULL);
-                                       lensql2 += ast_strftime(sql2 + lensql2, sizesql2 - lensql2, DATE_FORMAT, &tm);
+                                       ast_strftime(buf, sizeof(buf), DATE_FORMAT, &tm);
+                                       ast_str_append(&sql2, 0, "%s", buf);
                                }
                        } else if (strcmp(cur->name, "end") == 0) {
                                if (strncmp(cur->type, "int", 3) == 0) {
                                        LENGTHEN_BUF2(12);
-                                       lensql2 += snprintf(sql2 + lensql2, sizesql2 - lensql2, "%ld", cdr->end.tv_sec);
+                                       ast_str_append(&sql2, 0, "%ld", cdr->end.tv_sec);
                                } else if (strncmp(cur->type, "float", 5) == 0) {
                                        LENGTHEN_BUF2(30);
-                                       lensql2 += snprintf(sql2 + lensql2, sizesql2 - lensql2, "%f", (double)cdr->end.tv_sec + (double)cdr->end.tv_usec / 1000000.0);
+                                       ast_str_append(&sql2, 0, "%f", (double)cdr->end.tv_sec + (double)cdr->end.tv_usec / 1000000.0);
                                } else {
                                        /* char, hopefully */
                                        LENGTHEN_BUF2(30);
                                        ast_localtime(&cdr->end, &tm, NULL);
-                                       lensql2 += ast_strftime(sql2 + lensql2, sizesql2 - lensql2, DATE_FORMAT, &tm);
+                                       ast_strftime(buf, sizeof(buf), DATE_FORMAT, &tm);
+                                       ast_str_append(&sql2, 0, "%s", buf);
                                }
                        } else if (strcmp(cur->name, "duration") == 0 || strcmp(cur->name, "billsec") == 0) {
                                if (cur->type[0] == 'i') {
                                        /* Get integer, no need to escape anything */
                                        ast_cdr_getvar(cdr, cur->name, &value, buf, sizeof(buf), 0, 0);
                                        LENGTHEN_BUF2(12);
-                                       lensql2 += snprintf(sql2 + lensql2, sizesql2 - lensql2, "%s", value);
+                                       ast_str_append(&sql2, 0, "%s", value);
                                } else if (strncmp(cur->type, "float", 5) == 0) {
                                        struct timeval *when = cur->name[0] == 'd' ? &cdr->start : &cdr->answer;
                                        LENGTHEN_BUF2(30);
-                                       lensql2 += snprintf(sql2 + lensql2, sizesql2 - lensql2, "%f", (double)cdr->end.tv_sec - when->tv_sec + cdr->end.tv_usec / 1000000.0 - when->tv_usec / 1000000.0);
+                                       ast_str_append(&sql2, 0, "%f", (double)cdr->end.tv_sec - when->tv_sec + cdr->end.tv_usec / 1000000.0 - when->tv_usec / 1000000.0);
                                } else {
                                        /* Char field, probably */
                                        struct timeval *when = cur->name[0] == 'd' ? &cdr->start : &cdr->answer;
                                        LENGTHEN_BUF2(30);
-                                       lensql2 += snprintf(sql2 + lensql2, sizesql2 - lensql2, "'%f'", (double)cdr->end.tv_sec - when->tv_sec + cdr->end.tv_usec / 1000000.0 - when->tv_usec / 1000000.0);
+                                       ast_str_append(&sql2, 0, "'%f'", (double)cdr->end.tv_sec - when->tv_sec + cdr->end.tv_usec / 1000000.0 - when->tv_usec / 1000000.0);
                                }
                        } else if (strcmp(cur->name, "disposition") == 0 || strcmp(cur->name, "amaflags") == 0) {
                                if (strncmp(cur->type, "int", 3) == 0) {
                                        /* Integer, no need to escape anything */
                                        ast_cdr_getvar(cdr, cur->name, &value, buf, sizeof(buf), 0, 1);
                                        LENGTHEN_BUF2(12);
-                                       lensql2 += snprintf(sql2 + lensql2, sizesql2 - lensql2, "%s", value);
+                                       ast_str_append(&sql2, 0, "%s", value);
                                } else {
                                        /* Although this is a char field, there are no special characters in the values for these fields */
                                        ast_cdr_getvar(cdr, cur->name, &value, buf, sizeof(buf), 0, 0);
                                        LENGTHEN_BUF2(30);
-                                       lensql2 += snprintf(sql2 + lensql2, sizesql2 - lensql2, "'%s'", value);
+                                       ast_str_append(&sql2, 0, "'%s'", value);
                                }
                        } else {
                                /* Arbitrary field, could be anything */
@@ -232,19 +237,19 @@ static int pgsql_log(struct ast_cdr *cdr)
                                        long long whatever;
                                        if (value && sscanf(value, "%lld", &whatever) == 1) {
                                                LENGTHEN_BUF2(25);
-                                               lensql2 += snprintf(sql2 + lensql2, sizesql2 - lensql2, "%lld", whatever);
+                                               ast_str_append(&sql2, 0, "%lld", whatever);
                                        } else {
                                                LENGTHEN_BUF2(1);
-                                               lensql2 += snprintf(sql2 + lensql2, sizesql2 - lensql2, "0");
+                                               ast_str_append(&sql2, 0, "0");
                                        }
                                } else if (strncmp(cur->type, "float", 5) == 0) {
                                        long double whatever;
                                        if (value && sscanf(value, "%Lf", &whatever) == 1) {
                                                LENGTHEN_BUF2(50);
-                                               lensql2 += snprintf(sql2 + lensql2, sizesql2 - lensql2, "%30Lf", whatever);
+                                               ast_str_append(&sql2, 0, "%30Lf", whatever);
                                        } else {
                                                LENGTHEN_BUF2(1);
-                                               lensql2 += snprintf(sql2 + lensql2, sizesql2 - lensql2, "0");
+                                               ast_str_append(&sql2, 0, "0");
                                        }
                                /* XXX Might want to handle dates, times, and other misc fields here XXX */
                                } else {
@@ -253,19 +258,18 @@ static int pgsql_log(struct ast_cdr *cdr)
                                        else
                                                escapebuf[0] = '\0';
                                        LENGTHEN_BUF2(strlen(escapebuf) + 2);
-                                       lensql2 += snprintf(sql2 + lensql2, sizesql2 - lensql2, "'%s'", escapebuf);
+                                       ast_str_append(&sql2, 0, "'%s'", escapebuf);
                                }
                        }
                        LENGTHEN_BUF2(1);
-                       strcat(sql2 + lensql2, ",");
-                       lensql2++;
+                       ast_str_append(&sql2, 0, ",");
                }
                AST_RWLIST_UNLOCK(&psql_columns);
-               LENGTHEN_BUF1(lensql2);
-               sql[lensql - 1] = ')';
-               sql2[lensql2 - 1] = ')';
-               strcat(sql + lensql, sql2);
-               ast_verb(11, "[%s]\n", sql);
+               LENGTHEN_BUF1(sql2->len);
+               sql->str[sql->len - 1] = ')';
+               sql2->str[sql2->len - 1] = ')';
+               ast_str_append(&sql, 0, "%s", sql2->str);
+               ast_verb(11, "[%s]\n", sql->str);
 
                ast_debug(2, "inserting a CDR record.\n");
 
@@ -291,7 +295,7 @@ static int pgsql_log(struct ast_cdr *cdr)
                                return -1;
                        }
                }
-               result = PQexec(conn, sql);
+               result = PQexec(conn, sql->str);
                if (PQresultStatus(result) != PGRES_COMMAND_OK) {
                        pgerror = PQresultErrorMessage(result);
                        ast_log(LOG_ERROR, "Failed to insert call detail record into database!\n");
@@ -302,7 +306,7 @@ static int pgsql_log(struct ast_cdr *cdr)
                                ast_log(LOG_ERROR, "Connection reestablished.\n");
                                connected = 1;
                                PQclear(result);
-                               result = PQexec(conn, sql);
+                               result = PQexec(conn, sql->str);
                                if (PQresultStatus(result) != PGRES_COMMAND_OK) {
                                        pgerror = PQresultErrorMessage(result);
                                        ast_log(LOG_ERROR, "HARD ERROR!  Attempted reconnection failed.  DROPPING CALL RECORD!\n");
@@ -311,9 +315,13 @@ static int pgsql_log(struct ast_cdr *cdr)
                        }
                        ast_mutex_unlock(&pgsql_lock);
                        PQclear(result);
+                       ast_free(sql);
+                       ast_free(sql2);
                        return -1;
                }
                PQclear(result);
+               ast_free(sql);
+               ast_free(sql2);
        }
        ast_mutex_unlock(&pgsql_lock);
        return 0;