EnumClass.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 "IteratorBE.h"
00027 #include "CollectionBE.h"
00028 #include <iostream>
00029 
00030 //
00031 // EnumClass
00032 //
00033 
00034 namespace eyedb {
00035 
00036   EnumClass::EnumClass(const char *s) : Class(s)
00037   {
00038     items_cnt = 0;
00039     items = 0;
00040 
00041     parent = Enum_Class;
00042     setClass(EnumClass_Class);
00043 #ifdef IDB_UNDEF_ENUM_HINT
00044     idr_objsz = IDB_OBJ_HEAD_SIZE + sizeof(char) + sizeof(eyedblib::int32);
00045 #else
00046     idr_objsz = IDB_OBJ_HEAD_SIZE + sizeof(eyedblib::int32);
00047 #endif
00048     idr_psize = idr_objsz;
00049     idr_vsize = 0;
00050     type = _EnumClass_Type;
00051   }
00052 
00053   EnumClass::EnumClass(Database *_db, const char *s) : Class(_db, s)
00054   {
00055     items_cnt = 0;
00056     items = 0;
00057 
00058     parent = Enum_Class;
00059     setClass(EnumClass_Class);
00060 #ifdef IDB_UNDEF_ENUM_HINT
00061     idr_objsz = IDB_OBJ_HEAD_SIZE + sizeof(char) + sizeof(eyedblib::int32);
00062 #else
00063     idr_objsz = IDB_OBJ_HEAD_SIZE + sizeof(eyedblib::int32);
00064 #endif
00065     idr_psize = idr_objsz;
00066     idr_vsize = 0;
00067     type = _EnumClass_Type;
00068   }
00069 
00070   void
00071   EnumClass::copy_realize(const EnumClass &cl)
00072   {
00073     items_cnt = cl.items_cnt;
00074     items = (EnumItem **)malloc(sizeof(EnumItem*)*items_cnt);
00075     for (int i = 0; i < items_cnt; i++)
00076       items[i] = cl.items[i]->clone();
00077   }
00078 
00079   EnumClass::EnumClass(const EnumClass &cl)
00080     : Class(cl)
00081   {
00082     copy_realize(cl);
00083   }
00084 
00085   EnumClass::EnumClass(const Oid &_oid, const char *_name)
00086     : Class(_oid, _name)
00087   {
00088     items_cnt = 0;
00089     items = 0;
00090     type = _EnumClass_Type;
00091   }
00092 
00093   Status
00094   EnumClass::loadComplete(const Class *cl)
00095   {
00096     assert(cl->asEnumClass());
00097     Status s = Class::loadComplete(cl);
00098     if (s) return s;
00099     copy_realize(*cl->asEnumClass());
00100     return Success;
00101   }
00102 
00103   EnumClass& EnumClass::operator=(const EnumClass &cl)
00104   {
00105     this->Class::operator=(cl);
00106     copy_realize(cl);
00107 
00108     return *this;
00109   }
00110 
00111   int EnumClass::getEnumItemsCount(void) const
00112   {
00113     return items_cnt;
00114   }
00115 
00116   const EnumItem *EnumClass::getEnumItem(int n) const
00117   {
00118     if (n >= 0 && n < items_cnt)
00119       return items[n];
00120     else
00121       return 0;
00122   }
00123 
00124   const EnumItem *EnumClass::getEnumItemFromName(const char *nm) const
00125   {
00126     for (int i = 0; i < items_cnt; i++)
00127       if (!strcmp(items[i]->name, nm))
00128         return items[i];
00129 
00130     return (const EnumItem *)0;
00131   }
00132 
00133   const EnumItem *EnumClass::getEnumItemFromVal(unsigned int val) const
00134   {
00135     for (int i = 0; i < items_cnt; i++)
00136       if (items[i]->value == val)
00137         return items[i];
00138 
00139     return (const EnumItem *)0;
00140   }
00141 
00142   void EnumClass::free_items(void)
00143   {
00144     if (items_cnt)
00145       {
00146         for (int i = 0; i < items_cnt; i++)
00147           delete items[i];
00148 
00149         free(items);
00150       }
00151   }
00152 
00153   Status EnumClass::setEnumItems(EnumItem **nitems, int cnt)
00154   {
00155     free_items();
00156 
00157     items_cnt = cnt;
00158 
00159     if (items_cnt)
00160       {
00161         items = (EnumItem**)malloc(sizeof(EnumItem*)*items_cnt);
00162         for (int i = 0; i < items_cnt; i++)
00163           items[i] = new EnumItem(nitems[i], i);
00164       }
00165 
00166     return Success;
00167   }
00168 
00169   const EnumItem **EnumClass::getEnumItems(int& cnt) const
00170   {
00171     cnt = items_cnt;
00172     return (const EnumItem **)items;
00173   }
00174 
00175   Bool
00176   EnumClass::compare_perform(const Class *cl,
00177                              Bool compClassOwner,
00178                              Bool compNum,
00179                              Bool compName,
00180                              Bool inDepth) const
00181   {
00182     const EnumClass *me = (EnumClass *)cl;
00183     if (items_cnt != me->items_cnt)
00184       return False;
00185 
00186     for (int i = 0; i < items_cnt; i++)
00187       if (!items[i]->compare(me->items[i]))
00188         return False;
00189 
00190     return True;
00191   }
00192 
00193   Object *EnumClass::newObj(Database *_db) const
00194   {
00195     if (!idr_objsz)
00196       return 0;
00197 
00198     Enum *t = new Enum(_db);
00199 
00200     ObjectPeer::make(t, this, 0, _Enum_Type, idr_objsz,
00201                      idr_psize, idr_vsize);
00202     return t;
00203   }
00204 
00205   Object *EnumClass::newObj(Data data, Bool _copy) const
00206   {
00207     if (!idr_objsz)
00208       return 0;
00209 
00210     Enum *t = new Enum();
00211 
00212     ObjectPeer::make(t, this, data, _Enum_Type, idr_objsz,
00213                      idr_psize, idr_vsize, _copy);
00214     return t;
00215   }
00216 
00217   void EnumClass::_setCSDRSize(Size, Size)
00218   {
00219   }
00220 
00221   Status
00222   EnumClass::setName(const char *s)
00223   {
00224     return setNameRealize(s);
00225   }
00226 
00227   Status EnumClass::trace(FILE *fd, unsigned int flags, const RecMode *rcm) const
00228   {
00229     if (const_cast<EnumClass *>(this)->wholeComplete())
00230       return 0;
00231 
00232     char *indent_str = make_indent(INDENT_INC);
00233     EnumItem **item;
00234     int n;
00235 
00236     fprintf(fd, "%s enum %s { ", oid.getString(), name);
00237 
00238     Status status = Success;
00239     status = trace_common(fd, INDENT_INC, flags, rcm);
00240     if (status) goto out;
00241 
00242     for (n = 0, item = items; n < items_cnt; n++, item++)
00243       fprintf(fd, "%s%s = %d%s\n", indent_str, (*item)->name, (*item)->value,
00244               ((n != items_cnt - 1) ? "," : ""));
00245 
00246     status = trace_comps(fd, INDENT_INC, flags, rcm);
00247     if (status) goto out;
00248 
00249     fprintf(fd, "};\n");
00250 
00251   out:
00252     delete_indent(indent_str);
00253     return status;
00254   }
00255 
00256   static int global_check_enum_value =
00257   getenv("EYEDBNOCHECKENUM") ? False : True;
00258 
00259   Status EnumClass::setRawData(Data xdata, Data hdata, int nb,
00260                                Bool& mod, Bool check_value)
00261   {
00262 #ifdef E_XDR_TRACE
00263     cout << "EnumClass::setRawData " << name << endl;
00264 #endif
00265     mod = False;
00266 #ifdef IDB_UNDEF_ENUM_HINT
00267     xdata += sizeof(char);
00268 #endif
00269 #ifdef IDB_UNDEF_ENUM_HINT
00270     for (int i = 0; i < nb; i++, xdata += sizeof(char) + sizeof(eyedblib::int32),
00271            hdata += sizeof(eyedblib::int32))
00272 #else
00273       for (int i = 0; i < nb; i++, xdata += sizeof(eyedblib::int32),
00274              hdata += sizeof(eyedblib::int32)) {
00275 #endif
00276         eyedblib::int32 l;
00277         x2h_32_cpy(&l, xdata);
00278         if (memcmp(&l, hdata, sizeof(eyedblib::int32))) {
00279           if (check_value && global_check_enum_value) {
00280             eyedblib::int32 val;
00281             eyedblib_mcp(&val, hdata, sizeof(eyedblib::int32));
00282             if (!getEnumItemFromVal(val))
00283               return Exception::make(IDB_ERROR, "invalid value '%d' for "
00284                                      "enum class %s", val, name);
00285           }
00286           h2x_32_cpy(xdata, hdata);
00287           //eyedblib_mcp(xdata, hdata, sizeof(eyedblib::int32));
00288           mod = True;
00289         }
00290       }
00291 
00292     return Success;
00293   }
00294 
00295   Status EnumClass::getRawData(Data hdata, Data xdata, int nb) const
00296   {
00297 #ifdef E_XDR_TRACE
00298     cout << "EnumClass::getRawData " << name << endl;
00299 #endif
00300 #ifdef IDB_UNDEF_ENUM_HINT
00301     xdata += sizeof(char);
00302     for (int i = 0; i < nb; i++, hdata += sizeof(eyedblib::int32),
00303            xdata += sizeof(char) + sizeof(eyedblib::int32))
00304       memcpy(hdata, xdata, sizeof(eyedblib::int32));
00305 #else
00306     for (int i = 0; i < nb; i++, hdata += sizeof(eyedblib::int32),
00307            xdata += sizeof(eyedblib::int32)) {
00308 #ifdef E_XDR
00309       x2h_32_cpy(hdata, xdata);
00310 #else
00311       memcpy(hdata, xdata, sizeof(eyedblib::int32));
00312 #endif
00313     }
00314 #endif
00315 
00316     return Success;
00317   }
00318 
00319   Status EnumClass::traceData(FILE *fd, int, Data inidata, Data data, TypeModifier *tmod) const
00320   {
00321     int i;
00322     if (data)
00323       {
00324 #ifdef IDB_UNDEF_ENUM_HINT
00325         data += sizeof(char);
00326 #endif
00327         const EnumItem *it;
00328         eyedblib::int32 j;
00329         if (tmod)
00330           {
00331             if (tmod->pdims > 1)
00332               {
00333                 fprintf(fd, "{");
00334                 for (i = 0; i < tmod->pdims; i++)
00335                   {
00336                     if (i)
00337                       fprintf(fd, ", ");
00338 #ifdef E_XDR
00339                     x2h_32_cpy(&j, data);
00340 #else
00341                     memcpy(&j, data, sizeof(eyedblib::int32));
00342 #endif
00343                     it = getEnumItemFromVal(j);
00344                     if (it)
00345                       fprintf(fd, "%s", it->name);
00346                     else
00347                       {
00348                         fprintf(fd, "%d", j);
00349                         if (j)
00350                           fprintf(fd, " [%XH 0%o]", j, j);
00351                       }
00352 
00353 #ifdef IDB_UNDEF_ENUM_HINT
00354                     data += sizeof(eyedblib::int32) + sizeof(char);
00355 #else
00356                     data += sizeof(eyedblib::int32);
00357 #endif
00358                   }
00359                 fprintf(fd, "}");
00360               }
00361             else
00362               {
00363 #ifdef E_XDR
00364                 x2h_32_cpy(&j, data);
00365 #else
00366                 memcpy(&j, data, sizeof(eyedblib::int32));
00367 #endif
00368                 it = getEnumItemFromVal(j);
00369                 if (it)
00370                   fprintf(fd, "%s", it->name);
00371                 else
00372                   {
00373                     fprintf(fd, "%d", j);
00374                     if (j)
00375                       fprintf(fd, " [%XH 0%o]", j, j);
00376                   }
00377               }
00378           }
00379         else
00380           {
00381 #ifdef E_XDR
00382             x2h_32_cpy(&j, data);
00383 #else
00384             memcpy(&j, data, sizeof(eyedblib::int32));
00385 #endif
00386             it = getEnumItemFromVal(j);
00387             if (it)
00388               fprintf(fd, "%s", it->name);
00389             else
00390               {
00391                 fprintf(fd, "%d", j);
00392                 if (j)
00393                   fprintf(fd, " [%XH 0%o]", j, j);
00394               }
00395           }
00396       }
00397     else
00398       fprintf(fd, "null");
00399 
00400     return Success;
00401   }
00402 
00403   Status EnumClass::setValue(Data)
00404   {
00405     return Success;
00406   }
00407 
00408   Status EnumClass::getValue(Data*) const
00409   {
00410     return Success;
00411   }
00412 
00413   Status EnumClass::create()
00414   {
00415     if (oid.isValid())
00416       return Exception::make(IDB_OBJECT_ALREADY_CREATED, "creating enum class '%s'", name);
00417 
00418     IDB_CHECK_WRITE(db);
00419 
00420     Size alloc_size;
00421     Offset offset;
00422     Status status;
00423 
00424     alloc_size = 0;
00425     Data data = 0;
00426     offset = IDB_CLASS_IMPL_TYPE;
00427     Status s = IndexImpl::code(data, offset, alloc_size, *idximpl);
00428     if (s) return s;
00429 
00430     offset = IDB_CLASS_MTYPE;
00431     eyedblib::int32 mt = m_type;
00432     int32_code (&data, &offset, &alloc_size, &mt);
00433 
00434     offset = IDB_CLASS_DSPID;
00435     eyedblib::int16 dspid = get_instdspid();
00436     int16_code (&data, &offset, &alloc_size, &dspid);
00437 
00438     offset = IDB_CLASS_HEAD_SIZE;
00439   
00440     status = class_name_code(db->getDbHandle(), getDataspaceID(), &data, &offset,
00441                              &alloc_size, name);
00442     if (status) return status;
00443 
00444     int32_code  (&data, &offset, &alloc_size, &items_cnt);
00445   
00446     for (int i = 0; i < items_cnt; i++)
00447       {
00448         EnumItem *item = items[i];
00449         string_code (&data, &offset, &alloc_size, item->name);
00450         int32_code  (&data, &offset, &alloc_size, (eyedblib::int32 *)&item->value);
00451       }
00452 
00453     int idr_sz = offset;
00454     idr->setIDR(idr_sz, data);
00455     headerCode(_EnumClass_Type, idr_sz);
00456 
00457     RPCStatus rpc_status;
00458     rpc_status = objectCreate(db->getDbHandle(), getDataspaceID(), data, oid.getOid());
00459   
00460     if (rpc_status == RPCSuccess)
00461       {
00462         Status status;
00463 
00464         status = ClassPeer::makeColls(db, this, data, &oid);
00465         if (status != Success)
00466           return status;
00467       }
00468 
00469     if (rpc_status == RPCSuccess)
00470       gbx_locked = gbxTrue;
00471     return StatusMake(rpc_status);
00472   }
00473 
00474   Status EnumClass::update()
00475   {
00476     return Success;
00477   }
00478 
00479   Status EnumClass::remove(const RecMode*)
00480   {
00481     return Success;
00482   }
00483 
00484   Status EnumClass::trace_realize(FILE*, int, unsigned int flags, const RecMode *rcm) const
00485   {
00486     return Success;
00487   }
00488 
00489   int
00490   EnumClass::genODL(FILE *fd, Schema *) const
00491   {
00492     extern Bool odl_system_class;
00493      
00494     if (const_cast<EnumClass *>(this)->wholeComplete())
00495       return 0;
00496 
00497     if (isSystem() && !odl_system_class)
00498       return 0;
00499 
00500     fprintf(fd, "enum %s {\n", name);
00501 
00502     EnumItem **item;
00503     int n;
00504 
00505     for (n = 0, item = items; n < items_cnt; n++, item++)
00506       fprintf(fd, "\t%s = %d%s\n", (*item)->name, (*item)->value,
00507               ((n != items_cnt - 1) ? "," : ""));
00508     fprintf(fd, "};\n");
00509     return 1;
00510   }
00511 
00512   void
00513   EnumClass::touch()
00514   {
00515     Class::touch();
00516     LinkedList *cl_list = IteratorBE::getMclList();
00517     if (cl_list)
00518       cl_list->insertObjectLast(this);
00519   }
00520 
00521   void EnumClass::garbage()
00522   {
00523     free_items();
00524     Class::garbage();
00525   }
00526 
00527   EnumClass::~EnumClass()
00528   {
00529     garbageRealize();
00530   }
00531 
00532   EnumItem::EnumItem(const char *nm, unsigned int val, int _num)
00533   {
00534     name = strdup(nm);
00535     aliasname = 0;
00536     value = val;
00537     num = _num;
00538   }
00539 
00540   EnumItem::EnumItem(const char *nm, const char *_aliasname,
00541                      unsigned int val, int _num)
00542   {
00543     name = strdup(nm);
00544     aliasname = _aliasname ? strdup(_aliasname) : 0;
00545     value = val;
00546     num = _num;
00547   }
00548 
00549   EnumItem::EnumItem(const EnumItem *item, int n)
00550   {
00551     name = strdup(item->name);
00552     aliasname = item->aliasname ? strdup(item->aliasname) : 0;
00553     value = item->value;
00554     num = n;
00555   }
00556 
00557   EnumItem *
00558   EnumItem::clone() const
00559   {
00560     return new EnumItem(name, aliasname, value, num);
00561   }
00562 
00563   Bool
00564   EnumItem::compare(const EnumItem *item) const
00565   {
00566     if (num != item->num)
00567       return False;
00568     if (value != item->value)
00569       return False;
00570     if (strcmp(name, item->name))
00571       return False;
00572     /*
00573       if (strcmp(getAliasName(), item->getAliasName()))
00574       return False;
00575     */
00576 
00577     return True;
00578   }
00579 
00580 
00581   EnumItem::~EnumItem()
00582   {
00583     free(name);
00584     free(aliasname);
00585   }
00586 }

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