U_CAPI int32_t U_EXPORT2 /* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */ u_file_read( UChar *chars, int32_t count, UFILE *f) { int32_t dataSize; int32_t read; /* fill the buffer */ ufile_fill_uchar_buffer(f); /* determine the amount of data in the buffer */ dataSize = (int32_t)(f->fUCLimit - f->fUCPos); /* if the buffer contains the amount requested, just copy */ if(dataSize > count) { memcpy(chars, f->fUCPos, count * sizeof(UChar)); /* update the current buffer position */ f->fUCPos += count; /* return # of chars read */ return count; } /* otherwise, iteratively fill the buffer and copy */ read = 0; do { /* determine the amount of data in the buffer */ dataSize = (int32_t)(f->fUCLimit - f->fUCPos); /* copy the current data in the buffer */ memcpy(chars + read, f->fUCPos, dataSize * sizeof(UChar)); /* update number of items read */ read += dataSize; /* update the current buffer position */ f->fUCPos += dataSize; /* refill the buffer */ ufile_fill_uchar_buffer(f); } while(dataSize != 0 && read < count); return read; }
static int32_t u_scanf_integer_handler(UFILE *input, u_scanf_spec_info *info, ufmt_args *args, const UChar *fmt, int32_t *fmtConsumed, int32_t *argConverted) { int32_t len; void *num = (void*) (args[0].ptrValue); UNumberFormat *format; int32_t parsePos = 0; int32_t skipped; UErrorCode status = U_ZERO_ERROR; int64_t result; /* skip all ws in the input */ skipped = u_scanf_skip_leading_ws(input, info->fPadChar); /* fill the input's internal buffer */ ufile_fill_uchar_buffer(input); /* determine the size of the input's buffer */ len = (int32_t)(input->str.fLimit - input->str.fPos); /* truncate to the width, if specified */ if(info->fWidth != -1) len = ufmt_min(len, info->fWidth); /* get the formatter */ format = u_locbund_getNumberFormat(&input->str.fBundle, UNUM_DECIMAL); /* handle error */ if(format == 0) return 0; /* Skip the positive prefix. ICU normally can't handle this due to strict parsing. */ skipped += u_scanf_skip_leading_positive_sign(input, format, &status); /* parse the number */ result = unum_parseInt64(format, input->str.fPos, len, &parsePos, &status); /* mask off any necessary bits */ if (!info->fSkipArg) { if (info->fIsShort) *(int16_t*)num = (int16_t)(UINT16_MAX & result); else if (info->fIsLongLong) *(int64_t*)num = result; else *(int32_t*)num = (int32_t)(UINT32_MAX & result); } /* update the input's position to reflect consumed data */ input->str.fPos += parsePos; /* we converted 1 arg */ *argConverted = !info->fSkipArg; return parsePos + skipped; }
U_CFUNC UBool U_EXPORT2 ufile_getch32(UFILE *f, UChar32 *c32) { UBool isValidChar = FALSE; u_localized_string *str; *c32 = U_EOF; /* Fill the buffer if it is empty */ str = &f->str; if (f && str->fPos + 1 >= str->fLimit) { ufile_fill_uchar_buffer(f); } /* Get the next character in the buffer */ if (str->fPos < str->fLimit) { *c32 = *(str->fPos)++; if (U_IS_LEAD(*c32)) { if (str->fPos < str->fLimit) { UChar c16 = *(str->fPos)++; *c32 = U16_GET_SUPPLEMENTARY(*c32, c16); isValidChar = TRUE; } else { *c32 = U_EOF; } } else { isValidChar = TRUE; } } return isValidChar; }
static int32_t u_scanf_spellout_handler(UFILE *input, u_scanf_spec_info *info, ufmt_args *args, const UChar *fmt, int32_t *fmtConsumed, int32_t *argConverted) { int32_t len; double num; UNumberFormat *format; int32_t parsePos = 0; int32_t skipped; UErrorCode status = U_ZERO_ERROR; /* skip all ws in the input */ skipped = u_scanf_skip_leading_ws(input, info->fPadChar); /* fill the input's internal buffer */ ufile_fill_uchar_buffer(input); /* determine the size of the input's buffer */ len = (int32_t)(input->str.fLimit - input->str.fPos); /* truncate to the width, if specified */ if(info->fWidth != -1) len = ufmt_min(len, info->fWidth); /* get the formatter */ format = u_locbund_getNumberFormat(&input->str.fBundle, UNUM_SPELLOUT); /* handle error */ if(format == 0) return 0; /* Skip the positive prefix. ICU normally can't handle this due to strict parsing. */ /* This is not applicable to RBNF. */ /*skipped += u_scanf_skip_leading_positive_sign(input, format, &status);*/ /* parse the number */ num = unum_parseDouble(format, input->str.fPos, len, &parsePos, &status); if (!info->fSkipArg) { *(double*)(args[0].ptrValue) = num; } /* mask off any necessary bits */ /* if(! info->fIsLong_double) num &= DBL_MAX;*/ /* update the input's position to reflect consumed data */ input->str.fPos += parsePos; /* we converted 1 arg */ *argConverted = !info->fSkipArg; return parsePos + skipped; }
/* Read a UChar from a UFILE and process escape sequences */ U_CAPI UChar32 U_EXPORT2 /* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */ u_fgetcx(UFILE *f) { int32_t length; int32_t offset; UChar32 c32; UChar c16; /* Fill the buffer if it is empty */ if (f->fUCPos >= f->fUCLimit) { ufile_fill_uchar_buffer(f); } /* Get the next character in the buffer */ if (f->fUCPos < f->fUCLimit) { c16 = *(f->fUCPos)++; } else { c16 = U_EOF; } /* If it isn't a backslash, return it */ if (c16 != 0x005C /*'\\'*/) { return c16; } /* Determine the amount of data in the buffer */ length = (int32_t)(f->fUCLimit - f->fUCPos); /* The longest escape sequence is \Uhhhhhhhh; make sure we have at least that many characters */ if (length < 10) { /* fill the buffer */ ufile_fill_uchar_buffer(f); length = (int32_t)(f->fUCLimit - f->fUCPos); } /* Process the escape */ offset = 0; c32 = u_unescapeAt(_charAt, &offset, length, (void*)f); /* Update the current buffer position */ f->fUCPos += offset; return c32; }
static int32_t u_scanf_hex_handler(UFILE *input, u_scanf_spec_info *info, ufmt_args *args, const UChar *fmt, int32_t *fmtConsumed, int32_t *argConverted) { int32_t len; int32_t skipped; void *num = (void*) (args[0].ptrValue); int64_t result; /* skip all ws in the input */ skipped = u_scanf_skip_leading_ws(input, info->fPadChar); /* fill the input's internal buffer */ ufile_fill_uchar_buffer(input); /* determine the size of the input's buffer */ len = (int32_t)(input->str.fLimit - input->str.fPos); /* truncate to the width, if specified */ if(info->fWidth != -1) len = ufmt_min(len, info->fWidth); /* check for alternate form */ if( *(input->str.fPos) == 0x0030 && (*(input->str.fPos + 1) == 0x0078 || *(input->str.fPos + 1) == 0x0058) ) { /* skip the '0' and 'x' or 'X' if present */ input->str.fPos += 2; len -= 2; } /* parse the number */ result = ufmt_uto64(input->str.fPos, &len, 16); /* update the input's position to reflect consumed data */ input->str.fPos += len; /* mask off any necessary bits */ if (!info->fSkipArg) { if (info->fIsShort) *(int16_t*)num = (int16_t)(UINT16_MAX & result); else if (info->fIsLongLong) *(int64_t*)num = result; else *(int32_t*)num = (int32_t)(UINT32_MAX & result); } /* we converted 1 arg */ *argConverted = !info->fSkipArg; return len + skipped; }
U_CAPI UChar U_EXPORT2 /* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */ u_fgetc(UFILE *f) { /* if we have an available character in the buffer, return it */ if(f->fUCPos < f->fUCLimit) return *(f->fUCPos)++; /* otherwise, fill the buffer and return the next character */ else { ufile_fill_uchar_buffer(f); if(f->fUCPos < f->fUCLimit) return *(f->fUCPos)++; else return 0xFFFF; } }
static int32_t u_scanf_pointer_handler(UFILE *input, u_scanf_spec_info *info, ufmt_args *args, const UChar *fmt, int32_t *fmtConsumed, int32_t *argConverted) { int32_t len; int32_t skipped; void *result; void **p = (void**)(args[0].ptrValue); /* skip all ws in the input */ skipped = u_scanf_skip_leading_ws(input, info->fPadChar); /* fill the input's internal buffer */ ufile_fill_uchar_buffer(input); /* determine the size of the input's buffer */ len = (int32_t)(input->str.fLimit - input->str.fPos); /* truncate to the width, if specified */ if(info->fWidth != -1) { len = ufmt_min(len, info->fWidth); } /* Make sure that we don't consume too much */ if (len > (int32_t)(sizeof(void*)*2)) { len = (int32_t)(sizeof(void*)*2); } /* parse the pointer - assign to temporary value */ result = ufmt_utop(input->str.fPos, &len); if (!info->fSkipArg) { *p = result; } /* update the input's position to reflect consumed data */ input->str.fPos += len; /* we converted 1 arg */ *argConverted = !info->fSkipArg; return len + skipped; }
U_CFUNC UBool U_EXPORT2 ufile_getch(UFILE *f, UChar *ch) { UBool isValidChar = FALSE; *ch = U_EOF; /* if we have an available character in the buffer, return it */ if(f->str.fPos < f->str.fLimit) { *ch = *(f->str.fPos)++; isValidChar = TRUE; } else { /* otherwise, fill the buffer and return the next character */ if(f->str.fPos >= f->str.fLimit) { ufile_fill_uchar_buffer(f); } if(f->str.fPos < f->str.fLimit) { *ch = *(f->str.fPos)++; isValidChar = TRUE; } } return isValidChar; }
U_CAPI int32_t U_EXPORT2 /* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */ u_file_read( UChar *chars, int32_t count, UFILE *f) { int32_t dataSize; int32_t read = 0; u_localized_string *str = &f->str; do { /* determine the amount of data in the buffer */ dataSize = (int32_t)(str->fLimit - str->fPos); if (dataSize <= 0) { /* fill the buffer */ ufile_fill_uchar_buffer(f); dataSize = (int32_t)(str->fLimit - str->fPos); } /* Make sure that we don't read too much */ if (dataSize > (count - read)) { dataSize = count - read; } /* copy the current data in the buffer */ memcpy(chars + read, str->fPos, dataSize * sizeof(UChar)); /* update number of items read */ read += dataSize; /* update the current buffer position */ str->fPos += dataSize; } while (dataSize != 0 && read < count); return read; }
U_CAPI UChar* U_EXPORT2 /* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */ u_fgets(UFILE *f, int32_t n, UChar *s) { int32_t dataSize; int32_t count; UChar *alias; UChar *limit; UChar *sItr; if (n <= 0) { /* Caller screwed up. We need to write the null terminatior. */ return NULL; } /* fill the buffer if needed */ if (f->fUCPos >= f->fUCLimit) { ufile_fill_uchar_buffer(f); } /* subtract 1 from n to compensate for the terminator */ --n; /* determine the amount of data in the buffer */ dataSize = (int32_t)(f->fUCLimit - f->fUCPos); /* if 0 characters were left, return 0 */ if (dataSize == 0) return NULL; /* otherwise, iteratively fill the buffer and copy */ count = 0; sItr = s; while (dataSize > 0 && count < n) { alias = f->fUCPos; /* Find how much to copy */ if (dataSize < n) { limit = f->fUCLimit; } else { limit = alias + n; } /* Copy UChars until we find the first occurrence of a delimiter character */ while (alias < limit && !IS_STRING_DELIMITER(*alias)) { count++; *(sItr++) = *(alias++); } /* Preserve the newline */ if (alias < limit && IS_STRING_DELIMITER(*alias)) { count++; *(sItr++) = *(alias++); } /* update the current buffer position */ f->fUCPos = alias; /* if we found a delimiter */ if (alias < f->fUCLimit) { /* break out */ break; } /* refill the buffer */ ufile_fill_uchar_buffer(f); /* determine the amount of data in the buffer */ dataSize = (int32_t)(f->fUCLimit - f->fUCPos); } /* add the terminator and return s */ *sItr = 0x0000; return s; }
U_CAPI UChar* U_EXPORT2 /* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */ u_fgets(UChar *s, int32_t n, UFILE *f) { int32_t dataSize; int32_t count; UChar *alias; const UChar *limit; UChar *sItr; UChar currDelim = 0; u_localized_string *str; if (n <= 0) { /* Caller screwed up. We need to write the null terminatior. */ return NULL; } /* fill the buffer if needed */ str = &f->str; if (str->fPos >= str->fLimit) { ufile_fill_uchar_buffer(f); } /* subtract 1 from n to compensate for the terminator */ --n; /* determine the amount of data in the buffer */ dataSize = (int32_t)(str->fLimit - str->fPos); /* if 0 characters were left, return 0 */ if (dataSize == 0) return NULL; /* otherwise, iteratively fill the buffer and copy */ count = 0; sItr = s; currDelim = 0; while (dataSize > 0 && count < n) { alias = str->fPos; /* Find how much to copy */ if (dataSize < (n - count)) { limit = str->fLimit; } else { limit = alias + (n - count); } if (!currDelim) { /* Copy UChars until we find the first occurrence of a delimiter character */ while (alias < limit && !IS_FIRST_STRING_DELIMITER(*alias)) { count++; *(sItr++) = *(alias++); } /* Preserve the newline */ if (alias < limit && IS_FIRST_STRING_DELIMITER(*alias)) { if (CAN_HAVE_COMBINED_STRING_DELIMITER(*alias)) { currDelim = *alias; } else { currDelim = 1; /* This isn't a newline, but it's used to say that we should break later. We've checked all possible newline combinations even across buffer boundaries. */ } count++; *(sItr++) = *(alias++); } } /* If we have a CRLF combination, preserve that too. */ if (alias < limit) { if (currDelim && IS_COMBINED_STRING_DELIMITER(currDelim, *alias)) { count++; *(sItr++) = *(alias++); } currDelim = 1; /* This isn't a newline, but it's used to say that we should break later. We've checked all possible newline combinations even across buffer boundaries. */ } /* update the current buffer position */ str->fPos = alias; /* if we found a delimiter */ if (currDelim == 1) { /* break out */ break; } /* refill the buffer */ ufile_fill_uchar_buffer(f); /* determine the amount of data in the buffer */ dataSize = (int32_t)(str->fLimit - str->fPos); } /* add the terminator and return s */ *sItr = 0x0000; return s; }
static int32_t u_scanf_scidbl_handler(UFILE *input, u_scanf_spec_info *info, ufmt_args *args, const UChar *fmt, int32_t *fmtConsumed, int32_t *argConverted) { int32_t len; double num; UNumberFormat *scientificFormat, *genericFormat; /*int32_t scientificResult, genericResult;*/ double scientificResult, genericResult; int32_t scientificParsePos = 0, genericParsePos = 0, parsePos = 0; int32_t skipped; UErrorCode scientificStatus = U_ZERO_ERROR; UErrorCode genericStatus = U_ZERO_ERROR; /* since we can't determine by scanning the characters whether */ /* a number was formatted in the 'f' or 'g' styles, parse the */ /* string with both formatters, and assume whichever one */ /* parsed the most is the correct formatter to use */ /* skip all ws in the input */ skipped = u_scanf_skip_leading_ws(input, info->fPadChar); /* fill the input's internal buffer */ ufile_fill_uchar_buffer(input); /* determine the size of the input's buffer */ len = (int32_t)(input->str.fLimit - input->str.fPos); /* truncate to the width, if specified */ if(info->fWidth != -1) len = ufmt_min(len, info->fWidth); /* get the formatters */ scientificFormat = u_locbund_getNumberFormat(&input->str.fBundle, UNUM_SCIENTIFIC); genericFormat = u_locbund_getNumberFormat(&input->str.fBundle, UNUM_DECIMAL); /* handle error */ if(scientificFormat == 0 || genericFormat == 0) return 0; /* Skip the positive prefix. ICU normally can't handle this due to strict parsing. */ skipped += u_scanf_skip_leading_positive_sign(input, genericFormat, &genericStatus); /* parse the number using each format*/ scientificResult = unum_parseDouble(scientificFormat, input->str.fPos, len, &scientificParsePos, &scientificStatus); genericResult = unum_parseDouble(genericFormat, input->str.fPos, len, &genericParsePos, &genericStatus); /* determine which parse made it farther */ if(scientificParsePos > genericParsePos) { /* stash the result in num */ num = scientificResult; /* update the input's position to reflect consumed data */ parsePos += scientificParsePos; } else { /* stash the result in num */ num = genericResult; /* update the input's position to reflect consumed data */ parsePos += genericParsePos; } input->str.fPos += parsePos; if (!info->fSkipArg) { if (info->fIsLong) *(double*)(args[0].ptrValue) = num; else if (info->fIsLongDouble) *(long double*)(args[0].ptrValue) = num; else *(float*)(args[0].ptrValue) = (float)num; } /* mask off any necessary bits */ /* if(! info->fIsLong_double) num &= DBL_MAX;*/ /* we converted 1 arg */ *argConverted = !info->fSkipArg; return parsePos + skipped; }
static int32_t u_scanf_scientific_handler(UFILE *input, u_scanf_spec_info *info, ufmt_args *args, const UChar *fmt, int32_t *fmtConsumed, int32_t *argConverted) { int32_t len; double num; UNumberFormat *format; int32_t parsePos = 0; int32_t skipped; UErrorCode status = U_ZERO_ERROR; UChar srcExpBuf[UPRINTF_SYMBOL_BUFFER_SIZE]; int32_t srcLen, expLen; UChar expBuf[UPRINTF_SYMBOL_BUFFER_SIZE]; /* skip all ws in the input */ skipped = u_scanf_skip_leading_ws(input, info->fPadChar); /* fill the input's internal buffer */ ufile_fill_uchar_buffer(input); /* determine the size of the input's buffer */ len = (int32_t)(input->str.fLimit - input->str.fPos); /* truncate to the width, if specified */ if(info->fWidth != -1) len = ufmt_min(len, info->fWidth); /* get the formatter */ format = u_locbund_getNumberFormat(&input->str.fBundle, UNUM_SCIENTIFIC); /* handle error */ if(format == 0) return 0; /* set the appropriate flags on the formatter */ srcLen = unum_getSymbol(format, UNUM_EXPONENTIAL_SYMBOL, srcExpBuf, sizeof(srcExpBuf), &status); /* Upper/lower case the e */ if (info->fSpec == (UChar)0x65 /* e */) { expLen = u_strToLower(expBuf, (int32_t)sizeof(expBuf), srcExpBuf, srcLen, input->str.fBundle.fLocale, &status); } else { expLen = u_strToUpper(expBuf, (int32_t)sizeof(expBuf), srcExpBuf, srcLen, input->str.fBundle.fLocale, &status); } unum_setSymbol(format, UNUM_EXPONENTIAL_SYMBOL, expBuf, expLen, &status); /* Skip the positive prefix. ICU normally can't handle this due to strict parsing. */ skipped += u_scanf_skip_leading_positive_sign(input, format, &status); /* parse the number */ num = unum_parseDouble(format, input->str.fPos, len, &parsePos, &status); if (!info->fSkipArg) { if (info->fIsLong) *(double*)(args[0].ptrValue) = num; else if (info->fIsLongDouble) *(long double*)(args[0].ptrValue) = num; else *(float*)(args[0].ptrValue) = (float)num; } /* mask off any necessary bits */ /* if(! info->fIsLong_double) num &= DBL_MAX;*/ /* update the input's position to reflect consumed data */ input->str.fPos += parsePos; /* we converted 1 arg */ *argConverted = !info->fSkipArg; return parsePos + skipped; }