root/trunk/bintod/bintod.d

Revision 319, 8.1 kB (checked in by keinfarbton, 7 years ago)

BinToD fixed for windows

Line 
1 /*
2  *  Copyright (C) 2006/2007 Frank Benoit <benoit@tionex.de>
3  *
4  *  This software is provided 'as-is', without any express or implied
5  *  warranty.  In no event will the authors be held liable for any damages
6  *  arising from the use of this software.
7  *
8  *  Permission is granted to anyone to use this software for any purpose,
9  *  including commercial applications, and to alter it and redistribute it
10  *  freely, subject to the following restrictions:
11  *
12  *  1. The origin of this software must not be misrepresented; you must not
13  *     claim that you wrote the original software. If you use this software
14  *     in a product, an acknowledgment in the product documentation would be
15  *     appreciated but is not required.
16  *  2. Altered source versions must be plainly marked as such, and must not be
17  *     misrepresented as being the original software.
18  *  3. This notice may not be removed or altered from any source distribution.
19  */
20 module bintod;
21
22 import             tango.io.Stdout;
23 import             tango.io.FileConduit;
24 import             tango.io.Buffer;
25 import             tango.io.Print;
26 import             tango.text.convert.Layout;
27 import             tango.text.convert.Utf;
28 import             tango.text.convert.UnicodeBom;
29 import             tango.text.Util : replace, containsPattern;
30 import             tango.text.stream.LineIterator;
31
32 import             mango.xml.sax.Exceptions;
33 import             mango.xml.sax.DefaultSAXHandler;
34 import             mango.xml.sax.model.ISAXParser;
35 import             mango.xml.sax.parser.teqXML;
36
37 public Layout!(char) Layouter;
38
39 static this(){
40     Layouter  = new Layout!(char);
41 }
42
43 public bool isDigit( dchar c ){
44     return ( c >= '0' && c <= '9' );
45 }
46
47 public bool isAlpha( dchar c ){
48     return ( c >= 'a' && c <= 'z' ) || ( c >= 'A' && c <= 'Z' );
49 }
50
51 public bool isAlphaNumeric( dchar c ){
52     return isAlpha(c) || isDigit(c);
53 }
54 void usage() {
55     Stdout.formatln("usage: configfile.xml");
56 }
57
58 class ResourceData {
59     char[]       mFile;
60     char[]       mId;
61     char[]       mVarName;
62     char[]       mVersion;
63 }
64
65 class Config {
66     char[]         mTargetFile;
67     char[]         mTargetModule;
68     ResourceData[] mResources;
69 }
70
71
72 const char[] idResource       = "resource";
73 const char[]       idPath     = "path";
74 const char[]       idId       = "id";
75 const char[]       idVersion  = "version";
76 const char[]       idVariable = "variable";
77
78 const char[]       idTarget = "target";
79 const char[]       idFile   = "file";
80 const char[]       idModule = "module";
81
82 Config parserConfig(char[] aConfigPath) {
83     Config config;
84     FileConduit conduit = new FileConduit(aConfigPath);
85
86     auto parser = new XMLReader!(char)();
87     parser.parse( conduit, new class DefaultSAXHandler!(char){
88             char[][char[]] attribs;
89             void startDocument() {
90             }
91             void endDocument() {
92             }
93             void startElement(char[] name) {
94                 attribs = null;
95             }
96             void addAttribute(char[] key, char[] value) {
97                 attribs[key.dup] = value.dup;
98             }
99             void endElement(char[] name) {
100                 if (name == idTarget) {
101                     config               = new Config;
102                     config.mTargetFile   = attribs[idFile];
103                     config.mTargetModule = attribs[idModule];
104                 }
105                 else if (name == idResource) {
106                     ResourceData res = new ResourceData;
107                     res.mFile    = attribs[idPath];
108                     res.mId      = attribs[idId];
109                     res.mVarName = attribs[idVariable];
110                     if (idVersion in attribs) {
111                         res.mVersion = attribs[idVersion];
112                     }
113                     else {
114                         res.mVersion = "all";
115                     }
116                     config.mResources ~= res;
117                 }
118             }
119             } );
120
121     conduit.close();
122     return(config);
123 }
124
125 int main(char[][] args) {
126     if (args.length != 2) {
127         usage();
128         return(1);
129     }
130     Config      config  = parserConfig(args[1]);
131     auto        config_src = new FileConduit(args[1], FileConduit.ReadExisting );
132     auto        cfgIter = new LineIterator!(char) ( config_src );
133
134     FileConduit file = new FileConduit(config.mTargetFile, FileConduit.ReadWriteCreate);
135     file.truncate();
136     auto        mWriter = new Print!(char) (Layouter, new Buffer(file));
137
138     mWriter.formatln("//");
139     mWriter.formatln("// This file was generated with bintod");
140     mWriter.formatln("//");
141     mWriter.formatln("// The content of the config was:"c);
142     while (cfgIter.next) {
143         mWriter.format("//:");
144         mWriter.formatln(cfgIter.get);
145     }
146     config_src.close();
147     mWriter.formatln("module {0};", config.mTargetModule);
148     mWriter.formatln("");
149     mWriter.formatln("");
150
151     // Write id to variable mapper
152     mWriter.formatln("extern(C) ubyte[] resources_getDataById( char[] aId ){{");
153     foreach (ResourceData res; config.mResources) {
154         mWriter.formatln("    version( {0} ){{", res.mVersion);
155         mWriter.formatln("        if( aId == \"{0}\" ) return {1};", res.mId, res.mVarName);
156         mWriter.formatln("    }");
157     }
158     mWriter.formatln("    return null;");
159     mWriter.formatln("}");
160     mWriter.formatln("");
161
162     // Write the data
163     foreach (ResourceData res; config.mResources) {
164         mWriter.formatln("version( {0} ){{", res.mVersion);
165
166         version( Windows ){
167             char[] fn = replace( res.mFile, '/', '\\' );
168         }
169         else version( linux ){
170             char[] fn = replace( res.mFile, '\\', '/' );
171         }
172         auto path = new FilePath( fn );
173         if( path.exists() ){
174             Stdout.formatln( "processing file {}", fn );
175         }
176         else{
177             Stdout.formatln( "BINTOD Error: file {} does not exist.", fn );
178         }
179         FileConduit dataFc = new FileConduit( fn, FileConduit.ReadExisting );
180         ubyte[]     data   = new ubyte[] (dataFc.length);
181         dataFc.read(data);
182         dataFc.close();
183         char[]      showLine;
184         const       LINE_ITEMCOUNT = 16;
185         uint        lastIdx;
186         if( data.length == 0 ){
187             mWriter.formatln("    ubyte[] {0};", res.mVarName);
188         }
189         else{
190             mWriter.formatln("    ubyte[] {0} = [ cast(ubyte)", res.mVarName);
191             foreach (uint idx, ubyte d; data) {
192                 lastIdx = idx;
193                 if ((idx % LINE_ITEMCOUNT) == 0) {
194                     mWriter("        ");
195                 }
196                 mWriter.format("0x{0:X2}, ", d);
197                 if (isAlphaNumeric(d) || .containsPattern(" []{};:'\"~`!@#$%^&*()_+=-/?.>,<\\|", [cast(char)d])) {
198                     showLine ~= d;
199                 }
200                 else {
201                     switch (d) {
202                     case '\n':
203                         showLine ~= "\u00b6";
204                         break;
205
206                     case '\t':
207                         showLine ~= "\u00bb";
208                         break;
209
210                     default:
211                         showLine ~= '.';
212                         break;
213                     }
214                 }
215                 if ((idx % LINE_ITEMCOUNT) == LINE_ITEMCOUNT - 1) {
216                     mWriter.format(" // [0x{:X6}] {}", idx - (LINE_ITEMCOUNT - 1), showLine);
217                     showLine = null;
218                     mWriter.newline();
219                 }
220             }
221             mWriter.format("];");
222             bool        printLastShowLine = false;
223             bool        firstFill         = true;
224             while ((lastIdx % LINE_ITEMCOUNT) != LINE_ITEMCOUNT - 1) {
225                 if (!firstFill) {
226                     mWriter(" ");
227                 }
228                 mWriter("     ");
229                 firstFill = false;
230                 lastIdx++;
231                 printLastShowLine = true;
232             }
233             if (printLastShowLine) {
234                 mWriter.format("// [0x{:X6}] {}", lastIdx - (LINE_ITEMCOUNT - 1), showLine);
235                 mWriter.newline();
236             }
237         }
238         mWriter.formatln("}"c);
239         mWriter.formatln(""c);
240         mWriter.formatln(""c);
241     }
242     mWriter.flush;
243     return(0);
244 }
Note: See TracBrowser for help on using the browser.