int lziparchive_openfrommemory(lua_State* L) { ZipArchive* archive = lziparchive_check(L, 1); const char* buffer = luaL_checkstring(L, 2); MemFile memFile; memFile.Attach((BYTE*)buffer, lua_objlen(L, 2)); int readOnly = 1; int flags = (int)luaL_optnumber(L, 3, ZipArchive::SUPPORT_MD5); const char* defaultPassword = luaL_optstring(L, 4, NULL); lua_pushboolean(L, archive->Open(memFile, "@memory", readOnly != 0, flags, defaultPassword) != 0); return 1; }
TEST(TestMemFile, EmptyFileInCache) { StaticContentCache::TheFileCache = std::make_shared<FileCache>(); StaticContentCache::TheFileCache->write("/no/content/entry"); MemFile mf; // The file itself... ASSERT_FALSE(mf.open("/no/content/entry", "r")); // ... and one of the automatically-created "directory" entries. ASSERT_FALSE(mf.open("/no/content", "r")); }
bool ReadUnsupp (MemFile &file, std::shared_ptr<Disk> &/*disk*/) { std::array<char, SECTOR_SIZE> buf; if (!file.rewind() || !file.read(buf)) return false; std::string strType; if (std::string(buf.data() + 0x00, 12) == "CPC-Emulator" && std::string(buf.data() + 0x10, 10) == "DiskImageV") strType = "CPCemu"; else if (std::string(buf.data() + 0x00, 4) == "CPCD") strType = "EmuCPC"; else if (std::string(buf.data() + 0x00, 8) == "NORMDISK") strType = "CPD"; if (!strType.empty()) throw util::exception(strType, " disk images are not currently supported"); return false; }
bool ReadD81 (MemFile &file, std::shared_ptr<Disk> &disk) { // D81 is a fixed-size image uint8_t ab[256]; if (file.size() != D81_DISK_SIZE || !file.seek(D81_HEADER_OFFSET) || !file.read(&ab, sizeof(ab))) return false; // Check for 1581 signature and various check bytes if (ab[2] != 'D' || ab[3] || ab[0x14] != 0xa0 || ab[0x15] != 0xa0 || ab[0x1b] != 0xa0 || ab[0x1c] != 0xa0) return false; Format fmt { RegularFormat::D81 }; // D2M stores the sides in the reverse order, so fiddle things to read it easily file.rewind(); std::swap(fmt.head0, fmt.head1); disk->format(fmt, file.data()); std::swap(disk->fmt.head0, disk->fmt.head1); disk->flip_sides(); disk->strType = "D81"; return true; }
TEST(TestMemFile, RealFileInCache) { string temp_fn; ASSERT_TRUE(makeTempFile("123abc", &temp_fn)); StaticContentCache::TheFileCache = std::make_shared<FileCache>(); StaticContentCache::TheFileCache->write("/content", temp_fn.c_str()); MemFile mf; ASSERT_TRUE(mf.open("/content", "r")); ASSERT_EQ(mf.getc(), '1'); ASSERT_EQ(mf.getc(), '2'); ASSERT_EQ(mf.getc(), '3'); ASSERT_EQ(mf.getc(), 'a'); ASSERT_EQ(mf.getc(), 'b'); ASSERT_EQ(mf.getc(), 'c'); ASSERT_EQ(mf.getc(), EOF); ASSERT_TRUE(mf.close()); ASSERT_EQ(unlink(temp_fn.c_str()), 0); }
TEST(TestMemFile, NotInCache) { StaticContentCache::TheFileCache = std::make_shared<FileCache>(); MemFile mf; ASSERT_FALSE(mf.open("/not/even/there", "r")); }
TEST(TestMemFile, BadOpenModes) { MemFile mf; ASSERT_FALSE(mf.open("/some/file1", "+")); ASSERT_FALSE(mf.open("/some/file2", "a")); ASSERT_FALSE(mf.open("/some/file3", "w")); }
TEST(TestMemFile, BadReadFromCache) { StaticContentCache::TheFileCache = std::make_shared<FileCache>(); MemFile mf; ASSERT_FALSE(mf.open("/some/random/file", "r")); }
bool ReadSCP (MemFile &file, std::shared_ptr<Disk> &disk) { SCP_FILE_HEADER fh {}; if (!file.rewind() || !file.read(&fh, sizeof(fh)) || std::string(fh.signature, 3) != "SCP") return false; /*if (!(fh.flags & FLAG_INDEX)) throw util::exception("not an index-synchronised image"); else*/ if (fh.revolutions == 0 || fh.revolutions > 10) throw util::exception("invalid revolution count (", fh.revolutions, ")"); else if (fh.bitcell_width != 0 && fh.bitcell_width != 16) throw util::exception("unsupported bit cell width (", fh.bitcell_width, ")"); else if (fh.start_track > fh.end_track) throw util::exception("start track (", fh.start_track, ") > end track (", fh.end_track, ")"); std::vector<uint32_t> tdh_offsets(fh.end_track + 1); if (!file.read(tdh_offsets)) throw util::exception("short file reading track offset index"); auto scp_disk = std::make_shared<SCPDisk>(); for (auto tracknr = fh.start_track; tracknr <= fh.end_track; ++tracknr) { TRACK_DATA_HEADER tdh; auto cyl = tracknr >> 1; auto head = tracknr & 1; CylHead cylhead(cyl, head); if (!tdh_offsets[tracknr]) continue; if (!file.seek(tdh_offsets[tracknr]) || !file.read(&tdh, sizeof(tdh))) throw util::exception("short file reading ", cylhead, " track header"); else if (std::string(tdh.signature, 3) != "TRK") throw util::exception("invalid track signature on ", cylhead); else if (tdh.tracknr != tracknr) throw util::exception("track number mismatch (", tdh.tracknr, " != ", tracknr, ") in ", cylhead, " header"); std::vector<uint32_t> rev_index(fh.revolutions * 3); if (!file.read(rev_index)) throw util::exception("short file reading ", cylhead, " track index"); std::vector<std::vector<uint16_t>> revs_data; revs_data.reserve(fh.revolutions); for (uint8_t rev = 0; rev < fh.revolutions; ++rev) { // auto index_time = util::letoh<uint32_t>(rev_index[rev * 3 + 0]); auto flux_count = util::letoh<uint32_t>(rev_index[rev * 3 + 1]); auto data_offset = util::letoh<uint32_t>(rev_index[rev * 3 + 2]); std::vector<uint16_t> flux_data(flux_count); if (!file.seek(tdh_offsets[tracknr] + data_offset) || !file.read(flux_data)) throw util::exception("short error reading ", cylhead, " data"); revs_data.push_back(std::move(flux_data)); } scp_disk->add_track_data(cylhead, std::move(revs_data)); } scp_disk->strType = "SCP"; disk = scp_disk; return true; }
bool SML::ParseValues(MemFile& valuesMemFile) { if (valuesMemFile.getSize() == 0) return true; // loop through all name/value pairs MemFile memLine; TokenIStream filterLine(&valuesMemFile); filterLine.setTrimTokens(SML_TOKEN_IGNORECHARS); filterLine.setToken(SML_TOKEN_VALUETOKEN); MemFile memValue; TokenIStream filterValue(&memLine); filterValue.setTrimTokens(SML_TOKEN_IGNORECHARS); filterValue.setToken(SML_TOKEN_NAMETOKEN); do { // parse value name and value filterLine.readLine(memLine); filterLine.trimBackLine(memLine); filterLine.trimFrontLine(memLine); if (memLine.isEOF()) continue; // empty line, return // parse value name const size_t lenNameValueReal = (size_t)memLine.getSizeLeft(); const size_t lenName = filterValue.readLine(memValue); #if SML_AUTOVALUES == SML_AUTOVALUES_ON String szName; if (filterValue.trimBackLine(memValue) == lenName || lenNameValueReal == lenName) { // no name found, auto generate the name szName = _T("Item") + String::ToString(size()); } else { // read the name szName = (LPCTSTR)memValue.getData(); memValue.setSize(0); } #else filterValue.trimBackLine(memValue); String szName = (LPCTSTR)memValue.getData(); ASSERT(!filterValue.isEOS() && !szName.IsEmpty()); if (filterValue.isEOS() || szName.IsEmpty()) { memValue.setSize(0); memLine.setSize(0); filterValue.setPos(0); continue; // Parse Error: invalid syntax ('=' not found) } ASSERT(szName.size() == memValue.getSizeLeft()); memValue.setSize(0); #endif SMLVALUE& val = operator[](szName); // parse value filterValue.read(memValue); LPCTSTR szValue = filterValue.trimFrontLine(memValue); val.val = szValue; ASSERT(_tcslen(szValue) == memValue.getSizeLeft()); memValue.setSize(0); memLine.setSize(0); filterValue.setPos(0); } while (!filterLine.isEOS()); // all file processed, safe to reset it to 0 valuesMemFile.setSize(0); return true; }
bool SML::ParseSection(TokenIStream& filter, MemFile& memFile) { while (true) { // find first section start (NameOpenBracket) filter.setToken(SML_TOKEN_NAMEOPENBRACKET); filter.readLine(memFile); // parse values before the new section or end of section const size_f_t posMemFile = memFile.getPos(); MemFile valuesMemFile; TokenIStream sectionFilter(&memFile, SML_TOKEN_SECTIONCLOSEBRACKET); const size_t lenValues = sectionFilter.readLine(valuesMemFile); if (ParseValues(valuesMemFile) == false) return false; // Parse Error: invalid values ASSERT(valuesMemFile.getSize() == 0); // if end of section found, return if (!sectionFilter.isEOS()) { // if a name open bracket was found before the EOS, // then restore it for the parent next ParseSection() memFile.setPos(posMemFile+(lenValues+1)*sizeof(TCHAR)); if (!filter.isEOS()) filter.restoreToken(); break; } else { ASSERT(memFile.getSize()-posMemFile == lenValues*sizeof(TCHAR)); ASSERT(memFile.getSize()-posMemFile == memFile.getSize() || memFile.getSize()-posMemFile == memFile.getSizeLeft() || memFile.getSizeLeft() == 0); memFile.setSize(0); } // if no more data, return if (filter.isEOS()) break; // parse child section name filter.setToken(SML_TOKEN_NAMECLOSEBRACKET); const size_t lenName = filter.readLine(memFile); ASSERT(!filter.isEOS()); if (lenName == 0) return false; // Parse Error: invalid section name const String strChildName((LPCTSTR)memFile.getData(), (UINT)lenName); memFile.growSize(-((size_f_t)(lenName*sizeof(TCHAR)))); ASSERT(memFile.getSize() == 0); // create the child with the given name const IDX idxChild = CreateChildUnique(strChildName); LPSML const pChild = m_arrChildren[idxChild]; pChild->SetFncItem(m_fncInitItem, m_fncSaveItem, m_fncReleaseItem, m_fncItemData); // parse child section filter.setToken(SML_TOKEN_SECTIONOPENBRACKET); filter.readLine(memFile); filter.trimBackLine(memFile); ASSERT(memFile.getSize() == 0); if (pChild->ParseSection(filter, memFile) == false) return false; } return true; }
void TemplateManager::SaveRegistry() { int i; WORD count = GetCount(); if (count > 0) { MemFile filenameFile; filenameFile.Write(&count, sizeof(count)); for (i = 0; i < GetCount(); i++) { WWhizTemplateGroup* file = GetTemplateGroup(i); bool isActive = file->IsActive(); filenameFile.Write(&isActive, sizeof(bool)); WORD len = file->GetFilename().GetLength(); filenameFile.Write(&len, sizeof(WORD)); filenameFile.Write((LPCTSTR)file->GetFilename(), len); unsigned __int64 time = file->GetTimeStamp().GetTime(); filenameFile.Write(&time, sizeof(unsigned __int64)); } LONG filenameFileSize = filenameFile.GetLength(); BYTE* filenameFileMem = filenameFile.Detach(); AfxGetApp()->WriteProfileBinary("Templates", "FileList2", filenameFileMem, filenameFileSize); free(filenameFileMem); } else { AfxGetApp()->WriteProfileBinary("Templates", "FileList2", NULL, 0); } // Write out the tree state. LONG treeStateSize = m_treeStateFile.GetLength(); BYTE* treeStateMem = m_treeStateFile.Detach(); if (treeStateSize > 0) { AfxGetApp()->WriteProfileBinary("Templates", "TreeState", treeStateMem, treeStateSize); // Reattach the memory. m_treeStateFile.SetLength(0); m_treeStateFile.Write(treeStateMem, treeStateSize); free(treeStateMem); } // Write out all parameters. MemFile paramFile; for (i = 0; i < GetCount(); i++) { WWhizTemplateGroup* file = GetTemplateGroup(i); for (int j = 0; j < file->GetCount(); j++) { Template* code = (Template*)file->Get(j); CString menuName = file->GetName() + "|" + code->GetName(); WORD nameLen = menuName.GetLength(); paramFile.Write(&nameLen, sizeof(WORD)); paramFile.Write((LPCTSTR)menuName, nameLen); WORD dicCount = code->m_dictionary.GetCount(); paramFile.Write(&dicCount, sizeof(WORD)); POSITION pos = code->m_dictionary.GetStartPosition(); while (pos) { CString entry; CString value; code->m_dictionary.GetNextAssoc(pos, entry, value); BYTE bLen = entry.GetLength(); paramFile.Write(&bLen, sizeof(BYTE)); paramFile.Write((LPCTSTR)entry, bLen); WORD wLen; wLen = value.GetLength(); paramFile.Write(&wLen, sizeof(WORD)); paramFile.Write((LPCTSTR)value, wLen); } } } UINT paramFileSize = paramFile.GetLength(); BYTE* paramFileMem = paramFile.Detach(); AfxGetApp()->WriteProfileBinary("Templates", "SavedParameters", paramFileMem, paramFileSize); free(paramFileMem); }
void TemplateManager::LoadRegistry() { for (size_t i = 0; i < m_files.GetCount(); i++) { delete m_files[i]; } m_files.RemoveAll(); UINT size; BYTE* mem; BYTE* mem2; // Read in the filename file. if (AfxGetApp()->GetProfileBinary("Templates", "FileList2", &mem, &size) && size != 0) { MemFile filenameFile; filenameFile.Write(mem, size); filenameFile.Seek(0, CFile::begin); WORD count; filenameFile.Read(&count, sizeof(WORD)); size_t i; for (i = 0; i < count; i++) { CString filename; bool isActive; filenameFile.Read(&isActive, sizeof(bool)); ReadStringGT255(filenameFile, filename); if (filename.IsEmpty()) break; // Error. bool oldChanged = m_changed; int which = Add(filename); if (which == -1) { m_changed = true; } else { WWhizTemplateGroup* file = GetTemplateGroup(which); file->SetActive(isActive); CTime timeStamp; ReadTimeStamp(filenameFile, timeStamp); if (timeStamp != file->GetTimeStamp()) m_changed = true; else m_changed = oldChanged; } } } else if (AfxGetApp()->GetProfileBinary("Templates", "FileList", &mem2, &size)) { MemFile filenameFile; filenameFile.Write(mem2, size); filenameFile.Seek(0, CFile::begin); delete [] mem2; WORD count; filenameFile.Read(&count, sizeof(WORD)); size_t i; for (i = 0; i < count; i++) { CString filename; ReadStringGT255(filenameFile, filename); if (filename.IsEmpty()) break; // Error. bool oldChanged = m_changed; int which = Add(filename); if (which == -1) { m_changed = true; } else { WWhizTemplateGroup* file = GetTemplateGroup(which); CTime timeStamp; ReadTimeStamp(filenameFile, timeStamp); if (timeStamp != file->GetTimeStamp()) m_changed = true; else m_changed = oldChanged; } } } delete [] mem; mem = NULL; // Read in the tree state. if (AfxGetApp()->GetProfileBinary("Templates", "TreeState", &mem, &size)) { m_treeStateFile.SetLength(0); m_treeStateFile.Write(mem, size); m_treeStateFile.Seek(0, CFile::begin); } delete [] mem; mem = NULL; // Read in the parameters. if (AfxGetApp()->GetProfileBinary("Templates", "SavedParameters", &mem, &size)) { MemFile paramFile; paramFile.Write(mem, size); paramFile.Seek(0, CFile::begin); delete [] mem; mem = NULL; if (size > 0) { // The saved parameters SHOULD be in the same order. for (size_t i = 0; i < (size_t)GetCount(); i++) { WWhizTemplateGroup* file = GetTemplateGroup(i); for (int j = 0; j < file->GetCount(); j++) { WWhizTemplate* code = file->Get(j); CString menuName = file->GetName() + "|" + code->GetName(); WORD nameLen; if (paramFile.Read(&nameLen, sizeof(WORD)) != sizeof(WORD)) break; // Not enough info in the file. CString newMenuName; LPTSTR buf = newMenuName.GetBufferSetLength(nameLen); if (paramFile.Read(buf, nameLen) != nameLen) break; // Not enough info in the file. newMenuName.ReleaseBuffer(nameLen); if (menuName.CompareNoCase(newMenuName) != 0) { // AfxMessageBox("Doesn't match.\n"); goto DoneWithParams; } WORD dicCount; paramFile.Read(&dicCount, sizeof(WORD)); for (int k = 0; k < dicCount; k++) { CString entry; CString value; BYTE bLen; paramFile.Read(&bLen, sizeof(BYTE)); LPTSTR buf = entry.GetBufferSetLength(bLen); paramFile.Read(buf, bLen); entry.ReleaseBuffer(bLen); WORD wLen; paramFile.Read(&wLen, sizeof(WORD)); buf = value.GetBufferSetLength(wLen); paramFile.Read(buf, wLen); value.ReleaseBuffer(wLen); code->SetEntry(entry, value); } } } } } delete[] mem; DoneWithParams: int hi = 5; }
TEST(TestMemFile, NotInCache) { StaticContentCache::TheFileCache = FileCachePtr(new FileCache()); MemFile mf; ASSERT_FALSE(mf.open("/not/even/there", "r")); }
TEST(TestMemFile, BadReadFromCache) { StaticContentCache::TheFileCache = FileCachePtr(new FileCache()); MemFile mf; ASSERT_FALSE(mf.open("/some/random/file", "r")); }