~ubuntu-branches/ubuntu/precise/kompozer/precise

« back to all changes in this revision

Viewing changes to mozilla/rdf/opendir/rdfparse.c

  • Committer: Bazaar Package Importer
  • Author(s): Anthony Yarusso
  • Date: 2007-08-27 01:11:03 UTC
  • Revision ID: james.westby@ubuntu.com-20070827011103-2jgf4s6532gqu2ka
Tags: upstream-0.7.10
ImportĀ upstreamĀ versionĀ 0.7.10

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 
2
/* ***** BEGIN LICENSE BLOCK *****
 
3
 * Version: NPL 1.1/GPL 2.0/LGPL 2.1
 
4
 *
 
5
 * The contents of this file are subject to the Netscape Public License
 
6
 * Version 1.1 (the "License"); you may not use this file except in
 
7
 * compliance with the License. You may obtain a copy of the License at
 
8
 * http://www.mozilla.org/NPL/
 
9
 *
 
10
 * Software distributed under the License is distributed on an "AS IS" basis,
 
11
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 
12
 * for the specific language governing rights and limitations under the
 
13
 * License.
 
14
 *
 
15
 * The Original Code is mozilla.org code.
 
16
 *
 
17
 * The Initial Developer of the Original Code is 
 
18
 * Netscape Communications Corporation.
 
19
 * Portions created by the Initial Developer are Copyright (C) 1998
 
20
 * the Initial Developer. All Rights Reserved.
 
21
 *
 
22
 * Contributor(s):
 
23
 *
 
24
 * Alternatively, the contents of this file may be used under the terms of
 
25
 * either the GNU General Public License Version 2 or later (the "GPL"), or 
 
26
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 
27
 * in which case the provisions of the GPL or the LGPL are applicable instead
 
28
 * of those above. If you wish to allow use of your version of this file only
 
29
 * under the terms of either the GPL or the LGPL, and not to allow others to
 
30
 * use your version of this file under the terms of the NPL, indicate your
 
31
 * decision by deleting the provisions above and replace them with the notice
 
32
 * and other provisions required by the GPL or the LGPL. If you do not delete
 
33
 * the provisions above, a recipient may use your version of this file under
 
34
 * the terms of any one of the NPL, the GPL or the LGPL.
 
35
 *
 
36
 * ***** END LICENSE BLOCK ***** */
 
37
 
 
38
 
 
39
#include "rdf-int.h"
 
40
#include <stdio.h>
 
41
 
 
42
 
 
43
char* error_string = NULL;
 
44
int lineNumber = 0;
 
45
 
 
46
static HashTable resourceHash = NULL;
 
47
static RDF_Resource gURL = NULL;
 
48
 
 
49
RDF_Resource 
 
50
getResource (char* key, int createp) {
 
51
  RDF_Resource existing = (RDF_Resource) HashLookup(resourceHash, key);
 
52
  if (existing) {
 
53
    return existing;
 
54
  } else if (createp){
 
55
    existing = (RDF_Resource)fgetMem(sizeof(RDF_ResourceStruct));
 
56
    existing->url = fcopyString(key);
 
57
    HashAdd(resourceHash, existing->url, existing);
 
58
    if (!gURL) {
 
59
      gURL = (RDF_Resource)fgetMem(sizeof(RDF_ResourceStruct));
 
60
      gURL->url = fcopyString("URL");
 
61
      HashAdd(resourceHash, gURL->url, gURL);
 
62
    }
 
63
    remoteStoreAdd(NULL, existing, gURL, existing->url, RDF_STRING_TYPE,1); 
 
64
    return existing;
 
65
  } else return NULL;
 
66
}
 
67
 
 
68
char* 
 
69
RDF_ResourceID (RDF_Resource u) {
 
70
  return u->url;
 
71
}
 
72
 
 
73
static char* MemBlock = 0;
 
74
size_t allocated = 0;
 
75
#define MEM_BLOCK_SIZE 10000
 
76
 
 
77
char*
 
78
fgetMem (size_t rsize) {
 
79
  char* ans = 0;
 
80
  size_t size = rsize + (4 - ldiv(rsize, 4).rem);  
 
81
  if (!MemBlock || (size >= (MEM_BLOCK_SIZE  - allocated))) {
 
82
          MemBlock = getMem(MEM_BLOCK_SIZE);
 
83
          allocated = 0;
 
84
  }
 
85
  ans = MemBlock;
 
86
  MemBlock = MemBlock + size;
 
87
  allocated = allocated + size;
 
88
  return ans;
 
89
}
 
90
 
 
91
void readRDFFile (char* file) {
 
92
  FILE* f = fopen(file, "r");   
 
93
  if (f) {
 
94
    RDFT rf = (RDFT)getRDFT(file, 1) ; 
 
95
    int ok = 1;
 
96
    char* buff  = (char*) malloc(100 * 1024);
 
97
    int len ;
 
98
    int i = 0;
 
99
    memset(buff, '\0', (100 * 1024));
 
100
    memset(rf, '\0', sizeof(RDF_FileStruct));
 
101
 
 
102
    rf->line = (char*)getMem(RDF_BUF_SIZE);
 
103
    rf->holdOver = (char*)getMem(RDF_BUF_SIZE);
 
104
    rf->depth = 1;
 
105
    rf->lastItem = rf->stack[0] ;
 
106
    while ((len = fread(buff, 1, (100 * 1024) -1, f)) > 0) {
 
107
      buff[len] = '\0';
 
108
      printf("[%i] ", i++);
 
109
      fflush(0);
 
110
      if (!(ok = parseNextRDFXMLBlobInt(rf, buff, len))) {
 
111
        printf("Error in RDF File\n");
 
112
      }
 
113
    }
 
114
    
 
115
    freeMem(rf->line);
 
116
    rf->line = NULL;
 
117
    freeMem(rf->holdOver);
 
118
    rf->holdOver = NULL;
 
119
    free(buff);
 
120
    printf("Finished reading %s\n", file); 
 
121
  } else  printf("Could not find %s\n", file);    
 
122
}
 
123
 
 
124
static HashTable rdftHash = NULL;
 
125
 
 
126
RDFT
 
127
getRDFT (char* key, int createp) {
 
128
  RDFT existing = (RDFT) HashLookup(rdftHash, key);
 
129
  if (existing) {
 
130
    return existing;
 
131
  } else if (createp){
 
132
    existing = (RDFT)getMem(sizeof(RDF_FileStruct));
 
133
    existing->url = fcopyString(key);
 
134
    HashAdd(rdftHash, existing->url, existing);
 
135
    return existing;
 
136
  } else return NULL;
 
137
}
 
138
 
 
139
void 
 
140
rdf_init () {
 
141
  error_string = getMem(1000);
 
142
  resourceHash = NewHashTable((int)0x00000FFF);
 
143
  rdftHash = NewHashTable((int)0x00000FFF);
 
144
}
 
145
 
 
146
int
 
147
rdf_DigestNewStuff (char* url, char* data, int len) {
 
148
  RDFT rf = (RDFT)getRDFT(url, 1) ; 
 
149
  int ok = 1;
 
150
  RDF_Resource u;
 
151
  unloadRDFT(rf);
 
152
  memset(rf, '\0', sizeof(RDF_FileStruct));
 
153
  rf->line = (char*)getMem(RDF_BUF_SIZE);
 
154
  rf->holdOver = (char*)getMem(RDF_BUF_SIZE);
 
155
  rf->depth = 1;
 
156
  rf->lastItem = rf->stack[0] ; 
 
157
  ok = parseNextRDFXMLBlobInt(rf, data, len);  
 
158
  /* if (!ok) unloadRDFT(rf); */
 
159
  freeMem(rf->line);
 
160
  rf->line = NULL;
 
161
  freeMem(rf->holdOver);
 
162
  rf->holdOver = NULL;
 
163
  return ok;
 
164
}
 
165
 
 
166
 
 
167
int
 
168
startsWith (const char* pattern, const char* uuid) {
 
169
  int l1 = strlen(pattern);
 
170
  int l2 = strlen(uuid);
 
171
  int n;
 
172
  if (l2 < l1) return 0;
 
173
  for (n = 0; n < l1; n++) {
 
174
    if (pattern[n] != uuid[n]) return 0;
 
175
  } 
 
176
  return 1;
 
177
}
 
178
 
 
179
char* 
 
180
getMem (size_t n) {
 
181
  return (char*) calloc(1, n);
 
182
}
 
183
 
 
184
void 
 
185
freeMem(void* item) {
 
186
  free(item);
 
187
}
 
188
 
 
189
char 
 
190
decodeEntityRef (char* string, int* stringIndexPtr, int len) {
 
191
  if (startsWith("lt;", string)) {
 
192
    *stringIndexPtr = *stringIndexPtr + 3;
 
193
    return '<';
 
194
  } else if (startsWith("gt;", string)) {
 
195
    *stringIndexPtr = *stringIndexPtr + 3;
 
196
    return '>';
 
197
  } else  if (startsWith("amp;", string)) {
 
198
    *stringIndexPtr = *stringIndexPtr + 4;
 
199
    return '&';
 
200
  } else return '&';
 
201
}
 
202
 
 
203
char *
 
204
copyStringIgnoreWhiteSpace(char* string)
 
205
{
 
206
   int len = strlen(string);
 
207
   char* buf = (char*)fgetMem(len + 1);
 
208
   int inWhiteSpace = 1;
 
209
   int buffIndex = 0;
 
210
   int stringIndex = 0;
 
211
 
 
212
   while (stringIndex < len) {
 
213
     char nextChar = *(string + stringIndex);
 
214
     int wsp = wsCharp(nextChar);
 
215
     if (!wsp) {
 
216
       if (nextChar == '&') {
 
217
         *(buf + buffIndex++) = decodeEntityRef(&string[stringIndex+1], 
 
218
                                                &stringIndex, len-stringIndex);
 
219
       } else {
 
220
         *(buf + buffIndex++) = nextChar;
 
221
       }
 
222
       inWhiteSpace = 0;
 
223
     } else if (!inWhiteSpace) {
 
224
       *(buf + buffIndex++) = ' ';
 
225
       inWhiteSpace = 1;
 
226
     } else {
 
227
       inWhiteSpace = 1;
 
228
     }
 
229
     stringIndex++;
 
230
   }
 
231
 
 
232
   return buf;
 
233
}
 
234
 
 
235
char *
 
236
getHref(char** attlist)
 
237
{
 
238
        char* ans = getAttributeValue(attlist, "resource");
 
239
        if (!ans) ans = getAttributeValue(attlist, "rdf:resource");
 
240
        return ans;
 
241
}
 
242
 
 
243
 
 
244
char *
 
245
getID(char** attlist)
 
246
{
 
247
        char* ans = getAttributeValue(attlist, "id");
 
248
        if (!ans) ans = getAttributeValue(attlist, "about"); 
 
249
        if (!ans) ans = getAttributeValue(attlist, "rdf:about");
 
250
        return ans;
 
251
}
 
252
 
 
253
 
 
254
int 
 
255
parseNextRDFXMLBlobInt(RDFT f, char* blob, int size) {
 
256
  int n, last, m;
 
257
  int somethingseenp = 0;
 
258
  n = last = 0; 
 
259
  while (n < size) {
 
260
    char c = blob[n];
 
261
    if ((c == '\n') || (c == '\r')) lineNumber++;
 
262
    m = 0;
 
263
    somethingseenp = 0;
 
264
    /*    memset(f->line, '\0', RDF_BUF_SIZE-1); */
 
265
    if (f->holdOver[0] != '\0') {
 
266
      memcpy(f->line, f->holdOver, strlen(f->holdOver));
 
267
      m = strlen(f->holdOver);
 
268
      somethingseenp = 1;
 
269
          f->holdOver[0] = '\0';
 
270
      /*    memset(f->holdOver, '\0', RDF_BUF_SIZE-1); */
 
271
    }   
 
272
    while ((n < size) && (wsCharp(c))  && (!somethingseenp)) {
 
273
      c = blob[++n]; 
 
274
      if ((c == '\n') || (c == '\r')) lineNumber++;
 
275
    }
 
276
    while ((m < RDF_BUF_SIZE-1) && (c != '<') && (c != '>')) {
 
277
      f->line[m] = c;
 
278
      m++;
 
279
      somethingseenp = (somethingseenp || (!(wsCharp(c))));
 
280
      n++;      
 
281
      if (n < size) c = blob[n]; 
 
282
      else break;
 
283
      if ((c == '\n') || (c == '\r')) lineNumber++;
 
284
    }
 
285
    f->line[m] = '\0';
 
286
    f->line[m+1] = '\0';
 
287
    if (c == '>') f->line[m] = c;
 
288
    n++;
 
289
    if (m > 0) {
 
290
      if ((c == '<') || (c == '>')) {
 
291
        last = n;
 
292
        if (c == '<') {
 
293
          f->holdOver[0] = '<'; 
 
294
          f->holdOver[1] = '\0';
 
295
                }
 
296
        if (somethingseenp == 1) {
 
297
          parseNextRDFToken(f, f->line);
 
298
        }
 
299
      } else if (size > last) {
 
300
        memcpy(f->holdOver, f->line, m);
 
301
        f->holdOver[m] = '\0';
 
302
      }
 
303
    } else if (c == '<') {
 
304
      f->holdOver[0] = '<';
 
305
      f->holdOver[1] = '\0';
 
306
    }
 
307
  }
 
308
  return(1);
 
309
}
 
310
 
 
311
char *
 
312
getAttributeValue (char** attlist, char* elName)
 
313
{
 
314
  size_t n = 0;
 
315
  if (!attlist) return NULL;
 
316
  while ((n < 2*MAX_ATTRIBUTES) && (*(attlist + n) != NULL)) {
 
317
    char* attname = *(attlist + n);
 
318
    char* base = strchr(attname, ':');
 
319
    if (base) attname = base + 1;
 
320
    if (strcmp(attname, elName) == 0) return *(attlist + n + 1);
 
321
    n = n + 2;
 
322
  }
 
323
  return NULL;
 
324
}
 
325
 
 
326
char* 
 
327
copyString (char* str) {
 
328
  char* ans = getMem(strlen(str)+1);
 
329
  if (ans) {
 
330
    memcpy(ans, str, strlen(str));
 
331
    return ans;
 
332
  } else return NULL;
 
333
}
 
334
 
 
335
char* 
 
336
fcopyString (char* str) {
 
337
  char* ans = fgetMem(strlen(str)+1);
 
338
  if (ans) {
 
339
    memcpy(ans, str, strlen(str));
 
340
    return ans;
 
341
  } else return NULL;
 
342
}
 
343
 
 
344
 
 
345
 
 
346
void
 
347
addElementProps (char** attlist, char* elementName, RDFT f, RDF_Resource obj)
 
348
{
 
349
  int count = 0;
 
350
  while (count < 2*MAX_ATTRIBUTES) {
 
351
    char* attName = attlist[count++];
 
352
    char* attValue = attlist[count++];
 
353
    char* baseName;
 
354
    if ((attName == NULL) || (attValue == NULL)) break;
 
355
    baseName  = strchr(attName, ':');
 
356
    if (baseName) attName = baseName + 1;
 
357
    if (startsWith("xmlns", attName)) {
 
358
      /* addNameSpace(attName, attValue, f); */
 
359
    } else if (!stringEquals(attName, "resource") && 
 
360
        !stringEquals(attName, "rdf:resource")  && 
 
361
        !stringEquals(attName, "about") && 
 
362
        !stringEquals(attName, "rdf:about") && 
 
363
        !stringEquals(attName, "tv") &&
 
364
        !stringEquals(attName, "id")) {
 
365
      remoteStoreAdd(f, obj, getResource(attName, 1), 
 
366
                   copyStringIgnoreWhiteSpace(attValue), 
 
367
                   RDF_STRING_TYPE, 1);
 
368
    }
 
369
  }
 
370
}
 
371
        
 
372
int
 
373
parseNextRDFToken (RDFT f, char* token)
 
374
{
 
375
  char* attlist[2*MAX_ATTRIBUTES+1];
 
376
  char* elementName;
 
377
 
 
378
  if (token[0] != '<')   {
 
379
    if ((f->status == EXPECTING_OBJECT) && (f->depth > 1)) {
 
380
      RDF_Resource u = f->stack[f->depth-2];
 
381
      RDF_Resource s = f->stack[f->depth-1];
 
382
      char* val      = copyStringIgnoreWhiteSpace(token);
 
383
      remoteStoreAdd(f, u, s, val , RDF_STRING_TYPE, 1);
 
384
          return 1;
 
385
    } else  {
 
386
      printf(error_string, "Did not expect \n\"%s\".\n Was expecting a tag.", token);
 
387
      return 0;
 
388
    } 
 
389
  } else if  (startsWith("<!--", token)) {
 
390
    return 1;
 
391
  } else if (token[1] == '?')  {
 
392
    return 1;
 
393
  } else if (token[1] == '/') {
 
394
    if ((f->status != EXPECTING_OBJECT) && (f->status != EXPECTING_PROPERTY)) {
 
395
      printf(error_string, "Did not expect %s. Something pretty screwed up", token);
 
396
      return 0;
 
397
    }
 
398
    if (f->depth > 0) f->depth--;
 
399
    f->status = (f->status == EXPECTING_OBJECT ? EXPECTING_PROPERTY : EXPECTING_OBJECT);
 
400
    return 1;
 
401
  } else if ((f->status == 0) && (startsWith("<RDF:RDF", token) || 
 
402
                                  startsWith("<RDF", token))) {
 
403
    f->status = EXPECTING_OBJECT;
 
404
    return 1;
 
405
  } else {
 
406
    int emptyElementp = (token[strlen(token)-2] == '/');  
 
407
    if ((f->status != EXPECTING_OBJECT) && (f->status != EXPECTING_PROPERTY)) return 1;
 
408
    if (!tokenizeElement(token, attlist, &elementName)) return 0;
 
409
    if (f->status == EXPECTING_OBJECT) {
 
410
      char* url = NULL;
 
411
      RDF_Resource obj;
 
412
      int count = 0;    
 
413
      url = getID(attlist);
 
414
      if (!url) {
 
415
        if (f->tagDepth > 2) {
 
416
          printf(error_string, "Unbalanced tags ");
 
417
        } else {
 
418
          printf(error_string, "Require a \"about\" attribute on %s", token);
 
419
        }
 
420
        return 0;
 
421
      }
 
422
      obj =  getResource(url, 1);
 
423
      addElementProps (attlist, elementName, f, obj) ;
 
424
      if (!stringEquals(elementName, "RDF:Description")) {
 
425
          RDF_Resource eln = getResource(elementName, 1);
 
426
          remoteStoreAdd(f, obj, getResource("type", 1), 
 
427
                       eln, RDF_RESOURCE_TYPE, 
 
428
                       1);        
 
429
      }
 
430
      if (f->depth > 1) {
 
431
        remoteStoreAdd(f, f->stack[f->depth-2], f->stack[f->depth-1], obj, 
 
432
                     RDF_RESOURCE_TYPE, 1);
 
433
      }
 
434
      if (!emptyElementp) {
 
435
        f->stack[f->depth++] = obj;
 
436
        f->status = EXPECTING_PROPERTY;
 
437
      }
 
438
    } else if (f->status == EXPECTING_PROPERTY) {
 
439
      char* url;
 
440
      RDF_Resource obj;
 
441
      int count = 0;
 
442
      url = getHref(attlist) ;      
 
443
      if (url) {
 
444
        RDF_Resource eln = getResource(elementName, 1);      
 
445
        obj =  getResource(url, 1);        
 
446
        addElementProps (attlist, elementName, f, obj) ;     
 
447
        remoteStoreAdd(f, f->stack[f->depth-1], eln, obj, RDF_RESOURCE_TYPE,  1);
 
448
        /* printf("%s %s %s\n", RDF_ResourceID(f->stack[f->depth-1]), 
 
449
               RDF_ResourceID(eln), url); */
 
450
      } 
 
451
      if (!emptyElementp) {
 
452
        f->stack[f->depth++] = getResource(elementName, 1);
 
453
        f->status = EXPECTING_OBJECT;
 
454
      }
 
455
    }
 
456
    return 1;
 
457
  }
 
458
}       
 
459
 
 
460
 
 
461
 
 
462
int
 
463
tokenizeElement (char* attr, char** attlist, char** elementName)
 
464
{
 
465
  size_t n = 1;
 
466
  size_t s = strlen(attr); 
 
467
  char c ;
 
468
  size_t m = 0;
 
469
  size_t atc = 0;
 
470
  char* base;
 
471
  int emptyTagp =  (attr[s-2] == '/');
 
472
  int inAttrNamep = 1;
 
473
  c = attr[n++]; 
 
474
  while (wsCharp(c)) {
 
475
    c = attr[n++];
 
476
  }
 
477
  *elementName = &attr[n-1];
 
478
  while (n < s) {
 
479
    if (wsCharp(c)) break;
 
480
    c = attr[n++];
 
481
  }
 
482
  attr[n-1] = '\0';
 
483
  while (atc < 2*MAX_ATTRIBUTES+1) {*(attlist + atc++) = NULL;}
 
484
  atc = 0;
 
485
  s = (emptyTagp ? s-2 : s-1);
 
486
  while (n < s) {
 
487
    int attributeOpenStringSeenp = 0;
 
488
    m = 0;
 
489
    c = attr[n++];
 
490
    while ((n <= s) && (atc < 2*MAX_ATTRIBUTES)) {
 
491
      if (inAttrNamep && (m > 0) && (wsCharp(c) || (c == '='))) {
 
492
        attr[n-1] = '\0';
 
493
        *(attlist + atc++) = &attr[n-m-1];
 
494
        break;
 
495
      }
 
496
      if  (!inAttrNamep && attributeOpenStringSeenp && (c == '"')) {
 
497
        attr[n-1] = '\0';
 
498
        *(attlist + atc++) = &attr[n-m-1];
 
499
        break;
 
500
      }
 
501
      if (inAttrNamep) {
 
502
        if ((m > 0) || (!wsCharp(c))) m++;
 
503
      } else {
 
504
        if (c == '"') {
 
505
          attributeOpenStringSeenp = 1;
 
506
        } else {
 
507
          if ((m > 0) || (!(wsCharp(c)))) m++;
 
508
        }
 
509
      }
 
510
      c = attr[n++];
 
511
    }
 
512
    inAttrNamep = (inAttrNamep ? 0 : 1);
 
513
  }
 
514
  base = strchr(*elementName, ':');
 
515
  if (base) *elementName = base+1;
 
516
  return 1;
 
517
}