Argument.cc

00001 /* 
00002    EyeDB Object Database Management System
00003    Copyright (C) 1994-2008 SYSRA
00004    
00005    EyeDB is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Lesser General Public
00007    License as published by the Free Software Foundation; either
00008    version 2.1 of the License, or (at your option) any later version.
00009    
00010    EyeDB is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Lesser General Public License for more details.
00014    
00015    You should have received a copy of the GNU Lesser General Public
00016    License along with this library; if not, write to the Free Software
00017    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA 
00018 */
00019 
00020 /*
00021   Author: Eric Viara <viara@sysra.com>
00022 */
00023 
00024 
00025 #include "eyedb_p.h"
00026 #include "odl.h"
00027 
00028 #define NEW_ALLOC_POLICY
00029 
00030 //
00031 // Argument
00032 //
00033 
00034 namespace eyedb {
00035 
00036   static ArgType *types[BYTE_TYPE+1];
00037   static ArgType *arrtypes[BYTE_TYPE+1];
00038 
00039   inline static void
00040   make_type(ArgType *types[], ArgType_Type idx)
00041   {
00042     types[idx] = new ArgType();
00043     types[idx]->setType(idx, False);
00044     types[idx]->lock();
00045 
00046     arrtypes[idx] = new ArgType();
00047     arrtypes[idx]->setType((ArgType_Type)(idx|ARRAY_TYPE), False);
00048     arrtypes[idx]->lock();
00049   }
00050 
00051   static void
00052   init_types()
00053   {
00054     make_type(types, ANY_TYPE);
00055     make_type(types, INT16_TYPE);
00056     make_type(types, INT32_TYPE);
00057     make_type(types, INT64_TYPE);
00058     make_type(types, STRING_TYPE);
00059     make_type(types, CHAR_TYPE);
00060     make_type(types, FLOAT_TYPE);
00061     make_type(types, OID_TYPE);
00062     make_type(types, RAW_TYPE);
00063     make_type(types, BYTE_TYPE);
00064 
00065     types[OBJ_TYPE] = 0;
00066   }
00067 
00068   static ArgType *
00069   getType(ArgType_Type _type)
00070   {
00071     if (!types[0]) init_types();
00072     ArgType *type = (_type & ARRAY_TYPE) ? arrtypes[_type&~ARRAY_TYPE] :
00073       types[_type];
00074     if (type) {
00075       assert(!(type->getType() & INOUT_ARG_TYPE));
00076       return type;
00077     }
00078     type = new ArgType();
00079     type->setType(_type, False);
00080     return type;
00081   }
00082 
00083   void Argument::init(ArgType_Type _type)
00084   {
00085 #ifdef NEW_ALLOC_POLICY
00086     type = eyedb::getType(_type);
00087 #else
00088     type = new ArgType();
00089     type->setType(_type, False);
00090 #endif
00091     str = (char *)0;
00092     policy = Argument::NoGarbage;
00093     db = (Database *)0;
00094     //  printf("Argument::init(%p, %p)\n", this, type);
00095   }
00096 
00097   //
00098   // Constructors
00099   //
00100 
00101   // basic types : without copy and without garbage
00102 
00103   Argument::Argument()
00104   {
00105     init(VOID_TYPE);
00106   }
00107 
00108   Argument::Argument(eyedblib::int16 _i)
00109   {
00110     init(VOID_TYPE);
00111     set(_i);
00112   }
00113 
00114   Argument::Argument(eyedblib::int32 _i)
00115   {
00116     init(VOID_TYPE);
00117     set(_i);
00118   }
00119 
00120   Argument::Argument(eyedblib::int64 _i)
00121   {
00122     init(VOID_TYPE);
00123     set(_i);
00124   }
00125 
00126   Argument::Argument(const char *_s)
00127   {
00128     init(VOID_TYPE);
00129     set(_s);
00130   }
00131 
00132   Argument::Argument(char _c)
00133   {
00134     init(VOID_TYPE);
00135     set(_c);
00136   }
00137 
00138   Argument::Argument(unsigned char _by)
00139   {
00140     init(VOID_TYPE);
00141     set(_by);
00142   }
00143 
00144   Argument::Argument(double _d)
00145   {
00146     init(VOID_TYPE);
00147     set(_d);
00148   }
00149 
00150   Argument::Argument(const Oid &_oid, Database *_db)
00151   {
00152     init(VOID_TYPE);
00153     set(_oid, _db);
00154   }
00155 
00156   Argument::Argument(const Object *_o)
00157   {
00158     init(VOID_TYPE);
00159     set(_o);
00160   }
00161 
00162   Argument::Argument(const unsigned char *_raw, int size)
00163   {
00164     init(VOID_TYPE);
00165     set(_raw, size);
00166   }
00167 
00168   Argument::Argument(void *_x)
00169   {
00170     init(VOID_TYPE);
00171     set(_x);
00172   }
00173 
00174   Argument::Argument(const ArgArray *_array)
00175   {
00176     init(VOID_TYPE);
00177     set(_array);
00178   }
00179 
00180   // basic types : without copy and with garbage according to garbage policy
00181 
00182   Argument::Argument(char *_s, Argument::GarbagePolicy _policy)
00183   {
00184     init(VOID_TYPE);
00185     set(_s, _policy);
00186   }
00187 
00188   Argument::Argument(unsigned char *_raw, int size,
00189                      Argument::GarbagePolicy _policy)
00190   {
00191     init(VOID_TYPE);
00192     set(_raw, _policy);
00193   }
00194 
00195   Argument::Argument(Object *_o, Argument::GarbagePolicy _policy)
00196   {
00197     init(VOID_TYPE);
00198     set(_o, _policy);
00199   }
00200 
00201   Argument::Argument(ArgArray *_array,
00202                      Argument::GarbagePolicy _policy)
00203   {
00204     init(VOID_TYPE);
00205     set(_array, _policy);
00206   }
00207 
00208   // const array types : without copy and without garbage
00209   Argument::Argument(const int *_i, int cnt)
00210   {
00211     init(VOID_TYPE);
00212     set(_i, cnt);
00213   }
00214 
00215   Argument::Argument(const char *_c, int cnt)
00216   {
00217     init(VOID_TYPE);
00218     set(_c, cnt);
00219   }
00220 
00221   Argument::Argument(char **_s, int cnt)
00222   {
00223     init(VOID_TYPE);
00224     set(_s, cnt);
00225   }
00226 
00227   Argument::Argument(const double *_d, int cnt)
00228   {
00229     init(VOID_TYPE);
00230     set(_d, cnt);
00231   }
00232 
00233   Argument::Argument(const Oid *_oid, int cnt, Database *_db)
00234   {
00235     init(VOID_TYPE);
00236     set(_oid, cnt, _db);
00237   }
00238 
00239   Argument::Argument(const Object **_o, int cnt)
00240   {
00241     init(VOID_TYPE);
00242     set(_o, cnt);
00243   }
00244 
00245   // array types : without copy and with garbage according to garbage policy
00246   Argument::Argument(int *_i, int cnt, Argument::GarbagePolicy _policy)
00247   {
00248     init(VOID_TYPE);
00249     set(_i, cnt, _policy);
00250   }
00251 
00252   Argument::Argument(char *_c, int cnt, Argument::GarbagePolicy _policy)
00253   {
00254     init(VOID_TYPE);
00255     set(_c, cnt, _policy);
00256   }
00257 
00258   Argument::Argument(char **_s, int cnt,
00259                      Argument::GarbagePolicy _policy)
00260   {
00261     init(VOID_TYPE);
00262     set(_s, cnt, _policy);
00263   }
00264 
00265   Argument::Argument(double *_d, int cnt, Argument::GarbagePolicy _policy)
00266   {
00267     init(VOID_TYPE);
00268     set(_d, cnt, _policy);
00269   }
00270 
00271   Argument::Argument(Oid *_oid, int cnt,
00272                      Argument::GarbagePolicy _policy, Database *_db)
00273   {
00274     init(VOID_TYPE);
00275     set(_oid, cnt, _policy, _db);
00276   }
00277 
00278   Argument::Argument(Object **_o, int cnt,
00279                      Argument::GarbagePolicy _policy)
00280   {
00281     init(VOID_TYPE);
00282     set(_o, cnt, _policy);
00283   }
00284 
00285   //
00286   // Set methods
00287   //
00288 
00289   void Argument::set(eyedblib::int16 _i)
00290   {
00291     garbage();
00292     init(INT16_TYPE);
00293     u.i16 = _i;
00294   }
00295 
00296   void Argument::set(eyedblib::int32 _i)
00297   {
00298     garbage();
00299     init(INT32_TYPE);
00300     u.i32 = _i;
00301   }
00302 
00303   void Argument::set(eyedblib::int64 _i)
00304   {
00305     garbage();
00306     init(INT64_TYPE);
00307     u.i64 = _i;
00308   }
00309 
00310   void Argument::set(const char *_s)
00311   {
00312     garbage();
00313     init(STRING_TYPE);
00314     u.s = (char *)_s;
00315   }
00316 
00317   void Argument::set(char _c)
00318   {
00319     garbage();
00320     init(CHAR_TYPE);
00321     u.c = _c;
00322   }
00323 
00324   void Argument::set(unsigned char _by)
00325   {
00326     garbage();
00327     init(BYTE_TYPE);
00328     u.by = _by;
00329   }
00330 
00331   void Argument::set(double _d)
00332   {
00333     garbage();
00334     init(FLOAT_TYPE);
00335     u.d = _d;
00336   }
00337 
00338   void Argument::set(const Oid &_oid, Database *_db)
00339   {
00340     garbage();
00341     init(OID_TYPE);
00342     u.oid = new Oid(_oid.getOid());
00343     db = _db;
00344   }
00345 
00346   void Argument::set(const Object *_o)
00347   {
00348     garbage();
00349     init(OBJ_TYPE);
00350     u.o = (Object *)_o;
00351     if (u.o)
00352       type->setClname(u.o->getClass()->getName());
00353     db = (u.o ? u.o->getDatabase() : NULL);
00354   }
00355 
00356   void Argument::set(const unsigned char *_raw, int size)
00357   {
00358     garbage();
00359     init(RAW_TYPE);
00360     u.raw.data = (unsigned char *)_raw;
00361     u.raw.size = size;
00362   }
00363 
00364   void Argument::set(void *_x)
00365   {
00366     garbage();
00367     init(ANY_TYPE);
00368     u.x = _x;
00369   }
00370 
00371   void Argument::set(const ArgArray *_array)
00372   {
00373     garbage();
00374     init(ARRAY_TYPE);
00375     u.array = (ArgArray *)_array;
00376   }
00377 
00378   // basic types : without copy and with garbage according to garbage policy
00379   void Argument::set(Object *_o, Argument::GarbagePolicy _policy)
00380   {
00381     garbage();
00382     init(OBJ_TYPE);
00383     u.o = _o;
00384     if (u.o)
00385       type->setClname(u.o->getClass()->getName());
00386 
00387     policy = _policy;
00388     db = (u.o ? u.o->getDatabase() : NULL);
00389   }
00390 
00391   void Argument::set(char *_s, Argument::GarbagePolicy _policy)
00392   {
00393     garbage();
00394     init(STRING_TYPE);
00395     u.s = _s;
00396     policy = _policy;
00397   }
00398 
00399   void Argument::set(unsigned char *_raw, int size,
00400                      Argument::GarbagePolicy _policy)
00401   {
00402     garbage();
00403     init(RAW_TYPE);
00404     u.raw.data = _raw;
00405     u.raw.size = size;
00406     policy = _policy;
00407   }
00408 
00409   void Argument::set(ArgArray *_array, Argument::GarbagePolicy _policy)
00410   {
00411     garbage();
00412     init(ARRAY_TYPE);
00413     u.array = _array;
00414     policy = _policy;
00415   }
00416 
00417   // array types : without copy and with garbage according to garbage policy
00418 
00419   void Argument::set(const eyedblib::int16 *_i, int cnt)
00420   {
00421     garbage();
00422     init((ArgType_Type)(ARRAY_TYPE | INT16_TYPE));
00423     u.arr_i16.i = (eyedblib::int16 *)_i;
00424     u.arr_i16.cnt = cnt;
00425   }
00426 
00427   void Argument::set(const eyedblib::int32 *_i, int cnt)
00428   {
00429     garbage();
00430     init((ArgType_Type)(ARRAY_TYPE | INT32_TYPE));
00431     u.arr_i32.i = (eyedblib::int32 *)_i;
00432     u.arr_i32.cnt = cnt;
00433   }
00434 
00435   void Argument::set(const eyedblib::int64 *_i, int cnt)
00436   {
00437     garbage();
00438     init((ArgType_Type)(ARRAY_TYPE | INT64_TYPE));
00439     u.arr_i64.i = (eyedblib::int64 *)_i;
00440     u.arr_i64.cnt = cnt;
00441   }
00442 
00443   void Argument::set(const char *_c, int cnt)
00444   {
00445     garbage();
00446     init((ArgType_Type)(ARRAY_TYPE | CHAR_TYPE));
00447     u.arr_c.c = (char *)_c;
00448     u.arr_c.cnt = cnt;
00449   }
00450 
00451   void Argument::set(char **_s, int cnt)
00452   {
00453     garbage();
00454     init((ArgType_Type)(ARRAY_TYPE | STRING_TYPE));
00455     u.arr_s.s = (char **)_s;
00456     u.arr_s.cnt = cnt;
00457   }
00458 
00459   void Argument::set(const double *_d, int cnt)
00460   {
00461     garbage();
00462     init((ArgType_Type)(ARRAY_TYPE | FLOAT_TYPE));
00463     u.arr_d.d = (double *)_d;
00464     u.arr_d.cnt = cnt;
00465   }
00466 
00467   void Argument::set(const Oid *_oid, int cnt, Database *_db)
00468   {
00469     garbage();
00470     init((ArgType_Type)(ARRAY_TYPE | OID_TYPE));
00471     u.arr_oid.oid = (Oid *)_oid;
00472     u.arr_oid.cnt = cnt;
00473     db = _db;
00474   }
00475 
00476   void Argument::set(const Object **_o, int cnt)
00477   {
00478     garbage();
00479     init((ArgType_Type)(ARRAY_TYPE | OBJ_TYPE));
00480     u.arr_o.o = (Object **)_o;
00481     u.arr_o.cnt = cnt;
00482   }
00483 
00484   void Argument::set(eyedblib::int16 *_i, int cnt, Argument::GarbagePolicy _policy)
00485   {
00486     garbage();
00487     init((ArgType_Type)(ARRAY_TYPE | INT16_TYPE));
00488     u.arr_i16.i = _i;
00489     u.arr_i16.cnt = cnt;
00490     policy = _policy;
00491   }
00492 
00493   void Argument::set(eyedblib::int32 *_i, int cnt, Argument::GarbagePolicy _policy)
00494   {
00495     garbage();
00496     init((ArgType_Type)(ARRAY_TYPE | INT32_TYPE));
00497     u.arr_i32.i = _i;
00498     u.arr_i32.cnt = cnt;
00499     policy = _policy;
00500   }
00501 
00502   void Argument::set(eyedblib::int64 *_i, int cnt, Argument::GarbagePolicy _policy)
00503   {
00504     garbage();
00505     init((ArgType_Type)(ARRAY_TYPE | INT64_TYPE));
00506     u.arr_i64.i = _i;
00507     u.arr_i64.cnt = cnt;
00508     policy = _policy;
00509   }
00510 
00511   void Argument::set(char *_c, int cnt, Argument::GarbagePolicy _policy)
00512   {
00513     garbage();
00514     init((ArgType_Type)(ARRAY_TYPE | CHAR_TYPE));
00515     u.arr_c.c = _c;
00516     u.arr_c.cnt = cnt;
00517     policy = _policy;
00518   }
00519 
00520   void Argument::set(char **_s, int cnt, Argument::GarbagePolicy _policy)
00521   {
00522     garbage();
00523     init((ArgType_Type)(ARRAY_TYPE | STRING_TYPE));
00524     u.arr_s.s = _s;
00525     u.arr_s.cnt = cnt;
00526     policy = _policy;
00527   }
00528 
00529   void Argument::set(double *_d, int cnt, Argument::GarbagePolicy _policy)
00530   {
00531     garbage();
00532     init((ArgType_Type)(ARRAY_TYPE | FLOAT_TYPE));
00533     u.arr_d.d = _d;
00534     u.arr_d.cnt = cnt;
00535     policy = _policy;
00536   }
00537 
00538   void Argument::set(Oid *_oid, int cnt,
00539                      Argument::GarbagePolicy _policy, Database *_db)
00540   {
00541     garbage();
00542     init((ArgType_Type)(ARRAY_TYPE | OID_TYPE));
00543     u.arr_oid.oid = _oid;
00544     u.arr_oid.cnt = cnt;
00545     policy = _policy;
00546     db = _db;
00547   }
00548 
00549   void Argument::set(const Argument &arg)
00550   {
00551     *this = arg;
00552   }
00553 
00554   void Argument::set(Object **_o, int cnt,
00555                      Argument::GarbagePolicy _policy)
00556   {
00557     garbage();
00558     init((ArgType_Type)(ARRAY_TYPE | OBJ_TYPE));
00559     u.arr_o.o = _o;
00560     u.arr_o.cnt = cnt;
00561     policy = _policy;
00562   }
00563 
00564 
00565   //
00566   // accessor methods
00567   //
00568 
00569   eyedblib::int64 Argument::getInteger() const
00570   {
00571     int t = type->getType();
00572 
00573     if (t == INT16_TYPE)
00574       return u.i16;
00575 
00576     if (t == INT32_TYPE)
00577       return u.i32;
00578 
00579     if (t == INT64_TYPE)
00580       return u.i64;
00581 
00582     return -1; // should send an exception!
00583   }
00584 
00585   const Object *Argument::getObject() const
00586   {
00587     if (type->getType() == OBJ_TYPE)
00588       return u.o;
00589 
00590     if (type->getType() == OID_TYPE && db) {
00591       Object *xo = 0;
00592       db->transactionBegin();
00593       db->loadObject(*u.oid, xo);
00594       db->transactionCommit();
00595       return xo;
00596     }
00597 
00598     return NULL;
00599   }
00600 
00601   Object *Argument::getObject()
00602   {
00603     return (Object *)((const Argument *)this)->getObject();
00604   }
00605 
00606   const eyedblib::int16 *Argument::getIntegers16(int &cnt) const
00607   {
00608     if (type->getType() != (INT16_TYPE|ARRAY_TYPE))
00609       return NULL;
00610 
00611     cnt = u.arr_i16.cnt;
00612     return u.arr_i16.i;
00613   }
00614 
00615   const eyedblib::int32 *Argument::getIntegers32(int &cnt) const
00616   {
00617     if (type->getType() != (INT32_TYPE|ARRAY_TYPE))
00618       return NULL;
00619 
00620     cnt = u.arr_i32.cnt;
00621     return u.arr_i32.i;
00622   }
00623 
00624   const eyedblib::int64 *Argument::getIntegers64(int &cnt) const
00625   {
00626     if (type->getType() != (INT64_TYPE|ARRAY_TYPE))
00627       return NULL;
00628 
00629     cnt = u.arr_i64.cnt;
00630     return u.arr_i64.i;
00631   }
00632 
00633   const char *Argument::getChars(int &cnt) const
00634   {
00635     if (type->getType() != (CHAR_TYPE|ARRAY_TYPE))
00636       return NULL;
00637 
00638     cnt = u.arr_c.cnt;
00639     return u.arr_c.c;
00640   }
00641 
00642   const double *Argument::getFloats(int &cnt) const
00643   {
00644     if (type->getType() != (FLOAT_TYPE|ARRAY_TYPE))
00645       return NULL;
00646 
00647     cnt = u.arr_d.cnt;
00648     return u.arr_d.d;
00649   }
00650 
00651   const Oid *Argument::getOids(int &cnt) const
00652   {
00653     if (type->getType() != (OID_TYPE|ARRAY_TYPE))
00654       return NULL;
00655 
00656     cnt = u.arr_oid.cnt;
00657     return u.arr_oid.oid;
00658   }
00659 
00660   char **Argument::getStrings(int &cnt) const
00661   {
00662     if (type->getType() != (STRING_TYPE|ARRAY_TYPE))
00663       return NULL;
00664 
00665     cnt = u.arr_s.cnt;
00666     return (char **)u.arr_s.s;
00667   }
00668 
00669   Object **Argument::getObjects(int &cnt) const
00670   {
00671     if (type->getType() != (OBJ_TYPE|ARRAY_TYPE))
00672       return NULL;
00673 
00674     cnt = u.arr_o.cnt;
00675     return (Object **)u.arr_o.o;
00676   }
00677 
00678   Argument &Argument::operator=(const Argument &arg)
00679   {
00680     int _type = arg.type->getType();
00681 
00682     if (_type == INT16_TYPE)
00683       set(arg.u.i16);
00684 
00685     else if (_type == INT32_TYPE)
00686       set(arg.u.i32);
00687 
00688     else if (_type == INT64_TYPE)
00689       set(arg.u.i64);
00690 
00691     else if (_type == STRING_TYPE)
00692       set(const_cast<const char *>(arg.u.s));
00693 
00694     else if (_type == CHAR_TYPE)
00695       set(arg.u.c);
00696 
00697     else if (_type == BYTE_TYPE)
00698       set(arg.u.by);
00699 
00700     else if (_type == FLOAT_TYPE)
00701       set(arg.u.d);
00702 
00703     else if (_type == OID_TYPE)
00704       set(*arg.u.oid);
00705 
00706     else if (_type == OBJ_TYPE)
00707       set(const_cast<Object *>(arg.u.o));
00708 
00709     else if (_type == ARRAY_TYPE)
00710       set(arg.u.array);
00711 
00712     else if (_type == RAW_TYPE)
00713       set((const unsigned char *)arg.u.raw.data, arg.u.raw.size);
00714 
00715     else if (_type == ANY_TYPE)
00716       set(arg.u.x);
00717 
00718     else if (_type == (ARRAY_TYPE|INT16_TYPE))
00719       set(const_cast<const eyedblib::int16 *>(arg.u.arr_i16.i), arg.u.arr_i16.cnt);
00720 
00721     else if (_type == (ARRAY_TYPE|INT32_TYPE))
00722       set(const_cast<const eyedblib::int32 *>(arg.u.arr_i32.i), arg.u.arr_i32.cnt);
00723 
00724     else if (_type == (ARRAY_TYPE|INT64_TYPE))
00725       set(const_cast<const eyedblib::int64 *>(arg.u.arr_i64.i), arg.u.arr_i64.cnt);
00726 
00727     else if (_type == (ARRAY_TYPE|CHAR_TYPE))
00728       set(const_cast<const char *>(arg.u.arr_c.c), arg.u.arr_c.cnt);
00729 
00730     else if (_type == (ARRAY_TYPE|FLOAT_TYPE))
00731       set(const_cast<const double *>(arg.u.arr_d.d), arg.u.arr_d.cnt);
00732 
00733     else if (_type == (ARRAY_TYPE|OID_TYPE))
00734       set(const_cast<const Oid *>(arg.u.arr_oid.oid), arg.u.arr_oid.cnt);
00735 
00736     else if (_type == (ARRAY_TYPE|STRING_TYPE))
00737       set(const_cast<char **>(arg.u.arr_s.s), arg.u.arr_s.cnt);
00738 
00739     else if (_type == (ARRAY_TYPE|OBJ_TYPE))
00740       set(const_cast<const Object **>(arg.u.arr_o.o), arg.u.arr_o.cnt);
00741 
00742     else if (_type == VOID_TYPE)
00743       {
00744         garbage();
00745         init(VOID_TYPE);
00746       }
00747 
00748     else
00749       abort();
00750 
00751     return *this;
00752   }
00753 
00754   Argument::Argument(const Argument &arg)
00755   {
00756     init(VOID_TYPE);
00757     *this = arg;
00758   }
00759 
00760   const char *
00761   Argument::getArgTypeStr(const ArgType *argtype, Bool printref)
00762   {
00763 #define RTMX 4
00764     static int _rettype_idx;
00765     static char _rettype[RTMX][128];
00766     char *rettype;
00767     const char *array;
00768     int type = argtype->getType();
00769 
00770     if (_rettype_idx >= RTMX)
00771       _rettype_idx = 0;
00772 
00773     rettype = &_rettype[_rettype_idx++][0];
00774 
00775     if ((type & INOUT_ARG_TYPE) == INOUT_ARG_TYPE)
00776       {
00777         if (printref)
00778           strcpy(rettype, "inout ");
00779         else
00780           strcpy(rettype, "_INOUT_");
00781       }
00782     else if (type & IN_ARG_TYPE)
00783       {
00784         if (printref)
00785           strcpy(rettype, "in ");
00786         else
00787           strcpy(rettype, "_IN_");
00788       }
00789     else if (type & OUT_ARG_TYPE)
00790       {
00791         if (printref)
00792           strcpy(rettype, "out ");
00793         else
00794           strcpy(rettype, "_OUT_");
00795       }
00796     else
00797       *rettype = 0;
00798 
00799     if (type & ARRAY_TYPE)
00800       {
00801         if (printref)
00802           array = "[]";
00803         else
00804           array = "_ARRAY_";
00805       }
00806     else
00807       array = "";
00808 
00809     type &= ~(INOUT_ARG_TYPE | ARRAY_TYPE);
00810 
00811     if (type == ANY_TYPE)
00812       return strcat(strcat(rettype, "any"), array);
00813 
00814     if (type == VOID_TYPE)
00815       return strcat(strcat(rettype, "void"), array);
00816 
00817     if (type == INT16_TYPE)
00818       return strcat(strcat(rettype, Int16_Class->getName()), array);
00819 
00820     if (type == INT32_TYPE)
00821       {
00822         const char *clname = argtype->getClname().c_str();
00823         if (clname && *clname)
00824           return strcat(strcat(rettype, clname), array);
00825 
00826         return strcat(strcat(rettype, Int32_Class->getName()), array);
00827       }
00828 
00829     if (type == INT64_TYPE)
00830       return strcat(strcat(rettype, Int64_Class->getName()), array);
00831 
00832     if (type == STRING_TYPE)
00833       return strcat(strcat(rettype, "string"), array);
00834 
00835     if (type == CHAR_TYPE)
00836       return strcat(strcat(rettype, char_class_name), array);
00837 
00838     if (type == BYTE_TYPE)
00839       return strcat(strcat(rettype, "byte"), array);
00840 
00841     if (type == RAW_TYPE)
00842       return strcat(strcat(rettype, "rawdata"), array);
00843 
00844     if (type == FLOAT_TYPE)
00845       return strcat(strcat(rettype, "float"), array);
00846 
00847     if (type == OID_TYPE)
00848       return strcat(strcat(rettype, "oid"), array);
00849 
00850     if (type == OBJ_TYPE)
00851       {
00852         static char s[1024];
00853         sprintf(s, "%s%s", (*argtype->getClname().c_str() ? argtype->getClname().c_str() :
00854                             "<unknown class>"), (printref ? "*" : "_REF_"));
00855         return strcat(strcat(rettype, s), array);
00856       }
00857 
00858     return "";
00859   }
00860 
00861   const char *Argument::toString() const
00862   {
00863     if (str)
00864       return str;
00865 
00866     char buf[1024];
00867 
00868     int t = type->getType();
00869 
00870     if (t == INT16_TYPE)
00871       {
00872         sprintf(buf, "%d", u.i16);
00873         return (((Argument *)this)->str = strdup(buf));
00874       }
00875 
00876     if (t == INT32_TYPE)
00877       {
00878         sprintf(buf, "%ld", u.i32);
00879         return (((Argument *)this)->str = strdup(buf));
00880       }
00881 
00882     if (t == INT64_TYPE)
00883       {
00884         sprintf(buf, "%lld", u.i64);
00885         return (((Argument *)this)->str = strdup(buf));
00886       }
00887 
00888     if (t == STRING_TYPE)
00889       return u.s;
00890 
00891     if (t == CHAR_TYPE)
00892       {
00893         sprintf(buf, "'%c'", u.c);
00894         return (((Argument *)this)->str = strdup(buf));
00895       }
00896   
00897     if (t == BYTE_TYPE)
00898       {
00899         sprintf(buf, "'\\%3o'", u.by);
00900         return (((Argument *)this)->str = strdup(buf));
00901       }
00902   
00903     if (t == FLOAT_TYPE)
00904       {
00905         sprintf(buf, "%f", u.d);
00906         return (((Argument *)this)->str = strdup(buf));
00907       }
00908   
00909     if (t == OID_TYPE)
00910       return u.oid->getString();
00911   
00912     if (t == OBJ_TYPE)
00913       {
00914         sprintf(buf, "%p:%s", u.o, type->getClname().c_str());
00915         return (((Argument *)this)->str = strdup(buf));
00916       }
00917   
00918     if (t == ARRAY_TYPE)
00919       return (((Argument *)this)->str = strdup(u.array->toString()));
00920 
00921     return "<type not supported>";
00922   }
00923 
00924   //
00925   // garbage
00926   //
00927 
00928   void Argument::garbage()
00929   {
00930     int t = type->getType();
00931 
00932     if (t == OID_TYPE)
00933       delete u.oid;
00934     else if (policy != NoGarbage) {
00935       int _i;
00936       if (t == OBJ_TYPE) {
00937         if (u.o && !gbxAutoGarb::isObjectDeleted(u.o))
00938           u.o->release();
00939       }
00940       else if (t == STRING_TYPE)
00941 	::free(u.s);
00942       else if (t == RAW_TYPE)
00943 	::free(u.raw.data);
00944       else if (t == ARRAY_TYPE) {
00945         if (u.array && !gbxAutoGarb::isObjectDeleted(u.array))
00946           u.array->release();
00947       }
00948       else if (t == (ARRAY_TYPE|INT16_TYPE))
00949 	::free(u.arr_i16.i);
00950       else if (t == (ARRAY_TYPE|INT32_TYPE))
00951         ::free(u.arr_i32.i);
00952       else if (t == (ARRAY_TYPE|INT64_TYPE))
00953         ::free(u.arr_i64.i);
00954       else if (t == (ARRAY_TYPE|CHAR_TYPE))
00955         ::free(u.arr_c.c);
00956       else if (t == (ARRAY_TYPE|STRING_TYPE)) {
00957         if (policy == AutoFullGarbage)
00958           for (_i = 0; _i < u.arr_s.cnt; _i++)
00959             ::free(u.arr_s.s[_i]);
00960 	::free(u.arr_s.s);
00961       }
00962       else if (t == (ARRAY_TYPE|OBJ_TYPE)) {
00963         if (policy == AutoFullGarbage)
00964           for (_i = 0; _i < u.arr_o.cnt; _i++)
00965             if (u.arr_o.o[_i] && !gbxAutoGarb::isObjectDeleted(u.arr_o.o[_i]))
00966               u.arr_o.o[_i]->release();
00967 	::free(u.arr_o.o);
00968       }
00969       else if (t == (ARRAY_TYPE|OID_TYPE))
00970         ::free(u.arr_oid.oid);
00971     }
00972 
00973     ::free(str);
00974     str = NULL;
00975 
00976     if (!gbxAutoGarb::isObjectDeleted(type))
00977       type->release();
00978 
00979     type = NULL;
00980   }
00981 
00982 #define COPY_ARRAY(TYPE, X, SZ) \
00983   TYPE *__x = (TYPE *)malloc((SZ) * sizeof(TYPE)); \
00984   memcpy(__x, X, (SZ) * sizeof(TYPE)); \
00985   return __x
00986 
00987 #define ALLOC_ARRAY(TYPE, X, SZ) \
00988   if (!(X)) \
00989      return (TYPE *)calloc((SZ), sizeof(TYPE)); \
00990   return (TYPE *)realloc(X, (SZ) * sizeof(TYPE))
00991 
00992   char *Argument::alloc(unsigned int sz, char *x)
00993   {
00994     ALLOC_ARRAY(char, x, sz);
00995   }
00996 
00997   unsigned char *Argument::alloc(unsigned int sz, unsigned char *x)
00998   {
00999     ALLOC_ARRAY(unsigned char, x, sz);
01000   }
01001 
01002   eyedblib::int16 *Argument::alloc(unsigned int sz, eyedblib::int16 *x)
01003   {
01004     ALLOC_ARRAY(eyedblib::int16, x, sz);
01005   }
01006 
01007   eyedblib::int32 *Argument::alloc(unsigned int sz, eyedblib::int32 *x)
01008   {
01009     ALLOC_ARRAY(eyedblib::int32, x, sz);
01010   }
01011 
01012   eyedblib::int64 *Argument::alloc(unsigned int sz, eyedblib::int64 *x)
01013   {
01014     ALLOC_ARRAY(eyedblib::int64, x, sz);
01015   }
01016 
01017   double *Argument::alloc(unsigned int sz, double *x)
01018   {
01019     ALLOC_ARRAY(double, x, sz);
01020   }
01021 
01022   Oid *Argument::alloc(unsigned int sz, Oid *x)
01023   {
01024     ALLOC_ARRAY(Oid, x, sz);
01025   }
01026 
01027   char **Argument::alloc(unsigned int sz, char **x)
01028   {
01029     ALLOC_ARRAY(char *, x, sz);
01030   }
01031 
01032   Object **Argument::alloc(unsigned int sz, Object **x)
01033   {
01034     ALLOC_ARRAY(Object *, x, sz);
01035   }
01036 
01037   char *Argument::dup(const char *s)
01038   {
01039     return strdup(s);
01040   }
01041 
01042   unsigned char *Argument::dup(const unsigned char *x, int sz)
01043   {
01044     COPY_ARRAY(unsigned char, x, sz);
01045   }
01046 
01047   eyedblib::int16 *Argument::dup(const eyedblib::int16 *x, int cnt)
01048   {
01049     COPY_ARRAY(eyedblib::int16, x, cnt);
01050   }
01051 
01052   eyedblib::int32 *Argument::dup(const eyedblib::int32 *x, int cnt)
01053   {
01054     COPY_ARRAY(eyedblib::int32, x, cnt);
01055   }
01056 
01057   eyedblib::int64 *Argument::dup(const eyedblib::int64 *x, int cnt)
01058   {
01059     COPY_ARRAY(eyedblib::int64, x, cnt);
01060   }
01061 
01062   double *Argument::dup(const double *x, int cnt)
01063   {
01064     COPY_ARRAY(double, x, cnt);
01065   }
01066 
01067   Oid *Argument::dup(const Oid *x, int cnt)
01068   {
01069     COPY_ARRAY(Oid, x, cnt);
01070   }
01071 
01072   char **Argument::dup(char **x, int cnt)
01073   {
01074     char **_x = (char **)malloc(cnt * sizeof(char *));
01075     for (int i = 0; i < cnt; i++)
01076       _x[i] = strdup(x[i]);
01077     return _x;
01078   }
01079 
01080   Object **Argument::dup(Object **x, int cnt)
01081   {
01082     COPY_ARRAY(Object *, x, cnt);
01083   }
01084 
01085   void Argument::free(char *x)
01086   {
01087     ::free(x);
01088   }
01089 
01090   void Argument::free(unsigned char *x)
01091   {
01092     ::free(x);
01093   }
01094 
01095   void Argument::free(eyedblib::int16 *x)
01096   {
01097     ::free(x);
01098   }
01099 
01100   void Argument::free(eyedblib::int32 *x)
01101   {
01102     ::free(x);
01103   }
01104 
01105   void Argument::free(eyedblib::int64 *x)
01106   {
01107     ::free(x);
01108   }
01109 
01110   void Argument::free(double *x)
01111   {
01112     ::free(x);
01113   }
01114 
01115   void Argument::free(Oid *x)
01116   {
01117     ::free(x);
01118   }
01119 
01120   void Argument::free(char **x, int cnt)
01121   {
01122     for (int i = 0; i < cnt; i++)
01123       ::free(x[i]);
01124     ::free(x);
01125   }
01126 
01127   void Argument::free(Object *x)
01128   {
01129     if (x)
01130       x->release();
01131   }
01132 
01133   void Argument::free(Object **x, int cnt)
01134   {
01135     for (int i = 0; i < cnt; i++)
01136       if (x[i])
01137         x[i]->release();
01138     ::free(x);
01139   }
01140 
01141   Argument::~Argument()
01142   {
01143     garbageRealize();
01144   }
01145 
01146   //
01147   // ArgArray
01148   //
01149 
01150   ArgArray::ArgArray()
01151     : cnt(0), args(NULL), str(NULL), policy(Argument::NoGarbage)
01152   {
01153   }
01154 
01155   ArgArray::ArgArray(const Argument **_args, int _cnt)
01156     : cnt(_cnt), args((Argument **)_args), policy(Argument::NoGarbage),
01157       str(NULL)
01158   {
01159   }
01160 
01161   ArgArray::ArgArray(Argument **_args, int _cnt,
01162                      Argument::GarbagePolicy _policy)
01163     : cnt(_cnt), args(_args), policy(_policy), str(NULL)
01164   {
01165   }
01166 
01167   // 15/01/99: set the default policy to full garbage
01168   //ArgArray::ArgArray(int _cnt) : str(NULL), policy(Argument::NoGarbage)
01169   ArgArray::ArgArray(int _cnt, Argument::GarbagePolicy _policy) :
01170     str(NULL), policy(_policy)
01171   {
01172     cnt = _cnt;
01173 
01174     args = (Argument **)malloc(cnt * sizeof(Argument *));
01175 
01176     for (int i = 0; i < cnt; i++)
01177       args[i] = new Argument();
01178   }
01179 
01180   void
01181   ArgArray::set(Argument **_args, int _cnt,
01182                 Argument::GarbagePolicy _policy)
01183   {
01184     garbage();
01185     str = NULL;
01186     cnt = _cnt;
01187     args = _args;
01188     policy = _policy;
01189   }
01190 
01191   ArgType_Type
01192   ArgArray::getType() const
01193   {
01194     ArgType_Type type = (ArgType_Type)-1;
01195     for (int i = 0; i < cnt; i++)
01196       {
01197         ArgType_Type argtyp = args[i]->type->getType();
01198 
01199         if (type >= 0 && argtyp != type)
01200           return ANY_TYPE;
01201         type = argtyp;
01202       }
01203 
01204     return type >= 0 ? type : ANY_TYPE;
01205   }
01206 
01207   const char *
01208   ArgArray::toString() const
01209   {
01210     ::free(str);
01211 
01212     char *r = strdup("{");
01213 
01214     for (int ii = 0; ii < cnt; ii++)
01215       {
01216         const char *rs = args[ii]->toString();
01217         r = (char *)realloc(r, strlen(r) + strlen(rs) + (ii ? 3 : 1));
01218         if (ii)
01219           strcat(r, ", ");
01220         strcat(r, rs);
01221       }
01222   
01223     r = (char *)realloc(r, strlen(r) + strlen("}") + 1);
01224     strcat(r, "}");
01225     return ((ArgArray *)this)->str = r;
01226   }
01227 
01228   void ArgArray::garbage()
01229   {
01230     ::free(str);
01231     str = NULL;
01232 
01233     if (policy == Argument::NoGarbage)
01234       return;
01235 
01236     for (int i = 0; i < cnt; i++)
01237       args[i]->release();
01238 
01239     if (policy == Argument::AutoFullGarbage)
01240       ::free(args);
01241   }
01242 
01243   ArgArray::~ArgArray()
01244   {
01245     garbageRealize();
01246   }
01247 
01248   //
01249   // ArgType
01250   //
01251 
01252   Bool ArgType::operator==(const ArgType &argtype) const
01253   {
01254     ArgType_Type _type = getType();
01255 
01256     if (argtype.getType() != _type)
01257       return False;
01258 
01259     if (_type != OBJ_TYPE)
01260       return True;
01261 
01262     return !strcmp(getClname().c_str(), argtype.getClname().c_str()) ? True : False;
01263   }
01264 
01265   Bool ArgType::operator!=(const ArgType &argtype) const
01266   {
01267     return (argtype == *this ? False : True);
01268   }
01269 
01270   int
01271   ArgType::getBasicType(const char *s)
01272   {
01273     if (!strcmp(s, "any"))
01274       return ANY_TYPE;
01275 
01276     if (!strcmp(s, "void"))
01277       return VOID_TYPE;
01278 
01279     if (!strcmp(s, "short") || !strcmp(s, int16_class_name))
01280       return INT16_TYPE;
01281 
01282     if (!strcmp(s, "int") || !strcmp(s, int32_class_name))
01283       return INT32_TYPE;
01284       
01285     if (!strcmp(s, "long") || !strcmp(s, int64_class_name))
01286       return INT64_TYPE;
01287 
01288     if (!strcmp(s, "string"))
01289       return STRING_TYPE;
01290 
01291     if (!strcmp(s, char_class_name))
01292       return CHAR_TYPE;
01293 
01294     if (!strcmp(s, "byte"))
01295       return BYTE_TYPE;
01296 
01297     if (!strcmp(s, "float") || !strcmp(s, "double"))
01298       return FLOAT_TYPE;
01299 
01300     if (!strcmp(s, "oid"))
01301       return OID_TYPE;
01302 
01303     if (!strcmp(s, "raw") || !strcmp(s, "rawdata"))
01304       return RAW_TYPE;
01305 
01306     return -1;
01307   }
01308 
01309   ArgType *
01310   ArgType::make(Schema *m, const char *_s)
01311   {
01312     ArgType *type;
01313     int basic_type;
01314     static char x[128];
01315     int mod;
01316     int len = strlen(_s);
01317     const char *enum_class = 0;
01318 
01319     strcpy(x, _s);
01320 
01321     if (len > 2 && !strcmp(&x[len-2], "[]")) {
01322       mod = ARRAY_TYPE;
01323       x[len-2] = 0;
01324     }
01325     else
01326       mod = 0;
01327       
01328     basic_type = getBasicType(x);
01329 
01330     if (x[strlen(x)-1] == '*')
01331       x[strlen(x)-1] = 0;
01332 
01333     if (basic_type < 0) {
01334       const Class *cl = m->getClass(x);
01335       if (cl && cl->asEnumClass()) {
01336         basic_type = INT32_TYPE;
01337         enum_class = cl->getAliasName();
01338       }
01339     }
01340 
01341     if (basic_type >= 0) {
01342       // 16/01/99: do not support array of raw
01343       if (basic_type == RAW_TYPE && mod == ARRAY_TYPE)
01344         return 0;
01345       type = new ArgType();
01346       type->setType((ArgType_Type)(basic_type | mod), False);
01347       if (enum_class)
01348         type->setClname(enum_class);
01349       return type;
01350     }
01351   
01352     if (!strcmp(x, "int"))
01353       strcpy(x, int32_class_name);
01354 
01355     if (!strcmp(x, "short"))
01356       strcpy(x, int16_class_name);
01357 
01358     if (!strcmp(x, "long"))
01359       strcpy(x, int64_class_name);
01360 
01361     const Class *cls = m->getClass(x);
01362     if (!cls)
01363       return 0;
01364   
01365     type = new ArgType();
01366 
01367     type->setType((ArgType_Type)(OBJ_TYPE | mod), False);
01368     type->setClname(x);
01369 
01370     return type;
01371   }
01372 
01373 #define PURGE(T) ((T) & ~(INOUT_ARG_TYPE|ARRAY_TYPE))
01374 
01375   extern Bool odl_class_enums;
01376 
01377   const char *
01378   ArgType::getCType(Schema *m) const
01379   {
01380     int _type = PURGE(getType());
01381 
01382     if (_type == OBJ_TYPE)
01383       {
01384         static char tok[512];
01385         sprintf(tok, "%s *", m->getClass(getClname().c_str())->getCName(True));
01386         return tok;
01387       }
01388     if (_type == ANY_TYPE)
01389       return "Argument";
01390     if (_type == INT16_TYPE)
01391       return Int16_Class->getCName();
01392     if (_type == INT32_TYPE)
01393       {
01394         const char *clname = getClname().c_str();
01395         if (clname && *clname)
01396           {
01397             static char tok[512];
01398             std::string clsname = getClname();
01399             sprintf(tok, "%s", m->getClass(clsname.c_str())->getCName(True));
01400             if (odl_class_enums && !Class::isBoolClass(clsname.c_str()))
01401               strcat(tok, "::Type");
01402             return tok;
01403           }
01404         return Int32_Class->getCName();
01405       }
01406     if (_type == INT64_TYPE)
01407       return Int64_Class->getCName();
01408     if (_type == CHAR_TYPE)
01409       return char_class_name;
01410     if (_type == BYTE_TYPE)
01411       return "unsigned char";
01412     if (_type == FLOAT_TYPE)
01413       return "double";
01414     if (_type == STRING_TYPE)
01415       return "char *";
01416     if (_type == OID_TYPE)
01417       return "Oid";
01418     if (_type == RAW_TYPE)
01419       return "unsigned char *";
01420 
01421     return "";
01422   }
01423 
01424 #define CONST(T) \
01425 ((((T) & OUT_ARG_TYPE) || \
01426   (((T) & ARRAY_TYPE) && \
01427    (PURGE(T) == STRING_TYPE) || \
01428    (PURGE(T) == OBJ_TYPE))) \
01429  ? "" : "const ")
01430 
01431   void
01432   ArgType::getCPrefix(FILE *fd, Schema *m, const char *prefix,
01433                       const char *name, Bool fullcast) const
01434   {
01435     int _type = PURGE(getType());
01436  
01437     int isArray = (getType() & ARRAY_TYPE);
01438     const char *s = (isArray ? "s" : "");
01439     const char *r = (isArray ? "" : "*");
01440 
01441     if (_type == INT16_TYPE)
01442       fprintf(fd, "%s%sgetInteger%s16(", r, prefix, s);
01443     else if (_type == INT32_TYPE)
01444       {
01445         fprintf(fd, r);
01446         fprintf(fd, "%sgetInteger%s32(", prefix, s);
01447       }
01448     else if (_type == INT64_TYPE)
01449       fprintf(fd, "%s%sgetInteger%s64(", r, prefix, s);
01450     else if (_type == CHAR_TYPE)
01451       fprintf(fd, "%s%sgetChar%s(", r, prefix, s);
01452     else if (_type == BYTE_TYPE)
01453       fprintf(fd, "%s%sgetByte%s(", r, prefix, s);
01454     else if (_type == FLOAT_TYPE)
01455       fprintf(fd, "%s%sgetFloat%s(", r, prefix, s);
01456     else if (_type == STRING_TYPE)
01457       fprintf(fd, "%sgetString%s(", prefix, s);
01458     else if (_type == OID_TYPE)
01459       fprintf(fd, "%s%sgetOid%s(", r, prefix, s);
01460     else if (_type == OBJ_TYPE)
01461       {
01462         if (fullcast)
01463           fprintf(fd, "(%s%s *%s)%sgetObject%s(", 
01464                   //(*s ? "const " : ""),
01465                   CONST(_type),
01466                   m->getClass(getClname().c_str())->getCName(True),
01467                   (*s ? " *" : ""), prefix, s);
01468         else
01469           fprintf(fd, "%sgetObject%s(", 
01470                   prefix, s);
01471       }
01472     else if (_type == RAW_TYPE)
01473       fprintf(fd, "%sgetRaw(", prefix);
01474     else if (_type == ANY_TYPE)
01475       fprintf(fd, "%sgetArgument(", prefix);
01476 
01477     if (isArray)
01478       fprintf(fd, "%s_cnt", name);
01479     else if (_type == RAW_TYPE)
01480       fprintf(fd, "%s_size", name);
01481 
01482     fprintf(fd, ")");
01483   }
01484 
01485   void ArgType::declare(FILE *fd, Schema *m, const char *name)
01486   {
01487     int _type = getType();
01488 
01489     const char *_ref;
01490     const char *_const;
01491 
01492     if ((_type & (OUT_ARG_TYPE|ARRAY_TYPE)) ==
01493         (OUT_ARG_TYPE|ARRAY_TYPE))
01494       _ref = "* &";
01495     else if (_type & OUT_ARG_TYPE)
01496       _ref = "&";
01497     else if (_type & ARRAY_TYPE)
01498       _ref = "*";
01499     else
01500       _ref = "";
01501 
01502     _const = CONST(_type);
01503   
01504     char _array[1024];
01505     if (_type & ARRAY_TYPE)
01506       sprintf(_array, ", int %s%s_cnt", (_type & OUT_ARG_TYPE ? "&" : ""),
01507               name);
01508     else if (PURGE(_type) == RAW_TYPE)
01509       sprintf(_array, ", int %s%s_size", (_type & OUT_ARG_TYPE ? "&" : ""),
01510               name);
01511     else
01512       *_array = 0;
01513 
01514     fprintf(fd, "%s%s %s%s%s", _const, getCType(m), _ref, name, _array);
01515   }
01516 
01517   void ArgType::init(FILE *fd, Schema *m, const char *prefix,
01518                      const char *name, const char *indent)
01519   {
01520     int _type = getType();
01521 
01522     if (_type & ARRAY_TYPE)
01523       fprintf(fd, "%sint %s_cnt = 0;\n", indent, name);
01524     else if (PURGE(_type) == RAW_TYPE)
01525       fprintf(fd, "%sint %s_size = 0;\n", indent, name);
01526 
01527     const char *_const = CONST(_type);
01528 
01529     fprintf(fd, "%s%s%s %s%s = ", indent,
01530             _const,
01531             getCType(m), (_type & ARRAY_TYPE) ? "*" : "",
01532             name);
01533 
01534     if ((_type & INOUT_ARG_TYPE) == INOUT_ARG_TYPE)
01535       {
01536         if (_type & ARRAY_TYPE)
01537           fprintf(fd, "(%s *)", getCType(m));
01538         else if (PURGE(_type) == RAW_TYPE)
01539           fprintf(fd, "(%sunsigned char *)", _const);
01540       }
01541 
01542     if (PURGE(_type) == INT32_TYPE && *getClname().c_str()) {
01543       std::string clsname = getClname();
01544       fprintf(fd, "(%s%s%s)",  m->getClass(clsname.c_str())->getCName(True),
01545               (odl_class_enums && !Class::isBoolClass(clsname.c_str()) ? "::Type" : ""),
01546               (_type & ARRAY_TYPE) ? " *" : "");
01547     }
01548 
01549     if (_type & IN_ARG_TYPE)
01550       getCPrefix(fd, m, prefix, name, True);
01551     else if (PURGE(_type) == OID_TYPE && !(_type & ARRAY_TYPE))
01552       fprintf(fd, "Oid::nullOid");
01553     else
01554       fprintf(fd, "0");
01555   }
01556 
01557   void ArgType::ret(FILE *fd, Schema *m, const char *prefix, const char *name)
01558   {
01559     int _type = PURGE(getType());
01560  
01561     fprintf(fd, "%s = (%s%s)", name, getCType(m),
01562             (getType() & ARRAY_TYPE ? " *" : ""));
01563 
01564     getCPrefix(fd, m, prefix, name, False);
01565 
01566     if (getType() & ARRAY_TYPE)
01567       {
01568         fprintf(fd, ";\n");
01569         if (PURGE(getType()) == OBJ_TYPE)
01570           {
01571             const char *clname = getClname().c_str();
01572             if (clname && *clname)
01573               fprintf(fd, "  %s = (%s **)eyedb::Argument::dup((Object **)%s, "
01574                       "%s_cnt)", name, clname, name, name);
01575             else
01576               fprintf(fd, "  %s = eyedb::Argument::dup((Object **)%s, %s_cnt)",
01577                       name, name, name);
01578           }
01579         else if (PURGE(getType()) == INT32_TYPE && *getClname().c_str())
01580           fprintf(fd, "  %s = (%s *)eyedb::Argument::dup((eyedblib::int32 *)%s, %s_cnt)",
01581                   name, getClname().c_str(), name, name);
01582         else
01583           fprintf(fd, "  %s = eyedb::Argument::dup(%s, %s_cnt)", name, name, name);
01584       }
01585     else if (_type == STRING_TYPE)
01586       fprintf(fd, ";\n  %s = eyedb::Argument::dup(%s)", name, name);
01587     else if (_type == RAW_TYPE)
01588       fprintf(fd, ";\n  %s = eyedb::Argument::dup(%s, %s_size)", name, name, name);
01589   }
01590 
01591   //
01592   // Signature
01593   //
01594 
01595   Bool Signature::operator==(const Signature &sign) const
01596   {
01597     if (*getRettype() != *sign.getRettype() ||
01598         getNargs() != sign.getNargs())
01599       return False;
01600 
01601     int nargs = getNargs();
01602     for (int i = 0; i < nargs; i++)
01603       if (*getTypes(i) != *sign.getTypes(i))
01604         return False;
01605 
01606     return True;
01607   }
01608 
01609   Bool Signature::operator!=(const Signature &sign) const
01610   {
01611     return (sign == *this ? False : True);
01612   }
01613 
01614   static const char parg[]    = "arg";
01615   static const char pretarg[] = "retarg";
01616   static const char ppretarg[] = "_retarg";
01617 
01618   const char *
01619   Signature::getArg(int i)
01620   {
01621     static char sarg[512];
01622     if (getUserData())
01623       {
01624         char **names = ((odlSignUserData *)getUserData())->names;
01625 
01626         if (names && names[i])
01627           return names[i];
01628       }
01629 
01630     sprintf(sarg, "%s%d", parg, i+1);
01631     return sarg;
01632   }
01633 
01634   const char *
01635   Signature::getPrefix(const char *prefix, int i)
01636   {
01637     static char sprefix[512];
01638     sprintf(sprefix, prefix, i);
01639     return sprefix;
01640   }
01641 
01642   Bool
01643   Signature::isVoid(const ArgType *type)
01644   {
01645     return (PURGE(type->getType()) == VOID_TYPE) ?
01646       True : False;
01647   }
01648 
01649   void Signature::listArgs(FILE *fd, Schema *m)
01650   {
01651     int nargs = getNargs();
01652     for (int i = 0; i < nargs; i++)
01653       {
01654         ArgType *arg = getTypes(i);
01655         if (i)
01656           fprintf(fd, ", ");
01657         fprintf(fd, getArg(i));
01658         if (arg->getType() & ARRAY_TYPE)
01659           fprintf(fd, ", %s_cnt", getArg(i));
01660         else if (PURGE(arg->getType()) == RAW_TYPE)
01661           fprintf(fd, ", %s_size", getArg(i));
01662       }
01663 
01664     if (isVoid(getRettype()))
01665       return;
01666 
01667     if (nargs)
01668       fprintf(fd, ", ");
01669     fprintf(fd, "%s", ppretarg);
01670     if (getRettype()->getType() & ARRAY_TYPE)
01671       fprintf(fd, ", %s_cnt", ppretarg);
01672     else if (PURGE(getRettype()->getType()) == RAW_TYPE)
01673       fprintf(fd, ", %s_size", ppretarg);
01674   }
01675 
01676   void Signature::declArgs(FILE *fd, Schema *m)
01677   {
01678     int nargs = getNargs();
01679     for (int i = 0, n = 0; i < nargs; i++)
01680       {
01681         ArgType *arg = getTypes(i);
01682         if (i)
01683           fprintf(fd, ", ");
01684         arg->declare(fd, m, getArg(i));
01685       }
01686 
01687     if (isVoid(getRettype()))
01688       return;
01689 
01690     if (nargs)
01691       fprintf(fd, ", ");
01692     getRettype()->declare(fd, m, pretarg);
01693   }
01694 
01695   void Signature::initArgs(FILE *fd, Schema *m, const char *prefix,
01696                            const char *preret, const char *indent)
01697   {
01698     int nargs = getNargs();
01699     for (int i = 0, n = 0; i < nargs; i++)
01700       {
01701         ArgType *arg = getTypes(i);
01702         arg->init(fd, m, getPrefix(prefix, i), getArg(i), indent);
01703         fprintf(fd, ";\n");
01704       }
01705 
01706     if (isVoid(getRettype()))
01707       return;
01708 
01709     getRettype()->init(fd, m, 0, preret, indent);
01710     fprintf(fd, ";\n");
01711   }
01712 
01713   static const char *
01714   getCast(int type, const char *clname, int isout)
01715   {
01716     if ((type & (ARRAY_TYPE|OBJ_TYPE)) == (ARRAY_TYPE|OBJ_TYPE))
01717       return isout ? "(Object **)" : "(const Object **)";
01718     else if (*clname && (type & (ARRAY_TYPE|INT32_TYPE)) ==
01719              (ARRAY_TYPE|INT32_TYPE))
01720       return isout ? "(eyedblib::int32 *)" : "(const eyedblib::int32 *)";
01721 
01722     return "";
01723   }
01724 
01725   void Signature::setArgs(FILE *fd, Schema *m, int _type,
01726                           const char *prefix, const char *preret,
01727                           const char *indent)
01728   {
01729     int nargs = getNargs();
01730 
01731     // 19/02/99 ->
01732     const char *polstr = (_type & OUT_ARG_TYPE) ?
01733       ", eyedb::Argument::AutoFullGarbage" : ", eyedb::Argument::NoGarbage";
01734 
01735     //const char *polstr = ", Argument::NoGarbage";
01736 
01737     for (int i = 0; i < nargs; i++)
01738       {
01739         ArgType *arg = getTypes(i);
01740         if ((arg->getType() & _type) == _type)
01741           {
01742             fprintf(fd, "%s%sset(%s%s", indent, getPrefix(prefix, i),
01743                     getCast(arg->getType(), arg->getClname().c_str(), (arg->getType() & OUT_ARG_TYPE)),
01744                     getArg(i));
01745             if (arg->getType() & ARRAY_TYPE)
01746               fprintf(fd, ", %s_cnt%s", getArg(i),
01747                       !(arg->getType() & OUT_ARG_TYPE) ? "" : polstr);
01748             else if (PURGE(arg->getType()) == RAW_TYPE)
01749               fprintf(fd, ", %s_size%s", getArg(i),
01750                       !(arg->getType() & OUT_ARG_TYPE) ? "" : polstr);
01751             else if ((_type & OUT_ARG_TYPE) &&
01752                      (PURGE(arg->getType()) == STRING_TYPE ||
01753                       PURGE(arg->getType()) == OBJ_TYPE))
01754               fprintf(fd, "%s", polstr);
01755             fprintf(fd, ");\n");
01756           }
01757       }
01758 
01759     if (isVoid(getRettype()))
01760       return;
01761 
01762     if (_type & OUT_ARG_TYPE)
01763       {
01764         ArgType *rettype = getRettype();
01765         fprintf(fd, "%s%sset(%s%s", indent, preret,
01766                 getCast(rettype->getType(), rettype->getClname().c_str(), 1), ppretarg);
01767         if (rettype->getType() & ARRAY_TYPE)
01768           fprintf(fd, ", %s_cnt%s", ppretarg, polstr);
01769         else if (PURGE(rettype->getType()) == RAW_TYPE)
01770           fprintf(fd, ", %s_size%s", ppretarg, polstr);
01771         else if (PURGE(rettype->getType()) == STRING_TYPE ||
01772                  PURGE(rettype->getType()) == OBJ_TYPE)
01773           fprintf(fd, "%s", polstr);
01774         fprintf(fd, ");\n");
01775       }
01776   }
01777 
01778   void Signature::retArgs(FILE *fd, Schema *m, const char *prefix,
01779                           const char *preret,
01780                           const char *indent)
01781   {
01782     int nargs = getNargs();
01783     for (int i = 0, n = 0; i < nargs; i++)
01784       {
01785         ArgType *arg = getTypes(i);
01786         if (arg->getType() & OUT_ARG_TYPE)
01787           {
01788             fprintf(fd, indent);
01789             arg->ret(fd, m, getPrefix(prefix, i), getArg(i));
01790             fprintf(fd, ";\n");
01791           }
01792       }
01793 
01794     if (isVoid(getRettype()))
01795       return;
01796 
01797     fprintf(fd, indent);
01798     getRettype()->ret(fd, m, preret, pretarg);
01799     fprintf(fd, ";\n");
01800   }
01801 }

Generated on Mon Dec 22 18:15:47 2008 for eyedb by  doxygen 1.5.3