Skip to main content

gaia_types/reader/
mod.rs

1#![doc = include_str!("readme.md")]
2
3pub use self::{token::Token, token_stream::TokenStream};
4use crate::{GaiaDiagnostics, GaiaError};
5use byteorder::{ByteOrder, ReadBytesExt};
6use serde::{Deserialize, Serialize};
7use std::{
8    io::{Read, Seek, SeekFrom},
9    marker::PhantomData,
10};
11use url::Url;
12
13mod token;
14mod token_stream;
15
16/// 二进制读取器,用于从实现了 ReadBytesExt trait 的类型中读取数据
17///
18/// 这是一个泛型结构体,可以包装任何实现了 ReadBytesExt trait 的类型,
19/// 提供二进制数据的读取功能。
20#[derive(Debug)]
21pub struct BinaryReader<R, E> {
22    reader: R,
23    position: u64,
24    endian: PhantomData<E>,
25    errors: Vec<GaiaError>,
26}
27
28impl<R: Read, E> Read for BinaryReader<R, E> {
29    fn read(&mut self, buffer: &mut [u8]) -> std::io::Result<usize> {
30        let bytes_read = self.reader.read(buffer)?;
31        self.position += bytes_read as u64;
32        Ok(bytes_read)
33    }
34}
35
36impl<R: Seek, E> Seek for BinaryReader<R, E> {
37    fn seek(&mut self, pos: SeekFrom) -> std::io::Result<u64> {
38        let new_position = self.reader.seek(pos)?;
39        self.position = new_position;
40        Ok(new_position)
41    }
42}
43
44impl<R, E> BinaryReader<R, E> {
45    /// 创建新的二进制读取器
46    ///
47    /// # Arguments
48    /// * `lexer` - 要读取的数据
49    ///
50    /// # Returns
51    /// 返回新的 BinaryReader 实例
52    pub fn new(reader: R) -> Self {
53        Self { reader, position: 0, endian: Default::default(), errors: vec![] }
54    }
55
56    /// 获取当前读取位置
57    ///
58    /// # Returns
59    /// 返回当前的字节偏移位置
60    pub fn get_position(&self) -> u64 {
61        self.position
62    }
63
64    /// 设置读取位置
65    ///
66    /// 注意:如果底层reader不支持Seek操作,此函数将返回错误
67    ///
68    /// # Arguments
69    /// * `pos` - 新的读取位置
70    ///
71    /// # Returns
72    /// 返回操作结果
73    pub fn set_position(&mut self, position: u64) -> Result<u64, GaiaError>
74    where
75        R: Seek,
76    {
77        self.reader.seek(SeekFrom::Start(position))?;
78        self.position = position;
79        Ok(position)
80    }
81    /// 完成读取器并返回结果。
82    pub fn finish(self) -> GaiaDiagnostics<R> {
83        GaiaDiagnostics { result: Ok(self.reader), diagnostics: self.errors }
84    }
85
86    /// 获取并清空当前累积的错误列表。
87    /// 该方法会返回所有在读取过程中遇到的错误,并重置内部的错误存储。
88    pub fn take_errors(&mut self) -> Vec<GaiaError> {
89        std::mem::take(&mut self.errors)
90    }
91}
92
93impl<R: ReadBytesExt, E: ByteOrder> BinaryReader<R, E> {
94    /// 读取 u8
95    ///
96    /// # Returns
97    /// 返回读取的 u8 值或 IO 错误
98    pub fn read_u8(&mut self) -> std::io::Result<u8> {
99        let value = self.reader.read_u8()?;
100        self.position += 1;
101        Ok(value)
102    }
103
104    /// 读取 u16
105    ///
106    /// # Returns
107    /// 返回读取的 u16 值或 IO 错误
108    pub fn read_u16(&mut self) -> std::io::Result<u16> {
109        let value = self.reader.read_u16::<E>()?;
110        self.position += 2;
111        Ok(value)
112    }
113
114    /// 读取 i16
115    ///
116    /// # Returns
117    /// 返回读取的 i16 值或 IO 错误
118    pub fn read_i16(&mut self) -> std::io::Result<i16> {
119        let value = self.reader.read_i16::<E>()?;
120        self.position += 2;
121        Ok(value)
122    }
123
124    /// 读取 u32
125    ///
126    /// # Returns
127    /// 返回读取的 u32 值或 IO 错误
128    pub fn read_u32(&mut self) -> std::io::Result<u32> {
129        let value = self.reader.read_u32::<E>()?;
130        self.position += 4;
131        Ok(value)
132    }
133
134    /// 读取 u64
135    ///
136    /// # Returns
137    /// 返回读取的 u64 值或 IO 错误
138    pub fn read_u64(&mut self) -> std::io::Result<u64> {
139        let value = self.reader.read_u64::<E>()?;
140        self.position += 8;
141        Ok(value)
142    }
143
144    /// 读取 i32
145    ///
146    /// # Returns
147    /// 返回读取的 i32 值或 IO 错误
148    pub fn read_i32(&mut self) -> std::io::Result<i32> {
149        let value = self.reader.read_i32::<E>()?;
150        self.position += 4;
151        Ok(value)
152    }
153
154    /// 读取 i64
155    ///
156    /// # Returns
157    /// 返回读取的 i64 值或 IO 错误
158    pub fn read_i64(&mut self) -> std::io::Result<i64> {
159        let value = self.reader.read_i64::<E>()?;
160        self.position += 8;
161        Ok(value)
162    }
163
164    /// 读取 f32
165    ///
166    /// # Returns
167    /// 返回读取的 f32 值或 IO 错误
168    pub fn read_f32(&mut self) -> std::io::Result<f32> {
169        let value = self.reader.read_f32::<E>()?;
170        self.position += 4;
171        Ok(value)
172    }
173
174    /// 读取 f64
175    ///
176    /// # Returns
177    /// 返回读取的 f64 值或 IO 错误
178    pub fn read_f64(&mut self) -> std::io::Result<f64> {
179        let value = self.reader.read_f64::<E>()?;
180        self.position += 8;
181        Ok(value)
182    }
183
184    /// 读取指定长度的字节数组
185    ///
186    /// # Arguments
187    /// * `len` - 要读取的字节数
188    ///
189    /// # Returns
190    /// 返回读取的字节数组或 IO 错误
191    pub fn read_bytes(&mut self, len: usize) -> std::io::Result<Vec<u8>> {
192        let mut buf = vec![0u8; len];
193        self.reader.read_exact(&mut buf)?;
194        self.position += len as u64;
195        Ok(buf)
196    }
197
198    /// 读取固定长度的字节数组
199    ///
200    /// # Returns
201    /// 返回读取的字节数组或 IO 错误
202    pub fn read_array<const N: usize>(&mut self) -> std::io::Result<[u8; N]> {
203        let mut buf = [0u8; N];
204        self.reader.read_exact(&mut buf)?;
205        self.position += N as u64;
206        Ok(buf)
207    }
208
209    /// 跳过指定数量的字节
210    ///
211    /// 注意:如果底层reader不支持Seek操作,此函数将返回错误
212    ///
213    /// # Arguments
214    /// * `count` - 要跳过的字节数
215    ///
216    /// # Returns
217    /// 返回操作结果
218    pub fn skip(&mut self, count: u64) -> std::io::Result<u64>
219    where
220        R: Seek,
221    {
222        let new_pos = self.reader.seek(SeekFrom::Current(count as i64))?;
223        self.position = new_pos;
224        Ok(new_pos)
225    }
226
227    /// 读取 LEB128 编码的无符号 32 位整数
228    ///
229    /// # Returns
230    /// 返回读取的 u32 值或 IO 错误
231    pub fn read_u32_leb128(&mut self) -> std::io::Result<u32> {
232        let mut result = 0u32;
233        let mut shift = 0;
234
235        loop {
236            let byte = self.read_u8()?;
237            result |= ((byte & 0x7F) as u32) << shift;
238
239            if byte & 0x80 == 0 {
240                break;
241            }
242
243            shift += 7;
244            if shift >= 32 {
245                return Err(std::io::Error::new(std::io::ErrorKind::InvalidData, "LEB128 value too large for u32"));
246            }
247        }
248
249        Ok(result)
250    }
251
252    /// 读取 LEB128 编码的有符号 32 位整数
253    ///
254    /// # Returns
255    /// 返回读取的 i32 值或 IO 错误
256    pub fn read_i32_leb128(&mut self) -> std::io::Result<i32> {
257        let mut result = 0i32;
258        let mut shift = 0;
259        let mut byte;
260
261        loop {
262            byte = self.read_u8()?;
263            result |= ((byte & 0x7F) as i32) << shift;
264            shift += 7;
265
266            if byte & 0x80 == 0 {
267                break;
268            }
269
270            if shift >= 32 {
271                return Err(std::io::Error::new(std::io::ErrorKind::InvalidData, "LEB128 value too large for i32"));
272            }
273        }
274
275        // 符号扩展
276        if shift < 32 && (byte & 0x40) != 0 {
277            result |= !0 << shift;
278        }
279
280        Ok(result)
281    }
282
283    /// 读取 LEB128 编码的有符号 64 位整数
284    ///
285    /// # Returns
286    /// 返回读取的 i64 值或 IO 错误
287    pub fn read_i64_leb128(&mut self) -> std::io::Result<i64> {
288        let mut result = 0i64;
289        let mut shift = 0;
290        let mut byte;
291
292        loop {
293            byte = self.read_u8()?;
294            result |= ((byte & 0x7F) as i64) << shift;
295            shift += 7;
296
297            if byte & 0x80 == 0 {
298                break;
299            }
300
301            if shift >= 64 {
302                return Err(std::io::Error::new(std::io::ErrorKind::InvalidData, "LEB128 value too large for i64"));
303            }
304        }
305
306        // 符号扩展
307        if shift < 64 && (byte & 0x40) != 0 {
308            result |= !0 << shift;
309        }
310
311        Ok(result)
312    }
313}
314
315impl<R, E> BinaryReader<R, E> {
316    /// 计算 LEB128 编码值的字节长度(静态方法)
317    ///
318    /// # Arguments
319    /// * `value` - 要计算长度的值
320    ///
321    /// # Returns
322    /// 返回编码后的字节长度
323    pub fn leb128_size(mut value: u32) -> u32 {
324        let mut size = 0;
325        loop {
326            value >>= 7;
327            size += 1;
328            if value == 0 {
329                break;
330            }
331        }
332        size
333    }
334}
335
336/// 源代码位置信息,表示代码在源文件中的位置
337///
338/// 该结构体用于跟踪源代码的位置信息,包括行号、列号等。
339#[derive(Copy, Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
340pub struct SourcePosition {
341    /// 行号,从 1 开始计数
342    ///
343    /// 表示当前位置所在的行号,第一行为 1。
344    pub line: u32,
345    /// 列号,从 1 开始计数
346    ///
347    /// 表示当前位置所在的列号,第一列为 1。
348    pub column: u32,
349    /// 字节偏移量,从 0 开始计数
350    ///
351    /// 表示从文件开始到当前位置的字节偏移量。
352    pub offset: usize,
353    /// 长度,表示该位置所覆盖的字节数
354    ///
355    /// 通常用于表示标记或符号的长度。
356    pub length: usize,
357}
358
359/// 源代码位置,包含文件 URL 和位置信息
360///
361/// 该结构体扩展了 SourcePosition,增加了文件 URL 信息,
362/// 可以表示代码在特定文件中的位置。
363#[derive(Clone, Debug, Serialize, Deserialize)]
364pub struct SourceLocation {
365    /// 行号,从 1 开始计数
366    ///
367    /// 表示当前位置所在的行号。
368    pub line: u32,
369    /// 列号,从 1 开始计数
370    ///
371    /// 表示当前位置所在的列号。
372    pub column: u32,
373    /// 源文件的 URL,可选
374    ///
375    /// 如果存在,表示包含该代码的文件的 URL 或路径。
376    /// 可以是文件系统路径或网络 URL。
377    pub url: Option<Url>,
378}
379
380impl Default for SourceLocation {
381    fn default() -> Self {
382        Self { line: 1, column: 1, url: None }
383    }
384}