diff options
Diffstat (limited to 'core/encoding/xml')
| -rw-r--r-- | core/encoding/xml/debug_print.odin | 16 | ||||
| -rw-r--r-- | core/encoding/xml/example/xml_example.odin | 6 | ||||
| -rw-r--r-- | core/encoding/xml/helpers.odin | 29 | ||||
| -rw-r--r-- | core/encoding/xml/xml_reader.odin | 42 |
4 files changed, 44 insertions, 49 deletions
diff --git a/core/encoding/xml/debug_print.odin b/core/encoding/xml/debug_print.odin index e9a1cb160..0736e8893 100644 --- a/core/encoding/xml/debug_print.odin +++ b/core/encoding/xml/debug_print.odin @@ -65,19 +65,21 @@ print_element :: proc(writer: io.Writer, doc: ^Document, element_id: Element_ID, if element.kind == .Element { wprintf(writer, "<%v>\n", element.ident) - if len(element.value) > 0 { - tab(writer, indent + 1) - wprintf(writer, "[Value] %v\n", element.value) + + for value in element.value { + switch v in value { + case string: + tab(writer, indent + 1) + wprintf(writer, "[Value] %v\n", v) + case Element_ID: + print_element(writer, doc, v, indent + 1) + } } for attr in element.attribs { tab(writer, indent + 1) wprintf(writer, "[Attr] %v: %v\n", attr.key, attr.val) } - - for child in element.children { - print_element(writer, doc, child, indent + 1) - } } else if element.kind == .Comment { wprintf(writer, "[COMMENT] %v\n", element.value) } diff --git a/core/encoding/xml/example/xml_example.odin b/core/encoding/xml/example/xml_example.odin index 887b40764..aebb8d0ea 100644 --- a/core/encoding/xml/example/xml_example.odin +++ b/core/encoding/xml/example/xml_example.odin @@ -72,10 +72,10 @@ example :: proc() { return } - printf("Found `<charlist>` with %v children, %v elements total\n", len(docs[0].elements[charlist].children), docs[0].element_count) + printf("Found `<charlist>` with %v children, %v elements total\n", len(docs[0].elements[charlist].value), docs[0].element_count) - crc32 := doc_hash(docs[0]) - printf("[%v] CRC32: 0x%08x\n", "🎉" if crc32 == 0xcaa042b9 else "🤬", crc32) + crc32 := doc_hash(docs[0], false) + printf("[%v] CRC32: 0x%08x\n", "🎉" if crc32 == 0x420dbac5 else "🤬", crc32) for round in 0..<N { defer xml.destroy(docs[round]) diff --git a/core/encoding/xml/helpers.odin b/core/encoding/xml/helpers.odin index 48f058334..200c5c1de 100644 --- a/core/encoding/xml/helpers.odin +++ b/core/encoding/xml/helpers.odin @@ -13,20 +13,25 @@ find_child_by_ident :: proc(doc: ^Document, parent_id: Element_ID, ident: string tag := doc.elements[parent_id] count := 0 - for child_id in tag.children { - child := doc.elements[child_id] - /* - Skip commments. They have no name. - */ - if child.kind != .Element { continue } + for v in tag.value { + switch child_id in v { + case string: continue + case Element_ID: + child := doc.elements[child_id] + /* + Skip commments. They have no name. + */ + if child.kind != .Element { continue } - /* - If the ident matches and it's the nth such child, return it. - */ - if child.ident == ident { - if count == nth { return child_id, true } - count += 1 + /* + If the ident matches and it's the nth such child, return it. + */ + if child.ident == ident { + if count == nth { return child_id, true } + count += 1 + } } + } return 0, false } diff --git a/core/encoding/xml/xml_reader.odin b/core/encoding/xml/xml_reader.odin index f5523c299..f4f8a4b05 100644 --- a/core/encoding/xml/xml_reader.odin +++ b/core/encoding/xml/xml_reader.odin @@ -125,16 +125,19 @@ Document :: struct { Element :: struct { ident: string, - value: string, + value: [dynamic]Value, attribs: Attributes, kind: enum { Element = 0, Comment, }, - parent: Element_ID, - children: [dynamic]Element_ID, +} + +Value :: union { + string, + Element_ID, } Attribute :: struct { @@ -247,9 +250,6 @@ parse_bytes :: proc(data: []u8, options := DEFAULT_OPTIONS, path := "", error_ha err = .Unexpected_Token element, parent: Element_ID - - tag_is_open := false - first_element := true open: Token /* @@ -275,16 +275,10 @@ parse_bytes :: proc(data: []u8, options := DEFAULT_OPTIONS, path := "", error_ha e.g. <odin - Start of new element. */ element = new_element(doc) - tag_is_open = true - - if first_element { - /* - First element. - */ - parent = element - first_element = false + if element == 0 { // First Element + parent = element } else { - append(&doc.elements[parent].children, element) + append(&doc.elements[parent].value, element) } doc.elements[element].parent = parent @@ -324,7 +318,6 @@ parse_bytes :: proc(data: []u8, options := DEFAULT_OPTIONS, path := "", error_ha expect(t, .Gt) or_return parent = doc.elements[element].parent element = parent - tag_is_open = false case: error(t, t.offset, "Expected close tag, got: %#v\n", end_token) @@ -344,7 +337,6 @@ parse_bytes :: proc(data: []u8, options := DEFAULT_OPTIONS, path := "", error_ha } parent = doc.elements[element].parent element = parent - tag_is_open = false } else if open.kind == .Exclaim { /* @@ -392,8 +384,8 @@ parse_bytes :: proc(data: []u8, options := DEFAULT_OPTIONS, path := "", error_ha el := new_element(doc) doc.elements[el].parent = element doc.elements[el].kind = .Comment - doc.elements[el].value = comment - append(&doc.elements[element].children, el) + append(&doc.elements[el].value, comment) + append(&doc.elements[element].value, el) } } @@ -436,9 +428,6 @@ parse_bytes :: proc(data: []u8, options := DEFAULT_OPTIONS, path := "", error_ha /* End of file. */ - if tag_is_open { - return doc, .Premature_EOF - } break loop case: @@ -450,7 +439,7 @@ parse_bytes :: proc(data: []u8, options := DEFAULT_OPTIONS, path := "", error_ha needs_processing |= .Decode_SGML_Entities in opts.flags if !needs_processing { - doc.elements[element].value = body_text + append(&doc.elements[element].value, body_text) continue } @@ -472,10 +461,10 @@ parse_bytes :: proc(data: []u8, options := DEFAULT_OPTIONS, path := "", error_ha decoded, decode_err := entity.decode_xml(body_text, decode_opts) if decode_err == .None { - doc.elements[element].value = decoded + append(&doc.elements[element].value, decoded) append(&doc.strings_to_free, decoded) } else { - doc.elements[element].value = body_text + append(&doc.elements[element].value, body_text) } } } @@ -518,7 +507,7 @@ destroy :: proc(doc: ^Document) { for el in doc.elements { delete(el.attribs) - delete(el.children) + delete(el.value) } delete(doc.elements) @@ -710,6 +699,5 @@ new_element :: proc(doc: ^Document) -> (id: Element_ID) { cur := doc.element_count doc.element_count += 1 - return cur }
\ No newline at end of file |