mirror of https://gitlab.com/basile.b/dexed.git
224 lines
8.3 KiB
D
224 lines
8.3 KiB
D
module resman;
|
|
|
|
import std.stdio, std.getopt, std.path;
|
|
import std.json, std.file, std.conv, std.string;
|
|
|
|
import utils, item;
|
|
|
|
enum ResType {aFile, aFolder}
|
|
|
|
/**
|
|
* Resman main procedure.
|
|
* Params:
|
|
* args = the options and a list of file.
|
|
* - -v or --verbose: detailed messages for each operation.
|
|
* - -b or --basepath: a path used to solve relative resource filenames.
|
|
* - -files: a list of files produced by the Resman widget.
|
|
*/
|
|
void main(string[] args)
|
|
{
|
|
string[] files;
|
|
string basePath;
|
|
bool verbose;
|
|
ResourceItems items;
|
|
|
|
getopt(args, config.passThrough, "v|verbose", &verbose);
|
|
getopt(args, config.passThrough, "b|basepath", &basePath);
|
|
files = args[1..$];
|
|
|
|
if (basePath.length && basePath.exists)
|
|
{/*setCUrrentDirectory(basePath) : use to solve relative resource path\name*/}
|
|
|
|
if (!files.length) return; // + verbose, msg
|
|
foreach(f; files)
|
|
{
|
|
json2Items(f, items);
|
|
Items2Module(f, items);
|
|
}
|
|
//readln;
|
|
}
|
|
|
|
static string fmt_json_err = "invalid JSON format: %s, in file '%s'";
|
|
static string fmt_file_skp = "invalid JSON file: %s, '%s' is skipped";
|
|
static string fmt_item_skp = "invalid JSON item: %s, '%s' is skipped";
|
|
static string fmt_item_rep = "invalid JSON value: %s, has been set to '%s'";
|
|
|
|
/**
|
|
* Transforms the items contained in the JSON file fname to an array of
|
|
* ResourceItem.
|
|
* Params:
|
|
* fname = a valid filename.
|
|
* items = container for the ResourceItem found in the file.
|
|
*/
|
|
void json2Items(string fname, out ResourceItems items)
|
|
{
|
|
if (!fname.exists) {
|
|
writeMessage(true, format(fmt_file_skp, "it does not exists", fname));
|
|
return;
|
|
}
|
|
|
|
size_t size = cast(size_t) getSize(fname);
|
|
if (size == 0) {
|
|
writeMessage(true, format(fmt_file_skp, "empty file", fname));
|
|
return;
|
|
}
|
|
|
|
auto json_string = cast(string) std.file.read(fname, size);
|
|
JSONValue root = parseJSON(json_string);
|
|
if (root.type != JSON_TYPE.OBJECT) {
|
|
writeMessage(true, format(fmt_json_err, "first value must be of type OBJECT", fname));
|
|
return;
|
|
}
|
|
|
|
JSONValue * itms = ("resources" in root.object);
|
|
if (itms == null) {
|
|
writeMessage(true, format(fmt_json_err, "the member 'resources' is missing", fname));
|
|
return;
|
|
}
|
|
if (itms.type != JSON_TYPE.ARRAY) {
|
|
writeMessage(true, format(fmt_json_err, "'resources' must be of type ARRAY", fname));
|
|
return;
|
|
}
|
|
|
|
foreach(itm; itms.array)
|
|
{
|
|
if (itm.type != JSON_TYPE.OBJECT) {
|
|
writeMessage(true, format(fmt_item_skp, "an item must be of type OBJECT", itm.toString));
|
|
continue;
|
|
}
|
|
|
|
JSONValue * itm_tpe = ("resourceType" in itm.object);
|
|
JSONValue * itm_nme = ("name" in itm.object);
|
|
JSONValue * itm_idt = ("identifier" in itm.object);
|
|
JSONValue * itm_fmt = ("format" in itm.object);
|
|
JSONValue * itm_mdt = ("metadata" in itm.object);
|
|
|
|
if (itm_tpe == null || itm_nme == null || itm_idt == null ||
|
|
itm_fmt == null || itm_mdt == null)
|
|
{
|
|
writeMessage(true, format(fmt_item_skp, "an item must contain all the properties",
|
|
itm.toString));
|
|
continue;
|
|
}
|
|
|
|
if (itm_tpe.type != JSON_TYPE.STRING || itm_nme.type != JSON_TYPE.STRING ||
|
|
itm_idt.type != JSON_TYPE.STRING || itm_fmt.type != JSON_TYPE.STRING ||
|
|
itm_mdt.type != JSON_TYPE.STRING)
|
|
{
|
|
writeMessage(true, format(fmt_item_skp, "an item value must be of type STRING",
|
|
itm.toString));
|
|
continue;
|
|
}
|
|
|
|
string[] nme_vs;
|
|
string nme_v = itm_nme.str;
|
|
string idt_v = itm_idt.str;
|
|
string mdt_v = itm_mdt.str;
|
|
ResType tpe_v;
|
|
ResFormat fmt_v;
|
|
|
|
if (!nme_v.exists) {
|
|
writeMessage(true, format(fmt_item_skp, "the item filename or path is invalid", nme_v));
|
|
continue;
|
|
}
|
|
|
|
try tpe_v = to!ResType(itm_tpe.str);
|
|
catch (Exception e) {
|
|
if (isDir(nme_v)) tpe_v = ResType.aFolder;
|
|
else tpe_v = ResType.aFile;
|
|
writeMessage(true, format(fmt_item_rep, "resourceType", to!string(tpe_v)));
|
|
}
|
|
|
|
try fmt_v = to!ResFormat(itm_fmt.str);
|
|
catch (Exception e) {
|
|
fmt_v = ResFormat.bytes;
|
|
writeMessage(true, format(fmt_item_rep, "format", to!string(fmt_v)));
|
|
}
|
|
|
|
if (idt_v == "" && tpe_v == ResType.aFile)
|
|
writeMessage(true, format(fmt_item_rep, "identifier", "the striped filename"));
|
|
|
|
if (idt_v != "" && tpe_v == ResType.aFolder)
|
|
writeMessage(true, format(fmt_item_rep,
|
|
"identifier", "the striped filename of each entry in the direrctory"));
|
|
|
|
if (nme_v.isDir)
|
|
{
|
|
foreach(e; dirEntries(nme_v, SpanMode.shallow)) nme_vs ~= e;
|
|
idt_v = "";
|
|
}
|
|
else nme_vs ~= nme_v;
|
|
|
|
foreach(n; nme_vs)
|
|
{
|
|
items ~= new ResourceItem(n, fmt_v, idt_v, mdt_v);
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Writes the ResourceItems *items* as valid D code D in a file whose content
|
|
* will be imported by the library template activateResman(). The file written
|
|
* in this method has the same name as the JSON file analyzed before, but with
|
|
* another extension.
|
|
* Params:
|
|
* fname = the name of the JSON file parsed previously.
|
|
* items = an array of *ResourceItem*
|
|
*/
|
|
void Items2Module(string fname, ref ResourceItems resItems)
|
|
{
|
|
string outputFname = fname.stripExtension ~ ".resdata";
|
|
if (outputFname.exists) std.file.remove(outputFname);
|
|
|
|
// writes the resource representations to the module
|
|
writeMessage(true, "writing the resources data as text...");
|
|
outputFname.append("\r\n\r\n");
|
|
outputFname.append("private static const resource_txt = [");
|
|
foreach (i; 0 .. resItems.length -1)
|
|
outputFname.append(format("\r\n\t" ~ "\"" ~ "%s" ~ "\"" ~ ",", resItems[i].resText));
|
|
outputFname.append(format("\r\n\t" ~ "\"" ~ "%s" ~ "\"" ~ "\r\n];", resItems[$-1].resText));
|
|
|
|
// writes the resources identifiers to the module
|
|
writeMessage(true, "writing the resources identifiers...");
|
|
outputFname.append("\r\n\r\n");
|
|
outputFname.append("private static const resource_idt = [");
|
|
foreach (i; 0 .. resItems.length -1)
|
|
outputFname.append(format("\r\n\t" ~ "\"" ~ "%s" ~ "\"" ~ ",", resItems[i].resIdentifier));
|
|
outputFname.append(format("\r\n\t" ~ "\"" ~ "%s" ~ "\"" ~ "\r\n];", resItems[$-1].resIdentifier));
|
|
|
|
// writes the resources metadata to the module
|
|
writeMessage(true, "writing the resources metadata...");
|
|
outputFname.append("\r\n\r\n");
|
|
outputFname.append("private static const resource_mdt = [");
|
|
foreach (i; 0 .. resItems.length -1)
|
|
outputFname.append(format("\r\n\t" ~ "\"" ~ "%s" ~ "\"" ~ ",", resItems[i].resMetaData));
|
|
outputFname.append(format("\r\n\t" ~ "\"" ~ "%s" ~ "\"" ~ "\r\n];", resItems[$-1].resMetaData));
|
|
|
|
// writes the resources encoder kind to the module
|
|
writeMessage(true, "writing the resources kind...");
|
|
outputFname.append("\r\n\r\n");
|
|
outputFname.append("private static const resource_enc = [");
|
|
foreach (i; 0 .. resItems.length -1)
|
|
outputFname.append(format("\r\n\t%s.%s,", ResFormat.stringof, resItems[i].resFormat));
|
|
outputFname.append(format("\r\n\t%s.%s \r\n];", ResFormat.stringof, resItems[$-1].resFormat));
|
|
|
|
// writes the initial sums to the module
|
|
writeMessage(true, "writing the resources initial sum...");
|
|
outputFname.append("\r\n\r\n");
|
|
outputFname.append("private static const uint[] resource_sumi = [");
|
|
foreach (i; 0 .. resItems.length -1)
|
|
outputFname.append(format("\r\n\t" ~ "%.d" ~ ",", resItems[i].initialSum));
|
|
outputFname.append(format("\r\n\t" ~ "%.d" ~ "\r\n];", resItems[$-1].initialSum));
|
|
|
|
// writes the encoded sums to the module
|
|
writeMessage(true, "writing the resources encoded sum...");
|
|
outputFname.append("\r\n\r\n");
|
|
outputFname.append("private static const uint[] resource_sume = [");
|
|
foreach (i; 0 .. resItems.length -1)
|
|
outputFname.append(format("\r\n\t" ~ "%.d" ~ ",", resItems[i].encodedSum));
|
|
outputFname.append(format("\r\n\t" ~ "%.d" ~ "\r\n];", resItems[$-1].encodedSum));
|
|
}
|
|
|
|
|