//============================================================================ // NDataEncoder::Hex_Decode : Decode from hex. //---------------------------------------------------------------------------- NData NDataEncoder::Hex_Decode(const NString &theValue) { NIndex n, theSize; NData theResult; uint8_t *dataPtr; const char *textPtr; unsigned int byteVal; // Validate our parameters NN_ASSERT(theValue.IsEmpty() || (theValue.GetSize() % 2) == 0); // Get the state we need theSize = theValue.GetSize() / 2; dataPtr = theResult.AppendData(theSize); textPtr = theValue.GetUTF8(); if (theSize == 0 || dataPtr == NULL || textPtr == NULL) return(theResult); // Convert the string // // Visual Studio does not support 'hh' correctly, so we need to read byte // values into a temporary variable: // // https://connect.microsoft.com/VisualStudio/feedback/details/416843/sscanf-cannot-not-handle-hhd-format for (n = 0; n < theSize; n++) { sscanf(textPtr, "%2x", &byteVal); NN_ASSERT((byteVal & 0xFFFFFF00) == 0); dataPtr[n] = (uint8_t) byteVal; textPtr += 2; } return(theResult); }
//============================================================================ // NNumber::SetValue : Set the value. //---------------------------------------------------------------------------- bool NNumber::SetValue(const NString &theValue) { NRange foundDot, foundE; NIndex thePrecision; int64_t valueInteger; float64_t valueReal; // Parse the value // // Some integers will also pass parsing as floats, however we coerce these // back to integers when possible to allow us to use more tightly packed // types for storage in the future. if (sscanf(theValue.GetUTF8(), "%lf", &valueReal) == 1) { // Get the state we need foundDot = theValue.Find("."); foundE = theValue.Find("e", kNStringNoCase); if (foundDot.IsEmpty() || !foundE.IsEmpty()) thePrecision = kDecimalsFloat64; else thePrecision = theValue.GetSize() - foundDot.GetNext(); // Cast the value if (foundDot.IsEmpty() && foundE.IsEmpty() && valueReal >= kInt64Min && valueReal <= kInt64Max) SetInt64((int64_t) valueReal); else if (thePrecision <= kDecimalsFloat32 && valueReal >= kFloat32Min && valueReal <= kFloat32Max) SetFloat32((float32_t) valueReal); else SetFloat64(valueReal); return(true); } else if (sscanf(theValue.GetUTF8(), "%lld", &valueInteger) == 1 || sscanf(theValue.GetUTF8(), "%llx", &valueInteger) == 1 || sscanf(theValue.GetUTF8(), "0x%llx", &valueInteger) == 1 || sscanf(theValue.GetUTF8(), "0X%llx", &valueInteger) == 1) { SetInt64(valueInteger); return(true); } return(false); }