Changeset 104 for cpp/gdk/extvalue.cpp
- Timestamp:
- 07/23/13 18:15:30 (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
cpp/gdk/extvalue.cpp
r92 r104 5 5 #include "extvalue.h" 6 6 #include "param.h" 7 #include "sstringutils.h" 7 8 #include <math.h> 9 #include <ctype.h> 10 #include "collectionobj.h" 11 #include "3dobject.h" 8 12 9 13 SString ExtObject::toString() const 10 14 { 11 15 if (isEmpty()) return SString("<empty object>"); 12 ParamInterface *p=getParamInterface(); 16 Param tmp_param; 17 ParamInterface *p=getParamInterface(tmp_param); 13 18 int tostr=p->findId("toString"); 14 19 if (tostr>=0) … … 25 30 return tmp; 26 31 } 32 } 33 34 ThreadSingleton<ExtObject::Serialization> ExtObject::serialization; 35 36 void ExtObject::Serialization::begin() 37 { 38 if (level==0) 39 refs.clear(); 40 level++; 41 } 42 43 int ExtObject::Serialization::add(const ExtObject &o) 44 { 45 if (o.isEmpty()) return -1; 46 for(int i=0;i<refs.size();i++) 47 { 48 ExtObject& r=refs[i]; 49 if (r==o) return i; 50 } 51 refs.push_back(o); 52 return -1; 53 } 54 55 void ExtObject::Serialization::replace(const ExtObject& o,const ExtObject& other) 56 { 57 if (o.isEmpty()) return; 58 for(int i=0;i<refs.size();i++) 59 { 60 ExtObject& r=refs[i]; 61 if (r==o) 62 { 63 r=other; 64 return; 65 } 66 } 67 } 68 69 void ExtObject::Serialization::remove(const ExtObject& o) 70 { 71 if (o.isEmpty()) return; 72 for(int i=0;i<refs.size();i++) 73 { 74 ExtObject& r=refs[i]; 75 if (o==r) refs.erase(refs.begin()+i); 76 } 77 } 78 79 const ExtObject* ExtObject::Serialization::get(int ref) 80 { 81 if (ref<0) return NULL; 82 if (ref>=refs.size()) return NULL; 83 return &refs[ref]; 84 } 85 86 void ExtObject::Serialization::end() 87 { 88 level--; 89 if (level==0) 90 refs.clear(); 91 } 92 93 SString ExtObject::serialize_inner() const 94 { 95 int ref=serialization.getref().add(*this); 96 if (ref>=0) 97 { 98 SString ret; 99 sprintf(ret.directAppend(20),"^%d",ref);ret.endAppend(); 100 return ret; 101 } 102 103 if (isEmpty()) return SString(); 104 VectorObject *vec=VectorObject::fromObject(*this); 105 if (vec) 106 return vec->serialize(); 107 DictionaryObject *dic=DictionaryObject::fromObject(*this); 108 if (dic) 109 return dic->serialize(); 110 Param tmp_param; 111 ParamInterface *p=getParamInterface(tmp_param); 112 int m=p->findId("toVector"); 113 if (m<0) 114 m=p->findId("toDictionary"); 115 if (m>=0) 116 { 117 ExtObject o(p->getObject(m)); 118 SString ret=SString(interfaceName())+o.serialize(); 119 return ret; 120 } 121 m=p->findId("toString"); 122 if (m>=0) 123 { 124 SString str=p->getString(m); 125 sstringQuote(str); 126 SString ret=SString(interfaceName())+"\""+str+"\""; 127 return ret; 128 } 129 130 SString ret=interfaceName(); 131 sprintf(ret.directAppend(30),"<%p>",object?object:paraminterface);ret.endAppend(); 132 return ret; 133 } 134 135 SString ExtObject::serialize() const 136 { 137 serialization.getref().begin(); 138 SString ret=serialize_inner(); 139 serialization.getref().end(); 140 return ret; 27 141 } 28 142 … … 297 411 } 298 412 413 SString ExtValue::serialize() const 414 { 415 switch(type) 416 { 417 case TString: 418 { 419 SString q=sdata(); 420 sstringQuote(q); 421 return SString("\"")+q+SString("\""); 422 } 423 case TInt: 424 { 425 SString tmp; 426 sprintf(tmp.directAppend(20),"%d",idata()); 427 tmp.endAppend(); 428 return tmp; 429 } 430 case TDouble: 431 { 432 SString tmp; 433 sprintf(tmp.directAppend(20),"%.15g",ddata()); 434 tmp.endAppend(); 435 if ((!strchr(tmp,'.'))&&(!strchr(tmp,'e'))) tmp+=".0"; 436 return tmp; 437 } 438 case TObj: 439 return odata().serialize(); 440 case TInvalid: 441 return SString("undefined"); 442 default: 443 return SString("null"); 444 } 445 } 446 447 //returns the first character after the parsed number or NULL if not a number 448 const char* ExtValue::parseNumber(const char* in) 449 { 450 if (isdigit(*in)||((*in=='-')&&(isdigit(in[1])))) 451 { 452 const char* p=in; 453 if (*p=='-') p++; 454 while(isdigit(*p)) p++; 455 bool fp=false; 456 if ((*p=='.') && isdigit(p[1])) 457 { 458 p++; 459 while(isdigit(*p)) p++; 460 fp=true; 461 } 462 if (((*p=='e')||(*p=='E')) && (isdigit(p[1]) || (((p[1]=='-') || (p[1]=='+')) && isdigit(p[2])))) 463 { 464 p++; 465 if ((*p=='-')||(*p=='+')) p++; 466 while(isdigit(*p)) p++; 467 fp=true; 468 } 469 470 if (fp) 471 { 472 setDouble(atof(in)); 473 return p; 474 } 475 else 476 { 477 setInt(atol(in)); 478 return p; 479 } 480 } 481 return NULL; 482 } 483 484 PtrListTempl<ParamInterface*> ExtValue::deserializable_classes; 485 486 void ExtValue::initDeserializableClasses() 487 { 488 deserializable_classes+=&Pt3D_Ext::getStaticParam(); 489 deserializable_classes+=&Orient_Ext::getStaticParam(); 490 } 491 492 ParamInterface *ExtValue::findDeserializableClass(const char* name) 493 { 494 FOREACH(ParamInterface*,cls,deserializable_classes) 495 if (!strcmp(cls->getName(),name)) 496 return cls; 497 return NULL; 498 } 499 500 static const char* skipWord(const char* in) 501 { 502 while(isalpha(*in)) 503 in++; 504 return in; 505 } 506 507 //returns the first character after the parsed portion or NULL if invalid format 508 const char* ExtValue::deserialize_inner(const char* in) 509 { 510 const char* ret=parseNumber(in); 511 if (ret) 512 return ret; 513 else if (*in=='\"') 514 { 515 ret=skipQuoteString(in+1,NULL); 516 SString s(in+1,ret-(in+1)); 517 sstringUnquote(s); 518 setString(s); 519 if (*ret=='\"') 520 return ret+1; 521 else 522 return NULL; 523 } 524 else if (*in=='[') 525 { 526 VectorObject *vec=new VectorObject; 527 ExtObject o(&VectorObject::par,vec); 528 ExtObject::serialization.getref().add(o); 529 const char* p=in+1; 530 ExtValue tmp; 531 while(*p) 532 { 533 if (*p==']') {p++;break;} 534 ret=tmp.deserialize(p); 535 if (ret) 536 { 537 vec->data+=new ExtValue(tmp); 538 p=ret; 539 if (*p==',') p++; 540 } 541 else 542 { 543 p=NULL; 544 break; 545 } 546 } 547 setObject(o); 548 return p; 549 } 550 else if (*in=='{') 551 { 552 DictionaryObject *dic=new DictionaryObject; 553 ExtObject o(&DictionaryObject::par,dic); 554 ExtObject::serialization.getref().add(o); 555 const char* p=in+1; 556 ExtValue args[2]/*={value,key}*/, dummy_ret; 557 while(*p) 558 { 559 if (*p=='}') {p++;break;} 560 ret=args[1].deserialize(p); 561 if ((!ret)||(args[1].getType()!=TString)) {p=NULL;break;} 562 p=ret; 563 if (*p!=':') {p=NULL;break;} 564 p++; 565 ret=args[0].deserialize(p); 566 if (!ret) {p=NULL;break;} 567 p=ret; 568 dic->p_set(args,&dummy_ret); 569 if (*p==',') p++; 570 } 571 setObject(o); 572 return p; 573 } 574 else if (!strncmp(in,"null",4)) 575 { 576 setEmpty(); 577 return in+4; 578 } 579 else if (!strncmp(in,"undefined",9)) 580 { 581 setInvalid(); 582 return in+9; 583 } 584 else if (*in=='<') 585 { //unserializable object 586 setInvalid(); 587 while(*in) 588 if (*in=='>') 589 return in+1; 590 else in++; 591 return in; 592 } 593 else if (*in=='^') 594 { 595 in++; 596 ExtValue ref; 597 ret=ref.parseNumber(in); 598 if (ret && (ref.getType()==TInt)) 599 { 600 const ExtObject* o=ExtObject::serialization.getref().get(ref.getInt()); 601 if (o) 602 { 603 setObject(*o); 604 return ret; 605 } 606 } 607 return NULL; 608 } 609 else if ((ret=skipWord(in))&&(ret!=in)) 610 { 611 SString clsname(in,ret-in); 612 ExtValue tmp; 613 ret=tmp.deserialize(ret); 614 ParamInterface *cls=findDeserializableClass(clsname); 615 if (cls && (tmp.getType()!=TUnknown) && (tmp.getType()!=TInvalid)) 616 { 617 VectorObject *vec=VectorObject::fromObject(tmp.getObject()); 618 if (vec) 619 { 620 int m=cls->findId("newFromVector"); 621 if (m>=0) 622 { 623 cls->call(m,&tmp,this); 624 ExtObject::serialization.getref().replace(tmp.getObject(),getObject()); 625 return ret; 626 } 627 } 628 DictionaryObject *dic=DictionaryObject::fromObject(tmp.getObject()); 629 if (dic) 630 { 631 int m=cls->findId("newFromDictionary"); 632 if (m>=0) 633 { 634 cls->call(m,&tmp,this); 635 ExtObject::serialization.getref().replace(tmp.getObject(),getObject()); 636 return ret; 637 } 638 } 639 if (tmp.getType()==TString) 640 { 641 int m=cls->findId("newFromString"); 642 if (m>=0) 643 { 644 cls->call(m,&tmp,this); 645 ExtObject::serialization.getref().replace(tmp.getObject(),getObject()); 646 return ret; 647 } 648 } 649 ExtObject::serialization.getref().remove(tmp.getObject()); 650 setEmpty(); 651 } 652 FMprintf("ExtValue","deserialize",FMLV_WARN,"object of class \"%s\" could not be deserialized",(const char*)clsname); 653 return ret; 654 } 655 return NULL; 656 } 657 658 const char* ExtValue::deserialize(const char* in) 659 { 660 ExtObject::serialization.getref().begin(); 661 const char* ret=deserialize_inner(in); 662 ExtObject::serialization.getref().end(); 663 return ret; 664 } 665 299 666 ExtObject ExtValue::getObject() const 300 667 { … … 307 674 if (getType()!=TObj) return ExtValue((long)getType()); 308 675 ExtObject& o=odata(); 309 return ExtValue(SString(o.isEmpty()?"":o. getParamInterface()->getName()));310 } 676 return ExtValue(SString(o.isEmpty()?"":o.interfaceName())); 677 }
Note: See TracChangeset
for help on using the changeset viewer.