exip  Alpha 0.5.4
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
sTables.c
Go to the documentation of this file.
1 /*==================================================================*\
2 | EXIP - Embeddable EXI Processor in C |
3 |--------------------------------------------------------------------|
4 | This work is licensed under BSD 3-Clause License |
5 | The full license terms and conditions are located in LICENSE.txt |
6 \===================================================================*/
7 
17 #include "sTables.h"
18 #include "stringManipulate.h"
19 #include "memManagement.h"
20 #include "hashtable.h"
21 #include "dynamicArray.h"
22 
23 /********* BEGIN: String table default entries ***************/
24 
25 extern CharType ops_URI_1[];
26 extern CharType ops_PFX_1_0[];
27 extern CharType ops_LN_1_0[];
28 extern CharType ops_LN_1_1[];
29 extern CharType ops_LN_1_2[];
30 extern CharType ops_LN_1_3[];
31 extern CharType ops_URI_2[];
32 extern CharType ops_PFX_2_0[];
33 extern CharType ops_LN_2_0[];
34 extern CharType ops_LN_2_1[];
35 extern CharType ops_URI_3[];
36 extern CharType ops_LN_3_0[];
37 extern CharType ops_LN_3_1[];
38 extern CharType ops_LN_3_2[];
39 extern CharType ops_LN_3_3[];
40 extern CharType ops_LN_3_4[];
41 extern CharType ops_LN_3_5[];
42 extern CharType ops_LN_3_6[];
43 extern CharType ops_LN_3_7[];
44 extern CharType ops_LN_3_8[];
45 extern CharType ops_LN_3_9[];
46 extern CharType ops_LN_3_10[];
47 extern CharType ops_LN_3_11[];
48 extern CharType ops_LN_3_12[];
49 extern CharType ops_LN_3_13[];
50 extern CharType ops_LN_3_14[];
51 extern CharType ops_LN_3_15[];
52 extern CharType ops_LN_3_16[];
53 extern CharType ops_LN_3_17[];
54 extern CharType ops_LN_3_18[];
55 extern CharType ops_LN_3_19[];
56 extern CharType ops_LN_3_20[];
57 extern CharType ops_LN_3_21[];
58 extern CharType ops_LN_3_22[];
59 extern CharType ops_LN_3_23[];
60 extern CharType ops_LN_3_24[];
61 extern CharType ops_LN_3_25[];
62 extern CharType ops_LN_3_26[];
63 extern CharType ops_LN_3_27[];
64 extern CharType ops_LN_3_28[];
65 extern CharType ops_LN_3_29[];
66 extern CharType ops_LN_3_30[];
67 extern CharType ops_LN_3_31[];
68 extern CharType ops_LN_3_32[];
69 extern CharType ops_LN_3_33[];
70 extern CharType ops_LN_3_34[];
71 extern CharType ops_LN_3_35[];
72 extern CharType ops_LN_3_36[];
73 extern CharType ops_LN_3_37[];
74 extern CharType ops_LN_3_38[];
75 extern CharType ops_LN_3_39[];
76 extern CharType ops_LN_3_40[];
77 extern CharType ops_LN_3_41[];
78 extern CharType ops_LN_3_42[];
79 extern CharType ops_LN_3_43[];
80 extern CharType ops_LN_3_44[];
81 extern CharType ops_LN_3_45[];
82 
86 
88 static const String URI_2_PFX = {ops_PFX_2_0, 3};
89 
90 #define URI_1_LN_SIZE 4
91 static const String URI_1_LN[] = {{ops_LN_1_0, 4}, {ops_LN_1_1, 2}, {ops_LN_1_2, 4}, {ops_LN_1_3, 5}};
92 
93 #define URI_2_LN_SIZE 2
94 const String URI_2_LN[] = {{ops_LN_2_0, 3}, {ops_LN_2_1, 4}};
95 
96 #define URI_3_LN_SIZE 46
97 static const String URI_3_LN[] = {
98  {ops_LN_3_0, 8},
99  {ops_LN_3_1, 6},
100  {ops_LN_3_2, 2},
101  {ops_LN_3_3, 5},
102  {ops_LN_3_4, 6},
103  {ops_LN_3_5, 6},
104  {ops_LN_3_6, 7},
105  {ops_LN_3_7, 8},
106  {ops_LN_3_8, 8},
107  {ops_LN_3_9, 4},
108  {ops_LN_3_10, 5},
109  {ops_LN_3_11, 13},
110  {ops_LN_3_12, 7},
111  {ops_LN_3_13, 6},
112  {ops_LN_3_14, 12},
113  {ops_LN_3_15, 7},
114  {ops_LN_3_16, 4},
115  {ops_LN_3_17, 4},
116  {ops_LN_3_18, 8},
117  {ops_LN_3_19, 7},
118  {ops_LN_3_20, 6},
119  {ops_LN_3_21, 8},
120  {ops_LN_3_22, 5},
121  {ops_LN_3_23, 4},
122  {ops_LN_3_24, 6},
123  {ops_LN_3_25, 9},
124  {ops_LN_3_26, 5},
125  {ops_LN_3_27, 10},
126  {ops_LN_3_28, 9},
127  {ops_LN_3_29, 3},
128  {ops_LN_3_30, 7},
129  {ops_LN_3_31, 8},
130  {ops_LN_3_32, 4},
131  {ops_LN_3_33, 15},
132  {ops_LN_3_34, 18},
133  {ops_LN_3_35, 18},
134  {ops_LN_3_36, 16},
135  {ops_LN_3_37, 15},
136  {ops_LN_3_38, 5},
137  {ops_LN_3_39, 6},
138  {ops_LN_3_40, 4},
139  {ops_LN_3_41, 5},
140  {ops_LN_3_42, 12},
141  {ops_LN_3_43, 11},
142  {ops_LN_3_44, 12},
143  {ops_LN_3_45, 13}
144  };
145 
146 /********* END: String table default entries ***************/
147 
149 {
150  errorCode tmp_err_code;
151 
153 
154  valueTable->globalId = 0;
155 #if HASH_TABLE_USE
156  valueTable->hashTbl = NULL;
157 #endif
158  return EXIP_OK;
159 }
160 
161 errorCode addUriEntry(UriTable* uriTable, String uriStr, SmallIndex* uriEntryId)
162 {
163  errorCode tmp_err_code;
164  UriEntry* uriEntry;
165  Index uriLEntryId;
166 
167  TRY(addEmptyDynEntry(&uriTable->dynArray, (void**)&uriEntry, &uriLEntryId));
168 
169  // Fill in URI entry
170  uriEntry->uriStr = uriStr;
171 
172  // Create an empty prefix table
174 
175  // Create local names table for this URI
177 
178  *uriEntryId = (SmallIndex)uriLEntryId;
179  return EXIP_OK;
180 }
181 
182 errorCode addLnEntry(LnTable* lnTable, String lnStr, Index* lnEntryId)
183 {
184  errorCode tmp_err_code;
185  LnEntry* lnEntry;
186 
187  TRY(addEmptyDynEntry(&lnTable->dynArray, (void**)&lnEntry, lnEntryId));
188 
189  // Fill in local names entry
190  lnEntry->lnStr = lnStr;
191  lnEntry->elemGrammar = INDEX_MAX;
192  lnEntry->typeGrammar = INDEX_MAX;
193 #if VALUE_CROSSTABLE_USE
194  // The Vx table is created on-demand (additions to value cross table are done when a value is inserted in the value table)
195  lnEntry->vxTable = NULL;
196 #endif
197  return EXIP_OK;
198 }
199 
200 errorCode addValueEntry(EXIStream* strm, String valueStr, QNameID qnameID)
201 {
202  errorCode tmp_err_code = EXIP_UNEXPECTED_ERROR;
203  ValueEntry* valueEntry = NULL;
204  Index valueEntryId;
205 
206 #if VALUE_CROSSTABLE_USE
207  Index vxEntryId;
208  {
209  struct LnEntry* lnEntry;
210  VxEntry vxEntry;
211 
212  // Find the local name entry from QNameID
213  lnEntry = &GET_LN_URI_QNAME(strm->schema->uriTable, qnameID);
214 
215  // Add entry to the local name entry's value cross table (vxTable)
216  if(lnEntry->vxTable == NULL)
217  {
218  lnEntry->vxTable = memManagedAllocate(&strm->memList, sizeof(VxTable));
219  if(lnEntry->vxTable == NULL)
221 
222  // First value entry - create the vxTable
224  }
225 
226  assert(lnEntry->vxTable->vx);
227 
228  // Set the global ID in the value cross table entry
229  vxEntry.globalId = strm->valueTable.globalId;
230 
231  // Add the entry
232  TRY(addDynEntry(&lnEntry->vxTable->dynArray, (void*) &vxEntry, &vxEntryId));
233  }
234 #endif
235 
236  // If the global ID is less than the actual array size, we must have wrapped around
237  // In this case, we must reuse an existing entry
238  if(strm->valueTable.globalId < strm->valueTable.count)
239  {
240  // Get the existing value entry
241  valueEntry = &strm->valueTable.value[strm->valueTable.globalId];
242 
243 #if VALUE_CROSSTABLE_USE
244  assert(GET_LN_URI_QNAME(strm->schema->uriTable, valueEntry->locValuePartition.forQNameId).vxTable);
245  // Null out the existing cross table entry
246  GET_LN_URI_QNAME(strm->schema->uriTable, valueEntry->locValuePartition.forQNameId).vxTable->vx[valueEntry->locValuePartition.vxEntryId].globalId = INDEX_MAX;
247 #endif
248 
249 #if HASH_TABLE_USE
250  // Remove existing value string from hash table (if present)
251  if(strm->valueTable.hashTbl != NULL)
252  {
253  hashtable_remove(strm->valueTable.hashTbl, valueEntry->valueStr);
254  }
255 #endif
256  // Free the memory allocated by the previous string entry
257  EXIP_MFREE(valueEntry->valueStr.str);
258  }
259  else
260  {
261  // We are filling up the array and have not wrapped round yet
262  // See http://www.w3.org/TR/exi/#encodingOptimizedForMisses
263  TRY(addEmptyDynEntry(&strm->valueTable.dynArray, (void**)&valueEntry, &valueEntryId));
264  }
265 
266  // Set the value entry fields
267  valueEntry->valueStr = valueStr;
268 #if VALUE_CROSSTABLE_USE
269  valueEntry->locValuePartition.forQNameId = qnameID;
270  valueEntry->locValuePartition.vxEntryId = vxEntryId;
271 #endif
272 
273 #if HASH_TABLE_USE
274  // Add value string to hash table (if present)
275  if(strm->valueTable.hashTbl != NULL)
276  {
277  TRY(hashtable_insert(strm->valueTable.hashTbl, valueStr, strm->valueTable.globalId));
278  }
279 #endif
280 
281  // Increment global ID
282  strm->valueTable.globalId++;
283 
284  // The value table is limited by valuePartitionCapacity. If we have exceeded, we wrap around
285  // to the beginning of the value table and null out existing IDs in the corresponding
286  // cross table IDs
288  strm->valueTable.globalId = 0;
289 
290  return EXIP_OK;
291 }
292 
293 errorCode addPfxEntry(PfxTable* pfxTable, String pfxStr, SmallIndex* pfxEntryId)
294 {
295  errorCode tmp_err_code;
296  String* strEntry;
297 
298  TRY(addEmptyDynEntry(&pfxTable->dynArray, (void**)&strEntry, pfxEntryId));
299 
300  // Fill in local names entry
301  strEntry->length = pfxStr.length;
302  strEntry->str = pfxStr.str;
303 
304  return EXIP_OK;
305 }
306 
307 errorCode createUriTableEntry(UriTable* uriTable, const String uri, int createPfx, const String pfx, const String* lnBase, Index lnSize)
308 {
309  errorCode tmp_err_code;
310  Index i;
311  SmallIndex pfxEntryId;
312  SmallIndex uriEntryId;
313  Index lnEntryId;
314  UriEntry* uriEntry;
315 
316  // Add resulting String to URI table (creates lnTable as well)
317  TRY(addUriEntry(uriTable, uri, &uriEntryId));
318 
319  // Get ptr. to URI Entry
320  uriEntry = &uriTable->uri[uriEntryId];
321 
322  if(createPfx)
323  TRY(addPfxEntry(&uriEntry->pfxTable, pfx, &pfxEntryId));
324 
325  for(i = 0; i < lnSize; i++)
326  {
327  TRY(addLnEntry(&uriEntry->lnTable, lnBase[i], &lnEntryId));
328  }
329  return EXIP_OK;
330 }
331 
332 errorCode createUriTableEntries(UriTable* uriTable, boolean withSchema)
333 {
334  errorCode tmp_err_code = EXIP_UNEXPECTED_ERROR;
335  String emptyStr;
336  getEmptyString(&emptyStr);
337 
338  // See http://www.w3.org/TR/exi/#initialUriValues
339 
340  // URI 0: "" (empty string)
341  TRY(createUriTableEntry(uriTable,
342  emptyStr, // Namespace - empty string
343  TRUE, // Create prefix entry
344  emptyStr, // Prefix entry - empty string
345  NULL, // No local names
346  0));
347 
348  // URI 1: "http://www.w3.org/XML/1998/namespace"
349  TRY(createUriTableEntry(uriTable,
350  XML_NAMESPACE, // URI: "http://www.w3.org/XML/1998/namespace"
351  TRUE, // Create prefix entry
352  URI_1_PFX, // Prefix: "xml"
353  URI_1_LN, // Add local names
354  URI_1_LN_SIZE));
355 
356  // URI 2: "http://www.w3.org/2001/XMLSchema-instance"
357  TRY(createUriTableEntry(uriTable,
358  XML_SCHEMA_INSTANCE, // URI: "http://www.w3.org/2001/XMLSchema-instance"
359  TRUE, // Create prefix entry
360  URI_2_PFX, // Prefix: "xsi"
361  URI_2_LN, // Add local names
362  URI_2_LN_SIZE));
363 
364  if(withSchema == TRUE)
365  {
366  // URI 3: "http://www.w3.org/2001/XMLSchema"
367  TRY(createUriTableEntry(uriTable,
368  XML_SCHEMA_NAMESPACE, // URI: "http://www.w3.org/2001/XMLSchema"
369  FALSE, // No prefix entry (see http://www.w3.org/TR/exi/#initialPrefixValues)
370  emptyStr, // (no prefix)
371  URI_3_LN, // Add local names
372  URI_3_LN_SIZE));
373  }
374 
375  return EXIP_OK;
376 }
377 
378 boolean lookupUri(UriTable* uriTable, String uriStr, SmallIndex* uriEntryId)
379 {
380  SmallIndex i;
381 
382  if(uriTable == NULL)
383  return FALSE;
384 
385  for(i = 0; i < uriTable->count; i++)
386  {
387  if(stringEqual(uriTable->uri[i].uriStr, uriStr))
388  {
389  *uriEntryId = i;
390  return TRUE;
391  }
392  }
393  return FALSE;
394 }
395 
396 boolean lookupLn(LnTable* lnTable, String lnStr, Index* lnEntryId)
397 {
398  Index i;
399 
400  if(lnTable == NULL)
401  return FALSE;
402  for(i = 0; i < lnTable->count; i++)
403  {
404  if(stringEqual(lnTable->ln[i].lnStr, lnStr))
405  {
406  *lnEntryId = i;
407  return TRUE;
408  }
409  }
410  return FALSE;
411 }
412 
413 boolean lookupPfx(PfxTable* pfxTable, String pfxStr, SmallIndex* pfxEntryId)
414 {
415  SmallIndex i;
416 
417  for(i = 0; i < pfxTable->count; i++)
418  {
419  if(stringEqual(pfxTable->pfx[i], pfxStr))
420  {
421  *pfxEntryId = i;
422  return TRUE;
423  }
424  }
425  return FALSE;
426 }
427 
428 #if VALUE_CROSSTABLE_USE
429 boolean lookupVx(ValueTable* valueTable, VxTable* vxTable, String valueStr, Index* vxEntryId)
430 {
431  Index i;
432  VxEntry* vxEntry;
433  ValueEntry* valueEntry;
434 
435  if(vxTable == NULL || vxTable->vx == NULL)
436  return FALSE;
437 
438  for(i = 0; i < vxTable->count; i++)
439  {
440  vxEntry = vxTable->vx + i;
441  if(vxEntry->globalId == INDEX_MAX) // The value was removed from the local value partition
442  continue;
443  valueEntry = valueTable->value + vxEntry->globalId;
444  if(stringEqual(valueEntry->valueStr, valueStr))
445  {
446  *vxEntryId = i;
447  return TRUE;
448  }
449  }
450  return FALSE;
451 }
452 #endif
453 
454 boolean lookupValue(ValueTable* valueTable, String valueStr, Index* valueEntryId)
455 {
456  Index i;
457  ValueEntry* valueEntry;
458 
459  assert(valueTable);
460 
461 #if HASH_TABLE_USE
462  if(valueTable->hashTbl != NULL)
463  {
464  // Use hash table search
465  i = hashtable_search(valueTable->hashTbl, valueStr);
466  if(i != INDEX_MAX)
467  {
468  *valueEntryId = i;
469  return TRUE;
470  }
471  }
472  else
473 #endif
474  {
475  // No hash table - linear search
476  for(i = 0; i < valueTable->count; i++)
477  {
478  valueEntry = valueTable->value + i;
479  if(stringEqual(valueEntry->valueStr, valueStr))
480  {
481  *valueEntryId = i;
482  return TRUE;
483  }
484  }
485  }
486 
487  return FALSE;
488 }