本文整理汇总了C++中FileReader::GetLength方法的典型用法代码示例。如果您正苦于以下问题:C++ FileReader::GetLength方法的具体用法?C++ FileReader::GetLength怎么用?C++ FileReader::GetLength使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类FileReader
的用法示例。
在下文中一共展示了FileReader::GetLength方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: RenameNerve
//==========================================================================
//
// RenameNerve
//
// Renames map headers and map name pictures in nerve.wad so as to load it
// alongside Doom II and offer both episodes without causing conflicts.
// MD5 checksum for NERVE.WAD: 967d5ae23daf45196212ae1b605da3b0
//
//==========================================================================
void FWadCollection::RenameNerve ()
{
if (gameinfo.gametype != GAME_Doom)
return;
bool found = false;
BYTE cksum[16];
static const BYTE nerve[16] = { 0x96, 0x7d, 0x5a, 0xe2, 0x3d, 0xaf, 0x45, 0x19,
0x62, 0x12, 0xae, 0x1b, 0x60, 0x5d, 0xa3, 0xb0
};
size_t nervesize = 3819855; // NERVE.WAD's file size
int w = IWAD_FILENUM;
while (++w < GetNumWads())
{
FileReader *fr = GetFileReader(w);
if (fr == NULL)
{
continue;
}
if (fr->GetLength() != (long)nervesize)
{
// Skip MD5 computation when there is a
// cheaper way to know this is not the file
continue;
}
fr->Seek(0, SEEK_SET);
MD5Context md5;
md5.Update(fr, fr->GetLength());
md5.Final(cksum);
if (memcmp(nerve, cksum, 16) == 0)
{
found = true;
break;
}
}
if (!found)
return;
for (int i = GetFirstLump(w); i <= GetLastLump(w); i++)
{
// Only rename the maps from NERVE.WAD
assert(LumpInfo[i].wadnum == w);
if (LumpInfo[i].lump->dwName == MAKE_ID('C', 'W', 'I', 'L'))
{
LumpInfo[i].lump->Name[0] = 'N';
}
else if (LumpInfo[i].lump->dwName == MAKE_ID('M', 'A', 'P', '0'))
{
LumpInfo[i].lump->Name[6] = LumpInfo[i].lump->Name[4];
LumpInfo[i].lump->Name[5] = '0';
LumpInfo[i].lump->Name[4] = 'L';
LumpInfo[i].lump->dwName = MAKE_ID('L', 'E', 'V', 'E');
}
}
}
示例2: if
HMISong::HMISong (FileReader &reader, EMidiDevice type)
: MIDIStreamer(type), MusHeader(0), Tracks(0)
{
#ifdef _WIN32
if (ExitEvent == NULL)
{
return;
}
#endif
int len = reader.GetLength();
if (len < 0x100)
{ // Way too small to be HMI.
return;
}
MusHeader = new BYTE[len];
SongLen = len;
NumTracks = 0;
if (reader.Read(MusHeader, len) != len)
return;
// Do some validation of the MIDI file
if (memcmp(MusHeader, HMI_SONG_MAGIC, sizeof(HMI_SONG_MAGIC)) == 0)
{
SetupForHMI(len);
}
else if (((DWORD *)MusHeader)[0] == MAKE_ID('H','M','I','M') &&
((DWORD *)MusHeader)[1] == MAKE_ID('I','D','I','P'))
{
SetupForHMP(len);
}
}
示例3: MIDIStreamer
XMISong::XMISong (FileReader &reader, EMidiDevice type, const char *args)
: MIDIStreamer(type, args), MusHeader(0), Songs(0)
{
SongLen = reader.GetLength();
MusHeader = new uint8_t[SongLen];
if (reader.Read(MusHeader, SongLen) != SongLen)
return;
// Find all the songs in this file.
NumSongs = FindXMIDforms(MusHeader, SongLen, NULL);
if (NumSongs == 0)
{
return;
}
// XMIDI files are played with a constant 120 Hz clock rate. While the
// song may contain tempo events, these are vestigial remnants from the
// original MIDI file that were not removed by the converter and should
// be ignored.
//
// We can use any combination of Division and Tempo values that work out
// to be 120 Hz.
Division = 60;
InitialTempo = 500000;
Songs = new TrackInfo[NumSongs];
memset(Songs, 0, sizeof(*Songs) * NumSongs);
FindXMIDforms(MusHeader, SongLen, Songs);
CurrSong = Songs;
DPrintf(DMSG_SPAMMY, "XMI song count: %d\n", NumSongs);
}
示例4: Check
bool FPatchTexture::Check(FileReader & file)
{
if (file.GetLength() < 13) return false; // minimum length of a valid Doom patch
BYTE *data = new BYTE[file.GetLength()];
file.Seek(0, SEEK_SET);
file.Read(data, file.GetLength());
const patch_t * foo = (const patch_t *)data;
int height = LittleShort(foo->height);
int width = LittleShort(foo->width);
bool gapAtStart=true;
if (height > 0 && height < 2048 && width > 0 && width <= 2048 && width < file.GetLength()/4)
{
// The dimensions seem like they might be valid for a patch, so
// check the column directory for extra security. At least one
// column must begin exactly at the end of the column directory,
// and none of them must point past the end of the patch.
bool gapAtStart = true;
int x;
for (x = 0; x < width; ++x)
{
DWORD ofs = LittleLong(foo->columnofs[x]);
if (ofs == (DWORD)width * 4 + 8)
{
gapAtStart = false;
}
else if (ofs >= (DWORD)(file.GetLength())) // Need one byte for an empty column (but there's patches that don't know that!)
{
delete [] data;
return false;
}
}
delete [] data;
return !gapAtStart;
}
delete [] data;
return false;
}
示例5: EasyDecryptInMemory
errno_t EasyDecryptInMemory(const string& filename, const string& key, MemoryWriter *writer)
{
LOGPOS();
FilePath inFilePath(filename);
FileReader reader;
if (reader.Open(inFilePath.value()) != CPT_OK) {
LOGW("Open file %s failed!", inFilePath.value().c_str());
return CPT_ERROR;
}
uint64_t u64 = 0;
reader.GetLength(&u64);
if (writer->Reserve(u64) != CPT_OK) {
LOGW("MemoryWriter SetLength failed!");
return CPT_ERROR;
}
Decrypt decrypt;
if (decrypt.SetReader(&reader) != CPT_OK) {
LOGW("Decrypt set reader failed!");
return CPT_ERROR;
}
if (decrypt.LoadHeader() != CPT_OK) {
LOGW("Decrypt LoadHeader error");
return CPT_ERROR;
}
if (decrypt.DecryptHeader(key.c_str(), key.length()) == NULL) {
LOGW("LoadHeader error");
return CPT_ERROR;
}
if (decrypt.SetWriter(writer) != CPT_OK) {
LOGW("Decrypt set writer failed!");
return CPT_ERROR;
}
int err = decrypt.PreDecrypt();
ASSERT(err == CPT_OK);
if (decrypt.DoDecrypt(key.c_str(), key.length())) {
LOGW("Decrypt decrypt file failed!");
return CPT_ERROR;
}
err = decrypt.PostDecrypt();
ASSERT(err == CPT_OK);
return CPT_OK;
}
示例6: IMAADPCMUnpack16
// Note: Only works for mono samples.
bool IMAADPCMUnpack16(int16 *target, SmpLength sampleLen, FileReader file, uint16 blockAlign)
//-------------------------------------------------------------------------------------------
{
static const int32 IMAIndexTab[8] = { -1, -1, -1, -1, 2, 4, 6, 8 };
static const int32 IMAUnpackTable[90] =
{
7, 8, 9, 10, 11, 12, 13, 14,
16, 17, 19, 21, 23, 25, 28, 31,
34, 37, 41, 45, 50, 55, 60, 66,
73, 80, 88, 97, 107, 118, 130, 143,
157, 173, 190, 209, 230, 253, 279, 307,
337, 371, 408, 449, 494, 544, 598, 658,
724, 796, 876, 963, 1060, 1166, 1282, 1411,
1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024,
3327, 3660, 4026, 4428, 4871, 5358, 5894, 6484,
7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794,
32767, 0
};
if((sampleLen < 4) || (!target) || (blockAlign < 5) || (blockAlign > file.GetLength()))
return false;
SmpLength nPos = 0;
while((nPos < sampleLen) && file.CanRead(5))
{
int32 value = file.ReadIntLE<int16>();
int32 nIndex = file.ReadIntLE<uint8>();
nIndex = Clamp(nIndex, 0, 89);
file.Skip(1);
target[nPos++] = (int16)value;
for(uint32 i = 0; (i < (blockAlign - 4u) * 2u) && (nPos < sampleLen) && file.AreBytesLeft(); i++)
{
uint8 delta;
if(i & 1)
{
delta = (file.ReadIntLE<uint8>() >> 4) & 0x0F;
} else
{
delta = file.ReadIntLE<uint8>() & 0x0F;
file.SkipBack(1);
}
int32 v = IMAUnpackTable[nIndex] >> 3;
if (delta & 1) v += IMAUnpackTable[nIndex] >> 2;
if (delta & 2) v += IMAUnpackTable[nIndex] >> 1;
if (delta & 4) v += IMAUnpackTable[nIndex];
if (delta & 8) value -= v; else value += v;
nIndex += IMAIndexTab[delta & 7];
nIndex = Clamp(nIndex, 0, 88);
target[nPos++] = static_cast<int16>(Clamp(value, -32768, 32767));
}
示例7: OpenFile
bool FScanner::OpenFile (const char *name)
{
Close ();
FileReader fr;
if (!fr.OpenFile(name)) return false;
auto filesize = fr.GetLength();
auto filebuff = fr.Read();
if (filebuff.Size() == 0 && filesize > 0) return false;
ScriptBuffer = FString((const char *)filebuff.Data(), filesize);
ScriptName = name; // This is used for error messages so the full file name is preferable
LumpNum = -1;
PrepareScript ();
return true;
}
示例8: if
off_t MPG123Decoder::file_lseek(void *handle, off_t offset, int whence)
{
FileReader *reader = reinterpret_cast<MPG123Decoder*>(handle)->Reader;
if(whence == SEEK_CUR)
{
if(offset < 0 && reader->Tell()+offset < 0)
return -1;
}
else if(whence == SEEK_END)
{
if(offset < 0 && reader->GetLength()+offset < 0)
return -1;
}
if(reader->Seek(offset, whence) != 0)
return -1;
return reader->Tell();
}
示例9: ArchiveBase
CZipArchive::CZipArchive(FileReader &file) : ArchiveBase(file)
//------------------------------------------------------------
{
zipFile = new mz_zip_archive();
mz_zip_archive *zip = static_cast<mz_zip_archive*>(zipFile);
MemsetZero(*zip);
if(!mz_zip_reader_init_mem(zip, file.GetRawData(), file.GetLength(), 0))
{
delete zip;
zip = nullptr;
zipFile = nullptr;
}
if(!zip)
{
return;
}
for(mz_uint i = 0; i < mz_zip_reader_get_num_files(zip); ++i)
{
ArchiveFileInfo info;
info.type = ArchiveFileInvalid;
mz_zip_archive_file_stat stat;
MemsetZero(stat);
if(mz_zip_reader_file_stat(zip, i, &stat))
{
info.type = ArchiveFileNormal;
info.name = mpt::PathString::FromWide(mpt::ToWide(mpt::CharsetCP437, stat.m_filename));
info.size = stat.m_uncomp_size;
}
if(mz_zip_reader_is_file_a_directory(zip, i))
{
info.type = ArchiveFileSpecial;
} else if(mz_zip_reader_is_file_encrypted(zip, i))
{
info.type = ArchiveFileSpecial;
}
contents.push_back(info);
}
}
示例10: if
off_t MPG123Decoder::file_lseek(void *handle, off_t offset, int whence)
{
MPG123Decoder *self = reinterpret_cast<MPG123Decoder*>(handle);
FileReader *reader = self->Reader;
if(whence == SEEK_SET)
offset += self->StartOffset;
else if(whence == SEEK_CUR)
{
if(offset < 0 && reader->Tell()+offset < self->StartOffset)
return -1;
}
else if(whence == SEEK_END)
{
if(offset < 0 && reader->GetLength()+offset < self->StartOffset)
return -1;
}
if(reader->Seek(offset, whence) != 0)
return -1;
return reader->Tell() - self->StartOffset;
}
示例11: if
HMISong::HMISong (FileReader &reader)
{
int len = (int)reader.GetLength();
if (len < 0x100)
{ // Way too small to be HMI.
return;
}
MusHeader = new uint8_t[len];
SongLen = len;
NumTracks = 0;
if (reader.Read(MusHeader, len) != len)
return;
// Do some validation of the MIDI file
if (memcmp(MusHeader, HMI_SONG_MAGIC, sizeof(HMI_SONG_MAGIC)) == 0)
{
SetupForHMI(len);
}
else if (((uint32_t *)MusHeader)[0] == MAKE_ID('H','M','I','M') &&
((uint32_t *)MusHeader)[1] == MAKE_ID('I','D','I','P'))
{
SetupForHMP(len);
}
}
示例12: AddFile
void FWadCollection::AddFile (const char *filename, FileReader *wadinfo)
{
int startlump;
bool isdir = false;
if (wadinfo == NULL)
{
// Does this exist? If so, is it a directory?
if (!DirEntryExists(filename, &isdir))
{
Printf(TEXTCOLOR_RED "%s: File or Directory not found\n", filename);
PrintLastError();
return;
}
if (!isdir)
{
try
{
wadinfo = new FileReader(filename);
}
catch (CRecoverableError &err)
{ // Didn't find file
Printf (TEXTCOLOR_RED "%s\n", err.GetMessage());
PrintLastError ();
return;
}
}
}
if (!batchrun) Printf (" adding %s", filename);
startlump = NumLumps;
FResourceFile *resfile;
if (!isdir)
resfile = FResourceFile::OpenResourceFile(filename, wadinfo);
else
resfile = FResourceFile::OpenDirectory(filename);
if (resfile != NULL)
{
uint32_t lumpstart = LumpInfo.Size();
resfile->SetFirstLump(lumpstart);
for (uint32_t i=0; i < resfile->LumpCount(); i++)
{
FResourceLump *lump = resfile->GetLump(i);
FWadCollection::LumpRecord *lump_p = &LumpInfo[LumpInfo.Reserve(1)];
lump_p->lump = lump;
lump_p->wadnum = Files.Size();
}
if (static_cast<int>(Files.Size()) == GetIwadNum() && gameinfo.gametype == GAME_Strife && gameinfo.flags & GI_SHAREWARE)
{
resfile->FindStrifeTeaserVoices();
}
Files.Push(resfile);
for (uint32_t i=0; i < resfile->LumpCount(); i++)
{
FResourceLump *lump = resfile->GetLump(i);
if (lump->Flags & LUMPF_EMBEDDED)
{
FString path;
path.Format("%s:%s", filename, lump->FullName.GetChars());
FileReader *embedded = lump->NewReader();
AddFile(path, embedded);
}
}
if (hashfile)
{
uint8_t cksum[16];
char cksumout[33];
memset(cksumout, 0, sizeof(cksumout));
FileReader *reader = wadinfo;
if (reader != NULL)
{
MD5Context md5;
reader->Seek(0, SEEK_SET);
md5.Update(reader, reader->GetLength());
md5.Final(cksum);
for (size_t j = 0; j < sizeof(cksum); ++j)
{
sprintf(cksumout + (j * 2), "%02X", cksum[j]);
}
fprintf(hashfile, "file: %s, hash: %s, size: %ld\n", filename, cksumout, reader->GetLength());
}
else
fprintf(hashfile, "file: %s, Directory structure\n", filename);
for (uint32_t i = 0; i < resfile->LumpCount(); i++)
{
//.........这里部分代码省略.........
示例13: MIDIStreamer
MIDISong2::MIDISong2 (FileReader &reader, EMidiDevice type, const char *args)
: MIDIStreamer(type, args), MusHeader(0), Tracks(0)
{
int p;
int i;
#ifdef _WIN32
if (ExitEvent == NULL)
{
return;
}
#endif
SongLen = reader.GetLength();
MusHeader = new BYTE[SongLen];
if (reader.Read(MusHeader, SongLen) != SongLen)
return;
// Do some validation of the MIDI file
if (MusHeader[4] != 0 || MusHeader[5] != 0 || MusHeader[6] != 0 || MusHeader[7] != 6)
return;
if (MusHeader[8] != 0 || MusHeader[9] > 2)
return;
Format = MusHeader[9];
if (Format == 0)
{
NumTracks = 1;
}
else
{
NumTracks = MusHeader[10] * 256 + MusHeader[11];
}
// The division is the number of pulses per quarter note (PPQN).
Division = MusHeader[12] * 256 + MusHeader[13];
if (Division == 0)
{ // PPQN is zero? Then the song cannot play because it never pulses.
return;
}
Tracks = new TrackInfo[NumTracks];
// Gather information about each track
for (i = 0, p = 14; i < NumTracks && p < SongLen + 8; ++i)
{
DWORD chunkLen =
(MusHeader[p+4]<<24) |
(MusHeader[p+5]<<16) |
(MusHeader[p+6]<<8) |
(MusHeader[p+7]);
if (chunkLen + p + 8 > (DWORD)SongLen)
{ // Track too long, so truncate it
chunkLen = SongLen - p - 8;
}
if (MusHeader[p+0] == 'M' &&
MusHeader[p+1] == 'T' &&
MusHeader[p+2] == 'r' &&
MusHeader[p+3] == 'k')
{
Tracks[i].TrackBegin = MusHeader + p + 8;
Tracks[i].TrackP = 0;
Tracks[i].MaxTrackP = chunkLen;
}
p += chunkLen + 8;
}
// In case there were fewer actual chunks in the file than the
// header specified, update NumTracks with the current value of i
NumTracks = i;
if (NumTracks == 0)
{ // No tracks, so nothing to play
return;
}
}
示例14: if
OPENMPT_NAMESPACE_BEGIN
PNG::Bitmap *PNG::ReadPNG(FileReader &file)
//-----------------------------------------
{
file.Rewind();
if(!file.ReadMagic("\211PNG\r\n\032\n"))
{
return nullptr;
}
uint32_t width = 0;
uint32_t height = 0;
uint8_t bitDepth;
uint8_t colorType;
uint8_t compressionMethod;
uint8_t filterMethod;
uint8_t interlaceMethod;
std::vector<uint8_t> dataIn;
std::vector<Pixel> palette;
while(file.AreBytesLeft())
{
uint32_t chunkLength = file.ReadUint32BE();
char magic[4];
file.ReadArray(magic);
FileReader chunk = file.ReadChunk(chunkLength);
file.Skip(4); // CRC32
if(!memcmp(magic, "IHDR", 4))
{
// Image header
width = chunk.ReadUint32BE();
height = chunk.ReadUint32BE();
bitDepth = chunk.ReadUint8();
colorType = chunk.ReadUint8();
compressionMethod = chunk.ReadUint8();
filterMethod = chunk.ReadUint8();
interlaceMethod = chunk.ReadUint8();
ASSERT(!filterMethod && !interlaceMethod);
} else if(!memcmp(magic, "IDAT", 4))
{
// Data block(s)
z_stream strm;
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
strm.avail_in = static_cast<uInt>(chunk.GetLength());
strm.next_in = (Bytef *)(chunk.GetRawData());
if(inflateInit2(&strm, 15) != Z_OK)
{
break;
}
int retVal;
do
{
dataIn.resize(dataIn.size() + 4096);
strm.avail_out = 4096;
strm.next_out = (Bytef *)&dataIn[dataIn.size() - 4096];
retVal = inflate(&strm, Z_NO_FLUSH);
} while(retVal == Z_OK);
inflateEnd(&strm);
} else if(!memcmp(magic, "PLTE", 4))
{
// Palette for <= 8-bit images
palette.resize(256);
size_t numEntries = std::min<size_t>(256u, chunk.GetLength() / 3u);
for(size_t i = 0; i < numEntries; i++)
{
uint8_t p[3];
chunk.ReadArray(p);
palette[i] = Pixel(p[0], p[1], p[2], 255);
}
}
}
// LUT for translating the color type into a number of color samples
const uint32_t sampleTable[] =
{
1, // 0: Grayscale
0,
3, // 2: RGB
1, // 3: Palette bitmap
2, // 4: Grayscale + Alpha
0,
4 // 6: RGBA
};
const uint32_t bitsPerPixel = colorType < CountOf(sampleTable) ? sampleTable[colorType] * bitDepth : 0;
if(!width || !height || !bitsPerPixel
|| (colorType != 2 && colorType != 3 && colorType != 6) || bitDepth != 8 // Only RGB(A) and 8-bit palette PNGs for now.
|| compressionMethod || interlaceMethod
|| (colorType == 3 && palette.empty())
|| dataIn.size() < (bitsPerPixel * width * height) / 8 + height) // Enough data present?
{
return nullptr;
}
Bitmap *bitmap = new (std::nothrow) Bitmap(width, height);
//.........这里部分代码省略.........
示例15: void
OPENMPT_NAMESPACE_BEGIN
bool CSoundFile::ReadMO3(FileReader &file, ModLoadingFlags loadFlags)
//-------------------------------------------------------------------
{
file.Rewind();
// No valid MO3 file (magic bytes: "MO3")
if(!file.CanRead(8) || !file.ReadMagic("MO3"))
{
return false;
} else if(loadFlags == onlyVerifyHeader)
{
return true;
}
#ifdef NO_MO3
// As of November 2013, the format revision is 5; Versions > 31 are unlikely to exist in the next few years,
// so we will just ignore those if there's no UNMO3 library to tell us if the file is valid or not
// (avoid log entry with .MOD files that have a song name starting with "MO3".
if(file.ReadUint8() > 31)
{
return false;
}
AddToLog(GetStrI18N("The file appears to be a MO3 file, but this OpenMPT build does not support loading MO3 files."));
return false;
#else
bool result = false; // Result of trying to load the module, false == fail.
// Try to load unmo3 dynamically.
mpt::Library unmo3 = mpt::Library(mpt::LibraryPath::App(MPT_PATHSTRING("unmo3")));
if(!unmo3.IsValid())
{
// Didn't succeed.
AddToLog(GetStrI18N("Loading MO3 file failed because unmo3.dll could not be loaded."));
} else
{
// Library loaded successfully.
#if MPT_OS_WINDOWS
#define UNMO3_API __stdcall
#else
#define UNMO3_API
#endif
typedef uint32 (UNMO3_API * UNMO3_GETVERSION)();
// Decode a MO3 file (returns the same "exit codes" as UNMO3.EXE, eg. 0=success)
// IN: data/len = MO3 data/len
// OUT: data/len = decoded data/len (if successful)
// flags & 1: Don't load samples
typedef int32 (UNMO3_API * UNMO3_DECODE_OLD)(const void **data, uint32 *len);
typedef int32 (UNMO3_API * UNMO3_DECODE)(const void **data, uint32 *len, uint32 flags);
// Free the data returned by UNMO3_Decode
typedef void (UNMO3_API * UNMO3_FREE)(const void *data);
#undef UNMO3_API
UNMO3_GETVERSION UNMO3_GetVersion = nullptr;
UNMO3_DECODE_OLD UNMO3_Decode_Old = nullptr;
UNMO3_DECODE UNMO3_Decode = nullptr;
UNMO3_FREE UNMO3_Free = nullptr;
unmo3.Bind(UNMO3_GetVersion, "UNMO3_GetVersion");
if(UNMO3_GetVersion == nullptr)
{
// Old API version: No "flags" parameter.
unmo3.Bind(UNMO3_Decode_Old, "UNMO3_Decode");
} else
{
unmo3.Bind(UNMO3_Decode, "UNMO3_Decode");
}
unmo3.Bind(UNMO3_Free, "UNMO3_Free");
if((UNMO3_Decode != nullptr || UNMO3_Decode_Old != nullptr) && UNMO3_Free != nullptr)
{
file.Rewind();
const void *stream = file.GetRawData();
uint32 length = mpt::saturate_cast<uint32>(file.GetLength());
int32 unmo3result;
if(UNMO3_Decode != nullptr)
{
unmo3result = UNMO3_Decode(&stream, &length, (loadFlags & loadSampleData) ? 0 : 1);
} else
{
// Old API version: No "flags" parameter.
unmo3result = UNMO3_Decode_Old(&stream, &length);
}
if(unmo3result == 0)
{
// If decoding was successful, stream and length will keep the new pointers now.
FileReader unpackedFile(stream, length);
result = ReadXM(unpackedFile, loadFlags)
|| ReadIT(unpackedFile, loadFlags)
|| ReadS3M(unpackedFile, loadFlags)
|| ReadMTM(unpackedFile, loadFlags)
|| ReadMod(unpackedFile, loadFlags)
|| ReadM15(unpackedFile, loadFlags);
//.........这里部分代码省略.........