spirv_utils/parse/
read.rs1use std;
10use std::io::{Read};
11
12use super::{Result, RawInstruction, Header};
13
14const MAGIC_NUMBER : u32 = 0x07230203;
15
16pub struct Reader<R: ?Sized + Read> {
17 need_swap: bool,
18 is_eof: bool,
19 read_header: bool,
20 reader: R
21}
22
23impl<R: Read> Reader<R> {
24 pub fn new(mut reader: R) -> Result<Reader<R>> {
25 let mut word : u32 = 0;
26 unsafe {
27 let buf : &mut [u8;4] = std::mem::transmute(&mut word);
28 try!(reader.read(buf));
29 }
30
31 let need_swap = if word == MAGIC_NUMBER {
32 false
33 } else if word.swap_bytes() == MAGIC_NUMBER {
34 true
35 } else {
36 return Err(super::ParseError::InvalidMagicNumber(word));
37 };
38
39 Ok(Reader {
40 need_swap: need_swap,
41 is_eof: false,
42 read_header: false,
43 reader: reader
44 })
45 }
46}
47
48impl<R: ?Sized + Read> Reader<R> {
49 fn read_word(&mut self) -> Result<u32> {
50 if self.is_eof { return Ok(0); }
51
52 let mut word : u32 = 0;
53 unsafe {
54 let buf : &mut [u8;4] = std::mem::transmute(&mut word);
55 let n = try!(self.reader.read(buf));
56 if n != 4 {
57 self.is_eof = true;
58 return Ok(0);
59 }
60 }
61
62 if self.need_swap {
63 Ok(word.swap_bytes())
64 } else {
65 Ok(word)
66 }
67 }
68
69 pub fn read_header(&mut self) -> Result<Header> {
70 assert!(!self.read_header, "Already read header");
71 let version = try!(self.read_word());
72 let major = (version >> 16) as u8;
73 let minor = ((version >> 8) & 0xFF) as u8;
74
75 let generator_id = try!(self.read_word());
76 let id_bound = try!(self.read_word());
77
78 try!(self.read_word());
80 self.read_header = true;
81
82 Ok(Header {
83 version: (major, minor),
84 generator_id: generator_id,
85 id_bound: id_bound
86 })
87 }
88
89 pub fn skip_header(&mut self) -> Result<()> {
90 if !self.read_header {
91 self.read_header().map(|_| ())
92 } else {
93 Ok(())
94 }
95 }
96
97 pub fn read_instruction(&mut self) -> Result<Option<RawInstruction>> {
98 assert!(self.read_header, "Header needs to be read");
99 let op = try!(self.read_word());
100 if self.is_eof { return Ok(None); }
101
102 let code = (op & 0xFFFF) as u16;
103 let count = op >> 16;
104 let mut params = Vec::with_capacity(count as usize);
105
106 for _ in 1..count {
107 let p = try!(self.read_word());
108 params.push(p);
109 }
110
111 Ok(Some(RawInstruction {
112 opcode: code,
113 params: params
114 }))
115 }
116}