aboutsummaryrefslogtreecommitdiff
path: root/core/encoding/xml
diff options
context:
space:
mode:
Diffstat (limited to 'core/encoding/xml')
-rw-r--r--core/encoding/xml/debug_print.odin16
-rw-r--r--core/encoding/xml/example/xml_example.odin6
-rw-r--r--core/encoding/xml/helpers.odin29
-rw-r--r--core/encoding/xml/xml_reader.odin42
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