typedefstruct {
char16_t contextCharToUnicode; /* previous Unicode codepoint for contextual analysis */
char16_t contextCharFromUnicode; /* previous Unicode codepoint for contextual analysis */
uint16_t defDeltaToUnicode; /* delta for switching to default state when DEF is encountered */
uint16_t currentDeltaFromUnicode; /* current delta in Indic block */
uint16_t currentDeltaToUnicode; /* current delta in Indic block */
MaskEnum currentMaskFromUnicode; /* mask for current state in toUnicode */
MaskEnum currentMaskToUnicode; /* mask for current state in toUnicode */
MaskEnum defMaskToUnicode; /* mask for default state in toUnicode */
UBool isFirstBuffer; /* boolean for fromUnicode to see if we need to announce the first script */
UBool resetToDefaultToUnicode; /* boolean for resetting to default delta and mask when a newline is encountered*/ char name[sizeof(ISCII_CNV_PREFIX) + 1];
UChar32 prevToUnicodeStatus; /* Hold the previous toUnicodeStatus. This is necessary because we may need to know the last two code points. */
} UConverterDataISCII;
if ((args->converter == nullptr) || (args->targetLimit < args->target) || (args->sourceLimit < args->source)) {
*err = U_ILLEGAL_ARGUMENT_ERROR; return;
} /* initialize data */
converterData=(UConverterDataISCII*)args->converter->extraInfo;
newDelta=converterData->currentDeltaFromUnicode;
range = (uint16_t)(newDelta/DELTA);
if ((sourceChar = args->converter->fromUChar32)!=0) { goto getTrail;
}
/*writing the char to the output stream */ while (source < sourceLimit) { /* Write the language code following LF only if LF is not the last character. */ if (args->converter->fromUnicodeStatus == LF) {
targetByteUnit = ATR<<8;
targetByteUnit += (uint8_t) lookupInitialData[range].isciiLang;
args->converter->fromUnicodeStatus = 0x0000; /* now append ATR and language code */
WRITE_TO_TARGET_FROM_U(args,offsets,source,target,targetLimit,targetByteUnit,err); if (U_FAILURE(*err)) { break;
}
}
/*check if input is in ASCII and C0 control codes range*/ if (sourceChar <= ASCII_END) {
args->converter->fromUnicodeStatus = sourceChar;
WRITE_TO_TARGET_FROM_U(args,offsets,source,target,targetLimit,sourceChar,err); if (U_FAILURE(*err)) { break;
} continue;
} switch (sourceChar) { case ZWNJ: /* contextChar has HALANT */ if (converterData->contextCharFromUnicode) {
converterData->contextCharFromUnicode = 0x00;
targetByteUnit = ISCII_HALANT;
} else { /* consume ZWNJ and continue */
converterData->contextCharFromUnicode = 0x00; continue;
} break; case ZWJ: /* contextChar has HALANT */ if (converterData->contextCharFromUnicode) {
targetByteUnit = ISCII_NUKTA;
} else {
targetByteUnit =ISCII_INV;
}
converterData->contextCharFromUnicode = 0x00; break; default: /* is the sourceChar in the INDIC_RANGE? */ if ((uint16_t)(INDIC_BLOCK_END-sourceChar) <= INDIC_RANGE) { /* Danda and Double Danda are valid in Northern scripts.. since Unicode *doesnotincludethesecodepointsinallNorthernscripsweneedto *filterthemout
*/ if (sourceChar!= DANDA && sourceChar != DOUBLE_DANDA) { /* find out to which block the souceChar belongs*/
range =(uint16_t)((sourceChar-INDIC_BLOCK_BEGIN)/DELTA);
newDelta =(uint16_t)(range*DELTA);
/* Now are we in the same block as the previous? */ if (newDelta!= converterData->currentDeltaFromUnicode || converterData->isFirstBuffer) {
converterData->currentDeltaFromUnicode = newDelta;
converterData->currentMaskFromUnicode = lookupInitialData[range].maskEnum;
deltaChanged =true;
converterData->isFirstBuffer=false;
}
if (converterData->currentDeltaFromUnicode == PNJ_DELTA) { if (sourceChar == PNJ_TIPPI) { /* Make sure Tippi is converted to Bindi. */
sourceChar = PNJ_BINDI;
} elseif (sourceChar == PNJ_ADHAK) { /* This is for consonant cluster handling. */
converterData->contextCharFromUnicode = PNJ_ADHAK;
}
} /* Normalize all Indic codepoints to Devanagari and map them to ISCII */ /* now subtract the new delta from sourceChar*/
sourceChar -= converterData->currentDeltaFromUnicode;
}
/* get the target byte unit */
targetByteUnit=fromUnicodeTable[(uint8_t)sourceChar];
/* is the code point valid in current script? */ if ((validityTable[(uint8_t)sourceChar] & converterData->currentMaskFromUnicode)==0) { /* Vocallic RR is assigned in ISCII Telugu and Unicode */ if (converterData->currentDeltaFromUnicode!=(TELUGU_DELTA) || sourceChar!=VOCALLIC_RR) {
targetByteUnit=missingCharMarker;
}
}
if (deltaChanged) { /* we are in a script block which is different than *previoussourceChar'sscriptblockwriteATRandlanguagecodes
*/
uint32_t temp=0;
temp =(uint16_t)(ATR<<8);
temp += (uint16_t)((uint8_t) lookupInitialData[range].isciiLang); /* reset */
deltaChanged=false; /* now append ATR and language code */
WRITE_TO_TARGET_FROM_U(args,offsets,source,target,targetLimit,temp,err); if (U_FAILURE(*err)) { break;
}
}
if (converterData->currentDeltaFromUnicode == PNJ_DELTA && (sourceChar + PNJ_DELTA) == PNJ_ADHAK) { continue;
}
} /* reset context char */
converterData->contextCharFromUnicode = 0x00; break;
} if (converterData->currentDeltaFromUnicode == PNJ_DELTA && tempContextFromUnicode == PNJ_ADHAK && isPNJConsonant((sourceChar + PNJ_DELTA))) { /* If the previous codepoint is Adhak and the current codepoint is a consonant, the targetByteUnit should be C + Halant + C. */ /* reset context char */
converterData->contextCharFromUnicode = 0x0000;
targetByteUnit = targetByteUnit << 16 | ISCII_HALANT << 8 | targetByteUnit; /* write targetByteUnit to target */
WRITE_TO_TARGET_FROM_U(args, offsets, source, target, targetLimit, targetByteUnit,err); if (U_FAILURE(*err)) { break;
}
} elseif (targetByteUnit != missingCharMarker) { if (targetByteUnit==ISCII_HALANT) {
converterData->contextCharFromUnicode = (char16_t)targetByteUnit;
} /* write targetByteUnit to target*/
WRITE_TO_TARGET_FROM_U(args,offsets,source,target,targetLimit,targetByteUnit,err); if (U_FAILURE(*err)) { break;
}
} else { /* oops.. the code point is unassigned */ /*check if the char is a First surrogate*/ if (U16_IS_SURROGATE(sourceChar)) { if (U16_IS_SURROGATE_LEAD(sourceChar)) {
getTrail: /*look ahead to find the trail surrogate*/ if (source < sourceLimit) { /* test the following code unit */
char16_t trail= (*source); if (U16_IS_TRAIL(trail)) {
source++;
sourceChar=U16_GET_SUPPLEMENTARY(sourceChar, trail);
*err =U_INVALID_CHAR_FOUND; /* convert this surrogate code point */ /* exit this condition tree */
} else { /* this is an unmatched lead code unit (1st surrogate) */ /* callback(illegal) */
*err=U_ILLEGAL_CHAR_FOUND;
}
} else { /* no more input */
*err = U_ZERO_ERROR;
}
} else { /* this is an unmatched trail code unit (2nd surrogate) */ /* callback(illegal) */
*err=U_ILLEGAL_CHAR_FOUND;
}
} else { /* callback(unassigned) for a BMP code point */
*err = U_INVALID_CHAR_FOUND;
}
args->converter->fromUChar32=sourceChar; break;
}
}/* end while(mySourceIndex<mySourceLength) */
/*save the state and return */
args->source = source;
args->target = (char*)target;
}
data = (UConverterDataISCII*)(args->converter->extraInfo);
contextCharToUnicode = &data->contextCharToUnicode; /* contains previous ISCII codepoint visited */
toUnicodeStatus = (UChar32*)&args->converter->toUnicodeStatus;/* contains the mapping to Unicode of the above codepoint*/
while (U_SUCCESS(*err) && source<sourceLimit) {
targetUniChar = missingCharMarker;
if (target < targetLimit) {
sourceChar = (unsignedchar)*(source)++;
/* look at the post-context perform special processing */ if (*contextCharToUnicode==ATR) {
/* If we have ATR in *contextCharToUnicode then we need to change our *statetotheIndicScriptspecifiedbysourceChar
*/
/* check if the sourceChar is supported script range*/ if ((uint8_t)(PNJ-sourceChar)<=PNJ-DEV) {
data->currentDeltaToUnicode = (uint16_t)(lookupTable[sourceChar & 0x0F][0] * DELTA);
data->currentMaskToUnicode = (MaskEnum)lookupTable[sourceChar & 0x0F][1];
} elseif (sourceChar==DEF) { /* switch back to default */
data->currentDeltaToUnicode = data->defDeltaToUnicode;
data->currentMaskToUnicode = data->defMaskToUnicode;
} else { if ((sourceChar >= 0x21 && sourceChar <= 0x3F)) { /* these are display codes consume and continue */
} else {
*err =U_ILLEGAL_CHAR_FOUND; /* reset */
*contextCharToUnicode=NO_CHAR_MARKER; goto CALLBACK;
}
}
/* reset */
*contextCharToUnicode=NO_CHAR_MARKER;
continue;
} elseif (*contextCharToUnicode==EXT) { /* check if sourceChar is in 0xA1-0xEE range */ if ((uint8_t) (EXT_RANGE_END - sourceChar) <= (EXT_RANGE_END - EXT_RANGE_BEGIN)) { /* We currently support only Anudatta and Devanagari abbreviation sign */ if (sourceChar==0xBF || sourceChar == 0xB8) {
targetUniChar = (sourceChar==0xBF) ? DEV_ABBR_SIGN : DEV_ANUDATTA;
/* find out if the mapping is valid in this state */ if (validityTable[(uint8_t)targetUniChar] & data->currentMaskToUnicode) {
*contextCharToUnicode= NO_CHAR_MARKER;
/* Write the previous toUnicodeStatus, this was delayed to handle consonant clustering for Gurmukhi script. */ if (data->prevToUnicodeStatus) {
WRITE_TO_TARGET_TO_U(args,source,target,args->offsets,(source-args->source -1),data->prevToUnicodeStatus,0,err);
data->prevToUnicodeStatus = 0x0000;
} /* write to target */
WRITE_TO_TARGET_TO_U(args,source,target,args->offsets,(source-args->source -2),targetUniChar,data->currentDeltaToUnicode,err);
continue;
}
} /* byte unit is unassigned */
targetUniChar = missingCharMarker;
*err= U_INVALID_CHAR_FOUND;
} else { /* only 0xA1 - 0xEE are legal after EXT char */
*contextCharToUnicode= NO_CHAR_MARKER;
*err = U_ILLEGAL_CHAR_FOUND;
} goto CALLBACK;
} elseif (*contextCharToUnicode==ISCII_INV) { if (sourceChar==ISCII_HALANT) {
targetUniChar = 0x0020; /* replace with space according to Indic FAQ */
} else {
targetUniChar = ZWJ;
}
/* Write the previous toUnicodeStatus, this was delayed to handle consonant clustering for Gurmukhi script. */ if (data->prevToUnicodeStatus) {
WRITE_TO_TARGET_TO_U(args,source,target,args->offsets,(source-args->source -1),data->prevToUnicodeStatus,0,err);
data->prevToUnicodeStatus = 0x0000;
} /* write to target */
WRITE_TO_TARGET_TO_U(args,source,target,args->offsets,(source-args->source -2),targetUniChar,data->currentDeltaToUnicode,err); /* reset */
*contextCharToUnicode=NO_CHAR_MARKER;
}
/* look at the pre-context and perform special processing */ switch (sourceChar) { case ISCII_INV: case EXT: case ATR:
*contextCharToUnicode = (char16_t)sourceChar;
if (*toUnicodeStatus != missingCharMarker) { /* Write the previous toUnicodeStatus, this was delayed to handle consonant clustering for Gurmukhi script. */ if (data->prevToUnicodeStatus) {
WRITE_TO_TARGET_TO_U(args,source,target,args->offsets,(source-args->source -1),data->prevToUnicodeStatus,0,err);
data->prevToUnicodeStatus = 0x0000;
}
WRITE_TO_TARGET_TO_U(args,source,target,args->offsets,(source-args->source -2),*toUnicodeStatus,data->currentDeltaToUnicode,err);
*toUnicodeStatus = missingCharMarker;
} continue; case ISCII_DANDA: /* handle double danda*/ if (*contextCharToUnicode== ISCII_DANDA) {
targetUniChar = DOUBLE_DANDA; /* clear the context */
*contextCharToUnicode = NO_CHAR_MARKER;
*toUnicodeStatus = missingCharMarker;
} else {
GET_MAPPING(sourceChar,targetUniChar,data);
*contextCharToUnicode = sourceChar;
} break; case ISCII_HALANT: /* handle explicit halant */ if (*contextCharToUnicode == ISCII_HALANT) {
targetUniChar = ZWNJ; /* clear the context */
*contextCharToUnicode = NO_CHAR_MARKER;
} else {
GET_MAPPING(sourceChar,targetUniChar,data);
*contextCharToUnicode = sourceChar;
} break; case0x0A: case0x0D:
data->resetToDefaultToUnicode = true;
GET_MAPPING(sourceChar,targetUniChar,data)
;
*contextCharToUnicode = sourceChar; break;
case ISCII_VOWEL_SIGN_E:
i=1;
found=false; for (; i<vowelSignESpecialCases[0][0]; i++) {
U_ASSERT(i<UPRV_LENGTHOF(vowelSignESpecialCases)); if (vowelSignESpecialCases[i][0]==(uint8_t)*contextCharToUnicode) {
targetUniChar=vowelSignESpecialCases[i][1];
found=true; break;
}
} if (found) { /* find out if the mapping is valid in this state */ if (validityTable[(uint8_t)targetUniChar] & data->currentMaskToUnicode) { /*targetUniChar += data->currentDeltaToUnicode ;*/
*contextCharToUnicode= NO_CHAR_MARKER;
*toUnicodeStatus = missingCharMarker; break;
}
}
GET_MAPPING(sourceChar,targetUniChar,data);
*contextCharToUnicode = sourceChar; break;
case ISCII_NUKTA: /* handle soft halant */ if (*contextCharToUnicode == ISCII_HALANT) {
targetUniChar = ZWJ; /* clear the context */
*contextCharToUnicode = NO_CHAR_MARKER; break;
} elseif (data->currentDeltaToUnicode == PNJ_DELTA && data->contextCharToUnicode == 0xc0) { /* Write the previous toUnicodeStatus, this was delayed to handle consonant clustering for Gurmukhi script. */ if (data->prevToUnicodeStatus) {
WRITE_TO_TARGET_TO_U(args,source,target,args->offsets,(source-args->source -1),data->prevToUnicodeStatus,0,err);
data->prevToUnicodeStatus = 0x0000;
} /* We got here because ISCII_NUKTA was preceded by 0xc0 and we are converting Gurmukhi. *Inthatcasewemustconvert(0xc00xe9)to(\u0a5c\u0a4d\u0a39).
*/
targetUniChar = PNJ_RRA;
WRITE_TO_TARGET_TO_U(args, source, target, args->offsets, (source-args->source)-2, targetUniChar, 0, err); if (U_SUCCESS(*err)) {
targetUniChar = PNJ_SIGN_VIRAMA;
WRITE_TO_TARGET_TO_U(args, source, target, args->offsets, (source-args->source)-2, targetUniChar, 0, err); if (U_SUCCESS(*err)) {
targetUniChar = PNJ_HA;
WRITE_TO_TARGET_TO_U(args, source, target, args->offsets, (source-args->source)-2, targetUniChar, 0, err);
} else {
args->converter->UCharErrorBuffer[args->converter->UCharErrorBufferLength++]= PNJ_HA;
}
} else {
args->converter->UCharErrorBuffer[args->converter->UCharErrorBufferLength++]= PNJ_SIGN_VIRAMA;
args->converter->UCharErrorBuffer[args->converter->UCharErrorBufferLength++]= PNJ_HA;
}
*toUnicodeStatus = missingCharMarker;
data->contextCharToUnicode = NO_CHAR_MARKER; continue;
} else { /* try to handle <CHAR> + ISCII_NUKTA special mappings */
i=1;
found =false; for (; i<nuktaSpecialCases[0][0]; i++) { if (nuktaSpecialCases[i][0]==(uint8_t)
*contextCharToUnicode) {
targetUniChar=nuktaSpecialCases[i][1];
found =true; break;
}
} if (found) { /* find out if the mapping is valid in this state */ if (validityTable[(uint8_t)targetUniChar] & data->currentMaskToUnicode) { /*targetUniChar += data->currentDeltaToUnicode ;*/
*contextCharToUnicode= NO_CHAR_MARKER;
*toUnicodeStatus = missingCharMarker; if (data->currentDeltaToUnicode == PNJ_DELTA) { /* Write the previous toUnicodeStatus, this was delayed to handle consonant clustering for Gurmukhi script. */ if (data->prevToUnicodeStatus) {
WRITE_TO_TARGET_TO_U(args,source,target,args->offsets,(source-args->source -1),data->prevToUnicodeStatus,0,err);
data->prevToUnicodeStatus = 0x0000;
}
WRITE_TO_TARGET_TO_U(args,source,target,args->offsets,(source-args->source -2),targetUniChar,data->currentDeltaToUnicode,err); continue;
} break;
} /* else fall through to default */
} /* else fall through to default */
U_FALLTHROUGH;
} default:GET_MAPPING(sourceChar,targetUniChar,data)
;
*contextCharToUnicode = sourceChar; break;
}
if (*toUnicodeStatus != missingCharMarker) { /* Check to make sure that consonant clusters are handled correct for Gurmukhi script. */ if (data->currentDeltaToUnicode == PNJ_DELTA && data->prevToUnicodeStatus != 0 && isPNJConsonant(data->prevToUnicodeStatus) &&
(*toUnicodeStatus + PNJ_DELTA) == PNJ_SIGN_VIRAMA && ((UChar32)(targetUniChar + PNJ_DELTA) == data->prevToUnicodeStatus)) { /* Consonant clusters C + HALANT + C should be encoded as ADHAK + C */
offset = (int)(source-args->source - 3);
tempTargetUniChar = PNJ_ADHAK; /* This is necessary to avoid some compiler warnings. */
WRITE_TO_TARGET_TO_U(args,source,target,args->offsets,offset,tempTargetUniChar,0,err);
WRITE_TO_TARGET_TO_U(args,source,target,args->offsets,offset,data->prevToUnicodeStatus,0,err);
data->prevToUnicodeStatus = 0x0000; /* reset the previous unicode code point */
*toUnicodeStatus = missingCharMarker; continue;
} else { /* Write the previous toUnicodeStatus, this was delayed to handle consonant clustering for Gurmukhi script. */ if (data->prevToUnicodeStatus) {
WRITE_TO_TARGET_TO_U(args,source,target,args->offsets,(source-args->source -1),data->prevToUnicodeStatus,0,err);
data->prevToUnicodeStatus = 0x0000;
} /* Check to make sure that Bindi and Tippi are handled correctly for Gurmukhi script. *If0xA2isprecededbyacodepointinthePNJ_BINDI_TIPPI_SETthenthetargetcodepointshouldbeTippiinsteadofBindi.
*/ if (data->currentDeltaToUnicode == PNJ_DELTA && (targetUniChar + PNJ_DELTA) == PNJ_BINDI && isPNJBindiTippi((*toUnicodeStatus + PNJ_DELTA))) {
targetUniChar = PNJ_TIPPI - PNJ_DELTA;
WRITE_TO_TARGET_TO_U(args,source,target,args->offsets,(source-args->source -2),*toUnicodeStatus,PNJ_DELTA,err);
} elseif (data->currentDeltaToUnicode == PNJ_DELTA && (targetUniChar + PNJ_DELTA) == PNJ_SIGN_VIRAMA && isPNJConsonant((*toUnicodeStatus + PNJ_DELTA))) { /* Store the current toUnicodeStatus code point for later handling of consonant cluster in Gurmukhi. */
data->prevToUnicodeStatus = *toUnicodeStatus + PNJ_DELTA;
} else { /* write the previously mapped codepoint */
WRITE_TO_TARGET_TO_U(args,source,target,args->offsets,(source-args->source -2),*toUnicodeStatus,data->currentDeltaToUnicode,err);
}
}
*toUnicodeStatus = missingCharMarker;
}
if (targetUniChar != missingCharMarker) { /* now save the targetUniChar for delayed write */
*toUnicodeStatus = (char16_t) targetUniChar; if (data->resetToDefaultToUnicode) {
data->currentDeltaToUnicode = data->defDeltaToUnicode;
data->currentMaskToUnicode = data->defMaskToUnicode;
data->resetToDefaultToUnicode=false;
}
} else {
/* we reach here only if targetUniChar == missingCharMarker *soassigncodestoreasonanderr
*/
*err = U_INVALID_CHAR_FOUND;
CALLBACK:
args->converter->toUBytes[0] = sourceChar;
args->converter->toULength = 1; break;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.