mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-16 14:16:09 -06:00
89 lines
3 KiB
C++
89 lines
3 KiB
C++
#include "Core.h"
|
|
|
|
BinObjInfo::BinObjInfo()
|
|
{
|
|
}
|
|
|
|
void BinObjInfo::Block::Compress(String& data)
|
|
{
|
|
switch(encoding) {
|
|
case BinObjInfo::Block::ENC_BZ2: data = BZ2Compress(data); break;
|
|
case BinObjInfo::Block::ENC_ZIP: data = ZCompress(data); break;
|
|
case BinObjInfo::Block::ENC_LZ4: data = LZ4Compress(data); break;
|
|
case BinObjInfo::Block::ENC_LZMA: data = LZMACompress(data); break;
|
|
case BinObjInfo::Block::ENC_ZSTD: data = ZstdCompress(data); break;
|
|
}
|
|
}
|
|
|
|
void BinObjInfo::Parse(CParser& binscript, String base_dir)
|
|
{
|
|
while(!binscript.IsEof()) {
|
|
String binid = binscript.ReadId();
|
|
bool ba = (binid == "BINARY_ARRAY");
|
|
bool bm = (binid == "BINARY_MASK");
|
|
if(binid == "BINARY" || ba || bm) {
|
|
binscript.PassChar('(');
|
|
Block blk;
|
|
blk.scriptline = binscript.GetLine();
|
|
blk.ident = binscript.ReadId();
|
|
ArrayMap<int, Block>& brow = blocks.GetAdd(blk.ident);
|
|
binscript.PassChar(',');
|
|
blk.index = -1;
|
|
if(ba) {
|
|
blk.flags |= Block::FLG_ARRAY;
|
|
blk.index = binscript.ReadInt();
|
|
if(blk.index < 0 || blk.index > 1000000)
|
|
binscript.ThrowError(NFormat("invalid array index: %d", blk.index));
|
|
binscript.PassChar(',');
|
|
}
|
|
else if(bm) {
|
|
blk.flags |= Block::FLG_MASK;
|
|
blk.index = brow.GetCount();
|
|
}
|
|
String file = binscript.ReadString();
|
|
if(binscript.Id("ZIP"))
|
|
blk.encoding = Block::ENC_ZIP;
|
|
else if(binscript.Id("BZ2"))
|
|
blk.encoding = Block::ENC_BZ2;
|
|
else if(binscript.Id("LZ4"))
|
|
blk.encoding = Block::ENC_LZ4;
|
|
else if(binscript.Id("LZMA"))
|
|
blk.encoding = Block::ENC_LZMA;
|
|
else if(binscript.Id("ZSTD"))
|
|
blk.encoding = Block::ENC_ZSTD;
|
|
binscript.PassChar(')');
|
|
FindFile ff;
|
|
String searchpath = NormalizePath(file, base_dir);
|
|
String searchdir = GetFileDirectory(searchpath);
|
|
Vector<String> files;
|
|
Vector<int64> lengths;
|
|
if(ff.Search(searchpath))
|
|
do
|
|
if(ff.IsFile()) {
|
|
files.Add(ff.GetName());
|
|
lengths.Add(ff.GetLength());
|
|
}
|
|
while(ff.Next());
|
|
if(files.IsEmpty())
|
|
binscript.ThrowError(NFormat("'%s' not found or not a file", file));
|
|
if(!(blk.flags & Block::FLG_MASK) && files.GetCount() > 1)
|
|
binscript.ThrowError(NFormat("Multiple files found (e.g. %s, %s) in single file mode", files[0], files[1]));
|
|
IndexSort(files, lengths);
|
|
for(int i = 0; i < files.GetCount(); i++) {
|
|
blk.file = AppendFileName(searchdir, files[i]);
|
|
blk.length = (int)lengths[i];
|
|
int f = brow.Find(blk.index);
|
|
if(f >= 0)
|
|
binscript.ThrowError(NFormat("%s[%d] already seen at line %d", blk.ident, blk.index, brow[f].scriptline));
|
|
if(blk.index < 0 && !brow.IsEmpty() || blk.index >= 0 && !brow.IsEmpty() && brow[0].index < 0)
|
|
binscript.ThrowError(NFormat("%s: mixing non-array and array elements", blk.ident));
|
|
brow.Add(blk.index, blk);
|
|
if(!(blk.flags & Block::FLG_MASK))
|
|
break;
|
|
blk.index++;
|
|
}
|
|
}
|
|
else
|
|
binscript.ThrowError("binary script item identifier expected");
|
|
}
|
|
}
|