@@ -3,7 +3,6 @@ local Document = {}
33local libxml2 = require (" xmlua.libxml2" )
44local ffi = require (" ffi" )
55local converter = require (" xmlua.converter" )
6- local to_string = converter .to_string
76
87local Serializable = require (" xmlua.serializable" )
98local Searchable = require (" xmlua.searchable" )
@@ -29,6 +28,14 @@ function Document.lazy_load()
2928 ProcessingInstruction = require (" xmlua.processing-instruction" )
3029end
3130
31+ local function print_dbg (...)
32+ -- if ngx then
33+ -- ngx.log(ngx.DEBUG, ...)
34+ -- else
35+ -- print(...)
36+ -- end
37+ end
38+
3239local methods = {}
3340
3441local metatable = {}
@@ -40,54 +47,54 @@ function metatable.__index(document, key)
4047end
4148
4249function 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
4552 return nil
4653 end
47- return Element .new (self . document , root_element )
54+ return Element .new (self , node )
4855end
4956
5057function methods :parent ()
5158 return nil
5259end
5360
5461function methods :encoding ()
55- return ffi .string (self .document .encoding )
62+ return ffi .string (self .raw_document .encoding )
5663end
5764
5865function methods :create_cdata_section (data )
5966 local raw_cdata_section_node =
60- libxml2 .xmlNewCDataBlock (self .document ,
67+ libxml2 .xmlNewCDataBlock (self .raw_document ,
6168 data ,
6269 data :len ())
63- return CDATASection .new (self . document , raw_cdata_section_node )
70+ return CDATASection .new (self , raw_cdata_section_node )
6471end
6572
6673function methods :create_comment (data )
6774 local raw_comment_node =
6875 libxml2 .xmlNewComment (data )
69- return Comment .new (self . document , raw_comment_node )
76+ return Comment .new (self , raw_comment_node )
7077end
7178
7279function methods :create_document_fragment ()
7380 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 ,
7683 raw_document_fragment_node )
7784end
7885
7986function methods :create_document_type (name , external_id , system_id )
8087 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 ,
8390 raw_document_type )
8491end
8592
8693function methods :get_internal_subset ()
8794 local raw_document_type =
88- libxml2 .xmlGetIntSubset (self .document )
95+ libxml2 .xmlGetIntSubset (self .raw_document )
8996 if raw_document_type ~= nil then
90- return DocumentType .new (self . document ,
97+ return DocumentType .new (self ,
9198 raw_document_type )
9299 else
93100 return nil
96103
97104function methods :add_entity_reference (name )
98105 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 ,
101108 raw_entity_reference )
102109end
103110
104111function methods :create_namespace (href , prefix )
105112 local raw_namespace =
106113 libxml2 .xmlNewNs (self .node , href , prefix )
107- return Namespace .new (self . document , raw_namespace )
114+ return Namespace .new (self , raw_namespace )
108115end
109116
110117function methods :create_processing_instruction (name , content )
111118 local raw_processing_instruction =
112119 libxml2 .xmlNewPI (name , content )
113- return ProcessingInstruction .new (self . document ,
120+ return ProcessingInstruction .new (self ,
114121 raw_processing_instruction )
115122end
116123
117124function methods :add_entity (entity_info )
118125 local entity_type_name = entity_info [" entity_type" ]
119126 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 ,
121128 entity_info [" name" ],
122129 entity_type ,
123130 entity_info [" external_id" ],
@@ -127,14 +134,14 @@ function methods:add_entity(entity_info)
127134end
128135
129136function methods :get_entity (name )
130- local raw_entity = libxml2 .xmlGetDocEntity (self .document , name )
137+ local raw_entity = libxml2 .xmlGetDocEntity (self .raw_document , name )
131138 return converter .convert_xml_entity (raw_entity )
132139end
133140
134141function methods :add_dtd_entity (entity_info )
135142 local entity_type_name = entity_info [" entity_type" ]
136143 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 ,
138145 entity_info [" name" ],
139146 entity_type ,
140147 entity_info [" external_id" ],
@@ -144,7 +151,7 @@ function methods:add_dtd_entity(entity_info)
144151end
145152
146153function 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 )
148155 return converter .convert_xml_entity (raw_dtd_entity )
149156end
150157
@@ -167,7 +174,7 @@ function Document.build(raw_document, tree)
167174
168175 local root = Element .build (document , tree [1 ], tree [2 ])
169176 if not libxml2 .xmlDocSetRootElement (raw_document , root .node ) then
170- root :unlink ()
177+ -- root:unlink()
171178 return nil
172179 end
173180
@@ -186,10 +193,22 @@ function Document.new(raw_document, errors)
186193 if not errors then
187194 errors = {}
188195 end
196+ local unlinked = {}
189197 local document = {
190- document = raw_document ,
198+ raw_document = raw_document ,
191199 errors = errors ,
200+ unlinked = unlinked
192201 }
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 )
193212 setmetatable (document , metatable )
194213 return document
195214end
0 commit comments