Beispiel #1
0
Bool
DynBuf_Append(DynBuf *b,        // IN/OUT:
              void const *data, // IN:
              size_t size)      // IN:
{
    size_t new_size;

    ASSERT(b);

    if (size <= 0) {
        return TRUE;
    }

    ASSERT(data);

    new_size = b->size + size;

    if (new_size < b->size) {  // Prevent integer overflow
        return FALSE;
    }

    if (new_size > b->allocated) {
        /* Not enough room */
        if (DynBuf_Enlarge(b, new_size) == FALSE) {
            return FALSE;
        }
    }

    memcpy(b->data + b->size, data, size);
    b->size = new_size;

    return TRUE;
}
Beispiel #2
0
static DYNXDR_INLINE_T *
DynXdrInline(XDR *xdrs,                 // IN/OUT
             DYNXDR_INLINE_LEN_T len)   // IN
{
   DynXdrData *priv = (DynXdrData *)xdrs->x_private;
   DynBuf *buf = &priv->data;
   DYNXDR_INLINE_T *retAddr;

   ASSERT(len >= 0);
   ASSERT(xdrs->x_op == XDR_ENCODE);

   if (len == 0) {
      return (DYNXDR_INLINE_T *)&buf->data[buf->size];
   }

   if (buf->allocated - buf->size < len) {
      /* DynBuf too small.  Grow it. */
      if (!DynBuf_Enlarge(buf, buf->size + len)) {
         return NULL;
      }
   }

   retAddr = (DYNXDR_INLINE_T *)&buf->data[buf->size];
   buf->size += len;

   return retAddr;
}
Bool
GuestInfo_PerfMon(DynBuf *statBuf)  // IN/OUT: inited, ready to fill
{
   GuestInfoCollector *temp;
   static GuestInfoCollector *current = NULL;
   static GuestInfoCollector *previous = NULL;

   ASSERT(statBuf && DynBuf_GetSize(statBuf) == 0);

   /* Preallocate space to minimize realloc operations. */
   if (!DynBuf_Enlarge(statBuf, GUEST_INFO_PREALLOC_SIZE)) {
      return FALSE;
   }

   /* First time through, allocate all necessary memory */
   if (previous == NULL) {
      current = GuestInfoConstructCollector(guestInfoQuerySpecTable,
                                            N_QUERIES);

      previous = GuestInfoConstructCollector(guestInfoQuerySpecTable,
                                             N_QUERIES);
   }

   if ((current == NULL) ||
       (previous == NULL)) {
      GuestInfoDestroyCollector(current);
      current = NULL;
      GuestInfoDestroyCollector(previous);
      previous = NULL;
      return FALSE;
   }

   /* Collect the current data */
   GuestInfoCollect(current);

   /* Encode the captured data */
   GuestInfoEncodeStats(current, previous, statBuf);

   /* Switch the collections for next time. */
   temp = current;
   current = previous;
   previous = temp;

   return TRUE;
}
Beispiel #4
0
Bool
DynArray_SetCount(DynArray *a,          // IN/OUT
                  unsigned int c)       // IN
{
   size_t needed, allocated;

   ASSERT(a);

   needed = c * a->width;
   allocated = DynBuf_GetAllocatedSize(&a->buf);

   if (allocated < needed) {
      if (!DynBuf_Enlarge(&a->buf, needed)) {
         return FALSE;
      }
   }
   DynBuf_SetSize(&a->buf, needed);

   return TRUE;
}
Beispiel #5
0
Bool
StrUtil_VDynBufPrintf(DynBuf *b,        // IN/OUT
                      const char *fmt,  // IN
                      va_list args)     // IN
{
   /*
    * Arbitrary lower-limit on buffer size allocation, to avoid doing
    * many tiny enlarge operations.
    */

   const size_t minAllocSize = 128;

   while (1) {
      int i;
      size_t size = DynBuf_GetSize(b);
      size_t allocSize = DynBuf_GetAllocatedSize(b);

      /* Make sure the buffer isn't still unallocated */
      if (allocSize < minAllocSize) {
         Bool success = DynBuf_Enlarge(b, minAllocSize);
         if (!success) {
            return FALSE;
         }
         continue;
      }

      /*
       * Is there any allocated-but-not-occupied space? If so, try the printf.
       * If there was no space to begin with, or Str_Vsnprintf() ran out of
       * space, this will fail.
       */

      if (allocSize - size > 0) {
         va_list tmpArgs;

         va_copy(tmpArgs, args);
         i = Str_Vsnprintf((char *) DynBuf_Get(b) + size, allocSize - size,
                           fmt, tmpArgs);
         va_end(tmpArgs);
      } else {
         i = -1;
      }

      if (i >= 0) {
         /*
          * Success. Enlarge the buffer.
          *
          * The ASSERT here is to verify that printf() isn't lying
          * about the length of the string it wrote. This actually
          * happens, believe it or not. See bug 253674.
          */

         ASSERT(i + size == allocSize ||
                ((char *)DynBuf_Get(b))[i + size] == '\0');

         DynBuf_SetSize(b, size + i);
         break;

      } else {
         /*
          * Failure. We must grow the buffer first.  Note that this is
          * just a minimum size- dynbuf will probably decide to double
          * the actual reallocated buffer size.
          */

         Bool success = DynBuf_Enlarge(b, size + minAllocSize);

         if (!success) {
            return FALSE;
         }
      }
   }

   return TRUE;
}
Bool
CodeSet_GenericToGenericDb(const char *codeIn,  // IN
                           const char *bufIn,   // IN
                           size_t sizeIn,       // IN
                           const char *codeOut, // IN
                           unsigned int flags,  // IN
                           DynBuf *db)          // IN/OUT
{
   Bool result = FALSE;
   UErrorCode uerr;
   const char *bufInCur;
   const char *bufInEnd;
   UChar bufPiv[1024];
   UChar *bufPivSource;
   UChar *bufPivTarget;
   UChar *bufPivEnd;
   char *bufOut;
   char *bufOutCur;
   char *bufOutEnd;
   size_t bufOutSize;
   size_t bufOutOffset;
   UConverter *cvin = NULL;
   UConverter *cvout = NULL;
   UConverterToUCallback toUCb;
   UConverterFromUCallback fromUCb;

   ASSERT(codeIn);
   ASSERT(sizeIn == 0 || bufIn);
   ASSERT(codeOut);
   ASSERT(db);
   ASSERT((CSGTG_NORMAL == flags) || (CSGTG_TRANSLIT == flags) ||
          (CSGTG_IGNORE == flags));

   if (dontUseIcu) {
      // fall back
      return CodeSetOld_GenericToGenericDb(codeIn, bufIn, sizeIn, codeOut,
                                           flags, db);
   }

   /*
    * Trivial case.
    */

   if ((0 == sizeIn) || (NULL == bufIn)) {
      result = TRUE;
      goto exit;
   }

   /*
    * Open converters.
    */

   uerr = U_ZERO_ERROR;
   cvin = ucnv_open(codeIn, &uerr);
   if (!cvin) {
      goto exit;
   }

   uerr = U_ZERO_ERROR;
   cvout = ucnv_open(codeOut, &uerr);
   if (!cvout) {
      goto exit;
   }

   /*
    * Set callbacks according to flags.
    */

   switch (flags) {
   case CSGTG_NORMAL:
      toUCb = UCNV_TO_U_CALLBACK_STOP;
      fromUCb = UCNV_FROM_U_CALLBACK_STOP;
      break;

   case CSGTG_TRANSLIT:
      toUCb = UCNV_TO_U_CALLBACK_SUBSTITUTE;
      fromUCb = UCNV_FROM_U_CALLBACK_SUBSTITUTE;
      break;

   case CSGTG_IGNORE:
      toUCb = UCNV_TO_U_CALLBACK_SKIP;
      fromUCb = UCNV_FROM_U_CALLBACK_SKIP;
      break;

   default:
      NOT_IMPLEMENTED();
      break;
   }

   uerr = U_ZERO_ERROR;
   ucnv_setToUCallBack(cvin, toUCb, NULL, NULL, NULL, &uerr);
   if (U_ZERO_ERROR != uerr) {
      goto exit;
   }

   uerr = U_ZERO_ERROR;
   ucnv_setFromUCallBack(cvout, fromUCb, NULL, NULL, NULL, &uerr);
   if (U_ZERO_ERROR != uerr) {
      goto exit;
   }

   /*
    * Convert using ucnv_convertEx().
    * As a starting guess, make the output buffer the same size as
    * the input string (with a fudge constant added in to avoid degen
    * cases).
    */

   bufInCur = bufIn;
   bufInEnd = bufIn + sizeIn;
   bufOutSize = sizeIn + 4;
   bufOutOffset = 0;
   bufPivSource = bufPiv;
   bufPivTarget = bufPiv;
   bufPivEnd = bufPiv + ARRAYSIZE(bufPiv);

   for (;;) {
      if (!DynBuf_Enlarge(db, bufOutSize)) {
         goto exit;
      }
      bufOut = DynBuf_Get(db);
      bufOutCur = bufOut + bufOutOffset;
      bufOutSize = DynBuf_GetAllocatedSize(db);
      bufOutEnd = bufOut + bufOutSize;

      uerr = U_ZERO_ERROR;
      ucnv_convertEx(cvout, cvin, &bufOutCur, bufOutEnd,
		     &bufInCur, bufInEnd,
		     bufPiv, &bufPivSource, &bufPivTarget, bufPivEnd,
		     FALSE, TRUE, &uerr);

      if (!U_FAILURE(uerr)) {
         /*
          * "This was a triumph.
          *  I'm making a note here:
          *  HUGE SUCCESS.
          *  It's hard to overstate
          *  my satisfaction."
          */

         break;
      }

      if (U_BUFFER_OVERFLOW_ERROR != uerr) {
	 // failure
         goto exit;
      }

      /*
       * Our guess at 'bufOutSize' was obviously wrong, just double it.
       * We'll be reallocating bufOut, so will need to recompute bufOutCur
       * based on bufOutOffset.
       */

      bufOutSize *= 2;
      bufOutOffset = bufOutCur - bufOut;
   }

   /*
    * Set final size and return.
    */

   DynBuf_SetSize(db, bufOutCur - bufOut);

   result = TRUE;

  exit:
   if (cvin) {
      ucnv_close(cvin);
   }

   if (cvout) {
      ucnv_close(cvout);
   }

   return result;
}
Beispiel #7
0
StdIO_Status
StdIO_ReadNextLine(FILE *stream,         // IN:
                   char **buf,           // OUT:
                   size_t maxBufLength,  // IN:
                   size_t *count)        // OUT:
{
   DynBuf b;

   ASSERT(stream);
   ASSERT(buf);

   DynBuf_Init(&b);

   for (;;) {
      char *data;
      size_t size;
      size_t max;
      size_t nr;

      /*
       * The dynamic buffer must be at least 2 bytes large, so that at least
       * 1 stream byte and fgets()'s NUL byte can fit --hpreg
       */

      if (DynBuf_Enlarge(&b, 2) == FALSE) {
         errno = ENOMEM;
         goto error;
      }

      /* Read the next chunk of line directly in the dynamic buffer --hpreg */

      data = DynBuf_Get(&b);
      size = DynBuf_GetSize(&b);

      if (maxBufLength != 0 && size > maxBufLength) {
         errno = E2BIG;
         goto error;
      }

      max = DynBuf_GetAllocatedSize(&b);
      nr = max - size;

      if (SuperFgets(stream, &nr, data + size) == NULL) {
         goto error;
      }

      size += nr;
      DynBuf_SetSize(&b, size);

      if (size < max) {
         /* SuperFgets() found end-of-line */

         if (size == 0 && feof(stream)) {
            /* Reached end-of-file before reading anything */
            DynBuf_Destroy(&b);

            return StdIO_EOF;
         }

         break;
      }

      /*
       * No line terminator found yet, we need a larger buffer to do the next
       * SuperFgets() --hpreg
       */

   }

   /* There is a line in the buffer --hpreg */

   /* NUL terminator --hpreg */
   if (DynBuf_Append(&b, "", 1) == FALSE) {
      errno = ENOMEM;
      goto error;
   }

   *buf = DynBuf_Get(&b);
   if (count) {
      *count = DynBuf_GetSize(&b) - 1;
   }

   return StdIO_Success;

error:
   DynBuf_Destroy(&b);

   return StdIO_Error;
}