/** * Performs a mathematical operation on the number, formats it using * either ruleSet or decimalFormat, and inserts the result into * toInsertInto. * @param number The number being formatted. * @param toInsertInto The string we insert the result into * @param pos The position in toInsertInto where the owning rule's * rule text begins (this value is added to this substitution's * position to determine exactly where to insert the new text) */ void NFSubstitution::doSubstitution(int64_t number, UnicodeString& toInsertInto, int32_t _pos) const { if (ruleSet != NULL) { // perform a transformation on the number that is dependent // on the type of substitution this is, then just call its // rule set's format() method to format the result ruleSet->format(transformNumber(number), toInsertInto, _pos + this->pos); } else if (numberFormat != NULL) { // or perform the transformation on the number (preserving // the result's fractional part if the formatter it set // to show it), then use that formatter's format() method // to format the result double numberToFormat = transformNumber((double)number); if (numberFormat->getMaximumFractionDigits() == 0) { numberToFormat = uprv_floor(numberToFormat); } UnicodeString temp; numberFormat->format(numberToFormat, temp); toInsertInto.insert(_pos + this->pos, temp); } }
/** * If this is a >>> substitution, use ruleToUse to fill in * the substitution. Otherwise, just use the superclass function. * @param number The number being formatted * @toInsertInto The string to insert the result of this substitution * into * @param pos The position of the rule text in toInsertInto */ void ModulusSubstitution::doSubstitution(int64_t number, UnicodeString& toInsertInto, int32_t _pos) const { // if this isn't a >>> substitution, just use the inherited version // of this function (which uses either a rule set or a DecimalFormat // to format its substitution value) if (ruleToUse == NULL) { NFSubstitution::doSubstitution(number, toInsertInto, _pos); // a >>> substitution goes straight to a particular rule to // format the substitution value } else { int64_t numberToFormat = transformNumber(number); ruleToUse->doFormat(numberToFormat, toInsertInto, _pos + getPos()); } }
void NumeratorSubstitution::doSubstitution(double number, UnicodeString& toInsertInto, int32_t apos) const { // perform a transformation on the number being formatted that // is dependent on the type of substitution this is double numberToFormat = transformNumber(number); int64_t longNF = util64_fromDouble(numberToFormat); const NFRuleSet* aruleSet = getRuleSet(); if (withZeros && aruleSet != NULL) { // if there are leading zeros in the decimal expansion then emit them int64_t nf =longNF; int32_t len = toInsertInto.length(); while ((nf *= 10) < denominator) { toInsertInto.insert(apos + getPos(), gSpace); aruleSet->format((int64_t)0, toInsertInto, apos + getPos()); } apos += toInsertInto.length() - len; } // if the result is an integer, from here on out we work in integer // space (saving time and memory and preserving accuracy) if (numberToFormat == longNF && aruleSet != NULL) { aruleSet->format(longNF, toInsertInto, apos + getPos()); // if the result isn't an integer, then call either our rule set's // format() method or our DecimalFormat's format() method to // format the result } else { if (aruleSet != NULL) { aruleSet->format(numberToFormat, toInsertInto, apos + getPos()); } else { UErrorCode status = U_ZERO_ERROR; UnicodeString temp; getNumberFormat()->format(numberToFormat, temp, status); toInsertInto.insert(apos + getPos(), temp); } } }
/** * Parse parameter as number, number with unit or special value (min, max, default, ...) * @param context * @param value return value * @param mandatory if the parameter is mandatory * @return */ scpi_bool_t SCPIParser::SCPI_ParamNumber(scpi_number_t * value, scpi_bool_t mandatory) { scpi_bool_t result; const char * param; size_t len; size_t numlen; /* read parameter and shift to the next one */ result = SCPI_ParamString(¶m, &len, mandatory); /* value not initializes */ if (!value) { return FALSE; } value->type = SCPI_NUM_DEF; /* if parameter was not found, return TRUE or FALSE according * to fact that parameter was mandatory or not */ if (!result) { return mandatory ? FALSE : TRUE; } /* convert string to special number type */ if (translateSpecialNumber(context.special_numbers, param, len, value)) { /* found special type */ return TRUE; } /* convert text from double - no special type */ numlen = strToDouble(param, &value->value); /* transform units of value */ if (numlen <= len) { return transformNumber(param + numlen, len - numlen, value); } return FALSE; }
/** * Performs a mathematical operation on the number, formats it using * either ruleSet or decimalFormat, and inserts the result into * toInsertInto. * @param number The number being formatted. * @param toInsertInto The string we insert the result into * @param pos The position in toInsertInto where the owning rule's * rule text begins (this value is added to this substitution's * position to determine exactly where to insert the new text) */ void NFSubstitution::doSubstitution(double number, UnicodeString& toInsertInto, int32_t _pos) const { // perform a transformation on the number being formatted that // is dependent on the type of substitution this is double numberToFormat = transformNumber(number); // if the result is an integer, from here on out we work in integer // space (saving time and memory and preserving accuracy) if (numberToFormat == uprv_floor(numberToFormat) && ruleSet != NULL) { ruleSet->format(util64_fromDouble(numberToFormat), toInsertInto, _pos + this->pos); // if the result isn't an integer, then call either our rule set's // format() method or our DecimalFormat's format() method to // format the result } else { if (ruleSet != NULL) { ruleSet->format(numberToFormat, toInsertInto, _pos + this->pos); } else if (numberFormat != NULL) { UnicodeString temp; numberFormat->format(numberToFormat, temp); toInsertInto.insert(_pos + this->pos, temp); } } }
/** * Parse parameter as number, number with unit or special value (min, max, default, ...) * @param context * @param value return value * @param mandatory if the parameter is mandatory * @return */ scpi_bool_t SCPI_ParamNumber(scpi_t * context, const scpi_choice_def_t * special, scpi_number_t * value, scpi_bool_t mandatory) { scpi_token_t token; lex_state_t state; scpi_parameter_t param; scpi_bool_t result; int32_t tag; if (!value) { SCPI_ErrorPush(context, SCPI_ERROR_SYSTEM_ERROR); return FALSE; } result = SCPI_Parameter(context, ¶m, mandatory); if (!result) { return result; } state.buffer = param.ptr; state.pos = state.buffer; state.len = param.len; switch(param.type) { case SCPI_TOKEN_DECIMAL_NUMERIC_PROGRAM_DATA: case SCPI_TOKEN_HEXNUM: case SCPI_TOKEN_OCTNUM: case SCPI_TOKEN_BINNUM: case SCPI_TOKEN_DECIMAL_NUMERIC_PROGRAM_DATA_WITH_SUFFIX: case SCPI_TOKEN_PROGRAM_MNEMONIC: value->unit = SCPI_UNIT_NONE; value->special = FALSE; result = TRUE; break; } switch(param.type) { case SCPI_TOKEN_DECIMAL_NUMERIC_PROGRAM_DATA: case SCPI_TOKEN_DECIMAL_NUMERIC_PROGRAM_DATA_WITH_SUFFIX: case SCPI_TOKEN_PROGRAM_MNEMONIC: value->base = 10; break; case SCPI_TOKEN_BINNUM: value->base = 2; break; case SCPI_TOKEN_HEXNUM: value->base = 16; break; case SCPI_TOKEN_OCTNUM: value->base = 8; break; } switch(param.type) { case SCPI_TOKEN_DECIMAL_NUMERIC_PROGRAM_DATA: SCPI_ParamToDouble(context, ¶m, &(value->value)); break; case SCPI_TOKEN_HEXNUM: SCPI_ParamToDouble(context, ¶m, &(value->value)); break; case SCPI_TOKEN_OCTNUM: SCPI_ParamToDouble(context, ¶m, &(value->value)); break; case SCPI_TOKEN_BINNUM: SCPI_ParamToDouble(context, ¶m, &(value->value)); break; case SCPI_TOKEN_DECIMAL_NUMERIC_PROGRAM_DATA_WITH_SUFFIX: scpiLex_DecimalNumericProgramData(&state, &token); scpiLex_WhiteSpace(&state, &token); scpiLex_SuffixProgramData(&state, &token); SCPI_ParamToDouble(context, ¶m, &(value->value)); result = transformNumber(context, token.ptr, token.len, value); break; case SCPI_TOKEN_PROGRAM_MNEMONIC: scpiLex_WhiteSpace(&state, &token); scpiLex_CharacterProgramData(&state, &token); /* convert string to special number type */ SCPI_ParamToChoice(context, &token, special, &tag); value->special = TRUE; value->tag = tag; break; default: result = FALSE; } return result; }