xcell_types/value/convert/
binary.rs

1use std::io::Write;
2
3use stream_io::ByteOrder;
4
5use crate::{StreamWriter, XCellValue};
6
7impl StreamWriter for XCellValue {
8    fn write_to<W: Write>(&self, buffer: &mut W, order: ByteOrder) -> std::io::Result<()> {
9        match self {
10            XCellValue::Boolean(v) => match v {
11                true => 0u8.write_to(buffer, order)?,
12                false => 1u8.write_to(buffer, order)?,
13            },
14            XCellValue::Integer8(v) => v.write_to(buffer, order)?,
15            XCellValue::Integer16(v) => v.write_to(buffer, order)?,
16            XCellValue::Integer32(v) => v.write_to(buffer, order)?,
17            XCellValue::Integer64(v) => v.write_to(buffer, order)?,
18            XCellValue::Unsigned8(v) => v.write_to(buffer, order)?,
19            XCellValue::Unsigned16(v) => v.write_to(buffer, order)?,
20            XCellValue::Unsigned32(v) => v.write_to(buffer, order)?,
21            XCellValue::Unsigned64(v) => v.write_to(buffer, order)?,
22            XCellValue::Float32(v) => v.write_to(buffer, order)?,
23            XCellValue::Float64(v) => v.write_to(buffer, order)?,
24            XCellValue::Vector2(v) => {
25                for item in v {
26                    item.write_to(buffer, order)?;
27                }
28            }
29            XCellValue::Vector3(v) => {
30                for item in v {
31                    item.write_to(buffer, order)?;
32                }
33            }
34            XCellValue::Vector4(v) => {
35                for item in v {
36                    item.write_to(buffer, order)?;
37                }
38            }
39            XCellValue::Color4(v) => {
40                for item in v {
41                    item.write_to(buffer, order)?;
42                }
43            }
44            XCellValue::Quaternion4(v) => {
45                for item in v {
46                    item.write_to(buffer, order)?;
47                }
48            }
49            // https://en.wikipedia.org/wiki/Variable-length_quantity
50            XCellValue::String(v) => {
51                write_7_bit(v.len(), buffer, order)?;
52                for item in v.bytes() {
53                    item.write_to(buffer, order)?
54                }
55            }
56            XCellValue::Color(v) => {
57                v.r.write_to(buffer, order)?;
58                v.g.write_to(buffer, order)?;
59                v.b.write_to(buffer, order)?;
60                v.a.write_to(buffer, order)?;
61            }
62            XCellValue::Vector(v) => {
63                (v.len() as u32).write_to(buffer, order)?;
64                for item in v.iter() {
65                    item.write_to(buffer, order)?
66                }
67            }
68            XCellValue::Enumerate(v) => {
69                panic!("无法写入二进制 `{}`", v)
70            }
71        }
72        Ok(())
73    }
74}
75
76pub fn write_7_bit<W: Write>(length: usize, buffer: &mut W, order: ByteOrder) -> std::io::Result<()> {
77    let mut value = length as u32;
78    while value >= 0x80 {
79        ((value | 0x80) as u8).write_to(buffer, order)?;
80        value >>= 7;
81    }
82    (value as u8).write_to(buffer, order)
83}