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 <assert.h>
00026 #include "eyedb_p.h"
00027 #include <eyedblib/rpc_be.h>
00028
00029 #define NO_DIRECT_SET // added the 22/09/98
00030
00031
00032
00033
00034
00035
00036
00037 namespace eyedb {
00038
00039 #define UNKNOWN_TYPE(T, X) \
00040 { \
00041 fprintf(stderr, #X ": unknown argument type : %d\n", T); \
00042 abort(); \
00043 }
00044
00045 static unsigned int
00046 getSize(const ArgArray *);
00047
00048 static unsigned int
00049 getSize(const Argument *arg)
00050 {
00051 int type = arg->type->getType();
00052 unsigned int size = sizeof(int);
00053
00054 if (type == INT16_TYPE)
00055 size += sizeof(eyedblib::int16);
00056 else if (type == INT32_TYPE)
00057 size += sizeof(eyedblib::int32);
00058 else if (type == INT64_TYPE)
00059 size += sizeof(eyedblib::int64);
00060 else if (type == CHAR_TYPE)
00061 size += sizeof(char);
00062 else if (type == STRING_TYPE)
00063 size += sizeof(int) + strlen(arg->u.s)+1;
00064 else if (type == FLOAT_TYPE)
00065 size += sizeof(double);
00066 else if (type == OID_TYPE)
00067 size += sizeof(Oid);
00068 else if (type == OBJ_TYPE)
00069 size += sizeof(int) + (arg->u.o ? 2 * sizeof(Oid) +
00070 arg->u.o->getIDRSize() : 0);
00071 else if (type == ARRAY_TYPE)
00072 size += getSize(arg->u.array);
00073 else if (type == RAW_TYPE)
00074 size += sizeof(int) + arg->u.raw.size;
00075 else if (type == (ARRAY_TYPE|INT16_TYPE))
00076 {
00077 size += sizeof(int);
00078 size += sizeof(eyedblib::int16) * arg->u.arr_i16.cnt;
00079 }
00080 else if (type == (ARRAY_TYPE|INT32_TYPE))
00081 {
00082 size += sizeof(int);
00083 size += sizeof(eyedblib::int32) * arg->u.arr_i32.cnt;
00084 }
00085 else if (type == (ARRAY_TYPE|INT64_TYPE))
00086 {
00087 size += sizeof(int);
00088 size += sizeof(eyedblib::int64) * arg->u.arr_i64.cnt;
00089 }
00090 else if (type == (ARRAY_TYPE|CHAR_TYPE))
00091 {
00092 size += sizeof(int);
00093 size += sizeof(char) * arg->u.arr_c.cnt;
00094 }
00095 else if (type == (ARRAY_TYPE|FLOAT_TYPE))
00096 {
00097 size += sizeof(int);
00098 size += sizeof(double) * arg->u.arr_d.cnt;
00099 }
00100 else if (type == (ARRAY_TYPE|STRING_TYPE))
00101 {
00102 size += sizeof(int);
00103 for (int i = 0; i < arg->u.arr_s.cnt; i++)
00104 size += sizeof(int) + strlen(arg->u.arr_s.s[i]) + 1;
00105 }
00106 else if (type == (ARRAY_TYPE|OBJ_TYPE))
00107 {
00108 size += sizeof(int);
00109 for (int i = 0; i < arg->u.arr_o.cnt; i++)
00110 size += sizeof(int) + (arg->u.arr_o.o[i] ? 2 * sizeof(Oid) +
00111 arg->u.arr_o.o[i]->getIDRSize() : 0);
00112 }
00113 else if (type == (ARRAY_TYPE|OID_TYPE))
00114 {
00115 size += sizeof(int);
00116 size += sizeof(Oid) * arg->u.arr_oid.cnt;
00117 }
00118 else if (type == VOID_TYPE)
00119 ;
00120 else
00121 UNKNOWN_TYPE(type, getSize())
00122
00123 return size;
00124 }
00125
00126 static unsigned int
00127 getSize(const ArgArray *array)
00128 {
00129 int size = sizeof(int);
00130 int cnt = array->getCount();
00131 for (int i = 0; i < cnt; i++)
00132 size += getSize((*array)[i]);
00133
00134 return size;
00135 }
00136
00137 static void
00138 code_arg(const ArgArray *array, char * &);
00139
00140 static void
00141 code_arg(const char *s, char *&p)
00142 {
00143 int len = strlen(s)+1;
00144 mcp(p, &len, sizeof(int));
00145 p += sizeof(int);
00146 mcp(p, s, len);
00147 p += len;
00148 }
00149
00150 static void
00151 code_arg(const Object *o, char *&p)
00152 {
00153 int len = (o ? o->getIDRSize() : 0);
00154 mcp(p, &len, sizeof(int));
00155 p += sizeof(int);
00156 if (o)
00157 {
00158 Oid oid = o->getOid();
00159 mcp(p, &oid, sizeof(Oid));
00160 p += sizeof(Oid);
00161 oid = o->getClass()->getOid();
00162 mcp(p, &oid, sizeof(Oid));
00163 p += sizeof(Oid);
00164 mcp(p, o->getIDR(), o->getIDRSize());
00165 p += o->getIDRSize();
00166 }
00167 }
00168
00169 #define CODE_SIMPLE_ARRAY(PTR, F, TYPE, P) \
00170 { \
00171 int len = sizeof(TYPE) * PTR.cnt; \
00172 mcp(P, &PTR.cnt, sizeof(int)); \
00173 P += sizeof(int); \
00174 mcp(P, PTR.F, len); \
00175 P += len; \
00176 }
00177
00178 #define DECODE_SIMPLE_ARRAY(ARG, TYPE, P) \
00179 { \
00180 int cnt; \
00181 mcp(&cnt, P, sizeof(int)); \
00182 P += sizeof(int); \
00183 \
00184 TYPE *x = (TYPE *)malloc(sizeof(TYPE) * cnt); \
00185 for (int i = 0; i < cnt; i++) \
00186 { \
00187 mcp(&x[i], P, sizeof(TYPE)); \
00188 P += sizeof(TYPE); \
00189 } \
00190 ARG->set(x, cnt, Argument::AutoFullGarbage); \
00191 }
00192
00193 static void
00194 code_arg(const Argument *arg, char * &p)
00195 {
00196 int type = arg->type->getType();
00197 mcp(p, &type, sizeof(int));
00198
00199 p += sizeof(int);
00200
00201 if (type == INT16_TYPE)
00202 {
00203 mcp(p, &arg->u.i16, sizeof(eyedblib::int16));
00204 p += sizeof(eyedblib::int16);
00205 }
00206 else if (type == INT32_TYPE)
00207 {
00208 mcp(p, &arg->u.i32, sizeof(eyedblib::int32));
00209 p += sizeof(eyedblib::int32);
00210 }
00211 else if (type == INT64_TYPE)
00212 {
00213 mcp(p, &arg->u.i64, sizeof(eyedblib::int64));
00214 p += sizeof(eyedblib::int64);
00215 }
00216 else if (type == CHAR_TYPE)
00217 {
00218 mcp(p, &arg->u.c, sizeof(char));
00219 p += sizeof(char);
00220 }
00221 else if (type == STRING_TYPE)
00222 code_arg(arg->u.s, p);
00223 else if (type == RAW_TYPE)
00224 {
00225 mcp(p, &arg->u.raw.size, sizeof(int));
00226 p += sizeof(int);
00227 mcp(p, arg->u.raw.data, arg->u.raw.size);
00228 p += arg->u.raw.size;
00229 }
00230 else if (type == FLOAT_TYPE)
00231 {
00232 mcp(p, &arg->u.d, sizeof(double));
00233 p += sizeof(double);
00234 }
00235 else if (type == OID_TYPE)
00236 {
00237 mcp(p, arg->u.oid, sizeof(Oid));
00238 p += sizeof(Oid);
00239 }
00240 else if (type == OBJ_TYPE)
00241 code_arg(arg->u.o, p);
00242 else if (type == ARRAY_TYPE)
00243 code_arg(arg->u.array, p);
00244 else if (type == (ARRAY_TYPE|INT16_TYPE))
00245 {
00246 CODE_SIMPLE_ARRAY(arg->u.arr_i16, i, eyedblib::int16, p);
00247 }
00248 else if (type == (ARRAY_TYPE|INT32_TYPE))
00249 {
00250 CODE_SIMPLE_ARRAY(arg->u.arr_i32, i, eyedblib::int32, p);
00251 }
00252 else if (type == (ARRAY_TYPE|INT64_TYPE))
00253 {
00254 CODE_SIMPLE_ARRAY(arg->u.arr_i64, i, eyedblib::int64, p);
00255 }
00256 else if (type == (ARRAY_TYPE|CHAR_TYPE))
00257 {
00258 CODE_SIMPLE_ARRAY(arg->u.arr_c, c, char, p);
00259 }
00260 else if (type == (ARRAY_TYPE|FLOAT_TYPE))
00261 {
00262 CODE_SIMPLE_ARRAY(arg->u.arr_d, d, double, p);
00263 }
00264 else if (type == (ARRAY_TYPE|OID_TYPE))
00265 {
00266 CODE_SIMPLE_ARRAY(arg->u.arr_oid, oid, Oid, p);
00267 }
00268 else if (type == (ARRAY_TYPE|STRING_TYPE))
00269 {
00270 mcp(p, &arg->u.arr_s.cnt, sizeof(int));
00271 p += sizeof(int);
00272
00273 for (int i = 0; i < arg->u.arr_s.cnt; i++)
00274 code_arg(arg->u.arr_s.s[i], p);
00275 }
00276 else if (type == (ARRAY_TYPE|OBJ_TYPE))
00277 {
00278 mcp(p, &arg->u.arr_o.cnt, sizeof(int));
00279 p += sizeof(int);
00280
00281 for (int i = 0; i < arg->u.arr_o.cnt; i++)
00282 code_arg(arg->u.arr_o.o[i], p);
00283 }
00284 else if (type == VOID_TYPE)
00285 ;
00286 else
00287 UNKNOWN_TYPE(type, code_arg)
00288 }
00289
00290 static void
00291 code_arg(const ArgArray *array, char * &p)
00292 {
00293 int n = array->getCount();
00294 mcp(p, &n, sizeof(int));
00295 p += sizeof(int);
00296
00297 for (int i = 0; i < n; i++)
00298 code_arg((*array)[i], p);
00299 }
00300
00301 static void
00302 decode_arg(Database *, ArgArray *array, const char * &);
00303
00304 static void
00305 decode_arg(Database *db, Object *&o, const Class *&cls,
00306 const char *&p)
00307 {
00308 int len;
00309 mcp(&len, p, sizeof(int));
00310 p += sizeof(int);
00311
00312 if (!len)
00313 {
00314 o = NULL;
00315 return;
00316 }
00317
00318 Oid o_oid, cl_oid;
00319 mcp(&o_oid, p, sizeof(Oid));
00320 p += sizeof(Oid);
00321 mcp(&cl_oid, p, sizeof(Oid));
00322 p += sizeof(Oid);
00323
00324 p += len;
00325
00326 cls = db->getSchema()->getClass(cl_oid);
00327
00328 if (!cls)
00329 {
00330 o = NULL;
00331 return;
00332 }
00333
00334 o = cls->newObj((Data)p + IDB_OBJ_HEAD_SIZE);
00335
00336 if (o)
00337 ObjectPeer::setOid(o, o_oid);
00338 }
00339
00340 static void
00341 decode_arg(Database *db, Argument *arg, const char * &p)
00342 {
00343 int type;
00344
00345 mcp(&type, p, sizeof(int));
00346 p += sizeof(int);
00347
00348
00349
00350 if (type == INT16_TYPE)
00351 {
00352 eyedblib::int16 i;
00353 mcp(&i, p, sizeof(eyedblib::int16));
00354 arg->set(i);
00355 p += sizeof(eyedblib::int16);
00356 }
00357 else if (type == INT32_TYPE)
00358 {
00359 eyedblib::int32 i;
00360 mcp(&i, p, sizeof(eyedblib::int32));
00361 arg->set(i);
00362 p += sizeof(eyedblib::int32);
00363 }
00364 else if (type == INT64_TYPE)
00365 {
00366 eyedblib::int64 i;
00367 mcp(&i, p, sizeof(eyedblib::int64));
00368 arg->set(i);
00369 p += sizeof(eyedblib::int64);
00370 }
00371 else if (type == CHAR_TYPE)
00372 {
00373 char c;
00374 mcp(&c, p, sizeof(char));
00375 arg->set(c);
00376 p += sizeof(char);
00377 }
00378 else if (type == STRING_TYPE)
00379 {
00380 int len;
00381 mcp(&len, p, sizeof(int));
00382 p += sizeof(int);
00383
00384
00385 arg->set(strdup((char *)p), Argument::AutoFullGarbage);
00386 p += len;
00387 }
00388 else if (type == FLOAT_TYPE)
00389 {
00390 double d;
00391 mcp(&d, p, sizeof(double));
00392 arg->set(d);
00393 p += sizeof(double);
00394 }
00395 else if (type == OID_TYPE)
00396 {
00397 Oid oid;
00398 mcp(&oid, p, sizeof(Oid));
00399 arg->set(oid, db);
00400 p += sizeof(Oid);
00401 }
00402 else if (type == RAW_TYPE)
00403 {
00404 int size;
00405 mcp(&size, p, sizeof(int));
00406 p += sizeof(int);
00407
00408
00409 arg->set(Argument::dup((const unsigned char *)p, size), size,
00410 Argument::AutoFullGarbage);
00411 p += size;
00412 }
00413 else if (type == OBJ_TYPE)
00414 {
00415 Object *o = NULL;
00416 const Class *cls = NULL;
00417 decode_arg(db, o, cls, p);
00418 arg->set(o, Argument::AutoFullGarbage);
00419 if (cls)
00420 arg->type->setClname(cls->getName());
00421 }
00422 else if (type == (OBJ_TYPE|ARRAY_TYPE))
00423 {
00424 int cnt;
00425 mcp(&cnt, p, sizeof(int));
00426 p += sizeof(int);
00427 Object **o = (Object **)malloc(sizeof(Object *) * cnt);
00428
00429 const Class *cls = NULL;
00430 for (int i = 0; i < cnt; i++)
00431 decode_arg(db, o[i], cls, p);
00432
00433 arg->set(o, cnt, Argument::AutoFullGarbage);
00434 }
00435 else if (type == (INT16_TYPE|ARRAY_TYPE))
00436 {
00437 DECODE_SIMPLE_ARRAY(arg, eyedblib::int16, p);
00438 }
00439 else if (type == (INT32_TYPE|ARRAY_TYPE))
00440 {
00441 DECODE_SIMPLE_ARRAY(arg, eyedblib::int32, p);
00442 }
00443 else if (type == (INT64_TYPE|ARRAY_TYPE))
00444 {
00445 DECODE_SIMPLE_ARRAY(arg, eyedblib::int64, p);
00446 }
00447 else if (type == (CHAR_TYPE|ARRAY_TYPE))
00448 {
00449 DECODE_SIMPLE_ARRAY(arg, char, p);
00450 }
00451 else if (type == (STRING_TYPE|ARRAY_TYPE))
00452 {
00453 int cnt;
00454 mcp(&cnt, p, sizeof(int));
00455 p += sizeof(int);
00456
00457 char **s = (char **)malloc(sizeof(char *) * cnt);
00458 for (int i = 0; i < cnt; i++)
00459 {
00460 int len;
00461 mcp(&len, p, sizeof(int));
00462 p += sizeof(int);
00463 s[i] = strdup((char *)p);
00464 p += len;
00465 }
00466 arg->set(s, cnt, Argument::AutoFullGarbage);
00467 }
00468 else if (type == (FLOAT_TYPE|ARRAY_TYPE))
00469 {
00470 DECODE_SIMPLE_ARRAY(arg, double, p);
00471 }
00472 else if (type == (OID_TYPE|ARRAY_TYPE))
00473 {
00474 DECODE_SIMPLE_ARRAY(arg, Oid, p);
00475 }
00476 else if (type == ARRAY_TYPE)
00477 {
00478 int n;
00479 mcp(&n, p, sizeof(int));
00480 p += sizeof(int);
00481 ArgArray *array = new ArgArray(n, Argument::AutoFullGarbage);
00482 arg->set(array, Argument::AutoFullGarbage);
00483 decode_arg(db, (ArgArray *)array, p);
00484 }
00485 else if (type == VOID_TYPE)
00486 ;
00487 else
00488 UNKNOWN_TYPE(type, decode_arg)
00489 }
00490
00491 static void
00492 decode_arg(Database *db, ArgArray *array, const char * &p)
00493 {
00494 int cnt = array->getCount();
00495 for (int i = 0; i < cnt; i++)
00496 decode_arg(db, (Argument *)(*array)[i], p);
00497 }
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511 void
00512 code_arg_array(void *xdata, const void *xargarray)
00513 {
00514 rpc_Data *data = (rpc_Data *)xdata;
00515 const ArgArray *argarray = (const ArgArray *)xargarray;
00516 unsigned int size = sizeof(int);
00517
00518 int cnt = argarray->getCount();
00519 int i;
00520 for (i = 0; i < cnt; i++)
00521 {
00522 const Argument *arg = (*argarray)[i];
00523 size += getSize(arg);
00524 }
00525
00526 data->size = size;
00527 data->data = malloc(data->size);
00528 data->status = rpc_TempDataUsed;
00529
00530 char *p = (char *)data->data;
00531 mcp(p, &cnt, sizeof(int));
00532
00533 p += sizeof(int);
00534
00535 for (i = 0; i < cnt; i++)
00536 {
00537 const Argument *arg = (*argarray)[i];
00538 code_arg(arg, p);
00539 }
00540 }
00541
00542 int
00543 decode_arg_array(void *xdb, const void *xdata, void **pargarray,
00544 Bool allocate)
00545 {
00546 Database *db = (Database *)xdb;
00547 rpc_Data *data = (rpc_Data *)xdata;
00548 const char *p = (const char *)data->data;
00549 int cnt;
00550 mcp(&cnt, p, sizeof(int));
00551 p += sizeof(int);
00552
00553 ArgArray *argarray;
00554 if (allocate)
00555 {
00556
00557
00558
00559
00560 argarray = new ArgArray(cnt, Argument::AutoFullGarbage);
00561 *(ArgArray **)pargarray = argarray;
00562 }
00563 else
00564 argarray = (ArgArray *)pargarray;
00565
00566 for (int i = 0; i < cnt; i++)
00567 {
00568 Argument *arg = (*argarray)[i];
00569 decode_arg(db, arg, p);
00570 }
00571
00572
00573 return (int)(p - (char *)data->data);
00574 }
00575
00576
00577
00578
00579
00580
00581
00582 void
00583 code_argument(void *xdata, const void *xarg)
00584 {
00585 rpc_Data *data = (rpc_Data *)xdata;
00586 const Argument *arg = (const Argument *)xarg;
00587 int osize = data->size;
00588
00589 data->size += getSize(arg);
00590 data->data = realloc(data->data, data->size);
00591 data->status = rpc_TempDataUsed;
00592 char *p = ((char *)data->data) + osize;
00593
00594 code_arg(arg, p);
00595 }
00596
00597 void
00598 decode_argument(void *xdb, const void *xdata, void *xarg, int offset)
00599 {
00600 Database *db = (Database *)xdb;
00601 rpc_Data *data = (rpc_Data *)xdata;
00602
00603 Argument *arg = (Argument *)xarg;
00604 const char *p = ((const char *)data->data) + offset;
00605
00606 decode_arg(db, arg, p);
00607 }
00608
00609
00610
00611
00612
00613
00614
00615
00616 void
00617 code_signature(void *xdata, const void *xsign)
00618 {
00619 rpc_Data *data = (rpc_Data *)xdata;
00620 const Signature *sign = (const Signature *)xsign;
00621 int cnt = sign->getNargs();
00622
00623 data->size = sizeof(int) * (cnt + 2);
00624 data->data = malloc(data->size);
00625
00626 char *p = (char *)data->data;
00627 int type = sign->getRettype()->getType();
00628
00629 mcp(p, &type, sizeof(int));
00630 p += sizeof(int);
00631 mcp(p, &cnt, sizeof(int));
00632 p += sizeof(int);
00633
00634 for (int i = 0; i < cnt; i++)
00635 {
00636 type = sign->getTypes(i)->getType();
00637 mcp(p, &type, sizeof(int));
00638 p += sizeof(int);
00639 if (type == OBJ_TYPE)
00640 {
00641 const char *s = sign->getTypes(i)->getClname().c_str();
00642 int len = strlen(sign->getTypes(i)->getClname().c_str());
00643 mcp(p, &len, sizeof(int));
00644 p += sizeof(int);
00645 mcp(p, s, len);
00646 p += len;
00647 }
00648 }
00649
00650 assert(data->size == (int)(p - (char *)data->data));
00651 }
00652
00653 void
00654 decode_signature(const void *xdata, void *xsign)
00655 {
00656 rpc_Data *data = (rpc_Data *)xdata;
00657 const char *p = (const char *)data->data;
00658 Signature *sign = (Signature *)xsign;
00659 ArgType *type;
00660
00661 int _type;
00662 mcp(&_type, p, sizeof(int));
00663 p += sizeof(int);
00664 #ifdef NO_DIRECT_SET
00665 type = sign->getRettype();
00666 #else
00667 type = new ArgType();
00668 #endif
00669
00670 type->setType((ArgType_Type)_type, False);
00671
00672 #ifndef NO_DIRECT_SET
00673 sign->setRettype(type);
00674 #endif
00675
00676 int cnt;
00677 mcp(&cnt, p, sizeof(int));
00678 p += sizeof(int);
00679 sign->setNargs(cnt);
00680
00681 #ifdef NO_DIRECT_SET
00682 sign->setTypesCount(cnt);
00683 #endif
00684
00685 for (int i = 0; i < cnt; i++)
00686 {
00687 mcp(&_type, p, sizeof(int));
00688 p += sizeof(int);
00689 #ifdef NO_DIRECT_SET
00690 type = sign->getTypes(i);
00691 #else
00692 type = new ArgType();
00693 #endif
00694 type->setType((ArgType_Type)_type, False);
00695 if (_type == OBJ_TYPE)
00696 {
00697 int len;
00698 mcp(&len, p, sizeof(int));
00699 p += sizeof(int);
00700 char *s = (char *)malloc(len+1);
00701 mcp(s, p, len);
00702 p += len;
00703 type->setClname(s);
00704 free(s);
00705 }
00706
00707 #ifndef NO_DIRECT_SET
00708 sign->setTypes(i, type);
00709 #endif
00710 }
00711
00712 assert(data->size == (int)(p - (char *)data->data));
00713 }
00714 }