/*---------------------------------------------------------------------- | NPT_String::SetLength +---------------------------------------------------------------------*/ NPT_Result NPT_String::SetLength(NPT_Size length, bool pad) { // special case for 0 if (length == 0) { Reset(); return NPT_SUCCESS; } // reserve the space Reserve(length); // pad with spaces if necessary char* chars = UseChars(); if (pad) { unsigned int current_length = GetLength(); if (length > current_length) { unsigned int pad_length = length-current_length; NPT_SetMemory(chars+current_length, ' ', pad_length); } } // update the length and terminate the buffer GetBuffer()->SetLength(length); chars[length] = '\0'; return NPT_SUCCESS; }
/*---------------------------------------------------------------------- | TestBenchmark +---------------------------------------------------------------------*/ static int TestBenchmark() { unsigned char* data = new unsigned char[16*1024]; NPT_SetMemory(data, 0, sizeof(16*1024)); NPT_TimeStamp before; NPT_TimeStamp after; float elapsed; unsigned char key[16] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }; NPT_BlockCipher* cipher; NPT_BlockCipher::Create(NPT_BlockCipher::AES_128, NPT_BlockCipher::ENCRYPT, key, 16, cipher); NPT_System::GetCurrentTimeStamp(before); unsigned int block_count = 0; do { unsigned char out[16]; for (unsigned int i=0; i<1024; i++) { cipher->ProcessBlock(data+16*i, out); } block_count += 1024; NPT_System::GetCurrentTimeStamp(after); elapsed = after.ToSeconds()-before.ToSeconds(); } while (elapsed < 10.0f); NPT_Console::OutputF("AES: %d blocks in 10 seconds: %f MB/s\n", block_count, ((block_count*16.0f)/1000000.0f)/elapsed); delete data; return 0; }
/*---------------------------------------------------------------------- | NPT_ZipInflateState::NPT_ZipInflateState +---------------------------------------------------------------------*/ NPT_ZipInflateState::NPT_ZipInflateState() { // initialize the state NPT_SetMemory(&m_Stream, 0, sizeof(m_Stream)); // initialize the decompressor inflateInit2(&m_Stream, 15+32); // 15 = default window bits, +32 = automatic header }
/*---------------------------------------------------------------------- | NPT_File::GetInfo +---------------------------------------------------------------------*/ NPT_Result NPT_File::GetInfo(const char* path, NPT_FileInfo* info) { // default value if (info) NPT_SetMemory(info, 0, sizeof(*info)); return NPT_SUCCESS; }
/*---------------------------------------------------------------------- | NPT_Zip::Deflate +---------------------------------------------------------------------*/ NPT_Result NPT_Zip::Deflate(const NPT_DataBuffer& in, NPT_DataBuffer& out, int compression_level, Format format /* = ZLIB */) { // default return state out.SetDataSize(0); // check parameters if (compression_level < NPT_ZIP_COMPRESSION_LEVEL_DEFAULT || compression_level > NPT_ZIP_COMPRESSION_LEVEL_MAX) { return NPT_ERROR_INVALID_PARAMETERS; } // setup the stream z_stream stream; NPT_SetMemory(&stream, 0, sizeof(stream)); stream.next_in = (Bytef*)in.GetData(); stream.avail_in = (uInt)in.GetDataSize(); // setup the memory functions stream.zalloc = (alloc_func)0; stream.zfree = (free_func)0; stream.opaque = (voidpf)0; // initialize the compressor int err = deflateInit2(&stream, compression_level, Z_DEFLATED, 15 + (format == GZIP ? 16 : 0), 8, Z_DEFAULT_STRATEGY); if (err != Z_OK) return MapError(err); // reserve an output buffer known to be large enough out.Reserve(deflateBound(&stream, stream.avail_in) + (format==GZIP?10:0)); stream.next_out = out.UseData(); stream.avail_out = out.GetBufferSize(); // decompress err = deflate(&stream, Z_FINISH); if (err != Z_STREAM_END) { deflateEnd(&stream); return MapError(err); } // update the output size out.SetDataSize(stream.total_out); // cleanup err = deflateEnd(&stream); return MapError(err); }
/*---------------------------------------------------------------------- | NPT_File::GetInfo +---------------------------------------------------------------------*/ NPT_Result NPT_File::GetInfo(const char* path, NPT_FileInfo* info) { // default value if (info) NPT_SetMemory(info, 0, sizeof(*info)); #if defined(_WIN32) || defined(_XBOX) // On Windows, stat will fail if a dir ends with a separator NPT_String _path = path; _path.TrimRight("\\/"); // keep a separator at the end for drive names such as C:<backslash> if (NPT_StringLength(_path) == 2 && _path[1] == ':') { _path += NPT_FilePath::Separator; } #else #define _path path #endif // get the file info NPT_stat_struct stat_buffer; int result = NPT_stat(_path, &stat_buffer); if (result != 0) return MapErrno(errno); // setup the returned fields if (info) { info->m_Size = stat_buffer.st_size; if (S_ISREG(stat_buffer.st_mode)) { info->m_Type = NPT_FileInfo::FILE_TYPE_REGULAR; } else if (S_ISDIR(stat_buffer.st_mode)) { info->m_Type = NPT_FileInfo::FILE_TYPE_DIRECTORY; } else { info->m_Type = NPT_FileInfo::FILE_TYPE_OTHER; } info->m_AttributesMask &= NPT_FILE_ATTRIBUTE_READ_ONLY; if ((stat_buffer.st_mode & S_IWUSR) == 0) { info->m_Attributes &= NPT_FILE_ATTRIBUTE_READ_ONLY; } #if defined(NPT_CONFIG_HAVE_STAT_ST_BIRTHTIME) info->m_CreationTime.SetSeconds(stat_buffer.st_birthtime); #elif defined(NPT_CONFIG_STAT_ST_CTIME_IS_ST_BIRTHTIME) info->m_CreationTime.SetSeconds(stat_buffer.st_ctime); #else info->m_CreationTime.SetSeconds(0); #endif info->m_ModificationTime.SetSeconds(stat_buffer.st_mtime); } return NPT_SUCCESS; }
/*---------------------------------------------------------------------- | NPT_IpAddress::Parse +---------------------------------------------------------------------*/ NPT_Result NPT_IpAddress::Parse(const char* name) { // check the name if (name == NULL) return NPT_ERROR_INVALID_PARAMETERS; // clear the address NPT_SetMemory(&m_Address[0], 0, sizeof(m_Address)); // parse unsigned int fragment; bool fragment_empty = true; unsigned char address[4]; unsigned int accumulator; for (fragment = 0, accumulator = 0; fragment < 4; ++name) { if (*name == '\0' || *name == '.') { // fragment terminator if (fragment_empty) return NPT_ERROR_INVALID_SYNTAX; address[fragment++] = accumulator; if (*name == '\0') break; accumulator = 0; fragment_empty = true; } else if (*name >= '0' && *name <= '9') { // numerical character accumulator = accumulator*10 + (*name - '0'); if (accumulator > 255) return NPT_ERROR_INVALID_SYNTAX; fragment_empty = false; } else { // invalid character return NPT_ERROR_INVALID_SYNTAX; } } if (fragment == 4 && *name == '\0' && !fragment_empty) { m_Address[0] = address[0]; m_Address[1] = address[1]; m_Address[2] = address[2]; m_Address[3] = address[3]; return NPT_SUCCESS; } else { return NPT_ERROR_INVALID_SYNTAX; } }
/*---------------------------------------------------------------------- | NPT_ZipDeflateState::NPT_ZipDeflateState +---------------------------------------------------------------------*/ NPT_ZipDeflateState::NPT_ZipDeflateState(int compression_level, NPT_Zip::Format format) { // check parameters if (compression_level < NPT_ZIP_COMPRESSION_LEVEL_DEFAULT || compression_level > NPT_ZIP_COMPRESSION_LEVEL_MAX) { compression_level = NPT_ZIP_COMPRESSION_LEVEL_DEFAULT; } // initialize the state NPT_SetMemory(&m_Stream, 0, sizeof(m_Stream)); // initialize the compressor deflateInit2(&m_Stream, compression_level, Z_DEFLATED, 15 + (format == NPT_Zip::GZIP ? 16 : 0), 8, Z_DEFAULT_STRATEGY); }
/*---------------------------------------------------------------------- | NPT_Win32SerialPort::Open +---------------------------------------------------------------------*/ NPT_Result NPT_Win32SerialPort::Open(unsigned int speed, NPT_SerialPortStopBits stop_bits, NPT_SerialPortFlowControl flow_control, NPT_SerialPortParity parity) { // check if we're already open if (!m_HandleReference.IsNull()) { return NPT_ERROR_SERIAL_PORT_ALREADY_OPEN; } HANDLE handle = CreateFile(m_Name, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0); if (handle == INVALID_HANDLE_VALUE) { return NPT_ERROR_NO_SUCH_SERIAL_PORT; } // set the parameters DCB dcb; NPT_SetMemory(&dcb, 0, sizeof(dcb)); dcb.DCBlength = sizeof(DCB); if (!GetCommState(handle, &dcb)) { CloseHandle(handle); return NPT_FAILURE; } dcb.fBinary = TRUE; dcb.BaudRate = speed; switch (stop_bits) { case NPT_SERIAL_PORT_STOP_BITS_1: dcb.StopBits = ONESTOPBIT; break; case NPT_SERIAL_PORT_STOP_BITS_1_5: dcb.StopBits = ONE5STOPBITS; break; case NPT_SERIAL_PORT_STOP_BITS_2: dcb.StopBits = TWOSTOPBITS; break; } switch (flow_control) { case NPT_SERIAL_PORT_FLOW_CONTROL_NONE: dcb.fOutX = dcb.fOutxCtsFlow = dcb.fOutxDsrFlow = FALSE; dcb.fInX = dcb.fDsrSensitivity = FALSE; dcb.fRtsControl = RTS_CONTROL_DISABLE; dcb.fDtrControl = DTR_CONTROL_DISABLE; break; case NPT_SERIAL_PORT_FLOW_CONTROL_HARDWARE: dcb.fOutX = dcb.fOutxDsrFlow = FALSE; dcb.fOutxCtsFlow = TRUE; dcb.fInX = dcb.fDsrSensitivity = FALSE; dcb.fRtsControl = RTS_CONTROL_HANDSHAKE; dcb.fDtrControl = DTR_CONTROL_DISABLE; break; case NPT_SERIAL_PORT_FLOW_CONTROL_XON_XOFF: dcb.fOutX = TRUE; dcb.fOutxCtsFlow = dcb.fOutxDsrFlow = FALSE; dcb.fInX = TRUE; dcb.fDsrSensitivity = FALSE; dcb.fRtsControl = RTS_CONTROL_DISABLE; dcb.fDtrControl = DTR_CONTROL_DISABLE; break; } switch (parity) { case NPT_SERIAL_PORT_PARITY_NONE: dcb.fParity = FALSE; dcb.Parity = NOPARITY; break; case NPT_SERIAL_PORT_PARITY_EVEN: dcb.fParity = TRUE; dcb.Parity = EVENPARITY; break; case NPT_SERIAL_PORT_PARITY_ODD: dcb.fParity = TRUE; dcb.Parity = ODDPARITY; break; case NPT_SERIAL_PORT_PARITY_MARK: dcb.fParity = TRUE; dcb.Parity = MARKPARITY; break; } if (!SetCommState(handle, &dcb)) { CloseHandle(handle); return NPT_FAILURE; } // create a reference to the FILE object m_HandleReference = new NPT_Win32HandleWrapper(handle); return NPT_SUCCESS; }
/*---------------------------------------------------------------------- | TestBlockCiphers +---------------------------------------------------------------------*/ static int TestBlockCiphers() { NPT_BlockCipher* cipher = NULL; NPT_UInt8 b0[16]; NPT_UInt8 k1[16] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }; NPT_UInt8 pt1[16] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }; NPT_UInt8 ct1[16] = { 0x69, 0xc4, 0xe0, 0xd8, 0x6a, 0x7b, 0x04, 0x30, 0xd8, 0xcd, 0xb7, 0x80, 0x70, 0xb4, 0xc5, 0x5a }; NPT_Result result; result = NPT_BlockCipher::Create(NPT_BlockCipher::AES_128, NPT_BlockCipher::ENCRYPT, k1, 16, cipher); SHOULD_SUCCEED(result); SHOULD_EQUAL(cipher->GetBlockSize(), 16); result = cipher->ProcessBlock(pt1, b0); SHOULD_SUCCEED(result); SHOULD_EQUAL_MEM(b0, ct1, 16); delete cipher; result = NPT_BlockCipher::Create(NPT_BlockCipher::AES_128, NPT_BlockCipher::DECRYPT, k1, 16, cipher); SHOULD_SUCCEED(result); SHOULD_EQUAL(cipher->GetBlockSize(), 16); result = cipher->ProcessBlock(ct1, b0); SHOULD_SUCCEED(result); SHOULD_EQUAL_MEM(b0, pt1, 16); delete cipher; NPT_UInt8 key[16]; NPT_CopyMemory(key, k1, 16); for (unsigned int i=0; i<100; i++) { NPT_BlockCipher* encrypter; NPT_BlockCipher* decrypter; result = NPT_BlockCipher::Create(NPT_BlockCipher::AES_128, NPT_BlockCipher::ENCRYPT, key, 16, encrypter); result = NPT_BlockCipher::Create(NPT_BlockCipher::AES_128, NPT_BlockCipher::DECRYPT, key, 16, decrypter); NPT_UInt8 mem1[16]; NPT_UInt8 mem2[16]; NPT_UInt8 mem3[16]; NPT_SetMemory(mem1, 0, 16); for (unsigned int j=0; j<1000; j++) { encrypter->ProcessBlock(mem1, mem2); decrypter->ProcessBlock(mem2, mem3); SHOULD_EQUAL_MEM(mem1, mem3, 16); NPT_CopyMemory(mem1, mem2, 16); } delete encrypter; delete decrypter; NPT_CopyMemory(key, mem1, 16); } return 0; }
/*---------------------------------------------------------------------- | main +---------------------------------------------------------------------*/ int main(int /*argc*/, char** /*argv*/) { // setup debugging #if defined(WIN32) && defined(_DEBUG) int flags = _crtDbgFlag | _CRTDBG_ALLOC_MEM_DF | _CRTDBG_DELAY_FREE_MEM_DF | _CRTDBG_CHECK_ALWAYS_DF; _CrtSetDbgFlag(flags); //AllocConsole(); //freopen("CONOUT$", "w", stdout); #endif NPT_Result result; TcpServerThread* server_thread = NULL; NPT_TcpClientSocket* tcp_client = NULL; NPT_TcpServerSocket* tcp_server = NULL; CancellerThread* canceller = NULL; NPT_SocketAddress address(NPT_IpAddress(127,0,0,1), 10000); #if 0 result = RemoteIpAddress.ResolveName("www.google.com"); CHECK(result == NPT_SUCCESS); NPT_Console::Output("--- test for immediate connection\n"); NPT_Console::Output("[01] starting write server thread\n"); server_thread = new TcpServerThread(); server_thread->Start(); NPT_Console::Output("[01] waiting for server to be ready...\n"); server_thread->m_Ready.WaitUntilEquals(1); NPT_Console::Output("[01] server thread ready\n"); NPT_Console::Output("[01] waiting a while...\n"); NPT_System::Sleep(3.0); tcp_client = new NPT_TcpClientSocket(); NPT_Console::Output("[01] connection to 127.0.0.1:10000\n"); result = tcp_client->Connect(address); NPT_Console::OutputF("[01] connect returns %d : %s\n", result, NPT_ResultText(result)); CHECK(result == NPT_SUCCESS); delete tcp_client; NPT_Console::Output("[01] terminating server\n"); server_thread->m_Interrupted = true; server_thread->Wait(); delete server_thread; NPT_Console::Output("\n--- test for refused local connection\n"); address.SetPort(89); tcp_client = new NPT_TcpClientSocket(); NPT_Console::Output("[01] connecting to 127.0.0.1:89\n"); result = tcp_client->Connect(address); NPT_Console::OutputF("[01] connect returns %d : %s\n", result, NPT_ResultText(result)); CHECK(result == NPT_ERROR_CONNECTION_REFUSED); delete tcp_client; /*NPT_Console::Output("\n--- test for refused remote connection\n"); address.SetIpAddress(RemoteIpAddress); address.SetPort(81); tcp_client = new NPT_TcpClientSocket(); NPT_Console::Output("[01] connecting to www.google.com:81\n"); result = tcp_client->Connect(address); NPT_Console::OutputF("[01] connect returns %d : %s\n", result, NPT_ResultText(result)); CHECK(result == NPT_ERROR_CONNECTION_REFUSED); delete tcp_client;*/ NPT_Console::Output("\n--- test for connection timeout\n"); address.SetIpAddress(NPT_IpAddress(1,1,1,1)); NPT_Console::Output("[01] connecting to 1.1.1.1:89\n"); tcp_client = new NPT_TcpClientSocket(); result = tcp_client->Connect(address, 3000); NPT_Console::OutputF("[01] connect returns %d : %s\n", result, NPT_ResultText(result)); CHECK(result == NPT_ERROR_TIMEOUT); delete tcp_client; NPT_Console::Output("\n--- test for remote connection\n"); address.SetIpAddress(RemoteIpAddress); address.SetPort(80); NPT_Console::Output("[01] connecting to www.google.com:80\n"); tcp_client = new NPT_TcpClientSocket(); result = tcp_client->Connect(address); NPT_Console::OutputF("[01] connect returns %d : %s\n", result, NPT_ResultText(result)); CHECK(result == NPT_SUCCESS); delete tcp_client; #endif for (int i=0; i<2; i++) { NPT_Console::OutputF("\n--- test for cancelled connection, shutdown=%d\n", i); address.SetIpAddress(NPT_IpAddress(1,1,1,1)); address.SetPort(89); NPT_Console::Output("[01] connecting to 1.1.1.1:89\n"); tcp_client = new NPT_TcpClientSocket(NPT_SOCKET_FLAG_CANCELLABLE); canceller = new CancellerThread(tcp_client, 3.0f, i==1); result = tcp_client->Connect(address); NPT_Console::OutputF("[01] connect returns %d : %s\n", result, NPT_ResultText(result)); CHECK(result == NPT_ERROR_CANCELLED); canceller->Wait(); delete canceller; delete tcp_client; } for (int i=0; i<2; i++) { NPT_Console::OutputF("\n--- testing read cancellation, shutdown=%d\n", i); address.SetIpAddress(RemoteIpAddress); address.SetPort(80); NPT_Console::Output("[01] connecting to www.google.com:80\n"); tcp_client = new NPT_TcpClientSocket(NPT_SOCKET_FLAG_CANCELLABLE); result = tcp_client->Connect(address); NPT_Console::OutputF("[01] connect returns %d : %s\n", result, NPT_ResultText(result)); CHECK(result == NPT_SUCCESS); canceller = new CancellerThread(tcp_client, 3.0f, i==1); NPT_InputStreamReference input; tcp_client->GetInputStream(input); unsigned char buffer[4096]; NPT_SetMemory(buffer, 0, sizeof(buffer)); result = input->Read(buffer, 4096); NPT_Console::OutputF("{00} read returned %d (%s)\n", result, NPT_ResultText(result)); CHECK(result == NPT_ERROR_CANCELLED); delete tcp_client; canceller->Wait(); delete canceller; } for (int i=0; i<2; i++) { NPT_Console::OutputF("\n--- testing write cancellation, shutdown=%d\n", i); server_thread = new TcpServerThread(); server_thread->Start(); NPT_Console::Output("[01] waiting for server to be ready...\n"); server_thread->m_Ready.WaitUntilEquals(1); NPT_Console::Output("[01] server thread ready\n"); NPT_Console::Output("[01] waiting a while...\n"); NPT_System::Sleep(3.0); address.SetIpAddress(NPT_IpAddress(127,0,0,1)); address.SetPort(10000); NPT_Console::Output("[01] connecting to localhost:10000\n"); tcp_client = new NPT_TcpClientSocket(NPT_SOCKET_FLAG_CANCELLABLE); result = tcp_client->Connect(address); NPT_Console::OutputF("[01] connect returns %d : %s\n", result, NPT_ResultText(result)); CHECK(result == NPT_SUCCESS); canceller = new CancellerThread(tcp_client, 3.0f, i==1); NPT_OutputStreamReference output; tcp_client->GetOutputStream(output); NPT_Size total_written = 0; unsigned char buffer[4096]; NPT_SetMemory(buffer, 0, sizeof(buffer)); do { NPT_Size bytes_written = 0; result = output->Write(buffer, 4096, &bytes_written); if (NPT_SUCCEEDED(result)) { total_written += bytes_written; } } while (NPT_SUCCEEDED(result)); output = NULL; NPT_Console::OutputF("{01} write returned %d (%s)\n", result, NPT_ResultText(result)); NPT_Console::OutputF("{01} wrote %d bytes total\n", total_written); CHECK(result == NPT_ERROR_CANCELLED); delete tcp_client; canceller->Wait(); delete canceller; server_thread->m_Interrupted = true; server_thread->Wait(); delete server_thread; } for (int i=0; i<2; i++) { NPT_Console::OutputF("\n--- testing accept cancellation, shutdown=%d\n", i); NPT_Console::Output("{03} waiting for connection on port 10000\n"); address.SetIpAddress(NPT_IpAddress(127,0,0,1)); address.SetPort(10000); tcp_server = new NPT_TcpServerSocket(NPT_SOCKET_FLAG_CANCELLABLE); result = tcp_server->Bind(address, true); CHECK(result == NPT_SUCCESS); canceller = new CancellerThread(tcp_server, 3.0f, i==1); NPT_Socket* new_client = NULL; result = tcp_server->WaitForNewClient(new_client); NPT_Console::OutputF("{03} WaitForNewClient returned %d (%s)\n", result, NPT_ResultText(result)); CHECK(result == NPT_ERROR_CANCELLED); canceller->Wait(); delete canceller; delete tcp_server; } NPT_Console::Output("------------\n"); NPT_Console::Output("bye bye\n"); #if defined(WIN32) && defined(_DEBUG) _CrtDumpMemoryLeaks(); #endif return 0; }