home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / modules / rdf / src / nlcstore.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  22.9 KB  |  870 lines

  1. /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  2.  *
  3.  * The contents of this file are subject to the Netscape Public License
  4.  * Version 1.0 (the "NPL"); you may not use this file except in
  5.  * compliance with the NPL.  You may obtain a copy of the NPL at
  6.  * http://www.mozilla.org/NPL/
  7.  *
  8.  * Software distributed under the NPL is distributed on an "AS IS" basis,
  9.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
  10.  * for the specific language governing rights and limitations under the
  11.  * NPL.
  12.  *
  13.  * The Initial Developer of this code under the NPL is Netscape
  14.  * Communications Corporation.  Portions created by Netscape are
  15.  * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
  16.  * Reserved.
  17.  */
  18.  
  19. /* 
  20.    This file implements local store support for the rdf data model.
  21.    For more information on this file, contact rjc or guha 
  22.    For more information on RDF, look at the RDF section of www.mozilla.org
  23. */
  24.  
  25. #include "nlcstore.h"
  26. #include "glue.h"
  27. #include "mcf.h"
  28. #include "xpassert.h"
  29.  
  30.  
  31.     /* globals */
  32. PRBool doingFirstTimeInitp = 0;
  33. RDFT gOPSStore = 0;
  34. RDFT gLocalStore = 0;
  35.  
  36.  
  37.     /* externs */
  38. extern char *profileDirURL;
  39. extern char *gBookmarkURL;
  40.  
  41.  
  42.  
  43. /* 
  44.  
  45. To do : killing a unit
  46.  
  47. */
  48.  
  49.  
  50.  
  51. PRBool
  52. compareUnalignedUINT32Ptrs(void *v1, void *v2)
  53. {
  54.     uint32        val1, val2;
  55.  
  56.     memcpy(&val1,v1,sizeof(uint32));
  57.     memcpy(&val2,v2,sizeof(uint32));
  58.     return((val1==val2) ? PR_TRUE:PR_FALSE);
  59. }
  60.  
  61.  
  62.  
  63. char *
  64. makeRDFDBURL(char* directory, char* name)
  65. {
  66.   char        *ans;
  67.   size_t        s;
  68.   
  69.   if (profileDirURL == NULL) return NULL;
  70.   if ((ans = (char*) getMem(strlen(profileDirURL) + strlen(directory) + strlen(name) + 3)) != NULL) {
  71.     s = strlen(profileDirURL);
  72.     memcpy(ans, profileDirURL, s);
  73.     if (ans[s-1] != '/') {
  74.       ans[s++] = '/';
  75.     }
  76.     stringAppend(ans, directory);
  77.     stringAppend(ans, "/");
  78.     stringAppend(ans, name);
  79.   }
  80.   return(ans);
  81. }
  82.  
  83.  
  84.  
  85. void
  86. readInBookmarksOnInit(RDFFile f)
  87. {
  88.   RDF_Resource ptFolder;
  89.   PRFileDesc *fp;
  90.   int32 len;
  91.   char buf[512];
  92.   fp = CallPROpenUsingFileURL(f->url, PR_RDONLY|PR_CREATE_FILE, 0644);
  93.   if (fp == NULL) return;
  94.   while((len=PR_Read(fp, buf, sizeof(buf))) >0) {
  95.     parseNextBkBlob(f, buf, len);
  96.   }
  97.  
  98.   /* if no personal toolbar was specified in bookmark file, create one */
  99.  
  100.   ptFolder = nlocalStoreGetSlotValue(f->db, gNavCenter->RDF_PersonalToolbarFolderCategory,
  101.         gCoreVocab->RDF_instanceOf, RDF_RESOURCE_TYPE, true, true);
  102.  
  103.   if (ptFolder == NULL)
  104.   {
  105.       if ((ptFolder = createContainer("personaltoolbar.rdf")) != NULL)
  106.       {
  107.         addSlotValue(f, ptFolder, gCoreVocab->RDF_parent,
  108.             gNavCenter->RDF_BookmarkFolderCategory,
  109.             RDF_RESOURCE_TYPE, true);
  110.         /* XXX localization */
  111.           addSlotValue(f, ptFolder, gCoreVocab->RDF_name,
  112.               "Personal Toolbar", RDF_STRING_TYPE, true );
  113.         RDFUtil_SetPTFolder(ptFolder);
  114.       }
  115.   }
  116.  
  117.   PR_Close(fp);
  118.   freeMem(f->line);
  119.   freeMem(f->currentSlot);
  120.   freeMem(f->holdOver);
  121. }
  122.  
  123.  
  124.  
  125. void
  126. DBM_OpenDBMStore (DBMRDF store, char* directory)
  127. {
  128.   HASHINFO hash_info = {128, 0, 0, 0, 0, 0};  
  129.   PRBool createp = 0;
  130.   char* dbPathname;
  131.   char* dirPathname;
  132.   CHECK_VAR1(profileDirURL);
  133.   dirPathname = makeDBURL(directory);
  134.   CallPRMkDirUsingFileURL(dirPathname, 00700);  
  135.  
  136.   dbPathname =  makeRDFDBURL(directory, "names.db");
  137.   CHECK_VAR1(dbPathname);
  138.   store->nameDB    = CallDBOpenUsingFileURL(dbPathname, O_RDWR, 0644, DB_HASH, &hash_info);
  139.   if (store->nameDB == NULL) {
  140.     createp = 1;
  141.     store->nameDB    = CallDBOpenUsingFileURL(dbPathname, O_RDWR | O_CREAT, 0644, DB_HASH, &hash_info);
  142.   }
  143.   freeMem(dbPathname);
  144.   CHECK_VAR1(store->nameDB);
  145.   dbPathname = makeRDFDBURL(directory, "child.db");
  146.   CHECK_VAR1(dbPathname);
  147.   hash_info.bsize = 2056;
  148.   store->childrenDB    = CallDBOpenUsingFileURL(dbPathname, 
  149.              O_RDWR | O_CREAT, 0644, DB_HASH, &hash_info);
  150.   freeMem(dbPathname);
  151.   CHECK_VAR1(store->childrenDB);
  152.  
  153.   dbPathname = makeRDFDBURL(directory, "lstr.db");
  154.   hash_info.bsize = 1024  ;
  155.   store->propDB   = CallDBOpenUsingFileURL(dbPathname,
  156.             O_RDWR | O_CREAT, 0644, DB_HASH, &hash_info);
  157.   freeMem(dbPathname);
  158.   CHECK_VAR1(store->propDB);
  159.  
  160.   dbPathname =  makeRDFDBURL(directory, "ilstr.db");
  161.   CHECK_VAR1(dbPathname);
  162.   hash_info.bsize = 1024*16;
  163.   store->invPropDB   = CallDBOpenUsingFileURL(dbPathname,
  164.                O_RDWR | O_CREAT, 0644, DB_HASH, &hash_info);
  165.   freeMem(dbPathname);
  166.   CHECK_VAR1(store->invPropDB);
  167.   
  168.   if (createp && (strcmp(directory, "NavCen") == 0)) {
  169.     PRBool nlocalStoreAssert1 (RDFFile f, RDFT rdf, RDF_Resource u, RDF_Resource s, void* v, 
  170.              RDF_ValueType type, PRBool tv) ;
  171.     RDFFile newFile;
  172.     doingFirstTimeInitp = 1;
  173.     newFile = makeRDFFile(gBookmarkURL, RDF_GetResource(NULL, "NC:Bookmarks", true), true);
  174.     newFile->fileType = RDF_BOOKMARKS;
  175.     newFile->db = gLocalStore;
  176.     newFile->assert = nlocalStoreAssert1;
  177.     readInBookmarksOnInit(newFile);
  178.     doingFirstTimeInitp = 0;
  179.     (*store->propDB->sync)(store->propDB, 0);
  180.     (*store->invPropDB->sync)(store->invPropDB, 0);
  181.     (*store->nameDB->sync)(store->nameDB, 0);
  182.     (*store->childrenDB->sync)(store->childrenDB, 0); 
  183.   }
  184. }
  185.  
  186.  
  187.  
  188. RDF_Error
  189. DBM_CloseRDFDBMStore (RDFT r)
  190. {
  191.   
  192.   DBMRDF db = (DBMRDF)r->pdata;
  193.    if (r->rdf) return 0;
  194.   if (db->nameDB != NULL)        (*db->nameDB->close)(db->nameDB);
  195.   if (db->childrenDB != NULL)    (*db->childrenDB->close)(db->childrenDB);
  196.   if (db->propDB != NULL)        (*db->propDB->close)(db->propDB);
  197.   if (db->invPropDB != NULL)    (*db->invPropDB->close)(db->invPropDB);
  198.   freeMem(db);
  199.   r->pdata = NULL;
  200.   return 0;
  201. }
  202.  
  203.  
  204.  
  205. char *
  206. makeUSKey (RDF_Resource u, RDF_Resource s, PRBool inversep, size_t *size)
  207. {
  208.   if ((s == gCoreVocab->RDF_name) || (inversep && (s == gCoreVocab->RDF_parent))) {
  209.     *size = strlen(resourceID(u));
  210.     return  resourceID(u);
  211.   } else {
  212.     char* ans;
  213.     *size =  strlen(resourceID(u)) + strlen(resourceID(s));
  214.     ans = getMem(*size);  
  215.     memcpy(ans, resourceID(u), strlen(resourceID(u)));
  216.     memcpy(&ans[strlen(resourceID(u))],  resourceID(s), strlen(resourceID(s)));
  217.     return ans;
  218.   }
  219. }
  220.  
  221.  
  222.  
  223. DB *
  224. getUSDB (RDFT r, RDF_Resource u, RDF_Resource s, PRBool inversep)
  225. {
  226.   DBMRDF db = (DBMRDF)r->pdata;
  227.   if (inversep) {
  228.     if (s == gCoreVocab->RDF_parent) {
  229.       return db->childrenDB;
  230.     } else {
  231.       return db->invPropDB;
  232.     }
  233.   } else if (s == gCoreVocab->RDF_name) {
  234.     return db->nameDB;
  235.   } else return db->propDB;
  236. }
  237.  
  238.  
  239.  
  240. void
  241. freeKey (char* keyData, RDF_Resource u, RDF_Resource s, PRBool inversep)
  242. {
  243.   if ((s == gCoreVocab->RDF_name) || (inversep && (s == gCoreVocab->RDF_parent))) return;
  244.   freeMem(keyData);
  245. }
  246.  
  247.  
  248.  
  249. DBMAs *
  250. DBM_GetSlotValue (RDFT rdf, RDF_Resource u, RDF_Resource s, PRBool inversep, size_t *size)
  251. {
  252.   size_t keySize;
  253.   void* keyData = makeUSKey(u, s, inversep, &keySize);
  254.   DBT key, data;
  255.   DB *db;
  256.   int status;
  257.   CHECK_VAR(keyData, NULL);
  258.   key.data = keyData;
  259.   key.size = keySize;
  260.   db = getUSDB(rdf, u, s, inversep);
  261.   if (db == NULL) {
  262.     XP_ASSERT(db);
  263.     *size = 0;
  264.     freeKey(keyData, u, s, inversep);
  265.     return NULL;
  266.   }
  267.   status = (*db->get)(db, &key, &data, 0);
  268.   if (status != 0) {
  269.     *size = 0;
  270.     freeKey(keyData, u, s, inversep);
  271.     return NULL;
  272.   } else {
  273.     void* ans = (char*)getMem(data.size);
  274.     *size = data.size;
  275.     memcpy(ans, data.data, *size);
  276.     freeKey(keyData, u, s, inversep);
  277.     return (DBMAs*) ans;
  278.   }
  279. }
  280.  
  281.  
  282.  
  283. void
  284. DBM_PutSlotValue (RDFT rdf, RDF_Resource u, RDF_Resource s, PRBool inversep, void* value, size_t size)
  285. {
  286.   size_t keySize;
  287.   void* keyData = makeUSKey(u, s, inversep, &keySize);
  288.   DBT key, data;
  289.   int status;
  290.   DB* db;
  291.   CHECK_VAR1(keyData);
  292.   db = getUSDB(rdf, u, s, inversep);
  293.   if (db == NULL) { 
  294.     XP_ASSERT(db);
  295.     freeKey(keyData, u, s, inversep);
  296.     return ;
  297.   } 
  298.   key.data = keyData;
  299.   key.size = keySize;
  300.   data.data = value;
  301.   data.size = size; 
  302.   status = (*db->del)(db, &key, 0);
  303.   if (value != NULL) {
  304.      status = (*db->put)(db, &key, &data, 0);
  305.   }  
  306.   if ((status == 0) && (!doingFirstTimeInitp)) (*db->sync)(db, 0);
  307.   freeKey(keyData, u, s, inversep);
  308. }
  309.  
  310.  
  311.  
  312. PRBool
  313. nlocalStoreHasAssertion (RDFT rdf, RDF_Resource u, RDF_Resource s, void* v, RDF_ValueType type, PRBool tv)
  314. {
  315.   size_t size  ;
  316.   DBMAs   *data;    
  317.   uint16  n    = 0;
  318.   PRBool ans = 0;
  319.   PRBool invp = (s == gCoreVocab->RDF_parent);
  320.   data =  (invp ? DBM_GetSlotValue(rdf, (RDF_Resource)v, s, 1, &size) : 
  321.        DBM_GetSlotValue(rdf, u, s, 0, &size));
  322.   if (data == NULL) return 0;
  323.   while (n < size) {
  324.     DBMAs nas = nthdbmas(data, n);
  325.     XP_ASSERT(nas);
  326.     if (nas == NULL) break;
  327.     if ((type ==  valueTypeOfAs(nas)) && (tvOfAs(nas) == tv) && 
  328.     (invp  ? valueEqual(type, dataOfDBMAs(nas), u) : valueEqual(type, dataOfDBMAs(nas), v))) {
  329.       ans = 1;
  330.       break;
  331.     }
  332.     n = dbmasSize(nas) + n;
  333.   }
  334.   freeMem(data);
  335.   return ans;
  336. }
  337.  
  338.  
  339.  
  340. void *
  341. nlocalStoreGetSlotValue (RDFT rdf, RDF_Resource u, RDF_Resource s,  
  342.                    RDF_ValueType type, PRBool inversep, PRBool tv)
  343. {
  344.   size_t size  ;
  345.   DBMAs   *data;    
  346.   uint16  n    = 0;
  347.   void* ans;
  348.   data =  DBM_GetSlotValue(rdf, u, s, inversep, &size);
  349.   if (data == NULL) return 0;
  350.   while (n < size) {
  351.     DBMAs       nas = nthdbmas(data, n);
  352.     XP_ASSERT(nas);
  353.     if (nas == NULL) break;
  354.     if (type == valueTypeOfAs(nas)) {
  355.       if (type == RDF_STRING_TYPE) {
  356.     ans = copyString(dataOfDBMAs(nas));
  357.       } else if (type == RDF_RESOURCE_TYPE) {
  358.     ans = RDF_GetResource(NULL, dataOfDBMAs(nas), true);
  359.       } else if (type == RDF_INT_TYPE) {
  360.         /* ans = dataOfDBMAs(nas); */
  361.         memcpy((char*)&ans, dataOfDBMAs(nas), sizeof(uint32));
  362.       }
  363.       freeMem(data);
  364.       return ans;
  365.     }
  366.     n =  dbmasSize(nas) + n;
  367.   }
  368.   freeMem((void*)data);
  369.   return NULL;
  370. }
  371.  
  372.  
  373.  
  374. RDF_Cursor
  375. nlocalStoreGetSlotValues (RDFT rdf, RDF_Resource u, RDF_Resource s, 
  376.                     RDF_ValueType type, 
  377.                     PRBool inversep, PRBool tv)
  378. {
  379.   RDF_Cursor c;
  380.   void* val;
  381.   size_t size;
  382.   val = DBM_GetSlotValue(rdf, u, s, inversep, &size);
  383.   if (val == NULL) return NULL;
  384.   c = (RDF_Cursor) getMem(sizeof(struct RDF_CursorStruct));
  385.   if (c == NULL) {
  386.     freeMem(val);
  387.     return NULL;
  388.   }
  389.   c->u = u;
  390.   c->s = s;
  391.   c->inversep = inversep;
  392.   c->type = type; 
  393.   c->tv = tv;
  394.   c->count = 0;
  395.   c->pdata = val;
  396.   c->size = size;
  397.   return c;
  398. }
  399.  
  400.  
  401.  
  402. void *
  403. nlocalStoreNextValue (RDFT rdf, RDF_Cursor c)
  404. {
  405.   void* ans;
  406.   void* data;
  407.   if ((c == NULL) || (c->pdata == NULL)) return NULL;
  408.   data = c->pdata;
  409.   while (c->count < c->size) {
  410.     DBMAs     nas = nthdbmas(data, c->count);
  411.     if (nas == NULL) break;
  412.     if ((c->tv == tvOfAs(nas)) && (c->type == valueTypeOfAs(nas))) {
  413.       if (c->type == RDF_RESOURCE_TYPE) {
  414.     RDF_Resource nu = RDF_GetResource(NULL, dataOfDBMAs(nas), 1);
  415.     ans = nu;
  416.     c->count =  dbmasSize(nas) + c->count;
  417.     return nu;
  418.       } else {
  419.     ans = dataOfDBMAs(nas);
  420.     c->count =  dbmasSize(nas) + c->count;
  421.     return ans;
  422.       }
  423.     }
  424.     c->count =  dbmasSize(nas) + c->count;
  425.   }
  426.   return NULL;
  427. }
  428.  
  429.  
  430.  
  431. RDF_Error
  432. nlocalStoreDisposeCursor (RDFT rdf, RDF_Cursor c)
  433. {
  434.   if (c != NULL) {
  435.     if (c->pdata)    freeMem(c->pdata);
  436.     c->pdata = NULL;
  437.     freeMem(c);
  438.   }
  439.   return noRDFErr;
  440. }
  441.  
  442.  
  443.  
  444. DBMAs
  445. makeAsBlock (void* v, RDF_ValueType type, PRBool tv,  size_t *size)
  446. {
  447.   size_t vsize;
  448.   DBMAs ans;
  449.   int rem = 0;
  450. /*
  451.   ldiv_t  cdiv ;
  452. */
  453.   if (type == RDF_STRING_TYPE) {
  454.     vsize = strlen(v);
  455.   } else if (type == RDF_RESOURCE_TYPE) {
  456.     vsize = strlen( resourceID((RDF_Resource)v));
  457.   } else if (type == RDF_INT_TYPE) {
  458.     vsize = 4;
  459.   }
  460.   *size = 4 + vsize + 1;
  461.   rem = *size % 4;
  462.   if (rem) {
  463.     *size += 4 - rem;
  464.   }
  465.   ans = (DBMAs) getMem(*size);
  466.   if (ans == NULL) return NULL;
  467.   ans->size[0] = (uint8)(((*size) & 0x00FF0000) >> 16);
  468.   ans->size[1] = (uint8)(((*size) & 0x0000FF00) >> 8);
  469.   ans->size[2] = (uint8)((*size) & 0x000000FF);
  470.   *(((unsigned char *)ans)+3) = (tv ? 0x10 : 0) | (type & 0x0F);
  471.   if (type == RDF_STRING_TYPE) {
  472.     memcpy((char*)ans+4, (char*) v, vsize);
  473.   } else if (type == RDF_RESOURCE_TYPE) {
  474.     memcpy((char*)ans+4,  resourceID((RDF_Resource)v), vsize);
  475.   } else if (type == RDF_INT_TYPE) {
  476.     memcpy((char*)ans+4, (char*)v, vsize);
  477.   }
  478. /*
  479.   cdiv   = ldiv(*size, 256);
  480.   ans->size[0] = (uint8)(cdiv.quot);
  481.   ans->size[1] = (uint8)(cdiv.rem);
  482.   ans->tag  = (tv ? 0x10 : 0) | (type & 0x0F);
  483.   if (type == RDF_STRING_TYPE) {
  484.     memcpy((char*)ans+3, (char*) v, vsize);
  485.   } else if (type == RDF_RESOURCE_TYPE) {
  486.     memcpy((char*)ans+3,  resourceID((RDF_Resource)v), vsize);
  487.   } else if (type == RDF_INT_TYPE) {
  488.     memcpy((char*)ans+3, (char*)v, vsize);
  489.   }
  490. */
  491.   return ans;
  492. }
  493.  
  494.  
  495.  
  496. PRBool
  497. nlocalStoreAssert (RDFT rdf, RDF_Resource u, RDF_Resource s, void* v, 
  498.              RDF_ValueType type, PRBool tv)
  499. {
  500.     size_t size  ;
  501.     DBMAs*   data;
  502.     char* ndata;
  503.     DBMAs temp;
  504.     uint16  n    = 0;
  505.     size_t tsize;
  506.     PRBool ans = 0;
  507.     data =  DBM_GetSlotValue(rdf, u, s, 0, &size);
  508.     if (((data == NULL) && (size != 0)) || ((size == 0) && (data != NULL))) return 0;
  509.     while (n < size) {
  510.       DBMAs  nas = nthdbmas(data, n);
  511.       if (nas == NULL) {freeMem(data); return 0;}
  512.       if (type == valueTypeOfAs(nas) && (valueEqual(type, dataOfDBMAs(nas), v))) {
  513.       ans = 1;
  514.       break;
  515.     }
  516.       n =  dbmasSize(nas) + n;
  517.     }
  518.     if (ans) {
  519.       freeMem(data);
  520.       return 1;
  521.     } else {
  522.       temp = makeAsBlock(v, type, tv,  &tsize);
  523.       if (temp == NULL) {freeMem(data);return 0;}
  524.       if (data == NULL) {
  525.     DBM_PutSlotValue(rdf, u, s, 0, (void*)temp, tsize);
  526.     /* addSlotsHere(rdf, u, s); */
  527.     freeMem(temp);
  528.     temp = NULL;
  529.       } else {
  530.     ndata = (char*)getMem(size + tsize);
  531.     if (ndata == NULL) {freeMem(data); freeMem(temp);return 0;}
  532.     memcpy(ndata, data, size);
  533.     memcpy(&ndata[size], (char*)temp, tsize);
  534.     DBM_PutSlotValue(rdf, u,s, 0, ndata, size+tsize);
  535.     freeMem(data);
  536.     freeMem(ndata);
  537.     freeMem(temp);
  538.       }
  539.  
  540.       if (type == RDF_RESOURCE_TYPE) {
  541.     temp = makeAsBlock(u, RDF_RESOURCE_TYPE,  tv,  &tsize);
  542.     if (temp == NULL) return 0;
  543.     data = DBM_GetSlotValue(rdf, (RDF_Resource)v, s, 1, &size);
  544.     if (data == NULL) {
  545.       DBM_PutSlotValue(rdf, (RDF_Resource)v, s, 1, (void*) temp, tsize);
  546.       freeMem(temp);
  547.       /*   addSlotsIn(rdf, (RDF_Resource)v, s);*/
  548.     } else {
  549.       ndata = (char*)getMem(size + tsize);
  550.       if (ndata == NULL) {freeMem(data); freeMem(temp);return 0;}
  551.       memcpy(ndata, data, size);
  552.       memcpy(&ndata[size], (char*)temp, tsize);
  553.       DBM_PutSlotValue(rdf, (RDF_Resource)v, s, 1, ndata, size+tsize);
  554.       freeMem(data);
  555.       freeMem(ndata);
  556.       freeMem(temp);
  557.     }
  558.       }
  559.     }
  560.     sendNotifications2(rdf, RDF_INSERT_NOTIFY, u, s, v, type, tv);
  561.     return 1;
  562. }
  563.  
  564.  
  565.  
  566. PRBool
  567. nlocalStoreAssert1 (RDFFile f, RDFT rdf, RDF_Resource u, RDF_Resource s, void* v, 
  568.              RDF_ValueType type, PRBool tv)
  569. {
  570.     return nlocalStoreAssert(rdf, u, s, v, type, tv);
  571. }
  572.  
  573.  
  574.  
  575. PRBool
  576. nlocalStoreUnassert (RDFT rdf, RDF_Resource u, RDF_Resource s, void* v, 
  577.                RDF_ValueType type)
  578. {
  579.   size_t size  ;
  580.   DBMAs*   data;
  581.   char* temp;
  582.   uint16  n    = 0;
  583.   size_t tsize;
  584.   PRBool ans = 0;
  585.   DBMAs nas;
  586.   data =  DBM_GetSlotValue(rdf, u, s, 0, &size);
  587.   if (data == NULL) return 1;
  588.   while (n < size) {
  589.     nas =  nthdbmas(data, n);
  590.     if (type == valueTypeOfAs(nas) && (valueEqual(type, dataOfDBMAs(nas), v))) {
  591.       ans = 1;
  592.       break;
  593.     }
  594.     n =  dbmasSize(nas) + n;
  595.   }
  596.   if (!ans) {
  597.     freeMem(data);
  598.     return 1;
  599.   } else {
  600.     if (size ==  dbmasSize(nas)) {
  601.       DBM_PutSlotValue(rdf, u, s, 0, NULL, 0);
  602.       /*deleteSlotsHere(rdf, u, s);*/
  603.     } else {
  604.       tsize = size -  dbmasSize(nas);
  605.       temp = (char*)getMem(tsize);
  606.       if (temp == NULL) {
  607.     freeMem(data);
  608.     return 0;
  609.       }
  610.       if (n != 0) memcpy(temp, data, n);
  611.       memcpy(((char*)temp+n), ((char*)data + n +  dbmasSize(nas)), tsize-n);
  612.       DBM_PutSlotValue(rdf, u, s, 0, temp, tsize);
  613.       freeMem(temp);
  614.     }
  615.     freeMem(data);
  616.     
  617.     if (type == RDF_RESOURCE_TYPE) {
  618.       data = DBM_GetSlotValue(rdf, ((RDF_Resource)v), s, 1, &size);
  619.       ans = n = 0;
  620.       if (data == NULL) {
  621.     return 1;
  622.       } else {
  623.     while (n < size) {
  624.       nas =   nthdbmas(data, n);
  625.       if (valueEqual(RDF_RESOURCE_TYPE, dataOfDBMAs(nas), u)){
  626.         ans = 1;
  627.         break;
  628.       }
  629.       n =  dbmasSize(nas) + n;
  630.     }
  631.     if (!ans) {
  632.       return 1;
  633.     } else {
  634.       if (size ==  dbmasSize(nas)) {
  635.           DBM_PutSlotValue(rdf, (RDF_Resource)v, s, 1, NULL, 0);
  636.           /*          deleteSlotsIn(rdf, (RDF_Resource)v, s); */
  637.       } else {
  638.         tsize = size -  dbmasSize(nas);
  639.         temp = (char*)getMem(tsize);
  640.         if (temp == NULL)  {
  641.           freeMem(data);
  642.           return 0;
  643.         }
  644.         if (n) memcpy(temp, data, n);
  645.         memcpy(((char*)temp+n), ((char*)data + n +  dbmasSize(nas)), tsize-n);
  646.         DBM_PutSlotValue(rdf, ((RDF_Resource)v), s, 1, temp, tsize);
  647.         freeMem(temp);
  648.       }
  649.       freeMem(data);
  650.     }
  651.       }
  652.     }
  653.   }
  654.   sendNotifications2(rdf, RDF_DELETE_NOTIFY, u, s, v, type, 1);
  655.   return 1;
  656. }
  657.  
  658.  
  659.  
  660. void
  661. addSlotsHere (RDFT rdf, RDF_Resource u, RDF_Resource s)
  662. {
  663.   if ((s != gCoreVocab->RDF_name) && (s != gCoreVocab->RDF_parent) && 
  664.       (s != gCoreVocab->RDF_slotsHere) && (s != gCoreVocab->RDF_slotsIn)) {
  665.     nlocalStoreAssert (rdf, u, gCoreVocab->RDF_slotsHere, s, RDF_RESOURCE_TYPE, 1);
  666.   }
  667. }
  668.  
  669.  
  670.  
  671. void
  672. deleteSlotsHere (RDFT rdf, RDF_Resource u, RDF_Resource s)
  673. {
  674.   if ((s != gCoreVocab->RDF_name) && (s != gCoreVocab->RDF_parent) && 
  675.       (s != gCoreVocab->RDF_slotsHere) &&  (s != gCoreVocab->RDF_slotsIn)) {
  676.     nlocalStoreUnassert (rdf, u, gCoreVocab->RDF_slotsHere, s, RDF_RESOURCE_TYPE);
  677.   }
  678. }
  679.  
  680.  
  681.  
  682. void
  683. addSlotsIn (RDFT rdf, RDF_Resource u, RDF_Resource s)
  684. {
  685.   if ((s != gCoreVocab->RDF_name) && (s != gCoreVocab->RDF_parent) && 
  686.       (s != gCoreVocab->RDF_slotsHere) &&  (s != gCoreVocab->RDF_slotsIn)) {
  687.     nlocalStoreAssert (rdf, u, gCoreVocab->RDF_slotsIn, s, RDF_RESOURCE_TYPE, 1);
  688.   }
  689. }
  690.  
  691.  
  692.  
  693. void
  694. deleteSlotsIn (RDFT rdf, RDF_Resource u, RDF_Resource s)
  695. {
  696.   if ((s != gCoreVocab->RDF_name) && (s != gCoreVocab->RDF_parent) && 
  697.       (s != gCoreVocab->RDF_slotsHere) &&  (s != gCoreVocab->RDF_slotsIn)) {
  698.     nlocalStoreUnassert (rdf, u, gCoreVocab->RDF_slotsIn, s, RDF_RESOURCE_TYPE);
  699.   }
  700. }
  701.  
  702.  
  703.  
  704. void
  705. nlclStoreKill (RDFT rdf, RDF_Resource u)
  706. {
  707.   size_t size  ;
  708.   DBMAs*   data;
  709.   uint16  n    = 0;
  710.   data =  DBM_GetSlotValue(rdf, u, gCoreVocab->RDF_slotsHere, 0, &size);
  711.   while (n < size) {
  712.     DBMAs nas =  nthdbmas(data, n);
  713.     RDF_Resource s;
  714.     s = RDF_GetResource(NULL, (char*)dataOfDBMAs(nas), 1);
  715.     DBM_PutSlotValue(rdf, u, s, 0, NULL, 0);
  716.     n =  dbmasSize(nas) + n;
  717.   }
  718.   DBM_PutSlotValue(rdf, u, gCoreVocab->RDF_name, 0, NULL, 0) ;
  719.   DBM_PutSlotValue(rdf, u, gCoreVocab->RDF_parent, 1, NULL, 0) ;
  720.   DBM_PutSlotValue(rdf, u, gCoreVocab->RDF_parent, 0, NULL, 0) ;
  721.   data =  DBM_GetSlotValue(rdf, u, gCoreVocab->RDF_slotsIn, 0, &size);
  722.   while (n < size) {
  723.     DBMAs nas =  nthdbmas(data, n);
  724.     RDF_Resource s;
  725.     s = RDF_GetResource(NULL, (char*)dataOfDBMAs(nas), 1);
  726.     DBM_PutSlotValue(rdf, u, s, 1, NULL, 0);
  727.     n =  dbmasSize(nas) + n;
  728.   }
  729. }
  730.  
  731.  
  732.  
  733. PRBool
  734. nlocalStoreAddChildAt(RDFT rdf, RDF_Resource parent, RDF_Resource ref, 
  735.                   RDF_Resource new, PRBool beforep)
  736. {
  737.     size_t size  ;
  738.     DBMAs*   data;
  739.     char* ndata;
  740.     RDF_Resource s = gCoreVocab->RDF_parent;
  741.     DBMAs temp;
  742.     uint16  n    = 0;
  743.     size_t tsize;
  744.     PRBool ans = 0;
  745.     DBMAs  nas;
  746.     data =  DBM_GetSlotValue(rdf, parent, s, 1, &size);
  747.     if (!data) return 0;
  748.     while (n < size) {
  749.       nas = nthdbmas(data, n);
  750.       if (valueEqual(RDF_RESOURCE_TYPE, dataOfDBMAs(nas), ref)) {
  751.       ans = 1;
  752.       if (!beforep) {        
  753.         n =  dbmasSize(nas) + n;
  754.       }        
  755.       break;
  756.     }
  757.       n =  dbmasSize(nas) + n;
  758.     }
  759.     if (!ans) {
  760.       freeMem(data);
  761.       return 0;
  762.     } else {
  763.       char* dx = (char*)data;
  764.       
  765.       temp = makeAsBlock(new, RDF_RESOURCE_TYPE, 1,  &tsize);
  766.       ndata = (char*)getMem(size + tsize);
  767.       if ((temp == NULL) || (ndata == NULL)) {freeMem(data);freeMem(temp);freeMem(ndata);return 1;}
  768.       memcpy(ndata, dx, n);
  769.       memcpy(&ndata[n], (char*)temp, tsize);
  770.       memcpy(&ndata[n+tsize], &dx[n], size-n);
  771.       DBM_PutSlotValue(rdf, parent, s, 1, ndata, size+tsize);
  772.       freeMem(data);
  773.       freeMem(ndata);
  774.       freeMem(temp);
  775.     }
  776.  
  777.     temp = makeAsBlock(parent, RDF_RESOURCE_TYPE,  1,  &tsize);
  778.     if (temp == NULL) return 0;
  779.     data = DBM_GetSlotValue(rdf, new, s, 0, &size);
  780.     if (data == NULL) {
  781.       DBM_PutSlotValue(rdf, new, s, 0, (void*) temp, tsize);     
  782.     } else {
  783.       ndata = (char*)getMem(size + tsize);
  784.       if (ndata == NULL) {freeMem(data);freeMem(temp);return 0;}
  785.       memcpy(ndata, data, size);
  786.       memcpy(&ndata[size], (char*)temp, tsize);
  787.       DBM_PutSlotValue(rdf, (RDF_Resource)new, s, 0, ndata, size+tsize);
  788.       freeMem(data);
  789.       freeMem(ndata);
  790.       freeMem(temp);
  791.     }
  792.     sendNotifications2(rdf, RDF_INSERT_NOTIFY, new, s, parent, RDF_RESOURCE_TYPE, 1);
  793.     return 1;
  794. }
  795.  
  796. /*
  797.  
  798. RDF_Cursor 
  799. nlcStoreArcsIn (RDFT rdf, RDF_Resource u) {
  800.   RDF_Cursor c = (RDF_Cursor) getMem(sizeof(RDF_CursorStruc));
  801.   c->u = u;
  802.   c->queryType = RDF_ARC_LABELS_IN_QUERY;
  803.   c->inversep = 1;
  804.   c->count = 0;
  805.   return c;
  806. }
  807.  
  808. RDF_Cursor 
  809. nlcStoreArcsOut (RDFT rdf, RDF_Resource u) {
  810.   RDF_Cursor c = (RDF_Cursor) getMem(sizeof(RDF_CursorStruc));
  811.   c->u = u;
  812.   c->queryType =  RDF_ARC_LABELS_OUT_QUERY;
  813.   c->count = 0;
  814.   return c;
  815. }
  816.  
  817.  
  818. RDF_Resource 
  819. nlcStoreArcsInOutNextValue (RDF_Cursor c) {
  820.   while (c->count < gCoreVocabSize) {
  821.     RDF_Resource s = *(gAllVocab + c->count);
  822.     size_t size;
  823.     void* data = DBM_GetSlotValue(c->rdf, u, s, c->inversep, &size);
  824.     c->count++;
  825.     if (data) {
  826.       freeMem(data);
  827.       return s;
  828.     } else {
  829.       freeMem(data);
  830.     }
  831.   }
  832.   return NULL;
  833. }
  834.       
  835. */
  836.  
  837.  
  838. RDFT
  839. MakeLocalStore (char* url)
  840. {
  841.   if (startsWith(url, "rdf:localStore") && (gLocalStore))  {
  842.     return gLocalStore;
  843.   } else if (startsWith(url, "rdf:ops") && (gOPSStore))  {
  844.     return gOPSStore;
  845.   } else if (startsWith(url, "rdf:ops") || startsWith(url, "rdf:localStore")) {
  846.     RDFT ntr = (RDFT)getMem(sizeof(struct RDF_TranslatorStruct));
  847.     DBMRDF db  = (DBMRDF)getMem(sizeof(struct _DBMRDFStruct));
  848.     CHECK_VAR(ntr, NULL);
  849.     CHECK_VAR(db, NULL);
  850.     if (startsWith(url, "rdf:localStore")) {
  851.       gLocalStore = ntr;
  852.     } else {
  853.       gOPSStore = ntr;
  854.     }
  855.     ntr->url  = copyString(url);
  856.     ntr->assert = nlocalStoreAssert;
  857.     ntr->unassert = nlocalStoreUnassert;
  858.     ntr->getSlotValue = nlocalStoreGetSlotValue;
  859.     ntr->getSlotValues = nlocalStoreGetSlotValues;
  860.     ntr->hasAssertion = nlocalStoreHasAssertion;
  861.     ntr->nextValue = nlocalStoreNextValue;
  862.     ntr->disposeCursor = nlocalStoreDisposeCursor;
  863.     ntr->destroy = DBM_CloseRDFDBMStore;
  864.     ntr->pdata = db;
  865.     DBM_OpenDBMStore(db, (startsWith(url, "rdf:localStore") ? "NavCen" : &url[4]));
  866.     return ntr;
  867.   } 
  868.   else return NULL;
  869. }
  870.