Thu Apr 28 2011 17:16:22

Asterisk developer's documentation


strings.c File Reference

String manipulation API. More...

#include "asterisk.h"
#include "asterisk/strings.h"
#include "asterisk/pbx.h"
Include dependency graph for strings.c:

Go to the source code of this file.

Functions

int __ast_str_helper (struct ast_str **buf, ssize_t max_len, int append, const char *fmt, va_list ap)
 Core functionality of ast_str_(set|append)_va.
char * __ast_str_helper2 (struct ast_str **buf, ssize_t maxlen, const char *src, size_t maxsrc, int append, int escapecommas)
void ast_str_substitute_variables (struct ast_str **buf, size_t maxlen, struct ast_channel *chan, const char *template)

Detailed Description

String manipulation API.

Author:
Tilghman Lesher <tilghman@digium.com>

Definition in file strings.c.


Function Documentation

int __ast_str_helper ( struct ast_str **  buf,
ssize_t  max_len,
int  append,
const char *  fmt,
va_list  ap 
)

Core functionality of ast_str_(set|append)_va.

core handler for dynamic strings. This is not meant to be called directly, but rather through the various wrapper macros ast_str_set(...) ast_str_append(...) ast_str_set_va(...) ast_str_append_va(...)

Definition at line 55 of file strings.c.

References AST_DYNSTR_BUILD_FAILED, ast_str_make_space(), ast_verbose(), and len().

Referenced by ast_str_set_va().

{
   int res, need;
   int offset = (append && (*buf)->__AST_STR_LEN) ? (*buf)->__AST_STR_USED : 0;
   va_list aq;

   do {
      if (max_len < 0) {
         max_len = (*buf)->__AST_STR_LEN; /* don't exceed the allocated space */
      }
      /*
       * Ask vsnprintf how much space we need. Remember that vsnprintf
       * does not count the final <code>'\0'</code> so we must add 1.
       */
      va_copy(aq, ap);
      res = vsnprintf((*buf)->__AST_STR_STR + offset, (*buf)->__AST_STR_LEN - offset, fmt, aq);

      need = res + offset + 1;
      /*
       * If there is not enough space and we are below the max length,
       * reallocate the buffer and return a message telling to retry.
       */
      if (need > (*buf)->__AST_STR_LEN && (max_len == 0 || (*buf)->__AST_STR_LEN < max_len) ) {
         int len = (int)(*buf)->__AST_STR_LEN;
         if (max_len && max_len < need) { /* truncate as needed */
            need = max_len;
         } else if (max_len == 0) { /* if unbounded, give more room for next time */
            need += 16 + need / 4;
         }
         if (0) { /* debugging */
            ast_verbose("extend from %d to %d\n", len, need);
         }
         if (
#if (defined(MALLOC_DEBUG) && !defined(STANDALONE))
               _ast_str_make_space(buf, need, file, lineno, function)
#else
               ast_str_make_space(buf, need)
#endif
            ) {
            ast_verbose("failed to extend from %d to %d\n", len, need);
            va_end(aq);
            return AST_DYNSTR_BUILD_FAILED;
         }
         (*buf)->__AST_STR_STR[offset] = '\0';  /* Truncate the partial write. */

         /* Restart va_copy before calling vsnprintf() again. */
         va_end(aq);
         continue;
      }
      va_end(aq);
      break;
   } while (1);
   /* update space used, keep in mind the truncation */
   (*buf)->__AST_STR_USED = (res + offset > (*buf)->__AST_STR_LEN) ? (*buf)->__AST_STR_LEN - 1 : res + offset;

   return res;
}
char* __ast_str_helper2 ( struct ast_str **  buf,
ssize_t  maxlen,
const char *  src,
size_t  maxsrc,
int  append,
int  escapecommas 
)

Definition at line 126 of file strings.c.

References ast_str::__AST_STR_LEN, and ast_str_make_space().

Referenced by ast_str_append_substr(), ast_str_append_va(), ast_str_set_escapecommas(), and ast_str_set_substr().

{
   int dynamic = 0;
   char *ptr = append ? &((*buf)->__AST_STR_STR[(*buf)->__AST_STR_USED]) : (*buf)->__AST_STR_STR;

   if (maxlen < 1) {
      if (maxlen == 0) {
         dynamic = 1;
      }
      maxlen = (*buf)->__AST_STR_LEN;
   }

   while (*src && maxsrc && maxlen && (!escapecommas || (maxlen - 1))) {
      if (escapecommas && (*src == '\\' || *src == ',')) {
         *ptr++ = '\\';
         maxlen--;
         (*buf)->__AST_STR_USED++;
      }
      *ptr++ = *src++;
      maxsrc--;
      maxlen--;
      (*buf)->__AST_STR_USED++;

      if ((ptr >= (*buf)->__AST_STR_STR + (*buf)->__AST_STR_LEN - 3) ||
         (dynamic && (!maxlen || (escapecommas && !(maxlen - 1))))) {
         char *oldbase = (*buf)->__AST_STR_STR;
         size_t old = (*buf)->__AST_STR_LEN;
         if (ast_str_make_space(buf, (*buf)->__AST_STR_LEN * 2)) {
            /* If the buffer can't be extended, end it. */
            break;
         }
         /* What we extended the buffer by */
         maxlen = old;

         ptr += (*buf)->__AST_STR_STR - oldbase;
      }
   }
   if (__builtin_expect(!maxlen, 0)) {
      ptr--;
   }
   *ptr = '\0';
   return (*buf)->__AST_STR_STR;
}
void ast_str_substitute_variables ( struct ast_str **  buf,
size_t  maxlen,
struct ast_channel chan,
const char *  template 
)

Definition at line 115 of file strings.c.

References ast_str_make_space(), first, and pbx_substitute_variables_helper_full().

Referenced by acf_odbc_read(), acf_odbc_write(), cli_odbc_read(), and cli_odbc_write().

{
   int first = 1;
   do {
      ast_str_make_space(buf, maxlen ? maxlen :
         (first ? strlen(template) * 2 : (*buf)->__AST_STR_LEN * 2));
      pbx_substitute_variables_helper_full(chan, NULL, template, (*buf)->__AST_STR_STR, (*buf)->__AST_STR_LEN - 1, &((*buf)->__AST_STR_USED));
      first = 0;
   } while (maxlen == 0 && (*buf)->__AST_STR_LEN - 5 < (*buf)->__AST_STR_USED);
}