.
1 /*
2 Copyright (C) 2015 Johan Mattsson
3
4 This library is free software; you can redistribute it and/or modify
5 it under the terms of the GNU Lesser General Public License as
6 published by the Free Software Foundation; either version 3 of the
7 License, or (at your option) any later version.
8
9 This library is distributed in the hope that it will be useful, but
10 WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
13 */
14
15 namespace Bird {
16
17 public class XmlData : XmlString {
18 int* start_tags;
19 int tags_capacity;
20 int tags_size;
21
22 internal bool error = false;
23
24 public XmlData (char* data, int length) {
25 base (data, length);
26
27 start_tags = null;
28 tags_capacity = 0;
29 tags_size = 0;
30
31 index_start_tags ();
32 }
33
34 ~XmlData () {
35 if (start_tags != null) {
36 delete start_tags;
37 start_tags = null;
38 }
39 }
40
41 public int get_index (XmlString start) {
42 int offset = (int) ((size_t) start.data - (size_t) data);
43 return offset;
44 }
45
46 public int find_next_tag_token (int index) {
47 int new_index;
48
49 if (index >= length) {
50 return -1;
51 }
52
53 for (int i = 0; i < tags_size; i++) {
54 new_index = start_tags[i];
55 if (new_index >= index) {
56
57 if (new_index == 0 && i > 0) { //FIXME:DELETE
58 return -1;
59 }
60
61 return new_index;
62 }
63 }
64
65 return -1;
66 }
67
68 void index_start_tags () {
69 const char first_bit = 1 << 7;
70 int i = 0;
71 char* d = data;
72
73 while (d[i] != '\0') {
74 if ((int) (d[i] & first_bit) == 0) {
75 if (d[i] == '<') {
76 add_tag (i);
77 }
78 }
79 i++;
80 }
81 }
82
83 void add_tag (int index) {
84 if (unlikely (tags_size == tags_capacity)) {
85 if (!increase_capacity ()) {
86 return;
87 }
88 }
89
90 start_tags[tags_size] = index;
91 tags_size++;
92 }
93
94 bool increase_capacity () {
95 int* tags;
96
97 tags_capacity += 512;
98 tags = (int*) try_malloc (tags_capacity * sizeof (int));
99
100 if (tags == null) {
101 tags_capacity = 0;
102
103 if (start_tags != null) {
104 delete start_tags;
105 start_tags = null;
106 tags_size = 0;
107 error = true;
108 }
109
110 warning ("Can not allocate xml data buffer.");
111 return false;
112 }
113
114 if (tags_size > 0) {
115 Posix.memcpy (tags, start_tags, tags_size * sizeof (int));
116 }
117
118 if (start_tags != null) {
119 delete start_tags;
120 }
121
122 start_tags = tags;
123
124 return true;
125 }
126
127 public void print_all () {
128 XmlString s;
129 int i = -1;
130 string e;
131
132 print("All tags:\n");
133
134 for (int j = 0; j < tags_size; j++) {
135 i = find_next_tag_token (i + 1);
136
137 if (i > -1) {
138 s = substring (i);
139 s = s.substring (0, s.index_of (">"));
140 s = s.substring (0, s.index_of (" "));
141 } else {
142 e = "error";
143 s = new XmlString (e, e.length);
144 }
145
146 int o = start_tags[j];
147 print (s.to_string () + " : " + ((string) (data + o)).ndup (4) + @" $o $j i: $i\n");
148 }
149 }
150 }
151
152 }
153