intl/icu/source/common/uenum.c

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /*
     2 *******************************************************************************
     3 *
     4 *   Copyright (C) 2002-2012, International Business Machines
     5 *   Corporation and others.  All Rights Reserved.
     6 *
     7 *******************************************************************************
     8 *   file name:  uenum.c
     9 *   encoding:   US-ASCII
    10 *   tab size:   8 (not used)
    11 *   indentation:2
    12 *
    13 *   created on: 2002jul08
    14 *   created by: Vladimir Weinstein
    15 */
    17 #include "unicode/putil.h"
    18 #include "uenumimp.h"
    19 #include "cmemory.h"
    21 /* Layout of the baseContext buffer. */
    22 typedef struct {
    23     int32_t len;  /* number of bytes available starting at 'data' */
    24     char    data; /* actual data starts here */
    25 } _UEnumBuffer;
    27 /* Extra bytes to allocate in the baseContext buffer. */
    28 static const int32_t PAD = 8;
    30 /* Return a pointer to the baseContext buffer, possibly allocating
    31    or reallocating it if at least 'capacity' bytes are not available. */
    32 static void* _getBuffer(UEnumeration* en, int32_t capacity) {
    34     if (en->baseContext != NULL) {
    35         if (((_UEnumBuffer*) en->baseContext)->len < capacity) {
    36             capacity += PAD;
    37             en->baseContext = uprv_realloc(en->baseContext,
    38                                            sizeof(int32_t) + capacity);
    39             if (en->baseContext == NULL) {
    40                 return NULL;
    41             }
    42             ((_UEnumBuffer*) en->baseContext)->len = capacity;
    43         }
    44     } else {
    45         capacity += PAD;
    46         en->baseContext = uprv_malloc(sizeof(int32_t) + capacity);
    47         if (en->baseContext == NULL) {
    48             return NULL;
    49         }
    50         ((_UEnumBuffer*) en->baseContext)->len = capacity;
    51     }
    53     return (void*) & ((_UEnumBuffer*) en->baseContext)->data;
    54 }
    56 U_CAPI void U_EXPORT2
    57 uenum_close(UEnumeration* en)
    58 {
    59     if (en) {
    60         if (en->close != NULL) {
    61             if (en->baseContext) {
    62                 uprv_free(en->baseContext);
    63             }
    64             en->close(en);
    65         } else { /* this seems dangerous, but we better kill the object */
    66             uprv_free(en);
    67         }
    68     }
    69 }
    71 U_CAPI int32_t U_EXPORT2
    72 uenum_count(UEnumeration* en, UErrorCode* status)
    73 {
    74     if (!en || U_FAILURE(*status)) {
    75         return -1;
    76     }
    77     if (en->count != NULL) {
    78         return en->count(en, status);
    79     } else {
    80         *status = U_UNSUPPORTED_ERROR;
    81         return -1;
    82     }
    83 }
    85 /* Don't call this directly. Only uenum_unext should be calling this. */
    86 U_CAPI const UChar* U_EXPORT2
    87 uenum_unextDefault(UEnumeration* en,
    88             int32_t* resultLength,
    89             UErrorCode* status)
    90 {
    91     UChar *ustr = NULL;
    92     int32_t len = 0;
    93     if (en->next != NULL) {
    94         const char *cstr = en->next(en, &len, status);
    95         if (cstr != NULL) {
    96             ustr = (UChar*) _getBuffer(en, (len+1) * sizeof(UChar));
    97             if (ustr == NULL) {
    98                 *status = U_MEMORY_ALLOCATION_ERROR;
    99             } else {
   100                 u_charsToUChars(cstr, ustr, len+1);
   101             }
   102         }
   103     } else {
   104         *status = U_UNSUPPORTED_ERROR;
   105     }
   106     if (resultLength) {
   107         *resultLength = len;
   108     }
   109     return ustr;
   110 }
   112 /* Don't call this directly. Only uenum_next should be calling this. */
   113 U_CAPI const char* U_EXPORT2
   114 uenum_nextDefault(UEnumeration* en,
   115             int32_t* resultLength,
   116             UErrorCode* status)
   117 {
   118     if (en->uNext != NULL) {
   119         char *tempCharVal;
   120         const UChar *tempUCharVal = en->uNext(en, resultLength, status);
   121         if (tempUCharVal == NULL) {
   122             return NULL;
   123         }
   124         tempCharVal = (char*)
   125             _getBuffer(en, (*resultLength+1) * sizeof(char));
   126         if (!tempCharVal) {
   127             *status = U_MEMORY_ALLOCATION_ERROR;
   128             return NULL;
   129         }
   130         u_UCharsToChars(tempUCharVal, tempCharVal, *resultLength + 1);
   131         return tempCharVal;
   132     } else {
   133         *status = U_UNSUPPORTED_ERROR;
   134         return NULL;
   135     }
   136 }
   138 U_CAPI const UChar* U_EXPORT2
   139 uenum_unext(UEnumeration* en,
   140             int32_t* resultLength,
   141             UErrorCode* status)
   142 {
   143     if (!en || U_FAILURE(*status)) {
   144         return NULL;
   145     }
   146     if (en->uNext != NULL) {
   147         return en->uNext(en, resultLength, status);
   148     } else {
   149         *status = U_UNSUPPORTED_ERROR;
   150         return NULL;
   151     }
   152 }
   154 U_CAPI const char* U_EXPORT2
   155 uenum_next(UEnumeration* en,
   156           int32_t* resultLength,
   157           UErrorCode* status)
   158 {
   159     if (!en || U_FAILURE(*status)) {
   160         return NULL;
   161     }
   162     if (en->next != NULL) {
   163         if (resultLength != NULL) {
   164             return en->next(en, resultLength, status);
   165         }
   166         else {
   167             int32_t dummyLength=0;
   168             return en->next(en, &dummyLength, status);
   169         }
   170     } else {
   171         *status = U_UNSUPPORTED_ERROR;
   172         return NULL;
   173     }
   174 }
   176 U_CAPI void U_EXPORT2
   177 uenum_reset(UEnumeration* en, UErrorCode* status)
   178 {
   179     if (!en || U_FAILURE(*status)) {
   180         return;
   181     }
   182     if (en->reset != NULL) {
   183         en->reset(en, status);
   184     } else {
   185         *status = U_UNSUPPORTED_ERROR;
   186     }
   187 }

mercurial