<commit_before>import Foundation
import libxml2

extension Libxml2.In {
    class HTMLConverter: Converter {

        typealias RootNode = Libxml2.RootNode

        enum Error: String, ErrorType {
            case NoRootNode = "No root node"
        }

        /// Not sure why, but the compiler is requiring this initializer.
        ///
        init() {
        }

        /// Converts HTML data into an HTML Node representing the same data.
        ///
        /// - Parameters:
        ///     - html: the HTML string to convert.
        ///
        /// - Returns: the HTML root node.
        ///
        func convert(html: String) throws -> RootNode {

            // We wrap the HTML into a special root node, since it helps avoid conversion issues
            // with libxml2, where the library would add custom tags to "fix" the HTML code we
            // provide.
            //
            let wrappedHTML = "<\(RootNode.name)>\(html)</\(RootNode.name)>"
            let data = wrappedHTML.dataUsingEncoding(NSUTF8StringEncoding)!

            let bufferSize = 1024
            let buffer = Array<Int8>(count: bufferSize, repeatedValue: 0)
            let htmlPtr = UnsafePointer<Int8>(data.bytes)

            let parserContext = htmlCreateMemoryParserCtxt(buffer, 1024)

            // We don't want <p> tags added automattically.
            //
            htmlHandleOmittedElem(0)

            let document = htmlCtxtReadMemory(parserContext, htmlPtr, Int32(wrappedHTML.lengthOfBytesUsingEncoding(NSUTF8StringEncoding)), "", nil, Int32(HTML_PARSE_RECOVER.rawValue | HTML_PARSE_NODEFDTD.rawValue | HTML_PARSE_NOERROR.rawValue | HTML_PARSE_NOWARNING.rawValue | HTML_PARSE_NOIMPLIED.rawValue))

            let errorPtr = xmlGetLastError()

            if errorPtr != nil {
                let messagePtr = errorPtr.memory.message

                if messagePtr != nil {
                    let message = String(CString: messagePtr, encoding: NSUTF8StringEncoding)

                    NSLog("Message: \(message)")
                }

                // Some errors are really not a problem for us (like "misplaced HTML tag"), so let's
                // keep going.  In the future we should analyze the different errors here and decide
                // if there's a need to handle any of them in a different way.
                //
            }

            let rootNodePtr = xmlDocGetRootElement(document)
<commit_msg>Fixes two leaks.<commit_after>import Foundation
import libxml2

extension Libxml2.In {
    class HTMLConverter: Converter {

        typealias RootNode = Libxml2.RootNode

        enum Error: String, ErrorType {
            case NoRootNode = "No root node"
        }

        /// Not sure why, but the compiler is requiring this initializer.
        ///
        init() {
        }

        /// Converts HTML data into an HTML Node representing the same data.
        ///
        /// - Parameters:
        ///     - html: the HTML string to convert.
        ///
        /// - Returns: the HTML root node.
        ///
        func convert(html: String) throws -> RootNode {

            // We wrap the HTML into a special root node, since it helps avoid conversion issues
            // with libxml2, where the library would add custom tags to "fix" the HTML code we
            // provide.
            //
            let wrappedHTML = "<\(RootNode.name)>\(html)</\(RootNode.name)>"
            let data = wrappedHTML.dataUsingEncoding(NSUTF8StringEncoding)!

            let bufferSize = 1024
            let buffer = Array<Int8>(count: bufferSize, repeatedValue: 0)
            let htmlPtr = UnsafePointer<Int8>(data.bytes)

            let parserContext = htmlCreateMemoryParserCtxt(buffer, 1024)
            
            defer {
                htmlFreeParserCtxt(parserContext)
            }

            // We don't want <p> tags added automattically.
            //
            htmlHandleOmittedElem(0)

            let document = htmlCtxtReadMemory(parserContext, htmlPtr, Int32(wrappedHTML.lengthOfBytesUsingEncoding(NSUTF8StringEncoding)), "", nil, Int32(HTML_PARSE_RECOVER.rawValue | HTML_PARSE_NODEFDTD.rawValue | HTML_PARSE_NOERROR.rawValue | HTML_PARSE_NOWARNING.rawValue | HTML_PARSE_NOIMPLIED.rawValue))
            
            defer {
                xmlFreeDoc(document)
            }

            let errorPtr = xmlGetLastError()

            if errorPtr != nil {
                let messagePtr = errorPtr.memory.message

                if messagePtr != nil {
                    let message = String(CString: messagePtr, encoding: NSUTF8StringEncoding)

                    NSLog("Message: \(message)")
                }

                // Some errors are really not a problem for us (like "misplaced HTML tag"), so let's
                // keep going.  In the future we should analyze the different errors here and decide
                // if there's a need to handle any of them in a different way.
                //
            }

            let rootNodePtr = xmlDocGetRootElement(document)

{'fraction_non_alphanumeric': 0.08254156769596199, 'fraction_numerical': 0.009105304829770388, 'mean_word_length': 1.767250821467689, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 13}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7391413', 'n_tokens_mistral': 1344, 'n_tokens_neox': 1252, 'n_words': 400}