int main(int argc, char* argv[]) { if(argc < 3) { printf("Usage whateveryoujusttyped.exe readFileName writeFileName\n"); return -1; } const char* readFilename = argv[1]; const char* writeFilename = argv[2]; std::ifstream readFile(readFilename); if(!readFile.is_open()) { printf("Couldn't open %s for reading\n", readFilename); return -1; } std::ofstream writeFile(writeFilename); if(!writeFile.is_open()) { printf("Couldn't open %s for writing\n", writeFilename); return -1; } typedef std::list<std::string> Entries; Entries entries; std::string currentEntry; std::string line; while(std::getline(readFile, line)) { if(strstr(line.c_str(), "===") != NULL) { if(!currentEntry.empty()) { entries.push_back(currentEntry); } currentEntry.clear(); } currentEntry += line; currentEntry += "\n"; } if(!currentEntry.empty()) { entries.push_back(currentEntry); } readFile.close(); for(auto entryIt = entries.rbegin(); entryIt != entries.rend(); ++entryIt) { writeFile << (*entryIt); } writeFile.close(); return 0; }
void ArchiveTestCase<ClassFactoryT>::ExtractArchive(wxInputStream& in) { typedef Ptr<EntryT> EntryPtr; typedef std::list<EntryPtr> Entries; typedef typename Entries::iterator EntryIter; auto_ptr<InputStreamT> arc(m_factory->NewStream(in)); int expectedTotal = m_testEntries.size(); EntryPtr entry; Entries entries; if ((m_options & PipeIn) == 0) OnArchiveExtracted(*arc, expectedTotal); while (entry = EntryPtr(arc->GetNextEntry()), entry.get() != NULL) { wxString name = entry->GetName(wxPATH_UNIX); // provide some context for the error message so that we know which // iteration of the loop we were on string error_entry((_T(" '") + name + _T("'")).mb_str()); string error_context(" failed for entry" + error_entry); TestEntries::iterator it = m_testEntries.find(name); CPPUNIT_ASSERT_MESSAGE( "archive contains an entry that shouldn't be there" + error_entry, it != m_testEntries.end()); const TestEntry& testEntry = *it->second; wxDateTime dt = testEntry.GetDateTime(); if (dt.IsValid()) CPPUNIT_ASSERT_MESSAGE("timestamp check" + error_context, dt == entry->GetDateTime()); // non-seekable entries are allowed to have GetSize == wxInvalidOffset // until the end of the entry's data has been read past CPPUNIT_ASSERT_MESSAGE("entry size check" + error_context, testEntry.GetLength() == entry->GetSize() || ((m_options & PipeIn) != 0 && entry->GetSize() == wxInvalidOffset)); CPPUNIT_ASSERT_MESSAGE( "arc->GetLength() == entry->GetSize()" + error_context, arc->GetLength() == entry->GetSize()); if (name.Last() != _T('/')) { CPPUNIT_ASSERT_MESSAGE("!IsDir" + error_context, !entry->IsDir()); wxCharBuffer buf(testEntry.GetSize() + 1); CPPUNIT_ASSERT_MESSAGE("Read until Eof" + error_context, arc->Read(buf.data(), testEntry.GetSize() + 1).Eof()); CPPUNIT_ASSERT_MESSAGE("LastRead check" + error_context, arc->LastRead() == testEntry.GetSize()); CPPUNIT_ASSERT_MESSAGE("data compare" + error_context, !memcmp(buf.data(), testEntry.GetData(), testEntry.GetSize())); } else { CPPUNIT_ASSERT_MESSAGE("IsDir" + error_context, entry->IsDir()); } // GetSize() must return the right result in all cases after all the // data has been read CPPUNIT_ASSERT_MESSAGE("entry size check" + error_context, testEntry.GetLength() == entry->GetSize()); CPPUNIT_ASSERT_MESSAGE( "arc->GetLength() == entry->GetSize()" + error_context, arc->GetLength() == entry->GetSize()); if ((m_options & PipeIn) == 0) { OnEntryExtracted(*entry, testEntry, arc.get()); delete it->second; m_testEntries.erase(it); } else { entries.push_back(entry); } } // check that the end of the input archive was reached without error CPPUNIT_ASSERT(arc->Eof()); // for non-seekable streams these data are only guaranteed to be // available once the end of the archive has been reached if (m_options & PipeIn) { for (EntryIter i = entries.begin(); i != entries.end(); ++i) { wxString name = (*i)->GetName(wxPATH_UNIX); TestEntries::iterator j = m_testEntries.find(name); OnEntryExtracted(**i, *j->second); delete j->second; m_testEntries.erase(j); } OnArchiveExtracted(*arc, expectedTotal); } }
void make_entry(Tracked const * const r) { if (Entry * const e = entry(r)) if (e->status != destructed) error()() << "leaked: " << *e << '.'; Entry const e = { r, "?", fresh }; entries.push_back(e); }