//============================================================================ // 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); }
//============================================================================ // 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); }
//============================================================================ // NTargetNetwork::SocketOpen : Open a socket. //---------------------------------------------------------------------------- NSocketRef NTargetNetwork::SocketOpen(NSocket *nanoSocket, const NString &theHost, uint16_t thePort) { struct addrinfo *theAddress, *addrList; int sysErr, tmpSocket; NSocketRef theSocket; const char *hostName; struct addrinfo addrInfo; bool isListen; NString portNum; // Get the state we need isListen = theHost.IsEmpty(); theAddress = NULL; hostName = isListen ? NULL : theHost.GetUTF8(); portNum.Format("%d",thePort); // Create the address memset(&addrInfo, 0, sizeof(struct addrinfo)); addrInfo.ai_family = AF_UNSPEC; // Allow IPv4 or IPv6 addrInfo.ai_socktype = SOCK_STREAM; // Always TCP addrInfo.ai_flags = isListen ? AI_PASSIVE : 0; sysErr = getaddrinfo(hostName, portNum.GetUTF8(), &addrInfo, &addrList); NN_ASSERT_NOERR(sysErr); if (sysErr != 0) return(NULL); // Create the socket // // As we may have multiple addresses, we loop until we find one that we can connect/bind. for (theAddress = addrList; theAddress != NULL; theAddress = theAddress->ai_next) { tmpSocket = socket(theAddress->ai_family, theAddress->ai_socktype, theAddress->ai_protocol); if (tmpSocket == kSocketHandleInvalid) continue; if (isListen) { if (bind(tmpSocket, theAddress->ai_addr, theAddress->ai_addrlen) == 0) break; } else { if (connect(tmpSocket, theAddress->ai_addr, theAddress->ai_addrlen) == 0) break; } close(tmpSocket); } freeaddrinfo(addrList); NN_ASSERT(theAddress != NULL); if (theAddress == NULL) return(NULL); // Setup signal handler for closed sockets // // TO DO /* sa.sa_handler = sigchld_handler; sigemptyset(&sa.sa_mask); sa.sa_flags = SA_RESTART; NN_ASSERT(sigaction(SIGCHLD, &sa, NULL) != -1); */ // TODO Create thread for listening/accepting connections // Create the socket info theSocket = new NSocketInfo; theSocket->nanoSocket = nanoSocket; theSocket->nativeSocket = tmpSocket; return(theSocket); }