00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <eyedb/eyedb_p.h>
00026 #include <sstream>
00027
00028 using namespace std;
00029
00030
00031 #define TRY_GETELEMS_GC
00032
00033 namespace eyedb {
00034
00035 int
00036 Value::Struct::operator==(const Struct &stru)
00037 {
00038 if (attr_cnt != stru.attr_cnt)
00039 return 0;
00040
00041 for (int i = 0; i < attr_cnt; i++)
00042 {
00043 if (strcmp(attrs[i]->name, stru.attrs[i]->name))
00044 return 0;
00045 if (*attrs[i]->value != *stru.attrs[i]->value)
00046 return 0;
00047 }
00048
00049 return 1;
00050 }
00051
00052 void
00053 Value::Struct::print(FILE *fd) const
00054 {
00055 fprintf(fd, "struct(");
00056 for (int ii = 0; ii < attr_cnt; ii++)
00057 {
00058 if (ii) fprintf(fd, ", ");
00059 fprintf(fd, "%s: ", attrs[ii]->name);
00060 attrs[ii]->value->print(fd);
00061 }
00062 fprintf(fd, ")");
00063 }
00064
00065 std::string
00066 Value::Struct::toString() const
00067 {
00068 std::string s = "struct(";
00069 for (int ii = 0; ii < attr_cnt; ii++)
00070 {
00071 if (ii) s += ", ";
00072 s += std::string(attrs[ii]->name) + ": " + attrs[ii]->value->getString();
00073 }
00074 return s + ")";
00075 }
00076
00077 int Value::operator==(const Value &val) const
00078 {
00079 if (type != val.type)
00080 return 0;
00081
00082 switch(type)
00083 {
00084 case tNil:
00085 return 1;
00086
00087 case tNull:
00088 return 1;
00089
00090 case tBool:
00091 return val.b == b;
00092
00093 case tByte:
00094 return val.by == by;
00095
00096 case tChar:
00097 return val.c == c;
00098
00099 case tShort:
00100 return val.s == s;
00101
00102 case tInt:
00103 return val.i == i;
00104
00105 case tLong:
00106 return val.l == l;
00107
00108 case tDouble:
00109 return val.d == d;
00110
00111 case tIdent:
00112 case tString:
00113 return !strcmp(val.str, str);
00114
00115 case tData:
00116 return val.data.data == data.data &&
00117 val.data.size == data.size;
00118
00119 case tOid:
00120 return *val.oid == *oid;
00121
00122 case tObject:
00123 return val.o == o;
00124
00125 case tObjectPtr:
00126 return val.o_ptr->getObject() == o_ptr->getObject();
00127
00128 case tList:
00129 case tBag:
00130 case tSet:
00131 case tArray:
00132 if (list->getCount() != val.list->getCount())
00133 return 0;
00134 return val.list == list;
00135
00136 case tPobj:
00137 return val.idx == idx;
00138
00139 case tStruct:
00140 return *val.stru == *stru;
00141
00142 default:
00143 abort();
00144 }
00145
00146 return 0;
00147 }
00148
00149 int cmp_objects(const Object *o, const Object *val_o)
00150 {
00151 if (o->getOid().isValid() && val_o->getOid().isValid())
00152 return o->getOid().getNX() < val_o->getOid().getNX();
00153
00154 Size o_size;
00155 Data o_idr = o->getIDR(o_size);
00156
00157 Size val_o_size;
00158 Data val_o_idr = val_o->getIDR(val_o_size);
00159
00160 Size size = (o_size < val_o_size ? o_size : val_o_size);
00161
00162 int r = memcmp(o_idr, val_o_idr, size);
00163 if (r < 0)
00164 return 1;
00165 if (r > 0)
00166 return 0;
00167 return o < val_o;
00168 }
00169
00170 int Value::operator<(const Value &val) const
00171 {
00172 if (type != val.type)
00173 return (int)type < (int)val.type;
00174
00175 switch(type) {
00176
00177 case tNil:
00178 case tNull:
00179 return 0;
00180
00181 case tBool:
00182 return b < val.b;
00183
00184 case tByte:
00185 return by < val.by;
00186
00187 case tChar:
00188 return c < val.c;
00189
00190 case tShort:
00191 return s < val.s;
00192
00193 case tInt:
00194 return i < val.i;
00195
00196 case tLong:
00197 return l < val.l;
00198
00199 case tDouble:
00200 return d < val.d;
00201
00202 case tIdent:
00203 case tString:
00204 return strcmp(str, val.str) < 0 ? 1 : 0;
00205
00206 case tData: {
00207 Size size = data.size;
00208 if (val.data.size < size)
00209 size = val.data.size;
00210 return memcmp(data.data, val.data.data, size) < 0 ? 1 : 0;
00211 }
00212
00213 case tOid:
00214 return oid->getNX() < val.oid->getNX();
00215
00216 #if 1
00217 case tObject:
00218 return cmp_objects(o, val.o);
00219
00220 case tObjectPtr:
00221 return cmp_objects(o_ptr->getObject(), val.o_ptr->getObject());
00222 #else
00223 case tObject: {
00224 if (o->getOid().isValid() && val.o->getOid().isValid())
00225 return o->getOid().getNX() < val.o->getOid().getNX();
00226
00227 Size o_size;
00228 Data o_idr = o->getIDR(o_size);
00229
00230 Size val_o_size;
00231 Data val_o_idr = val.o->getIDR(val_o_size);
00232
00233 Size size = (o_size < val_o_size ? o_size : val_o_size);
00234
00235 int r = memcmp(o_idr, val_o_idr, size);
00236 if (r < 0)
00237 return 1;
00238 if (r > 0)
00239 return 0;
00240 return o < val.o;
00241 }
00242 #endif
00243
00244 default:
00245 return !(*this == val);
00246 }
00247 }
00248
00249 int Value::operator!=(const Value &val) const
00250 {
00251 return !(*this == val);
00252 }
00253
00254 Value::Value(const Value &val)
00255 {
00256 bufstr = NULL;
00257 type = tNil;
00258 auto_obj_garb = false;
00259 *this = val;
00260 }
00261
00262 void Value::set(Object *_o)
00263 {
00264 type = tObject;
00265 #ifdef TRY_GETELEMS_GC
00266 if (auto_obj_garb) {
00267 if (o)
00268 o->release();
00269 o = _o;
00270 if (o)
00271 o->incrRefCount();
00272
00273 unvalid();
00274 return;
00275 }
00276 #endif
00277 o = _o;
00278 unvalid();
00279 }
00280
00281 Status
00282 Value::toOidObjectArray(Database *db, LinkedList &ll, Bool isobj,
00283 const RecMode *rcm)
00284 {
00285 if (type == tOid) {
00286 if (isobj) {
00287 if (db) {
00288 Object *x;
00289 Status status = db->loadObject(*oid, x, rcm);
00290 if (status)
00291 return status;
00292 ll.insertObjectLast(x);
00293 }
00294 }
00295 else
00296 ll.insertObjectLast(new Oid(*oid));
00297 }
00298 else if (type == tObject) {
00299 if (isobj) {
00300 #ifdef TRY_GETELEMS_GC
00301 if (o)
00302 o->incrRefCount();
00303 #endif
00304 ll.insertObjectLast(o);
00305 }
00306 else if (o) {
00307 Oid *xoid = new Oid(o->getOid());
00308 ll.insertObjectLast(new Oid(*xoid));
00309 }
00310 }
00311
00312 else if (type == tObjectPtr) {
00313 if (isobj) {
00314 if (o_ptr->getObject())
00315 o_ptr->getObject()->incrRefCount();
00316 ll.insertObjectLast(o_ptr->getObject());
00317 }
00318 else if (o_ptr->getObject()) {
00319 Oid *xoid = new Oid(o_ptr->getObject()->getOid());
00320 ll.insertObjectLast(new Oid(*xoid));
00321 }
00322 }
00323
00324 else if (type == tList || type == tBag || type == tSet || type == tArray) {
00325 LinkedListCursor cc(list);
00326 Value *v;
00327 Status status;
00328 while (cc.getNext((void *&)v))
00329 if (status = v->toOidObjectArray(db, ll, isobj, rcm))
00330 return status;
00331 }
00332 else if (type == tStruct) {
00333 Status status;
00334 for (int ii = 0; ii < stru->attr_cnt; ii++)
00335 if (status = stru->attrs[ii]->value->toOidObjectArray(db, ll, isobj, rcm))
00336 return status;
00337 }
00338
00339 return Success;
00340 }
00341
00342 Status
00343 Value::toValueArray(LinkedList &ll)
00344 {
00345 if (type == tList || type == tBag || type == tSet || type == tArray) {
00346 LinkedListCursor cc(list);
00347 Value *v;
00348 Status status;
00349 while (cc.getNext((void *&)v))
00350 if (status = v->toValueArray(ll))
00351 return status;
00352 }
00353 else if (type == tStruct) {
00354 Status status;
00355 for (int ii = 0; ii < stru->attr_cnt; ii++)
00356 if (status = stru->attrs[ii]->value->toValueArray(ll))
00357 return status;
00358 }
00359 else
00360 ll.insertObjectLast(new Value(*this));
00361
00362 return Success;
00363 }
00364
00365 Status
00366 Value::toArray(Database *db, ObjectPtrVector &obj_vect, const RecMode *rcm)
00367 {
00368 ObjectArray obj_array;
00369 Status s = toArray(db, obj_array, rcm);
00370 if (s)
00371 return s;
00372 obj_array.makeObjectPtrVector(obj_vect);
00373 return Success;
00374 }
00375
00376 Status
00377 Value::toArray(Database *db, ObjectArray &objarr, const RecMode *rcm)
00378 {
00379 LinkedList ll;
00380 Status status = toOidObjectArray(db, ll, True, rcm);
00381 if (status)
00382 return status;
00383
00384 #ifdef TRY_GETELEMS_GC
00385 Object **o_arr = new Object*[ll.getCount()];
00386 LinkedListCursor cc(ll);
00387 Object *o;
00388 for (int ii = 0; cc.getNext((void *&)o); ii++)
00389 o_arr[ii] = o;
00390
00391 objarr.set(o_arr, ll.getCount());
00392 delete [] o_arr;
00393
00394 if (objarr.isAutoGarbage()) {
00395
00396
00397 LinkedListCursor cc2(ll);
00398 for (int ii = 0; cc2.getNext((void *&)o); ii++) {
00399 if (o)
00400 o->release();
00401 }
00402 }
00403 #else
00404 objarr.set(0, ll.getCount());
00405
00406 LinkedListCursor cc(ll);
00407 Object *x;
00408 for (int ii = 0; cc.getNext((void *&)x); ii++)
00409 objarr.setObjectAt(ii, x);
00410
00411 #endif
00412 return Success;
00413 }
00414
00415 Status
00416 Value::toArray(OidArray &oidarr)
00417 {
00418 LinkedList ll;
00419 Status status = toOidObjectArray(0, ll, False, 0);
00420 if (status) return status;
00421
00422 oidarr.set(0, ll.getCount());
00423
00424 LinkedListCursor cc(ll);
00425 Oid *x;
00426 for (int ii = 0; cc.getNext((void *&)x); ii++) {
00427 oidarr[ii] = *x;
00428 delete x;
00429 }
00430
00431 return Success;
00432 }
00433
00434 Status
00435 Value::toArray(ValueArray &valarr)
00436 {
00437 LinkedList ll;
00438 Status status = toValueArray(ll);
00439 if (status)
00440 return status;
00441
00442 valarr.set(0, ll.getCount());
00443
00444 LinkedListCursor cc(ll);
00445
00446 Value *x;
00447 for (int ii = 0; cc.getNext((void *&)x); ii++) {
00448 valarr.setValueAt(ii, *x);
00449 delete x;
00450 }
00451
00452 return Success;
00453 }
00454
00455 Value &Value::operator=(const Value &val)
00456 {
00457 if (this == &val)
00458 return *this;
00459
00460 garbage();
00461
00462 type = val.type;
00463
00464 if (type == tString || type == tIdent)
00465 str = strdup(val.str);
00466 else if (type == tOid)
00467 oid = new Oid(*val.oid);
00468 else if (type == tList || type == tBag || type == tArray || type == tSet) {
00469 list = new LinkedList();
00470 LinkedListCursor cursor(val.list);
00471 Value *value;
00472 for (int ii = 0; cursor.getNext((void *&)value); ii++)
00473 if (value) list->insertObjectLast(new Value(*value));
00474 }
00475 else if (type == tStruct) {
00476 stru = new Struct(val.stru->attr_cnt);
00477 for (int ii = 0; ii < stru->attr_cnt; ii++)
00478 stru->attrs[ii] = new Attr(val.stru->attrs[ii]->name,
00479 val.stru->attrs[ii]->value);
00480 }
00481 #ifdef TRY_GETELEMS_GC
00482 else if (type == tObject) {
00483 o = val.o;
00484 if (auto_obj_garb && o) {
00485 o->incrRefCount();
00486 }
00487 }
00488 #endif
00489 else if (type == tObjectPtr) {
00490 o_ptr = new ObjectPtr(*val.o_ptr);
00491 }
00492 else
00493 memcpy(this, &val, sizeof(*this));
00494
00495 bufstr = NULL;
00496
00497 return *this;
00498 }
00499
00500 static void
00501 append(char *& buf, const char *s)
00502 {
00503 buf = (char *)realloc(buf, strlen(buf)+strlen(s)+1);
00504 strcat(buf, s);
00505 }
00506
00507
00508
00509 static std::string
00510 getStringList(LinkedList *list, const char *head)
00511 {
00512 #ifdef OPTIM_STRLIST
00513 int len = 16;
00514 char *s = (char *)malloc(len);
00515 *s = 0;
00516
00517 LinkedListCursor cursor(list);
00518 Value *value;
00519 for (int i = 0; cursor.getNext((void *&)value); i++)
00520 {
00521 if (isBackendInterrupted())
00522 {
00523 set_backendInterrupt(False);
00524 return "<interrupted>";
00525 }
00526
00527 char *x = value->getString();
00528 int l = strlen(x);
00529 if (l + strlen(s) + 4 >= len)
00530 {
00531 len += l + 200;
00532 s = (char *)realloc(s, len);
00533 }
00534
00535 if (i) strcat(s, ", ");
00536 strcat(s, x);
00537 }
00538
00539 if (strlen(s) + 4 >= len)
00540 {
00541 len += 4;
00542 s = (char *)realloc(s, len);
00543 }
00544
00545 strcat(s, ")");
00546 return std::string(s);
00547 #else
00548 std::string s = std::string(head) + "(";
00549
00550 LinkedListCursor cursor(list);
00551 Value *value;
00552 for (int i = 0; cursor.getNext((void *&)value); i++)
00553 {
00554 if (i) s += ", ";
00555 s += value->getString();
00556 }
00557
00558 s += ")";
00559 return s;
00560 #endif
00561 }
00562
00563 static void
00564 print_list(FILE *fd, LinkedList *list, const char *head)
00565 {
00566 fprintf(fd, "%s(", head);
00567
00568 LinkedListCursor cursor(list);
00569 Value *value;
00570 for (int i = 0; cursor.getNext((void *&)value); i++)
00571 {
00572 if (i) fprintf(fd, ", ");
00573 value->print(fd);
00574 }
00575
00576 fprintf(fd, ")");
00577 }
00578
00579 const char *Value::getString() const
00580 {
00581 if (bufstr)
00582 return bufstr;
00583
00584 char tok[32];
00585
00586 *tok = 0;
00587
00588 switch(type)
00589 {
00590 case tNil:
00591 ((Value *)this)->bufstr = strdup(NilString);
00592 break;
00593
00594 case tNull:
00595 ((Value *)this)->bufstr = strdup(NullString);
00596 break;
00597
00598 case tBool:
00599 sprintf(tok, "%s", (b ? "true" : "false"));
00600 break;
00601
00602 case tByte:
00603 sprintf(tok, "\\0%d", b);
00604 break;
00605
00606 case tChar:
00607 sprintf(tok, "'%c'", c);
00608 break;
00609
00610 case tShort:
00611 sprintf(tok, "%d", s);
00612 break;
00613
00614 case tInt:
00615 sprintf(tok, "%d", i);
00616 break;
00617
00618 case tLong:
00619 sprintf(tok, "%lld", l);
00620 break;
00621
00622 case tDouble:
00623 sprintf(tok, "%f", d);
00624 break;
00625
00626 case tIdent:
00627 ((Value *)this)->bufstr = strdup(str);
00628 break;
00629
00630 case tString:
00631 ((Value *)this)->bufstr = (char *)malloc(strlen(str)+3);
00632 sprintf(((Value *)this)->bufstr, "\"%s\"", str);
00633 break;
00634
00635 case tData:
00636 sprintf(tok, "[0x%x, %u]", data.data, data.size);
00637 break;
00638
00639 case tOid:
00640 ((Value *)this)->bufstr = strdup(oid->getString());
00641 break;
00642
00643 case tObject:
00644 {
00645 ostringstream ostr;
00646 ostr << o;
00647 ((Value *)this)->bufstr = strdup(ostr.str().c_str());
00648 }
00649 break;
00650
00651 case tObjectPtr:
00652 {
00653 ostringstream ostr;
00654 ostr << o_ptr->getObject();
00655 ((Value *)this)->bufstr = strdup(ostr.str().c_str());
00656 }
00657 break;
00658
00659 case tList:
00660 ((Value *)this)->bufstr = strdup(getStringList(list, "list").c_str());
00661 break;
00662
00663 case tSet:
00664 ((Value *)this)->bufstr = strdup(getStringList(list, "set").c_str());
00665 break;
00666
00667 case tBag:
00668 ((Value *)this)->bufstr = strdup(getStringList(list, "bag").c_str());
00669 break;
00670
00671 case tArray:
00672 ((Value *)this)->bufstr = strdup(getStringList(list, "array").c_str());
00673 break;
00674
00675 case tPobj:
00676 {
00677 std::string x = str_convert((long)idx, "%x:obj");
00678 ((Value *)this)->bufstr = strdup(x.c_str());
00679 }
00680 break;
00681
00682 case tStruct:
00683 ((Value *)this)->bufstr = strdup(stru->toString().c_str());
00684 break;
00685
00686 default:
00687 abort();
00688 }
00689
00690 if (*tok)
00691 ((Value *)this)->bufstr = strdup(tok);
00692
00693 return bufstr;
00694 }
00695
00696 void
00697 Value::print(FILE *fd) const
00698 {
00699 switch(type)
00700 {
00701 case tNil:
00702 fprintf(fd, NilString);
00703 break;
00704
00705 case tNull:
00706 fprintf(fd, NullString);
00707 break;
00708
00709 case tBool:
00710 fprintf(fd, "%s", (b ? "true" : "false"));
00711 break;
00712
00713 case tByte:
00714 fprintf(fd, "\\0%d", b);
00715 break;
00716
00717 case tChar:
00718 fprintf(fd, "'%c'", c);
00719 break;
00720
00721 case tShort:
00722 fprintf(fd, "%d", s);
00723 break;
00724
00725 case tInt:
00726 fprintf(fd, "%d", i);
00727 break;
00728
00729 case tLong:
00730 fprintf(fd, "%lld", l);
00731 break;
00732
00733 case tDouble:
00734 fprintf(fd, "%f", d);
00735 break;
00736
00737 case tIdent:
00738 fprintf(fd, "%s", str);
00739 break;
00740
00741 case tString:
00742 fprintf(fd, "\"%s\"", str);
00743 break;
00744
00745 case tData:
00746 fprintf(fd, "0x%x", data);
00747 break;
00748
00749 case tOid:
00750 fprintf(fd, oid->getString());
00751 break;
00752
00753 case tObject:
00754 o->trace(fd);
00755 break;
00756
00757 case tObjectPtr:
00758 o_ptr->getObject()->trace(fd);
00759 break;
00760
00761 case tList:
00762 print_list(fd, list, "list");
00763 break;
00764
00765 case tSet:
00766 print_list(fd, list, "set");
00767 break;
00768
00769 case tBag:
00770 print_list(fd, list, "bag");
00771 break;
00772
00773 case tArray:
00774 print_list(fd, list, "array");
00775 break;
00776
00777 case tPobj:
00778 fprintf(fd, "%x:obj", idx);
00779 break;
00780
00781 case tStruct:
00782 fprintf(fd, "%s", stru->toString().c_str());
00783 break;
00784
00785 default:
00786 abort();
00787 }
00788 }
00789
00790 const char *
00791 Value::getAttributeName(const Class *cl, Bool isIndirect)
00792 {
00793 if (cl->asCharClass())
00794 {
00795 if (isIndirect)
00796 return "str";
00797 return "c";
00798 }
00799
00800 if (isIndirect || (!cl->asBasicClass() && !cl->asEnumClass()))
00801 return "o";
00802
00803 if (cl->asInt16Class())
00804 return "s";
00805
00806 if (cl->asInt32Class())
00807 return "i";
00808
00809 if (cl->asInt64Class())
00810 return "l";
00811
00812 if (cl->asFloatClass())
00813 return "d";
00814
00815 if (cl->asOidClass())
00816 return "oid";
00817
00818 if (cl->asByteClass())
00819 return "by";
00820
00821 return "<unknown class>";
00822 }
00823
00824 ostream& operator<<(ostream& os, const Value &value)
00825 {
00826 os << value.getString();
00827 return os;
00828 }
00829
00830 ostream& operator<<(ostream& os, const Value *value)
00831 {
00832 os << value->getString();
00833 return os;
00834 }
00835
00836 void
00837 Value::garbage()
00838 {
00839 if (type == tString || type == tIdent)
00840 free(str);
00841 else if (type == tOid)
00842 delete oid;
00843 else if (type == tList || type == tBag || type == tSet || type == tArray) {
00844 LinkedListCursor cursor(list);
00845 Value *value;
00846 while (cursor.getNext((void *&)value))
00847 delete value;
00848 delete list;
00849 }
00850 else if (type == tStruct)
00851 delete stru;
00852 #ifdef TRY_GETELEMS_GC
00853 else if (type == tObject) {
00854 if (auto_obj_garb && o) {
00855 o->release();
00856 }
00857 }
00858 #endif
00859 else if (type == tObjectPtr)
00860 delete o_ptr;
00861
00862 free(bufstr);
00863 }
00864
00865 const char *
00866 Value::getStringType() const
00867 {
00868 return getStringType(type);
00869 }
00870
00871 const char *
00872 Value::getStringType(Value::Type type)
00873 {
00874 switch(type)
00875 {
00876 case tNil:
00877 return "nil";
00878
00879 case tNull:
00880 return "null";
00881
00882 case tBool:
00883 return "bool";
00884
00885 case tByte:
00886 return "byte";
00887
00888 case tChar:
00889 return "char";
00890
00891 case tShort:
00892 return "int16";
00893
00894 case tInt:
00895 return "int32";
00896
00897 case tLong:
00898 return "int64";
00899
00900 case tDouble:
00901 return "double";
00902
00903 case tIdent:
00904 return "ident";
00905
00906 case tString:
00907 return "string";
00908
00909 case tData:
00910 return "data";
00911
00912 case tOid:
00913 return "oid";
00914
00915 case tObject:
00916 return "object";
00917
00918 case tObjectPtr:
00919 return "object_ptr";
00920
00921 case tList:
00922 return "list";
00923
00924 case tSet:
00925 return "set";
00926
00927 case tBag:
00928 return "bag";
00929
00930 case tArray:
00931 return "array";
00932
00933 case tPobj:
00934 return "pobject";
00935
00936 case tStruct:
00937 return "struct";
00938
00939 default:
00940 return "<unknown>";
00941 }
00942 }
00943
00944 Data
00945 Value::getData(Size *psize) const
00946 {
00947 switch(type)
00948 {
00949 case tNil:
00950 case tNull:
00951 if (psize)
00952 *psize = 0;
00953 return 0;
00954
00955 case tByte:
00956 if (psize)
00957 *psize = sizeof(by);
00958 return (Data)&by;;
00959
00960 case tChar:
00961 if (psize)
00962 *psize = sizeof(c);
00963 return (Data)&c;;
00964
00965 case tShort:
00966 if (psize)
00967 *psize = sizeof(s);
00968 return (Data)&s;;
00969
00970 case tInt:
00971 if (psize)
00972 *psize = sizeof(i);
00973 return (Data)&i;
00974
00975 case tLong:
00976 if (psize)
00977 *psize = sizeof(l);
00978 return (Data)&l;;
00979
00980 case tDouble:
00981 if (psize)
00982 *psize = sizeof(d);
00983 return (Data)&d;;
00984
00985 case tString:
00986 if (psize)
00987 *psize = strlen(str)+1;
00988 return (Data)str;
00989
00990 case tData:
00991 if (psize)
00992 *psize = data.size;
00993 return data.data;
00994
00995 case tOid:
00996 if (psize)
00997 *psize = sizeof(oid);
00998 return (Data)&oid;;
00999
01000 default:
01001 assert(0);
01002 if (psize)
01003 *psize = 0;
01004 return (Data)0;;
01005 }
01006 }
01007
01008 void
01009 Value::code(Data &idr, Offset &offset, Size &alloc_size) const
01010 {
01011 char x = type;
01012 char_code(&idr, &offset, &alloc_size, &x);
01013
01014 switch(type)
01015 {
01016 case tNil:
01017 case tNull:
01018 break;
01019
01020 case tBool:
01021 x = b;
01022 char_code(&idr, &offset, &alloc_size, &x);
01023 break;
01024
01025 case tByte:
01026 char_code(&idr, &offset, &alloc_size, (char *)&by);
01027 break;
01028
01029 case tChar:
01030 char_code(&idr, &offset, &alloc_size, &c);
01031 break;
01032
01033 case tShort:
01034 int16_code(&idr, &offset, &alloc_size, &s);
01035 break;
01036
01037 case tInt:
01038 int32_code(&idr, &offset, &alloc_size, &i);
01039 break;
01040
01041 case tLong:
01042 int64_code(&idr, &offset, &alloc_size, &l);
01043 break;
01044
01045 case tDouble:
01046 double_code(&idr, &offset, &alloc_size, &d);
01047 break;
01048
01049 case tIdent:
01050 case tString:
01051 string_code(&idr, &offset, &alloc_size, str);
01052 break;
01053
01054 case tData:
01055 throw *eyedb::Exception::make(eyedb::IDB_UNSERIALIZABLE_TYPE_ERROR, "tData");
01056 break;
01057
01058 case tOid:
01059 oid_code(&idr, &offset, &alloc_size, oid->getOid());
01060 break;
01061
01062 case tObject:
01063 throw *eyedb::Exception::make(eyedb::IDB_UNSERIALIZABLE_TYPE_ERROR, "tObject");
01064 break;
01065
01066 case tObjectPtr:
01067 throw *eyedb::Exception::make(eyedb::IDB_UNSERIALIZABLE_TYPE_ERROR, "tObjectPtr");
01068 break;
01069
01070 case tList:
01071 case tSet:
01072 case tBag:
01073 case tArray:
01074 {
01075 int cnt = list->getCount();
01076 int32_code(&idr, &offset, &alloc_size, &cnt);
01077 LinkedListCursor cc(list);
01078 Value *v;
01079 while (cc.getNext((void *&)v))
01080 v->code(idr, offset, alloc_size);
01081 }
01082 break;
01083
01084 case tPobj:
01085 int32_code(&idr, &offset, &alloc_size, (eyedblib::int32 *)&idx);
01086 break;
01087
01088 case tStruct:
01089 {
01090 int32_code(&idr, &offset, &alloc_size, &stru->attr_cnt);
01091 for (int ii = 0; ii < stru->attr_cnt; ii++)
01092 {
01093 string_code(&idr, &offset, &alloc_size, stru->attrs[ii]->name);
01094 stru->attrs[ii]->value->code(idr, offset, alloc_size);
01095 }
01096
01097 }
01098 break;
01099
01100 default:
01101 throw *eyedb::Exception::make(eyedb::IDB_INTERNAL_ERROR, "Unknown type in Value code()");
01102 break;
01103 }
01104 }
01105
01106 void Value::setMustRelease(bool must_release)
01107 {
01108 if (type == tObject && o)
01109 o->setMustRelease(must_release);
01110 }
01111
01112 Value::~Value()
01113 {
01114 garbage();
01115 }
01116
01117 ValueArray::ValueArray(const Collection *coll)
01118 {
01119 values = NULL;
01120 value_cnt = 0;
01121 coll->getElements(*this);
01122 }
01123
01124 ValueArray::ValueArray(const ValueArray &valarr)
01125 {
01126 value_cnt = 0;
01127 values = NULL;
01128 *this = valarr;
01129 }
01130
01131 ValueArray::ValueArray(const ValueList &list)
01132 {
01133 value_cnt = 0;
01134 int cnt = list.getCount();
01135 if (!cnt) {
01136 values = 0;
01137 return;
01138 }
01139
01140 values = (Value *)malloc(sizeof(Value) * cnt);
01141 memset(values, 0, sizeof(Value) * cnt);
01142
01143 ValueListCursor c(list);
01144 Value value;
01145
01146 for (; c.getNext(value); value_cnt++)
01147 values[value_cnt] = value;
01148 }
01149
01150 ValueArray &ValueArray::operator=(const ValueArray &valarr)
01151 {
01152 set(valarr.values, valarr.value_cnt, True);
01153 return *this;
01154 }
01155
01156 void ValueArray::set(Value *_values, unsigned int _value_cnt, Bool copy)
01157 {
01158 if (values)
01159 delete[] values;
01160
01161 value_cnt = _value_cnt;
01162
01163 if (copy) {
01164 values = new Value[value_cnt];
01165
01166 #ifdef TRY_GETELEMS_GC
01167 for (int i = 0; i < value_cnt; i++)
01168 values[i].setAutoObjGarbage(auto_obj_garb);
01169 #endif
01170
01171 if (_values) {
01172 for (int i = 0; i < value_cnt; i++) {
01173 values[i] = _values[i];
01174 }
01175 }
01176
01177 return;
01178 }
01179
01180 values = _values;
01181 }
01182
01183 void ValueArray::setMustRelease(bool must_release)
01184 {
01185 for (int i = 0; i < value_cnt; i++)
01186 values[i].setMustRelease(must_release);
01187 }
01188
01189 void ValueArray::setAutoObjGarbage(bool _auto_obj_garb)
01190 {
01191 auto_obj_garb = _auto_obj_garb;
01192 #ifdef TRY_GETELEMS_GC
01193 for (int i = 0; i < value_cnt; i++)
01194 values[i].setAutoObjGarbage(auto_obj_garb);
01195 #endif
01196 }
01197
01198 Status ValueArray::setValueAt(unsigned int ind, const Value &value)
01199 {
01200 if (ind >= value_cnt)
01201 return Exception::make(IDB_ERROR, "invalid range %d (maximun is %d)",
01202 ind, value_cnt);
01203
01204 values[ind] = value;
01205 return Success;
01206 }
01207
01208 ValueList *
01209 ValueArray::toList() const
01210 {
01211 return new ValueList(*this);
01212 }
01213
01214 ValueArray::~ValueArray()
01215 {
01216 if (values)
01217 delete [] values;
01218 }
01219
01220 void
01221 Value::decode(Data idr, Offset &offset)
01222 {
01223 garbage();
01224
01225 char x;
01226 char_decode(idr, &offset, &x);
01227 type = (Type)x;
01228
01229 switch(type)
01230 {
01231 case tNil:
01232 case tNull:
01233 break;
01234
01235 case tBool:
01236 char_decode(idr, &offset, &x);
01237 b = (Bool)x;
01238 break;
01239
01240 case tByte:
01241 char_decode(idr, &offset, (char *)&by);
01242 break;
01243
01244 case tChar:
01245 char_decode(idr, &offset, &c);
01246 break;
01247
01248 case tShort:
01249 int16_decode(idr, &offset, &s);
01250 break;
01251
01252 case tInt:
01253 int32_decode(idr, &offset, &i);
01254 break;
01255
01256 case tLong:
01257 int64_decode(idr, &offset, &l);
01258 break;
01259
01260 case tDouble:
01261 double_decode(idr, &offset, &d);
01262 break;
01263
01264 case tIdent:
01265 case tString:
01266 {
01267 char *y;
01268 string_decode(idr, &offset, &y);
01269 str = strdup(y);
01270 }
01271 break;
01272
01273 case tData:
01274 break;
01275
01276 case tOid:
01277 {
01278 eyedbsm::Oid xoid;
01279 oid_decode(idr, &offset, &xoid);
01280 oid = new Oid(xoid);
01281 }
01282 break;
01283
01284 case tObject:
01285 break;
01286
01287 case tObjectPtr:
01288 break;
01289
01290 case tList:
01291 case tSet:
01292 case tBag:
01293 case tArray:
01294 {
01295 int cnt;
01296 int32_decode(idr, &offset, &cnt);
01297 list = new LinkedList();
01298 for (int ii = 0; ii < cnt; ii++)
01299 {
01300 Value *v = new Value();
01301 v->decode(idr, offset);
01302 list->insertObjectLast(v);
01303 }
01304 }
01305 break;
01306
01307 case tPobj:
01308 int32_decode(idr, &offset, (eyedblib::int32 *)&idx);
01309 break;
01310
01311 case tStruct:
01312 {
01313 int cnt;
01314 int32_decode(idr, &offset, &cnt);
01315 stru = new Struct(cnt);
01316 for (int ii = 0; ii < stru->attr_cnt; ii++)
01317 {
01318 char *y;
01319 string_decode(idr, &offset, &y);
01320 Value *v = new Value();
01321 v->decode(idr, offset);
01322 stru->attrs[ii] = new Attr(y, v);
01323 }
01324
01325 }
01326 break;
01327
01328 default:
01329 abort();
01330 break;
01331 }
01332 }
01333
01334 void decode_value(void *xdata, void *xvalue)
01335 {
01336 Offset offset = 0;
01337 ((Value *)xvalue)->decode((Data)((rpc_Data *)xdata)->data, offset);
01338 }
01339
01340 ValueList::ValueList()
01341 {
01342 list = new LinkedList();
01343 }
01344
01345 ValueList::ValueList(const ValueArray &value_array)
01346 {
01347 list = new LinkedList();
01348 for (int i = 0; i < value_array.getCount(); i++)
01349 insertValueLast(value_array[i]);
01350 }
01351
01352 int ValueList::getCount() const
01353 {
01354 return list->getCount();
01355 }
01356
01357 void
01358 ValueList::insertValue(const Value &value)
01359 {
01360 list->insertObject(new Value(value));
01361 }
01362
01363 void
01364 ValueList::insertValueFirst(const Value &value)
01365 {
01366 list->insertObjectFirst(new Value(value));
01367 }
01368
01369 void
01370 ValueList::insertValueLast(const Value &value)
01371 {
01372 list->insertObjectLast(new Value(value));
01373 }
01374
01375 Bool
01376 ValueList::suppressValue(const Value &value)
01377 {
01378 LinkedListCursor c(list);
01379 Value *xvalue;
01380 while (c.getNext((void *&)xvalue))
01381 if (*xvalue == value) {
01382 list->deleteObject(xvalue);
01383 return True;
01384 }
01385
01386 return False;
01387 }
01388
01389 Bool
01390 ValueList::suppressPairValues(const Value &value1, const Value &value2)
01391 {
01392 LinkedListCursor c(list);
01393 int cnt = list->getCount();
01394
01395 for (int n = 0; n < cnt; n += 2) {
01396 Value *xvalue1, *xvalue2;
01397 assert(c.getNext((void *&)xvalue1));
01398 assert(c.getNext((void *&)xvalue2));
01399
01400 if (value1 == *xvalue1 && value2 == *xvalue2) {
01401 list->deleteObject(xvalue1);
01402 list->deleteObject(xvalue2);
01403 return True;
01404 }
01405 }
01406
01407 return False;
01408 }
01409
01410 Bool
01411 ValueList::exists(const Value &value) const
01412 {
01413 LinkedListCursor c(list);
01414 Value *xvalue;
01415 while (c.getNext((void *&)xvalue))
01416 if (*xvalue == value)
01417 return True;
01418 return False;
01419 }
01420
01421 void
01422 ValueList::empty()
01423 {
01424 list->empty();
01425 }
01426
01427 ValueArray *
01428 ValueList::toArray() const
01429 {
01430 int cnt = list->getCount();
01431 if (!cnt)
01432 return new ValueArray();
01433 Value *arr = (Value *)malloc(sizeof(Value) * cnt);
01434 memset(arr, 0, sizeof(Value) * cnt);
01435
01436 LinkedListCursor c(list);
01437 Value *xvalue;
01438 for (int i = 0; c.getNext((void *&)xvalue); i++)
01439 arr[i] = *xvalue;
01440
01441 ValueArray *value_arr = new ValueArray(arr, cnt);
01442 free(arr);
01443 return value_arr;
01444 }
01445
01446 ValueList::~ValueList()
01447 {
01448 LinkedListCursor c(list);
01449 Value *xvalue;
01450 while (c.getNext((void *&)xvalue))
01451 delete xvalue;
01452 delete list;
01453 }
01454
01455 ValueListCursor::ValueListCursor(const ValueList &valuelist)
01456 {
01457 c = new LinkedListCursor(valuelist.list);
01458 }
01459
01460 ValueListCursor::ValueListCursor(const ValueList *valuelist)
01461 {
01462 c = new LinkedListCursor(valuelist->list);
01463 }
01464
01465 Bool
01466 ValueListCursor::getNext(Value &value)
01467 {
01468 Value *xvalue;
01469 if (c->getNext((void *&)xvalue))
01470 {
01471 value = *xvalue;
01472 return True;
01473 }
01474
01475 return False;
01476 }
01477
01478 ValueListCursor::~ValueListCursor()
01479 {
01480 delete c;
01481 }
01482 }