mirror of https://gitlab.com/basile.b/dexed.git
160 lines
5.1 KiB
D
160 lines
5.1 KiB
D
module item;
|
|
|
|
import core.exception;
|
|
|
|
import std.file, std.path;
|
|
import std.string: format;
|
|
|
|
import utils;
|
|
|
|
enum ResFormat {bytes, utf8, base16, base64, z85, e7F}
|
|
|
|
alias ResourceItems = ResourceItem * [];
|
|
|
|
/**
|
|
* Resource item.
|
|
* The resource properties and the encoded form are generated in the constructor.
|
|
*/
|
|
struct ResourceItem{
|
|
private:
|
|
static const resFileMsg = "resource file '%s' ";
|
|
ResFormat _resFormat;
|
|
string _resIdentifier;
|
|
string _resMetaData;
|
|
char[] _resTxtData;
|
|
ubyte[] _resRawData;
|
|
uint _initialSum;
|
|
uint _encodedSum;
|
|
|
|
bool encodeDispatcher(){
|
|
final switch(this._resFormat){
|
|
case ResFormat.bytes:
|
|
return encodeUtf8(); // should add to a ubyte[][] import(filename)
|
|
case ResFormat.utf8:
|
|
return encodeUtf8();
|
|
case ResFormat.base16:
|
|
return encodeb16();
|
|
case ResFormat.base64:
|
|
return encodeb64();
|
|
case ResFormat.z85:
|
|
return encodez85();
|
|
case ResFormat.e7F:
|
|
return encodee7F();
|
|
}
|
|
}
|
|
|
|
/// encodes _resRawData to an UTF8 string
|
|
bool encodeUtf8(){
|
|
scope(failure) return false;
|
|
_resTxtData = (cast(char[])_resRawData).dup;
|
|
return true;
|
|
}
|
|
|
|
/// encodes _resRawData to a hex string
|
|
bool encodeb16(){
|
|
scope(failure) return false;
|
|
foreach(b; _resRawData)
|
|
this._resTxtData ~= ubyte2Hex(b);
|
|
assert(_resTxtData.length == _resRawData.length * 2,
|
|
"b16 representation length mismatches");
|
|
return true;
|
|
}
|
|
|
|
/// encodes _resRawData to a base64 string
|
|
bool encodeb64(){
|
|
import std.base64: Base64;
|
|
scope(failure) return false;
|
|
_resTxtData = Base64.encode(_resRawData);
|
|
return true;
|
|
}
|
|
|
|
/// encodes _resRawData to a Z85 string
|
|
bool encodez85(){
|
|
import z85: Z85_encode;
|
|
scope(failure) return false;
|
|
_resTxtData = Z85_encode(_resRawData);
|
|
assert(_resTxtData.length == _resRawData.length * 5 / 4,
|
|
"z85 representation length mismatches");
|
|
return true;
|
|
}
|
|
|
|
/// encodes _resRawData to an e7F string
|
|
bool encodee7F()
|
|
{
|
|
import e7F: encode_7F;
|
|
scope(failure) return false;
|
|
_resTxtData = encode_7F(_resRawData);
|
|
return true;
|
|
}
|
|
|
|
public:
|
|
|
|
/**
|
|
* Creates and encodes a new resource item.
|
|
*
|
|
* Params:
|
|
*
|
|
* resFile = the file whose content is to encode.
|
|
* resEnc = the encoding format.
|
|
* resIdent = optional string used as identifier. When not set, the filename is used.
|
|
* resMeta = optional string used as metadata.
|
|
*
|
|
* Examples:
|
|
* --------
|
|
* auto item = new Item("\folder\strings_en.txt", ResEncoding.e7F, "string_english");
|
|
* auto item = new Item("\folder\strings_fr.txt", ResEncoding.e7F, "string_frecnh");
|
|
* --------
|
|
*/
|
|
this(string resFile, ResFormat resFormat, string resIdent = "", string resMeta = "")
|
|
{
|
|
this._resFormat = resFormat;
|
|
|
|
// load the raw content
|
|
if (!resFile.exists)
|
|
throw new Exception(format(resFileMsg ~ "does not exist", resFile));
|
|
else
|
|
_resRawData = cast(ubyte[])std.file.read(resFile);
|
|
if (!_resRawData.length)
|
|
throw new Exception(format(resFileMsg ~ "is empty", resFile));
|
|
|
|
import std.digest.crc: CRC32;
|
|
CRC32 ihash;
|
|
ihash.put(_resRawData);
|
|
_initialSum = crc322uint(ihash.finish);
|
|
|
|
// sets the resource identifier to the res filename if param is empty
|
|
this._resIdentifier = resIdent;
|
|
if (this._resIdentifier == "")
|
|
this._resIdentifier = resFile.baseName.stripExtension;
|
|
|
|
this._resMetaData = resMeta;
|
|
|
|
if (!encodeDispatcher)
|
|
throw new Exception(format(resFileMsg ~ "encoding failed", resFile));
|
|
this._resRawData.length = 0;
|
|
CRC32 ehash;
|
|
ehash.put(cast(ubyte[])_resTxtData);
|
|
_encodedSum = crc322uint(ehash.finish);
|
|
|
|
writeMessage(true, format("encoded resource file '%s'", resFile));
|
|
}
|
|
|
|
/// returns the resource encoded as a string.
|
|
char[] resText(){return _resTxtData;}
|
|
|
|
/// returns the resource identifier.
|
|
string resIdentifier(){return _resIdentifier;}
|
|
|
|
/// returns the resource metadata.
|
|
string resMetaData(){return _resMetaData;}
|
|
|
|
/// returns the resource encoding kind.
|
|
ResFormat resFormat(){return _resFormat;}
|
|
|
|
/// returns the signature of the original data.
|
|
uint initialSum(){return _initialSum;}
|
|
|
|
/// returns the signature of the encoded data.
|
|
uint encodedSum(){return _encodedSum;}
|
|
}
|