void CharArrayBufferTest::testCompareTo() { // compare to self CPPUNIT_ASSERT( 0 == testBuffer1->compareTo( *testBuffer1 ) ); CPPUNIT_ASSERT( testBuffer1->capacity() > SMALL_TEST_LENGTH ); testBuffer1->clear(); CharBuffer* other = CharBuffer::allocate( testBuffer1->capacity() ); for( int ix = 0; ix < testData1Size; ++ix ){ testBuffer1->put( ix, testData1[ix] ); } for( int ix = 0; ix < testData1Size; ++ix ){ other->put( ix, testData1[ix] ); } CPPUNIT_ASSERT( 0 == testBuffer1->compareTo( *other ) ); CPPUNIT_ASSERT( 0 == other->compareTo( *testBuffer1 ) ); testBuffer1->position(1); CPPUNIT_ASSERT( testBuffer1->compareTo( *other ) > 0 ); CPPUNIT_ASSERT( other->compareTo( *testBuffer1 ) < 0 ); other->position( 2 ); CPPUNIT_ASSERT( testBuffer1->compareTo( *other ) < 0 ); CPPUNIT_ASSERT( other->compareTo( *testBuffer1 ) > 0 ); testBuffer1->position( 2 ); other->limit(SMALL_TEST_LENGTH); CPPUNIT_ASSERT( testBuffer1->compareTo( *other ) > 0 ); CPPUNIT_ASSERT( other->compareTo( *testBuffer1 ) < 0 ); char* data = new char[21]; memset( data, 0, 21 ); CharBuffer* empty = CharBuffer::allocate(21); CharBuffer* wrapped = CharBuffer::wrap( data, 21, 0, 21 ); CPPUNIT_ASSERT( wrapped->compareTo( *empty ) == 0 ); delete empty; delete wrapped; delete other; delete [] data; }
CFURLRef createCFURLFromBuffer(const CharBuffer& buffer) { // NOTE: We use UTF-8 here since this encoding is used when computing strings when returning URL components // (e.g calls to NSURL -path). However, this function is not tolerant of illegal UTF-8 sequences, which // could either be a malformed string or bytes in a different encoding, like Shift-JIS, so we fall back // onto using ISO Latin-1 in those cases. CFURLRef result = CFURLCreateAbsoluteURLWithBytes(0, reinterpret_cast<const UInt8*>(buffer.data()), buffer.size(), kCFStringEncodingUTF8, 0, true); if (!result) result = CFURLCreateAbsoluteURLWithBytes(0, reinterpret_cast<const UInt8*>(buffer.data()), buffer.size(), kCFStringEncodingISOLatin1, 0, true); return result; }
void WinConsole::SetupConfigFile() { // create new config-file from config template char commonAppDataPath[MAX_PATH]; SHGetFolderPath(nullptr, CSIDL_COMMON_APPDATA, nullptr, 0, commonAppDataPath); BString<1024> filename("%s\\NZBGet\\nzbget.conf", commonAppDataPath); BString<1024> appDataPath("%s\\NZBGet", commonAppDataPath); FileSystem::CreateDirectory(appDataPath); BString<1024> confTemplateFilename("%s\\nzbget.conf.template", g_Options->GetAppDir()); CopyFile(confTemplateFilename, filename, FALSE); // set MainDir in the config-file int size = 0; CharBuffer config; if (FileSystem::LoadFileIntoBuffer(filename, config, true)) { const char* SIGNATURE = "MainDir=${AppDir}\\downloads"; char* p = strstr(config, SIGNATURE); if (p) { DiskFile outfile; if (outfile.Open(filename, DiskFile::omWrite)) { outfile.Write(config, p - config); outfile.Write("MainDir=", 8); outfile.Write(appDataPath, strlen(appDataPath)); outfile.Write(p + strlen(SIGNATURE), config.Size() - 1 - (p + strlen(SIGNATURE) - config) - 1); outfile.Close(); } } } // create default destination directory (which is not created on start automatically) BString<1024> completeDir("%s\\NZBGet\\complete", commonAppDataPath); FileSystem::CreateDirectory(completeDir); }
void CharArrayBufferTest::testReadOnlyMap() { CharBuffer* cb = testBuffer1->asReadOnlyBuffer(); MyCharSequence cs( "String" ); CPPUNIT_ASSERT_THROW_MESSAGE( "Should throw a ReadOnlyBufferException", cb->append( 'A' ), ReadOnlyBufferException ); CPPUNIT_ASSERT_THROW_MESSAGE( "Should throw a ReadOnlyBufferException", cb->append( &cs ), ReadOnlyBufferException ); CPPUNIT_ASSERT_THROW_MESSAGE( "Should throw a ReadOnlyBufferException", cb->append( &cs, 1, 2 ), ReadOnlyBufferException ); delete cb; }
void CharArrayBufferTest::testAppendCharSequenceNormal() { CharBuffer* cb = CharBuffer::allocate(10); cb->put('A'); MyCharSequence cs( "String" ); CPPUNIT_ASSERT( cb == &( cb->append( &cs ) ) ); cb->flip(); CPPUNIT_ASSERT( MyCharSequence("AString").toString() == cb->toString() ); cb->append( (const lang::CharSequence*)NULL ); cb->flip(); CPPUNIT_ASSERT( cb->toString() == "null" ); delete cb; }
void CharArrayBufferTest::testAppendCharSequenceIINormal() { CharBuffer* cb = CharBuffer::allocate( 10 ); cb->put( 'A' ); MyCharSequence cs( "String" ); CPPUNIT_ASSERT( cb == &( cb->append( &cs, 1, 3 ) ) ); cb->flip(); CPPUNIT_ASSERT( "Atr" == cb->toString() ); cb->append( (const lang::CharSequence*)NULL, 0, 1 ); cb->flip(); CPPUNIT_ASSERT( "n" == cb->toString() ); delete cb; }
bool RarVolume::ReadRar3File(DiskFile& file, RarBlock& block, RarFile& innerFile) { innerFile.m_splitBefore = block.flags & RAR3_FILE_SPLITBEFORE; innerFile.m_splitAfter = block.flags & RAR3_FILE_SPLITAFTER; uint16 namelen; uint32 size; if (!Read32(file, &block, &size)) return false; innerFile.m_size = size; if (!Skip(file, &block, 1)) return false; if (!Skip(file, &block, 4)) return false; if (!Read32(file, &block, &innerFile.m_time)) return false; if (!Skip(file, &block, 2)) return false; if (!Read16(file, &block, &namelen)) return false; if (!Read32(file, &block, &innerFile.m_attr)) return false; if (block.flags & RAR3_FILE_ADDSIZE) { uint32 highsize; if (!Read32(file, &block, &highsize)) return false; block.trailsize += (uint64)highsize << 32; if (!Read32(file, &block, &highsize)) return false; innerFile.m_size += (uint64)highsize << 32; } if (namelen > 8192) return false; // an error CharBuffer name; name.Reserve(namelen + 1); if (!Read(file, &block, (char*)name, namelen)) return false; name[namelen] = '\0'; innerFile.m_filename = name; debug("%i, %i, %s", (int)block.trailsize, (int)namelen, (const char*)name); return true; }
void CharArrayBufferTest::testReadOverflow() { std::vector<char> buffer; buffer.push_back('S'); CharBuffer* source = CharBuffer::wrap( buffer ); CharBuffer* target = CharBuffer::allocate( 1 ); CPPUNIT_ASSERT( 1 == source->read(target) ); target->flip(); CPPUNIT_ASSERT( "S" == target->toString() ); CPPUNIT_ASSERT( 1 == source->position() ); delete source; delete target; }
PathName SessionImpl::GetMyProgramFile(bool canonicalized) { // we do this once if (myProgramFile.Empty()) { #if defined(__APPLE__) CharBuffer<char> buf; uint32_t bufsize = buf.GetCapacity(); if (_NSGetExecutablePath(buf.GetData(), &bufsize) < 0) { buf.Reserve(bufsize); if (_NSGetExecutablePath(buf.GetData(), &bufsize) != 0) { MIKTEX_UNEXPECTED(); } } myProgramFile = buf.GetData(); #else string invocationName = initInfo.GetProgramInvocationName(); if (invocationName.empty()) { MIKTEX_FATAL_ERROR(T_("No invocation name has been set.")); } if (Utils::IsAbsolutePath(invocationName.c_str())) { myProgramFile = invocationName; } else if (invocationName.length() > 3 && (invocationName.substr(0, 2) == "./" || invocationName.substr(0, 3) == "../")) { myProgramFile = GetFullPath(invocationName.c_str()); } else if (!Utils::FindProgram(invocationName, myProgramFile)) { MIKTEX_FATAL_ERROR_2(T_("The invoked program could not be found in the PATH."), "invocationName", invocationName); } #endif myProgramFileCanon = myProgramFile; myProgramFileCanon.Canonicalize(); } if (canonicalized) { return myProgramFileCanon; } else { return myProgramFile; } }
String FileAccess::get_line() const { CharBuffer line; CharType c = get_8(); while (!eof_reached()) { if (c == '\n' || c == '\0') { line.push_back(0); return String::utf8(line.get_data()); } else if (c != '\r') line.push_back(c); c = get_8(); } line.push_back(0); return String::utf8(line.get_data()); }
void CharArrayBufferTest::testEquals() { // equal to self CPPUNIT_ASSERT( testBuffer1->equals( *testBuffer1 ) ); CharBuffer* readOnly = testBuffer1->asReadOnlyBuffer(); CPPUNIT_ASSERT( testBuffer1->equals( *readOnly ) ); CharBuffer* duplicate = testBuffer1->duplicate(); CPPUNIT_ASSERT( testBuffer1->equals( *duplicate ) ); CPPUNIT_ASSERT( testBuffer1->capacity() > SMALL_TEST_LENGTH ); testBuffer1->limit( testBuffer1->capacity() ).position( 0 ); readOnly->limit( readOnly->capacity() ).position( 1 ); CPPUNIT_ASSERT( !testBuffer1->equals( *readOnly ) ); testBuffer1->limit( testBuffer1->capacity() - 1 ).position( 0 ); duplicate->limit( duplicate->capacity() ).position( 0 ); CPPUNIT_ASSERT( !testBuffer1->equals( *duplicate ) ); delete readOnly; delete duplicate; }
void BinHTTPInputStreamCommon::createHTTPRequest(const XMLURL &urlSource, const XMLNetHTTPInfo *httpInfo, CharBuffer &buffer) { static const char *GET = "GET "; static const char *PUT = "PUT "; static const char *POST = "POST "; static const char *HTTP10 = " HTTP/1.0\r\n"; static const char *HOST = "Host: "; static const char *AUTHORIZATION = "Authorization: Basic "; static const char *COLON = ":"; XMLTransService::Codes failReason; const XMLSize_t blockSize = 2048; XMLTranscoder* trans = XMLPlatformUtils::fgTransService->makeNewTranscoderFor("ISO8859-1", failReason, blockSize, fMemoryManager); Janitor<XMLTranscoder> janTrans(trans); TranscodeToStr hostName(urlSource.getHost(), trans, fMemoryManager); TranscodeToStr path(urlSource.getPath(), trans, fMemoryManager); TranscodeToStr fragment(urlSource.getFragment(), trans, fMemoryManager); TranscodeToStr query(urlSource.getQuery(), trans, fMemoryManager); // Build up the http GET command to send to the server. // To do: We should really support http 1.1. This implementation // is weak. if(httpInfo) { switch(httpInfo->fHTTPMethod) { case XMLNetHTTPInfo::GET: buffer.append(GET); break; case XMLNetHTTPInfo::PUT: buffer.append(PUT); break; case XMLNetHTTPInfo::POST: buffer.append(POST); break; } } else { buffer.append(GET); } if(path.str() != 0) { buffer.append((char*)path.str()); } else { buffer.append("/"); } if(query.str() != 0) { buffer.append("?"); buffer.append((char*)query.str()); } if(fragment.str() != 0) { buffer.append((char*)fragment.str()); } buffer.append(HTTP10); buffer.append(HOST); buffer.append((char*)hostName.str()); if(urlSource.getPortNum() != 80) { buffer.append(COLON); buffer.appendDecimalNumber(urlSource.getPortNum()); } buffer.append(CRLF); const XMLCh *username = urlSource.getUser(); const XMLCh *password = urlSource.getPassword(); if(username && password) { XMLBuffer userPassBuf(256, fMemoryManager); userPassBuf.append(username); userPassBuf.append(chColon); userPassBuf.append(password); TranscodeToStr userPass(userPassBuf.getRawBuffer(), trans, fMemoryManager); XMLSize_t len; XMLByte* encodedData = Base64::encode(userPass.str(), userPass.length(), &len, fMemoryManager); ArrayJanitor<XMLByte> janBuf2(encodedData, fMemoryManager); if(encodedData) { // HTTP doesn't want the 0x0A separating the data in chunks of 76 chars per line XMLByte* authData = (XMLByte*)fMemoryManager->allocate((len+1)*sizeof(XMLByte)); ArrayJanitor<XMLByte> janBuf(authData, fMemoryManager); XMLByte *cursor = authData; for(XMLSize_t i = 0; i < len; ++i) if(encodedData[i] != chLF) *cursor++ = encodedData[i]; *cursor++ = 0; buffer.append(AUTHORIZATION); buffer.append((char*)authData); buffer.append(CRLF); } } if(httpInfo && httpInfo->fHeaders) buffer.append(httpInfo->fHeaders, httpInfo->fHeadersLen); buffer.append(CRLF); }
int CLI::pollEvent(GRE::Event &ev) { struct pollfd fd; bool food = false; char ch; int idx; int r; if (!m_enabled) return -1; idx = 0; do { fd.fd = STDIN_FILENO; fd.events = POLLIN | POLLRDHUP; fd.revents = 0; r = poll(&fd, 1, 0); if (r < 0) { m_enabled = false; return -1; } else if (r == 0) { break; } if (fd.revents & POLLRDHUP) { m_enabled = false; return -1; } else { r = read(STDIN_FILENO, &ch, 1); if (r == 1) { m_buffer->push(ch); } else { m_enabled = false; return -1; } } } while (r > 0); while (m_buffer->size()) { food = true; switch ((ch = m_buffer->pop())) { case 0xd: case 0x20: ev.type = GRE::Event::Next; break; case 'q': ev.type = GRE::Event::Quit; break; case 'h': ev.type = GRE::Event::HaltToggle; break; case 'F': ev.type = GRE::Event::FilterToggle; break; case 'f': ev.type = GRE::Event::FullscreenToggle; break; case 0x1b: if (m_buffer->size() < 2) { ev.type = GRE::Event::Quit; break; } if (!memcmp(m_buffer->peek(), "[C", 2)) { ev.type = GRE::Event::Next; m_buffer->pop(), m_buffer->pop(); break; } if (!memcmp(m_buffer->peek(), "[D", 2)) { ev.type = GRE::Event::Prev; m_buffer->pop(), m_buffer->pop(); break; } food = false; break; default: food = false; break; } if (food) break; } return -(food == false); }
void run() { // start server thread _myAcceptor = AcceptorPtr(new ConduitAcceptor<POLICY>(_myLocalEndpoint, myLowercaseServer<POLICY>::create)); ENSURE(_myAcceptor->start()); // XXX uncomment this to play with telnet //while (true); // start client { CharBuffer myInputBuffer; typename Conduit<POLICY>::Ptr myClient(new Conduit<POLICY>(_myLocalEndpoint)); ENSURE(myClient); setSilentSuccess(true); for (int i = 0; i < 20; ++i) { myClient->sendData("HELLO",5); while (!myClient->receiveData(myInputBuffer)) { myClient->handleIO(10); } ENSURE(myInputBuffer.size()==5); ENSURE(strncmp(&myInputBuffer[0],"hello",5)==0); } setSilentSuccess(false); // now send something, but don't pick up the reply myClient->sendData("GOOD BYE!",5); } msleep(100); // Stress Test setSilentSuccess(true); for (int i=0; i < 20; ++i) { CharBuffer myInputBuffer(5,0); typename Conduit<POLICY>::Ptr myClient(new Conduit<POLICY>(_myLocalEndpoint)); ENSURE(myClient); //msleep(100); string myOutput("Q"); myOutput += as_string(i); ENSURE(myClient->sendData(myOutput.c_str(), myOutput.length())); while (!myClient->receiveData(myInputBuffer)) { myClient->handleIO(10); } //cerr << "sent '" << myOutput << "', recv '" << &(myInputBuffer[0]) << "'" << endl; ENSURE(myInputBuffer.size()==myOutput.length()); string myExpectedReply("q"); myExpectedReply += as_string(i); ENSURE_MSG(strncmp(&myInputBuffer[0],myExpectedReply.c_str(),myInputBuffer.size())==0, " iterations."); } setSilentSuccess(false); // now start two clients simultaneously { CharBuffer myInputBuffer1; typename Conduit<POLICY>::Ptr myClient1(new Conduit<POLICY>(_myLocalEndpoint)); ENSURE(myClient1); CharBuffer myInputBuffer2; typename Conduit<POLICY>::Ptr myClient2(new Conduit<POLICY>(_myLocalEndpoint)); ENSURE(myClient2); myClient2->sendData("WORLD",5); myClient1->sendData("HELLO",5); bool myWaiting1 = true; bool myWaiting2 = true; while (myWaiting1 || myWaiting2) { if (myWaiting1 && myClient1->receiveData(myInputBuffer1)) { myWaiting1 = false; }; if (myWaiting2 && myClient2->receiveData(myInputBuffer2)) { myWaiting2 = false; }; } ENSURE(strncmp(&myInputBuffer1[0],"hello",5)==0); ENSURE(strncmp(&myInputBuffer2[0],"world",5)==0); } // how about a really big string { std::string myBigString; for (int i = 0; i<10000; ++i) { myBigString += as_string(i); } CharBuffer myInputBuffer; typename Conduit<POLICY>::Ptr myClient(new Conduit<POLICY>(_myLocalEndpoint)); ENSURE(myClient); ENSURE(myClient->sendData(myBigString.c_str(), myBigString.length())); string myReceiveString; while (myReceiveString.length() < myBigString.length() && myClient->isValid()) { if (myClient->receiveData(myInputBuffer)) { myReceiveString += string(&myInputBuffer[0], myInputBuffer.size()); } } ENSURE(myReceiveString == myBigString); } // check already-is-use behaviour { AcceptorPtr myAcceptor; ENSURE_EXCEPTION(myAcceptor = AcceptorPtr(new ConduitAcceptor<POLICY>(_myLocalEndpoint, myLowercaseServer<POLICY>::create)), ConduitInUseException); } // close the server (also test if the server is cancelable) msleep(100); ENSURE_MSG(_myAcceptor->stop(), "Cancelling server thread"); msleep(100); _myAcceptor = AcceptorPtr(0); }
bool RarVolume::ReadRar5File(DiskFile& file, RarBlock& block, RarFile& innerFile) { innerFile.m_splitBefore = block.flags & RAR5_BLOCK_SPLITBEFORE; innerFile.m_splitAfter = block.flags & RAR5_BLOCK_SPLITAFTER; uint64 val; uint64 fileflags; if (!ReadV(file, &block, &fileflags)) return false; if (!ReadV(file, &block, &val)) return false; // skip innerFile.m_size = (int64)val; if (!ReadV(file, &block, &val)) return false; innerFile.m_attr = (uint32)val; if (fileflags & RAR5_FILE_TIME && !Read32(file, &block, &innerFile.m_time)) return false; if (fileflags & RAR5_FILE_CRC && !Skip(file, &block, 4)) return false; if (!ReadV(file, &block, &val)) return false; // skip if (!ReadV(file, &block, &val)) return false; // skip uint64 namelen; if (!ReadV(file, &block, &namelen)) return false; if (namelen > 8192) return false; // an error CharBuffer name; name.Reserve((uint32)namelen + 1); if (!Read(file, &block, (char*)name, namelen)) return false; name[namelen] = '\0'; innerFile.m_filename = name; // reading extra headers to find file time if (block.flags & RAR5_BLOCK_EXTRADATA) { uint64 remsize = block.addsize; while (remsize > 0) { uint64 trailsize = block.trailsize; uint64 len; if (!ReadV(file, &block, &len)) return false; remsize -= trailsize - block.trailsize + len; trailsize = block.trailsize; uint64 type; if (!ReadV(file, &block, &type)) return false; if (type == RAR5_FILE_EXTRATIME) { uint64 flags; if (!ReadV(file, &block, &flags)) return false; if (flags & RAR5_FILE_EXTRATIMEUNIXFORMAT) { if (!Read32(file, &block, &innerFile.m_time)) return false; } else { uint32 timelow, timehigh; if (!Read32(file, &block, &timelow)) return false; if (!Read32(file, &block, &timehigh)) return false; uint64 wintime = ((uint64)timehigh << 32) + timelow; innerFile.m_time = (uint32)(wintime / 10000000 - 11644473600LL); } } len -= trailsize - block.trailsize; if (!Skip(file, &block, len)) return false; } } debug("%llu, %i, %s", (long long)block.trailsize, (int)namelen, (const char*)name); return true; }
void TarExtractor::Extract (/*[in]*/ Stream * pStreamIn_, /*[in]*/ const PathName & destDir, /*[in]*/ bool makeDirectories, /*[in]*/ IExtractCallback * pCallback, /*[in]*/ const char * lpszPrefix) { try { pStreamIn = pStreamIn_; totalBytesRead = 0; traceStream->WriteFormattedLine ("libextractor", T_("extracting to %s (%s)"), Q_(destDir), (makeDirectories ? T_("make directories") : T_("don't make directories"))); size_t len; Header header; size_t prefixLen = (lpszPrefix == 0 ? 0 : StrLen(lpszPrefix)); unsigned fileCount = 0; bool checkHeader = true; CharBuffer<char> buffer; buffer.Reserve (1024 * 1024); while ((len = Read(&header, sizeof(header))) > 0) { // read next header if (len != sizeof(header)) { FATAL_EXTRACTOR_ERROR ("TarExtractor::Extract", T_("Invalid package archive file."), 0); } if (header.IsEndOfArchive()) { break; } if (checkHeader) { if (! header.Check()) { FATAL_EXTRACTOR_ERROR ("TarExtractor::Extract", T_("Invalid package archive file."), 0); } #if ! defined(MIKTEX_DEBUG) checkHeader = false; #endif } PathName dest = header.GetFileName(); size_t size = header.GetFileSize(); if (! header.IsNormalFile()) { if (header.GetType() == Header::LongName) { if (size >= BLOCKSIZE) { UNEXPECTED_CONDITION ("TarExtractor::Extract"); } char longNameData[BLOCKSIZE]; ReadBlock (longNameData); longNameData[size] = 0; longName = longNameData; haveLongName = true; } else { Skip (((size + sizeof(Header) - 1) / sizeof(Header)) * sizeof(Header)); } continue; } if (haveLongName) { dest = longName; haveLongName = false; } // skip directory prefix if (lpszPrefix != 0 && PathName::Compare(lpszPrefix, dest, prefixLen) == 0) { PathName tmp (dest); dest = tmp.Get() + prefixLen; } // make the destination path name PathName path (destDir); if (! makeDirectories) { dest.RemoveDirectorySpec (); } path += dest; // notify the client if (pCallback != 0) { pCallback->OnBeginFileExtraction (path.Get(), size); } // create the destination directory Directory::Create (PathName(path).RemoveFileSpec()); // remove the existing file if (File::Exists(path)) { File::Delete (path, true); } // extract the file FileStream streamOut (File::Open(path, FileMode::Create, FileAccess::Write, false)); size_t bytesRead = 0; while (bytesRead < size) { size_t remaining = size - bytesRead; size_t n = (remaining > buffer.GetCapacity() ? buffer.GetCapacity() : remaining); if (Read(buffer.GetBuffer(), n) != n) { FATAL_EXTRACTOR_ERROR ("TarExtractor::Extract", T_("Invalid package archive file."), 0); } streamOut.Write (buffer.Get(), n); bytesRead += n; } streamOut.Close (); // skip extra bytes if (bytesRead % sizeof(Header) > 0) { Skip (sizeof(Header) - bytesRead % sizeof(Header)); } fileCount += 1; // set time when the file was created time_t time = header.GetLastModificationTime(); File::SetTimes (path, time, time, time); #if 0 // set file attributes File::SetAttributes (path, todo); #endif // notify the client if (pCallback != 0) { pCallback->OnEndFileExtraction (0, size); } } traceStream->WriteFormattedLine ("libextractor", T_("extracted %u file(s)"), fileCount); } catch (const exception &) { traceStream->WriteFormattedLine ("libextractor", T_("%u bytes were read from the tar stream"), static_cast<unsigned>(totalBytesRead)); throw; } }
void CharArrayBufferTest::testAppendSelf() { CharBuffer* cb = CharBuffer::allocate(10); CharBuffer* cb2 = cb->duplicate(); cb->append( cb ); CPPUNIT_ASSERT( 10 == cb->position() ); cb->clear(); CPPUNIT_ASSERT( cb2->equals( *cb ) ); delete cb2; cb->put( "abc" ); cb2 = cb->duplicate(); cb->append( cb ); CPPUNIT_ASSERT( 10 == cb->position() ); cb->clear(); cb2->clear(); CPPUNIT_ASSERT( cb2->equals( *cb ) ); delete cb2; cb->put( "edfg" ); cb->clear(); cb2 = cb->duplicate(); cb->append( cb ); CPPUNIT_ASSERT( 10 == cb->position() ); cb->clear(); cb2->clear(); CPPUNIT_ASSERT( cb->equals( *cb2 ) ); delete cb; delete cb2; }
void CharArrayBufferTest::testSlice() { CPPUNIT_ASSERT( testBuffer1->capacity() > SMALL_TEST_LENGTH ); testBuffer1->position( 1 ); testBuffer1->limit( testBuffer1->capacity() - 1 ); CharBuffer* slice = testBuffer1->slice(); CPPUNIT_ASSERT( testBuffer1->isReadOnly() == slice->isReadOnly() ); CPPUNIT_ASSERT( slice->position() == 0 ); CPPUNIT_ASSERT( slice->limit() == testBuffer1->remaining() ); CPPUNIT_ASSERT( slice->capacity() == testBuffer1->remaining() ); CPPUNIT_ASSERT_THROW_MESSAGE( "Should throw a InvalidMarkException", slice->reset(), InvalidMarkException ); // slice share the same content with buf for( int ix = 0; ix < slice->capacity(); ++ix ){ slice->put( ix, testData1[ix] ); } for( int ix = 0; ix < slice->capacity(); ix++ ) { CPPUNIT_ASSERT( testBuffer1->get( ix + 1 ) == slice->get( ix ) ); } testBuffer1->put( 2, 100 ); CPPUNIT_ASSERT( slice->get(1) == 100 ); delete slice; }
void CharArrayBufferTest::testPutCharBuffer() { CharBuffer* other = CharBuffer::allocate( testBuffer1->capacity() ); CharBuffer* readOnly = testBuffer1->asReadOnlyBuffer(); readOnly->clear(); CPPUNIT_ASSERT_THROW_MESSAGE( "Should throw a ReadOnlyBufferException", readOnly->put( *other ), ReadOnlyBufferException ); delete readOnly; CPPUNIT_ASSERT_THROW_MESSAGE( "Should throw a IllegalArgumentException", testBuffer1->put( *testBuffer1 ), IllegalArgumentException ); CharBuffer* toBig = testBuffer1->allocate( testBuffer1->capacity() + 1 ); toBig->clear(); CPPUNIT_ASSERT_THROW_MESSAGE( "Should throw a BufferOverflowException", testBuffer1->put( *toBig ), BufferOverflowException ); delete toBig; for( int ix = 0; ix < testData1Size; ++ix ){ other->put( ix, testData1[ix] ); } other->clear(); testBuffer1->clear(); CharBuffer& ret = testBuffer1->put( *other ); CPPUNIT_ASSERT( other->position() == other->capacity() ); CPPUNIT_ASSERT( testBuffer1->position() == testBuffer1->capacity() ); for( int ix = 0; ix < testBuffer1->capacity() - 1; ix++ ) { CPPUNIT_ASSERT( testBuffer1->get( ix ) == other->get( ix ) ); } CPPUNIT_ASSERT( &ret == testBuffer1 ); delete other; }
bool Frontend::RequestFileList() { const char* controlIp = !strcmp(g_Options->GetControlIp(), "0.0.0.0") ? "127.0.0.1" : g_Options->GetControlIp(); Connection connection(controlIp, g_Options->GetControlPort(), false); bool OK = connection.Connect(); if (!OK) { return false; } SNzbListRequest ListRequest; InitMessageBase(&ListRequest.m_messageBase, rrList, sizeof(ListRequest)); ListRequest.m_fileList = htonl(m_fileList); ListRequest.m_serverState = htonl(m_summary); if (!connection.Send((char*)(&ListRequest), sizeof(ListRequest))) { return false; } // Now listen for the returned list SNzbListResponse ListResponse; bool read = connection.Recv((char*) &ListResponse, sizeof(ListResponse)); if (!read || (int)ntohl(ListResponse.m_messageBase.m_signature) != (int)NZBMESSAGE_SIGNATURE || ntohl(ListResponse.m_messageBase.m_structSize) != sizeof(ListResponse)) { return false; } CharBuffer buf; if (ntohl(ListResponse.m_trailingDataLength) > 0) { buf.Reserve(ntohl(ListResponse.m_trailingDataLength)); if (!connection.Recv(buf, buf.Size())) { return false; } } connection.Disconnect(); if (m_summary) { m_pauseDownload = ntohl(ListResponse.m_downloadPaused); m_remainingSize = Util::JoinInt64(ntohl(ListResponse.m_remainingSizeHi), ntohl(ListResponse.m_remainingSizeLo)); m_currentDownloadSpeed = ntohl(ListResponse.m_downloadRate); m_downloadLimit = ntohl(ListResponse.m_downloadLimit); m_threadCount = ntohl(ListResponse.m_threadCount); m_postJobCount = ntohl(ListResponse.m_postJobCount); m_upTimeSec = ntohl(ListResponse.m_upTimeSec); m_dnTimeSec = ntohl(ListResponse.m_downloadTimeSec); m_standBy = ntohl(ListResponse.m_downloadStandBy); m_allBytes = Util::JoinInt64(ntohl(ListResponse.m_downloadedBytesHi), ntohl(ListResponse.m_downloadedBytesLo)); } if (m_fileList && ntohl(ListResponse.m_trailingDataLength) > 0) { RemoteClient client; client.SetVerbose(false); client.BuildFileList(&ListResponse, buf, DownloadQueue::Guard()); } return true; }
bool TwoWayReply::parse(RFC822Message *msg) { // Parse the message in <msg>. Parsing continues until all data has // been read. If an item is specified multiple times, only the // first will be used. If parsing is not successful, the individual // Reply methods may be used to see what information was // successfully read. // Returns: true if all items were successfully parsed from the message, // false otherwise. bool ret = false; #if defined(DEBUG) dlog->log_entry(DEBUG_MAJTRC, "TwoWayReply::parse(%d)", msg); dlog->log_progress(DEBUG_PARSER, "Trying to parse message as Nextel reply"); #endif if(msg) { // First, get stuff from the headers char *mf = msg->header_entry("From", 0); if(mf) { #if defined(DEBUG) dlog->log_progress(DEBUG_PARSER, "Message from '%s'", mf); #endif f = xstrdup(mf); } char *ms = msg->header_entry("Subject", 0); if(ms) { // Pull out hostname and service char *p = strstr(ms, "ALERT: "); if(p) { p += 7; List *ts = tokenize(p, "@"); if(ts) { // This was backwards, bug #635 // Patched by Olivier Calle svc = xstrdup(ts->retrieve(0)); h = xstrdup(ts->retrieve(1)); #if defined(DEBUG) dlog->log_progress(DEBUG_PARSER, "Host '%s', service '%s'", h, svc); #endif xdelete(ts); } } } // Now get the rest of the info from the body CharBuffer *body = msg->body(); if(body) { for(char *s = body->read_line();s != NULL;s = body->read_line()) { if(!t && strncmp(s, "Token=", 6)==0) { // Pull out token t = xstrdup(s+6); #if defined(DEBUG) dlog->log_progress(DEBUG_PARSER, "Token '%s'", t); #endif } else if(!inst && strncmp(s, "Instance=", 9)==0) { // Pull out instance inst = xstrdup(s+9); #if defined(DEBUG) dlog->log_progress(DEBUG_PARSER, "Instance '%s'", inst); #endif } else if(ry == unknown_reply && strcmp(s, "Acknowledge")==0) { ry = acknowledge_reply; #if defined(DEBUG) dlog->log_progress(DEBUG_PARSER, "Reply command '%s'", s); #endif } else if(ry == unknown_reply && strcmp(s, "Escalate")==0) { ry = escalate_reply; #if defined(DEBUG) dlog->log_progress(DEBUG_PARSER, "Reply command '%s'", s); #endif } else if(ry == unknown_reply && strcmp(s, "Inhibit")==0) { ry = inhibit_reply; #if defined(DEBUG) dlog->log_progress(DEBUG_PARSER, "Reply command '%s'", s); #endif } } } if(f && h && inst && svc && t && (ry != unknown_reply)) ret = true; } #if defined(DEBUG) dlog->log_exit(DEBUG_MAJTRC, "TwoWayReply::parse = %s", IOTF(ret)); #endif return(ret); }
void CharSource::ConstCharPtr::ReleaseString(CharBuffer & buffer) { const char * begin = PopPtr(); buffer.Append(begin, ptr_); }
// Read a BAM file's header. bool BamInterface::readHeader(IFILE filePtr, SamFileHeader& header, SamStatus& status) { if(filePtr == NULL) { // File is not open, return false. status.setStatus(SamStatus::FAIL_ORDER, "Cannot read header since the file pointer is null"); return(false); } if(filePtr->isOpen() == false) { status.setStatus(SamStatus::FAIL_ORDER, "Cannot read header since the file is not open"); return(false); } // Clear the passed in header. header.resetHeader(); int32_t headerLength; int readSize = ifread(filePtr, &headerLength, sizeof(headerLength)); if(readSize != sizeof(headerLength)) { String errMsg = "Failed to read the BAM header length, read "; errMsg += readSize; errMsg += " bytes instead of "; errMsg += (unsigned int)sizeof(headerLength); status.setStatus(SamStatus::FAIL_IO, errMsg.c_str()); return(false); } String headerStr; if(headerLength > 0) { // Read the header. readSize = ifread(filePtr, headerStr.LockBuffer(headerLength + 1), headerLength); headerStr[headerLength] = 0; headerStr.UnlockBuffer(); if(readSize != headerLength) { // Failed to read the header. status.setStatus(SamStatus::FAIL_IO, "Failed to read the BAM header."); return(false); } } // Parse the header that was read. if(!header.addHeader(headerStr)) { // Status is set in the method on failure. status.setStatus(SamStatus::FAIL_PARSE, header.getErrorMessage()); return(false); } int referenceCount; // Read the number of references sequences. ifread(filePtr, &referenceCount, sizeof(int)); // Get and clear the reference info so it can be set // from the bam reference table. SamReferenceInfo& refInfo = header.getReferenceInfoForBamInterface(); refInfo.clear(); CharBuffer refName; // Read each reference sequence for (int i = 0; i < referenceCount; i++) { int nameLength; int rc; // Read the length of the reference name. rc = ifread(filePtr, &nameLength, sizeof(int)); if(rc != sizeof(int)) { status.setStatus(SamStatus::FAIL_IO, "Failed to read the BAM reference dictionary."); return(false); } // Read the name. refName.readFromFile(filePtr, nameLength); // Read the length of the reference sequence. int32_t refLen; rc = ifread(filePtr, &refLen, sizeof(int)); if(rc != sizeof(int)) { status.setStatus(SamStatus::FAIL_IO, "Failed to read the BAM reference dictionary."); return(false); } refInfo.add(refName.c_str(), refLen); } // Successfully read the file. return(true); }
bool Frontend::RequestMessages() { const char* controlIp = !strcmp(g_Options->GetControlIp(), "0.0.0.0") ? "127.0.0.1" : g_Options->GetControlIp(); Connection connection(controlIp, g_Options->GetControlPort(), false); bool OK = connection.Connect(); if (!OK) { return false; } SNzbLogRequest LogRequest; InitMessageBase(&LogRequest.m_messageBase, rrLog, sizeof(LogRequest)); LogRequest.m_lines = htonl(m_neededLogEntries); if (m_neededLogEntries == 0) { LogRequest.m_idFrom = htonl(m_neededLogFirstId > 0 ? m_neededLogFirstId : 1); } else { LogRequest.m_idFrom = 0; } if (!connection.Send((char*)(&LogRequest), sizeof(LogRequest))) { return false; } // Now listen for the returned log SNzbLogResponse LogResponse; bool read = connection.Recv((char*) &LogResponse, sizeof(LogResponse)); if (!read || (int)ntohl(LogResponse.m_messageBase.m_signature) != (int)NZBMESSAGE_SIGNATURE || ntohl(LogResponse.m_messageBase.m_structSize) != sizeof(LogResponse)) { return false; } CharBuffer buf; if (ntohl(LogResponse.m_trailingDataLength) > 0) { buf.Reserve(ntohl(LogResponse.m_trailingDataLength)); if (!connection.Recv(buf, buf.Size())) { return false; } } connection.Disconnect(); if (ntohl(LogResponse.m_trailingDataLength) > 0) { char* bufPtr = (char*)buf; for (uint32 i = 0; i < ntohl(LogResponse.m_nrTrailingEntries); i++) { SNzbLogResponseEntry* logAnswer = (SNzbLogResponseEntry*) bufPtr; char* text = bufPtr + sizeof(SNzbLogResponseEntry); m_remoteMessages.emplace_back(ntohl(logAnswer->m_id), (Message::EKind)ntohl(logAnswer->m_kind), ntohl(logAnswer->m_time), text); bufPtr += sizeof(SNzbLogResponseEntry) + ntohl(logAnswer->m_textLen); } } return true; }
void CharArrayBufferTest::testCompact() { // readonly's contents should be the same as buf CharBuffer* readOnly = testBuffer1->asReadOnlyBuffer(); CPPUNIT_ASSERT_THROW_MESSAGE( "Should throw a ReadOnlyBufferExceptio", readOnly->compact(), ReadOnlyBufferException ); // case: buffer is full testBuffer1->clear(); testBuffer1->mark(); for( int ix = 0; ix < testData1Size; ++ix ){ testBuffer1->put( ix, testData1[ix] ); } CharBuffer& ret = testBuffer1->compact(); CPPUNIT_ASSERT( &ret == testBuffer1 ); CPPUNIT_ASSERT( testBuffer1->position() == testBuffer1->capacity() ); CPPUNIT_ASSERT( testBuffer1->limit() == testBuffer1->capacity() ); for( int ix = 0; ix < testBuffer1->capacity(); ix++ ) { CPPUNIT_ASSERT( testBuffer1->get( ix ) == testData1[ix] ); } CPPUNIT_ASSERT_THROW_MESSAGE( "Should throw a InvalidMarkException", readOnly->reset(), InvalidMarkException ); delete readOnly; // case: buffer is empty testBuffer1->position(0); testBuffer1->limit(0); testBuffer1->mark(); ret = testBuffer1->compact(); CPPUNIT_ASSERT( &ret == testBuffer1 ); CPPUNIT_ASSERT( testBuffer1->position() == 0 ); CPPUNIT_ASSERT( testBuffer1->limit() == testBuffer1->capacity() ); for( int ix = 0; ix < testBuffer1->capacity(); ix++ ) { CPPUNIT_ASSERT( testBuffer1->get( ix ) == testData1[ix] ); } CPPUNIT_ASSERT_THROW_MESSAGE( "Should throw a InvalidMarkException", testBuffer1->reset(), InvalidMarkException ); // case: normal testBuffer1->position(1); testBuffer1->limit(SMALL_TEST_LENGTH); testBuffer1->mark(); ret = testBuffer1->compact(); CPPUNIT_ASSERT( &ret == testBuffer1 ); CPPUNIT_ASSERT( testBuffer1->position() == SMALL_TEST_LENGTH - 1 ); CPPUNIT_ASSERT( testBuffer1->limit() == testBuffer1->capacity() ); for( int ix = 0; ix < SMALL_TEST_LENGTH - 1; ix++ ) { CPPUNIT_ASSERT( testBuffer1->get( ix ) == testData1[ix + 1] ); } CPPUNIT_ASSERT_THROW_MESSAGE( "Should throw a InvalidMarkException", testBuffer1->reset(), InvalidMarkException ); }
// see Q246772 bool Utils::GetDefPrinter(string& printerName) { OSVERSIONINFOW osv; osv.dwOSVersionInfoSize = sizeof(OSVERSIONINFOW); GetVersionExW(&osv); if (osv.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) { #if defined(MIKTEX_SUPPORT_LEGACY_WINDOWS) unsigned long dwNeeded, dwReturned; EnumPrintersW(PRINTER_ENUM_DEFAULT, 0, 2, 0, 0, &dwNeeded, &dwReturned); if (dwNeeded == 0) { return false; } AutoGlobalMemory hMem(GlobalAlloc(GPTR, dwNeeded)); if (hMem.Get() == nullptr) { OUT_OF_MEMORY("GlobalAlloc"); } PRINTER_INFO_2W* ppi2 = reinterpret_cast<PRINTER_INFO_2W *>(hMem.Get()); if (!EnumPrintersW(PRINTER_ENUM_DEFAULT, 0, 2, reinterpret_cast<LPBYTE>(ppi2), dwNeeded, &dwNeeded, &dwReturned)) { return false; } size_t l = StrLen(ppi2->pPrinterName); if (l >= *pBufferSize) { *pBufferSize = l + 1; return false; } StringUtil::CopyString(pPrinterName, *pBufferSize, ppi2->pPrinterName); *pBufferSize = l + 1; return true; #else UNSUPPORTED_PLATFORM(); #endif } else { if (osv.dwPlatformId != VER_PLATFORM_WIN32_NT) { MIKTEX_UNEXPECTED(); } if (osv.dwMajorVersion >= 5) { CharBuffer<wchar_t> printerNameBuf; DWORD dwBufferSize = static_cast<DWORD>(printerNameBuf.GetCapacity()); BOOL bDone = GetDefaultPrinterW(printerNameBuf.GetData(), &dwBufferSize); if (!bDone) { if (::GetLastError() == ERROR_FILE_NOT_FOUND) { return false; } else { MIKTEX_FATAL_WINDOWS_ERROR("GetDefaultPrinterW"); } } else { printerName = WU_(printerNameBuf.GetData()); return true; } } else { #if defined(MIKTEX_SUPPORT_LEGACY_WINDOWS) wchar_t cBuffer[4096]; if (GetProfileStringW(L"windows", L"device", L",,,", cBuffer, 4096) <= 0) { return false; } Tokenizer tok(StringUtil::WideCharToUTF8(cBuffer), ","); if (tok.GetCurrent() == nullptr) { return false; } unsigned long l = static_cast<unsigned long>(StrLen(tok.GetCurrent())); if (l >= *pBufferSize) { *pBufferSize = l + 1; return false; } StringUtil::CopyString(pPrinterName, *pBufferSize, tok.GetCurrent()); *pBufferSize = l + 1; return true; #else UNSUPPORTED_PLATFORM(); #endif } } }
void ArticleWriter::CompleteFileParts() { debug("Completing file parts"); debug("ArticleFilename: %s", m_fileInfo->GetFilename()); bool directWrite = (g_Options->GetDirectWrite() || m_fileInfo->GetForceDirectWrite()) && m_fileInfo->GetOutputInitialized(); BString<1024> nzbName; BString<1024> nzbDestDir; BString<1024> filename; { GuardedDownloadQueue guard = DownloadQueue::Guard(); nzbName = m_fileInfo->GetNzbInfo()->GetName(); nzbDestDir = m_fileInfo->GetNzbInfo()->GetDestDir(); filename = m_fileInfo->GetFilename(); } BString<1024> infoFilename("%s%c%s", *nzbName, PATH_SEPARATOR, *filename); bool cached = m_fileInfo->GetCachedArticles() > 0; if (g_Options->GetRawArticle()) { detail("Moving articles for %s", *infoFilename); } else if (directWrite && cached) { detail("Writing articles for %s", *infoFilename); } else if (directWrite) { detail("Checking articles for %s", *infoFilename); } else { detail("Joining articles for %s", *infoFilename); } // Ensure the DstDir is created CString errmsg; if (!FileSystem::ForceDirectories(nzbDestDir, errmsg)) { m_fileInfo->GetNzbInfo()->PrintMessage(Message::mkError, "Could not create directory %s: %s", *nzbDestDir, *errmsg); return; } CString ofn; if (m_fileInfo->GetForceDirectWrite()) { ofn.Format("%s%c%s", *nzbDestDir, PATH_SEPARATOR, *filename); } else { ofn = FileSystem::MakeUniqueFilename(nzbDestDir, *filename); } DiskFile outfile; BString<1024> tmpdestfile("%s.tmp", *ofn); if (!g_Options->GetRawArticle() && !directWrite) { FileSystem::DeleteFile(tmpdestfile); if (!outfile.Open(tmpdestfile, DiskFile::omWrite)) { m_fileInfo->GetNzbInfo()->PrintMessage(Message::mkError, "Could not create file %s: %s", *tmpdestfile, *FileSystem::GetLastErrorMessage()); return; } } else if (directWrite && cached) { if (!outfile.Open(m_outputFilename, DiskFile::omReadWrite)) { m_fileInfo->GetNzbInfo()->PrintMessage(Message::mkError, "Could not open file %s: %s", *m_outputFilename, *FileSystem::GetLastErrorMessage()); return; } tmpdestfile = *m_outputFilename; } else if (g_Options->GetRawArticle()) { FileSystem::DeleteFile(tmpdestfile); if (!FileSystem::CreateDirectory(ofn)) { m_fileInfo->GetNzbInfo()->PrintMessage(Message::mkError, "Could not create directory %s: %s", *ofn, *FileSystem::GetLastErrorMessage()); return; } } if (outfile.Active()) { SetWriteBuffer(outfile, 0); } uint32 crc = 0; { std::unique_ptr<ArticleCache::FlushGuard> flushGuard; if (cached) { flushGuard = std::make_unique<ArticleCache::FlushGuard>(g_ArticleCache->GuardFlush()); } CharBuffer buffer; bool firstArticle = true; if (!g_Options->GetRawArticle() && !directWrite) { buffer.Reserve(1024 * 64); } for (ArticleInfo* pa : m_fileInfo->GetArticles()) { if (pa->GetStatus() != ArticleInfo::aiFinished) { continue; } if (!g_Options->GetRawArticle() && !directWrite && pa->GetSegmentOffset() > -1 && pa->GetSegmentOffset() > outfile.Position() && outfile.Position() > -1) { memset(buffer, 0, buffer.Size()); if (!g_Options->GetSkipWrite()) { while (pa->GetSegmentOffset() > outfile.Position() && outfile.Position() > -1 && outfile.Write(buffer, std::min((int)(pa->GetSegmentOffset() - outfile.Position()), buffer.Size()))); } } if (pa->GetSegmentContent()) { if (!g_Options->GetSkipWrite()) { outfile.Seek(pa->GetSegmentOffset()); outfile.Write(pa->GetSegmentContent(), pa->GetSegmentSize()); } pa->DiscardSegment(); } else if (!g_Options->GetRawArticle() && !directWrite && !g_Options->GetSkipWrite()) { DiskFile infile; if (pa->GetResultFilename() && infile.Open(pa->GetResultFilename(), DiskFile::omRead)) { int cnt = buffer.Size(); while (cnt == buffer.Size()) { cnt = (int)infile.Read(buffer, buffer.Size()); outfile.Write(buffer, cnt); } infile.Close(); } else { m_fileInfo->SetFailedArticles(m_fileInfo->GetFailedArticles() + 1); m_fileInfo->SetSuccessArticles(m_fileInfo->GetSuccessArticles() - 1); m_fileInfo->GetNzbInfo()->PrintMessage(Message::mkError, "Could not find file %s for %s [%i/%i]", pa->GetResultFilename(), *infoFilename, pa->GetPartNumber(), (int)m_fileInfo->GetArticles()->size()); } } else if (g_Options->GetRawArticle()) { BString<1024> dstFileName("%s%c%03i", *ofn, PATH_SEPARATOR, pa->GetPartNumber()); if (!FileSystem::MoveFile(pa->GetResultFilename(), dstFileName)) { m_fileInfo->GetNzbInfo()->PrintMessage(Message::mkError, "Could not move file %s to %s: %s", pa->GetResultFilename(), *dstFileName, *FileSystem::GetLastErrorMessage()); } } if (m_format == Decoder::efYenc) { crc = firstArticle ? pa->GetCrc() : Crc32::Combine(crc, pa->GetCrc(), pa->GetSegmentSize()); firstArticle = false; } } buffer.Clear(); } if (outfile.Active()) { outfile.Close(); if (!directWrite && !FileSystem::MoveFile(tmpdestfile, ofn)) { m_fileInfo->GetNzbInfo()->PrintMessage(Message::mkError, "Could not move file %s to %s: %s", *tmpdestfile, *ofn, *FileSystem::GetLastErrorMessage()); } } if (directWrite) { if (!FileSystem::SameFilename(m_outputFilename, ofn) && !FileSystem::MoveFile(m_outputFilename, ofn)) { m_fileInfo->GetNzbInfo()->PrintMessage(Message::mkError, "Could not move file %s to %s: %s", *m_outputFilename, *ofn, *FileSystem::GetLastErrorMessage()); } // if destination directory was changed delete the old directory (if empty) int len = strlen(nzbDestDir); if (!(!strncmp(nzbDestDir, m_outputFilename, len) && (m_outputFilename[len] == PATH_SEPARATOR || m_outputFilename[len] == ALT_PATH_SEPARATOR))) { debug("Checking old dir for: %s", *m_outputFilename); BString<1024> oldDestDir; oldDestDir.Set(m_outputFilename, (int)(FileSystem::BaseFileName(m_outputFilename) - m_outputFilename)); if (FileSystem::DirEmpty(oldDestDir)) { debug("Deleting old dir: %s", *oldDestDir); FileSystem::RemoveDirectory(oldDestDir); } } } if (!directWrite) { for (ArticleInfo* pa : m_fileInfo->GetArticles()) { if (pa->GetResultFilename()) { FileSystem::DeleteFile(pa->GetResultFilename()); } } } if (m_fileInfo->GetTotalArticles() == m_fileInfo->GetSuccessArticles()) { m_fileInfo->GetNzbInfo()->PrintMessage(Message::mkInfo, "Successfully downloaded %s", *infoFilename); } else if (m_fileInfo->GetMissedArticles() + m_fileInfo->GetFailedArticles() > 0) { m_fileInfo->GetNzbInfo()->PrintMessage(Message::mkWarning, "%i of %i article downloads failed for \"%s\"", m_fileInfo->GetMissedArticles() + m_fileInfo->GetFailedArticles(), m_fileInfo->GetTotalArticles(), *infoFilename); } else { m_fileInfo->GetNzbInfo()->PrintMessage(Message::mkInfo, "Partially downloaded %s", *infoFilename); } { GuardedDownloadQueue guard = DownloadQueue::Guard(); m_fileInfo->SetCrc(crc); m_fileInfo->SetOutputFilename(ofn); if (strcmp(m_fileInfo->GetFilename(), filename)) { // file was renamed during completion, need to move the file ofn = FileSystem::MakeUniqueFilename(nzbDestDir, m_fileInfo->GetFilename()); if (!FileSystem::MoveFile(m_fileInfo->GetOutputFilename(), ofn)) { m_fileInfo->GetNzbInfo()->PrintMessage(Message::mkError, "Could not rename file %s to %s: %s", m_fileInfo->GetOutputFilename(), *ofn, *FileSystem::GetLastErrorMessage()); } m_fileInfo->SetOutputFilename(ofn); } if (strcmp(m_fileInfo->GetNzbInfo()->GetDestDir(), nzbDestDir)) { // destination directory was changed during completion, need to move the file MoveCompletedFiles(m_fileInfo->GetNzbInfo(), nzbDestDir); } } }