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; } }
static void _expect(const UTransliterator* trans, const char* cfrom, const char* cto) { /* u_uastrcpy has no capacity param for the buffer -- so just * make all buffers way too big */ enum { CAP = 256 }; UChar from[CAP]; UChar to[CAP]; UChar buf[CAP]; const UChar *ID; int32_t IDLength; const char *id; UErrorCode status = U_ZERO_ERROR; int32_t limit; UTransPosition pos; XReplaceable xrep; XReplaceable *xrepPtr = &xrep; UReplaceableCallbacks xrepVtable; u_uastrcpy(from, cfrom); u_uastrcpy(to, cto); ID = utrans_getUnicodeID(trans, &IDLength); id = aescstrdup(ID, IDLength); /* utrans_transUChars() */ u_strcpy(buf, from); limit = u_strlen(buf); utrans_transUChars(trans, buf, NULL, CAP, 0, &limit, &status); if (U_FAILURE(status)) { log_err("FAIL: utrans_transUChars() failed, error=%s\n", u_errorName(status)); return; } if (0 == u_strcmp(buf, to)) { log_verbose("Ok: utrans_transUChars(%s) x %s -> %s\n", id, cfrom, cto); } else { char actual[CAP]; u_austrcpy(actual, buf); log_err("FAIL: utrans_transUChars(%s) x %s -> %s, expected %s\n", id, cfrom, actual, cto); } /* utrans_transIncrementalUChars() */ u_strcpy(buf, from); pos.start = pos.contextStart = 0; pos.limit = pos.contextLimit = u_strlen(buf); utrans_transIncrementalUChars(trans, buf, NULL, CAP, &pos, &status); utrans_transUChars(trans, buf, NULL, CAP, pos.start, &pos.limit, &status); if (U_FAILURE(status)) { log_err("FAIL: utrans_transIncrementalUChars() failed, error=%s\n", u_errorName(status)); return; } if (0 == u_strcmp(buf, to)) { log_verbose("Ok: utrans_transIncrementalUChars(%s) x %s -> %s\n", id, cfrom, cto); } else { char actual[CAP]; u_austrcpy(actual, buf); log_err("FAIL: utrans_transIncrementalUChars(%s) x %s -> %s, expected %s\n", id, cfrom, actual, cto); } /* utrans_trans() */ InitXReplaceableCallbacks(&xrepVtable); InitXReplaceable(&xrep, cfrom); limit = u_strlen(from); utrans_trans(trans, (UReplaceable*)xrepPtr, &xrepVtable, 0, &limit, &status); if (U_FAILURE(status)) { log_err("FAIL: utrans_trans() failed, error=%s\n", u_errorName(status)); FreeXReplaceable(&xrep); return; } if (0 == u_strcmp(xrep.text, to)) { log_verbose("Ok: utrans_trans(%s) x %s -> %s\n", id, cfrom, cto); } else { char actual[CAP]; u_austrcpy(actual, xrep.text); log_err("FAIL: utrans_trans(%s) x %s -> %s, expected %s\n", id, cfrom, actual, cto); } FreeXReplaceable(&xrep); /* utrans_transIncremental() */ InitXReplaceable(&xrep, cfrom); pos.start = pos.contextStart = 0; pos.limit = pos.contextLimit = u_strlen(from); utrans_transIncremental(trans, (UReplaceable*)xrepPtr, &xrepVtable, &pos, &status); utrans_trans(trans, (UReplaceable*)xrepPtr, &xrepVtable, pos.start, &pos.limit, &status); if (U_FAILURE(status)) { log_err("FAIL: utrans_transIncremental() failed, error=%s\n", u_errorName(status)); FreeXReplaceable(&xrep); return; } if (0 == u_strcmp(xrep.text, to)) { log_verbose("Ok: utrans_transIncremental(%s) x %s -> %s\n", id, cfrom, cto); } else { char actual[CAP]; u_austrcpy(actual, xrep.text); log_err("FAIL: utrans_transIncremental(%s) x %s -> %s, expected %s\n", id, cfrom, actual, cto); } FreeXReplaceable(&xrep); }