1 /* |
|
2 * Copyright (c) 2000 - 2001 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of the License "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 /***************************************************************** |
|
20 ** File: dictionary.c |
|
21 ** Description: |
|
22 *****************************************************************/ |
|
23 #include "cxml_internal.h" |
|
24 #include "nw_wbxml_parsei.h" |
|
25 #include <xml/cxml/nw_string_char.h> |
|
26 #include <xml/cxml/nw_wbxml_dictionary.h> |
|
27 #include "DictionaryContext.h" |
|
28 |
|
29 /* HTTP_iso_8859_1 IANA MIBenum 4 */ |
|
30 #define NW_WBXML_DICTIONARY_CHARSET 4 |
|
31 |
|
32 /* |
|
33 * The dictionaries ... |
|
34 */ |
|
35 |
|
36 |
|
37 static |
|
38 NW_Bool |
|
39 NW_WBXML_Dictionary_CmpDictDocType(NW_WBXML_Dictionary_t* dictionary, |
|
40 NW_String_t* string, |
|
41 NW_Uint32 encoding) |
|
42 { |
|
43 NW_Ucs2* docType; |
|
44 |
|
45 docType = dictionary->doc_type; |
|
46 while (*docType != 0) |
|
47 { |
|
48 NW_Int32 bytesRead; |
|
49 NW_Ucs2 c; |
|
50 |
|
51 bytesRead = NW_String_readChar(string->storage, &c, encoding); |
|
52 if (c != *docType){ |
|
53 return NW_FALSE; |
|
54 } |
|
55 NW_ASSERT(bytesRead > 0); |
|
56 string->storage = string->storage + bytesRead; |
|
57 string->length = string->length - (NW_Uint32)bytesRead; |
|
58 docType++; |
|
59 } |
|
60 return NW_TRUE; |
|
61 } |
|
62 |
|
63 static |
|
64 NW_String_UCS2Buff_t * |
|
65 getTagByToken (NW_WBXML_Codepage_t * page, |
|
66 NW_Byte token) |
|
67 { |
|
68 NW_WBXML_DictEntry_t *e; |
|
69 NW_Int32 r; |
|
70 NW_Int32 l = 0; |
|
71 |
|
72 if (page == NULL) |
|
73 return NULL; |
|
74 |
|
75 r = page->count - 1; |
|
76 e = page->tokens; |
|
77 |
|
78 /* Binary search (tokens must be stored in order) */ |
|
79 |
|
80 while (r >= l) |
|
81 { |
|
82 NW_Int32 m = (l + r) / 2; |
|
83 if (token == e[m].token) |
|
84 return e[m].name; |
|
85 if (token < e[m].token) |
|
86 r = m - 1; |
|
87 else |
|
88 l = m + 1; |
|
89 } |
|
90 |
|
91 return NULL; |
|
92 } |
|
93 |
|
94 /* |
|
95 * Return -1 if tag is not found, page is 0 or tag is 0 |
|
96 */ |
|
97 |
|
98 static |
|
99 NW_Int16 |
|
100 getTokenByTag (NW_WBXML_Codepage_t * page, |
|
101 NW_String_UCS2Buff_t * tag, |
|
102 NW_Bool matchCase) |
|
103 { |
|
104 NW_Byte *names; |
|
105 NW_Int32 r; |
|
106 NW_Int32 l = 0; |
|
107 |
|
108 if (page == NULL || tag == NULL) |
|
109 return -1; |
|
110 |
|
111 names = page->names; |
|
112 r = page->count - 1; |
|
113 |
|
114 while (r >= l) |
|
115 { |
|
116 NW_Int32 m = (l + r) / 2; |
|
117 NW_Int32 c = NW_String_UCS2BuffCmp (tag, (page->tokens)[names[m]].name, matchCase); |
|
118 if (c == 0) |
|
119 return (page->tokens)[names[m]].token; |
|
120 if (c < 0) |
|
121 r = m - 1; |
|
122 else |
|
123 l = m + 1; |
|
124 } |
|
125 |
|
126 return -1; |
|
127 } |
|
128 |
|
129 static |
|
130 NW_Status_t |
|
131 getTokenByTag2 (NW_WBXML_Codepage_t * page, |
|
132 NW_Uint32 encoding, |
|
133 NW_Uint32 charCount, |
|
134 NW_Uint8 * name, |
|
135 NW_Uint16 * pageToken) |
|
136 { |
|
137 NW_Byte *names; |
|
138 NW_Int32 r; |
|
139 NW_Int32 l = 0; |
|
140 |
|
141 if (page == NULL || name == NULL || pageToken == NULL) { |
|
142 return NW_STAT_FAILURE; |
|
143 } |
|
144 |
|
145 names = page->names; |
|
146 r = page->count - 1; |
|
147 |
|
148 while (r >= l) |
|
149 { |
|
150 NW_Int32 m = (l + r) / 2; |
|
151 NW_Int32 c; |
|
152 NW_Status_t s; |
|
153 s = NW_String_CmpToNativeAlignedUCS2 (encoding, charCount, name, |
|
154 (NW_Uint16*)((page->tokens)[names[m]].name), |
|
155 &c); |
|
156 if (NW_STAT_IS_FAILURE(s)) { |
|
157 return s; |
|
158 } |
|
159 if (c == 0) { |
|
160 *pageToken = (page->tokens)[names[m]].token; |
|
161 return NW_STAT_SUCCESS; |
|
162 } |
|
163 if (c < 0) |
|
164 r = m - 1; |
|
165 else |
|
166 l = m + 1; |
|
167 } |
|
168 return NW_STAT_FAILURE; |
|
169 } |
|
170 |
|
171 static |
|
172 NW_Status_t |
|
173 getTokenByTag_HandleDuplicates (NW_WBXML_Codepage_t * page, |
|
174 NW_Uint32 encoding, |
|
175 NW_Uint32 charCount, |
|
176 NW_Uint8 * name, |
|
177 NW_Uint16 * pageToken, |
|
178 NW_Bool isName) |
|
179 { |
|
180 NW_Byte *names; |
|
181 NW_Int32 i = 0; |
|
182 NW_Uint16 tmpToken; |
|
183 |
|
184 if (page == NULL || name == NULL || pageToken == NULL) { |
|
185 return NW_STAT_FAILURE; |
|
186 } |
|
187 |
|
188 names = page->names; |
|
189 |
|
190 while (i < page->count) |
|
191 { |
|
192 NW_Int32 c; |
|
193 NW_Status_t s; |
|
194 tmpToken = (page->tokens)[names[i]].token; |
|
195 /* If the tag is AttributeTag, then MSB of lower order byte (token) |
|
196 * should be unset. If the tag is AttributeValueTag, then MSB of |
|
197 * lower order byte (token) should be set. |
|
198 */ |
|
199 if((isName && !(tmpToken & 0x80)) || (!isName && (tmpToken & 0x80))) |
|
200 { |
|
201 s = NW_String_CmpToNativeAlignedUCS2 (encoding, charCount, name, |
|
202 (NW_Uint16*)((page->tokens)[names[i]].name), |
|
203 &c); |
|
204 if (NW_STAT_IS_FAILURE(s)) { |
|
205 return s; |
|
206 } |
|
207 if (c == 0) { |
|
208 *pageToken = tmpToken; |
|
209 return NW_STAT_SUCCESS; |
|
210 } |
|
211 } |
|
212 i++; |
|
213 } |
|
214 return NW_STAT_FAILURE; |
|
215 } |
|
216 |
|
217 /* |
|
218 * Dictionary ids are a 1-based index into the dictionary table |
|
219 * |
|
220 * Return NULL if id is < 1 or id is greater than dictionary_count |
|
221 */ |
|
222 |
|
223 static |
|
224 NW_WBXML_Dictionary_t * |
|
225 getDictionaryById (NW_Uint32 id) |
|
226 { |
|
227 NW_WBXML_Dictionary_t *d; |
|
228 NW_WBXML_Dictionary_t **dictionaries = GetDictionaries(); |
|
229 |
|
230 if (id < 1 || id > GetDictionaryCount()) |
|
231 return NULL; |
|
232 |
|
233 //#ifdef __WINS__ |
|
234 d = dictionaries[id - 1]; |
|
235 //#endif |
|
236 |
|
237 return d; |
|
238 } |
|
239 |
|
240 /* |
|
241 * This function checks if the dictionary has already been added |
|
242 * to the 'dictionaries' table. The comparison is based on |
|
243 * puclic ids, and therefore it is important that each dictionary |
|
244 * has unique public id. |
|
245 * |
|
246 */ |
|
247 static NW_Bool ExistingDictionary(NW_WBXML_Dictionary_t *dictionary) |
|
248 { |
|
249 //#ifdef __WINS__ |
|
250 NW_Uint32 i; |
|
251 NW_Uint32 dictionary_count = GetDictionaryCount(); |
|
252 NW_WBXML_Dictionary_t **dictionaries = GetDictionaries(); |
|
253 |
|
254 for (i=0; i<dictionary_count; i++) { |
|
255 if (dictionaries[i]->public_id == dictionary->public_id) { |
|
256 return NW_TRUE; |
|
257 } |
|
258 } |
|
259 //#endif |
|
260 return NW_FALSE; |
|
261 } |
|
262 |
|
263 EXPORT_C NW_Status_t |
|
264 NW_WBXML_Dictionary_initialize (NW_Int32 n, |
|
265 NW_WBXML_Dictionary_t * d[]) |
|
266 { |
|
267 NW_WBXML_Dictionary_t **dictionaries = GetDictionaries(); |
|
268 |
|
269 /* Make sure that adding dictionaries is done by calling NW_WBXML_Dictionary_add(). */ |
|
270 if (dictionaries == NULL) |
|
271 { |
|
272 dictionaries = (NW_WBXML_Dictionary_t **)NW_Mem_Malloc(sizeof(NW_WBXML_Dictionary_t*) * MAX_DICTIONARIES); |
|
273 if (dictionaries == NULL) { |
|
274 DestroyDictionaries(); |
|
275 return NW_STAT_OUT_OF_MEMORY; |
|
276 } |
|
277 StoreDictionaries(dictionaries); |
|
278 StoreDictionaryCount(0); |
|
279 } |
|
280 UpdateDictRefCnt(NW_CONTEXT_REF_DICT_CNT_INR); |
|
281 return NW_WBXML_Dictionary_add(n, d); |
|
282 } |
|
283 |
|
284 NW_Status_t |
|
285 NW_WBXML_Dictionary_add(NW_Int32 n, NW_WBXML_Dictionary_t* d[]) |
|
286 { |
|
287 NW_Int32 i; |
|
288 NW_WBXML_Dictionary_t **dictionaries = GetDictionaries(); |
|
289 |
|
290 if (dictionaries == NULL) |
|
291 { |
|
292 return NW_STAT_FAILURE; |
|
293 } |
|
294 |
|
295 NW_ASSERT(n > 0); |
|
296 NW_ASSERT(d != NULL); |
|
297 |
|
298 /* This loop adds only the new dictionaries received in the |
|
299 function call (the *d[] table) into the 'dictionaries' table. */ |
|
300 for (i=0; i<n; i++) { |
|
301 if (!ExistingDictionary(d[i])) { |
|
302 NW_Uint32 dictionary_count = GetDictionaryCount(); |
|
303 |
|
304 /* Return error if the table is full */ |
|
305 if ((NW_Uint32)GetDictionaryCount() >= MAX_DICTIONARIES) { |
|
306 return NW_STAT_FAILURE; |
|
307 } |
|
308 dictionaries[dictionary_count++] = d[i]; |
|
309 StoreDictionaryCount(dictionary_count); |
|
310 } |
|
311 } |
|
312 |
|
313 return NW_STAT_SUCCESS; |
|
314 } |
|
315 |
|
316 EXPORT_C NW_Status_t |
|
317 NW_WBXML_Dictionary_destroy () |
|
318 { |
|
319 UpdateDictRefCnt(NW_CONTEXT_REF_DICT_CNT_DCR); |
|
320 DestroyDictionaries(); |
|
321 return NW_STAT_SUCCESS; |
|
322 } |
|
323 |
|
324 |
|
325 /* |
|
326 * Return NULL if GetDictionaryById returns 0 or if GetTagByToken returns 0 |
|
327 */ |
|
328 |
|
329 EXPORT_C NW_String_UCS2Buff_t * |
|
330 NW_WBXML_Dictionary_getTagByFqToken (NW_Uint32 fq_token) |
|
331 { |
|
332 NW_WBXML_Dictionary_t *d; |
|
333 NW_Byte cp_index = (NW_Byte) ((fq_token & NW_WBXML_MASK_CODEPAGE) >> 8); |
|
334 NW_Byte token = (NW_Byte) (fq_token & NW_WBXML_MASK_TOKEN); |
|
335 NW_WBXML_Codepage_t page; |
|
336 NW_Uint16 dict_id = (NW_Uint16) ((fq_token & NW_WBXML_MASK_DICTIONARY) >> 16); |
|
337 |
|
338 if ((d = getDictionaryById (dict_id)) == NULL) |
|
339 return NULL; |
|
340 |
|
341 if ((fq_token & NW_WBXML_MASK_CPSTATE) == NW_WBXML_CP_STATE_TAG) |
|
342 { |
|
343 if (cp_index > (d->tag_page_count - 1)) |
|
344 return NULL; |
|
345 page = d->tag_pages[cp_index]; |
|
346 token &= NW_WBXML_MASK_TAG_ID; /* Only lowest 6 bits for tags */ |
|
347 } |
|
348 else |
|
349 { |
|
350 if (cp_index > (d->attr_page_count - 1)) |
|
351 return NULL; |
|
352 page = d->attr_pages[cp_index]; |
|
353 } |
|
354 |
|
355 |
|
356 return getTagByToken (&page, token); |
|
357 } |
|
358 |
|
359 NW_String_UCS2Buff_t * |
|
360 NW_WBXML_Dictionary_getElementNameByToken (NW_WBXML_Dictionary_t *dictionary, |
|
361 NW_Uint16 token) |
|
362 { |
|
363 NW_Byte cp_index = (NW_Byte) ((token & NW_WBXML_MASK_CODEPAGE) >> 8); |
|
364 NW_Byte tok = (NW_Byte) (token & NW_WBXML_MASK_TOKEN); |
|
365 NW_WBXML_Codepage_t page; |
|
366 |
|
367 if (dictionary == NULL) |
|
368 return NULL; |
|
369 |
|
370 if (cp_index > (dictionary->tag_page_count - 1)) |
|
371 return NULL; |
|
372 page = dictionary->tag_pages[cp_index]; |
|
373 tok &= NW_WBXML_MASK_TAG_ID; /* Only lowest 6 bits for tags */ |
|
374 return getTagByToken (&page, tok); |
|
375 } |
|
376 |
|
377 EXPORT_C NW_String_UCS2Buff_t * |
|
378 NW_WBXML_Dictionary_getAttributeNameByToken (NW_WBXML_Dictionary_t *dictionary, |
|
379 NW_Uint16 token) |
|
380 { |
|
381 NW_Byte cp_index = (NW_Byte) ((token & NW_WBXML_MASK_CODEPAGE) >> 8); |
|
382 NW_Byte tok = (NW_Byte) (token & NW_WBXML_MASK_TOKEN); |
|
383 NW_WBXML_Codepage_t page; |
|
384 |
|
385 if (dictionary == NULL) |
|
386 return NULL; |
|
387 |
|
388 if (cp_index > (dictionary->attr_page_count - 1)) |
|
389 return NULL; |
|
390 page = dictionary->attr_pages[cp_index]; |
|
391 return getTagByToken (&page, tok); |
|
392 } |
|
393 |
|
394 /* |
|
395 * These return the lower 16 bits of the fully qualified token |
|
396 * i.e., the token and code page. The rest of the token can be |
|
397 * constructed by the caller if needed. We don't use all 32 bits |
|
398 * in order to be able to return a signed quantity to indicate |
|
399 * failure. |
|
400 */ |
|
401 |
|
402 /* |
|
403 * Return -1 if the token is not found for the given attribute name or if |
|
404 * dictionary or name is 0 |
|
405 */ |
|
406 |
|
407 EXPORT_C NW_Int16 |
|
408 NW_WBXML_Dictionary_getAttributeToken (NW_WBXML_Dictionary_t * dictionary, |
|
409 const NW_String_t* name, |
|
410 NW_Uint32 encoding, |
|
411 NW_Bool matchCase) |
|
412 { |
|
413 NW_Int16 token = -1; |
|
414 NW_WBXML_Codepage_t *page; |
|
415 NW_Byte i; |
|
416 NW_Ucs2* ucs2Name; |
|
417 NW_Status_t status; |
|
418 |
|
419 if (dictionary == NULL || name == NULL){ |
|
420 return -1; |
|
421 } |
|
422 if (encoding != HTTP_iso_10646_ucs_2){ |
|
423 status = NW_String_stringToUCS2Char(name, encoding, &ucs2Name); |
|
424 NW_ASSERT(status == NW_STAT_SUCCESS); |
|
425 /* To fix TI compiler warning */ |
|
426 (void) status; |
|
427 } |
|
428 else{ |
|
429 ucs2Name = (NW_Ucs2*)name->storage; |
|
430 } |
|
431 |
|
432 for (i = 0; i < dictionary->attr_page_count; i++) |
|
433 { |
|
434 page = dictionary->attr_pages + i; |
|
435 /* this is a hack - ucs2buff types should be removed */ |
|
436 if ((token = getTokenByTag (page, (NW_String_UCS2Buff_t*) ucs2Name, matchCase)) >= 0){ |
|
437 token = (NW_Int16) (token | (i << 8)); |
|
438 break; |
|
439 } |
|
440 } |
|
441 if (encoding != HTTP_iso_10646_ucs_2){ |
|
442 NW_Mem_Free(ucs2Name); |
|
443 } |
|
444 return token; |
|
445 } |
|
446 |
|
447 NW_Status_t |
|
448 NW_WBXML_Dictionary_getAttributeToken2 (NW_WBXML_Dictionary_t * dictionary, |
|
449 NW_Uint32 encoding, |
|
450 NW_Uint32 charCount, |
|
451 NW_Uint8 * name, |
|
452 NW_Uint16 * pageToken, |
|
453 NW_Bool isName) |
|
454 { |
|
455 NW_WBXML_Codepage_t *page; |
|
456 NW_Byte i; |
|
457 NW_Status_t s; |
|
458 |
|
459 if (dictionary == NULL || name == NULL || pageToken == NULL) { |
|
460 return NW_STAT_FAILURE; |
|
461 } |
|
462 |
|
463 for (i = 0; i < dictionary->attr_page_count; i++) { |
|
464 page = dictionary->attr_pages + i; |
|
465 s = getTokenByTag2 (page, encoding, charCount, name, pageToken); |
|
466 if (NW_STAT_IS_FAILURE(s)) { |
|
467 /* failure may mean "not found" so continue to next page */ |
|
468 continue; |
|
469 } |
|
470 if (isName) { |
|
471 if (*pageToken >= 128) { |
|
472 s = getTokenByTag_HandleDuplicates (page, encoding, charCount, name, pageToken, isName); |
|
473 if (NW_STAT_IS_FAILURE(s)) { |
|
474 /* failure may mean "not found" so continue to next page */ |
|
475 continue; |
|
476 } |
|
477 } |
|
478 } else { |
|
479 if (*pageToken < 128) { |
|
480 s = getTokenByTag_HandleDuplicates (page, encoding, charCount, name, pageToken, isName); |
|
481 if (NW_STAT_IS_FAILURE(s)) { |
|
482 /* failure may mean "not found" so continue to next page */ |
|
483 continue; |
|
484 } |
|
485 } |
|
486 } |
|
487 *pageToken |= (i << 8); |
|
488 return NW_STAT_SUCCESS; |
|
489 } |
|
490 return NW_STAT_FAILURE; |
|
491 } |
|
492 |
|
493 NW_Status_t |
|
494 NW_WBXML_Dictionary_getAttributeNameToken (NW_WBXML_Dictionary_t * dictionary, |
|
495 NW_Uint32 encoding, |
|
496 NW_Uint32 charCount, |
|
497 NW_Uint8 * name, |
|
498 NW_Uint16 * pageToken) |
|
499 { |
|
500 return NW_WBXML_Dictionary_getAttributeToken2 (dictionary, encoding, |
|
501 charCount, name, pageToken, |
|
502 NW_TRUE); |
|
503 |
|
504 } |
|
505 |
|
506 NW_Status_t |
|
507 NW_WBXML_Dictionary_getAttributeValueToken (NW_WBXML_Dictionary_t * dictionary, |
|
508 NW_Uint32 encoding, |
|
509 NW_Uint32 charCount, |
|
510 NW_Uint8 * name, |
|
511 NW_Uint16 * pageToken) |
|
512 { |
|
513 return NW_WBXML_Dictionary_getAttributeToken2 (dictionary, encoding, |
|
514 charCount, name, pageToken, |
|
515 NW_FALSE); |
|
516 |
|
517 } |
|
518 |
|
519 /* |
|
520 * Return -1 if the token is not found for the given tag name or if |
|
521 * dictionary or name is 0 |
|
522 */ |
|
523 |
|
524 EXPORT_C NW_Int16 |
|
525 NW_WBXML_Dictionary_getTagToken (NW_WBXML_Dictionary_t * dictionary, |
|
526 NW_String_UCS2Buff_t * name, |
|
527 NW_Bool matchCase) |
|
528 { |
|
529 NW_Int16 token = 0; |
|
530 NW_WBXML_Codepage_t *page; |
|
531 NW_Byte i; |
|
532 |
|
533 if (dictionary == NULL || name == NULL) |
|
534 return -1; |
|
535 |
|
536 for (i = 0; i < dictionary->tag_page_count; i++) |
|
537 { |
|
538 page = dictionary->tag_pages + i; |
|
539 if ((token = getTokenByTag (page, name, matchCase)) >= 0) |
|
540 return (NW_Int16)(token | (i << 8)); |
|
541 } |
|
542 |
|
543 return -1; |
|
544 } |
|
545 |
|
546 NW_Status_t |
|
547 NW_WBXML_Dictionary_getTagToken2(NW_WBXML_Dictionary_t * dictionary, |
|
548 NW_Uint32 encoding, |
|
549 NW_Uint32 charCount, |
|
550 NW_Uint8* name, |
|
551 NW_Uint16* pageToken) |
|
552 { |
|
553 NW_WBXML_Codepage_t *page; |
|
554 NW_Byte i; |
|
555 NW_Status_t s; |
|
556 |
|
557 if (dictionary == NULL || name == NULL || pageToken == NULL) { |
|
558 return NW_STAT_FAILURE; |
|
559 } |
|
560 |
|
561 for (i = 0; i < dictionary->tag_page_count; i++) { |
|
562 page = dictionary->tag_pages + i; |
|
563 s = getTokenByTag2 (page, encoding, charCount, name, pageToken); |
|
564 if (NW_STAT_IS_FAILURE(s)) { |
|
565 /* failure may mean "not found" so continue to next page */ |
|
566 continue; |
|
567 } |
|
568 *pageToken |= (i << 8); |
|
569 return NW_STAT_SUCCESS; |
|
570 } |
|
571 return NW_STAT_FAILURE; |
|
572 } |
|
573 |
|
574 /* Linear searches are ok here since we only do these once */ |
|
575 |
|
576 /* |
|
577 * Return NULL if a dictionary is not found for the given public_id |
|
578 */ |
|
579 |
|
580 EXPORT_C |
|
581 NW_WBXML_Dictionary_t * |
|
582 NW_WBXML_Dictionary_getByPublicId (NW_Uint32 public_id) |
|
583 { |
|
584 //#ifdef __WINS__ |
|
585 NW_Uint32 i; |
|
586 NW_Uint32 dictionary_count = GetDictionaryCount(); |
|
587 NW_WBXML_Dictionary_t **dictionaries = GetDictionaries(); |
|
588 |
|
589 for (i = 0; i < dictionary_count; i++) |
|
590 { |
|
591 if (dictionaries[i]->public_id == public_id) |
|
592 return dictionaries[i]; |
|
593 } |
|
594 //#endif |
|
595 return NULL; |
|
596 } |
|
597 |
|
598 /* |
|
599 * Return NULL if a dictionary is not found for the given doc_type or if |
|
600 * doc_type is 0 |
|
601 */ |
|
602 |
|
603 NW_WBXML_Dictionary_t * |
|
604 NW_WBXML_Dictionary_getByDocType (NW_String_t * doc_type, NW_Uint32 encoding) |
|
605 { |
|
606 //#ifdef __WINS__ |
|
607 NW_Uint32 i; |
|
608 NW_Uint32 dictionary_count = GetDictionaryCount(); |
|
609 NW_WBXML_Dictionary_t **dictionaries = GetDictionaries(); |
|
610 |
|
611 if (doc_type == NULL) |
|
612 return NULL; |
|
613 |
|
614 for (i = 0; i < dictionary_count; i++) |
|
615 { |
|
616 if (NW_WBXML_Dictionary_CmpDictDocType(dictionaries[i], doc_type, encoding)){ |
|
617 return dictionaries[i]; |
|
618 } |
|
619 } |
|
620 //#endif |
|
621 return NULL; |
|
622 } |
|
623 |
|
624 /* Get the 1-based index into the dictionary table */ |
|
625 |
|
626 /* |
|
627 * Return 0 if the dictionary is not found |
|
628 */ |
|
629 |
|
630 NW_Uint32 |
|
631 NW_WBXML_Dictionary_getIndexByPublicId (NW_Uint32 public_id) |
|
632 { |
|
633 //#ifdef __WINS__ |
|
634 NW_Uint32 i; |
|
635 NW_Uint32 dictionary_count = GetDictionaryCount(); |
|
636 NW_WBXML_Dictionary_t **dictionaries = GetDictionaries(); |
|
637 |
|
638 for (i = 0; i < dictionary_count; i++) |
|
639 { |
|
640 if (dictionaries[i]->public_id == public_id) |
|
641 return i + 1; |
|
642 } |
|
643 //#endif |
|
644 return 0; |
|
645 } |
|
646 |
|
647 /* |
|
648 * Return 0 if the dictionary is not found or doc_type is 0 |
|
649 */ |
|
650 |
|
651 NW_Uint32 |
|
652 NW_WBXML_Dictionary_getIndexByDocType (NW_String_t * doc_type, NW_Uint32 encoding) |
|
653 { |
|
654 //#ifdef __WINS__ |
|
655 NW_Uint32 i; |
|
656 NW_Uint32 dictionary_count = GetDictionaryCount(); |
|
657 NW_WBXML_Dictionary_t **dictionaries = GetDictionaries(); |
|
658 |
|
659 if(doc_type == NULL){ |
|
660 return 0; |
|
661 } |
|
662 |
|
663 for (i = 0; i < dictionary_count; i++) { |
|
664 if (NW_WBXML_Dictionary_CmpDictDocType(dictionaries[i], doc_type, encoding)){ |
|
665 return i + 1; |
|
666 } |
|
667 } |
|
668 //#endif |
|
669 return 0; |
|
670 } |
|
671 |
|
672 NW_WBXML_Dictionary_t * |
|
673 NW_WBXML_Dictionary_getByIndex(NW_Uint32 dictIndex) |
|
674 { |
|
675 //#ifdef __WINS__ |
|
676 NW_WBXML_Dictionary_t **dictionaries = GetDictionaries(); |
|
677 |
|
678 if (dictIndex == 0){ |
|
679 return NULL; |
|
680 } |
|
681 return dictionaries[dictIndex -1]; |
|
682 //#else |
|
683 // return NULL; |
|
684 //#endif |
|
685 } |
|
686 |
|
687 /* |
|
688 * Given a tag or attribute token, if the token is a literal, |
|
689 * use the given name to lookup the tag/attribute's "real" token |
|
690 * and return that token. |
|
691 * |
|
692 * |
|
693 * Returns NW_STAT_SUCCESS |
|
694 * NW_STAT_FAILURE - if the token lookup fails (NOT fatal) |
|
695 * NW_STAT_OUT_OF_MEMORY |
|
696 */ |
|
697 |
|
698 EXPORT_C NW_Status_t |
|
699 NW_WBXML_Dictionary_resolveLiteralToken(NW_Uint32 *token, /* In/Out */ |
|
700 NW_String_t *name, /* Ask Deepika why NULL is allowed */ |
|
701 NW_Bool is_tag, /* NW_TRUE == token is for tag; |
|
702 NW_FALSE == attribute */ |
|
703 NW_Uint32 encoding, /* Used in the name conversion */ |
|
704 NW_Bool matchCase) |
|
705 { |
|
706 |
|
707 NW_Ucs2 * buff; |
|
708 NW_Uint32 dict_id = ((*token) & NW_WBXML_MASK_DICTIONARY) >> 16; |
|
709 NW_Int16 tmp_token; |
|
710 |
|
711 if (NW_WBXML_Dictionary_getTagByFqToken(*token) != NULL){ |
|
712 /* The token is NOT a literal, no need for further processing */ |
|
713 return NW_STAT_SUCCESS; |
|
714 } |
|
715 |
|
716 if(name == NULL){ /* TODO: Ask Deepika if this can be made an assert?? */ |
|
717 return NW_STAT_FAILURE; |
|
718 } |
|
719 |
|
720 /* |
|
721 * Before looking up the name in the dictionary, must convert |
|
722 * name to the type used in dictionary names. |
|
723 */ |
|
724 |
|
725 if (NW_String_stringToUCS2Char(name, encoding, &buff) != NW_STAT_SUCCESS) { |
|
726 return NW_STAT_OUT_OF_MEMORY; |
|
727 } |
|
728 |
|
729 tmp_token = (NW_Int16) ((is_tag == NW_TRUE) ? |
|
730 NW_WBXML_Dictionary_getTagToken(getDictionaryById(dict_id), (NW_String_UCS2Buff_t *) buff, matchCase) : |
|
731 NW_WBXML_Dictionary_getAttributeToken(getDictionaryById(dict_id), name, encoding, matchCase)); |
|
732 |
|
733 NW_Mem_Free (buff); |
|
734 |
|
735 if (tmp_token == -1) |
|
736 { |
|
737 return NW_STAT_FAILURE; |
|
738 } |
|
739 |
|
740 *token = ((NW_Uint16) dict_id << 16)| (NW_Uint16) tmp_token; |
|
741 |
|
742 return NW_STAT_SUCCESS; |
|
743 } |
|
744 |
|
745 |
|
746 /* 1. returns success, oom, or failure |
|
747 2. if oom or failure, no leaks and no residual memory allocations |
|
748 3. if oom or failure on return *ppDocType is NULL |
|
749 4 if success on return *ppDocType is a valid string or NULL if |
|
750 no matching dictionary or dictionary did not have a doc_type string. */ |
|
751 NW_Status_t |
|
752 NW_WBXML_Dictionary_publicId_to_doctypeString(NW_Uint32 publicId, |
|
753 NW_String_t** ppDocType) |
|
754 { |
|
755 NW_WBXML_Dictionary_t *pDictionary |
|
756 = NW_WBXML_Dictionary_getByPublicId (publicId); |
|
757 *ppDocType = NULL; |
|
758 if (pDictionary != NULL) { |
|
759 if (pDictionary->doc_type != NULL) { |
|
760 *ppDocType = NW_String_new(); |
|
761 if (*ppDocType != NULL) { |
|
762 if (NW_String_initialize(*ppDocType, pDictionary->doc_type, |
|
763 NW_WBXML_DICTIONARY_CHARSET) |
|
764 != NW_STAT_SUCCESS) { |
|
765 NW_String_delete(*ppDocType); |
|
766 *ppDocType = NULL; |
|
767 return NW_STAT_FAILURE; |
|
768 } |
|
769 } else { |
|
770 return NW_STAT_OUT_OF_MEMORY; |
|
771 } |
|
772 } |
|
773 } |
|
774 return NW_STAT_SUCCESS; |
|
775 } |
|
776 |
|