]> git.tdb.fi Git - libs/datafile.git/blobdiff - tool/tool.cpp
Add an unpack option to the data tool
[libs/datafile.git] / tool / tool.cpp
index a82d5875f2a40630cfc1252f5a99ac920bdfc60c..73c49f7433ad6631a2f32a42607f79736fde68b2 100644 (file)
@@ -2,6 +2,7 @@
 #include <msp/io/buffered.h>
 #include <msp/io/console.h>
 #include <msp/io/file.h>
+#include <msp/datafile/packsource.h>
 #include <msp/datafile/parser.h>
 #include <msp/datafile/statement.h>
 #include "compiler.h"
@@ -18,30 +19,44 @@ DataTool::DataTool(int argc, char **argv):
        float_size(0),
        compress(false),
        pack(false),
+       unpack(false),
        debug(false)
 {
        GetOpt getopt;
-       getopt.add_option('b', "binary", binary, GetOpt::NO_ARG);
-       getopt.add_option('c', "compile", compile, GetOpt::NO_ARG);
-       getopt.add_option('f', "float-size", float_size, GetOpt::REQUIRED_ARG);
-       getopt.add_option('g', "debug", debug, GetOpt::NO_ARG);
-       getopt.add_option('o', "output", out_fn, GetOpt::REQUIRED_ARG);
-       getopt.add_option('p', "pack", pack, GetOpt::NO_ARG);
-       getopt.add_option('z', "compress", compress, GetOpt::NO_ARG);
+       getopt.add_option('b', "binary", binary, GetOpt::NO_ARG).set_help("Produce a binary datafile");
+       getopt.add_option('c', "compile", compile, GetOpt::NO_ARG).set_help("Create a collection based on a template file");
+       getopt.add_option('f', "float-size", float_size, GetOpt::REQUIRED_ARG).set_help("Floating-point precision", "BITS");
+       getopt.add_option('g', "debug", debug, GetOpt::NO_ARG).set_help("Display control statements");
+       getopt.add_option('o', "output", out_fn, GetOpt::REQUIRED_ARG).set_help("Output to a file instead of stdout", "FILE");
+       getopt.add_option('p', "pack", pack, GetOpt::NO_ARG).set_help("Create a pack from multiple files");
+       getopt.add_option('u', "unpack", unpack, GetOpt::NO_ARG).set_help("Unpacks files from packs into the current directory");
+       getopt.add_option('z', "compress", compress, GetOpt::NO_ARG).set_help("Produce a compressed datafile");
+       getopt.add_argument("infile", in_fns, GetOpt::OPTIONAL_ARG).set_help("Files to process");
        getopt(argc, argv);
 
-       in_fns = getopt.get_args();
-       if(in_fns.empty())
-               in_fns.push_back("-");
+       if(compile+pack+unpack>1)
+               throw usage_error("Only one of -c, -p and -u may be specified");
 
        if(pack && out_fn=="-")
                throw usage_error("Can't write pack to stdout");
+
+       if(in_fns.empty())
+               in_fns.push_back("-");
+
+       if(unpack)
+       {
+               for(list<string>::const_iterator i=in_fns.begin(); i!=in_fns.end(); ++i)
+                       if(*i=="-")
+                               throw usage_error("Can't unpack from stdout");
+       }
 }
 
 int DataTool::main()
 {
        if(pack)
                do_pack();
+       else if(unpack)
+               do_unpack();
        else if(compile)
                do_compile();
        else
@@ -55,7 +70,7 @@ void DataTool::do_transfer()
        IO::Base *out = open_output(out_fn);
        DataFile::Writer *writer = create_writer(*out);
 
-       for(vector<string>::const_iterator i=in_fns.begin(); i!=in_fns.end(); ++i)
+       for(list<string>::const_iterator i=in_fns.begin(); i!=in_fns.end(); ++i)
        {
                IO::Base *in = open_input(*i);
                DataFile::Parser parser(*in, *i);
@@ -80,7 +95,7 @@ void DataTool::do_compile()
        DataFile::Writer *writer = create_writer(*out);
 
        Compiler compiler(*writer);
-       for(vector<string>::const_iterator i=in_fns.begin(); i!=in_fns.end(); ++i)
+       for(list<string>::const_iterator i=in_fns.begin(); i!=in_fns.end(); ++i)
        {
                IO::Base *in = open_input(*i);
                DataFile::Parser parser(*in, *i);
@@ -95,11 +110,35 @@ void DataTool::do_compile()
 void DataTool::do_pack()
 {
        Packer packer(*this);
-       for(vector<string>::const_iterator i=in_fns.begin(); i!=in_fns.end(); ++i)
+       for(list<string>::const_iterator i=in_fns.begin(); i!=in_fns.end(); ++i)
                packer.pack_file(*i);
        packer.create_pack(out_fn);
 }
 
+void DataTool::do_unpack()
+{
+       DataFile::PackSource source;
+       for(list<string>::const_iterator i=in_fns.begin(); i!=in_fns.end(); ++i)
+               source.add_pack_file(*i);
+
+       list<DataFile::PackSource::FileInfo> files = source.list_files();
+       for(list<DataFile::PackSource::FileInfo>::const_iterator i=files.begin(); i!=files.end(); ++i)
+       {
+               IO::Seekable *in = source.open(i->name);
+               IO::Base *out = open_output(i->name);
+               char buf[16384];
+               while(1)
+               {
+                       unsigned len = in->read(buf, sizeof(buf));
+                       out->write(buf, len);
+                       if(len<sizeof(buf))
+                               break;
+               }
+               delete in;
+               delete out;
+       }
+}
+
 IO::Base *DataTool::open_output(const string &fn)
 {
        if(fn=="-")