/*---------------------------------------------------------------------- | NPT_ZipFile::GetInputStream +---------------------------------------------------------------------*/ NPT_Result NPT_ZipFile::GetInputStream(Entry& entry, NPT_InputStreamReference& zip_stream, NPT_InputStream*& file_stream) { // default return value file_stream = NULL; // we don't support encrypted files if (entry.m_Flags & NPT_ZIP_FILE_FLAG_ENCRYPTED) { return NPT_ERROR_NOT_SUPPORTED; } // check that we support the compression method #if NPT_CONFIG_ENABLE_ZIP if (entry.m_CompressionMethod != NPT_ZIP_FILE_COMPRESSION_METHOD_NONE && entry.m_CompressionMethod != NPT_ZIP_FILE_COMPRESSION_METHOD_DEFLATE) { return NPT_ERROR_NOT_SUPPORTED; } #else if (entry.m_CompressionMethod != NPT_ZIP_FILE_COMPRESSION_METHOD_NONE) { return NPT_ERROR_NOT_SUPPORTED; } #endif // seek to the start of the file entry NPT_Result result = zip_stream->Seek(entry.m_RelativeOffset); if (NPT_FAILED(result)) { NPT_LOG_WARNING_1("seek failed (%d)", result); return result; } // read the fixed part of the header unsigned char header[30]; result = zip_stream->ReadFully(header, 30); if (NPT_FAILED(result)) { NPT_LOG_WARNING_1("read failed (%d)", result); return result; } NPT_UInt16 file_name_length = NPT_BytesToInt16Le(&header[26]); NPT_UInt16 extra_field_length = NPT_BytesToInt16Le(&header[28]); unsigned int header_size = 30+file_name_length+extra_field_length; NPT_LargeSize zip_stream_size = 0; zip_stream->GetSize(zip_stream_size); if (entry.m_RelativeOffset+header_size+entry.m_CompressedSize > zip_stream_size) { // something's wrong here return NPT_ERROR_INVALID_FORMAT; } file_stream = new NPT_SubInputStream(zip_stream, entry.m_RelativeOffset+header_size, entry.m_CompressedSize); #if NPT_CONFIG_ENABLE_ZIP if (entry.m_CompressionMethod == NPT_ZIP_FILE_COMPRESSION_METHOD_DEFLATE) { NPT_InputStreamReference file_stream_ref(file_stream); file_stream = new NPT_ZipInflatingInputStream(file_stream_ref, true); } #endif return NPT_SUCCESS; }
/*---------------------------------------------------------------------- | PLT_HttpHelper::IsBodyStreamSeekable +---------------------------------------------------------------------*/ bool PLT_HttpHelper::IsBodyStreamSeekable(NPT_HttpMessage* message) { NPT_HttpEntity* entity = message->GetEntity(); NPT_InputStreamReference stream; if (!entity || NPT_FAILED(entity->GetInputStream(stream))) return true; // try to get current position and seek there NPT_Position position; if (NPT_FAILED(stream->Tell(position)) || NPT_FAILED(stream->Seek(position))) { return false; } return true; }
void serveFile2(AbortableTask *task, const NPT_String& filePath, const NPT_String& mimeType, const FrontEnd::RequestContext& reqCtx, const NPT_HttpRequest *req, NPT_HttpResponse& resp, HttpOutput *httpOutput) { #if 1 NPT_File f(filePath); NPT_FileInfo fileInfo; if (NPT_FAILED(f.GetInfo(fileInfo)) || fileInfo.m_Type != NPT_FileInfo::FILE_TYPE_REGULAR || NPT_FAILED(f.Open(NPT_FILE_OPEN_MODE_READ))) { setStatusCode(resp, 404); httpOutput->writeResponseHeader(resp); return; } NPT_InputStreamReference fileInput; f.GetInputStream(fileInput); serveStream(task, fileInput.AsPointer(), fileInfo.m_ModificationTime, mimeType, reqCtx, req, resp, httpOutput); #else bool isGetMethod = req->GetMethod().Compare("GET") == 0; bool isHeadMethod = req->GetMethod().Compare("HEAD") == 0; if (isGetMethod || isHeadMethod) { NPT_Result nr; NPT_File f(filePath); NPT_FileInfo fileInfo; if (NPT_FAILED(f.GetInfo(fileInfo)) || fileInfo.m_Type != NPT_FileInfo::FILE_TYPE_REGULAR || NPT_FAILED(f.Open(NPT_FILE_OPEN_MODE_READ))) { setStatusCode(resp, 404); httpOutput->writeResponseHeader(resp); return; } NPT_InputStreamReference fileInput; f.GetInputStream(fileInput); NPT_UInt64 offset, length; NPT_HttpHeader *hdrRange = req->GetHeaders().GetHeader("RANGE"); if (hdrRange) { if (!parseRangeHeader(hdrRange->GetValue(), fileInfo.m_Size, offset, length)) { setStatusCode(resp, 416); httpOutput->writeResponseHeader(resp); return; } setStatusCode(resp, 206); resp.GetHeaders().SetHeader(NPT_HTTP_HEADER_CONTENT_RANGE, NPT_String::Format("bytes %s-%s/%s", NPT_String::FromIntegerU(offset).GetChars(), NPT_String::FromIntegerU(offset + length - 1).GetChars(), NPT_String::FromIntegerU(fileInfo.m_Size).GetChars())); fileInput->Seek(offset); } else { offset = 0; length = fileInfo.m_Size; setStatusCode(resp, 200); } resp.GetHeaders().SetHeader(NPT_HTTP_HEADER_CONTENT_TYPE, mimeType); resp.GetHeaders().SetHeader(NPT_HTTP_HEADER_CONTENT_LENGTH, NPT_String::FromIntegerU(length)); resp.GetHeaders().SetHeader("Last-Modified", NPT_DateTime(fileInfo.m_ModificationTime).ToString(NPT_DateTime::FORMAT_RFC_1123)); resp.GetHeaders().SetHeader("Accept-Ranges", "bytes"); resp.GetHeaders().SetHeader("EXT", ""); if (reqCtx.transferMode != FrontEnd::TM_None) { const char *transferMode = "Streaming"; switch (reqCtx.transferMode) { case FrontEnd::TM_Background: transferMode = "Background"; break; case FrontEnd::TM_Interactive: transferMode = "Interactive"; break; } resp.GetHeaders().SetHeader("transferMode.dlna.org", transferMode); } if (reqCtx.getcontentFeaturesReq) { NPT_String contentFeatures("DLNA.ORG_OP=01;DLNA.ORG_CI=0;DLNA.ORG_FLAGS=01700000000000000000000000000000"); resp.GetHeaders().SetHeader("contentFeatures.dlna.org", contentFeatures); } httpOutput->writeResponseHeader(resp); if (isGetMethod) { bool abortFlag = false; ServeFileAbortCallback abortCallback(&abortFlag); if (task->registerAbortCallback(&abortCallback)) { NPT_DataBuffer buffer(4096); NPT_UInt64 cbRemain = length; for (;;) { if (abortFlag) { break; } if (cbRemain == 0) { break; } NPT_Size cbRead; NPT_UInt64 cbToRead = cbRemain; if (cbToRead > buffer.GetBufferSize()) { cbToRead = buffer.GetBufferSize(); } nr = fileInput->Read(buffer.UseData(), buffer.GetBufferSize(), &cbRead); if (NPT_FAILED(nr)) { /*if (nr == NPT_ERROR_EOS) { } else { }*/ break; } if (abortFlag) { break; } if (cbRead > 0) { cbRemain -= cbRead; httpOutput->writeData(buffer.GetData(), cbRead); } } task->unregisterAbortCallback(&abortCallback); } } } else { setStatusCode(resp, 405); resp.GetHeaders().SetHeader("Allow", "GET, HEAD"); httpOutput->writeResponseHeader(resp); } #endif }
/*---------------------------------------------------------------------- | PLT_HttpServer::ServeStream +---------------------------------------------------------------------*/ NPT_Result PLT_HttpServer::ServeStream(const NPT_HttpRequest& request, const NPT_HttpRequestContext& context, NPT_HttpResponse& response, NPT_InputStreamReference& body, const char* content_type) { if (body.IsNull()) return NPT_FAILURE; // set date NPT_TimeStamp now; NPT_System::GetCurrentTimeStamp(now); response.GetHeaders().SetHeader("Date", NPT_DateTime(now).ToString(NPT_DateTime::FORMAT_RFC_1123), true); // get entity NPT_HttpEntity* entity = response.GetEntity(); NPT_CHECK_POINTER_FATAL(entity); // set the content type entity->SetContentType(content_type); // check for range requests const NPT_String* range_spec = request.GetHeaders().GetHeaderValue(NPT_HTTP_HEADER_RANGE); // setup entity body NPT_CHECK(NPT_HttpFileRequestHandler::SetupResponseBody(response, body, range_spec)); // set some default headers if (response.GetEntity()->GetTransferEncoding() != NPT_HTTP_TRANSFER_ENCODING_CHUNKED) { // set but don't replace Accept-Range header only if body is seekable NPT_Position offset; if (NPT_SUCCEEDED(body->Tell(offset)) && NPT_SUCCEEDED(body->Seek(offset))) { response.GetHeaders().SetHeader(NPT_HTTP_HEADER_ACCEPT_RANGES, "bytes", false); } } // set getcontentFeatures.dlna.org const NPT_String* value = request.GetHeaders().GetHeaderValue("getcontentFeatures.dlna.org"); if (value) { PLT_HttpRequestContext tmp_context(request, context); const char* dlna = PLT_ProtocolInfo::GetDlnaExtension(entity->GetContentType(), &tmp_context); if (dlna) response.GetHeaders().SetHeader("ContentFeatures.DLNA.ORG", dlna, false); } // transferMode.dlna.org value = request.GetHeaders().GetHeaderValue("transferMode.dlna.org"); if (value) { // Interactive mode not supported? /*if (value->Compare("Interactive", true) == 0) { response.SetStatus(406, "Not Acceptable"); return NPT_SUCCESS; }*/ response.GetHeaders().SetHeader("TransferMode.DLNA.ORG", value->GetChars(), false); } else { response.GetHeaders().SetHeader("TransferMode.DLNA.ORG", "Streaming", false); } if (request.GetHeaders().GetHeaderValue("TimeSeekRange.dlna.org")) { response.SetStatus(406, "Not Acceptable"); return NPT_SUCCESS; } return NPT_SUCCESS; }
/*---------------------------------------------------------------------- | main +---------------------------------------------------------------------*/ int main(int argc, char** argv) { NPT_Result result; NPT_FileInfo info; NPT_ASSERT(NPT_File::GetInfo("foobar.doesnotexist", NULL) == NPT_ERROR_NO_SUCH_FILE); NPT_ASSERT(!NPT_File::Exists("foobar.doesnotexist")); // test special names NPT_File file(NPT_FILE_STANDARD_INPUT); NPT_ASSERT(NPT_SUCCEEDED(file.GetInfo(info))); NPT_ASSERT(info.m_Type == NPT_FileInfo::FILE_TYPE_SPECIAL); file = NPT_File(NPT_FILE_STANDARD_OUTPUT); NPT_ASSERT(NPT_SUCCEEDED(file.GetInfo(info))); NPT_ASSERT(info.m_Type == NPT_FileInfo::FILE_TYPE_SPECIAL); file = NPT_File(NPT_FILE_STANDARD_ERROR); NPT_ASSERT(NPT_SUCCEEDED(file.GetInfo(info))); NPT_ASSERT(info.m_Type == NPT_FileInfo::FILE_TYPE_SPECIAL); if (NPT_File::Exists("foobar.file1")) { result = NPT_File::DeleteFile("foobar.file1"); NPT_ASSERT(NPT_SUCCEEDED(result)); } result = CreateNewFile("foobar.file1", 9); NPT_ASSERT(NPT_SUCCEEDED(result)); NPT_ASSERT(NPT_File::Exists("foobar.file1")); result = NPT_File::GetInfo("foobar.file1", &info); NPT_ASSERT(NPT_SUCCEEDED(result)); NPT_ASSERT(info.m_Type == NPT_FileInfo::FILE_TYPE_REGULAR); NPT_ASSERT(info.m_Size == 9); { NPT_File f1("foobar.file1"); result = f1.GetInfo(info); NPT_ASSERT(NPT_SUCCEEDED(result)); NPT_ASSERT(info.m_Type == NPT_FileInfo::FILE_TYPE_REGULAR); NPT_ASSERT(info.m_Size == 9); } { NPT_File f1("foobar.file1"); NPT_LargeSize size; result = f1.GetSize(size); NPT_ASSERT(NPT_SUCCEEDED(result)); NPT_ASSERT(size == 9); } { NPT_File f1("foobar.file1"); result = f1.Rename("foobar.file1-r"); NPT_ASSERT(NPT_SUCCEEDED(result)); NPT_ASSERT(f1.GetPath() == "foobar.file1-r"); } NPT_ASSERT(NPT_File::Exists("foobar.file1-r")); result = NPT_File::GetInfo("foobar.file1-r", &info); NPT_ASSERT(NPT_SUCCEEDED(result)); NPT_ASSERT(info.m_Type == NPT_FileInfo::FILE_TYPE_REGULAR); NPT_ASSERT(info.m_Size == 9); // dirs NPT_ASSERT(!NPT_File::Exists("foobar.dir")); result = NPT_File::CreateDirectory("foobar.dir"); NPT_ASSERT(NPT_SUCCEEDED(result)); result = NPT_File::GetInfo("foobar.dir", &info); NPT_ASSERT(NPT_SUCCEEDED(result)); NPT_ASSERT(info.m_Type == NPT_FileInfo::FILE_TYPE_DIRECTORY); { NPT_File f1("foobar.dir"); result = f1.GetInfo(info); NPT_ASSERT(NPT_SUCCEEDED(result)); NPT_ASSERT(info.m_Type == NPT_FileInfo::FILE_TYPE_DIRECTORY); } NPT_String dirname = "foobar.dir"; NPT_String fname; fname = dirname; fname += NPT_FilePath::Separator; fname += "file1"; result = CreateNewFile(fname, 1); NPT_ASSERT(NPT_SUCCEEDED(result)); fname = dirname; fname += NPT_FilePath::Separator; fname += "file2"; result = CreateNewFile(fname, 2); NPT_ASSERT(NPT_SUCCEEDED(result)); fname = dirname; fname += NPT_FilePath::Separator; fname += "file3"; result = CreateNewFile(fname, 3); NPT_ASSERT(NPT_SUCCEEDED(result)); NPT_List<NPT_String> entries; result = NPT_File::ListDirectory("foobar.dir", entries); NPT_ASSERT(NPT_SUCCEEDED(result)); NPT_ASSERT(entries.GetItemCount() == 3); result = NPT_File::DeleteFile("foobar.dir"); NPT_ASSERT(NPT_FAILED(result)); result = NPT_File::DeleteDirectory("foobar.dir"); NPT_ASSERT(result == NPT_ERROR_DIRECTORY_NOT_EMPTY); result = NPT_File::Rename("foobar.dir", "foobar.dir-r"); NPT_ASSERT(NPT_SUCCEEDED(result)); dirname = "foobar.dir-r"; fname = dirname; fname += NPT_FilePath::Separator; fname += "file1"; result = NPT_File::DeleteFile(fname); NPT_ASSERT(NPT_SUCCEEDED(result)); fname = dirname; fname += NPT_FilePath::Separator; fname += "file2"; result = NPT_File::DeleteFile(fname); NPT_ASSERT(NPT_SUCCEEDED(result)); fname = dirname; fname += NPT_FilePath::Separator; fname += "file3"; result = NPT_File::DeleteFile(fname); NPT_ASSERT(NPT_SUCCEEDED(result)); result = NPT_File::DeleteDirectory("foobar.dir-r"); NPT_ASSERT(NPT_SUCCEEDED(result)); NPT_ASSERT(!NPT_File::Exists("foobar.dir-r")); // paths NPT_String test; test = NPT_FilePath::BaseName(""); NPT_ASSERT(test == ""); test = NPT_FilePath::BaseName("a"); NPT_ASSERT(test == "a"); test = NPT_FilePath::BaseName("a"+NPT_FilePath::Separator+"b"); NPT_ASSERT(test == "b"); test = NPT_FilePath::BaseName("a"+NPT_FilePath::Separator+"b"+NPT_FilePath::Separator); NPT_ASSERT(test == ""); test = NPT_FilePath::BaseName(NPT_FilePath::Separator+"a"); NPT_ASSERT(test == "a"); test = NPT_FilePath::BaseName(NPT_FilePath::Separator); NPT_ASSERT(test == ""); test = NPT_FilePath::DirectoryName(""); NPT_ASSERT(test == ""); test = NPT_FilePath::DirectoryName("a"); NPT_ASSERT(test == ""); test = NPT_FilePath::DirectoryName("a"+NPT_FilePath::Separator+"b"); NPT_ASSERT(test == "a"); test = NPT_FilePath::DirectoryName("a"+NPT_FilePath::Separator+"b"+NPT_FilePath::Separator); NPT_ASSERT(test == "a"+NPT_FilePath::Separator+"b"); test = NPT_FilePath::DirectoryName(NPT_FilePath::Separator+"a"); NPT_ASSERT(test == NPT_FilePath::Separator); test = NPT_FilePath::DirectoryName(NPT_FilePath::Separator); NPT_ASSERT(test == NPT_FilePath::Separator); // large files if (argc == 2) { result = CreateNewFile(argv[1], 0x10000, 0x10007); NPT_ASSERT(NPT_SUCCEEDED(result)); NPT_String new_name = argv[1]; new_name += ".renamed"; result = NPT_File::Rename(argv[1], new_name); NPT_ASSERT(NPT_SUCCEEDED(result)); file = NPT_File(new_name); result = file.Open(NPT_FILE_OPEN_MODE_READ); NPT_ASSERT(NPT_SUCCEEDED(result)); NPT_InputStreamReference input; file.GetInputStream(input); NPT_Position position; result = input->Tell(position); NPT_ASSERT(NPT_SUCCEEDED(result)); NPT_ASSERT(position == 0); NPT_LargeSize large_size = (NPT_LargeSize)0x10007 * (NPT_LargeSize)0x10000; result = input->Seek(large_size-0x10007); NPT_ASSERT(NPT_SUCCEEDED(result)); result = input->Tell(position); NPT_ASSERT(NPT_SUCCEEDED(result)); NPT_ASSERT(position == large_size-0x10007); unsigned char* buffer = new unsigned char[0x10007]; result = input->ReadFully(buffer, 0x10007); NPT_ASSERT(NPT_SUCCEEDED(result)); result = input->Tell(position); NPT_ASSERT(NPT_SUCCEEDED(result)); NPT_ASSERT(position == large_size); for (unsigned int i=0; i<0x10007; i++) { NPT_ASSERT(buffer[i] == (unsigned char)i); } file.Close(); NPT_File::DeleteFile(new_name); } return 0; }
/*---------------------------------------------------------------------- | main +---------------------------------------------------------------------*/ int main(int argc, char** argv) { NPT_Result result; NPT_FileInfo info; NPT_ASSERT(NPT_File::GetInfo("foobar.doesnotexist", NULL) == NPT_ERROR_NO_SUCH_FILE); NPT_ASSERT(!NPT_File::Exists("foobar.doesnotexist")); // test special names NPT_File file(NPT_FILE_STANDARD_INPUT); NPT_ASSERT(NPT_SUCCEEDED(file.GetInfo(info))); NPT_ASSERT(info.m_Type == NPT_FileInfo::FILE_TYPE_SPECIAL); file = NPT_File(NPT_FILE_STANDARD_OUTPUT); NPT_ASSERT(NPT_SUCCEEDED(file.GetInfo(info))); NPT_ASSERT(info.m_Type == NPT_FileInfo::FILE_TYPE_SPECIAL); file = NPT_File(NPT_FILE_STANDARD_ERROR); NPT_ASSERT(NPT_SUCCEEDED(file.GetInfo(info))); NPT_ASSERT(info.m_Type == NPT_FileInfo::FILE_TYPE_SPECIAL); if (NPT_File::Exists("foobar.file1")) { result = NPT_File::RemoveFile("foobar.file1"); NPT_ASSERT(NPT_SUCCEEDED(result)); } result = CreateNewFile("foobar.file1", 9); NPT_ASSERT(NPT_SUCCEEDED(result)); NPT_ASSERT(NPT_File::Exists("foobar.file1")); result = NPT_File::GetInfo("foobar.file1", &info); NPT_ASSERT(NPT_SUCCEEDED(result)); NPT_ASSERT(info.m_Type == NPT_FileInfo::FILE_TYPE_REGULAR); NPT_ASSERT(info.m_Size == 9); { NPT_File f1("foobar.file1"); result = f1.GetInfo(info); NPT_ASSERT(NPT_SUCCEEDED(result)); NPT_ASSERT(info.m_Type == NPT_FileInfo::FILE_TYPE_REGULAR); NPT_ASSERT(info.m_Size == 9); } { NPT_File f1("foobar.file1"); NPT_LargeSize size; result = f1.GetSize(size); NPT_ASSERT(NPT_SUCCEEDED(result)); NPT_ASSERT(size == 9); } { NPT_File f1("foobar.file1"); result = f1.Rename("foobar.file1-r"); NPT_ASSERT(NPT_SUCCEEDED(result)); NPT_ASSERT(f1.GetPath() == "foobar.file1-r"); } NPT_ASSERT(NPT_File::Exists("foobar.file1-r")); result = NPT_File::GetInfo("foobar.file1-r", &info); NPT_ASSERT(NPT_SUCCEEDED(result)); NPT_ASSERT(info.m_Type == NPT_FileInfo::FILE_TYPE_REGULAR); NPT_ASSERT(info.m_Size == 9); // dirs NPT_ASSERT(!NPT_File::Exists("foobar.dir")); result = NPT_File::CreateDir("foobar.dir"); NPT_ASSERT(NPT_SUCCEEDED(result)); result = NPT_File::GetInfo("foobar.dir", &info); NPT_ASSERT(NPT_SUCCEEDED(result)); NPT_ASSERT(info.m_Type == NPT_FileInfo::FILE_TYPE_DIRECTORY); { NPT_File f1("foobar.dir"); result = f1.GetInfo(info); NPT_ASSERT(NPT_SUCCEEDED(result)); NPT_ASSERT(info.m_Type == NPT_FileInfo::FILE_TYPE_DIRECTORY); } NPT_String dirname = "foobar.dir"; NPT_String fname; fname = dirname; fname += NPT_FilePath::Separator; fname += "file1"; result = CreateNewFile(fname, 1); NPT_ASSERT(NPT_SUCCEEDED(result)); fname = dirname; fname += NPT_FilePath::Separator; fname += "file2"; result = CreateNewFile(fname, 2); NPT_ASSERT(NPT_SUCCEEDED(result)); fname = dirname; fname += NPT_FilePath::Separator; fname += "file3"; result = CreateNewFile(fname, 3); NPT_ASSERT(NPT_SUCCEEDED(result)); NPT_List<NPT_String> entries; result = NPT_File::ListDir("foobar.dir", entries); NPT_ASSERT(NPT_SUCCEEDED(result)); NPT_ASSERT(entries.GetItemCount() == 3); result = NPT_File::RemoveFile("foobar.dir"); NPT_ASSERT(NPT_FAILED(result)); result = NPT_File::RemoveDir("foobar.dir"); NPT_ASSERT(result == NPT_ERROR_DIRECTORY_NOT_EMPTY); result = NPT_File::Rename("foobar.dir", "foobar.dir-r"); NPT_ASSERT(NPT_SUCCEEDED(result)); dirname = "foobar.dir-r"; fname = dirname; fname += NPT_FilePath::Separator; fname += "file1"; result = NPT_File::RemoveFile(fname); NPT_ASSERT(NPT_SUCCEEDED(result)); fname = dirname; fname += NPT_FilePath::Separator; fname += "file2"; result = NPT_File::RemoveFile(fname); NPT_ASSERT(NPT_SUCCEEDED(result)); fname = dirname; fname += NPT_FilePath::Separator; fname += "file3"; result = NPT_File::RemoveFile(fname); NPT_ASSERT(NPT_SUCCEEDED(result)); result = NPT_File::RemoveDir("foobar.dir-r"); NPT_ASSERT(NPT_SUCCEEDED(result)); NPT_ASSERT(!NPT_File::Exists("foobar.dir-r")); // paths NPT_String test; test = NPT_FilePath::BaseName(""); NPT_ASSERT(test == ""); test = NPT_FilePath::BaseName("a"); NPT_ASSERT(test == "a"); test = NPT_FilePath::BaseName("a"+NPT_FilePath::Separator+"b"); NPT_ASSERT(test == "b"); test = NPT_FilePath::BaseName("a"+NPT_FilePath::Separator+"b"+NPT_FilePath::Separator); NPT_ASSERT(test == ""); test = NPT_FilePath::BaseName(NPT_FilePath::Separator+"a"); NPT_ASSERT(test == "a"); test = NPT_FilePath::BaseName(NPT_FilePath::Separator); NPT_ASSERT(test == ""); test = NPT_FilePath::DirName(""); NPT_ASSERT(test == ""); test = NPT_FilePath::DirName("a"); NPT_ASSERT(test == ""); test = NPT_FilePath::DirName("a"+NPT_FilePath::Separator+"b"); NPT_ASSERT(test == "a"); test = NPT_FilePath::DirName("a"+NPT_FilePath::Separator+"b"+NPT_FilePath::Separator); NPT_ASSERT(test == "a"+NPT_FilePath::Separator+"b"); test = NPT_FilePath::DirName(NPT_FilePath::Separator+"a"); NPT_ASSERT(test == NPT_FilePath::Separator); test = NPT_FilePath::DirName(NPT_FilePath::Separator); NPT_ASSERT(test == NPT_FilePath::Separator); // small files result = CreateNewFile("small.bin", 0x100, 0x107); NPT_ASSERT(NPT_SUCCEEDED(result)); file = NPT_File("small.bin"); result = file.Open(NPT_FILE_OPEN_MODE_READ); NPT_ASSERT(NPT_SUCCEEDED(result)); NPT_InputStreamReference input; file.GetInputStream(input); NPT_Position position; result = input->Tell(position); NPT_ASSERT(NPT_SUCCEEDED(result)); NPT_ASSERT(position == 0); NPT_LargeSize large_size = (NPT_LargeSize)0x107 * (NPT_LargeSize)0x100; result = input->Seek(large_size-0x107); NPT_ASSERT(NPT_SUCCEEDED(result)); result = input->Tell(position); NPT_ASSERT(NPT_SUCCEEDED(result)); NPT_ASSERT(position == large_size-0x107); unsigned char* buffer = new unsigned char[0x107]; result = input->ReadFully(buffer, 0x107); NPT_ASSERT(NPT_SUCCEEDED(result)); result = input->Tell(position); NPT_ASSERT(NPT_SUCCEEDED(result)); NPT_ASSERT(position == large_size); for (unsigned int i=0; i<0x107; i++) { NPT_ASSERT(buffer[i] == (unsigned char)i); } file.Close(); NPT_File::RemoveFile(file.GetPath()); // large files if (argc == 2) { result = CreateNewFile(argv[1], 0x10000, 0x10007); NPT_ASSERT(NPT_SUCCEEDED(result)); NPT_String new_name = argv[1]; new_name += ".renamed"; result = NPT_File::Rename(argv[1], new_name); NPT_ASSERT(NPT_SUCCEEDED(result)); file = NPT_File(new_name); result = file.Open(NPT_FILE_OPEN_MODE_READ); NPT_ASSERT(NPT_SUCCEEDED(result)); file.GetInputStream(input); result = input->Tell(position); NPT_ASSERT(NPT_SUCCEEDED(result)); NPT_ASSERT(position == 0); large_size = (NPT_LargeSize)0x10007 * (NPT_LargeSize)0x10000; result = input->Seek(large_size-0x10007); NPT_ASSERT(NPT_SUCCEEDED(result)); result = input->Tell(position); NPT_ASSERT(NPT_SUCCEEDED(result)); NPT_ASSERT(position == large_size-0x10007); buffer = new unsigned char[0x10007]; result = input->ReadFully(buffer, 0x10007); NPT_ASSERT(NPT_SUCCEEDED(result)); result = input->Tell(position); NPT_ASSERT(NPT_SUCCEEDED(result)); NPT_ASSERT(position == large_size); for (unsigned int i=0; i<0x10007; i++) { NPT_ASSERT(buffer[i] == (unsigned char)i); } file.Close(); NPT_File::RemoveFile(new_name); } // test dynamic size //NPT_LargeSize size; unsigned char buff[16] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}; const char* filename = "pi.\xCF\x80.test"; NPT_TimeInterval wait(2.0f); if (argc > 1) { filename = argv[1]; } NPT_File file1(filename); NPT_OutputStreamReference output; NPT_ASSERT(NPT_SUCCEEDED(file1.Open(NPT_FILE_OPEN_MODE_CREATE | NPT_FILE_OPEN_MODE_WRITE | NPT_FILE_OPEN_MODE_READ | NPT_FILE_OPEN_MODE_TRUNCATE))); NPT_ASSERT(NPT_SUCCEEDED(file1.GetSize(size))); NPT_ASSERT(size == 0); NPT_ASSERT(NPT_SUCCEEDED(file1.GetOutputStream(output))); NPT_ASSERT(NPT_SUCCEEDED(file1.GetInputStream(input))); NPT_ASSERT(NPT_SUCCEEDED(output->Tell(position))); NPT_ASSERT(position == 0); NPT_ASSERT(NPT_SUCCEEDED(input->Tell(position))); NPT_ASSERT(position == 0); NPT_ASSERT(NPT_SUCCEEDED(output->WriteFully(buff, 16))); output->Flush(); NPT_System::Sleep(wait); NPT_ASSERT(NPT_SUCCEEDED(file1.GetSize(size))); NPT_ASSERT(size == 16); NPT_ASSERT(NPT_SUCCEEDED(output->Tell(position))); NPT_ASSERT(NPT_SUCCEEDED(input->GetSize(size))); NPT_ASSERT(size == 16); NPT_ASSERT(position == 16); NPT_ASSERT(NPT_SUCCEEDED(input->Tell(position))); NPT_ASSERT(position == 16); NPT_ASSERT(NPT_SUCCEEDED(output->Seek(8))); NPT_ASSERT(NPT_SUCCEEDED(output->Tell(position))); NPT_ASSERT(position == 8); NPT_File file2(filename); NPT_InputStreamReference input2; NPT_ASSERT(NPT_SUCCEEDED(file2.Open(NPT_FILE_OPEN_MODE_READ))); NPT_ASSERT(NPT_SUCCEEDED(file2.GetSize(size))); NPT_ASSERT(size == 16); NPT_ASSERT(NPT_SUCCEEDED(file2.GetInputStream(input2))); NPT_ASSERT(NPT_SUCCEEDED(input2->GetSize(size))); NPT_ASSERT(size == 16); NPT_ASSERT(NPT_SUCCEEDED(input2->Tell(position))); NPT_ASSERT(position == 0); NPT_ASSERT(NPT_SUCCEEDED(input2->Seek(8))); NPT_ASSERT(NPT_SUCCEEDED(input2->Tell(position))); NPT_ASSERT(position == 8); NPT_ASSERT(NPT_SUCCEEDED(output->WriteFully(buff, 16))); output->Flush(); NPT_System::Sleep(wait); NPT_ASSERT(NPT_SUCCEEDED(file2.GetSize(size))); NPT_ASSERT(size == 24); NPT_ASSERT(NPT_SUCCEEDED(output->Tell(position))); NPT_ASSERT(position == 24); NPT_ASSERT(NPT_SUCCEEDED(input->Tell(position))); NPT_ASSERT(position == 24); NPT_ASSERT(NPT_SUCCEEDED(input2->GetSize(size))); NPT_ASSERT(size == 24); NPT_ASSERT(NPT_SUCCEEDED(input2->Seek(20))); NPT_ASSERT(NPT_SUCCEEDED(input2->Read(buff, 4, NULL))); return 0; }