Changeset 32
- Timestamp:
- 02/09/08 18:04:11 (1 year ago)
- Files:
-
- trunk/.classpath (added)
- trunk/.project (added)
- trunk/.settings (added)
- trunk/.settings/descent.ui.prefs (added)
- trunk/bin/sqlite3.dll (added)
- trunk/bin/sqlite3.lib (added)
- trunk/doost/core/Any.d (modified) (3 diffs)
- trunk/doost/core/Traits.d (modified) (3 diffs)
- trunk/doost/text/Tokenizer.d (added)
- trunk/doost/util/DUnit.d (modified) (19 diffs)
- trunk/doost/util/serializer/Registry.d (modified) (3 diffs)
- trunk/doost/util/serializer/Serializer.d (modified) (17 diffs)
- trunk/doost/util/serializer/archive/JSONArchive.d (modified) (32 diffs)
- trunk/doost/util/serializer/archive/TextArchive.d (modified) (37 diffs)
- trunk/examples/text/FunctionTest.d (modified) (4 diffs)
- trunk/examples/util/config/FunctionTest.d (modified) (1 diff)
- trunk/examples/util/config/util_config.cbp (modified) (7 diffs)
- trunk/examples/util/config/util_config.depend (deleted)
- trunk/examples/util/config/util_config_build_log.html (deleted)
- trunk/examples/util/serializer/FunctionTest.d (modified) (27 diffs)
- trunk/examples/util/serializer/FunctionTest1.d (added)
- trunk/examples/util/serializer/util_serializer.cbp (modified) (2 diffs)
- trunk/std2/contracts.d (deleted)
- trunk/std2/conv.d (modified) (31 diffs)
- trunk/std2/string.d (deleted)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/doost/core/Any.d
r31 r32 84 84 Params: value = value to assign 85 85 **************************************************************************/ 86 //NOTE: Temporar workaround till constructors don't get ability to be templatized86 //NOTE: Temporary workaround till constructors don't get ability to be templatized 87 87 Any assign(ValueType)(ValueType value) { 88 88 static if (is(ValueType == Any)) content = value.content !is null ? value.content.clone() : null; … … 93 93 /*************************************************************************** 94 94 Gives information if container is empty. 95 Returns: true if nothing is assi nged to container95 Returns: true if nothing is assigned to container 96 96 **************************************************************************/ 97 97 bool empty() { … … 213 213 214 214 unittest { 215 testSuite. begin("Any");215 testSuite.start("Any"); 216 216 } 217 217 trunk/doost/core/Traits.d
r28 r32 36 36 alias U arrayElementType; 37 37 else 38 static assert(false, "Not an array"); 38 static assert(false, "'" ~ T.stringof ~ "' is not an array."); 39 } 40 41 /******************************************************************************* 42 Evaluates to type of array element 43 ******************************************************************************/ 44 //TODO: checki na speÅnianie wymagaÅ co do array 45 template elementType(T) { 46 static if( is( T U : U[] ) ) { 47 pragma(msg, "elementType: " ~ T.stringof ~ " -> " ~ U.stringof); 48 alias U elementType; 49 } else 50 static if( is( typeof(T.get(1u)) U == U[]) ) { 51 pragma(msg, "elementType: " ~ T.stringof ~ " -> " ~ U.stringof); 52 alias U elementType; 53 } else 54 static assert(false, "'" ~ T.stringof ~ "' can not be threated as array."); 39 55 } 40 56 … … 87 103 88 104 /******************************************************************************* 105 Evaluates to true if value is number 106 ******************************************************************************/ 107 template isNumber( T ) { 108 static if( is( T == byte ) 109 || is( T == short ) 110 || is( T == int ) 111 || is( T == long ) 112 || is( T == ubyte ) 113 || is( T == ushort ) 114 || is( T == uint ) 115 || is( T == ulong ) 116 || is( T == float ) 117 || is( T == double ) 118 || is( T == real ) 119 || is( T == ifloat ) 120 || is( T == idouble ) 121 || is( T == ireal ) 122 || is( T == cfloat ) 123 || is( T == cdouble ) 124 || is( T == creal ) ) 125 const isNumber = true; 126 else 127 const isNumber = false; 128 } 129 130 /******************************************************************************* 131 Evaluates to true if value is number 132 ******************************************************************************/ 133 template isChar( T ) { 134 static if( is( T == char ) 135 || is( T == wchar ) 136 || is( T == dchar ) 137 ) 138 const isChar = true; 139 else 140 const isChar = false; 141 } 142 143 /******************************************************************************* 89 144 Evaluates to true for associative arrays 90 145 ******************************************************************************/ … … 93 148 } 94 149 95 150 //****************************************************************************** 151 //****************************************************************************** 152 //****************************************************************************** 153 //Reaped from Phobos 2.0 154 155 /** 156 * Detect whether type T is a static array. 157 */ 158 template isStaticArray(T : U[N], U, size_t N) 159 { 160 const bool isStaticArray = true; 161 } 162 163 template isStaticArray(T) 164 { 165 const bool isStaticArray = false; 166 } 167 168 static assert (isStaticArray!(int[51])); 169 static assert (isStaticArray!(int[][2])); 170 static assert (isStaticArray!(char[][int][11])); 171 static assert (!isStaticArray!(int[])); 172 static assert (!isStaticArray!(int[char])); 173 static assert (!isStaticArray!(int[1][])); 174 static assert(isStaticArray!(char[13u])); 175 static assert (isStaticArray!(typeof("string literal"))); 176 static assert (isStaticArray!(void[0])); 177 static assert (!isStaticArray!(int[int])); 178 static assert (!isStaticArray!(int)); 179 180 /** 181 * Detect whether type T is a dynamic array. 182 */ 183 template isDynamicArray(T, U = void) 184 { 185 static const isDynamicArray = false; 186 } 187 188 template isDynamicArray(T : U[], U) 189 { 190 static const isDynamicArray = !isStaticArray!(T); 191 } 192 193 static assert(isDynamicArray!(int[])); 194 static assert(!isDynamicArray!(int[5])); 195 196 /** 197 * Detect whether type T is an array. 198 */ 199 template isArray(T) 200 { 201 static const isArray = isStaticArray!(T) || isDynamicArray!(T); 202 } 203 204 static assert(isArray!(int[])); 205 static assert(isArray!(int[5])); 206 static assert(!isArray!(uint)); 207 static assert(!isArray!(uint[uint])); 208 static assert(isArray!(void[])); 209 210 211 template BaseTypeTuple(A) 212 { 213 static if (is(A P == super)) 214 alias P BaseTypeTuple; 215 else 216 static assert(0, "argument is not a class or interface"); 217 } 218 trunk/doost/util/DUnit.d
r31 r32 22 22 import std.path; 23 23 import std.date; 24 import std2.traits;25 24 import std2.conv; 26 25 … … 108 107 //------------------------------------------------------------------------------ 109 108 109 class EmptyElem : Element { 110 public: 111 this() { 112 } 113 override string pattern() { 114 return ""; 115 } 116 override string render(string str) { 117 return str; 118 } 119 } 120 121 //------------------------------------------------------------------------------ 122 110 123 class HlElem : CellElem { 111 124 public: … … 148 161 //------------------------------------------------------------------------------ 149 162 150 class Table { 163 Element Empty() { 164 return new EmptyElem(); 165 } 166 167 //------------------------------------------------------------------------------ 168 169 class Renderer { 151 170 public: 152 171 this(uint width = 75) { … … 211 230 212 231 unittest { 213 auto p = new Table;232 auto p = new Renderer; 214 233 assert(p.argNumberToMunch("%% %% %% %% %") == 1); 215 234 assert(p.argNumberToMunch("% %% % %% %") == 3); … … 234 253 235 254 //------------------------------------------------------------------------------ 255 256 /********************************* 257 * Returns !=0 if e is a NaN. 258 * Taken from Tango 259 */ 260 //FIXME: remove after conversion to Tango 261 int isNaN(real x) 262 { 263 static if (real.mant_dig==double.mant_dig) { 264 // 64-bit real 265 ulong* p = cast(ulong *)&x; 266 return (*p & 0x7FF0_0000 == 0x7FF0_0000) && *p & 0x000F_FFFF; 267 } else { 268 // 80-bit real 269 ushort* pe = cast(ushort *)&x; 270 ulong* ps = cast(ulong *)&x; 271 272 return (pe[4] & 0x7FFF) == 0x7FFF && 273 *ps & 0x7FFFFFFFFFFFFFFF; 274 } 275 } 236 276 237 277 class TestCase { … … 273 313 else tc_no = to!(string)(m_owner.m_tccounter) ~ "."; 274 314 275 if (m_dotiming) m_owner.table.render(m_owner.tc_tim, tc_no, m_testname ~ " test...", result, no, m_elapsedtime); 276 else m_owner.table.render(m_owner.tc, tc_no, m_testname ~ " test...", result); 277 278 if (m_elapsedtime !is real.nan) m_owner.m_elapsedtime+=m_elapsedtime; 315 if (m_dotiming) m_owner.renderer.render(m_owner.tc_tim, tc_no, m_testname ~ " test...", result, no, m_elapsedtime); 316 else m_owner.renderer.render(m_owner.tc, tc_no, m_testname ~ " test...", result); 317 318 //BUG: przy sprawdzaniu nan is oraz !is powinno dziaÅaÄ 319 if (!isNaN(m_elapsedtime)) m_owner.m_elapsedtime+=m_elapsedtime; 279 320 } 280 321 … … 314 355 foreach(t; m_traces) { 315 356 if (t.file != lastfile) { 316 m_owner. table.render(m_owner.simple);317 if (t.file != "") m_owner. table.render(m_owner.simple, " " ~ getBaseName(t.file) ~ ":");318 else m_owner. table.render(m_owner.simple);357 m_owner.renderer.render(m_owner.simple); 358 if (t.file != "") m_owner.renderer.render(m_owner.simple, " " ~ getBaseName(t.file) ~ ":"); 359 else m_owner.renderer.render(m_owner.simple); 319 360 lastfile = t.file; 320 361 } 321 362 322 if (t.line !=0) m_owner. table.render(m_owner.simple, " " ~ format("%4d: %s", t.line, t.trace));323 else m_owner. table.render(m_owner.simple, " " ~ t.trace);363 if (t.line !=0) m_owner.renderer.render(m_owner.simple, " " ~ format("%4d: %s", t.line, t.trace)); 364 else m_owner.renderer.render(m_owner.simple, " " ~ t.trace); 324 365 } 325 366 } … … 350 391 m_groupname = groupname; 351 392 if (groupname != "") { 352 //m_owner. table.render(m_owner.simple);353 /*if (!first)*/ m_owner. table.render(m_owner.hl);354 m_owner. table.render(m_owner.simple, "Group: " ~ groupname);355 /*if (!last)*/ //m_owner. table.render(m_owner.hl);393 //m_owner.renderer.render(m_owner.simple); 394 /*if (!first)*/ m_owner.renderer.render(m_owner.hl); 395 m_owner.renderer.render(m_owner.simple, "Group: " ~ groupname); 396 /*if (!last)*/ //m_owner.renderer.render(m_owner.hl); 356 397 } 357 398 } 358 399 359 400 void finish() { 360 401 //FIXME: currently not possible to finish group, as every call to testGroup 402 //creates new group 403 //m_owner.m_curgroup = null; 361 404 } 362 405 … … 400 443 class TestSuite { 401 444 public: 402 //TODO: function disable, which sets repeat to 0403 445 //TODO: tylko jeden otwarty test suite jednoczeÅnie. 404 446 //jeÅŒeli ktoÅ próbuje otworzyÄ drugi to musi czekaÄ na skoÅczenie pierwszego?? … … 410 452 m_tccounter = 0; 411 453 m_tcfcounter = 0; 412 413 table.render(hl); 414 table.render(title, m_suitename ~ " test suite."); 415 //table.render(hl); 454 m_tcfailed = null; 455 m_elapsedtime=0; 456 457 renderer.render(hl); 458 renderer.render(title, m_suitename ~ " test suite."); 459 //renderer.render(hl); 416 460 } 417 461 … … 420 464 421 465 if (m_tcfailed.length>0) { 422 table.render(hl);423 table.render(simple, "Failed test cases / errors / traces:");424 table.render(simple);466 renderer.render(hl); 467 renderer.render(simple, "Failed test cases / errors / traces:"); 468 renderer.render(simple); 425 469 foreach(tc; m_tcfailed) { 426 table.render(fail, tc.m_number, tc.m_testname);427 table.render(simple, " " ~ tc.m_error);428 table.render(simple);470 renderer.render(fail, tc.m_number, tc.m_testname); 471 renderer.render(simple, " " ~ tc.m_error); 472 renderer.render(simple); 429 473 tc.printTraces; 430 474 } … … 433 477 434 478 if (m_dotraces || m_reqtraces) { 435 table.render(hl);436 table.render(simple, "Traces:");437 table.render(simple);479 renderer.render(hl); 480 renderer.render(simple, "Traces:"); 481 renderer.render(simple); 438 482 foreach(tc; m_testcases) { 439 483 if (tc.m_repeat == 0 || tc.m_dotraces == false) continue; 440 table.render(fail, tc.m_number, tc.m_testname);484 renderer.render(fail, tc.m_number, tc.m_testname); 441 485 tc.printTraces; 442 table.render(simple);486 renderer.render(simple); 443 487 } 444 488 } 445 489 446 table.render(hl); 447 table.render(simple); 448 table.render(etime, "Statistics :", "Total time :", m_elapsedtime); 449 table.render(stat, " - all :", m_tccounter); 450 table.render(stat, " - passed :", tcpcounter, cast(double)(tcpcounter*100)/m_tccounter); 451 table.render(stat, " - failed :", m_tcfcounter, cast(double)(m_tcfcounter*100)/m_tccounter); 452 table.render(hl); 490 renderer.render(hl); 491 renderer.render(simple); 492 renderer.render(etime, "Statistics :", "Total time :", m_elapsedtime); 493 renderer.render(stat, " - all :", m_tccounter); 494 renderer.render(stat, " - passed :", tcpcounter, cast(double)(tcpcounter*100)/m_tccounter); 495 renderer.render(stat, " - failed :", m_tcfcounter, cast(double)(m_tcfcounter*100)/m_tccounter); 496 renderer.render(hl); 497 renderer.render(empty); 498 renderer.render(empty); 499 renderer.render(empty); 453 500 454 501 } … … 485 532 486 533 TestSuite width(uint w) { 487 table.m_width = w;534 renderer.m_width = w; 488 535 return this; 489 536 } … … 494 541 **************************************************************************/ 495 542 this() { 496 table = new Table;543 renderer = new Renderer; 497 544 498 545 title = [Sep, Cell(-1, Align.Center), Sep]; … … 504 551 fail = [Sep, Cell(5, Align.Right, "%d."), Cell(-1, Align.Left), Sep]; 505 552 hl = [Hl]; 553 empty = [Empty]; 506 554 507 555 } … … 538 586 } 539 587 540 if (m_firstingroup) { table.render(hl); m_firstingroup=false;}588 if (m_firstingroup) {renderer.render(hl); m_firstingroup=false;} 541 589 m_testcases~=tc; 542 590 m_curcase = tc; … … 544 592 } 545 593 546 Table table;547 Row title, tc, tc_tim, simple, etime, stat, fail, hl ;594 Renderer renderer; 595 Row title, tc, tc_tim, simple, etime, stat, fail, hl, empty; 548 596 549 597 void delegate() m_setup; … … 600 648 //------------------------------------------------------------------------------ 601 649 602 bool isNan(real x) {603 if (x is real.nan) return true;604 return false;605 }606 607 650 bool compareFloats(T)(T first, T second) { 608 651 trace(first, " ?? ", second); 609 if (isNa n(first) || isNaN(second)) {652 if (isNaN(first) || isNaN(second)) { 610 653 return isNaN(first) && isNaN(second); 611 654 } … … 664 707 } 665 708 666 //TODO: add printouts -- always visible 667 //TODO: add versions without file and line 709 //TODO: add printouts -- always visible (similary as traces) 668 710 //TODO: unit testy tylko w wersji debug 669 711 //TODO: funkcja porównujÄ trunk/doost/util/serializer/Registry.d
r31 r32 155 155 /*********************************************************************** 156 156 **********************************************************************/ 157 typeof(this) dup_ staticinfo(){157 typeof(this) dup_info(){ 158 158 typeof(this) result; 159 159 static if (is(typeof(this) == class)) … … 178 178 ******************************************************************************/ 179 179 interface Registration { 180 Registration dup_ staticinfo();180 Registration dup_info(); 181 181 } 182 182 … … 185 185 class Registry { 186 186 public: 187 Registry dup_ staticinfo() {187 Registry dup_info() { 188 188 auto result = new Registry; 189 189 foreach(key, value; registry) 190 result.registry[key] = value.dup_ staticinfo;190 result.registry[key] = value.dup_info; 191 191 return result; 192 192 } trunk/doost/util/serializer/Serializer.d
r31 r32 16 16 module doost.util.serializer.Serializer; 17 17 18 import std.traits;19 20 18 import doost.api.Common; 21 19 import doost.core.Traits; … … 27 25 ******************************************************************************/ 28 26 template Serializable() { 29 import std.string;30 27 void describeUdt(T)(T arch) { 31 28 foreach(i, v; this.tupleof) … … 87 84 private: 88 85 const info = "Type '" ~ STORAGE.stringof ~ "' does not meet Storage requirements: "; 89 static assert(is(typeof(STORAGE.init) == STORAGE), info ~ "lack of init() method.");90 static assert(is(typeof(STORAGE.dup) == STORAGE), info ~ "lack of dup() method.");86 //static assert(is(typeof(STORAGE.init) == STORAGE), info ~ "lack of init() method."); 87 //static assert(is(typeof(STORAGE.dup) == STORAGE), info ~ "lack of dup() method."); 91 88 92 89 enum Mode {LOAD, DUMP} 90 alias elementType!(STORAGE)[] STORAGETYPE; 91 93 92 mixin CONCRETEARCHIVE!(Archive); 94 93 … … 112 111 **************************************************************************/ 113 112 Archive archive() { 114 return m_archive.dup_ staticinfo;113 return m_archive.dup_info; 115 114 } 116 115 … … 119 118 **************************************************************************/ 120 119 void archive(Archive arch) { 121 m_archive = arch.dup_ staticinfo;120 m_archive = arch.dup_info; 122 121 } 123 122 … … 140 139 normalizedType!(T) value = v; 141 140 142 if (archive is null) archive = m_archive.dup_ staticinfo;143 else archive = archive.dup_ staticinfo;141 if (archive is null) archive = m_archive.dup_info; 142 else archive = archive.dup_info; 144 143 145 144 archive.mode = Mode.DUMP; … … 170 169 VALUE load(VALUE)(STORAGE storage, Archive archive = null) { 171 170 //TODO: static asserts in serializer --> check if all template functions exists in Archive 172 //TODO: czy tu storage nie powinno byÄ duplikowane??? storage.dup 173 174 if (archive is null) archive = m_archive.dup_staticinfo; 175 else archive = archive.dup_staticinfo; 171 172 if (archive is null) archive = m_archive.dup_info; 173 else archive = archive.dup_info; 176 174 177 175 archive.mode = Mode.LOAD; … … 192 190 /*************************************************************************** 193 191 **************************************************************************/ 194 bool traverse(VALUE)(ref VALUE value, refArchive archive) {192 bool traverse(VALUE)(ref VALUE value, Archive archive) { 195 193 static if (!is(VALUE TYPE == typedef)) { 196 194 //level is not increased for typedefs … … 199 197 } 200 198 201 pragma(msg, "Type: " ~ VALUE.stringof );199 pragma(msg, "Type: " ~ VALUE.stringof ~ " STORAGETYPE: " ~ STORAGETYPE.stringof ~ " STORAGE: " ~ STORAGE.stringof); 202 200 203 201 //Eventual additional operations ... at begining of traverse... … … 221 219 //BUG: Trick with delegate doesn't work here. Why? 222 220 //compile time extension function for parsing 221 //Below line is for debuging; change 0 to 1 222 static if (0 && CONCRETEARCHIVE.stringof == "JsonArchiveExt(ARCHIVE)" && VALUE.stringof =="Date") return extend!(VALUE)(value, archive); 223 223 static if (is(typeof(extend!(VALUE)(value, archive)) == bool)) { 224 224 return extend!(VALUE)(value, archive); … … 269 269 return true; 270 270 } else 271 //Bools 272 static if(is (VALUE == bool)) { 271 static if (is(VALUE == bool)) { 273 272 if (archive.mode == Mode.LOAD) return loadBool(value, archive); 274 273 else return dumpBool(value, archive); 275 274 } else 276 //Other built-in types 277 //TODO: rozbiÄ isAtomic na Integral i Floating i Char 278 static if (isAtomic!(VALUE)) { 279 if (archive.mode == Mode.LOAD) return loadAtomic(value, archive); 280 else return dumpAtomic(value, archive); 281 } else { 275 static if (isNumber!(VALUE)) { 276 if (archive.mode == Mode.LOAD) return loadNumber(value, archive); 277 else return dumpNumber(value, archive); 278 } else 279 static if (isChar!(VALUE)) { 280 if (archive.mode == Mode.LOAD) return loadChar(value, archive); 281 else return dumpChar(value, archive); 282 } else 283 { 282 284 static assert(false, "Unsupported type '" ~ VALUE.stringof ~ 283 285 "'. Types like void*, union, enum are not serializable without additional information"); … … 287 289 } 288 290 289 //TODO: move checking for version and functions inside user UDT into 290 //serializer from Archive. How? 291 292 /*************************************************************************** 293 **************************************************************************/ 294 bool attendFields(VALUE)(ref VALUE value, Archive archive) { 291 /*************************************************************************** 292 Returns: true if ok 293 **************************************************************************/ 294 bool processMemberStruct(VALUE)(ref VALUE value, Archive archive) { 295 uint defined_ver = 0; 296 static if (is(typeof((cast(VALUE)value).versionUdt) == uint)) { 297 defined_ver = (cast(VALUE)value).versionUdt; 298 } 299 300 auto reg = archive.registry.peek!(TypeDescription, VALUE); 301 if (reg !is null && reg.ver > 0) defined_ver = reg.ver; 302 303 if (archive.mode == Mode.LOAD) { 304 uint stored_ver; 305 bool loaded=false; 306 auto verloaded = loadVersion(stored_ver, archive); 307 assert((verloaded == true && stored_ver != 0) || verloaded == false, "For unversioned classes you should not use version specifier!"); 308 309 if (stored_ver > 0) { 310 if (stored_ver != defined_ver && defined_ver>0) { 311 static if ( is(typeof(&value.transform!(Archive)) == void delegate(ref VALUE, Archive, uint))) { 312 value.transform(value, archive, stored_ver); 313 loaded = true; 314 } else { 315 throw new SerializerException("Udt version in storage is different than in program"); 316 } 317 } 318 } 319 320 if (!loaded) loadFields(value, archive); 321 322 } else { 323 if (!dumpVersion(defined_ver, archive)) 324 throw new SerializerException("Can not dump version."); 325 326 dumpFields(value, archive); 327 } 328 return true; 329 } 330 331 /*************************************************************************** 332 **************************************************************************/ 333 bool processMemberStructFields(VALUE)(ref VALUE value, Archive archive) { 295 334 //Load function exists 335 296 336 static if ( is(typeof(&value.loadUdt!(Archive)) == void delegate(Archive))) { 297 337 if (archive.mode == Mode.LOAD) {value.loadUdt(archive); return true;} 298 } 338 } else alias bool notExistsLoad; 299 339 //Dump function exists 300 340 static if ( is(typeof(&value.dumpUdt!(Archive)) == void delegate(Archive))) { 301 341 if (archive.mode == Mode.DUMP) {value.dumpUdt(archive); return true;} 302 } 303 //TODO: moÅŒna zmniejszyÄ wielkoÅÄ funkcji przez sprawdzenie, czy obie powyÅŒsze 304 //funkcje udaÅo siÄ zainstancjowaÄ. jeÅŒeli tak to poniÅŒsze nie musi byÄ wstawiane 305 306 //Exists describe function 307 static if ( is(typeof(&value.describeUdt!(Archive)) == void delegate(Archive))) { 308 value.describeUdt(archive); 309 } else 310 //All fields are visible 311 static if (areUdtFieldsVisible!(VALUE)) { 312 foreach(i, v; value.tupleof) { 313 if (archive.mode == Mode.LOAD) { 314 normalizedType!(typeof(v)) elem; 315 loadOneField(elem, value.tupleof[i].stringof, archive); 316 checkType!(typeof(v))(elem); 317 318 static if (isStaticArray!(typeof(v))) { 319 foreach(n, saval; value.tupleof[i]) value.tupleof[i][n] = elem[n]; 342 } else alias bool notExistsDump; 343 344 345 //BUG: One more place where it would be much better to have alias defining 346 //compile time constants 347 //or enum bool notExistsLoad = true; will work? 348 static if (is(notExistsLoad == bool) || is(notExistsDump == bool)) { 349 //Exists describe function 350 static if ( is(typeof(&value.describeUdt!(Archive)) == void delegate(Archive))) { 351 value.describeUdt(archive); 352 } else 353 //All fields are visible 354 static if (areUdtFieldsVisible!(VALUE)) { 355 foreach(i, v; value.tupleof) { 356 if (archive.mode == Mode.LOAD) { 357 normalizedType!(typeof(v)) elem; 358 loadOneField(elem, value.tupleof[i].stringof, archive); 359 checkType!(typeof(v))(elem); 360 361 static if (isStaticArray!(typeof(v))) { 362 foreach(n, saval; value.tupleof[i]) value.tupleof[i][n] = elem[n]; 363 } else { 364 value.tupleof[i]= elem; 365 } 366 320 367 } else { 321 value.tupleof[i]= elem; 368 normalizedType!(typeof(v)) elem = v; 369 dumpOneField(elem, value.tupleof[i].stringof, archive); 322 370 } 323 324 } else {325 normalizedType!(typeof(v)) elem = v;326 dumpOneField(elem, value.tupleof[i].stringof, archive);327 371 } 372 } else { 373 //FIXME: 374 static assert(false, "UDT '" ~ VALUE.stringof ~ "' is not serializable."); 328 375 } 329 } else {330 //FIXME:331 static assert(false, "UDT '" ~ VALUE.stringof ~ "' is not serializable.");332 376 } 333 377 334 378 return true; 335 379 } 336 337 338 /***************************************************************************339 Returns: true if class was imported by this function340 **************************************************************************/341 bool attendVersion(VALUE)(ref VALUE value, Archive archive, uint stored_ver) {342 if (stored_ver > 0) {343 uint defined_ver = 0;344 //more important is version in registry; it allows to override345 //mistakenly defined versions in classes...346 static if (is(typeof((cast(VALUE)value).versionUdt) == uint)) {347 defined_ver = (cast(VALUE)value).versionUdt;348 }349 if (auto peek = archive.registry.peek!(TypeDescription, VALUE)) {350 uint ver = peek.ver;351 if (ver>0) defined_ver = ver;352 }353 if (stored_ver != defined_ver && defined_ver>0) {354 static if ( is(typeof(&value.importUdt!(Archive)) == void delegate(ref VALUE, Archive, uint))) {355 //FIXME: przy imporcie pola nie bÄdÄ356 zparsowane??? (JSON)357 value.importUdt(value, archive, stored_ver);358 return true;359 } else {360 throw new SerializerException("Udt version in storage is different than in program");361 }362 }363 }364 return false;365 }366 367 380 368 381 //------------------------------------------------------------------------------ … … 373 386 private: 374 387 //BUG: private attribute is not applied to template functions 375 376 //Bug - jak sprawdziÄ czy poniÅŒsze jest zdefiniowane? 388 //BUG: how to check if ArchiveExt is defined? 377 389 mixin ArchiveExt; 378 390 … … 384 396 Registry registry; 385 397 386 Archive dup_ staticinfo() {387 static if(is(typeof(dup_ staticinfoext) == Archive)) {388 auto result = dup_ staticinfoext;398 Archive dup_info() { 399 static if(is(typeof(dup_infoext) == Archive)) { 400 auto result = dup_infoext; 389 401 } else auto result = new Archive; 390 402 391 403 result.storage = STORAGE.init; 392 404 result.tracking = tracking; 393 result.registry = registry.dup_ staticinfo;394 395 result.level = 0;396 result.mode = Mode.DUMP;405 result.registry = registry.dup_info; 406 407 result.level = level; 408 result.mode = mode; 397 409 398 410 return result; … … 405 417 /*********************************************************************** 406 418 **********************************************************************/ 407 void describe(TYPE)(ref TYPE variable, string name ="") {419 void describe(TYPE)(ref TYPE variable, string name) { 408 420 bool result; 409 421 //writefln("NAME: ", name, " TYPE: ", TYPE.stringof); … … 423 435 /*********************************************************************** 424 436 **********************************************************************/ 425 void describeStaticArray(T)(T variable, string name ="") {437 void describeStaticArray(T)(T variable, string name) { 426 438 normalizedType!(T) var = variable; 427 439 describe(var, name); … … 437 449 /*********************************************************************** 438 450 **********************************************************************/ 439 void importUdt(T)(ref T variable) {451 void transform(T)(ref T variable) { 440 452 //BUG:This form fails - implicit form doesn't 441 453 //if (!traverse!(T)(variable, this)) trunk/doost/util/serializer/archive/JSONArchive.d
r31 r32 14 14 ******************************************************************************/ 15 15 16 module doost.util.serializer.J SONArchive;16 module doost.util.serializer.JsonArchive; 17 17 18 18 //------------------------------------------------------------------------------ 19 19 20 template JSONArchive(ARCHIVE) { 20 /******************************************************************************* 21 This is JSON format archive for serializer. 22 23 Internal policy for returning bool from loaders/dumpers: 24 1. true - value was properly loaded/dumped 25 2. exception - loading of value was not succesfull (token not found or found 26 but is wrongly formatted) 27 28 ******************************************************************************/ 29 30 template JsonArchive(ARCHIVE) { 21 31 private: 22 32 //Static functions and definitions 23 33 24 34 import std2.conv; 25 import std2.string : munch;26 35 import std.regexp; 27 36 import std.typetuple; … … 30 39 import doost.util.serializer.Registry; 31 40 import doost.text.Escaper; 32 33 /******************************************************************************* 34 ******************************************************************************/ 35 static struct Result(VALUE) { 36 bool matched; 37 VALUE value; 38 } 41 import doost.text.Tokenizer; 39 42 40 43 /******************************************************************************* … … 89 92 mixin(generator("Pattern(T)", ["pattern", ""])); 90 93 91 mixin(generator("Skip", [ 92 "skip", " \t\r\n", 93 "space", " ", 94 "newline", "\n", 95 "indent", " " 96 ])); 97 mixin(generator("Array", ["p_begin", r"\[", "p_separator", r",", "p_end", r"\]", "begin", "[", "s_separator", ", ", "s_end", r"]"])); 98 mixin(generator("String", ["p_delim", "\"'", "p_content", "\\\"|\\'|\\t|\\r|\\n|\\v|\\f", "p_idcontent", "a-zA-Z0-9_", "s_begin", "\"", "s_end", "\""])); 94 // mixin(generator("Skip", [ 95 // "skip", " \t\r\n", 96 // "space", " ", 97 // "newline", "\n", 98 // "indent", " " 99 // ])); 100 101 static struct Skip { 102 103 static public string space = " "; 104 static public string newline = "\n"; 105 static public string indent = " "; 106 107 static public string skip() { 108 return m_skip; 109 } 110 111 static public void skip(string s) { 112 m_skip = s; 113 } 114 115 static public CharClass!(char) skip_cc() { 116 if (m_skip_cc.empty) return m_skip_cc.whitespace; 117 return m_skip_cc; 118 } 119 120 static private CharClass!(char) m_skip_cc; 121 static public string m_skip = " \t\r\n"; 122 } 123 124 125 mixin(generator("Array", ["begin", "[", "separator", ",", "end", "]"])); 126 mixin(generator("String", ["delim1", "\"", "delim2", "'"])); 99 127 mixin(generator("Udt", [ 100 "verbegin", "(", 101 "verend", ")", 102 128 "ver", "versionUdt", 103 129 "begin", "{", 104 130 "kvseparator", ":", 105 106 "s_kvseparator", r" : ", 107 108 "p_separator", ",", 109 "s_separator", ", ", 110 131 "separator", ",", 111 132 "end", "}" 112 133 ])); 113 134 114 mixin(generator("Reference", ["p_null", "null", "p_ref", r"\$", "p_pointer", r"\*", "s_null", "null", "s_ref", "$", "s_pointer", "*"]));135 mixin(generator("Reference", ["p_null", "null", "p_ref", "$", "p_pointer", r"*", "s_null", "null", "s_ref", "$", "s_pointer", "*"])); 115 136 116 137 //-------------------------------------------------------------------------- … … 118 139 template ArchiveExt() { 119 140 bool mismatch = false; 120 STORAGE rest = STORAGE.init;141 STORAGETYPE rest = STORAGETYPE.init; 121 142 uint indent = 0; 122 143 123 //wersja[nazwa typu]124 uint[STORAGE] versions;125 //zawartoÅÄ[nazwa typu]126 STORAGE[STORAGE] includedclasses; // all classes which are part of higher level class127 144 //zawartoÅÄ[nazwa pola] 128 STORAGE[STORAGE] fields; //fields of specific class with values; 129 130 bool[STORAGE] parsed; 131 132 Archive dup_staticinfoext() { 145 STORAGETYPE[STORAGETYPE] memberStructFields; &
