Moved Expat class to own file, made it a class for deinit()
This commit is contained in:
parent
f89ed83dfd
commit
b9f0dd9fd2
|
@ -7,6 +7,7 @@
|
|||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
E8C667EC19757405004EFA0C /* Expat.swift in Sources */ = {isa = PBXBuildFile; fileRef = E8C667EB19757405004EFA0C /* Expat.swift */; };
|
||||
E8FB77441971609A00E0557D /* SwiftyExpat.h in Headers */ = {isa = PBXBuildFile; fileRef = E8FB77431971609A00E0557D /* SwiftyExpat.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
E8FB77721971667F00E0557D /* ascii.h in Headers */ = {isa = PBXBuildFile; fileRef = E8FB775F1971667F00E0557D /* ascii.h */; };
|
||||
E8FB77731971667F00E0557D /* asciitab.h in Headers */ = {isa = PBXBuildFile; fileRef = E8FB77601971667F00E0557D /* asciitab.h */; };
|
||||
|
@ -64,6 +65,7 @@
|
|||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
E8C667EB19757405004EFA0C /* Expat.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Expat.swift; sourceTree = "<group>"; };
|
||||
E8FB773E1971609A00E0557D /* SwiftyExpat.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SwiftyExpat.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
E8FB77421971609A00E0557D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
E8FB77431971609A00E0557D /* SwiftyExpat.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SwiftyExpat.h; sourceTree = "<group>"; };
|
||||
|
@ -134,6 +136,7 @@
|
|||
E8FB77401971609A00E0557D /* SwiftyExpat */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
E8C667EB19757405004EFA0C /* Expat.swift */,
|
||||
E8FB779D1971E5AA00E0557D /* main.swift */,
|
||||
E8FB77431971609A00E0557D /* SwiftyExpat.h */,
|
||||
E8FB775E1971667F00E0557D /* expat */,
|
||||
|
@ -341,6 +344,7 @@
|
|||
E8FB77811971667F00E0557D /* xmltok.c in Sources */,
|
||||
E8FB777E1971667F00E0557D /* xmlparse.c in Sources */,
|
||||
E8FB779E1971E5AA00E0557D /* main.swift in Sources */,
|
||||
E8C667EC19757405004EFA0C /* Expat.swift in Sources */,
|
||||
E8FB777F1971667F00E0557D /* xmlrole.c in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
|
|
|
@ -0,0 +1,80 @@
|
|||
//
|
||||
// Expat.swift
|
||||
// SwiftyExpat
|
||||
//
|
||||
// Created by Helge Heß on 7/15/14.
|
||||
// Copyright (c) 2014 Always Right Institute. All rights reserved.
|
||||
//
|
||||
|
||||
/**
|
||||
* Simple wrapper for the Expat parser. Though the block based Expat is
|
||||
* reasonably easy to use as-is.
|
||||
*
|
||||
* Done as a class as this is no value object (and struct's have no deinit())
|
||||
*/
|
||||
class Expat : OutputStream {
|
||||
|
||||
let parser : XML_Parser
|
||||
|
||||
init(encoding: String = "UTF-8", nsSeparator: Character = ":") {
|
||||
let sepUTF8 = ("" + nsSeparator).utf8
|
||||
let separator = sepUTF8[sepUTF8.startIndex]
|
||||
|
||||
var newParser : XML_Parser = nil
|
||||
encoding.withCString { cs in
|
||||
// if I use parser, swiftc crashes (if Expat is a class)
|
||||
// FIXME: use String for separator, and codepoints to get the Int?
|
||||
newParser = XML_ParserCreateNS(cs, 58 /* ':' */)
|
||||
}
|
||||
assert(newParser != nil)
|
||||
|
||||
parser = newParser
|
||||
}
|
||||
deinit {
|
||||
XML_ParserFree(parser)
|
||||
}
|
||||
|
||||
|
||||
/* feed the parser */
|
||||
|
||||
func write(cs: CString) {
|
||||
let cslen = strlen(cs)
|
||||
let isFinal = cslen == 0
|
||||
XML_Parse(parser, cs, Int32(cslen), isFinal ? 1 : 0)
|
||||
}
|
||||
|
||||
func write(s: String) {
|
||||
s.withCString { cs in self.write(cs) }
|
||||
}
|
||||
|
||||
func close() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* callbacks */
|
||||
|
||||
func onStartElement(cb: ( String, [ String : String ] ) -> Void) -> Self {
|
||||
XML_SetStartElementHandler(parser) {
|
||||
// void *userData, const XML_Char *name, const XML_Char **atts
|
||||
( userData, name, attrs ) in
|
||||
let sName = String.fromCString(name)! // unwrap, must be set
|
||||
|
||||
var sAttrs = [ String : String]()
|
||||
if attrs != nil {
|
||||
var i = 0
|
||||
while attrs[i] { // Note: you cannot compare it with nil?!
|
||||
let name = String.fromCString(attrs[i])
|
||||
let value = String.fromCString(attrs[i + 1])
|
||||
sAttrs[name!] = value! // force unwrap
|
||||
i += 2
|
||||
}
|
||||
}
|
||||
|
||||
cb(sName, sAttrs)
|
||||
}
|
||||
|
||||
return self
|
||||
}
|
||||
|
||||
}
|
|
@ -1133,6 +1133,11 @@ destroyBindings(BINDING *bindings, XML_Parser parser)
|
|||
void XMLCALL
|
||||
XML_ParserFree(XML_Parser parser)
|
||||
{
|
||||
TAG *tagList;
|
||||
OPEN_INTERNAL_ENTITY *entityList;
|
||||
if (parser == NULL)
|
||||
return;
|
||||
|
||||
#ifdef EXPAT_WITH_BLOCKS
|
||||
// Block_release seems to check for NULL
|
||||
Block_release(startElementHandler);
|
||||
|
@ -1159,10 +1164,6 @@ XML_ParserFree(XML_Parser parser)
|
|||
Block_release(xmlDeclHandler);
|
||||
#endif
|
||||
|
||||
TAG *tagList;
|
||||
OPEN_INTERNAL_ENTITY *entityList;
|
||||
if (parser == NULL)
|
||||
return;
|
||||
/* free tagStack and freeTagList */
|
||||
tagList = tagStack;
|
||||
for (;;) {
|
||||
|
|
|
@ -8,63 +8,6 @@
|
|||
|
||||
import Foundation
|
||||
|
||||
struct Expat : OutputStream {
|
||||
|
||||
let parser : XML_Parser
|
||||
|
||||
init(encoding: String = "UTF-8", nsSeparator: Character = ":") {
|
||||
let sepUTF8 = ("" + nsSeparator).utf8
|
||||
let separator = sepUTF8[sepUTF8.startIndex]
|
||||
|
||||
var newParser : XML_Parser = nil
|
||||
encoding.withCString { cs in
|
||||
// if I use parser, swiftc crashes (if Expat is a class)
|
||||
// FIXME: use String for separator, and codepoints to get the Int?
|
||||
newParser = XML_ParserCreateNS(cs, 58 /* ':' */)
|
||||
}
|
||||
assert(newParser != nil)
|
||||
|
||||
parser = newParser
|
||||
}
|
||||
|
||||
|
||||
/* feed the parser */
|
||||
|
||||
func write(cs: CString) {
|
||||
let cslen = strlen(cs)
|
||||
let isFinal = cslen == 0
|
||||
XML_Parse(parser, cs, Int32(cslen), isFinal ? 1 : 0)
|
||||
}
|
||||
|
||||
func write(s: String) {
|
||||
s.withCString { cs in self.write(cs) }
|
||||
}
|
||||
|
||||
|
||||
/* callbacks */
|
||||
|
||||
func onStartElement(cb: ( String, [ String : String ] ) -> Void) {
|
||||
XML_SetStartElementHandler(parser, {
|
||||
// void *userData, const XML_Char *name, const XML_Char **atts
|
||||
( userData, name, attrs ) in
|
||||
let sName = String.fromCString(name)! // unwrap, must be set
|
||||
|
||||
var sAttrs = [ String : String]()
|
||||
if attrs != nil {
|
||||
var i = 0
|
||||
while attrs[i] { // Note: you cannot compare it with nil?!
|
||||
let name = String.fromCString(attrs[i])
|
||||
let value = String.fromCString(attrs[i + 1])
|
||||
sAttrs[name!] = value! // force unwrap
|
||||
i += 2
|
||||
}
|
||||
}
|
||||
|
||||
cb(sName, sAttrs)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func testit() {
|
||||
println("testing it ...")
|
||||
|
||||
|
|
Loading…
Reference in New Issue