xmlhash 1.2.2 → 1.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/History.txt +8 -0
- data/ext/xmlhash/xmlhash.c +60 -17
- data/lib/xmlhash/xmlhash.so +0 -0
- data/lib/xmlhash.rb +1 -1
- data/test/test_xmlhash.rb +13 -0
- metadata +4 -4
data/History.txt
CHANGED
data/ext/xmlhash/xmlhash.c
CHANGED
|
@@ -1,6 +1,16 @@
|
|
|
1
1
|
#include <assert.h>
|
|
2
2
|
#include <ruby.h>
|
|
3
|
-
#
|
|
3
|
+
#ifdef HAVE_RUBY_ST_H
|
|
4
|
+
# include <ruby/st.h>
|
|
5
|
+
#else
|
|
6
|
+
# include <st.h>
|
|
7
|
+
#endif
|
|
8
|
+
|
|
9
|
+
/* API_VERSION_CODE is only defined in those we want */
|
|
10
|
+
#ifdef HAVE_RUBY_ENCODING_H
|
|
11
|
+
# include <ruby/encoding.h>
|
|
12
|
+
#endif
|
|
13
|
+
|
|
4
14
|
#include <libxml/parser.h>
|
|
5
15
|
#include <libxml/xmlreader.h>
|
|
6
16
|
|
|
@@ -8,6 +18,9 @@ static VALUE m_current = Qnil;
|
|
|
8
18
|
static VALUE m_stack = Qnil;
|
|
9
19
|
static VALUE m_cstring = Qnil;
|
|
10
20
|
static VALUE m_result = Qnil;
|
|
21
|
+
#ifdef HAVE_RUBY_ENCODING_H
|
|
22
|
+
static rb_encoding *m_current_encoding = NULL;
|
|
23
|
+
#endif
|
|
11
24
|
|
|
12
25
|
void init_XmlhashParserData()
|
|
13
26
|
{
|
|
@@ -18,9 +31,10 @@ void init_XmlhashParserData()
|
|
|
18
31
|
|
|
19
32
|
void xml_hash_start_element(const xmlChar *name)
|
|
20
33
|
{
|
|
21
|
-
|
|
34
|
+
VALUE pair;
|
|
35
|
+
/* needed for further attributes */
|
|
22
36
|
m_current = rb_hash_new();
|
|
23
|
-
|
|
37
|
+
pair = rb_ary_new();
|
|
24
38
|
rb_ary_push(pair, rb_str_new2((const char*)name));
|
|
25
39
|
rb_ary_push(pair, m_current);
|
|
26
40
|
rb_ary_push(m_stack, pair);
|
|
@@ -29,18 +43,24 @@ void xml_hash_start_element(const xmlChar *name)
|
|
|
29
43
|
|
|
30
44
|
void xml_hash_end_element(const xmlChar *name)
|
|
31
45
|
{
|
|
46
|
+
VALUE pair, cname, chash, phash, obj;
|
|
47
|
+
|
|
32
48
|
assert(m_stack != Qnil);
|
|
33
|
-
|
|
49
|
+
pair = rb_ary_pop(m_stack);
|
|
34
50
|
assert(pair != Qnil);
|
|
35
|
-
|
|
36
|
-
|
|
51
|
+
cname = rb_ary_entry(pair, 0);
|
|
52
|
+
chash = rb_ary_entry(pair, 1);
|
|
37
53
|
assert(!strcmp((const char*)name, RSTRING_PTR(cname)));
|
|
38
54
|
|
|
39
55
|
if (rb_obj_is_kind_of(chash, rb_cHash) && RHASH_SIZE(chash) == 0) {
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
56
|
+
VALUE string;
|
|
57
|
+
const char *string_ptr;
|
|
58
|
+
long string_len;
|
|
59
|
+
|
|
60
|
+
/* now check if the cstring array contains non-empty string */
|
|
61
|
+
string = rb_ary_join(m_cstring, Qnil);
|
|
62
|
+
string_ptr = RSTRING_PTR(string);
|
|
63
|
+
string_len = RSTRING_LEN(string);
|
|
44
64
|
while (string_len > 0 && (string_ptr[0] == ' ' || string_ptr[0] == '\t' || string_ptr[0] == '\n')) {
|
|
45
65
|
string_ptr++;
|
|
46
66
|
string_len--;
|
|
@@ -48,7 +68,7 @@ void xml_hash_end_element(const xmlChar *name)
|
|
|
48
68
|
while (string_len > 0 && (string_ptr[string_len-1] == ' ' || string_ptr[string_len-1] == '\t' || string_ptr[string_len-1] == '\n')) {
|
|
49
69
|
string_len--;
|
|
50
70
|
}
|
|
51
|
-
|
|
71
|
+
/* avoid overwriting empty hash with empty string */
|
|
52
72
|
if (string_len > 0)
|
|
53
73
|
chash = string;
|
|
54
74
|
}
|
|
@@ -58,10 +78,9 @@ void xml_hash_end_element(const xmlChar *name)
|
|
|
58
78
|
}
|
|
59
79
|
|
|
60
80
|
pair = rb_ary_entry(m_stack, RARRAY_LEN(m_stack)-1);
|
|
61
|
-
|
|
62
|
-
VALUE phash = rb_ary_entry(pair, 1);
|
|
81
|
+
phash = rb_ary_entry(pair, 1);
|
|
63
82
|
|
|
64
|
-
|
|
83
|
+
obj = rb_hash_aref(phash, cname);
|
|
65
84
|
if (obj != Qnil) {
|
|
66
85
|
if (rb_obj_is_kind_of(obj, rb_cArray)) {
|
|
67
86
|
rb_ary_push(obj, chash);
|
|
@@ -72,20 +91,36 @@ void xml_hash_end_element(const xmlChar *name)
|
|
|
72
91
|
rb_hash_aset(phash, cname, nobj);
|
|
73
92
|
}
|
|
74
93
|
} else {
|
|
75
|
-
|
|
94
|
+
/* implement force_array */
|
|
76
95
|
rb_hash_aset(phash, cname, chash);
|
|
77
96
|
}
|
|
78
97
|
}
|
|
79
98
|
|
|
80
99
|
void xml_hash_add_attribute(const xmlChar *name, const xmlChar *value)
|
|
81
100
|
{
|
|
101
|
+
#ifdef HAVE_RUBY_ENCODING_H
|
|
102
|
+
VALUE v_name, v_value;
|
|
103
|
+
#endif
|
|
104
|
+
|
|
82
105
|
assert(m_current != Qnil);
|
|
106
|
+
#ifdef HAVE_RUBY_ENCODING_H
|
|
107
|
+
v_name = rb_external_str_new_with_enc((const char*)name, xmlStrlen(name), m_current_encoding);
|
|
108
|
+
v_value = rb_external_str_new_with_enc((const char*)value, xmlStrlen(value), m_current_encoding);
|
|
109
|
+
rb_hash_aset(m_current, v_name, v_value);
|
|
110
|
+
#else
|
|
83
111
|
rb_hash_aset(m_current, rb_str_new2((const char*)name), rb_str_new2((const char*)value));
|
|
112
|
+
#endif
|
|
84
113
|
}
|
|
85
114
|
|
|
86
115
|
void xml_hash_add_text(const xmlChar *text)
|
|
87
116
|
{
|
|
117
|
+
#ifdef HAVE_RUBY_ENCODING_H
|
|
118
|
+
VALUE str;
|
|
119
|
+
str = rb_external_str_new_with_enc((const char*)text, xmlStrlen(text), m_current_encoding);
|
|
120
|
+
rb_ary_push(m_cstring, str);
|
|
121
|
+
#else
|
|
88
122
|
rb_ary_push(m_cstring, rb_str_new2((const char*)text));
|
|
123
|
+
#endif
|
|
89
124
|
}
|
|
90
125
|
|
|
91
126
|
void processAttribute(xmlTextReaderPtr reader)
|
|
@@ -153,7 +188,10 @@ static VALUE parse_xml_hash(VALUE self, VALUE rb_xml)
|
|
|
153
188
|
int ret;
|
|
154
189
|
|
|
155
190
|
Check_Type(rb_xml, T_STRING);
|
|
156
|
-
|
|
191
|
+
#ifdef HAVE_RUBY_ENCODING_H
|
|
192
|
+
m_current_encoding = rb_enc_get(rb_xml);
|
|
193
|
+
#endif
|
|
194
|
+
|
|
157
195
|
data = (char*)calloc(RSTRING_LEN(rb_xml), sizeof(char));
|
|
158
196
|
memcpy(data, StringValuePtr(rb_xml), RSTRING_LEN(rb_xml));
|
|
159
197
|
|
|
@@ -173,13 +211,18 @@ static VALUE parse_xml_hash(VALUE self, VALUE rb_xml)
|
|
|
173
211
|
}
|
|
174
212
|
|
|
175
213
|
free(data);
|
|
214
|
+
#ifdef HAVE_RUBY_ENCODING_H
|
|
215
|
+
m_current_encoding = 0;
|
|
216
|
+
#endif
|
|
176
217
|
return m_result;
|
|
177
218
|
}
|
|
178
219
|
|
|
179
220
|
void Init_xmlhash()
|
|
180
221
|
{
|
|
222
|
+
VALUE mXmlhash;
|
|
223
|
+
|
|
181
224
|
LIBXML_TEST_VERSION
|
|
182
|
-
|
|
225
|
+
mXmlhash = rb_define_module("Xmlhash");
|
|
183
226
|
rb_define_singleton_method(mXmlhash, "parse", &parse_xml_hash, 1);
|
|
184
227
|
m_stack = rb_ary_new();
|
|
185
228
|
rb_global_variable(&m_stack);
|
data/lib/xmlhash/xmlhash.so
CHANGED
|
Binary file
|
data/lib/xmlhash.rb
CHANGED
data/test/test_xmlhash.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# encoding: UTF-8
|
|
2
|
+
|
|
1
3
|
require "test/unit"
|
|
2
4
|
require "xmlhash"
|
|
3
5
|
require 'json'
|
|
@@ -89,4 +91,15 @@ eos
|
|
|
89
91
|
assert_equal ret, rubyoutput
|
|
90
92
|
end
|
|
91
93
|
|
|
94
|
+
def test_encoding
|
|
95
|
+
xml = "<?xml version='1.0' encoding='UTF-8'?><name>Adrian Schröter</name>"
|
|
96
|
+
|
|
97
|
+
ret = Xmlhash.parse(xml)
|
|
98
|
+
assert_equal ret, "Adrian Schröter"
|
|
99
|
+
|
|
100
|
+
xml = "<?xml version='1.0' encoding='UTF-8'?><name value='Adrian Schröter'/>"
|
|
101
|
+
ret = Xmlhash.parse(xml)
|
|
102
|
+
assert_equal ret, {"value"=>"Adrian Schröter"}
|
|
103
|
+
end
|
|
104
|
+
|
|
92
105
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: xmlhash
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.2.
|
|
4
|
+
version: 1.2.4
|
|
5
5
|
prerelease:
|
|
6
6
|
platform: ruby
|
|
7
7
|
authors:
|
|
@@ -9,7 +9,7 @@ authors:
|
|
|
9
9
|
autorequire:
|
|
10
10
|
bindir: bin
|
|
11
11
|
cert_chain: []
|
|
12
|
-
date: 2012-
|
|
12
|
+
date: 2012-09-27 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: pkg-config
|
|
@@ -66,7 +66,7 @@ dependencies:
|
|
|
66
66
|
requirements:
|
|
67
67
|
- - ~>
|
|
68
68
|
- !ruby/object:Gem::Version
|
|
69
|
-
version: '3.
|
|
69
|
+
version: '3.1'
|
|
70
70
|
type: :development
|
|
71
71
|
prerelease: false
|
|
72
72
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -74,7 +74,7 @@ dependencies:
|
|
|
74
74
|
requirements:
|
|
75
75
|
- - ~>
|
|
76
76
|
- !ruby/object:Gem::Version
|
|
77
|
-
version: '3.
|
|
77
|
+
version: '3.1'
|
|
78
78
|
description: ! 'A small C module that wraps libxml2''s xmlreader to parse a XML
|
|
79
79
|
|
|
80
80
|
string into a ruby hash'
|