.
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 public XmlData (char* data, int length) {
23 base (data, length);
24
25 start_tags = null;
26 tags_capacity = 0;
27 tags_size = 0;
28
29 index_start_tags ();
30 }
31
32 ~XmlData () {
33 if (start_tags != null) {
34 delete start_tags;
35 start_tags = null;
36 }
37 }
38
39 public int get_index (XmlString start) {
40 int offset = (int) ((size_t) start.data - (size_t) data);
41 return offset;
42 }
43
44 public int find_next_tag_token (int index) {
45 int new_index;
46
47 if (index >= length) {
48 return -1;
49 }
50
51 for (int i = 0; i < tags_size; i++) {
52 new_index = start_tags[i];
53 if (new_index >= index) {
54
55 if (new_index == 0 && i > 0) { //FIXME:DELETE
56 return -1;
57 }
58
59 return new_index;
60 }
61 }
62
63 return -1;
64 }
65
66 void index_start_tags () {
67 const char first_bit = 1 << 7;
68 int i = 0;
69 char* d = data;
70
71 while (d[i] != '\0') {
72 if ((int) (d[i] & first_bit) == 0) {
73 if (d[i] == '<') {
74 add_tag (i);
75 }
76 }
77 i++;
78 }
79 }
80
81 void add_tag (int index) {
82 if (unlikely (tags_size == tags_capacity)) {
83 if (!increase_capacity ()) {
84 return;
85 }
86 }
87
88 start_tags[tags_size] = index;
89 tags_size++;
90 }
91
92 bool increase_capacity () {
93 int* tags;
94
95 tags_capacity += 10;
96 tags = (int*) new int [tags_capacity];
97
98 if (tags == null) {
99 tags_capacity = 0;
100
101 if (start_tags != null) {
102 delete start_tags;
103 start_tags = null;
104 }
105
106 warning ("Can not allocate xml data buffer.");
107 return false;
108 }
109
110 if (tags_size > 0) {
111 Posix.memcpy (tags, start_tags, tags_size * sizeof (int));
112 }
113
114 if (start_tags != null) {
115 delete start_tags;
116 }
117
118 start_tags = tags;
119
120 return true;
121 }
122
123 public void print_all () {
124 XmlString s;
125 int i = -1;
126 string e;
127
128 print("All tags:\n");
129
130 for (int j = 0; j < tags_size; j++) {
131 i = find_next_tag_token (i + 1);
132
133 if (i > -1) {
134 s = substring (i);
135 s = s.substring (0, s.index_of (">"));
136 s = s.substring (0, s.index_of (" "));
137 } else {
138 e = "error";
139 s = new XmlString (e, e.length);
140 }
141
142 int o = start_tags[j];
143 print (s.to_string () + " : " + ((string) (data + o)).ndup (4) + @" $o $j i: $i\n");
144 }
145 }
146 }
147
148 }
149