/** * Allocate argTypes[] to at least the given capacity and return * TRUE if successful. If not, leave argTypes[] unchanged. * * If argTypes is NULL, allocate it. If it is not NULL, enlarge it * if necessary to be at least as large as specified. */ UBool MessageFormat::allocateArgTypes(int32_t capacity) { if (argTypes == NULL) { argTypes = (Formattable::Type*) uprv_malloc(sizeof(*argTypes) * capacity); argTypeCount = 0; argTypeCapacity = capacity; if (argTypes == NULL) { argTypeCapacity = 0; return FALSE; } for (int32_t i=0; i<capacity; ++i) { argTypes[i] = Formattable::kString; } } else if (argTypeCapacity < capacity) { if (capacity < 2*argTypeCapacity) { capacity = 2*argTypeCapacity; } Formattable::Type* a = (Formattable::Type*) uprv_realloc(argTypes, sizeof(*argTypes) * capacity); if (a == NULL) { return FALSE; // request failed } for (int32_t i=argTypeCapacity; i<capacity; ++i) { a[i] = Formattable::kString; } argTypes = a; argTypeCapacity = capacity; } return TRUE; }
void UVector32::setMaxCapacity(int32_t limit) { U_ASSERT(limit >= 0); if (limit < 0) { limit = 0; } if (limit > (int32_t)(INT32_MAX / sizeof(int32_t))) { // integer overflow check for realloc // Something is very wrong, don't realloc, leave capacity and maxCapacity unchanged return; } maxCapacity = limit; if (capacity <= maxCapacity || maxCapacity == 0) { // Current capacity is within the new limit. return; } // New maximum capacity is smaller than the current size. // Realloc the storage to the new, smaller size. int32_t* newElems = (int32_t *)uprv_realloc(elements, sizeof(int32_t)*maxCapacity); if (newElems == NULL) { // Realloc to smaller failed. // Just keep what we had. No need to call it a failure. return; } elements = newElems; capacity = maxCapacity; if (count > capacity) { count = capacity; } }
void UVector64::setMaxCapacity(int32_t limit) { U_ASSERT(limit >= 0); maxCapacity = limit; if (maxCapacity < 0) { maxCapacity = 0; } if (capacity <= maxCapacity || maxCapacity == 0) { // Current capacity is within the new limit. return; } // New maximum capacity is smaller than the current size. // Realloc the storage to the new, smaller size. int64_t* newElems = (int64_t *)uprv_realloc(elements, sizeof(int64_t)*maxCapacity); if (newElems == NULL) { // Realloc to smaller failed. // Just keep what we had. No need to call it a failure. return; } elements = newElems; capacity = maxCapacity; if (count > capacity) { count = capacity; } }
UBool UVector64::expandCapacity(int32_t minimumCapacity, UErrorCode &status) { if (capacity >= minimumCapacity) { return TRUE; } if (maxCapacity>0 && minimumCapacity>maxCapacity) { status = U_BUFFER_OVERFLOW_ERROR; return FALSE; } int32_t newCap = capacity * 2; if (newCap < minimumCapacity) { newCap = minimumCapacity; } if (maxCapacity > 0 && newCap > maxCapacity) { newCap = maxCapacity; } int64_t* newElems = (int64_t *)uprv_realloc(elements, sizeof(int64_t)*newCap); if (newElems == NULL) { // We keep the original contents on the memory failure on realloc. status = U_MEMORY_ALLOCATION_ERROR; return FALSE; } elements = newElems; capacity = newCap; return TRUE; }
UBool UVector::ensureCapacity(int32_t minimumCapacity, UErrorCode &status) { if (minimumCapacity < 0) { status = U_ILLEGAL_ARGUMENT_ERROR; return FALSE; } if (capacity < minimumCapacity) { if (capacity > (INT32_MAX - 1) / 2) { // integer overflow check status = U_ILLEGAL_ARGUMENT_ERROR; return FALSE; } int32_t newCap = capacity * 2; if (newCap < minimumCapacity) { newCap = minimumCapacity; } if (newCap > (int32_t)(INT32_MAX / sizeof(UElement))) { // integer overflow check // We keep the original memory contents on bad minimumCapacity. status = U_ILLEGAL_ARGUMENT_ERROR; return FALSE; } UElement* newElems = (UElement *)uprv_realloc(elements, sizeof(UElement)*newCap); if (newElems == NULL) { // We keep the original contents on the memory failure on realloc or bad minimumCapacity. status = U_MEMORY_ALLOCATION_ERROR; return FALSE; } elements = newElems; capacity = newCap; } return TRUE; }
void add(void* elem, UErrorCode& status) { if (U_SUCCESS(status)) { if (size == cap) { if (cap == 0) { cap = 1; } else if (cap < 256) { cap *= 2; } else { cap += 256; } if (buf == NULL) { buf = (void**)uprv_malloc(cap * sizeof(void*)); } else { buf = (void**)uprv_realloc(buf, cap * sizeof(void*)); } if (buf == NULL) { // if we couldn't realloc, we leak the memory we've already allocated, but we're in deep trouble anyway status = U_MEMORY_ALLOCATION_ERROR; return; } void* start = &buf[size]; size_t count = (cap - size) * sizeof(void*); uprv_memset(start, 0, count); // fill with nulls, just because } buf[size++] = elem; } }
static void uprv_growTable(ContractionTable *tbl, UErrorCode *status) { if(tbl->position == tbl->size) { uint32_t *newData = (uint32_t *)uprv_realloc(tbl->CEs, 2*tbl->size*sizeof(uint32_t)); if(newData == NULL) { *status = U_MEMORY_ALLOCATION_ERROR; return; } UChar *newCPs = (UChar *)uprv_realloc(tbl->codePoints, 2*tbl->size*sizeof(UChar)); if(newCPs == NULL) { uprv_free(newData); *status = U_MEMORY_ALLOCATION_ERROR; return; } tbl->CEs = newData; tbl->codePoints = newCPs; tbl->size *= 2; } }
/** * Guarantee that _bufp is allocated to include _buflen characters * where _buflen >= minlen. Return TRUE if successful, FALSE * otherwise. */ UBool ensureCapacity(int32_t minlen) { if (_bufp != NULL && _buflen >= minlen) { return TRUE; } _buflen = minlen + 8; // add 8 to prevent thrashing _bufp = (_bufp == NULL) ? uprv_malloc(_buflen) : uprv_realloc(_bufp, _buflen); return _bufp != NULL; }
UBool UVector::ensureCapacity(int32_t minimumCapacity, UErrorCode &status) { if (capacity < minimumCapacity) { int32_t newCap = capacity * 2; if (newCap < minimumCapacity) { newCap = minimumCapacity; } UHashTok* newElems = (UHashTok *)uprv_realloc(elements, sizeof(UHashTok)*newCap); if (newElems == NULL) { // We keep the original contents on the memory failure on realloc. status = U_MEMORY_ALLOCATION_ERROR; return FALSE; } elements = newElems; capacity = newCap; } return TRUE; }
void *SpoofData::reserveSpace(int32_t numBytes, UErrorCode &status) { if (U_FAILURE(status)) { return NULL; } if (!fDataOwned) { UPRV_UNREACHABLE; } numBytes = (numBytes + 15) & ~15; // Round up to a multiple of 16 uint32_t returnOffset = fMemLimit; fMemLimit += numBytes; fRawData = static_cast<SpoofDataHeader *>(uprv_realloc(fRawData, fMemLimit)); fRawData->fLength = fMemLimit; uprv_memset((char *)fRawData + returnOffset, 0, numBytes); initPtrs(status); return (char *)fRawData + returnOffset; }
U_CDECL_BEGIN // We have switched CanonicalMap to use const UChar* strings for the key and for the id field of // CanonicalMapEntry; that is because for the most part these now point into UChar strings in the // shared data file, in order to reduce process-specific dynamically-allocated memory. Consequently, // there is no longer a deleter for the key field, and the deleter for CanonicalMapEntry // no longer frees the id field. However, for the few strings that are obtained from the // TimeZone::createEnumeration() enumerator or from TimeZone::dereferOlsonLink instead of the // data file, we do need to allocate copies. In order to ensure that these strings are freed by // zoneMeta_cleanup(), we need to create a little memory manager for them; this is in the form of // a table that tracks the strings allocated for this purpose. The following three functions // (along with the gUStringXxxxx statics) are used to allocate and free such strings. // The following allocs space for a UChar* string of the specified length, puts a pointer to the string // in gUStringTable, and returns either a pointer to the allocated string space, or NULL for failure. static UChar * allocUStringInTable(int32_t uStringLen) { UChar * uStringSpace = NULL; // initialize the table if necessary umtx_lock(&gZoneMetaLock); if (gUStringTable == NULL) { gUStringTable = (UChar**)uprv_malloc(USTRING_ALLOC_START*sizeof(UChar*)); if (gUStringTable != NULL) { gUStringAlloc = USTRING_ALLOC_START; } } if (gUStringTable != NULL) { // expand the table if necessary if (gUStringCount == gUStringAlloc) { UChar ** newTable = (UChar**)uprv_realloc(gUStringTable, (gUStringAlloc+USTRING_ALLOC_INCR)*sizeof(UChar*)); if (newTable != NULL) { gUStringTable = newTable; gUStringAlloc += USTRING_ALLOC_INCR; } } // add the string if possible if (gUStringCount < gUStringAlloc) { uStringSpace = (UChar*)uprv_malloc(uStringLen*sizeof(UChar)); if (uStringSpace != NULL) { gUStringTable[gUStringCount++] = uStringSpace; } } } umtx_unlock(&gZoneMetaLock); return uStringSpace; }
/* Destroys data in the string */ static void ustr_resize(struct UString *s, int32_t len, UErrorCode *status) { if(U_FAILURE(*status)) return; /* +1 for trailing 0x0000 */ s->fChars = (UChar*) uprv_realloc(s->fChars, sizeof(UChar) * (len + 1)); if(s->fChars == 0) { *status = U_MEMORY_ALLOCATION_ERROR; s->fLength = s->fCapacity = 0; return; } s->fCapacity = len; }
UBool UVector32::expandCapacity(int32_t minimumCapacity, UErrorCode &status) { if (U_FAILURE(status)) { return FALSE; } if (minimumCapacity < 0) { status = U_ILLEGAL_ARGUMENT_ERROR; return FALSE; } if (capacity >= minimumCapacity) { return TRUE; } if (maxCapacity>0 && minimumCapacity>maxCapacity) { status = U_BUFFER_OVERFLOW_ERROR; return FALSE; } if (capacity > (INT32_MAX - 1) / 2) { // integer overflow check status = U_ILLEGAL_ARGUMENT_ERROR; return FALSE; } int32_t newCap = capacity * 2; if (newCap < minimumCapacity) { newCap = minimumCapacity; } if (maxCapacity > 0 && newCap > maxCapacity) { newCap = maxCapacity; } if (newCap > (int32_t)(INT32_MAX / sizeof(int32_t))) { // integer overflow check // We keep the original memory contents on bad minimumCapacity/maxCapacity. status = U_ILLEGAL_ARGUMENT_ERROR; return FALSE; } int32_t* newElems = (int32_t *)uprv_realloc(elements, sizeof(int32_t)*newCap); if (newElems == NULL) { // We keep the original contents on the memory failure on realloc. status = U_MEMORY_ALLOCATION_ERROR; return FALSE; } elements = newElems; capacity = newCap; return TRUE; }
static UBool utm_hasCapacity(UToolMemory *mem, int32_t capacity) { if(mem->capacity<capacity) { int32_t newCapacity; if(mem->maxCapacity<capacity) { fprintf(stderr, "error: %s - trying to use more than maxCapacity=%ld units\n", mem->name, (long)mem->maxCapacity); exit(U_MEMORY_ALLOCATION_ERROR); } /* try to allocate a larger array */ if(capacity>=2*mem->capacity) { newCapacity=capacity; } else if(mem->capacity<=mem->maxCapacity/3) { newCapacity=2*mem->capacity; } else { newCapacity=mem->maxCapacity; } if(mem->array==mem->staticArray) { mem->array=uprv_malloc(newCapacity*mem->size); if(mem->array!=NULL) { uprv_memcpy(mem->array, mem->staticArray, mem->idx*mem->size); } } else { mem->array=uprv_realloc(mem->array, newCapacity*mem->size); } if(mem->array==NULL) { fprintf(stderr, "error: %s - out of memory\n", mem->name); exit(U_MEMORY_ALLOCATION_ERROR); } mem->capacity=newCapacity; } return TRUE; }
/** * Allocate subformats[] to at least the given capacity and return * TRUE if successful. If not, leave subformats[] unchanged. * * If subformats is NULL, allocate it. If it is not NULL, enlarge it * if necessary to be at least as large as specified. */ UBool MessageFormat::allocateSubformats(int32_t capacity) { if (subformats == NULL) { subformats = (Subformat*) uprv_malloc(sizeof(*subformats) * capacity); subformatCapacity = capacity; subformatCount = 0; if (subformats == NULL) { subformatCapacity = 0; return FALSE; } } else if (subformatCapacity < capacity) { if (capacity < 2*subformatCapacity) { capacity = 2*subformatCapacity; } Subformat* a = (Subformat*) uprv_realloc(subformats, sizeof(*subformats) * capacity); if (a == NULL) { return FALSE; // request failed } subformats = a; subformatCapacity = capacity; } return TRUE; }
/* Return a pointer to the baseContext buffer, possibly allocating or reallocating it if at least 'capacity' bytes are not available. */ static void* _getBuffer(UEnumeration* en, int32_t capacity) { if (en->baseContext != NULL) { if (((_UEnumBuffer*) en->baseContext)->len < capacity) { capacity += PAD; en->baseContext = uprv_realloc(en->baseContext, sizeof(int32_t) + capacity); if (en->baseContext == NULL) { return NULL; } ((_UEnumBuffer*) en->baseContext)->len = capacity; } } else { capacity += PAD; en->baseContext = uprv_malloc(sizeof(int32_t) + capacity); if (en->baseContext == NULL) { return NULL; } ((_UEnumBuffer*) en->baseContext)->len = capacity; } return (void*) & ((_UEnumBuffer*) en->baseContext)->data; }
U_CAPI int32_t U_EXPORT2 uprv_mstrm_write(UMemoryStream *MS, const void *buffer, int32_t len){ if(MS->fError == FALSE) { if(MS->fReadOnly == FALSE) { if(len + MS->fPos > MS->fSize) { uint8_t *newstart = (uint8_t *)uprv_realloc(MS->fStart, MS->fSize+len); if(newstart != NULL) { MS->fSize+=len; MS->fStart = newstart; } else { MS->fError = TRUE; return -1; } } uprv_memcpy(MS->fStart + MS->fPos, buffer, len); MS->fPos += len; return len; } else { MS->fError = TRUE; return 0; } } else { return 0; } }
static int printTransliterators(int canon) { #if UCONFIG_NO_TRANSLITERATION printf("no transliterators available because of UCONFIG_NO_TRANSLITERATION, see uconfig.h\n"); return 1; #else int32_t numtrans = utrans_countAvailableIDs(), i; int buflen = 512; char *buf = (char *) uprv_malloc(buflen); char staticbuf[512]; char sepchar = canon ? '\n' : ' '; if (!buf) { buf = staticbuf; buflen = sizeof(staticbuf); } for (i = 0; i < numtrans; ++i) { int32_t len = utrans_getAvailableID(i, buf, buflen); if (len >= buflen - 1) { if (buf != staticbuf) { buflen <<= 1; if (buflen < len) { buflen = len + 64; } buf = (char *) uprv_realloc(buf, buflen); if (!buf) { buf = staticbuf; buflen = sizeof(staticbuf); } } utrans_getAvailableID(i, buf, buflen); if (len >= buflen) { uprv_strcpy(buf + buflen - 4, "..."); /* Truncate the name. */ } } printf("%s", buf); if (i < numtrans - 1) { putchar(sepchar); } } /* Add a terminating newline if needed. */ if (sepchar != '\n') { putchar('\n'); } /* Free temporary data. */ if (buf != staticbuf) { uprv_free(buf); } /* Success. */ return 0; #endif }
static void addFile(const char *filename, const char *name, const char *source, UBool sourceTOC, UBool verbose) { char *s; uint32_t length; char *fullPath = NULL; if(fileCount==fileMax) { fileMax += CHUNK_FILE_COUNT; files = uprv_realloc(files, fileMax*sizeof(files[0])); /* note: never freed. */ if(files==NULL) { fprintf(stderr, "pkgdata/gencmn: Could not allocate %u bytes for %d files\n", (unsigned int)(fileMax*sizeof(files[0])), fileCount); exit(U_MEMORY_ALLOCATION_ERROR); } } if(!sourceTOC) { FileStream *file; if(uprv_pathIsAbsolute(filename)) { fprintf(stderr, "gencmn: Error: absolute path encountered. Old style paths are not supported. Use relative paths such as 'fur.res' or 'translit%cfur.res'.\n\tBad path: '%s'\n", U_FILE_SEP_CHAR, filename); exit(U_ILLEGAL_ARGUMENT_ERROR); } fullPath = pathToFullPath(filename, source); /* store the pathname */ length = (uint32_t)(uprv_strlen(filename) + 1 + uprv_strlen(name) + 1); s=allocString(length); uprv_strcpy(s, name); uprv_strcat(s, U_TREE_ENTRY_SEP_STRING); uprv_strcat(s, filename); /* get the basename */ fixDirToTreePath(s); files[fileCount].basename=s; files[fileCount].basenameLength=length; files[fileCount].pathname=fullPath; basenameTotal+=length; /* try to open the file */ file=T_FileStream_open(fullPath, "rb"); if(file==NULL) { fprintf(stderr, "gencmn: unable to open listed file %s\n", fullPath); exit(U_FILE_ACCESS_ERROR); } /* get the file length */ length=T_FileStream_size(file); if(T_FileStream_error(file) || length<=20) { fprintf(stderr, "gencmn: unable to get length of listed file %s\n", fullPath); exit(U_FILE_ACCESS_ERROR); } T_FileStream_close(file); /* do not add files that are longer than maxSize */ if(maxSize && length>maxSize) { if (verbose) { printf("%s ignored (size %ld > %ld)\n", fullPath, (long)length, (long)maxSize); } return; } files[fileCount].fileSize=length; } else { char *t; /* get and store the basename */ /* need to include the package name */ length = (uint32_t)(uprv_strlen(filename) + 1 + uprv_strlen(name) + 1); s=allocString(length); uprv_strcpy(s, name); uprv_strcat(s, U_TREE_ENTRY_SEP_STRING); uprv_strcat(s, filename); fixDirToTreePath(s); files[fileCount].basename=s; /* turn the basename into an entry point name and store in the pathname field */ t=files[fileCount].pathname=allocString(length); while(--length>0) { if(*s=='.' || *s=='-' || *s=='/') { *t='_'; } else { *t=*s; } ++s; ++t; } *t=0; } ++fileCount; }
/* @param standard When standard is 0, then it's the "empty" tag. */ static uint16_t addAlias(const char *alias, uint16_t standard, uint16_t converter, UBool defaultName) { uint32_t idx, idx2; UBool startEmptyWithoutDefault = FALSE; AliasList *aliasList; if(standard>=MAX_TAG_COUNT) { fprintf(stderr, "%s:%d: error: too many standard tags\n", path, lineNum); exit(U_BUFFER_OVERFLOW_ERROR); } if(converter>=MAX_CONV_COUNT) { fprintf(stderr, "%s:%d: error: too many converter names\n", path, lineNum); exit(U_BUFFER_OVERFLOW_ERROR); } aliasList = &tags[standard].aliasList[converter]; if (strchr(alias, '}')) { fprintf(stderr, "%s:%d: error: unmatched } found\n", path, lineNum); } if(aliasList->aliasCount + 1 >= MAX_TC_ALIAS_COUNT) { fprintf(stderr, "%s:%d: error: too many aliases for alias %s and converter %s\n", path, lineNum, alias, GET_ALIAS_STR(converters[converter].converter)); exit(U_BUFFER_OVERFLOW_ERROR); } /* Show this warning only once. All aliases are added to the "ALL" tag. */ if (standard == ALL_TAG_NUM && GET_ALIAS_STR(converters[converter].converter) != alias) { /* Normally these option values are parsed at runtime, and they can be discarded when the alias is a default converter. Options should only be on a converter and not an alias. */ if (uprv_strchr(alias, UCNV_OPTION_SEP_CHAR) != 0) { fprintf(stderr, "warning(line %d): alias %s contains a \""UCNV_OPTION_SEP_STRING"\". Options are parsed at run-time and do not need to be in the alias table.\n", lineNum, alias); } if (uprv_strchr(alias, UCNV_VALUE_SEP_CHAR) != 0) { fprintf(stderr, "warning(line %d): alias %s contains an \""UCNV_VALUE_SEP_STRING"\". Options are parsed at run-time and do not need to be in the alias table.\n", lineNum, alias); } } if (standard != ALL_TAG_NUM) { /* Check for duplicate aliases for this tag on all converters */ for (idx = 0; idx < converterCount; idx++) { for (idx2 = 0; idx2 < tags[standard].aliasList[idx].aliasCount; idx2++) { uint16_t aliasNum = tags[standard].aliasList[idx].aliases[idx2]; if (aliasNum && ucnv_compareNames(alias, GET_ALIAS_STR(aliasNum)) == 0) { if (idx == converter) { /* * (alias, standard) duplicates are harmless if they map to the same converter. * Only print a warning in verbose mode, or if the alias is a precise duplicate, * not just a lenient-match duplicate. */ if (verbose || 0 == uprv_strcmp(alias, GET_ALIAS_STR(aliasNum))) { fprintf(stderr, "%s:%d: warning: duplicate aliases %s and %s found for standard %s and converter %s\n", path, lineNum, alias, GET_ALIAS_STR(aliasNum), GET_TAG_STR(tags[standard].tag), GET_ALIAS_STR(converters[converter].converter)); } } else { fprintf(stderr, "%s:%d: warning: duplicate aliases %s and %s found for standard tag %s between converter %s and converter %s\n", path, lineNum, alias, GET_ALIAS_STR(aliasNum), GET_TAG_STR(tags[standard].tag), GET_ALIAS_STR(converters[converter].converter), GET_ALIAS_STR(converters[idx].converter)); } break; } } } /* Check for duplicate default aliases for this converter on all tags */ /* It's okay to have multiple standards prefer the same name */ /* if (verbose && !dupFound) { for (idx = 0; idx < tagCount; idx++) { if (tags[idx].aliasList[converter].aliases) { uint16_t aliasNum = tags[idx].aliasList[converter].aliases[0]; if (aliasNum && ucnv_compareNames(alias, GET_ALIAS_STR(aliasNum)) == 0) { fprintf(stderr, "%s:%d: warning: duplicate alias %s found for converter %s and standard tag %s\n", path, lineNum, alias, GET_ALIAS_STR(converters[converter].converter), GET_TAG_STR(tags[standard].tag)); break; } } } }*/ } if (aliasList->aliasCount <= 0) { aliasList->aliasCount++; startEmptyWithoutDefault = TRUE; } aliasList->aliases = (uint16_t *)uprv_realloc(aliasList->aliases, (aliasList->aliasCount + 1) * sizeof(aliasList->aliases[0])); if (startEmptyWithoutDefault) { aliasList->aliases[0] = 0; } if (defaultName) { if (aliasList->aliases[0] != 0) { fprintf(stderr, "%s:%d: error: Alias %s and %s cannot both be the default alias for standard tag %s and converter %s\n", path, lineNum, alias, GET_ALIAS_STR(aliasList->aliases[0]), GET_TAG_STR(tags[standard].tag), GET_ALIAS_STR(converters[converter].converter)); exit(U_PARSE_ERROR); } aliasList->aliases[0] = GET_ALIAS_NUM(alias); } else { aliasList->aliases[aliasList->aliasCount++] = GET_ALIAS_NUM(alias); } /* aliasList->converter = converter;*/ converters[converter].totalAliasCount++; /* One more to the column */ tags[standard].totalAliasCount++; /* One more to the row */ return aliasList->aliasCount; }
U_CAPI void U_EXPORT2 ucm_addMapping(UCMTable *table, UCMapping *m, UChar32 codePoints[UCNV_EXT_MAX_UCHARS], uint8_t bytes[UCNV_EXT_MAX_BYTES]) { UCMapping *tm; UChar32 c; int32_t idx; if(table->mappingsLength>=table->mappingsCapacity) { /* make the mappings array larger */ if(table->mappingsCapacity==0) { table->mappingsCapacity=1000; } else { table->mappingsCapacity*=10; } table->mappings=(UCMapping *)uprv_realloc(table->mappings, table->mappingsCapacity*sizeof(UCMapping)); if(table->mappings==NULL) { fprintf(stderr, "ucm error: unable to allocate %d UCMappings\n", (int)table->mappingsCapacity); exit(U_MEMORY_ALLOCATION_ERROR); } if(table->reverseMap!=NULL) { /* the reverseMap must be reallocated in a new sort */ uprv_free(table->reverseMap); table->reverseMap=NULL; } } if(m->uLen>1 && table->codePointsCapacity==0) { table->codePointsCapacity=10000; table->codePoints=(UChar32 *)uprv_malloc(table->codePointsCapacity*4); if(table->codePoints==NULL) { fprintf(stderr, "ucm error: unable to allocate %d UChar32s\n", (int)table->codePointsCapacity); exit(U_MEMORY_ALLOCATION_ERROR); } } if(m->bLen>4 && table->bytesCapacity==0) { table->bytesCapacity=10000; table->bytes=(uint8_t *)uprv_malloc(table->bytesCapacity); if(table->bytes==NULL) { fprintf(stderr, "ucm error: unable to allocate %d bytes\n", (int)table->bytesCapacity); exit(U_MEMORY_ALLOCATION_ERROR); } } if(m->uLen>1) { idx=table->codePointsLength; table->codePointsLength+=m->uLen; if(table->codePointsLength>table->codePointsCapacity) { fprintf(stderr, "ucm error: too many code points in multiple-code point mappings\n"); exit(U_MEMORY_ALLOCATION_ERROR); } uprv_memcpy(table->codePoints+idx, codePoints, (size_t)m->uLen*4); m->u=idx; } if(m->bLen>4) { idx=table->bytesLength; table->bytesLength+=m->bLen; if(table->bytesLength>table->bytesCapacity) { fprintf(stderr, "ucm error: too many bytes in mappings with >4 charset bytes\n"); exit(U_MEMORY_ALLOCATION_ERROR); } uprv_memcpy(table->bytes+idx, bytes, m->bLen); m->b.idx=idx; } /* set unicodeMask */ for(idx=0; idx<m->uLen; ++idx) { c=codePoints[idx]; if(c>=0x10000) { table->unicodeMask|=UCNV_HAS_SUPPLEMENTARY; /* there are supplementary code points */ } else if(U_IS_SURROGATE(c)) { table->unicodeMask|=UCNV_HAS_SURROGATES; /* there are surrogate code points */ } } /* set flagsType */ if(m->f<0) { table->flagsType|=UCM_FLAGS_IMPLICIT; } else { table->flagsType|=UCM_FLAGS_EXPLICIT; } tm=table->mappings+table->mappingsLength++; uprv_memcpy(tm, m, sizeof(UCMapping)); table->isSorted=FALSE; }
static const UChar * u_file_translit(UFILE *f, const UChar *src, int32_t *count, UBool flush) { int32_t newlen; int32_t junkCount = 0; int32_t textLength; int32_t textLimit; UTransPosition pos; UErrorCode status = U_ZERO_ERROR; if(count == NULL) { count = &junkCount; } if ((!f)||(!f->fTranslit)||(!f->fTranslit->translit)) { /* fast path */ return src; } /* First: slide over everything */ if(f->fTranslit->length > f->fTranslit->pos) { memmove(f->fTranslit->buffer, f->fTranslit->buffer + f->fTranslit->pos, (f->fTranslit->length - f->fTranslit->pos)*sizeof(UChar)); } f->fTranslit->length -= f->fTranslit->pos; /* always */ f->fTranslit->pos = 0; /* Calculate new buffer size needed */ newlen = (*count + f->fTranslit->length) * 4; if(newlen > f->fTranslit->capacity) { if(f->fTranslit->buffer == NULL) { f->fTranslit->buffer = (UChar*)uprv_malloc(newlen * sizeof(UChar)); } else { f->fTranslit->buffer = (UChar*)uprv_realloc(f->fTranslit->buffer, newlen * sizeof(UChar)); } f->fTranslit->capacity = newlen; } /* Now, copy any data over */ u_strncpy(f->fTranslit->buffer + f->fTranslit->length, src, *count); f->fTranslit->length += *count; /* Now, translit in place as much as we can */ if(flush == FALSE) { textLength = f->fTranslit->length; pos.contextStart = 0; pos.contextLimit = textLength; pos.start = 0; pos.limit = textLength; utrans_transIncrementalUChars(f->fTranslit->translit, f->fTranslit->buffer, /* because we shifted */ &textLength, f->fTranslit->capacity, &pos, &status); #ifdef _DEBUG if(U_FAILURE(status)) { fprintf(stderr, " Gack. Translit blew up with a %s\n", u_errorName(status)); return src; } #endif /* now: start/limit point to the transliterated text */ /* Transliterated is [buffer..pos.start) */ *count = pos.start; f->fTranslit->pos = pos.start; f->fTranslit->length = pos.limit; return f->fTranslit->buffer; } else { textLength = f->fTranslit->length; textLimit = f->fTranslit->length; utrans_transUChars(f->fTranslit->translit, f->fTranslit->buffer, &textLength, f->fTranslit->capacity, 0, &textLimit, &status); #ifdef _DEBUG if(U_FAILURE(status)) { fprintf(stderr, " Gack. Translit(flush) blew up with a %s\n", u_errorName(status)); return src; } #endif /* out: converted len */ *count = textLimit; /* Set pointers to 0 */ f->fTranslit->pos = 0; f->fTranslit->length = 0; return f->fTranslit->buffer; } }
U_CAPI int32_t U_EXPORT2 ualoc_getLanguagesForRegion(const char *regionID, double minimumFraction, UALanguageEntry *entries, int32_t entriesCapacity, UErrorCode *err) { if (U_FAILURE(*err)) { return 0; } if ( regionID == NULL || minimumFraction < 0.0 || minimumFraction > 1.0 || ((entries==NULL)? entriesCapacity!=0: entriesCapacity<0) ) { *err = U_ILLEGAL_ARGUMENT_ERROR; return 0; } UResourceBundle *rb = ures_openDirect(NULL, "supplementalData", err); rb = ures_getByKey(rb, "territoryInfo", rb, err); rb = ures_getByKey(rb, regionID, rb, err); if (U_FAILURE(*err)) { ures_close(rb); return 0; } int32_t entryCount = 0; UResourceBundle *langBund = NULL; int32_t lbIdx, lbCount = ures_getSize(rb); UALanguageEntry localLangEntries[kLocalLangEntriesMax]; UALanguageEntry * langEntries = localLangEntries; int32_t langEntriesMax = kLocalLangEntriesMax; for (lbIdx = 0; lbIdx < lbCount; lbIdx++) { langBund = ures_getByIndex(rb, lbIdx, langBund, err); if (U_FAILURE(*err)) { break; } const char * langCode = ures_getKey(langBund); if (uprv_strcmp(langCode,"territoryF") == 0) { continue; } if (strnlen(langCode, UALANGDATA_CODELEN+1) > UALANGDATA_CODELEN) { // no uprv_strnlen continue; // a code we cannot handle } UErrorCode localErr = U_ZERO_ERROR; double userFraction = 0.0; UResourceBundle *itemBund = ures_getByKey(langBund, "populationShareF", NULL, &localErr); if (U_SUCCESS(localErr)) { int32_t intF = ures_getInt(itemBund, &localErr); if (U_SUCCESS(localErr)) { userFraction = doubleFromIntF(intF); } ures_close(itemBund); } if (userFraction < minimumFraction) { continue; } if (entries != NULL) { localErr = U_ZERO_ERROR; UALanguageStatus langStatus = UALANGSTATUS_UNSPECIFIED; int32_t ulen; const UChar * ustrLangStatus = ures_getStringByKey(langBund, "officialStatus", &ulen, &localErr); if (U_SUCCESS(localErr)) { int32_t cmp = u_strcmp(ustrLangStatus, ustrLangStatusOfficial); if (cmp == 0) { langStatus = UALANGSTATUS_OFFICIAL; } else if (cmp < 0 && u_strcmp(ustrLangStatus, ustrLangStatusDefacto) == 0) { langStatus = UALANGSTATUS_DEFACTO_OFFICIAL; } else if (u_strcmp(ustrLangStatus, ustrLangStatusRegional) == 0) { langStatus = UALANGSTATUS_REGIONAL_OFFICIAL; } } // Now we have all of the info for our next entry if (entryCount >= langEntriesMax) { int32_t newMax = langEntriesMax * kLangEntriesFactor; if (langEntries == localLangEntries) { // first allocation, copy from local buf langEntries = (UALanguageEntry*)uprv_malloc(newMax*sizeof(UALanguageEntry)); if (langEntries == NULL) { *err = U_MEMORY_ALLOCATION_ERROR; break; } uprv_memcpy(langEntries, localLangEntries, entryCount*sizeof(UALanguageEntry)); } else { langEntries = (UALanguageEntry*)uprv_realloc(langEntries, newMax*sizeof(UALanguageEntry)); if (langEntries == NULL) { *err = U_MEMORY_ALLOCATION_ERROR; break; } } langEntriesMax = newMax; } uprv_strcpy(langEntries[entryCount].languageCode, langCode); langEntries[entryCount].userFraction = userFraction; langEntries[entryCount].status = langStatus; } entryCount++; } ures_close(langBund); ures_close(rb); if (U_FAILURE(*err)) { if (langEntries != localLangEntries) { free(langEntries); } return 0; } if (entries != NULL) { // sort langEntries, copy entries that fit to provided array qsort(langEntries, entryCount, sizeof(UALanguageEntry), compareLangEntries); if (entryCount > entriesCapacity) { entryCount = entriesCapacity; } uprv_memcpy(entries, langEntries, entryCount*sizeof(UALanguageEntry)); if (langEntries != localLangEntries) { free(langEntries); } } return entryCount; }