fyrox_impl/resource/fbx/document/
ascii.rs1use crate::core::byteorder::ReadBytesExt;
22use crate::{
23 core::pool::{Handle, Pool},
24 resource::fbx::{
25 document::{attribute::FbxAttribute, FbxDocument, FbxNode, FbxNodeContainer},
26 error::FbxError,
27 },
28};
29use std::io::{Read, Seek, SeekFrom};
30
31pub fn read_ascii<R>(reader: &mut R) -> Result<FbxDocument, FbxError>
32where
33 R: Read + Seek,
34{
35 let mut nodes: Pool<FbxNode> = Pool::new();
36 let root_handle = nodes.spawn(FbxNode {
37 name: String::from("__ROOT__"),
38 children: Vec::new(),
39 parent: Handle::NONE,
40 attributes: Vec::new(),
41 });
42 let mut parent_handle: Handle<FbxNode> = root_handle;
43 let mut node_handle: Handle<FbxNode> = Handle::NONE;
44 let mut buffer: Vec<u8> = Vec::new();
45 let mut name: Vec<u8> = Vec::new();
46 let mut value: Vec<u8> = Vec::new();
47
48 let buf_len = reader.seek(SeekFrom::End(0))?;
49 reader.rewind()?;
50
51 while reader.stream_position()? < buf_len {
53 buffer.clear();
55
56 let mut read_all = false;
57 while reader.stream_position()? < buf_len {
58 let symbol = reader.read_u8()?;
59 if symbol == b'\n' {
60 break;
61 } else if symbol == b'"' {
62 read_all = !read_all;
63 } else if read_all || !symbol.is_ascii_whitespace() {
64 buffer.push(symbol);
65 }
66 }
67
68 if buffer.is_empty() || buffer[0] == b';' {
70 continue;
71 }
72
73 let mut read_value = false;
75 name.clear();
76 for (i, symbol) in buffer.iter().enumerate() {
77 let symbol = *symbol;
78 if i == 0 && (symbol == b'-' || symbol.is_ascii_digit()) {
79 read_value = true;
80 }
81 if symbol == b':' && !read_value {
82 read_value = true;
83 let name_copy = String::from_utf8(name.clone())?;
84 let node = FbxNode {
85 name: name_copy,
86 attributes: Vec::new(),
87 parent: parent_handle,
88 children: Vec::new(),
89 };
90 node_handle = nodes.spawn(node);
91 name.clear();
92 let parent = nodes.borrow_mut(parent_handle);
93 parent.children.push(node_handle);
94 } else if symbol == b'{' {
95 parent_handle = node_handle;
97 if !value.is_empty() {
99 let node = nodes.borrow_mut(node_handle);
100 let string_value = String::from_utf8(value.clone())?;
101 let attrib = FbxAttribute::String(string_value);
102 node.attributes.push(attrib);
103 value.clear();
104 }
105 } else if symbol == b'}' {
106 let parent = nodes.borrow_mut(parent_handle);
108 parent_handle = parent.parent;
109 } else if symbol == b',' || (i == buffer.len() - 1) {
110 if symbol != b',' {
112 value.push(symbol);
113 }
114 let node = nodes.borrow_mut(node_handle);
115 let string_value = String::from_utf8(value.clone())?;
116 let attrib = FbxAttribute::String(string_value);
117 node.attributes.push(attrib);
118 value.clear();
119 } else if !read_value {
120 name.push(symbol);
121 } else {
122 value.push(symbol);
123 }
124 }
125 }
126
127 Ok(FbxDocument {
128 nodes: FbxNodeContainer { nodes },
129 root: root_handle,
130 })
131}