pe_assembler/formats/obj/
reader.rs1use crate::{
2 helpers::{CoffReader, read_coff_header, read_section_headers, read_coff_object},
3 types::coff::{CoffHeader, CoffInfo, CoffObject, SectionHeader},
4};
5use gaia_types::{GaiaDiagnostics, GaiaError};
6use std::{
7 io::{Read, Seek},
8};
9
10#[derive(Debug)]
12pub struct ObjReader<R> {
13 reader: R,
15 lazy_header: Option<CoffHeader>,
16 lazy_section_headers: Option<Vec<SectionHeader>>,
17 lazy_object: Option<CoffObject>,
18 lazy_info: Option<CoffInfo>,
19 diagnostics: Vec<GaiaError>,
20}
21
22impl<R> ObjReader<R> {
23 pub fn new(reader: R) -> Self {
24 Self {
25 reader,
26 lazy_header: None,
27 lazy_section_headers: None,
28 lazy_object: None,
29 lazy_info: None,
30 diagnostics: vec![],
31 }
32 }
33}
34
35impl<W: Read + Seek> CoffReader<W> for ObjReader<W> {
36 fn get_viewer(&mut self) -> &mut W {
37 &mut self.reader
38 }
39
40 fn add_diagnostics(&mut self, error: impl Into<GaiaError>) {
41 self.diagnostics.push(error.into());
42 }
43
44 fn get_coff_header(&mut self) -> Result<&CoffHeader, GaiaError> {
45 if self.lazy_header.is_none() {
46 let header = read_coff_header(self)?;
47 self.lazy_header = Some(header);
48 }
49 Ok(self.lazy_header.as_ref().unwrap())
50 }
51
52 fn set_coff_header(&mut self, head: CoffHeader) -> Option<CoffHeader> {
53 self.lazy_header.replace(head)
54 }
55
56 fn get_section_headers(&mut self) -> Result<&[SectionHeader], GaiaError> {
57 if self.lazy_section_headers.is_none() {
58 let headers = read_section_headers(self)?;
59 self.lazy_section_headers = Some(headers);
60 }
61 Ok(self.lazy_section_headers.as_ref().unwrap())
62 }
63
64 fn set_section_headers(&mut self, headers: Vec<SectionHeader>) -> Vec<SectionHeader> {
65 self.lazy_section_headers.replace(headers).unwrap_or_default()
66 }
67
68 fn get_coff_object(&mut self) -> Result<&CoffObject, GaiaError> {
69 if self.lazy_object.is_none() {
70 let object = read_coff_object(self)?;
71 self.lazy_object = Some(object);
72 }
73 Ok(self.lazy_object.as_ref().unwrap())
74 }
75
76 fn set_coff_object(&mut self, object: CoffObject) -> Option<CoffObject> {
77 self.lazy_object.replace(object)
78 }
79
80 fn get_coff_info(&mut self) -> Result<&CoffInfo, GaiaError> {
81 if self.lazy_info.is_none() {
82 let info = self.create_coff_info()?;
83 self.lazy_info = Some(info);
84 }
85 Ok(self.lazy_info.as_ref().unwrap())
86 }
87
88 fn set_coff_info(&mut self, info: CoffInfo) -> Option<CoffInfo> {
89 self.lazy_info.replace(info)
90 }
91}
92
93impl<W: Read + Seek> ObjReader<W> {
94 pub fn read_object(mut self) -> GaiaDiagnostics<CoffObject> {
96 match self.get_coff_object() {
97 Ok(_) => match self.lazy_object {
98 Some(object) => GaiaDiagnostics { result: Ok(object), diagnostics: self.diagnostics },
99 None => unreachable!(),
100 },
101 Err(error) => GaiaDiagnostics { result: Err(error), diagnostics: self.diagnostics },
102 }
103 }
104
105 pub fn view(&mut self) -> Result<CoffInfo, GaiaError> {
107 Ok(self.get_coff_info()?.clone())
108 }
109}
110