Skip to content

Commit 36c769a

Browse files
committed
Refactor parser context management into helpers.
1 parent df9cf99 commit 36c769a

File tree

1 file changed

+30
-28
lines changed

1 file changed

+30
-28
lines changed

src/xml.cr

Lines changed: 30 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -51,32 +51,44 @@ require "./xml/libxml2"
5151
# string # => "<?xml version=\"1.0\"?>\n<person id=\"1\">\n <firstname>Jane</firstname>\n <lastname>Doe</lastname>\n</person>\n"
5252
# ```
5353
module XML
54+
# Wraps a block that uses a XML parser context. Allocates the
55+
# context and ensures the context is freed after use.
56+
private def self.parse_xml(&)
57+
ctxt = LibXML.xmlNewParserCtxt
58+
begin
59+
from_ptr(ctxt) { yield ctxt }
60+
ensure
61+
LibXML.xmlFreeParserCtxt(ctxt)
62+
end
63+
end
64+
65+
# Wraps a block that uses a HTML parser context. Allocates the
66+
# context and ensures the context is freed after use.
67+
private def self.parse_html(&)
68+
ctxt = LibXML.htmlNewParserCtxt
69+
begin
70+
from_ptr(ctxt) { yield ctxt }
71+
ensure
72+
LibXML.htmlFreeParserCtxt(ctxt)
73+
end
74+
end
75+
5476
# Parses an XML document from *string* with *options* into an `XML::Node`.
5577
#
5678
# See `ParserOptions.default` for default options.
5779
def self.parse(string : String, options : ParserOptions = ParserOptions.default) : Document
5880
raise XML::Error.new("Document is empty", 0) if string.empty?
59-
ctxt = LibXML.xmlNewParserCtxt
60-
begin
61-
from_ptr(ctxt) do
62-
LibXML.xmlCtxtReadMemory(ctxt, string, string.bytesize, nil, nil, options)
63-
end
64-
ensure
65-
LibXML.xmlFreeParserCtxt(ctxt)
81+
parse_xml do |ctxt|
82+
LibXML.xmlCtxtReadMemory(ctxt, string, string.bytesize, nil, nil, options)
6683
end
6784
end
6885

6986
# Parses an XML document from *io* with *options* into an `XML::Node`.
7087
#
7188
# See `ParserOptions.default` for default options.
7289
def self.parse(io : IO, options : ParserOptions = ParserOptions.default) : Document
73-
ctxt = LibXML.xmlNewParserCtxt
74-
begin
75-
from_ptr(ctxt) do
76-
LibXML.xmlCtxtReadIO(ctxt, ->read_callback, ->close_callback, Box(IO).box(io), nil, nil, options)
77-
end
78-
ensure
79-
LibXML.xmlFreeParserCtxt(ctxt)
90+
parse_xml do |ctxt|
91+
LibXML.xmlCtxtReadIO(ctxt, ->read_callback, ->close_callback, Box(IO).box(io), nil, nil, options)
8092
end
8193
end
8294

@@ -85,27 +97,17 @@ module XML
8597
# See `HTMLParserOptions.default` for default options.
8698
def self.parse_html(string : String, options : HTMLParserOptions = HTMLParserOptions.default) : Document
8799
raise XML::Error.new("Document is empty", 0) if string.empty?
88-
ctxt = LibXML.htmlNewParserCtxt
89-
begin
90-
from_ptr(ctxt) do
91-
LibXML.htmlCtxtReadMemory(ctxt, string, string.bytesize, nil, "utf-8", options)
92-
end
93-
ensure
94-
LibXML.htmlFreeParserCtxt(ctxt)
100+
parse_html do |ctxt|
101+
LibXML.htmlCtxtReadMemory(ctxt, string, string.bytesize, nil, "utf-8", options)
95102
end
96103
end
97104

98105
# Parses an HTML document from *io* with *options* into an `XML::Node`.
99106
#
100107
# See `HTMLParserOptions.default` for default options.
101108
def self.parse_html(io : IO, options : HTMLParserOptions = HTMLParserOptions.default) : Document
102-
ctxt = LibXML.htmlNewParserCtxt
103-
begin
104-
from_ptr(ctxt) do
105-
LibXML.htmlCtxtReadIO(ctxt, ->read_callback, ->close_callback, Box(IO).box(io), nil, "utf-8", options)
106-
end
107-
ensure
108-
LibXML.htmlFreeParserCtxt(ctxt)
109+
parse_html do |ctxt|
110+
LibXML.htmlCtxtReadIO(ctxt, ->read_callback, ->close_callback, Box(IO).box(io), nil, "utf-8", options)
109111
end
110112
end
111113

0 commit comments

Comments
 (0)