1use std;
18
19#[derive(Debug)]
20pub(crate) enum NodeColour {
21 Red,
22 Black
23}
24
25impl NodeColour {
26 fn from(t: u8) -> Result<NodeColour, super::error::Error> {
27 match t {
28 0 => Ok(NodeColour::Red),
29 1 => Ok(NodeColour::Black),
30 _ => Err(super::error::Error::NodeTypeUnknown)
31 }
32 }
33}
34
35impl std::fmt::Display for NodeColour {
36 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
37 match *self {
38 NodeColour::Red => write!(f, "RED"),
39 NodeColour::Black => write!(f, "BLACK")
40 }
41 }
42}
43
44#[derive(PartialEq, Debug, Clone, Copy)]
45pub enum EntryType {
46 Empty,
48
49 UserStorage,
51
52 UserStream,
54
55 LockBytes,
57
58 Property,
60
61 RootStorage
63}
64
65impl EntryType {
66 fn from(t: u8) -> Result<EntryType, super::error::Error> {
67 match t {
68 0 => Ok(EntryType::Empty),
69 1 => Ok(EntryType::UserStorage),
70 2 => Ok(EntryType::UserStream),
71 3 => Ok(EntryType::LockBytes),
72 4 => Ok(EntryType::Property),
73 5 => Ok(EntryType::RootStorage),
74 _ => Err(super::error::Error::NodeTypeUnknown)
75 }
76 }
77}
78
79impl std::fmt::Display for EntryType {
80 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
81 match *self {
82 EntryType::Empty => write!(f, "Empty"),
83 EntryType::UserStorage => write!(f, "User storage"),
84 EntryType::UserStream => write!(f, "User stream"),
85 EntryType::LockBytes => write!(f, "?? Lock bytes ??"),
86 EntryType::Property => write!(f, "?? Property ??"),
87 EntryType::RootStorage => write!(f, "Root storage")
88 }
89 }
90}
91
92#[derive(Debug)]
111pub struct Entry {
112
113 id: u32,
115
116 name: std::string::String,
118
119 entry_type: EntryType,
121
122 color: NodeColour,
124
125 left_child_node: u32,
127
128 right_child_node: u32,
130
131 root_node: u32,
133
134 identifier: std::vec::Vec<u8>, flags: std::vec::Vec<u8>, creation_time: u64,
142
143 last_modification_time: u64,
145
146 sec_id_chain: std::vec::Vec<u32>,
148
149 size: usize,
151
152 children_nodes: std::vec::Vec<u32>,
154
155 parent_node: Option<u32>
157}
158
159impl Entry {
160
161 fn from_slice(sector: &[u8], dir_id: u32)
162 -> Result<Entry, super::error::Error> {
163 use util::FromSlice;
164 let entry = Entry {
165 id: dir_id,
166 name: Entry::build_name(§or[0 .. 64]),
167 entry_type: EntryType::from(sector[66])?,
168 color: NodeColour::from(sector[67])?,
169 left_child_node: u32::from_slice(§or[68 .. 72]),
170 right_child_node: u32::from_slice(§or[72 .. 76]),
171 root_node: u32::from_slice(§or[76 .. 80]),
172 identifier: sector[80 .. 96].to_vec(),
173 flags: sector[96 .. 100].to_vec(),
174 creation_time: u64::from_slice(§or[100 .. 108]),
175 last_modification_time: u64::from_slice(§or[108 .. 116]),
176 sec_id_chain: vec![u32::from_slice(§or[116 .. 120])],
177 size: usize::from_slice(§or[120 .. 124]),
178 children_nodes: std::vec::Vec::new(),
179 parent_node: None
180 };
181
182
183 Ok(entry)
184
185 }
186
187 fn build_name(array: &[u8]) -> std::string::String {
188 let mut name = std::string::String::new();
189
190 let mut i = 0usize;
191 while i < 64 && array[i] != 0 {
192 name.push(array[i] as char);
193 i = i + 2;
194 }
195
196 name
197 }
198
199 pub fn id(&self) -> u32 {
201 self.id
202 }
203
204 pub fn creation_time(&self) -> u64 {
206 self.creation_time
207 }
208
209
210 pub fn last_modification_time(&self) -> u64 {
212 self.last_modification_time
213 }
214
215 pub fn name(&self) -> &str {
217 &self.name
218 }
219
220 pub fn _type(&self) -> EntryType {
222 self.entry_type
223 }
224
225 pub fn len(&self) -> usize {
227 self.size
228 }
229
230 pub fn left_child_node(&self) -> u32 {
232 self.left_child_node
233 }
234
235 pub fn right_child_node(&self) -> u32 {
237 self.right_child_node
238 }
239
240 pub fn parent_node(&self) -> Option<u32> {
242 self.parent_node
243 }
244
245 pub fn children_nodes(&self) -> &std::vec::Vec<u32> {
247 &self.children_nodes
248 }
249}
250
251impl std::fmt::Display for Entry {
252 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
253 write!(f, "Entry #{}. Type: {}, Color: {}, Name: {},
254 Size: {}. SecID chain: {:?}",
255 self.id, self.entry_type, self.color, &self.name,
256 self.size, self.sec_id_chain)
257 }
258}
259
260
261pub struct EntrySlice<'s> {
283
284 max_chunk_size: usize,
286
287 chunks: std::vec::Vec<&'s [u8]>,
289
290 read: usize,
292
293 total_size: usize,
295
296 real_size: usize
298}
299
300impl<'s> EntrySlice<'s> {
301 fn new(max_chunk_size: usize, size: usize) -> EntrySlice<'s> {
302 EntrySlice {
303 max_chunk_size: max_chunk_size,
304 chunks: std::vec::Vec::new(),
305 read: 0usize,
306 total_size: size,
307 real_size: 0
308 }
309 }
310
311 fn add_chunk(&mut self, chunk: &'s [u8]) {
312 self.real_size += chunk.len();
313 self.chunks.push(chunk);
314 }
315
316 pub fn len(&self) -> usize {
318 self.total_size
319 }
320
321 pub fn real_len(&self) -> usize {
323 self.real_size
324 }
325}
326
327impl<'s> std::io::Read for EntrySlice<'s> {
328
329 fn read(&mut self, buf: &mut [u8]) -> Result<usize, std::io::Error> {
330 let to_read = std::cmp::min(buf.len(), self.total_size - self.read);
331 let result: Result<usize, std::io::Error>;
332 if to_read == 0 {
333 result = Ok(0usize);
334 } else {
335 let mut offset = self.read;
336 let mut read = 0;
337 while read != to_read {
338 let chunk_index = offset / self.max_chunk_size;
339 if chunk_index >= self.chunks.len() {
340 break;
341 }
342 let chunk = &self.chunks[chunk_index];
343 let local_offset = offset % self.max_chunk_size;
344 let end = std::cmp::min(local_offset + to_read - read,
345 self.max_chunk_size);
346 let slice = &chunk[local_offset .. end];
347 for u in slice {
348 buf[read] = *u;
349 read += 1;
350 self.read += 1;
351 }
352 offset = self.read;
353 }
354 result = Ok(read);
355 }
356
357 result
358 }
359}
360
361
362
363
364impl<'ole> super::ole::Reader<'ole> {
365
366
367 pub fn get_entry_slice(&self, entry: &Entry) ->
369 Result<EntrySlice, super::error::Error> {
370
371 let entry_slice: EntrySlice;
372 let size = entry.size;
373 if size == 0 {
374 Err(super::error::Error::EmptyEntry)
375 } else {
376 if &size < self.minimum_standard_stream_size.as_ref().unwrap() {
377 entry_slice = self.get_short_stream_slices(&entry.sec_id_chain, size)?;
378 } else {
379 entry_slice = self.get_stream_slices(&entry.sec_id_chain, size)?;
380 }
381 Ok(entry_slice)
382 }
383 }
384
385 pub(crate) fn build_directory_entries(&mut self)
386 -> Result<(), super::error::Error> {
387 let n_entry_by_sector = self.sec_size.as_ref().unwrap()
388 / super::constants::DIRECTORY_ENTRY_SIZE;
389 let mut entries = std::vec::Vec::<Entry>::with_capacity(
390 self.dsat.as_ref().unwrap().len() * n_entry_by_sector);
391
392 let mut k = 0usize;
393 for i in 0 .. self.dsat.as_ref().unwrap().len() {
394 let sector_index = self.dsat.as_ref().unwrap()[i];
395 let sector = self.read_sector(sector_index as usize)?;
396 for l in 0 .. n_entry_by_sector {
397 let entry = Entry::from_slice(§or[l
398 * super::constants::DIRECTORY_ENTRY_SIZE .. (l + 1)
399 * super::constants::DIRECTORY_ENTRY_SIZE], k as u32)?;
400 entries.push(entry);
401 k = k + 1;
402 }
403 }
404 let stream_size = *self.minimum_standard_stream_size.as_ref().unwrap();
405 for i in 0 .. entries.len() {
406 let entry = &mut entries[i];
407 match entry.entry_type {
408 EntryType::UserStream => {
409 let start_index = entry.sec_id_chain.pop().unwrap();
410 if entry.size < stream_size {
411 entry.sec_id_chain = self.build_chain_from_ssat(start_index);
412 } else {
413 entry.sec_id_chain = self.build_chain_from_sat(start_index);
414 }
415 },
416 EntryType::RootStorage => {
417 self.root_entry = Some(i as u32);
418 let start_index = entry.sec_id_chain.pop().unwrap();
419 entry.sec_id_chain = self.build_chain_from_sat(start_index);
420 },
421 _ => {}
422 }
423 }
424 self.entries = Some(entries);
425 self.build_entry_tree(0, None);
426 Ok(())
427 }
428
429 fn get_short_stream_slices(&self, chain: &std::vec::Vec<u32>, size: usize)
430 -> Result<EntrySlice, super::error::Error> {
431 let ssector_size = *self.short_sec_size.as_ref().unwrap();
432 let mut entry_slice = EntrySlice::new(ssector_size, size);
433 let short_stream_chain =
434 &self.entries.as_ref().unwrap()[0].sec_id_chain.clone();
435 let n_per_sector = *self.sec_size.as_ref().unwrap() /
436 ssector_size;
437 let mut total_read = 0;
438 for ssector_id in chain {
439 let sector_index = short_stream_chain[*ssector_id as usize / n_per_sector];
440 let sector = self.read_sector(sector_index as usize)?;
441 let ssector_index = *ssector_id as usize % n_per_sector;
442 let start = ssector_index as usize * ssector_size;
443 let end = start + std::cmp::min(ssector_size, size - total_read);
444 entry_slice.add_chunk(§or[start .. end]);
445 total_read += end - start;
446 }
447 Ok(entry_slice)
448 }
449
450 fn get_stream_slices(&self, chain: &std::vec::Vec<u32>, size: usize)
451 -> Result<EntrySlice, super::error::Error> {
452 let sector_size = *self.sec_size.as_ref().unwrap();
453 let mut entry_slice = EntrySlice::new(sector_size, size);
454 let mut total_read = 0;
455 for sector_id in chain {
456 let sector = self.read_sector(*sector_id as usize)?;
457 let start = 0usize;
458 let end = std::cmp::min(sector_size, size - total_read);
459 entry_slice.add_chunk(§or[start .. end]);
460 total_read += end - start;
461 }
462 Ok(entry_slice)
463 }
464
465 fn build_entry_tree(&mut self, id: u32, parent_id: Option<u32>) {
466
467 if id != super::constants::FREE_SECID_U32 {
468
469 self.entries.as_mut().unwrap()[id as usize].parent_node = parent_id;
471
472 if parent_id.is_some() {
474 self.entries.as_mut().unwrap()[parent_id.unwrap() as usize]
475 .children_nodes.push(id);
476 }
477
478 let node_type = self.entries.as_ref().unwrap()[id as usize]._type();
479
480 if node_type == EntryType::RootStorage || node_type ==
481 EntryType::UserStorage {
482 let child = self.entries.as_mut().unwrap()[id as usize].root_node;
483 self.build_entry_tree(child, Some(id));
484 }
485 let left_child = self.entries.as_mut().unwrap()[id as usize]
486 .left_child_node();
487 let right_child = self.entries.as_mut().unwrap()[id as usize]
488 .right_child_node();
489 let n = self.entries.as_ref().unwrap().len() as u32;
490 if left_child < n {
491 self.build_entry_tree(left_child, parent_id);
492 }
493 if right_child < n {
494 self.build_entry_tree(right_child, parent_id);
495 }
496 }
497 }
498}