odbengine.c

Go to the documentation of this file.
00001 
00002 /*  $Id: odbengine.c 1236 2006-04-09 11:28:08Z andreradke $    */
00003 
00004 /******************************************************************************
00005 
00006     UserLand Frontier(tm) -- High performance Web content management,
00007     object database, system-level and Internet scripting environment,
00008     including source code editing and debugging.
00009 
00010     Copyright (C) 1992-2004 UserLand Software, Inc.
00011 
00012     This program is free software; you can redistribute it and/or modify
00013     it under the terms of the GNU General Public License as published by
00014     the Free Software Foundation; either version 2 of the License, or
00015     (at your option) any later version.
00016 
00017     This program is distributed in the hope that it will be useful,
00018     but WITHOUT ANY WARRANTY; without even the implied warranty of
00019     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00020     GNU General Public License for more details.
00021 
00022     You should have received a copy of the GNU General Public License
00023     along with this program; if not, write to the Free Software
00024     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00025 
00026 ******************************************************************************/
00027 
00028 #include "frontier.h"
00029 #include "standard.h"
00030 
00031 #include "memory.h"
00032 #include "dialogs.h"
00033 #include "file.h"
00034 #include "font.h"
00035 #include "resources.h"
00036 #include "ops.h"
00037 #include "quickdraw.h"
00038 #include "strings.h"
00039 #include "langexternal.h"
00040 #include "langinternal.h"
00041 #include "langipc.h"
00042 #include "tablestructure.h"
00043 #include "tableinternal.h"
00044 #include "shell.rsrc.h"
00045 #include "odbinternal.h"
00046 #ifdef isFrontier
00047     #include "shellprivate.h"
00048 #endif
00049 #include "timedate.h"
00050 #include "byteorder.h"  /* 2006-04-08 aradke: endianness conversion macros */
00051 
00052 
00053 typedef struct tycancoonrecord { /*one of these for every cancoon file that's open*/
00054 
00055     hdldatabaserecord hdatabase; /*db.c's record*/
00056     
00057     hdlhashtable hroottable; /*the root symbol table for this file*/
00058     
00059     Handle hrootvariable; /*the variable record for the root symbol table*/
00060     
00061     hdltablestack htablestack;
00062     
00063     boolean accesssing;
00064     
00065     #ifdef isFrontier
00066     
00067     WindowPtr shellwindow;
00068     
00069     #endif
00070     } tycancoonrecord, *ptrcancoonrecord, **hdlcancoonrecord;
00071 
00072 #define cancoonversionnumber 0x03
00073 
00074 
00075 #ifndef isFrontier
00076 
00077 boolean fldatabasesaveas;
00078 
00079 static byte canthandlethistypeerror [] = "\x43" "This version of ODB Engine can not get or set objects of this type.";
00080 
00081 #endif
00082 
00083 
00084 #define ctwindowinfo 6 /*number of windowinfo records saved in each cancoon record*/
00085 
00086 typedef struct tycancoonwindowinfo { /*lives both in memory and on disk*/   
00087     
00088     Rect windowrect;
00089     
00090     diskfontstring fontname; /*only maintained on disk*/
00091     
00092     short fontnum; /*only valid when it's in memory*/
00093     
00094     short fontsize, fontstyle;
00095     
00096     WindowPtr w; /*only valid when it's in memory*/
00097     
00098     char waste [10];
00099     } tycancoonwindowinfo;
00100 
00101 
00102 typedef struct tyversion2cancoonrecord {
00103     
00104     short versionnumber;
00105     
00106     dbaddress adrroottable;
00107     
00108     tycancoonwindowinfo windowinfo [ctwindowinfo];
00109     
00110     dbaddress adrscriptstring; /*the string that appears in the quickscript window*/
00111     
00112     unsigned short flags;
00113     
00114     short ixprimaryagent;
00115     
00116     short waste [28]; /*room to grow*/
00117     } tyversion2cancoonrecord;
00118 
00119 #ifdef MACVERSION
00120     #define flflagdisabled_mask 0x8000 /*hide the flag?*/
00121     #define flpopupdisabled_mask 0x4000 /*hide the agents popup menu?*/
00122     #define flbigwindow_mask 0x2000 /*is the flag toggled to the big window state?*/
00123 #endif
00124 
00125 #ifdef WIN95VERSION
00126     #define flflagdisabled_mask 0x0080 /*hide the flag?*/
00127     #define flpopupdisabled_mask 0x0040 /*hide the agents popup menu?*/
00128     #define flbigwindow_mask 0x0020 /*is the flag toggled to the big window state?*/
00129 #endif
00130 
00131 static bigstring bserror = "\0";
00132 
00133 static hdlcancoonrecord cancoonglobals = nil;
00134 
00135 #ifndef isFrontier
00136 
00137 boolean alertdialog (bigstring bs) {
00138     
00139     copystring (bs, bserror);
00140     
00141     return (true);
00142     } /*alertdialog*/
00143 
00144 #endif
00145 
00146 static boolean disposecancoonrecord (hdlcancoonrecord hcancoon) {
00147     
00148     /*
00149     5.0.1 dmb: fixed leak - use tabledisposetable, not disposehashtable
00150     */
00151     
00152     hdlcancoonrecord hc = hcancoon;
00153     
00154     if (hc == nil)
00155         return (false);
00156     
00157     if (!(**hc).accesssing) {
00158         
00159         cleartablestructureglobals ();  /*do this now to avoid debug check in disposehashtable*/
00160         
00161         tabledisposetable ((**hc).hroottable, false); /*yup, checks for nil*/
00162         
00163         disposehandle ((Handle) (**hc).hrootvariable); /*1.0b2 dmb: site of memory leak*/
00164         }
00165     
00166     disposehandle ((Handle) (**hc).htablestack);
00167     
00168     disposehandle ((Handle) hc);
00169     
00170     return (true);
00171     } /*disposecancoonrecord*/
00172 
00173 
00174 static boolean newcancoonrecord (hdlcancoonrecord *hcancoon) {
00175     
00176     hdlcancoonrecord hc;
00177     hdltablestack htablestack;
00178     
00179     if (!newclearhandle (sizeof (tycancoonrecord), (Handle *) hcancoon))
00180         return (false);
00181     
00182     hc = *hcancoon;
00183     
00184     if (!newclearhandle (sizeof (tytablestack), (Handle *) &htablestack)) {
00185         
00186         disposehandle ((Handle) hc);
00187         
00188         return (false);
00189         }
00190     
00191     (**hc).htablestack = htablestack;
00192 
00193     return (true);
00194     } /*newcancoonrecord*/
00195 
00196 
00197 static boolean ccloadsystemtable (hdlcancoonrecord hcancoon, dbaddress adr) {
00198     
00199     /*
00200     1.0b2 dmb: we don't rely on the system table, so don't force 
00201     its creation by calling settablestructureglobals.
00202     */
00203     
00204     hdlcancoonrecord hc = hcancoon;
00205     boolean fl;
00206     Handle hvariable;
00207     hdlhashtable htable;
00208     
00209     hashtablestack = (**hc).htablestack;
00210     
00211     fl = tableloadsystemtable (adr, &hvariable, &htable, false);
00212     
00213     if (fl) {
00214         
00215         cleartablestructureglobals ();
00216         
00217         (**hc).hrootvariable = rootvariable = hvariable;
00218         
00219         (**hc).hroottable = roottable = htable;
00220         
00221         assert (tablevalidate (htable, true));
00222         
00223         /*
00224         fl = settablestructureglobals (hvariable, true);
00225         */
00226         
00227         currenthashtable = roottable;
00228         }
00229     
00230     return (fl);
00231     } /*ccloadsystemtable*/
00232 
00233 
00234 static boolean odberrorroutine (bigstring bs, ptrvoid refcon) {
00235 #pragma unused (refcon)
00236 
00237     copystring (bs, bserror);
00238     
00239     return (false); /*consume the error*/
00240     } /*odberrorroutine*/
00241 
00242 
00243 static void setcancoonglobals (hdlcancoonrecord hcancoon) {
00244     
00245     hdlcancoonrecord hc = hcancoon;
00246     
00247 #ifndef isFrontier
00248 
00249     if (hc != cancoonglobals) 
00250     
00251 #endif
00252         {
00253         databasedata = (**hc).hdatabase;
00254         
00255         hashtablestack = (**hc).htablestack;
00256         
00257         settablestructureglobals ((**hc).hrootvariable, false);
00258         
00259         currenthashtable = roottable;
00260         
00261         cancoonglobals = hc; /*this global is independent of shellpush/popglobals*/
00262         
00263         langcallbacks.errormessagecallback = &odberrorroutine;
00264         }
00265     } /*setcancoonglobals*/
00266 
00267 
00268 static void clearcancoonglobals (void) {
00269     
00270     databasedata = nil; /*db.c*/
00271     
00272     cleartablestructureglobals (); /*tablestructure.c: roottable, handlertable, etc.*/
00273     
00274     currenthashtable = nil;
00275     
00276     cancoonglobals = nil; /*our very own superglobal*/
00277     
00278     hashtablestack = nil;
00279     } /*clearcancoonglobals*/
00280 
00281 
00282 static boolean loadversion2cancoonfile (dbaddress adr, hdlcancoonrecord hcancoon) {
00283     
00284     tyversion2cancoonrecord info;
00285     
00286     if (!dbreference (adr, sizeof (info), &info))
00287         return (false);
00288     
00289     /* only variable used here! */
00290     disktomemlong (info.adrroottable);
00291 
00292     if (!ccloadsystemtable (hcancoon, info.adrroottable))
00293         return (false);
00294     
00295     assert ((**cancoonglobals).hroottable == roottable); /*should already be set up*/
00296     
00297     return (true);
00298     } /*loadversion2cancoonfile*/
00299 
00300 
00301 #ifndef isFrontier
00302 
00303     static short tablecomparenames (hdlhashtable ht, hdlhashnode hnode1, hdlhashnode hnode2) {
00304 
00305         bigstring bs1, bs2;
00306         
00307         gethashkey (hnode1, bs1);
00308 
00309         gethashkey (hnode2, bs2);
00310         
00311         alllower (bs1); /*comparison is unicase*/
00312         
00313         alllower (bs2);
00314         
00315         return (comparestrings (bs1, bs2));
00316         } /*tablecomparenames*/
00317 
00318 
00319     static boolean odbtabledirty (hdlhashtable htable, const bigstring bsname) {
00320         
00321     //  hdltablediskrecord hf = (hdltablediskrecord) (**htable).hashtableformats;
00322         
00323     //  if (hf != nil)
00324         (**htable).timelastsave = timenow (); /*modification time until saved*/
00325         
00326         return (true);
00327         } /*tabledirty*/
00328 
00329     static boolean odbsymbolchanged (hdlhashtable htable, const bigstring bsname, hdlhashnode hnode, boolean flvalue) {
00330         
00331         return (odbtabledirty (htable, bsname));
00332         } /*odbsymbolchanged*/
00333 
00334     static boolean odbsymbolunlinking (hdlhashtable ht, hdlhashnode hn) {
00335 
00336         return (true);
00337         } /*odbsymbolunlinking*/
00338 
00339 
00340     static void initlangcallbacks (void) {
00341 
00342         langcallbacks.symbolchangedcallback = &odbsymbolchanged; 
00343         
00344         langcallbacks.symboldeletedcallback = &odbtabledirty;
00345         
00346         langcallbacks.symbolinsertedcallback = &odbtabledirty;
00347         
00348         langcallbacks.symbolunlinkingcallback = &odbsymbolunlinking;
00349         
00350         langcallbacks.comparenodescallback = &tablecomparenames;
00351         }  /*initlangcallbacks*/
00352 
00353     #define odbexpandtodotparams(bs, htable, bsname) langexpandtodotparams(bs, htable, bsname)
00354 
00355 #else
00356 
00357     static boolean odbexpandtodotparams (bigstring bs, hdlhashtable *htable, bigstring bsname) {
00358         
00359         /*
00360         the odbengine version of langexpandtodotparams gaurantees that htable 
00361         will be non-nil. the frontier version doesn't. if we have just a name, 
00362         we interpret it as a root-level item
00363         */
00364         
00365         boolean fl;
00366         
00367         disablelangerror ();
00368         
00369         fl = langexpandtodotparams (bs, htable, bsname);
00370         
00371         enablelangerror ();
00372         
00373         if (!fl) {
00374             
00375             langparamerror (addresscoerceerror, bs);
00376             
00377             return (false);
00378             }
00379         
00380         if (*htable == nil)
00381             langsearchpathlookup (bsname, htable); /*always sets htable*/
00382         
00383         return (true);
00384         } /*odbexpandtodotparams*/
00385 
00386 #endif
00387 
00388 
00389 static boolean odbvaltotable (tyvaluerecord val, hdlhashtable *htable, hdlhashnode hnode) {
00390     
00391     if (!langexternalvaltotable (val, htable, hnode)) {
00392         
00393         bigstring bs;
00394         
00395         getstringlist (tableerrorlist, namenottableerror, bs);
00396         
00397         langerrormessage (bs);
00398         
00399         return (false);
00400         }
00401     
00402     return (true);      
00403     } /*odbvaltotable*/
00404 
00405 #ifdef isFrontier
00406 pascal boolean odbUpdateOdbref (WindowPtr w, odbref odb) {
00407     hdlcancoonrecord hc;
00408     
00409     setemptystring (bserror);
00410     
00411     hc = (hdlcancoonrecord) odb;
00412     
00413     if (w != NULL) {
00414         shellpushglobals (w);
00415     
00416         (*shellglobals.setsuperglobalsroutine) ();
00417         }
00418     
00419     (**hc).hdatabase = databasedata; /*current database*/
00420     
00421     (**hc).hroottable = roottable; /*current root table*/
00422     
00423     (**hc).hrootvariable = rootvariable; /*current root variable*/
00424     
00425     (**hc).shellwindow = shellwindow;
00426     
00427     (**hc).accesssing = true;
00428         
00429     if (w != NULL) {
00430         shellpopglobals ();
00431     
00432         (*shellglobals.setsuperglobalsroutine) ();  
00433         }
00434     
00435     return (true);
00436     } /*odbUpdateOdbref*/
00437 
00438 pascal boolean odbAccessWindow (WindowPtr w, odbref *odb) {
00439     
00440     /*
00441     4.1b5 dmb: new entrypoint
00442     
00443     for the db verbs withing frontier, we need to be able to "open" a 
00444     database that is already open. We keep our own hashtablestack; that's
00445     our context. But the root table and variable and the database are just 
00446     borrowed from the given root window.
00447     */
00448         
00449     setemptystring (bserror);
00450     
00451     if (!newcancoonrecord (&cancoonglobals))
00452         return (false);
00453     
00454     *odb = (odbref) cancoonglobals;
00455     
00456     odbUpdateOdbref (w, *odb);
00457     return (true);
00458     } /*odbAccess*/
00459 
00460 #endif
00461 
00462 
00463 pascal boolean odbNewFile (hdlfilenum fnum) {
00464     
00465     /*
00466     4.1b5 dmb: new routine. minimal db creation. does not leave it open
00467     */
00468     
00469     tyversion2cancoonrecord info;
00470     dbaddress adr = nildbaddress;
00471     boolean fl;
00472     
00473     setemptystring (bserror);
00474     
00475     if (!dbnew (fnum))
00476         return (false);
00477     
00478     clearbytes (&info, sizeof (info));
00479     
00480     info.versionnumber = conditionalshortswap (cancoonversionnumber);
00481     
00482     fl = dbassign (&adr, sizeof (info), &info);
00483     
00484     if (fl) {
00485         
00486         dbsetview (cancoonview, adr);
00487         
00488         dbclose ();
00489         }
00490     
00491     cancoonglobals = nil;   /*if they've been set, they're out of date*/
00492     
00493     dbdispose ();
00494     
00495     return (fl);
00496     } /*odbNewFile*/
00497 
00498 
00499 pascal boolean odbOpenFile (hdlfilenum fnum, odbref *odb, boolean flreadonly) {
00500     
00501     hdlcancoonrecord hc = nil;
00502     dbaddress adr;
00503     short versionnumber;
00504     
00505     setemptystring (bserror);
00506     
00507     #ifndef isFrontier
00508     
00509         initlangcallbacks ();
00510     
00511     #endif
00512     
00513     if (!dbopenfile (fnum, flreadonly))
00514         return (false);
00515     
00516     dbgetview (cancoonview, &adr);
00517     
00518     if (!dbreference (adr, sizeof (versionnumber), &versionnumber))
00519         goto error;
00520     
00521     disktomemshort (versionnumber);
00522     
00523     if (!newcancoonrecord (&cancoonglobals))
00524         goto error;
00525     
00526     hc = cancoonglobals;
00527     
00528     (**hc).hdatabase = databasedata; /*result from dbopenfile*/
00529     
00530     switch (versionnumber) {
00531         
00532         case 2:
00533         case cancoonversionnumber:
00534             if (!loadversion2cancoonfile (adr, hc))
00535                 goto error;
00536             
00537             *odb = (odbref) hc;
00538             
00539             return (true);
00540             
00541         default:
00542             alertdialog ((ptrstring) "\x59" "The version number of this database file is not recognized by this version of Frontier.");
00543             
00544             goto error;
00545         } /*switch*/
00546     
00547     error:
00548     
00549     dbdispose ();
00550     
00551     disposecancoonrecord (hc); /*checks for nil*/
00552     
00553     clearcancoonglobals ();
00554     
00555     return (false);
00556     } /*odbOpenFile*/
00557 
00558 
00559 pascal boolean odbSaveFile (odbref odb) {
00560     
00561     hdlcancoonrecord hc = (hdlcancoonrecord) odb;
00562     tyversion2cancoonrecord info;
00563     dbaddress adr;
00564     
00565     setemptystring (bserror);
00566     
00567     setcancoonglobals (hc);
00568     
00569     #ifdef isFrontier
00570     
00571     if ((**hc).accesssing) {
00572         
00573         return (shellsave ((**hc).shellwindow));
00574         }
00575     
00576     #endif
00577     
00578     dbgetview (cancoonview, &adr);
00579     
00580     if (adr == nildbaddress)
00581         return (false);
00582     
00583     if (!dbreference (adr, sizeof (info), &info))
00584         return (false); 
00585     
00586     info.versionnumber = conditionalshortswap (cancoonversionnumber);
00587     
00588     if (!tablesavesystemtable ((**hc).hrootvariable, &info.adrroottable))
00589         return (false);
00590     
00591     memtodisklong (info.adrroottable);
00592 
00593     clearbytes (&info.waste, sizeof (info.waste));
00594     
00595     if (!dbassign (&adr, sizeof (info), &info))
00596         return (false);
00597     
00598     dbflushreleasestack (); /*release all the db objects that were saved up*/
00599     
00600     dbsetview (cancoonview, adr);
00601     
00602     return (true);
00603     } /*odbSaveFile*/
00604 
00605 
00606 pascal boolean odbCloseFile (odbref odb) {
00607     
00608     /*
00609     1/22/91 dmb: added scan of new ccglobalsstack
00610     
00611     2/26/93 dmb: support shutdown scripts
00612     */
00613     
00614     hdlcancoonrecord hc = (hdlcancoonrecord) odb;
00615     
00616     setemptystring (bserror);
00617     
00618     if (hc == nil) /*nothing to do*/
00619         return (true);
00620     
00621     setcancoonglobals (hc);
00622     
00623     if (!(**hc).accesssing)
00624         dbdispose (); /*do before clearing globals -- depends on databasedata*/
00625     
00626     disposecancoonrecord (hc);
00627     
00628     clearcancoonglobals ();
00629     
00630     return (true);
00631     } /*odbCloseFile*/
00632 
00633 
00634 pascal boolean odbDefined (odbref odb, bigstring bspath) {
00635 
00636     /*
00637     4.1b5 dmb: new routine
00638     */
00639     
00640     hdlhashtable htable;
00641     bigstring bsname;
00642     boolean fl;
00643     
00644     setemptystring (bserror);
00645     
00646     setcancoonglobals ((hdlcancoonrecord) odb);
00647     
00648     disablelangerror ();
00649     
00650     fl = odbexpandtodotparams (bspath, &htable, bsname);
00651     
00652     enablelangerror ();
00653     
00654     if (fl) {
00655         
00656         pushhashtable (htable);
00657         
00658         fl = hashsymbolexists (bsname);
00659         
00660         pophashtable ();
00661         }
00662     
00663     return (fl);
00664     } /*odbDefined*/
00665 
00666 
00667 pascal boolean odbDelete (odbref odb, bigstring bspath) {
00668 
00669     hdlhashtable htable;
00670     bigstring bsname;
00671     
00672     setemptystring (bserror);
00673     
00674     setcancoonglobals ((hdlcancoonrecord) odb);
00675     
00676     if (!odbexpandtodotparams (bspath, &htable, bsname))
00677         return (false);
00678     
00679     return (hashtabledelete (htable, bsname));
00680     } /*odbDelete*/
00681 
00682 
00683 pascal boolean odbGetType (odbref odb, bigstring bspath, OSType *odbType) {
00684     
00685     hdlhashtable htable;
00686     bigstring bsname;
00687     tyvaluerecord val;
00688     hdlhashnode hnode;
00689     
00690     setemptystring (bserror);
00691     
00692     setcancoonglobals ((hdlcancoonrecord) odb);
00693     
00694     if (!odbexpandtodotparams (bspath, &htable, bsname))
00695         return (false);
00696     
00697     if (!langsymbolreference (htable, bsname, &val, &hnode))
00698         return (false);
00699     
00700     if (val.valuetype == binaryvaluetype)
00701         *odbType = getbinarytypeid (val.data.binaryvalue);
00702     else
00703         *odbType = langexternalgettypeid (val);
00704     
00705     return (true);
00706     } /*odbGetType*/
00707 
00708 
00709 pascal boolean odbGetValue (odbref odb, bigstring bspath, odbValueRecord *value) {
00710 
00711     hdlhashtable htable;
00712     bigstring bsname;
00713     tyvaluerecord val;
00714     hdlhashnode hnode;
00715     
00716     setemptystring (bserror);
00717     
00718     setcancoonglobals ((hdlcancoonrecord) odb);
00719     
00720     if (!odbexpandtodotparams (bspath, &htable, bsname))
00721         return (false);
00722     
00723     if (!langsymbolreference (htable, bsname, &val, &hnode))
00724         return (false);
00725     
00726     #ifndef isFrontier
00727 
00728     if (val.valuetype == externalvaluetype) {
00729         
00730         langerrormessage (canthandlethistypeerror);
00731         
00732         return (false);
00733         }
00734     
00735     #endif
00736     
00737     if (!copyvaluerecord (val, &val))
00738         return (false);
00739     
00740     if (!copyvaluedata (&val))
00741         return (false);
00742     
00743     exemptfromtmpstack (&val);
00744     
00745     (*value).valuetype = (odbValueType) langexternalgettypeid (val);
00746     
00747     /*
00748     if (val.valuetype == binaryvaluetype)
00749         pullfromhandle (val.data.binaryvalue, 0L, sizeof (typeid), &(*value).valuetype);
00750     */
00751     
00752     (*value).data.binaryvalue = val.data.binaryvalue; /*largest field covers everything*/
00753     
00754     return (true);
00755     } /*odbGetValue*/
00756 
00757 
00758 pascal boolean odbSetValue (odbref odb, bigstring bspath, odbValueRecord *value) {
00759 
00760     hdlhashtable htable;
00761     bigstring bsname;
00762     tyvaluerecord val;
00763     tyvaluetype type = langexternalgetvaluetype (value->valuetype);
00764     
00765     setemptystring (bserror);
00766     
00767     #ifndef isFrontier
00768     
00769     if (type == externalvaluetype) {
00770         
00771         langerrormessage (canthandlethistypeerror);
00772         
00773         return (false);
00774         }
00775     
00776     #endif
00777     
00778     setcancoonglobals ((hdlcancoonrecord) odb);
00779     
00780     if (!odbexpandtodotparams (bspath, &htable, bsname))
00781         return (false);
00782     
00783     if (type == (tyvaluetype) -1) {
00784     
00785         if (!setbinaryvalue (value->data.binaryvalue, value->valuetype, &val))
00786             return (false);
00787         }
00788     else {
00789     
00790         initvalue (&val, type);
00791         
00792         val.data.binaryvalue = value->data.binaryvalue;
00793         }
00794     
00795     if (!copyvaluerecord (val, &val))
00796         return (false);
00797     
00798     if (!hashtableassign (htable, bsname, val)) {
00799     
00800         disposevaluerecord (val, true);
00801         
00802         return (false);
00803         }
00804     
00805     exemptfromtmpstack (&val);
00806     
00807     return (true);  
00808     } /*odbSetValue*/
00809 
00810 
00811 pascal boolean odbNewTable (odbref odb, bigstring bspath) {
00812 
00813     hdlhashtable htable;
00814     bigstring bsname;
00815     tyvaluerecord val;
00816     
00817     setemptystring (bserror);
00818     
00819     setcancoonglobals ((hdlcancoonrecord) odb);
00820     
00821     if (!odbexpandtodotparams (bspath, &htable, bsname))
00822         return (false);
00823     
00824     if (!langexternalnewvalue (idtableprocessor, nil, &val))
00825         return (false);
00826     
00827     if (!hashtableassign (htable, bsname, val)) {
00828     
00829         disposevaluerecord (val, true);
00830         
00831         return (false);
00832         }
00833     
00834     exemptfromtmpstack (&val);
00835     
00836     return (true);  
00837     } /*odbNewTable*/
00838 
00839 
00840 pascal boolean odbCountItems (odbref odb, bigstring bspath, long *count) {
00841 
00842     hdlhashtable htable;
00843     bigstring bsname;
00844     tyvaluerecord val;
00845     long ctitems;
00846     hdlhashnode hnode;
00847     
00848     setemptystring (bserror);
00849     
00850     setcancoonglobals ((hdlcancoonrecord) odb);
00851     
00852     if (!odbexpandtodotparams (bspath, &htable, bsname))
00853         return (false);
00854     
00855     if (!langsymbolreference (htable, bsname, &val, &hnode))
00856         return (false);
00857     
00858     if (!odbvaltotable (val, &htable, hnode))
00859         return (false);
00860     
00861     if (!hashcountitems (htable, &ctitems))
00862         return (false);
00863     
00864     *count = ctitems;
00865     
00866     return (true);
00867     } /*odbCountItems*/
00868 
00869 
00870 pascal boolean odbGetNthItem (odbref odb, bigstring bspath, long n, bigstring bsname) {
00871 
00872     hdlhashtable htable;
00873     tyvaluerecord val;
00874     hdlhashnode hnode;
00875     
00876     setemptystring (bserror);
00877     
00878     setcancoonglobals ((hdlcancoonrecord) odb);
00879     
00880     if (!odbexpandtodotparams (bspath, &htable, bsname))
00881         return (false);
00882     
00883     if (!langsymbolreference (htable, bsname, &val, &hnode))
00884         return (false);
00885     
00886     if (!odbvaltotable (val, &htable, hnode))
00887         return (false);
00888     
00889     if (!hashgetiteminfo (htable, (short) (n - 1), bsname, nil))
00890         return (false);
00891     
00892     return (true);
00893     } /*odbGetNthItem*/
00894 
00895 
00896 
00897 pascal boolean odbGetModDate (odbref odb, bigstring bspath, unsigned long *date) {
00898 
00899     hdlhashtable htable;
00900     bigstring bsname;
00901     tyvaluerecord val;
00902     hdlhashnode hnode;
00903     
00904     setemptystring (bserror);
00905     
00906     setcancoonglobals ((hdlcancoonrecord) odb);
00907     
00908     if (!odbexpandtodotparams (bspath, &htable, bsname))
00909         return (false);
00910     
00911     if (!langsymbolreference (htable, bsname, &val, &hnode))
00912         return (false);
00913     
00914     if (!odbvaltotable (val, &htable, hnode))
00915         return (false);
00916     
00917     *date = (**htable).timelastsave;
00918     
00919     return (true);
00920     } /*odbGetModDate*/
00921 
00922 
00923 pascal void odbDisposeValue (odbref odb, odbValueRecord *value) {
00924     
00925     tyvaluetype type;
00926     tyvaluerecord val;
00927     
00928     setemptystring (bserror);
00929     
00930     setcancoonglobals ((hdlcancoonrecord) odb);
00931     
00932     type = langexternalgetvaluetype ((OSType) (*value).valuetype);
00933     
00934     if (type == -1) /*no match; must have been a binary value*/
00935         type = binaryvaluetype;
00936     
00937     initvalue (&val, type);
00938     
00939     val.data.binaryvalue = (*value).data.binaryvalue;
00940     
00941     disposevaluerecord (val, false);
00942     } /*odbDisposeValue*/
00943 
00944 
00945 pascal void odbGetError (bigstring bs) {
00946 
00947     copystring (bserror, bs);
00948     } /*odbGetError*/
00949 
00950 
00951 

Generated on Wed May 31 18:19:56 2006 for frontierkernel 10.1.10a by  doxygen 1.4.6