~ubuntu-branches/ubuntu/vivid/libxml-bare-perl/vivid

« back to all changes in this revision

Viewing changes to Bare.xs

  • Committer: Package Import Robot
  • Author(s): Nuno Carvalho, gregor herrmann, Salvatore Bonaccorso, Axel Beckert, Nuno Carvalho
  • Date: 2013-09-17 15:54:28 UTC
  • mfrom: (1.1.4)
  • Revision ID: package-import@ubuntu.com-20130917155428-4d0xb5cissw2323f
Tags: 0.53-1
* Team upload.

[ gregor herrmann ]
* debian/control: update {versioned,alternative} (build) dependencies.

[ Salvatore Bonaccorso ]
* Change Vcs-Git to canonical URI (git://anonscm.debian.org)
* Change search.cpan.org based URIs to metacpan.org based URIs

[ Axel Beckert ]
* debian/copyright: migrate pre-1.0 format to 1.0 using "cme fix dpkg-
  copyright"

[ Nuno Carvalho ]
* New upstream release.
* debian/copyright: update copyright years.
* debian/control: update standards version.
* debian/control: update debhelper required version, in order to pass all
  the hardening flags to EUMM.
* Add lintian override to apparently false-positive warning.
* Add set of patches accepted upstream but still not included in this
  release, visit https://rt.cpan.org/Public/Bug/Display.html?id=88155
  for details.

Show diffs side-by-side

added added

removed removed

Lines of Context:
7
7
#include "XSUB.h"
8
8
#include "parser.h"
9
9
 
10
 
struct nodec *root;
11
 
 
12
10
U32 vhash;
13
11
U32 chash;
14
12
U32 phash;
16
14
U32 cdhash;
17
15
U32 zhash;
18
16
U32 ahash;
 
17
U32 content_hash;
19
18
 
20
 
struct nodec *curnode;
21
19
char *rootpos;
22
20
 
23
 
/* -------------------------------------------------------------------- */
24
 
 
25
 
/*
26
 
*/
27
 
static SV *xml_dequote_string(unsigned char *src, STRLEN src_len)
28
 
{
29
 
  SV *dstSV;
30
 
  unsigned char *src2;
31
 
  unsigned char *dst;
32
 
  unsigned char c, c1, c2, c3, c4;
33
 
  STRLEN src_len2, dst_len;
34
 
 
35
 
  src2 = src;
36
 
  src_len2 = src_len;
37
 
  dst_len = src_len;
38
 
 
39
 
  // calculate dequoted string length
40
 
  while (src_len >= 3) {
41
 
    c = *src++;
42
 
    src_len--;
43
 
 
44
 
    if ('&' != c) {
45
 
      continue;
46
 
    }
47
 
 
48
 
    /* We have "&", now look for:- & " ' < > */
49
 
    c = *src;
50
 
    c1 = *(src + 1);
51
 
    c2 = *(src + 2);
52
 
    if (c2 == ';' && c1 == 't' && (c == 'l' || c == 'g')) {
53
 
      dst_len -= 3;
54
 
      src += 3;
55
 
      src_len -= 3;
56
 
      continue;
57
 
    }
58
 
 
59
 
    if (src_len >= 4) {
60
 
      c3 = *(src + 3);
61
 
    } else {
62
 
      continue;
63
 
    }
64
 
 
65
 
    if (c == 'a' && c1 == 'm' && c2 == 'p' && c3 == ';') {
66
 
      dst_len -= 4;
67
 
      src += 4;
68
 
      src_len -= 4;
69
 
      continue;
70
 
    }
71
 
 
72
 
    if (src_len >= 5) {
73
 
      c4 = *(src + 4);
74
 
    } else {
75
 
      continue;
76
 
    }
77
 
 
78
 
    if (c4 == ';'
79
 
        && ((c == 'q' && c1 == 'u' && c2 == 'o' && c3 == 't') || (c == 'a' && c1 == 'p' && c2 == 'o' && c3 == 's'))) {
80
 
      dst_len -= 5;
81
 
      src += 5;
82
 
      src_len -= 5;
83
 
      continue;
84
 
    }                           //if
85
 
  }                             //while
86
 
 
87
 
  if (dst_len == src_len2) {
88
 
    // nothing to dequote
89
 
    dstSV = newSVpv(src2, dst_len);
90
 
    return dstSV;
91
 
  }
92
 
 
93
 
  /* We have someting to dequote, so make a SV to put it into */
94
 
  dstSV = newSV(dst_len);
95
 
  SvCUR_set(dstSV, dst_len);
96
 
  SvPOK_on(dstSV);
97
 
  dst = SvPVX(dstSV);
98
 
 
99
 
  while (src_len2 >= 3) {       // 3 is min length of quoted symbol
100
 
    c = *src2++;
101
 
    src_len2--;
102
 
    if ('&' != c) {
103
 
      *dst++ = c;
104
 
      continue;
105
 
    }
106
 
    c = *src2;
107
 
    c1 = *(src2 + 1);
108
 
    c2 = *(src2 + 2);
109
 
 
110
 
    // 1. test len=3: < >
111
 
    if (c1 == 't' && c2 == ';') {
112
 
      if (c == 'l') {
113
 
        *dst++ = '<';
114
 
        src2 += 3;
115
 
        src_len2 -= 3;
116
 
        continue;
117
 
      } else if (c == 'g') {
118
 
        *dst++ = '>';
119
 
      } else {
120
 
        *dst++ = '&';
121
 
        continue;
122
 
      }
123
 
      src2 += 3;
124
 
      src_len2 -= 3;
125
 
      continue;
126
 
    }                           //if lt | gt
127
 
 
128
 
 
129
 
    // 2. test len=4: &amp;
130
 
    if (src_len2 >= 4) {
131
 
      c3 = *(src2 + 3);
132
 
    } else {
133
 
      *dst++ = '&';
134
 
      continue;
135
 
    }
136
 
 
137
 
    if (c == 'a' && c1 == 'm' && c2 == 'p' && c3 == ';') {
138
 
      *dst++ = '&';
139
 
      src2 += 4;
140
 
      src_len2 -= 4;
141
 
      continue;
142
 
    }
143
 
    // 3. test len=5: &quot; &apos;
144
 
    if (src_len2 >= 5) {
145
 
      c4 = *(src2 + 4);
146
 
    } else {
147
 
      *dst++ = '&';
148
 
      continue;
149
 
    }
150
 
 
151
 
    if (c4 == ';') {
152
 
      if (c == 'q' && c1 == 'u' && c2 == 'o' && c3 == 't') {
153
 
        *dst++ = '"';
154
 
      } else if (c == 'a' && c1 == 'p' && c2 == 'o' && c3 == 's') {
155
 
        *dst++ = '\'';
156
 
      } else {
157
 
        *dst++ = '&';
158
 
        continue;
159
 
      }
160
 
      src2 += 5;
161
 
      src_len2 -= 5;
162
 
      continue;
163
 
    }                           //if ;
164
 
 
165
 
    *dst++ = '&';
166
 
  }                             //while
167
 
 
168
 
 
169
 
  while (src_len2-- > 0) {      // also copy trailing \0
170
 
    *dst++ = *src2++;
171
 
  }
172
 
 
173
 
  return dstSV;
174
 
}
175
 
 
176
 
/* -------------------------------------------------------------------- */
177
 
 
178
 
SV *node_val_unescaped(struct nodec * thisnode)
179
 
{
180
 
  SV *sv;
181
 
 
182
 
  if (curnode->type == NODE_TYPE_ESCAPED)
183
 
    sv = xml_dequote_string(curnode->value, curnode->vallen);
184
 
  else
185
 
    sv = newSVpvn(curnode->value, curnode->vallen);
186
 
 
187
 
  SvUTF8_on(sv);
188
 
 
189
 
  return sv;
190
 
}
191
 
 
192
 
/* -------------------------------------------------------------------- */
193
 
 
194
 
SV *cxml2obj()
195
 
{
196
 
  HV *output = newHV();
197
 
  SV *outputref = newRV_noinc((SV *) output);
198
 
  int i;
199
 
  struct attc *curatt;
200
 
  int numatts = curnode->numatt;
 
21
//#define DEBUG
 
22
  
 
23
SV *cxml2obj( struct parserc *parser, struct nodec *curnode ) {
 
24
  HV *output = newHV(); // the root
 
25
  SV *outputref = newRV_noinc( (SV *) output ); // return a reference to the root
 
26
  int i; // loop index; defined at the top because this is C
 
27
  struct attc *curatt; // current attribute being worked with
 
28
  int numatts = curnode->numatt; // total number of attributes on the current node
201
29
  SV *attval;
202
30
  SV *attatt;
203
 
 
 
31
  int cur_type;
 
32
      
204
33
  int length = curnode->numchildren;
205
 
  SV *svi = newSViv(curnode->pos);
206
 
 
207
 
  hv_store(output, "_pos", 4, svi, phash);
208
 
  hv_store(output, "_i", 2, newSViv(curnode->name - rootpos), ihash);
209
 
  hv_store(output, "_z", 2, newSViv(curnode->z), zhash);
210
 
  if (!length) {
211
 
    if (curnode->vallen) {
212
 
      SV *sv = node_val_unescaped(curnode);
213
 
      hv_store(output, "value", 5, sv, vhash);
214
 
      if (curnode->type & NODE_TYPE_CDATA) {
215
 
        SV *svi = newSViv(1);
216
 
        hv_store(output, "_cdata", 6, svi, cdhash);
217
 
      }
218
 
    }
219
 
    if (curnode->comlen) {
220
 
      SV *sv = newSVpvn(curnode->comment, curnode->comlen);
221
 
      SvUTF8_on(sv);
222
 
      hv_store(output, "comment", 7, sv, chash);
223
 
    }
224
 
  } else {
225
 
    if (curnode->vallen) {
226
 
      SV *sv = node_val_unescaped(curnode);
227
 
      hv_store(output, "value", 5, sv, vhash);
228
 
      if (curnode->type & NODE_TYPE_CDATA) {
229
 
        SV *svi = newSViv(1);
230
 
        hv_store(output, "_cdata", 6, svi, cdhash);
231
 
      }
232
 
    }
233
 
    if (curnode->comlen) {
234
 
      SV *sv = newSVpvn(curnode->comment, curnode->comlen);
235
 
      SvUTF8_on(sv);
236
 
      hv_store(output, "comment", 7, sv, chash);
237
 
    }
238
 
 
 
34
  SV *svi = newSViv( curnode->pos );
 
35
  
 
36
  hv_store( output, "_pos", 4, svi, phash );
 
37
  hv_store( output, "_i", 2, newSViv( curnode->name - rootpos ), ihash );
 
38
  hv_store( output, "_z", 2, newSViv( curnode->z ), zhash );
 
39
  
 
40
  #ifdef DEBUG
 
41
  printf("Node: %.*s\n", curnode->namelen, curnode->name );
 
42
  #endif
 
43
  
 
44
  // node without children
 
45
  if( !length ) {
 
46
    if( curnode->vallen ) {
 
47
      SV * sv = newSVpvn( curnode->value, curnode->vallen );
 
48
      SvUTF8_on(sv);
 
49
      hv_store( output, "value", 5, sv, vhash );
 
50
      if( curnode->type ) {
 
51
        SV *svi = newSViv( 1 );
 
52
        hv_store( output, "_cdata", 6, svi, cdhash );
 
53
      }
 
54
    }
 
55
    if( curnode->comlen ) {
 
56
      SV * sv = newSVpvn( curnode->comment, curnode->comlen );
 
57
      SvUTF8_on(sv);
 
58
      hv_store( output, "comment", 7, sv, chash );
 
59
    }
 
60
  }
 
61
  
 
62
  // node with children
 
63
  else {
 
64
    if( curnode->vallen ) {
 
65
      SV *sv = newSVpvn( curnode->value, curnode->vallen );
 
66
      SvUTF8_on(sv);
 
67
      hv_store( output, "value", 5, sv, vhash );
 
68
      if( curnode->type ) {
 
69
        SV *svi = newSViv( 1 );
 
70
        hv_store( output, "_cdata", 6, svi, cdhash );
 
71
      }
 
72
    }
 
73
    if( curnode->comlen ) {
 
74
      SV *sv = newSVpvn( curnode->comment, curnode->comlen );
 
75
      SvUTF8_on(sv);
 
76
      hv_store( output, "comment", 7, sv, chash );
 
77
    }
 
78
    
 
79
    // loop through child nodes
239
80
    curnode = curnode->firstchild;
240
 
    for (i = 0; i < length; i++) {
241
 
      SV *key = newSVpv(curnode->name, curnode->namelen);
242
 
      SvUTF8_on(key);
243
 
      HE *curh = hv_fetch_ent(output, key, 0, 0);
244
 
 
245
 
      if (curnode->namelen > 6) {
246
 
        if (!strncmp(curnode->name, "multi_", 6)) {
247
 
          SV *subkey = newSVpv(&curnode->name[6], curnode->namelen - 6);
248
 
          SvUTF8_on(subkey);
249
 
          HE *oldh = hv_fetch_ent(output, subkey, 0, 0);
 
81
    for( i = 0; i < length; i++ ) {
 
82
      SV **cur = hv_fetch( output, curnode->name, curnode->namelen, 0 );
 
83
      
 
84
      // check for multi_[name] nodes
 
85
      if( curnode->namelen > 6 ) {
 
86
        if( !strncmp( curnode->name, "multi_", 6 ) ) {
 
87
          char *subname = &curnode->name[6];
 
88
          int subnamelen = curnode->namelen-6;
 
89
          SV **old = hv_fetch( output, subname, subnamelen, 0 );
250
90
          AV *newarray = newAV();
251
 
          SV *newarrayref = newRV_noinc((SV *) newarray);
252
 
          if (!oldh) {
253
 
            hv_store_ent(output, subkey, newarrayref, 0);
254
 
          } else {
255
 
            SV *old = HeVAL(oldh);
256
 
            if (SvTYPE(SvRV(old)) == SVt_PVHV) {        // check for hash ref
257
 
              SV *newref = newRV((SV *) SvRV(old));
258
 
              hv_delete_ent(output, subkey, 0, 0);
259
 
              hv_store_ent(output, subkey, newarrayref, 0);
260
 
              av_push(newarray, newref);
 
91
          SV *newarrayref = newRV_noinc( (SV *) newarray );
 
92
          if( !old ) {
 
93
            hv_store( output, subname, subnamelen, newarrayref, 0 );
 
94
          }
 
95
          else {
 
96
            if( SvTYPE( SvRV(*old) ) == SVt_PVHV ) { // check for hash ref
 
97
              SV *newref = newRV( (SV *) SvRV(*old) );
 
98
              hv_delete( output, subname, subnamelen, 0 );
 
99
              hv_store( output, subname, subnamelen, newarrayref, 0 );
 
100
              av_push( newarray, newref );
261
101
            }
262
102
          }
263
 
          SvREFCNT_dec(subkey); // no longer need the subkey
264
103
        }
265
104
      }
266
 
 
267
 
      if (!curh) {
268
 
        hv_store_ent(output, key, cxml2obj(), 0);
269
 
      } else {
270
 
        SV *cur = HeVAL(curh);
271
 
        if (SvTYPE(SvRV(cur)) == SVt_PVHV) {
 
105
      
 
106
      if( !cur ) {
 
107
        SV *ob = cxml2obj( parser, curnode );
 
108
        hv_store( output, curnode->name, curnode->namelen, ob, 0 );
 
109
      }
 
110
      else { // there is already a node stored with this name
 
111
        cur_type = SvTYPE( SvRV( *cur ) );
 
112
        if( cur_type == SVt_PVHV ) { // sub value is a hash; must be anode
272
113
          AV *newarray = newAV();
273
 
          SV *newarrayref = newRV_noinc((SV *) newarray);
274
 
          SV *newref = newRV((SV *) SvRV(cur));
275
 
          hv_delete_ent(output, key, 0, 0);
276
 
          hv_store_ent(output, key, newarrayref, 0);
277
 
          av_push(newarray, newref);
278
 
          av_push(newarray, cxml2obj());
279
 
        } else {
280
 
          AV *av = (AV *) SvRV(cur);
281
 
          av_push(av, cxml2obj());
 
114
          SV *newarrayref = newRV_noinc( (SV *) newarray );
 
115
          SV *newref = newRV( (SV *) SvRV( *cur ) );
 
116
          SV *ob;
 
117
          hv_delete( output, curnode->name, curnode->namelen, 0 );
 
118
          hv_store( output, curnode->name, curnode->namelen, newarrayref, 0 );
 
119
          av_push( newarray, newref );
 
120
          ob = cxml2obj( parser, curnode );
 
121
          av_push( newarray, ob );
 
122
        }
 
123
        else if( cur_type == SVt_PVAV ) {
 
124
          AV *av = (AV *) SvRV( *cur );
 
125
          SV *ob = cxml2obj( parser, curnode );
 
126
          av_push( av, ob );
 
127
        }
 
128
        else {
 
129
          // something else; probably an existing value node; just wipe it out
 
130
          SV *ob = cxml2obj( parser, curnode );
 
131
          hv_store( output, curnode->name, curnode->namelen, ob, 0 );
282
132
        }
283
133
      }
284
 
      if (i != (length - 1))
285
 
        curnode = curnode->next;
286
 
      SvREFCNT_dec(key);        // no longer need the key
 
134
      if( i != ( length - 1 ) ) curnode = curnode->next;
287
135
    }
288
 
 
 
136
    
289
137
    curnode = curnode->parent;
290
138
  }
291
 
 
292
 
  if (numatts) {
 
139
  
 
140
  if( numatts ) {
293
141
    curatt = curnode->firstatt;
294
 
    for (i = 0; i < numatts; i++) {
 
142
    for( i = 0; i < numatts; i++ ) {
295
143
      HV *atth = newHV();
296
 
      SV *atthref = newRV_noinc((SV *) atth);
297
 
      hv_store(output, curatt->name, curatt->namelen, atthref, 0);
298
 
 
299
 
      attval = newSVpvn(curatt->value, curatt->vallen);
 
144
      SV *atthref = newRV_noinc( (SV *) atth );
 
145
      hv_store( output, curatt->name, curatt->namelen, atthref, 0 );
 
146
      
 
147
      if( curatt->value == NULL ) attval = newSVpvn( "1", 1 );
 
148
      else attval = newSVpvn( curatt->value, curatt->vallen );
300
149
      SvUTF8_on(attval);
301
 
      hv_store(atth, "value", 5, attval, vhash);
302
 
      attatt = newSViv(1);
303
 
      hv_store(atth, "_att", 4, attatt, ahash);
304
 
      if (i != (numatts - 1))
305
 
        curatt = curatt->next;
 
150
      hv_store( atth, "value", 5, attval, vhash );
 
151
      attatt = newSViv( 1 );
 
152
      hv_store( atth, "_att", 4, attatt, ahash );
 
153
      if( i != ( numatts - 1 ) ) curatt = curatt->next;
306
154
    }
307
155
  }
308
156
  return outputref;
309
157
}
310
158
 
311
 
/* -------------------------------------------------------------------- */
312
 
 
313
 
SV *cxml2obj_simple()
314
 
{
 
159
SV *cxml2obj_simple( struct parserc *parser, struct nodec *curnode ) {
315
160
  int i;
316
161
  struct attc *curatt;
317
162
  int numatts = curnode->numatt;
321
164
  SV *attatt;
322
165
  HV *output;
323
166
  SV *outputref;
324
 
 
 
167
  
325
168
  int length = curnode->numchildren;
326
 
  if ((length + numatts) == 0) {
327
 
    if (curnode->vallen)
328
 
      return node_val_unescaped(curnode);
329
 
    else
330
 
      return newSVpv("", 0);    // an empty tag has empty string content
 
169
  if( ( length + numatts ) == 0 ) {
 
170
    if( curnode->vallen ) {
 
171
      SV * sv = newSVpvn( curnode->value, curnode->vallen );
 
172
      SvUTF8_on(sv);
 
173
      return sv;
 
174
    }
 
175
    return newSVpvn( "", 0 );
331
176
  }
332
 
 
 
177
  
333
178
  output = newHV();
334
 
  outputref = newRV_noinc((SV *) output);
335
 
 
336
 
  if (length) {
 
179
  outputref = newRV_noinc( (SV *) output );
 
180
  
 
181
  if( length ) {
337
182
    curnode = curnode->firstchild;
338
 
    for (i = 0; i < length; i++) {
339
 
      SV *key = newSVpv(curnode->name, curnode->namelen);
340
 
      SvUTF8_on(key);
341
 
      HE *curh = hv_fetch_ent(output, key, 0, 0);
342
 
 
343
 
      if (curnode->namelen > 6) {
344
 
        if (!strncmp(curnode->name, "multi_", 6)) {
345
 
          SV *subkey = newSVpv(&curnode->name[6], curnode->namelen - 6);
346
 
          SvUTF8_on(subkey);
347
 
          HE *oldh = hv_fetch_ent(output, subkey, 0, 0);
 
183
    for( i = 0; i < length; i++ ) {
 
184
      SV *namesv = newSVpvn( curnode->name, curnode->namelen );
 
185
      SvUTF8_on(namesv);
 
186
      
 
187
      SV **cur = hv_fetch( output, curnode->name, curnode->namelen, 0 );
 
188
      
 
189
      if( curnode->namelen > 6 ) {
 
190
        if( !strncmp( curnode->name, "multi_", 6 ) ) {
 
191
          char *subname = &curnode->name[6];
 
192
          int subnamelen = curnode->namelen-6;
 
193
          SV **old = hv_fetch( output, subname, subnamelen, 0 );
348
194
          AV *newarray = newAV();
349
 
          SV *newarrayref = newRV_noinc((SV *) newarray);
350
 
          if (!oldh) {
351
 
            hv_store_ent(output, subkey, newarrayref, 0);
352
 
          } else {
353
 
            SV *old = HeVAL(oldh);
354
 
            if (SvTYPE(SvRV(old)) == SVt_PVHV) {        // check for hash ref
355
 
              SV *newref = newRV((SV *) SvRV(old));
356
 
              hv_delete_ent(output, subkey, 0, 0);
357
 
              hv_store_ent(output, subkey, newarrayref, 0);
358
 
              av_push(newarray, newref);
 
195
          SV *newarrayref = newRV_noinc( (SV *) newarray );
 
196
          if( !old ) {
 
197
            hv_store( output, subname, subnamelen, newarrayref, 0 );
 
198
          }
 
199
          else {
 
200
            if( SvTYPE( SvRV(*old) ) == SVt_PVHV ) { // check for hash ref
 
201
              SV *newref = newRV_noinc( (SV *) SvRV(*old) );
 
202
              hv_delete( output, subname, subnamelen, 0 );
 
203
              hv_store( output, subname, subnamelen, newarrayref, 0 );
 
204
              av_push( newarray, newref );
359
205
            }
360
206
          }
361
 
          SvREFCNT_dec(subkey); // no longer need the subkey
362
207
        }
363
208
      }
364
 
 
365
 
      if (!curh) {
366
 
        hv_store_ent(output, key, cxml2obj_simple(), 0);
367
 
      } else {
368
 
        SV *cur = HeVAL(curh);
369
 
        if (SvROK(cur)) {
370
 
          if (SvTYPE(SvRV(cur)) == SVt_PVHV) {
 
209
        
 
210
      if( !cur ) {
 
211
        SV *ob = cxml2obj_simple( parser, curnode );
 
212
        hv_store( output, curnode->name, curnode->namelen, ob, 0 );
 
213
      }
 
214
      else {
 
215
        if( SvROK( *cur ) ) {
 
216
          if( SvTYPE( SvRV(*cur) ) == SVt_PVHV ) {
371
217
            AV *newarray = newAV();
372
 
            SV *newarrayref = newRV_noinc((SV *) newarray);
373
 
            SV *newref = newRV((SV *) SvRV(cur));
374
 
            hv_delete_ent(output, key, 0, 0);
375
 
            hv_store_ent(output, key, newarrayref, 0);
376
 
            av_push(newarray, newref);
377
 
            av_push(newarray, cxml2obj_simple());
378
 
          } else {
379
 
            AV *av = (AV *) SvRV(cur);
380
 
            av_push(av, cxml2obj_simple());
381
 
          }
382
 
        } else {
 
218
            SV *newarrayref = newRV_noinc( (SV *) newarray );
 
219
            SV *newref = newRV( (SV *) SvRV( *cur ) );
 
220
            hv_delete( output, curnode->name, curnode->namelen, 0 );
 
221
            hv_store( output, curnode->name, curnode->namelen, newarrayref, 0 );
 
222
            av_push( newarray, newref );
 
223
            av_push( newarray, cxml2obj_simple( parser, curnode ) );
 
224
          }
 
225
          else {
 
226
            AV *av = (AV *) SvRV( *cur );
 
227
            av_push( av, cxml2obj_simple( parser, curnode ) );
 
228
          }
 
229
        }
 
230
        else {
383
231
          AV *newarray = newAV();
384
 
          SV *newarrayref = newRV_noinc((SV *) newarray);
385
 
 
 
232
          SV *newarrayref = newRV( (SV *) newarray );
 
233
          
386
234
          STRLEN len;
387
 
          char *ptr = SvPV(cur, len);
388
 
          SV *newsv = newSVpvn(ptr, len);
 
235
          char *ptr = SvPV(*cur, len);
 
236
          SV *newsv = newSVpvn( ptr, len );
389
237
          SvUTF8_on(newsv);
390
 
 
391
 
          av_push(newarray, newsv);
392
 
          hv_delete_ent(output, key, 0, 0);
393
 
          hv_store_ent(output, key, newarrayref, 0);
394
 
          av_push(newarray, cxml2obj_simple());
 
238
          
 
239
          av_push( newarray, newsv );
 
240
          hv_delete( output, curnode->name, curnode->namelen, 0 );
 
241
          hv_store( output, curnode->name, curnode->namelen, newarrayref, 0 );
 
242
          av_push( newarray, cxml2obj_simple( parser, curnode ) );
395
243
        }
396
244
      }
397
 
      if (i != (length - 1))
398
 
        curnode = curnode->next;
399
 
      SvREFCNT_dec(key);        // no longer need the key
 
245
      if( i != ( length - 1 ) ) curnode = curnode->next;
400
246
    }
401
247
    curnode = curnode->parent;
402
 
  } else {
403
 
    SV *sv = node_val_unescaped(curnode);
404
 
    hv_store(output, "content", 7, sv, vhash);
405
 
  }
406
 
 
407
 
  if (numatts) {
 
248
  }
 
249
  else {
 
250
    if( curnode->type ) { // store cdata value under content, even if empty or spaces
 
251
      SV * sv = newSVpvn( curnode->value, curnode->vallen );
 
252
      SvUTF8_on(sv);
 
253
      hv_store( output, "content", 7, sv, content_hash );
 
254
    }
 
255
    else {
 
256
      int hasval = 0;
 
257
      for( i=0;i<curnode->vallen;i++ ) {
 
258
        char let = curnode->value[ i ];
 
259
        if( let != ' ' && let != 0x0d && let != 0x0a ) {
 
260
          hasval = 1;
 
261
          break;
 
262
        }
 
263
      }
 
264
      if( hasval ) {
 
265
        SV * sv = newSVpvn( curnode->value, curnode->vallen );
 
266
        SvUTF8_on(sv);
 
267
        hv_store( output, "content", 7, sv, content_hash );
 
268
      }
 
269
    }
 
270
  }
 
271
  
 
272
  if( numatts ) {
408
273
    curatt = curnode->firstatt;
409
 
    for (i = 0; i < numatts; i++) {
410
 
      attval = newSVpvn(curatt->value, curatt->vallen);
 
274
    for( i = 0; i < numatts; i++ ) {
 
275
      if( curatt->value == NULL ) attval = newSVpvn( "1", 1 );
 
276
      else attval = newSVpvn( curatt->value, curatt->vallen );
411
277
      SvUTF8_on(attval);
412
 
      hv_store(output, curatt->name, curatt->namelen, attval, 0);
413
 
      if (i != (numatts - 1))
414
 
        curatt = curatt->next;
 
278
      hv_store( output, curatt->name, curatt->namelen, attval, 0 );
 
279
      if( i != ( numatts - 1 ) ) curatt = curatt->next;
415
280
    }
416
281
  }
417
 
 
 
282
  
418
283
  return outputref;
419
284
}
420
285
 
421
 
/* -------------------------------------------------------------------- */
422
 
 
423
 
// *INDENT-OFF*
424
 
// Indent and XS declarations do not mix well :-(
 
286
void init_hashes() {
 
287
  PERL_HASH(vhash, "value", 5);
 
288
  PERL_HASH(ahash, "_att", 4);
 
289
  PERL_HASH(chash, "comment", 7);
 
290
  PERL_HASH(phash, "_pos", 4);
 
291
  PERL_HASH(ihash, "_i", 2 );
 
292
  PERL_HASH(zhash, "_z", 2 );
 
293
  PERL_HASH(cdhash, "_cdata", 6 );
 
294
}
425
295
 
426
296
MODULE = XML::Bare         PACKAGE = XML::Bare
427
297
 
428
298
SV *
429
 
xml2obj()
 
299
xml2obj( parsersv )
 
300
  SV *parsersv
430
301
  CODE:
431
 
    if( root->err ) RETVAL = newSViv( root->err );
 
302
    struct parserc *parser;
 
303
    parser = INT2PTR( struct parserc *, SvUV( parsersv ) );
 
304
    if( parser->err ) RETVAL = newSViv( parser->err );
432
305
    else {
433
 
      curnode = root;
434
 
      RETVAL = cxml2obj();
 
306
      RETVAL = cxml2obj( parser, parser->rootnode );
 
307
      //printf("refcnt: %i\n", SvREFCNT( RETVAL ) );
435
308
    }
436
309
  OUTPUT:
437
310
    RETVAL
438
311
    
439
312
SV *
440
 
xml2obj_simple()
441
 
  CODE:
442
 
    PERL_HASH(vhash, "content", 7);
443
 
    curnode = root;
444
 
    RETVAL = cxml2obj_simple();
445
 
  OUTPUT:
446
 
    RETVAL
447
 
 
448
 
void
 
313
xml2obj_simple( parsersv )
 
314
  SV *parsersv
 
315
  CODE:
 
316
    PERL_HASH( content_hash, "content", 7 );
 
317
    struct parserc *parser;
 
318
    parser = INT2PTR( struct parserc *, SvUV( parsersv ) );
 
319
    if( parser->err ) RETVAL = newSViv( parser->err );
 
320
    else {
 
321
      RETVAL = cxml2obj_simple( parser, parser->rootnode );
 
322
      //printf("refcnt: %i\n", SvREFCNT( RETVAL ) );
 
323
    }
 
324
  OUTPUT:
 
325
    RETVAL
 
326
 
 
327
SV *
 
328
c_parse_more( text, parsersv )
 
329
  char * text
 
330
  SV *parsersv
 
331
  CODE:
 
332
    struct parserc *parser = INT2PTR( struct parserc *, SvUV( parsersv ) );
 
333
    int err = parserc_parse( parser, text );
 
334
    RETVAL = newSVuv( PTR2UV( parser ) );
 
335
  OUTPUT:
 
336
    RETVAL
 
337
 
 
338
SV *
449
339
c_parse(text)
450
340
  char * text
451
341
  CODE:
452
 
    rootpos = text;
453
 
    PERL_HASH(vhash, "value", 5);
454
 
    PERL_HASH(ahash, "_att", 4);
455
 
    PERL_HASH(chash, "comment", 7);
456
 
    PERL_HASH(phash, "_pos", 4);
457
 
    PERL_HASH(ihash, "_i", 2 );
458
 
    PERL_HASH(zhash, "_z", 2 );
459
 
    PERL_HASH(cdhash, "_cdata", 6 );
460
 
    root = parserc_parse( text );
461
 
 
462
 
void
 
342
    init_hashes();
 
343
    
 
344
    struct parserc *parser = (struct parserc *) malloc( sizeof( struct parserc ) );
 
345
    parser->last_state = 0;
 
346
    int err = parserc_parse( parser, text );
 
347
    RETVAL = newSVuv( PTR2UV( parser ) );
 
348
  OUTPUT:
 
349
    RETVAL
 
350
 
 
351
SV *
 
352
c_parse_unsafely(text)
 
353
  char * text
 
354
  CODE:
 
355
    init_hashes();
 
356
    
 
357
    struct parserc *parser = (struct parserc *) malloc( sizeof( struct parserc ) );
 
358
    parser->last_state = 0;
 
359
    int err = parserc_parse_unsafely( parser, text );
 
360
    RETVAL = newSVuv( PTR2UV( parser ) );
 
361
  OUTPUT:
 
362
    RETVAL
 
363
 
 
364
SV *
463
365
c_parsefile(filename)
464
366
  char * filename
465
367
  CODE:
467
369
    unsigned long len;
468
370
    FILE *handle;
469
371
    
470
 
    PERL_HASH(vhash, "value", 5);
471
 
    PERL_HASH(ahash, "_att", 4);
472
 
    PERL_HASH(chash, "comment", 7);
473
 
    PERL_HASH(phash, "_pos", 4);
474
 
    PERL_HASH(ihash, "_i", 2 );
475
 
    PERL_HASH(zhash, "_z", 2 );
476
 
    PERL_HASH(cdhash, "_cdata", 6 );
 
372
    init_hashes();
477
373
    
478
374
    handle = fopen(filename,"r");
479
375
    
486
382
    rootpos = data;
487
383
    fread( data, 1, len, handle );
488
384
    fclose( handle );
489
 
    root = parserc_parse( data );
490
 
    free( data );
491
 
 
492
 
SV *
493
 
get_root()
494
 
  CODE:
495
 
    RETVAL = newSVuv( PTR2UV( root ) );
 
385
    struct parserc *parser = (struct parserc *) malloc( sizeof( struct parserc ) );
 
386
    parser->last_state = 0;
 
387
    int err = parserc_parse( parser, data );
 
388
    //free( parser );
 
389
    RETVAL = newSVuv( PTR2UV( parser ) );
496
390
  OUTPUT:
497
391
    RETVAL
498
392
 
499
393
void
500
 
free_tree_c( rootsv )
501
 
  SV *rootsv
 
394
free_tree_c( parsersv )
 
395
  SV *parsersv
502
396
  CODE:
503
 
    struct nodec *rootnode;
504
 
    rootnode = INT2PTR( struct nodec *, SvUV( rootsv ) );
505
 
    del_nodec( rootnode );
 
397
    struct parserc *parser;
 
398
    parser = INT2PTR( struct parserc *, SvUV( parsersv ) );
 
399
    struct nodec *rootnode = parser->rootnode;
 
400
    del_nodec( rootnode ); // note this frees the pointer as well
 
401
    free( parser );
 
 
b'\\ No newline at end of file'