@@ -3,7 +3,6 @@ local Document = {}
3
3
local libxml2 = require (" xmlua.libxml2" )
4
4
local ffi = require (" ffi" )
5
5
local converter = require (" xmlua.converter" )
6
- local to_string = converter .to_string
7
6
8
7
local Serializable = require (" xmlua.serializable" )
9
8
local Searchable = require (" xmlua.searchable" )
@@ -29,6 +28,14 @@ function Document.lazy_load()
29
28
ProcessingInstruction = require (" xmlua.processing-instruction" )
30
29
end
31
30
31
+ local function print_dbg (...)
32
+ -- if ngx then
33
+ -- ngx.log(ngx.DEBUG, ...)
34
+ -- else
35
+ -- print(...)
36
+ -- end
37
+ end
38
+
32
39
local methods = {}
33
40
34
41
local metatable = {}
@@ -40,54 +47,54 @@ function metatable.__index(document, key)
40
47
end
41
48
42
49
function methods :root ()
43
- local root_element = libxml2 .xmlDocGetRootElement (self .document )
44
- if not root_element then
50
+ local node = libxml2 .xmlDocGetRootElement (self .raw_document )
51
+ if not node then
45
52
return nil
46
53
end
47
- return Element .new (self . document , root_element )
54
+ return Element .new (self , node )
48
55
end
49
56
50
57
function methods :parent ()
51
58
return nil
52
59
end
53
60
54
61
function methods :encoding ()
55
- return ffi .string (self .document .encoding )
62
+ return ffi .string (self .raw_document .encoding )
56
63
end
57
64
58
65
function methods :create_cdata_section (data )
59
66
local raw_cdata_section_node =
60
- libxml2 .xmlNewCDataBlock (self .document ,
67
+ libxml2 .xmlNewCDataBlock (self .raw_document ,
61
68
data ,
62
69
data :len ())
63
- return CDATASection .new (self . document , raw_cdata_section_node )
70
+ return CDATASection .new (self , raw_cdata_section_node )
64
71
end
65
72
66
73
function methods :create_comment (data )
67
74
local raw_comment_node =
68
75
libxml2 .xmlNewComment (data )
69
- return Comment .new (self . document , raw_comment_node )
76
+ return Comment .new (self , raw_comment_node )
70
77
end
71
78
72
79
function methods :create_document_fragment ()
73
80
local raw_document_fragment_node =
74
- libxml2 .xmlNewDocFragment (self .document )
75
- return DocumentFragment .new (self . document ,
81
+ libxml2 .xmlNewDocFragment (self .raw_document )
82
+ return DocumentFragment .new (self ,
76
83
raw_document_fragment_node )
77
84
end
78
85
79
86
function methods :create_document_type (name , external_id , system_id )
80
87
local raw_document_type =
81
- libxml2 .xmlCreateIntSubset (self .document , name , external_id , system_id )
82
- return DocumentType .new (self . document ,
88
+ libxml2 .xmlCreateIntSubset (self .raw_document , name , external_id , system_id )
89
+ return DocumentType .new (self ,
83
90
raw_document_type )
84
91
end
85
92
86
93
function methods :get_internal_subset ()
87
94
local raw_document_type =
88
- libxml2 .xmlGetIntSubset (self .document )
95
+ libxml2 .xmlGetIntSubset (self .raw_document )
89
96
if raw_document_type ~= nil then
90
- return DocumentType .new (self . document ,
97
+ return DocumentType .new (self ,
91
98
raw_document_type )
92
99
else
93
100
return nil
96
103
97
104
function methods :add_entity_reference (name )
98
105
local raw_entity_reference =
99
- libxml2 .xmlNewReference (self .document , name )
100
- return EntityReference .new (self . document ,
106
+ libxml2 .xmlNewReference (self .raw_document , name )
107
+ return EntityReference .new (self ,
101
108
raw_entity_reference )
102
109
end
103
110
104
111
function methods :create_namespace (href , prefix )
105
112
local raw_namespace =
106
113
libxml2 .xmlNewNs (self .node , href , prefix )
107
- return Namespace .new (self . document , raw_namespace )
114
+ return Namespace .new (self , raw_namespace )
108
115
end
109
116
110
117
function methods :create_processing_instruction (name , content )
111
118
local raw_processing_instruction =
112
119
libxml2 .xmlNewPI (name , content )
113
- return ProcessingInstruction .new (self . document ,
120
+ return ProcessingInstruction .new (self ,
114
121
raw_processing_instruction )
115
122
end
116
123
117
124
function methods :add_entity (entity_info )
118
125
local entity_type_name = entity_info [" entity_type" ]
119
126
local entity_type = converter .convert_entity_type_name (entity_type_name )
120
- local raw_entity = libxml2 .xmlAddDocEntity (self .document ,
127
+ local raw_entity = libxml2 .xmlAddDocEntity (self .raw_document ,
121
128
entity_info [" name" ],
122
129
entity_type ,
123
130
entity_info [" external_id" ],
@@ -127,14 +134,14 @@ function methods:add_entity(entity_info)
127
134
end
128
135
129
136
function methods :get_entity (name )
130
- local raw_entity = libxml2 .xmlGetDocEntity (self .document , name )
137
+ local raw_entity = libxml2 .xmlGetDocEntity (self .raw_document , name )
131
138
return converter .convert_xml_entity (raw_entity )
132
139
end
133
140
134
141
function methods :add_dtd_entity (entity_info )
135
142
local entity_type_name = entity_info [" entity_type" ]
136
143
local entity_type = converter .convert_entity_type_name (entity_type_name )
137
- local raw_dtd_entity = libxml2 .xmlAddDtdEntity (self .document ,
144
+ local raw_dtd_entity = libxml2 .xmlAddDtdEntity (self .raw_document ,
138
145
entity_info [" name" ],
139
146
entity_type ,
140
147
entity_info [" external_id" ],
@@ -144,7 +151,7 @@ function methods:add_dtd_entity(entity_info)
144
151
end
145
152
146
153
function methods :get_dtd_entity (name )
147
- local raw_dtd_entity = libxml2 .xmlGetDtdEntity (self .document , name )
154
+ local raw_dtd_entity = libxml2 .xmlGetDtdEntity (self .raw_document , name )
148
155
return converter .convert_xml_entity (raw_dtd_entity )
149
156
end
150
157
@@ -167,7 +174,7 @@ function Document.build(raw_document, tree)
167
174
168
175
local root = Element .build (document , tree [1 ], tree [2 ])
169
176
if not libxml2 .xmlDocSetRootElement (raw_document , root .node ) then
170
- root :unlink ()
177
+ -- root:unlink()
171
178
return nil
172
179
end
173
180
@@ -186,10 +193,22 @@ function Document.new(raw_document, errors)
186
193
if not errors then
187
194
errors = {}
188
195
end
196
+ local unlinked = {}
189
197
local document = {
190
- document = raw_document ,
198
+ raw_document = raw_document ,
191
199
errors = errors ,
200
+ unlinked = unlinked
192
201
}
202
+ ffi .gc (document .raw_document , function (pdocument )
203
+ for node in pairs (unlinked ) do
204
+ if node .parent == ffi .NULL then
205
+ print_dbg (" Free unlinked: " , node )
206
+ libxml2 .xmlFreeNode (node )
207
+ end
208
+ end
209
+ print_dbg (" xmlFreeDoc: " , pdocument )
210
+ libxml2 .xmlFreeDoc (pdocument )
211
+ end )
193
212
setmetatable (document , metatable )
194
213
return document
195
214
end
0 commit comments