예제 #1
0
파일: NNumber.cpp 프로젝트: refnum/nano
//============================================================================
//		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);
}
예제 #2
0
//============================================================================
//		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);
}
예제 #3
0
//============================================================================
//      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);
}