Skip to content

Instantly share code, notes, and snippets.

@chriseidhof
Last active February 3, 2018 23:01
Show Gist options
  • Star 17 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save chriseidhof/4c5a49d4b81a0c2a37a1 to your computer and use it in GitHub Desktop.
Save chriseidhof/4c5a49d4b81a0c2a37a1 to your computer and use it in GitHub Desktop.
// gem install cocoapods-playgrounds
// pod playgrounds LibYAML
// Update: @floriankugler had a great idea to use UnsafeBufferPointer
// Paste in the following:
import LibYAML
public struct YAMLError: ErrorType {
let problem: String
let problemOffset: Int
}
public indirect enum YAMLNode {
case Scalar(s: String)
case Mapping([(String,YAMLNode)])
case Sequence([YAMLNode])
}
private class YAMLDocument {
private var document: UnsafeMutablePointer<yaml_document_t> = .alloc(1)
private var nodes: [yaml_node_t] {
let nodes = document.memory.nodes
return Array(UnsafeBufferPointer(start: nodes.start, count: nodes.top - nodes.start))
}
var rootNode: YAMLNode {
return YAMLNode(nodes: nodes, node: yaml_document_get_root_node(document).memory)
}
init(string: String) throws {
var parser: UnsafeMutablePointer<yaml_parser_t> = .alloc(1)
defer { parser.dealloc(1) }
yaml_parser_initialize(parser)
defer { yaml_parser_delete(parser) }
var bytes = string.utf8.map { UInt8($0) }
yaml_parser_set_encoding(parser, YAML_UTF8_ENCODING)
yaml_parser_set_input_string(parser, &bytes, bytes.count-1)
guard yaml_parser_load(parser, document) == 1 else {
throw YAMLError(problem: String.fromCString(parser.memory.problem)!, problemOffset: parser.memory.problem_offset)
}
}
deinit {
yaml_document_delete(document)
document.dealloc(1)
}
}
extension YAMLNode {
private init(nodes: [yaml_node_s], node: yaml_node_s) {
let newNode: Int32 -> YAMLNode = { x in YAMLNode(nodes: nodes, node: nodes[x-1]) }
switch node.type {
case YAML_MAPPING_NODE:
let pairs = node.data.mapping.pairs
self = .Mapping(UnsafeBufferPointer(start: pairs.start, count: pairs.top - pairs.start).map { pair in
guard case let .Scalar(value) = newNode(pair.key) else { fatalError("Not a scalar key") }
return (value, newNode(pair.value))
})
case YAML_SEQUENCE_NODE:
let items = node.data.sequence.items
self = .Sequence(UnsafeBufferPointer(start: items.start, count: items.top - items.start).map(newNode))
case YAML_SCALAR_NODE:
self = .Scalar(s: String.fromCString(UnsafeMutablePointer(node.data.scalar.value))!)
default:
fatalError("TODO")
}
}
public init(string: String) throws {
self = try YAMLDocument(string: string).rootNode
}
}
let node = try YAMLNode(string: "- 1: test ")
@floriankugler
Copy link

Use UnsafeBufferPointer instead of manually iterating and collecting results: https://gist.github.com/floriankugler/cfcb887b1fd10775abed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment