[286] | 1 | // This file is a part of Framsticks SDK. http://www.framsticks.com/ |
---|
| 2 | // Copyright (C) 1999-2015 Maciej Komosinski and Szymon Ulatowski. |
---|
| 3 | // See LICENSE.txt for details. |
---|
[109] | 4 | |
---|
| 5 | #include <frams/vm/classes/collectionobj.h> |
---|
| 6 | |
---|
| 7 | void printIndent(int indent) |
---|
| 8 | { |
---|
| 9 | for(int i=0;i<indent;i++) |
---|
| 10 | putchar(' '); |
---|
| 11 | } |
---|
| 12 | |
---|
| 13 | struct Trace |
---|
| 14 | { |
---|
| 15 | ExtObject object; |
---|
| 16 | Trace *previous; |
---|
| 17 | bool isAlreadyVisited(const ExtObject& o) |
---|
| 18 | { |
---|
| 19 | if (object==o) return true; |
---|
| 20 | if (previous) return previous->isAlreadyVisited(o); |
---|
| 21 | return false; |
---|
| 22 | } |
---|
| 23 | }; |
---|
| 24 | |
---|
| 25 | void print(ExtValue* v,int indent=0,Trace *prev_trace=NULL) |
---|
| 26 | { |
---|
| 27 | printIndent(indent); |
---|
| 28 | if (!v) |
---|
| 29 | {puts("null"); return;} |
---|
| 30 | |
---|
| 31 | switch(v->getType()) |
---|
| 32 | { |
---|
| 33 | case TUnknown: puts("null"); return; |
---|
[319] | 34 | case TInvalid: puts("invalid"); return; |
---|
[109] | 35 | case TInt: printf("int:"); break; |
---|
| 36 | case TDouble: printf("double:"); break; |
---|
| 37 | case TString: printf("string:"); break; |
---|
| 38 | case TObj: |
---|
| 39 | { |
---|
| 40 | Trace next_trace={v->getObject(),prev_trace}; |
---|
| 41 | printf("%s object:",v->getObject().interfaceName()); |
---|
| 42 | if (prev_trace && prev_trace->isAlreadyVisited(next_trace.object)) |
---|
| 43 | { |
---|
| 44 | printf(" already visited - breaking recursion\n"); |
---|
| 45 | return; |
---|
| 46 | } |
---|
[171] | 47 | VectorObject *vec=VectorObject::fromObject(v->getObject(),false); |
---|
[109] | 48 | if (vec) |
---|
| 49 | { |
---|
| 50 | printf("\n"); |
---|
| 51 | for(int i=0;i<vec->data.size();i++) |
---|
| 52 | print((ExtValue*)vec->data(i),indent+3,&next_trace); |
---|
| 53 | return; |
---|
| 54 | } |
---|
[171] | 55 | DictionaryObject *dict=DictionaryObject::fromObject(v->getObject(),false); |
---|
[109] | 56 | if (dict) |
---|
| 57 | { |
---|
| 58 | printf("\n"); |
---|
| 59 | for(HashEntryIterator it(dict->hash);it.isValid();it++) |
---|
| 60 | { |
---|
| 61 | printIndent(indent+3); |
---|
[348] | 62 | printf("key \"%s\"\n",it->key.c_str()); |
---|
[109] | 63 | print((ExtValue*)it->value,indent+6,&next_trace); |
---|
| 64 | } |
---|
| 65 | return; |
---|
| 66 | } |
---|
| 67 | } |
---|
| 68 | } |
---|
[348] | 69 | puts(v->getString().c_str()); |
---|
[109] | 70 | } |
---|
| 71 | |
---|
| 72 | int main(int argc,char*argv[]) |
---|
| 73 | { |
---|
| 74 | const char* in= (argc>1) ? argv[1] : "[1,2,3,null,{\"x\":3.4,\"y\":[7,77,777]},4]"; |
---|
| 75 | |
---|
| 76 | // note: this is not an example of how to read a param field, but only a special case where the input data was |
---|
| 77 | // previously identified as "serialized" and the "@Serialized:" prefix was already removed |
---|
| 78 | |
---|
| 79 | printf("DESERIALIZATION TEST\n" |
---|
| 80 | "input string = %s\n",in); |
---|
| 81 | ExtValue v; |
---|
| 82 | const char* ret=v.deserialize(in); |
---|
| 83 | if (ret==NULL) |
---|
| 84 | { |
---|
| 85 | printf("failed!\n"); |
---|
| 86 | return 1; |
---|
| 87 | } |
---|
| 88 | else |
---|
| 89 | { |
---|
| 90 | printf("OK, consumed %d of %d characters\n\n",ret-in,strlen(in)); |
---|
| 91 | print(&v); |
---|
| 92 | return 0; |
---|
| 93 | } |
---|
| 94 | } |
---|