本文整理汇总了C++中MemChunk::currentPos方法的典型用法代码示例。如果您正苦于以下问题:C++ MemChunk::currentPos方法的具体用法?C++ MemChunk::currentPos怎么用?C++ MemChunk::currentPos使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类MemChunk
的用法示例。
在下文中一共展示了MemChunk::currentPos方法的4个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: readDirectory
/* ResArchive::readDirectory
* Reads a res directory from a MemChunk
* Returns true if successful, false otherwise
*******************************************************************/
bool ResArchive::readDirectory(MemChunk& mc, size_t dir_offset, size_t num_lumps, ArchiveTreeNode* parent)
{
if (!parent)
{
LOG_MESSAGE(1, "ReadDir: No parent node");
Global::error = "Archive is invalid and/or corrupt";
return false;
}
mc.seek(dir_offset, SEEK_SET);
for (uint32_t d = 0; d < num_lumps; d++)
{
// Update splash window progress
UI::setSplashProgress(((float)d / (float)num_lumps));
// Read lump info
char magic[4] = "";
char name[15] = "";
uint32_t dumzero1, dumzero2;
uint16_t dumff, dumze;
uint8_t flags = 0;
uint32_t offset = 0;
uint32_t size = 0;
mc.read(magic, 4); // ReS\0
mc.read(name, 14); // Name
mc.read(&offset, 4); // Offset
mc.read(&size, 4); // Size
// Check the identifier
if (magic[0] != 'R' || magic[1] != 'e' || magic[2] != 'S' || magic[3] != 0)
{
LOG_MESSAGE(1, "ResArchive::readDir: Entry %s (%[email protected]%x) has invalid directory entry", name, size, offset);
Global::error = "Archive is invalid and/or corrupt";
return false;
}
// Byteswap values for big endian if needed
offset = wxINT32_SWAP_ON_BE(offset);
size = wxINT32_SWAP_ON_BE(size);
name[14] = '\0';
mc.read(&dumze, 2); if (dumze) LOG_MESSAGE(1, "Flag guard not null for entry %s", name);
mc.read(&flags, 1); if (flags != 1 && flags != 17) LOG_MESSAGE(1, "Unknown flag value for entry %s", name);
mc.read(&dumzero1, 4); if (dumzero1) LOG_MESSAGE(1, "Near-end values not set to zero for entry %s", name);
mc.read(&dumff, 2); if (dumff != 0xFFFF) LOG_MESSAGE(1, "Dummy set to a non-FF value for entry %s", name);
mc.read(&dumzero2, 4); if (dumzero2) LOG_MESSAGE(1, "Trailing values not set to zero for entry %s", name);
// If the lump data goes past the end of the file,
// the resfile is invalid
if (offset + size > mc.getSize())
{
LOG_MESSAGE(1, "ResArchive::readDirectory: Res archive is invalid or corrupt, offset overflow");
Global::error = "Archive is invalid and/or corrupt";
setMuted(false);
return false;
}
// Create & setup lump
ArchiveEntry* nlump = new ArchiveEntry(wxString::FromAscii(name), size);
nlump->setLoaded(false);
nlump->exProp("Offset") = (int)offset;
nlump->setState(0);
// Read entry data if it isn't zero-sized
if (nlump->getSize() > 0)
{
// Read the entry data
MemChunk edata;
mc.exportMemChunk(edata, offset, size);
nlump->importMemChunk(edata);
}
// What if the entry is a directory?
size_t d_o, n_l;
if (isResArchive(nlump->getMCData(), d_o, n_l))
{
ArchiveTreeNode* ndir = createDir(name, parent);
if (ndir)
{
UI::setSplashProgressMessage(S_FMT("Reading res archive data: %s directory", name));
// Save offset to restore it once the recursion is done
size_t myoffset = mc.currentPos();
readDirectory(mc, d_o, n_l, ndir);
ndir->getDirEntry()->setState(0);
// Restore offset and clean out the entry
mc.seek(myoffset, SEEK_SET);
delete nlump;
}
else
{
delete nlump;
return false;
}
// Not a directory, then add to entry list
}
else
//.........这里部分代码省略.........
示例2: write
/* ADatArchive::write
* Writes the dat archive to a MemChunk
* Returns true if successful, false otherwise
*******************************************************************/
bool ADatArchive::write(MemChunk& mc, bool update) {
// Clear current data
mc.clear();
MemChunk directory;
MemChunk compressed;
// Get archive tree as a list
vector<ArchiveEntry*> entries;
getEntryTreeAsList(entries);
// Write header
long dir_offset = wxINT32_SWAP_ON_BE(16);
long dir_size = wxINT32_SWAP_ON_BE(0);
char pack[4] = { 'A', 'D', 'A', 'T' };
uint32_t version = wxINT32_SWAP_ON_BE(9);
mc.seek(0, SEEK_SET);
mc.write(pack, 4);
mc.write(&dir_offset, 4);
mc.write(&dir_size, 4);
mc.write(&version, 4);
// Write entry data
for (unsigned a = 0; a < entries.size(); a++) {
// Skip folders
if (entries[a]->getType() == EntryType::folderType())
continue;
// Create compressed version of the lump
MemChunk * entry = NULL;
if (Compression::ZlibDeflate(entries[a]->getMCData(), compressed, 9)) {
entry = &compressed;
} else {
entry = &(entries[a]->getMCData());
wxLogMessage("Entry %s couldn't be deflated", CHR(entries[a]->getName()));
}
// Update entry
int offset = mc.currentPos();
if (update) {
entries[a]->setState(0);
entries[a]->exProp("Offset") = (int)offset;
}
///////////////////////////////////
// Step 1: Write directory entry //
///////////////////////////////////
// Check entry name
string name = entries[a]->getPath(true);
name.Remove(0, 1); // Remove leading /
if (name.Len() > 128) {
wxLogMessage("Warning: Entry %s path is too long (> 128 characters), putting it in the root directory", CHR(name));
wxFileName fn(name);
name = fn.GetFullName();
if (name.Len() > 128)
name.Truncate(128);
}
// Write entry name
char name_data[128];
memset(name_data, 0, 128);
memcpy(name_data, CHR(name), name.Length());
directory.write(name_data, 128);
// Write entry offset
long myoffset = wxINT32_SWAP_ON_BE(offset);
directory.write(&myoffset, 4);
// Write full entry size
long decsize = wxINT32_SWAP_ON_BE(entries[a]->getSize());
directory.write(&decsize, 4);
// Write compressed entry size
long compsize = wxINT32_SWAP_ON_BE(entry->getSize());
directory.write(&compsize, 4);
// Write whatever it is that should be there
// TODO: Reverse engineer what exactly it is
// and implement something valid for the game.
long whatever = 0;
directory.write(&whatever, 4);
//////////////////////////////
// Step 2: Write entry data //
//////////////////////////////
mc.write(entry->getData(), entry->getSize());
}
// Write directory
dir_offset = wxINT32_SWAP_ON_BE(mc.currentPos());
dir_size = wxINT32_SWAP_ON_BE(directory.getSize());
mc.write(directory.getData(), directory.getSize());
// Update directory offset and size in header
mc.seek(4, SEEK_SET);
//.........这里部分代码省略.........
示例3: open
/* GZipArchive::open
* Reads gzip format data from a MemChunk
* Returns true if successful, false otherwise
*******************************************************************/
bool GZipArchive::open(MemChunk& mc)
{
// Minimal metadata size is 18: 10 for header, 8 for footer
size_t mds = 18;
size_t size = mc.getSize();
if (mds > size)
return false;
// Read header
uint8_t header[4];
mc.read(header, 4);
// Check for GZip header; we'll only accept deflated gzip files
// and reject any field using unknown flags
if ((!(header[0] == GZIP_ID1 && header[1] == GZIP_ID2 && header[2] == GZIP_DEFLATE))
|| (header[3] & GZIP_FLG_FUNKN))
return false;
bool ftext, fhcrc, fxtra, fname, fcmnt;
ftext = (header[3] & GZIP_FLG_FTEXT) ? true : false;
fhcrc = (header[3] & GZIP_FLG_FHCRC) ? true : false;
fxtra = (header[3] & GZIP_FLG_FXTRA) ? true : false;
fname = (header[3] & GZIP_FLG_FNAME) ? true : false;
fcmnt = (header[3] & GZIP_FLG_FCMNT) ? true : false;
flags = header[3];
mc.read(&mtime, 4);
mtime = wxUINT32_SWAP_ON_BE(mtime);
mc.read(&xfl, 1);
mc.read(&os, 1);
// Skip extra fields which may be there
if (fxtra)
{
uint16_t xlen;
mc.read(&xlen, 2);
xlen = wxUINT16_SWAP_ON_BE(xlen);
mds += xlen + 2;
if (mds > size)
return false;
mc.exportMemChunk(xtra, mc.currentPos(), xlen);
mc.seek(xlen, SEEK_CUR);
}
// Skip past name, if any
string name;
if (fname)
{
char c;
do
{
mc.read(&c, 1);
if (c) name += c;
++mds;
}
while (c != 0 && size > mds);
}
else
{
// Build name from filename
name = getFilename(false);
wxFileName fn(name);
if (!fn.GetExt().CmpNoCase("tgz"))
fn.SetExt("tar");
else if (!fn.GetExt().CmpNoCase("gz"))
fn.ClearExt();
name = fn.GetFullName();
}
// Skip past comment
if (fcmnt)
{
char c;
do
{
mc.read(&c, 1);
if (c) comment += c;
++mds;
}
while (c != 0 && size > mds);
wxLogMessage("Archive %s says:\n %s", CHR(getFilename(true)), CHR(comment));
}
// Skip past CRC 16 check
if (fhcrc)
{
uint8_t* crcbuffer = new uint8_t[mc.currentPos()];
memcpy(crcbuffer, mc.getData(), mc.currentPos());
uint32_t fullcrc = Misc::crc(crcbuffer, mc.currentPos());
delete[] crcbuffer;
uint16_t hcrc;
mc.read(&hcrc, 2);
hcrc = wxUINT16_SWAP_ON_BE(hcrc);
mds += 2;
if (hcrc != (fullcrc & 0x0000FFFF))
//.........这里部分代码省略.........
示例4: isGZipArchive
/* GZipArchive::isGZipArchive
* Checks if the given data is a valid GZip archive
*******************************************************************/
bool GZipArchive::isGZipArchive(MemChunk& mc)
{
// Minimal metadata size is 18: 10 for header, 8 for footer
size_t mds = 18;
size_t size = mc.getSize();
if (size < mds)
return false;
// Read header
uint8_t header[4];
mc.read(header, 4);
// Check for GZip header; we'll only accept deflated gzip files
// and reject any field using unknown flags
if (!(header[0] == GZIP_ID1 && header[1] == GZIP_ID2 && header[2] == GZIP_DEFLATE)
|| (header[3] & GZIP_FLG_FUNKN))
return false;
bool ftext, fhcrc, fxtra, fname, fcmnt;
ftext = (header[3] & GZIP_FLG_FTEXT) ? true : false;
fhcrc = (header[3] & GZIP_FLG_FHCRC) ? true : false;
fxtra = (header[3] & GZIP_FLG_FXTRA) ? true : false;
fname = (header[3] & GZIP_FLG_FNAME) ? true : false;
fcmnt = (header[3] & GZIP_FLG_FCMNT) ? true : false;
uint32_t mtime;
mc.read(&mtime, 4);
uint8_t xfl;
mc.read(&xfl, 1);
uint8_t os;
mc.read(&os, 1);
// Skip extra fields which may be there
if (fxtra)
{
uint16_t xlen;
mc.read(&xlen, 2);
xlen = wxUINT16_SWAP_ON_BE(xlen);
mds += xlen + 2;
if (mds > size)
return false;
mc.seek(xlen, SEEK_CUR);
}
// Skip past name, if any
if (fname)
{
string name;
char c;
do
{
mc.read(&c, 1);
if (c) name += c;
++mds;
}
while (c != 0 && size > mds);
}
// Skip past comment
if (fcmnt)
{
string comment;
char c;
do
{
mc.read(&c, 1);
if (c) comment += c;
++mds;
}
while (c != 0 && size > mds);
}
// Skip past CRC 16 check
if (fhcrc)
{
uint16_t hcrc;
mc.read(&hcrc, 2);
mds += 2;
}
// Header is over
if (mds > size || mc.currentPos() + 8 > size)
return false;
// If it's passed to here it's probably a gzip file
return true;
}