comparison mde/resource/paths.d @ 47:e0839643ff52

New mtcp utility and changes to paths. Changed some of mde.resource.paths and mde.mergetag.Reader's handling of resolving mergetag files, and allowed getting a list of files. Created a simple mergetag-file copy utility. Fixed mergetag's MTTReader getting array out of bounds exceptions (now throws a mergetag exception). committer: Diggory Hardy <diggory.hardy@gmail.com>
author Diggory Hardy <diggory.hardy@gmail.com>
date Fri, 23 May 2008 13:13:08 +0100
parents 07bd1a09e161
children f000d6cd0f74
comparison
equal deleted inserted replaced
46:03fa79a48c48 47:e0839643ff52
70 * ds = The dataset, as for mergetag. Note: all actual readers share one dataset. 70 * ds = The dataset, as for mergetag. Note: all actual readers share one dataset.
71 * rdHeader = Read the headers for each file and merge if rdHeader == true. 71 * rdHeader = Read the headers for each file and merge if rdHeader == true.
72 */ 72 */
73 IReader makeMTReader (char[] file, PRIORITY readOrder, DataSet ds = null, bool rdHeader = false) 73 IReader makeMTReader (char[] file, PRIORITY readOrder, DataSet ds = null, bool rdHeader = false)
74 { 74 {
75 if (readOrder == PRIORITY.HIGH_ONLY) { 75 PathView[] files = getFiles (file, readOrder);
76 foreach_reverse (path; paths) { // starting with highest-priority path... 76 if (files is null)
77 try {
78 return makeReader (path~file, ds, rdHeader);
79 }
80 catch (MTFileIOException) {} // Ignore errors regarding no file for now.
81 }
82 throw new MTFileIOException ("Unable to find the file: "~file~"[.mtt|mtb]"); 77 throw new MTFileIOException ("Unable to find the file: "~file~"[.mtt|mtb]");
83 } 78
84 else return new mdeReader (file, readOrder, ds, rdHeader, paths); 79 return new mdeReader (files, ds, rdHeader);
85 } 80 }
86 81
87 /** Creates an MT writer for file deciding on the best path to use. 82 /** Creates an MT writer for file deciding on the best path to use.
88 * 83 *
89 * Params: 84 * Params:
95 { 90 {
96 // FIXME: use highest priority writable path 91 // FIXME: use highest priority writable path
97 return makeWriter (paths[pathsLen-1] ~ file, ds, WriterMethod.Text); 92 return makeWriter (paths[pathsLen-1] ~ file, ds, WriterMethod.Text);
98 } 93 }
99 94
95 /** Returns a string listing the file name or names (if readOrder is not HIGH_ONLY and multiple
96 * matches are found), or "no file found". Intended for user output only. */
97 char[] getFileName (char[] file, PRIORITY readOrder)
98 {
99 PathView[] files = getFiles (file, readOrder);
100 if (files is null)
101 return "no file found";
102
103 char[] ret = files[0].toString;
104 foreach (f; files[1..$])
105 ret ~= ", " ~ f.toString;
106 return ret;
107 }
108
100 /** Check whether the given file exists under any path with either .mtt or .mtb suffix. */ 109 /** Check whether the given file exists under any path with either .mtt or .mtb suffix. */
101 bool exists (char[] file) { 110 bool exists (char[] file) {
102 for (uint i = 0; i < pathsLen; ++i) { 111 for (uint i = 0; i < pathsLen; ++i) {
103 if (FilePath (paths[i]~file~".mtt").exists) return true; 112 if (FilePath (paths[i]~file~".mtt").exists) return true;
104 if (FilePath (paths[i]~file~".mtb").exists) return true; 113 if (FilePath (paths[i]~file~".mtb").exists) return true;
105 } 114 }
106 return false; 115 return false;
107 } 116 }
108 117
109 private: 118 private:
119 PathView[] getFiles (char[] filename, PRIORITY readOrder)
120 in {
121 assert (readOrder == PRIORITY.LOW_HIGH ||
122 readOrder == PRIORITY.HIGH_LOW ||
123 readOrder == PRIORITY.HIGH_ONLY );
124 } body {
125 PathView[] ret;
126 if (readOrder == PRIORITY.LOW_HIGH) {
127 for (size_t i = 0; i < pathsLen; ++i) {
128 PathView file = findFile (paths[i]~filename);
129 if (file !is null)
130 ret ~= file;
131 }
132 } else {
133 for (int i = pathsLen - 1; i >= 0; --i) {
134 PathView file = findFile (paths[i]~filename);
135 if (file !is null) {
136 ret ~= file;
137 if (readOrder == PRIORITY.HIGH_ONLY) break;
138 }
139 }
140 }
141 return ret;
142 }
110 143
111 // Unconditionally add a path 144 // Unconditionally add a path
112 void addPath (char[] path) { 145 void addPath (char[] path) {
113 paths[pathsLen++] = path~'/'; 146 paths[pathsLen++] = path~'/';
114 } 147 }
236 /** A special adapter for reading from multiple mergetag files with the same relative path to an 269 /** A special adapter for reading from multiple mergetag files with the same relative path to an
237 * mdeDirectory simultaneously. 270 * mdeDirectory simultaneously.
238 */ 271 */
239 class mdeReader : IReader 272 class mdeReader : IReader
240 { 273 {
241 private this (char[] file, PRIORITY readOrder, DataSet ds, bool rdHeader, char[][MAX_PATHS] paths) 274 private this (PathView[] files, DataSet ds, bool rdHeader)
242 in { assert (readOrder == PRIORITY.LOW_HIGH || readOrder == PRIORITY.HIGH_LOW); } 275 in {
243 body { 276 assert (files !is null, "mdeReader.this: files is null");
244 rdOrder = readOrder; 277 } body {
245 if (ds is null) ds = new DataSet; 278 if (ds is null) ds = new DataSet;
246 279
247 foreach (path; paths) { 280 foreach (file; files) {
248 try { 281 IReader r = makeReader (file, ds, rdHeader);
249 IReader r = makeReader (path~file, ds, rdHeader); 282
250 283 readers[readersLen++] = r;
251 readers[readersLen++] = r; 284 }
252 }
253 catch (MTFileIOException) {} // Ignore errors regarding no file for now.
254 }
255
256 if (readersLen == 0) { // totally failed to find any valid files
257 throw new MTFileIOException ("Unable to find the file: "~file~"[.mtt|mtb]");
258 }
259
260 // This is simply the easiest way of adjusting the reading order:
261 if (readOrder == PRIORITY.HIGH_LOW) readers[0..readersLen].reverse;
262 } 285 }
263 286
264 DataSet dataset () { /// Get the DataSet 287 DataSet dataset () { /// Get the DataSet
265 return readers[0].dataset; // all readers share the same dataset 288 return readers[0].dataset; // all readers share the same dataset
266 } 289 }