1#![forbid(unsafe_code)]
2#![deny(missing_docs)]
3#![doc = include_str!("../README.md")]
4#![no_std]
5extern crate alloc;
6#[cfg(feature = "std")]
7extern crate std;
8
9pub mod deserializer;
10pub mod error;
11pub mod models;
12
13pub use deserializer::{iter::PropertyIterator, typedstream::TypedStreamDeserializer};
14pub use models::{archived::Archived, output_data::OutputData};
15
16#[cfg(test)]
17mod test_typedstream_deserializer {
18 extern crate std;
19 use alloc::vec;
20 use std::{env::current_dir, fs::File, io::Read, println};
21
22 use crate::{
23 deserializer::{iter::print_resolved, typedstream::TypedStreamDeserializer},
24 models::{archived::Archived, class::Class, output_data::OutputData, types::Type},
25 };
26
27 #[test]
28 fn test_parse_text_iter() {
29 let typedstream_path = current_dir()
30 .unwrap()
31 .as_path()
32 .join("src/test_data/AttributedBodyTextOnly");
33 let mut file = File::open(typedstream_path).unwrap();
34 let mut bytes = vec![];
35 file.read_to_end(&mut bytes).unwrap();
36
37 let mut typedstream = TypedStreamDeserializer::new(&bytes);
38 let root = typedstream.oxidize().unwrap();
39 let root_obj = typedstream.resolve_properties(root).unwrap();
40 let primitives = root_obj.primitives();
41
42 assert_eq!(
43 primitives,
44 vec![
45 &OutputData::String("Noter test"),
46 &OutputData::UnsignedInteger(10),
47 &OutputData::SignedInteger(1),
48 &OutputData::SignedInteger(0),
49 &OutputData::String("__kIMMessagePartAttributeName"),
50 &OutputData::SignedInteger(1)
51 ]
52 );
53 }
54
55 #[test]
56 fn test_parse_text_basic() {
57 let typedstream_path = current_dir()
58 .unwrap()
59 .as_path()
60 .join("src/test_data/AttributedBodyTextOnly");
61 let mut file = File::open(typedstream_path).unwrap();
62 let mut bytes = vec![];
63 file.read_to_end(&mut bytes).unwrap();
64
65 let mut typedstream = TypedStreamDeserializer::new(&bytes);
66 let root = typedstream.oxidize().unwrap();
67 println!("\nResults:");
68 println!("Root object: {:x?}", typedstream.object_table[root]);
69 print_resolved(typedstream.resolve_properties(root).unwrap(), 2);
70
71 println!("\nFound {:?} types:", typedstream.type_table.len());
72 typedstream
73 .type_table
74 .iter()
75 .enumerate()
76 .for_each(|(idx, item)| println!("\t{idx}: {item:?}"));
77
78 println!("\nFound {:?} objects:", typedstream.object_table.len());
79 typedstream
80 .object_table
81 .iter()
82 .enumerate()
83 .for_each(|(idx, item)| println!("\t{idx}: {item:?}"));
84
85 let expected_types = vec![
86 vec![Type::Object],
87 vec![Type::String("NSMutableAttributedString")],
88 vec![Type::String("NSAttributedString")],
89 vec![Type::String("NSObject")],
90 vec![Type::String("NSMutableString")],
91 vec![Type::String("NSString")],
92 vec![Type::Utf8String],
93 vec![Type::SignedInt, Type::UnsignedInt],
94 vec![Type::String("NSDictionary")],
95 vec![Type::SignedInt],
96 vec![Type::String("NSNumber")],
97 vec![Type::String("NSValue")],
98 vec![Type::EmbeddedData],
99 ];
100
101 let expected_objects = vec![
102 Archived::Object {
103 class: 1,
104 data: vec![
105 vec![OutputData::Object(4)],
106 vec![
107 OutputData::SignedInteger(1),
108 OutputData::UnsignedInteger(10),
109 ],
110 vec![OutputData::Object(7)],
111 ],
112 },
113 Archived::Class(Class {
114 name_index: 1,
115 version: 0,
116 parent_index: Some(2),
117 }),
118 Archived::Class(Class {
119 name_index: 2,
120 version: 0,
121 parent_index: Some(3),
122 }),
123 Archived::Class(Class {
124 name_index: 3,
125 version: 0,
126 parent_index: None,
127 }),
128 Archived::Object {
129 class: 5,
130 data: vec![vec![OutputData::String("Noter test")]],
131 },
132 Archived::Class(Class {
133 name_index: 4,
134 version: 1,
135 parent_index: Some(6),
136 }),
137 Archived::Class(Class {
138 name_index: 5,
139 version: 1,
140 parent_index: Some(3),
141 }),
142 Archived::Object {
143 class: 8,
144 data: vec![
145 vec![OutputData::SignedInteger(1)],
146 vec![OutputData::Object(9)],
147 vec![OutputData::Object(10)],
148 ],
149 },
150 Archived::Class(Class {
151 name_index: 8,
152 version: 0,
153 parent_index: Some(3),
154 }),
155 Archived::Object {
156 class: 6,
157 data: vec![vec![OutputData::String("__kIMMessagePartAttributeName")]],
158 },
159 Archived::Object {
160 class: 11,
161 data: vec![vec![OutputData::SignedInteger(0)]],
162 },
163 Archived::Class(Class {
164 name_index: 10,
165 version: 0,
166 parent_index: Some(12),
167 }),
168 Archived::Class(Class {
169 name_index: 11,
170 version: 0,
171 parent_index: Some(3),
172 }),
173 Archived::Type(9),
174 ];
175
176 assert_eq!(typedstream.type_table, expected_types);
177 assert_eq!(typedstream.object_table, expected_objects);
178 }
179
180 #[test]
181 fn test_parse_text_basic_2() {
182 let typedstream_path = current_dir()
183 .unwrap()
184 .as_path()
185 .join("src/test_data/AttributedBodyTextOnly2");
186 let mut file = File::open(typedstream_path).unwrap();
187 let mut bytes = vec![];
188 file.read_to_end(&mut bytes).unwrap();
189
190 let mut typedstream = TypedStreamDeserializer::new(&bytes);
191 let root = typedstream.oxidize().unwrap();
192 println!("\nResults:");
193 println!("Root object: {:x?}", typedstream.object_table[root]);
194 print_resolved(typedstream.resolve_properties(root).unwrap(), 2);
195
196 println!("\nFound {:?} types:", typedstream.type_table.len());
197 typedstream
198 .type_table
199 .iter()
200 .enumerate()
201 .for_each(|(idx, item)| println!("\t{idx}: {item:?}"));
202
203 println!("\nFound {:?} objects:", typedstream.object_table.len());
204 typedstream
205 .object_table
206 .iter()
207 .enumerate()
208 .for_each(|(idx, item)| println!("\t{idx}: {item:?}"));
209
210 let expected_types = vec![
211 vec![Type::Object],
212 vec![Type::String("NSAttributedString")],
213 vec![Type::String("NSObject")],
214 vec![Type::String("NSString")],
215 vec![Type::Utf8String],
216 vec![Type::SignedInt, Type::UnsignedInt],
217 vec![Type::String("NSDictionary")],
218 vec![Type::SignedInt],
219 vec![Type::String("NSNumber")],
220 vec![Type::String("NSValue")],
221 vec![Type::EmbeddedData],
222 vec![Type::SignedInt],
223 ];
224
225 let expected_objects = vec![
226 Archived::Object {
227 class: 1,
228 data: vec![
229 vec![OutputData::Object(3)],
230 vec![OutputData::SignedInteger(1), OutputData::UnsignedInteger(6)],
231 vec![OutputData::Object(5)],
232 ],
233 },
234 Archived::Class(Class {
235 name_index: 1,
236 version: 0,
237 parent_index: Some(2),
238 }),
239 Archived::Class(Class {
240 name_index: 2,
241 version: 0,
242 parent_index: None,
243 }),
244 Archived::Object {
245 class: 4,
246 data: vec![vec![OutputData::String("Test 3")]],
247 },
248 Archived::Class(Class {
249 name_index: 3,
250 version: 1,
251 parent_index: Some(2),
252 }),
253 Archived::Object {
254 class: 6,
255 data: vec![
256 vec![OutputData::SignedInteger(2)],
257 vec![OutputData::Object(7)],
258 vec![OutputData::Object(8)],
259 vec![OutputData::Object(12)],
260 vec![OutputData::Object(13)],
261 ],
262 },
263 Archived::Class(Class {
264 name_index: 6,
265 version: 0,
266 parent_index: Some(2),
267 }),
268 Archived::Object {
269 class: 4,
270 data: vec![vec![OutputData::String(
271 "__kIMBaseWritingDirectionAttributeName",
272 )]],
273 },
274 Archived::Object {
275 class: 9,
276 data: vec![vec![OutputData::SignedInteger(-1)]],
277 },
278 Archived::Class(Class {
279 name_index: 8,
280 version: 0,
281 parent_index: Some(10),
282 }),
283 Archived::Class(Class {
284 name_index: 9,
285 version: 0,
286 parent_index: Some(2),
287 }),
288 Archived::Type(11),
289 Archived::Object {
290 class: 4,
291 data: vec![vec![OutputData::String("__kIMMessagePartAttributeName")]],
292 },
293 Archived::Object {
294 class: 9,
295 data: vec![vec![OutputData::SignedInteger(0)]],
296 },
297 ];
298
299 assert_eq!(typedstream.type_table, expected_types);
300 assert_eq!(typedstream.object_table, expected_objects);
301 }
302
303 #[test]
304 fn test_parse_text_overlapping_format_url() {
305 let typedstream_path = current_dir().unwrap().as_path().join("src/test_data/35123");
306 let mut file = File::open(typedstream_path).unwrap();
307 let mut bytes = vec![];
308 file.read_to_end(&mut bytes).unwrap();
309
310 let mut typedstream = TypedStreamDeserializer::new(&bytes);
311 let root = typedstream.oxidize().unwrap();
312 println!("\nResults:");
313 println!("Root object: {:x?}", typedstream.object_table[root]);
314 print_resolved(typedstream.resolve_properties(root).unwrap(), 2);
315
316 println!("\nFound {:?} types:", typedstream.type_table.len());
317 typedstream
318 .type_table
319 .iter()
320 .enumerate()
321 .for_each(|(idx, item)| println!("\t{idx}: {item:?}"));
322
323 println!("\nFound {:?} objects:", typedstream.object_table.len());
324 typedstream
325 .object_table
326 .iter()
327 .enumerate()
328 .for_each(|(idx, item)| println!("\t{idx}: {item:?}"));
329
330 let expected_types = vec![
331 vec![Type::Object],
332 vec![Type::String("NSMutableAttributedString")],
333 vec![Type::String("NSAttributedString")],
334 vec![Type::String("NSObject")],
335 vec![Type::String("NSMutableString")],
336 vec![Type::String("NSString")],
337 vec![Type::Utf8String],
338 vec![Type::SignedInt, Type::UnsignedInt],
339 vec![Type::String("NSDictionary")],
340 vec![Type::SignedInt],
341 vec![Type::String("NSNumber")],
342 vec![Type::String("NSValue")],
343 vec![Type::EmbeddedData],
344 vec![Type::SignedInt],
345 vec![Type::String("NSURL")],
346 vec![Type::SignedInt],
347 vec![Type::String("NSData")],
348 vec![Type::Array(649)],
349 ];
350
351 let expected_objects = vec![
352 Archived::Object {
353 class: 1,
354 data: vec![
355 vec![OutputData::Object(4)],
356 vec![OutputData::SignedInteger(1), OutputData::UnsignedInteger(5)],
357 vec![OutputData::Object(7)],
358 vec![OutputData::SignedInteger(2), OutputData::UnsignedInteger(2)],
359 vec![OutputData::Object(26)],
360 vec![OutputData::SignedInteger(3), OutputData::UnsignedInteger(3)],
361 vec![OutputData::Object(28)],
362 vec![OutputData::SignedInteger(4), OutputData::UnsignedInteger(6)],
363 vec![OutputData::Object(31)],
364 vec![OutputData::SignedInteger(5), OutputData::UnsignedInteger(8)],
365 vec![OutputData::Object(33)],
366 vec![
367 OutputData::SignedInteger(6),
368 OutputData::UnsignedInteger(10),
369 ],
370 vec![OutputData::Object(35)],
371 vec![
372 OutputData::SignedInteger(7),
373 OutputData::UnsignedInteger(13),
374 ],
375 vec![OutputData::Object(36)],
376 vec![OutputData::SignedInteger(8), OutputData::UnsignedInteger(2)],
377 vec![OutputData::Object(37)],
378 vec![OutputData::SignedInteger(9), OutputData::UnsignedInteger(4)],
379 vec![OutputData::Object(38)],
380 vec![
381 OutputData::SignedInteger(10),
382 OutputData::UnsignedInteger(5),
383 ],
384 vec![OutputData::Object(41)],
385 vec![OutputData::SignedInteger(8), OutputData::UnsignedInteger(1)],
386 vec![
387 OutputData::SignedInteger(11),
388 OutputData::UnsignedInteger(5),
389 ],
390 vec![OutputData::Object(43)],
391 vec![OutputData::SignedInteger(8), OutputData::UnsignedInteger(1)],
392 vec![
393 OutputData::SignedInteger(12),
394 OutputData::UnsignedInteger(3),
395 ],
396 vec![OutputData::Object(45)],
397 vec![OutputData::SignedInteger(8), OutputData::UnsignedInteger(1)],
398 vec![
399 OutputData::SignedInteger(13),
400 OutputData::UnsignedInteger(7),
401 ],
402 vec![OutputData::Object(47)],
403 vec![OutputData::SignedInteger(8), OutputData::UnsignedInteger(1)],
404 vec![
405 OutputData::SignedInteger(14),
406 OutputData::UnsignedInteger(6),
407 ],
408 vec![OutputData::Object(49)],
409 vec![OutputData::SignedInteger(8), OutputData::UnsignedInteger(1)],
410 vec![
411 OutputData::SignedInteger(15),
412 OutputData::UnsignedInteger(5),
413 ],
414 vec![OutputData::Object(51)],
415 vec![OutputData::SignedInteger(8), OutputData::UnsignedInteger(1)],
416 vec![
417 OutputData::SignedInteger(16),
418 OutputData::UnsignedInteger(6),
419 ],
420 vec![OutputData::Object(53)],
421 ],
422 },
423 Archived::Class(Class {
424 name_index: 1,
425 version: 0,
426 parent_index: Some(2),
427 }),
428 Archived::Class(Class {
429 name_index: 2,
430 version: 0,
431 parent_index: Some(3),
432 }),
433 Archived::Class(Class {
434 name_index: 3,
435 version: 0,
436 parent_index: None,
437 }),
438 Archived::Object {
439 class: 5,
440 data: vec![vec![OutputData::String(
441 "0123456789\nBold Italics Underline Strikethrough\u{a0}\u{a0}Big Small Shake Nod Explode Ripple Bloom Jitter",
442 )]],
443 },
444 Archived::Class(Class {
445 name_index: 4,
446 version: 1,
447 parent_index: Some(6),
448 }),
449 Archived::Class(Class {
450 name_index: 5,
451 version: 1,
452 parent_index: Some(3),
453 }),
454 Archived::Object {
455 class: 8,
456 data: vec![
457 vec![OutputData::SignedInteger(5)],
458 vec![OutputData::Object(9)],
459 vec![OutputData::Object(10)],
460 vec![OutputData::Object(14)],
461 vec![OutputData::Object(15)],
462 vec![OutputData::Object(17)],
463 vec![OutputData::Object(18)],
464 vec![OutputData::Object(21)],
465 vec![OutputData::Object(22)],
466 vec![OutputData::Object(23)],
467 vec![OutputData::Object(24)],
468 ],
469 },
470 Archived::Class(Class {
471 name_index: 8,
472 version: 0,
473 parent_index: Some(3),
474 }),
475 Archived::Object {
476 class: 6,
477 data: vec![vec![OutputData::String("__kIMTextUnderlineAttributeName")]],
478 },
479 Archived::Object {
480 class: 11,
481 data: vec![vec![OutputData::SignedInteger(1)]],
482 },
483 Archived::Class(Class {
484 name_index: 10,
485 version: 0,
486 parent_index: Some(12),
487 }),
488 Archived::Class(Class {
489 name_index: 11,
490 version: 0,
491 parent_index: Some(3),
492 }),
493 Archived::Type(9),
494 Archived::Object {
495 class: 6,
496 data: vec![vec![OutputData::String(
497 "__kIMBaseWritingDirectionAttributeName",
498 )]],
499 },
500 Archived::Object {
501 class: 11,
502 data: vec![vec![OutputData::SignedInteger(-1)]],
503 },
504 Archived::Type(13),
505 Archived::Object {
506 class: 6,
507 data: vec![vec![OutputData::String("__kIMLinkAttributeName")]],
508 },
509 Archived::Object {
510 class: 19,
511 data: vec![
512 vec![OutputData::SignedInteger(0)],
513 vec![OutputData::Object(20)],
514 ],
515 },
516 Archived::Class(Class {
517 name_index: 14,
518 version: 0,
519 parent_index: Some(3),
520 }),
521 Archived::Object {
522 class: 6,
523 data: vec![vec![OutputData::String("tel:0123456789")]],
524 },
525 Archived::Object {
526 class: 6,
527 data: vec![vec![OutputData::String("__kIMMessagePartAttributeName")]],
528 },
529 Archived::Object {
530 class: 11,
531 data: vec![vec![OutputData::SignedInteger(0)]],
532 },
533 Archived::Object {
534 class: 6,
535 data: vec![vec![OutputData::String("__kIMPhoneNumberAttributeName")]],
536 },
537 Archived::Object {
538 class: 25,
539 data: vec![
540 vec![OutputData::SignedInteger(649)],
541 vec![OutputData::Array(&[
542 98, 112, 108, 105, 115, 116, 48, 48, 212, 1, 2, 3, 4, 5, 6, 7, 12, 88, 36,
543 118, 101, 114, 115, 105, 111, 110, 89, 36, 97, 114, 99, 104, 105, 118, 101,
544 114, 84, 36, 116, 111, 112, 88, 36, 111, 98, 106, 101, 99, 116, 115, 18, 0,
545 1, 134, 160, 95, 16, 15, 78, 83, 75, 101, 121, 101, 100, 65, 114, 99, 104,
546 105, 118, 101, 114, 210, 8, 9, 10, 11, 87, 118, 101, 114, 115, 105, 111,
547 110, 89, 100, 100, 45, 114, 101, 115, 117, 108, 116, 128, 16, 128, 1, 175,
548 16, 17, 13, 14, 28, 36, 37, 38, 44, 45, 46, 51, 57, 61, 62, 63, 66, 69, 73,
549 85, 36, 110, 117, 108, 108, 215, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
550 25, 26, 27, 26, 82, 77, 83, 86, 36, 99, 108, 97, 115, 115, 82, 65, 82, 81,
551 84, 81, 80, 82, 83, 82, 82, 86, 78, 128, 6, 128, 15, 128, 2, 128, 7, 16, 1,
552 128, 8, 212, 29, 30, 31, 16, 32, 33, 34, 35, 95, 16, 18, 78, 83, 46, 114,
553 97, 110, 103, 101, 118, 97, 108, 46, 108, 101, 110, 103, 116, 104, 95, 16,
554 20, 78, 83, 46, 114, 97, 110, 103, 101, 118, 97, 108, 46, 108, 111, 99, 97,
555 116, 105, 111, 110, 90, 78, 83, 46, 115, 112, 101, 99, 105, 97, 108, 128,
556 3, 128, 4, 16, 4, 128, 5, 16, 10, 16, 0, 210, 39, 40, 41, 42, 90, 36, 99,
557 108, 97, 115, 115, 110, 97, 109, 101, 88, 36, 99, 108, 97, 115, 115, 101,
558 115, 87, 78, 83, 86, 97, 108, 117, 101, 162, 41, 43, 88, 78, 83, 79, 98,
559 106, 101, 99, 116, 90, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 91, 80, 104,
560 111, 110, 101, 78, 117, 109, 98, 101, 114, 210, 47, 16, 48, 50, 90, 78, 83,
561 46, 111, 98, 106, 101, 99, 116, 115, 161, 49, 128, 9, 128, 14, 215, 15, 16,
562 17, 18, 19, 20, 21, 52, 23, 54, 55, 26, 56, 26, 128, 11, 128, 15, 128, 10,
563 128, 12, 128, 13, 212, 29, 30, 31, 16, 32, 33, 34, 35, 128, 3, 128, 4, 128,
564 5, 90, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 85, 86, 97, 108, 117, 101,
565 210, 47, 16, 64, 50, 160, 128, 14, 210, 39, 40, 67, 68, 87, 78, 83, 65,
566 114, 114, 97, 121, 162, 67, 43, 210, 39, 40, 70, 71, 95, 16, 15, 68, 68,
567 83, 99, 97, 110, 110, 101, 114, 82, 101, 115, 117, 108, 116, 162, 72, 43,
568 95, 16, 15, 68, 68, 83, 99, 97, 110, 110, 101, 114, 82, 101, 115, 117, 108,
569 116, 16, 1, 0, 8, 0, 17, 0, 26, 0, 36, 0, 41, 0, 50, 0, 55, 0, 73, 0, 78,
570 0, 86, 0, 96, 0, 98, 0, 100, 0, 120, 0, 126, 0, 141, 0, 144, 0, 151, 0,
571 154, 0, 156, 0, 158, 0, 161, 0, 164, 0, 166, 0, 168, 0, 170, 0, 172, 0,
572 174, 0, 176, 0, 185, 0, 206, 0, 229, 0, 240, 0, 242, 0, 244, 0, 246, 0,
573 248, 0, 250, 0, 252, 1, 1, 1, 12, 1, 21, 1, 29, 1, 32, 1, 41, 1, 52, 1, 64,
574 1, 69, 1, 80, 1, 82, 1, 84, 1, 86, 1, 101, 1, 103, 1, 105, 1, 107, 1, 109,
575 1, 111, 1, 120, 1, 122, 1, 124, 1, 126, 1, 137, 1, 143, 1, 148, 1, 149, 1,
576 151, 1, 156, 1, 164, 1, 167, 1, 172, 1, 190, 1, 193, 1, 211, 0, 0, 0, 0, 0,
577 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 74, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
578 1, 213,
579 ])],
580 ],
581 },
582 Archived::Class(Class {
583 name_index: 16,
584 version: 0,
585 parent_index: Some(3),
586 }),
587 Archived::Object {
588 class: 8,
589 data: vec![
590 vec![OutputData::SignedInteger(6)],
591 vec![OutputData::Object(14)],
592 vec![OutputData::Object(15)],
593 vec![OutputData::Object(9)],
594 vec![OutputData::Object(10)],
595 vec![OutputData::Object(23)],
596 vec![OutputData::Object(24)],
597 vec![OutputData::Object(27)],
598 vec![OutputData::Object(10)],
599 vec![OutputData::Object(17)],
600 vec![OutputData::Object(18)],
601 vec![OutputData::Object(21)],
602 vec![OutputData::Object(22)],
603 ],
604 },
605 Archived::Object {
606 class: 6,
607 data: vec![vec![OutputData::String(
608 "__kIMTextStrikethroughAttributeName",
609 )]],
610 },
611 Archived::Object {
612 class: 8,
613 data: vec![
614 vec![OutputData::SignedInteger(5)],
615 vec![OutputData::Object(14)],
616 vec![OutputData::Object(15)],
617 vec![OutputData::Object(27)],
618 vec![OutputData::Object(10)],
619 vec![OutputData::Object(17)],
620 vec![OutputData::Object(29)],
621 vec![OutputData::Object(21)],
622 vec![OutputData::Object(22)],
623 vec![OutputData::Object(23)],
624 vec![OutputData::Object(24)],
625 ],
626 },
627 Archived::Object {
628 class: 19,
629 data: vec![
630 vec![OutputData::SignedInteger(0)],
631 vec![OutputData::Object(30)],
632 ],
633 },
634 Archived::Object {
635 class: 6,
636 data: vec![vec![OutputData::String("tel:0123456789")]],
637 },
638 Archived::Object {
639 class: 8,
640 data: vec![
641 vec![OutputData::SignedInteger(3)],
642 vec![OutputData::Object(14)],
643 vec![OutputData::Object(15)],
644 vec![OutputData::Object(21)],
645 vec![OutputData::Object(22)],
646 vec![OutputData::Object(32)],
647 vec![OutputData::Object(10)],
648 ],
649 },
650 Archived::Object {
651 class: 6,
652 data: vec![vec![OutputData::String("__kIMTextBoldAttributeName")]],
653 },
654 Archived::Object {
655 class: 8,
656 data: vec![
657 vec![OutputData::SignedInteger(4)],
658 vec![OutputData::Object(32)],
659 vec![OutputData::Object(10)],
660 vec![OutputData::Object(21)],
661 vec![OutputData::Object(22)],
662 vec![OutputData::Object(14)],
663 vec![OutputData::Object(15)],
664 vec![OutputData::Object(34)],
665 vec![OutputData::Object(10)],
666 ],
667 },
668 Archived::Object {
669 class: 6,
670 data: vec![vec![OutputData::String("__kIMTextItalicAttributeName")]],
671 },
672 Archived::Object {
673 class: 8,
674 data: vec![
675 vec![OutputData::SignedInteger(5)],
676 vec![OutputData::Object(32)],
677 vec![OutputData::Object(10)],
678 vec![OutputData::Object(14)],
679 vec![OutputData::Object(15)],
680 vec![OutputData::Object(21)],
681 vec![OutputData::Object(22)],
682 vec![OutputData::Object(9)],
683 vec![OutputData::Object(10)],
684 vec![OutputData::Object(34)],
685 vec![OutputData::Object(10)],
686 ],
687 },
688 Archived::Object {
689 class: 8,
690 data: vec![
691 vec![OutputData::SignedInteger(6)],
692 vec![OutputData::Object(14)],
693 vec![OutputData::Object(15)],
694 vec![OutputData::Object(34)],
695 vec![OutputData::Object(10)],
696 vec![OutputData::Object(32)],
697 vec![OutputData::Object(10)],
698 vec![OutputData::Object(27)],
699 vec![OutputData::Object(10)],
700 vec![OutputData::Object(21)],
701 vec![OutputData::Object(22)],
702 vec![OutputData::Object(9)],
703 vec![OutputData::Object(10)],
704 ],
705 },
706 Archived::Object {
707 class: 8,
708 data: vec![
709 vec![OutputData::SignedInteger(2)],
710 vec![OutputData::Object(14)],
711 vec![OutputData::Object(15)],
712 vec![OutputData::Object(21)],
713 vec![OutputData::Object(22)],
714 ],
715 },
716 Archived::Object {
717 class: 8,
718 data: vec![
719 vec![OutputData::SignedInteger(3)],
720 vec![OutputData::Object(14)],
721 vec![OutputData::Object(15)],
722 vec![OutputData::Object(21)],
723 vec![OutputData::Object(22)],
724 vec![OutputData::Object(39)],
725 vec![OutputData::Object(40)],
726 ],
727 },
728 Archived::Object {
729 class: 6,
730 data: vec![vec![OutputData::String("__kIMTextEffectAttributeName")]],
731 },
732 Archived::Object {
733 class: 11,
734 data: vec![vec![OutputData::SignedInteger(5)]],
735 },
736 Archived::Object {
737 class: 8,
738 data: vec![
739 vec![OutputData::SignedInteger(3)],
740 vec![OutputData::Object(14)],
741 vec![OutputData::Object(15)],
742 vec![OutputData::Object(21)],
743 vec![OutputData::Object(22)],
744 vec![OutputData::Object(39)],
745 vec![OutputData::Object(42)],
746 ],
747 },
748 Archived::Object {
749 class: 11,
750 data: vec![vec![OutputData::SignedInteger(11)]],
751 },
752 Archived::Object {
753 class: 8,
754 data: vec![
755 vec![OutputData::SignedInteger(3)],
756 vec![OutputData::Object(14)],
757 vec![OutputData::Object(15)],
758 vec![OutputData::Object(21)],
759 vec![OutputData::Object(22)],
760 vec![OutputData::Object(39)],
761 vec![OutputData::Object(44)],
762 ],
763 },
764 Archived::Object {
765 class: 11,
766 data: vec![vec![OutputData::SignedInteger(9)]],
767 },
768 Archived::Object {
769 class: 8,
770 data: vec![
771 vec![OutputData::SignedInteger(3)],
772 vec![OutputData::Object(14)],
773 vec![OutputData::Object(15)],
774 vec![OutputData::Object(21)],
775 vec![OutputData::Object(22)],
776 vec![OutputData::Object(39)],
777 vec![OutputData::Object(46)],
778 ],
779 },
780 Archived::Object {
781 class: 11,
782 data: vec![vec![OutputData::SignedInteger(8)]],
783 },
784 Archived::Object {
785 class: 8,
786 data: vec![
787 vec![OutputData::SignedInteger(3)],
788 vec![OutputData::Object(14)],
789 vec![OutputData::Object(15)],
790 vec![OutputData::Object(21)],
791 vec![OutputData::Object(22)],
792 vec![OutputData::Object(39)],
793 vec![OutputData::Object(48)],
794 ],
795 },
796 Archived::Object {
797 class: 11,
798 data: vec![vec![OutputData::SignedInteger(12)]],
799 },
800 Archived::Object {
801 class: 8,
802 data: vec![
803 vec![OutputData::SignedInteger(3)],
804 vec![OutputData::Object(14)],
805 vec![OutputData::Object(15)],
806 vec![OutputData::Object(21)],
807 vec![OutputData::Object(22)],
808 vec![OutputData::Object(39)],
809 vec![OutputData::Object(50)],
810 ],
811 },
812 Archived::Object {
813 class: 11,
814 data: vec![vec![OutputData::SignedInteger(4)]],
815 },
816 Archived::Object {
817 class: 8,
818 data: vec![
819 vec![OutputData::SignedInteger(3)],
820 vec![OutputData::Object(14)],
821 vec![OutputData::Object(15)],
822 vec![OutputData::Object(21)],
823 vec![OutputData::Object(22)],
824 vec![OutputData::Object(39)],
825 vec![OutputData::Object(52)],
826 ],
827 },
828 Archived::Object {
829 class: 11,
830 data: vec![vec![OutputData::SignedInteger(6)]],
831 },
832 Archived::Object {
833 class: 8,
834 data: vec![
835 vec![OutputData::SignedInteger(3)],
836 vec![OutputData::Object(14)],
837 vec![OutputData::Object(15)],
838 vec![OutputData::Object(21)],
839 vec![OutputData::Object(22)],
840 vec![OutputData::Object(39)],
841 vec![OutputData::Object(54)],
842 ],
843 },
844 Archived::Object {
845 class: 11,
846 data: vec![vec![OutputData::SignedInteger(10)]],
847 },
848 ];
849
850 assert_eq!(typedstream.type_table, expected_types);
851 assert_eq!(
852 typedstream.object_table[..expected_objects.len()],
853 expected_objects
854 );
855 }
856
857 #[test]
858 fn test_parse_text_overlapping_url_short() {
859 let typedstream_path = current_dir()
860 .unwrap()
861 .as_path()
862 .join("src/test_data/0123456789");
863 let mut file = File::open(typedstream_path).unwrap();
864 let mut bytes = vec![];
865 file.read_to_end(&mut bytes).unwrap();
866
867 let mut typedstream = TypedStreamDeserializer::new(&bytes);
868 let root = typedstream.oxidize().unwrap();
869 println!("\nResults:");
870 println!("Root object: {:x?}", typedstream.object_table[root]);
871 print_resolved(typedstream.resolve_properties(root).unwrap(), 2);
872
873 println!("\nFound {:?} types:", typedstream.type_table.len());
874 typedstream
875 .type_table
876 .iter()
877 .enumerate()
878 .for_each(|(idx, item)| println!("\t{idx}: {item:?}"));
879
880 println!("\nFound {:?} objects:", typedstream.object_table.len());
881 typedstream
882 .object_table
883 .iter()
884 .enumerate()
885 .for_each(|(idx, item)| println!("\t{idx}: {item:?}"));
886
887 let expected_types = vec![
888 vec![Type::Object],
889 vec![Type::String("NSAttributedString")],
890 vec![Type::String("NSObject")],
891 vec![Type::String("NSString")],
892 vec![Type::Utf8String],
893 vec![Type::SignedInt, Type::UnsignedInt],
894 vec![Type::String("NSDictionary")],
895 vec![Type::SignedInt],
896 vec![Type::String("NSMutableData")],
897 vec![Type::String("NSData")],
898 vec![Type::Array(635)],
899 vec![Type::String("NSNumber")],
900 vec![Type::String("NSValue")],
901 vec![Type::EmbeddedData],
902 vec![Type::String("NSURL")],
903 vec![Type::SignedInt],
904 ];
905
906 let expected_objects = vec![
907 Archived::Object {
908 class: 1,
909 data: vec![
910 vec![OutputData::Object(3)],
911 vec![OutputData::SignedInteger(1), OutputData::UnsignedInteger(6)],
912 vec![OutputData::Object(5)],
913 vec![OutputData::SignedInteger(2), OutputData::UnsignedInteger(4)],
914 vec![OutputData::Object(22)],
915 ],
916 },
917 Archived::Class(Class {
918 name_index: 1,
919 version: 0,
920 parent_index: Some(2),
921 }),
922 Archived::Class(Class {
923 name_index: 2,
924 version: 0,
925 parent_index: None,
926 }),
927 Archived::Object {
928 class: 4,
929 data: vec![vec![OutputData::String("0123456789")]],
930 },
931 Archived::Class(Class {
932 name_index: 3,
933 version: 1,
934 parent_index: Some(2),
935 }),
936 Archived::Object {
937 class: 6,
938 data: vec![
939 vec![OutputData::SignedInteger(4)],
940 vec![OutputData::Object(7)],
941 vec![OutputData::Object(8)],
942 vec![OutputData::Object(11)],
943 vec![OutputData::Object(12)],
944 vec![OutputData::Object(16)],
945 vec![OutputData::Object(17)],
946 vec![OutputData::Object(20)],
947 vec![OutputData::Object(21)],
948 ],
949 },
950 Archived::Class(Class {
951 name_index: 6,
952 version: 0,
953 parent_index: Some(2),
954 }),
955 Archived::Object {
956 class: 4,
957 data: vec![vec![OutputData::String("__kIMPhoneNumberAttributeName")]],
958 },
959 Archived::Object {
960 class: 9,
961 data: vec![
962 vec![OutputData::SignedInteger(635)],
963 vec![OutputData::Array(&[
964 98, 112, 108, 105, 115, 116, 48, 48, 212, 1, 2, 3, 4, 5, 6, 7, 12, 88, 36,
965 118, 101, 114, 115, 105, 111, 110, 89, 36, 97, 114, 99, 104, 105, 118, 101,
966 114, 84, 36, 116, 111, 112, 88, 36, 111, 98, 106, 101, 99, 116, 115, 18, 0,
967 1, 134, 160, 95, 16, 15, 78, 83, 75, 101, 121, 101, 100, 65, 114, 99, 104,
968 105, 118, 101, 114, 210, 8, 9, 10, 11, 87, 118, 101, 114, 115, 105, 111,
969 110, 89, 100, 100, 45, 114, 101, 115, 117, 108, 116, 128, 15, 128, 1, 175,
970 16, 16, 13, 14, 28, 36, 37, 38, 44, 45, 46, 51, 57, 61, 62, 65, 68, 72, 85,
971 36, 110, 117, 108, 108, 215, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
972 26, 27, 26, 82, 77, 83, 86, 36, 99, 108, 97, 115, 115, 82, 65, 82, 81, 84,
973 81, 80, 82, 83, 82, 82, 86, 78, 128, 6, 128, 14, 128, 2, 128, 7, 16, 1,
974 128, 8, 212, 29, 30, 31, 16, 32, 33, 34, 35, 95, 16, 18, 78, 83, 46, 114,
975 97, 110, 103, 101, 118, 97, 108, 46, 108, 101, 110, 103, 116, 104, 95, 16,
976 20, 78, 83, 46, 114, 97, 110, 103, 101, 118, 97, 108, 46, 108, 111, 99, 97,
977 116, 105, 111, 110, 90, 78, 83, 46, 115, 112, 101, 99, 105, 97, 108, 128,
978 3, 128, 4, 16, 4, 128, 5, 16, 10, 16, 0, 210, 39, 40, 41, 42, 90, 36, 99,
979 108, 97, 115, 115, 110, 97, 109, 101, 88, 36, 99, 108, 97, 115, 115, 101,
980 115, 87, 78, 83, 86, 97, 108, 117, 101, 162, 41, 43, 88, 78, 83, 79, 98,
981 106, 101, 99, 116, 90, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 91, 80, 104,
982 111, 110, 101, 78, 117, 109, 98, 101, 114, 210, 47, 16, 48, 50, 90, 78, 83,
983 46, 111, 98, 106, 101, 99, 116, 115, 161, 49, 128, 9, 128, 13, 215, 15, 16,
984 17, 18, 19, 20, 21, 22, 23, 54, 55, 26, 56, 26, 128, 6, 128, 14, 128, 10,
985 128, 11, 128, 12, 212, 29, 30, 31, 16, 32, 33, 34, 35, 128, 3, 128, 4, 128,
986 5, 85, 86, 97, 108, 117, 101, 210, 47, 16, 63, 50, 160, 128, 13, 210, 39,
987 40, 66, 67, 87, 78, 83, 65, 114, 114, 97, 121, 162, 66, 43, 210, 39, 40,
988 69, 70, 95, 16, 15, 68, 68, 83, 99, 97, 110, 110, 101, 114, 82, 101, 115,
989 117, 108, 116, 162, 71, 43, 95, 16, 15, 68, 68, 83, 99, 97, 110, 110, 101,
990 114, 82, 101, 115, 117, 108, 116, 16, 1, 0, 8, 0, 17, 0, 26, 0, 36, 0, 41,
991 0, 50, 0, 55, 0, 73, 0, 78, 0, 86, 0, 96, 0, 98, 0, 100, 0, 119, 0, 125, 0,
992 140, 0, 143, 0, 150, 0, 153, 0, 155, 0, 157, 0, 160, 0, 163, 0, 165, 0,
993 167, 0, 169, 0, 171, 0, 173, 0, 175, 0, 184, 0, 205, 0, 228, 0, 239, 0,
994 241, 0, 243, 0, 245, 0, 247, 0, 249, 0, 251, 1, 0, 1, 11, 1, 20, 1, 28, 1,
995 31, 1, 40, 1, 51, 1, 63, 1, 68, 1, 79, 1, 81, 1, 83, 1, 85, 1, 100, 1, 102,
996 1, 104, 1, 106, 1, 108, 1, 110, 1, 119, 1, 121, 1, 123, 1, 125, 1, 131, 1,
997 136, 1, 137, 1, 139, 1, 144, 1, 152, 1, 155, 1, 160, 1, 178, 1, 181, 1,
998 199, 0, 0, 0, 0, 0, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 73, 0, 0, 0, 0, 0, 0, 0,
999 0, 0, 0, 0, 0, 0, 0, 1, 201,
1000 ])],
1001 ],
1002 },
1003 Archived::Class(Class {
1004 name_index: 8,
1005 version: 0,
1006 parent_index: Some(10),
1007 }),
1008 Archived::Class(Class {
1009 name_index: 9,
1010 version: 0,
1011 parent_index: Some(2),
1012 }),
1013 Archived::Object {
1014 class: 4,
1015 data: vec![vec![OutputData::String("__kIMMessagePartAttributeName")]],
1016 },
1017 Archived::Object {
1018 class: 13,
1019 data: vec![vec![OutputData::SignedInteger(0)]],
1020 },
1021 Archived::Class(Class {
1022 name_index: 11,
1023 version: 0,
1024 parent_index: Some(14),
1025 }),
1026 Archived::Class(Class {
1027 name_index: 12,
1028 version: 0,
1029 parent_index: Some(2),
1030 }),
1031 Archived::Type(7),
1032 Archived::Object {
1033 class: 4,
1034 data: vec![vec![OutputData::String("__kIMLinkAttributeName")]],
1035 },
1036 Archived::Object {
1037 class: 18,
1038 data: vec![
1039 vec![OutputData::SignedInteger(0)],
1040 vec![OutputData::Object(19)],
1041 ],
1042 },
1043 Archived::Class(Class {
1044 name_index: 14,
1045 version: 0,
1046 parent_index: Some(2),
1047 }),
1048 Archived::Object {
1049 class: 4,
1050 data: vec![vec![OutputData::String("tel:0123456789")]],
1051 },
1052 Archived::Object {
1053 class: 4,
1054 data: vec![vec![OutputData::String(
1055 "__kIMTextStrikethroughAttributeName",
1056 )]],
1057 },
1058 Archived::Object {
1059 class: 13,
1060 data: vec![vec![OutputData::SignedInteger(1)]],
1061 },
1062 Archived::Object {
1063 class: 6,
1064 data: vec![
1065 vec![OutputData::SignedInteger(4)],
1066 vec![OutputData::Object(7)],
1067 vec![OutputData::Object(8)],
1068 vec![OutputData::Object(11)],
1069 vec![OutputData::Object(12)],
1070 vec![OutputData::Object(16)],
1071 vec![OutputData::Object(17)],
1072 vec![OutputData::Object(23)],
1073 vec![OutputData::Object(21)],
1074 ],
1075 },
1076 Archived::Object {
1077 class: 4,
1078 data: vec![vec![OutputData::String("__kIMTextItalicAttributeName")]],
1079 },
1080 ];
1081
1082 assert_eq!(typedstream.type_table, expected_types);
1083 assert_eq!(typedstream.object_table, expected_objects);
1084 }
1085
1086 #[test]
1087 fn test_parse_text_apple_music_lyrics() {
1088 let typedstream_path = current_dir()
1089 .unwrap()
1090 .as_path()
1091 .join("src/test_data/AppleMusicLyrics");
1092 let mut file = File::open(typedstream_path).unwrap();
1093 let mut bytes = vec![];
1094 file.read_to_end(&mut bytes).unwrap();
1095
1096 let mut typedstream = TypedStreamDeserializer::new(&bytes);
1097 let root = typedstream.oxidize().unwrap();
1098 println!("\nResults:");
1099 println!("Root object: {:x?}", typedstream.object_table[root]);
1100 print_resolved(typedstream.resolve_properties(root).unwrap(), 2);
1101
1102 println!("\nFound {:?} types:", typedstream.type_table.len());
1103 typedstream
1104 .type_table
1105 .iter()
1106 .enumerate()
1107 .for_each(|(idx, item)| println!("\t{idx}: {item:?}"));
1108
1109 println!("\nFound {:?} objects:", typedstream.object_table.len());
1110 typedstream
1111 .object_table
1112 .iter()
1113 .enumerate()
1114 .for_each(|(idx, item)| println!("\t{idx}: {item:?}"));
1115
1116 let expected_types = vec![
1117 vec![Type::Object],
1118 vec![Type::String("NSMutableAttributedString")],
1119 vec![Type::String("NSAttributedString")],
1120 vec![Type::String("NSObject")],
1121 vec![Type::String("NSMutableString")],
1122 vec![Type::String("NSString")],
1123 vec![Type::Utf8String],
1124 vec![Type::SignedInt, Type::UnsignedInt],
1125 vec![Type::String("NSDictionary")],
1126 vec![Type::SignedInt],
1127 vec![Type::String("NSNumber")],
1128 vec![Type::String("NSValue")],
1129 vec![Type::EmbeddedData],
1130 vec![Type::SignedInt],
1131 vec![Type::SignedInt],
1132 vec![Type::String("NSURL")],
1133 vec![Type::String("NSData")],
1134 vec![Type::Array(675)],
1135 ];
1136
1137 let expected_objects = vec![
1138 Archived::Object {
1139 class: 1,
1140 data: vec![
1141 vec![OutputData::Object(4)],
1142 vec![
1143 OutputData::SignedInteger(1),
1144 OutputData::UnsignedInteger(145),
1145 ],
1146 vec![OutputData::Object(7)],
1147 ],
1148 },
1149 Archived::Class(Class {
1150 name_index: 1,
1151 version: 0,
1152 parent_index: Some(2),
1153 }),
1154 Archived::Class(Class {
1155 name_index: 2,
1156 version: 0,
1157 parent_index: Some(3),
1158 }),
1159 Archived::Class(Class {
1160 name_index: 3,
1161 version: 0,
1162 parent_index: None,
1163 }),
1164 Archived::Object {
1165 class: 5,
1166 data: vec![vec![OutputData::String(
1167 "https://music.apple.com/us/lyrics/1329891623?ts=11.108&te=16.031&l=en&tk=2.v1.VsuX9f%2BaT1PyrgMgIT7ANQ%3D%3D&itsct=sharing_msg_lyrics&itscg=50401",
1168 )]],
1169 },
1170 Archived::Class(Class {
1171 name_index: 4,
1172 version: 1,
1173 parent_index: Some(6),
1174 }),
1175 Archived::Class(Class {
1176 name_index: 5,
1177 version: 1,
1178 parent_index: Some(3),
1179 }),
1180 Archived::Object {
1181 class: 8,
1182 data: vec![
1183 vec![OutputData::SignedInteger(5)],
1184 vec![OutputData::Object(9)],
1185 vec![OutputData::Object(10)],
1186 vec![OutputData::Object(14)],
1187 vec![OutputData::Object(15)],
1188 vec![OutputData::Object(17)],
1189 vec![OutputData::Object(18)],
1190 vec![OutputData::Object(21)],
1191 vec![OutputData::Object(22)],
1192 vec![OutputData::Object(23)],
1193 vec![OutputData::Object(24)],
1194 ],
1195 },
1196 Archived::Class(Class {
1197 name_index: 8,
1198 version: 0,
1199 parent_index: Some(3),
1200 }),
1201 Archived::Object {
1202 class: 6,
1203 data: vec![vec![OutputData::String(
1204 "__kIMBaseWritingDirectionAttributeName",
1205 )]],
1206 },
1207 Archived::Object {
1208 class: 11,
1209 data: vec![vec![OutputData::SignedInteger(-1)]],
1210 },
1211 Archived::Class(Class {
1212 name_index: 10,
1213 version: 0,
1214 parent_index: Some(12),
1215 }),
1216 Archived::Class(Class {
1217 name_index: 11,
1218 version: 0,
1219 parent_index: Some(3),
1220 }),
1221 Archived::Type(13),
1222 Archived::Object {
1223 class: 6,
1224 data: vec![vec![OutputData::String("__kIMLinkIsRichLinkAttributeName")]],
1225 },
1226 Archived::Object {
1227 class: 11,
1228 data: vec![vec![OutputData::SignedInteger(1)]],
1229 },
1230 Archived::Type(14),
1231 Archived::Object {
1232 class: 6,
1233 data: vec![vec![OutputData::String("__kIMLinkAttributeName")]],
1234 },
1235 Archived::Object {
1236 class: 19,
1237 data: vec![
1238 vec![OutputData::SignedInteger(0)],
1239 vec![OutputData::Object(20)],
1240 ],
1241 },
1242 Archived::Class(Class {
1243 name_index: 15,
1244 version: 0,
1245 parent_index: Some(3),
1246 }),
1247 Archived::Object {
1248 class: 6,
1249 data: vec![vec![OutputData::String(
1250 "https://music.apple.com/us/lyrics/1329891623?ts=11.108&te=16.031&l=en&tk=2.v1.VsuX9f%2BaT1PyrgMgIT7ANQ%3D%3D&itsct=sharing_msg_lyrics&itscg=50401",
1251 )]],
1252 },
1253 Archived::Object {
1254 class: 6,
1255 data: vec![vec![OutputData::String("__kIMMessagePartAttributeName")]],
1256 },
1257 Archived::Object {
1258 class: 11,
1259 data: vec![vec![OutputData::SignedInteger(0)]],
1260 },
1261 Archived::Object {
1262 class: 6,
1263 data: vec![vec![OutputData::String("__kIMDataDetectedAttributeName")]],
1264 },
1265 Archived::Object {
1266 class: 25,
1267 data: vec![
1268 vec![OutputData::SignedInteger(675)],
1269 vec![OutputData::Array(&[
1270 98, 112, 108, 105, 115, 116, 48, 48, 212, 1, 2, 3, 4, 5, 6, 7, 12, 88, 36,
1271 118, 101, 114, 115, 105, 111, 110, 89, 36, 97, 114, 99, 104, 105, 118, 101,
1272 114, 84, 36, 116, 111, 112, 88, 36, 111, 98, 106, 101, 99, 116, 115, 18, 0,
1273 1, 134, 160, 95, 16, 15, 78, 83, 75, 101, 121, 101, 100, 65, 114, 99, 104,
1274 105, 118, 101, 114, 210, 8, 9, 10, 11, 87, 118, 101, 114, 115, 105, 111,
1275 110, 89, 100, 100, 45, 114, 101, 115, 117, 108, 116, 128, 11, 128, 1, 172,
1276 13, 14, 28, 36, 37, 38, 44, 45, 46, 50, 53, 57, 85, 36, 110, 117, 108, 108,
1277 215, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 26, 82, 77, 83,
1278 86, 36, 99, 108, 97, 115, 115, 82, 65, 82, 81, 84, 81, 80, 82, 83, 82, 82,
1279 86, 78, 128, 6, 128, 10, 128, 2, 128, 7, 16, 1, 128, 8, 212, 29, 30, 31,
1280 16, 32, 33, 34, 35, 95, 16, 18, 78, 83, 46, 114, 97, 110, 103, 101, 118,
1281 97, 108, 46, 108, 101, 110, 103, 116, 104, 95, 16, 20, 78, 83, 46, 114, 97,
1282 110, 103, 101, 118, 97, 108, 46, 108, 111, 99, 97, 116, 105, 111, 110, 90,
1283 78, 83, 46, 115, 112, 101, 99, 105, 97, 108, 128, 3, 128, 4, 16, 4, 128, 5,
1284 16, 145, 16, 0, 210, 39, 40, 41, 42, 90, 36, 99, 108, 97, 115, 115, 110,
1285 97, 109, 101, 88, 36, 99, 108, 97, 115, 115, 101, 115, 87, 78, 83, 86, 97,
1286 108, 117, 101, 162, 41, 43, 88, 78, 83, 79, 98, 106, 101, 99, 116, 95, 16,
1287 145, 104, 116, 116, 112, 115, 58, 47, 47, 109, 117, 115, 105, 99, 46, 97,
1288 112, 112, 108, 101, 46, 99, 111, 109, 47, 117, 115, 47, 108, 121, 114, 105,
1289 99, 115, 47, 49, 51, 50, 57, 56, 57, 49, 54, 50, 51, 63, 116, 115, 61, 49,
1290 49, 46, 49, 48, 56, 38, 116, 101, 61, 49, 54, 46, 48, 51, 49, 38, 108, 61,
1291 101, 110, 38, 116, 107, 61, 50, 46, 118, 49, 46, 86, 115, 117, 88, 57, 102,
1292 37, 50, 66, 97, 84, 49, 80, 121, 114, 103, 77, 103, 73, 84, 55, 65, 78, 81,
1293 37, 51, 68, 37, 51, 68, 38, 105, 116, 115, 99, 116, 61, 115, 104, 97, 114,
1294 105, 110, 103, 95, 109, 115, 103, 95, 108, 121, 114, 105, 99, 115, 38, 105,
1295 116, 115, 99, 103, 61, 53, 48, 52, 48, 49, 87, 72, 116, 116, 112, 85, 82,
1296 76, 210, 47, 16, 48, 49, 90, 78, 83, 46, 111, 98, 106, 101, 99, 116, 115,
1297 160, 128, 9, 210, 39, 40, 51, 52, 87, 78, 83, 65, 114, 114, 97, 121, 162,
1298 51, 43, 210, 39, 40, 54, 55, 95, 16, 15, 68, 68, 83, 99, 97, 110, 110, 101,
1299 114, 82, 101, 115, 117, 108, 116, 162, 56, 43, 95, 16, 15, 68, 68, 83, 99,
1300 97, 110, 110, 101, 114, 82, 101, 115, 117, 108, 116, 16, 1, 0, 8, 0, 17, 0,
1301 26, 0, 36, 0, 41, 0, 50, 0, 55, 0, 73, 0, 78, 0, 86, 0, 96, 0, 98, 0, 100,
1302 0, 113, 0, 119, 0, 134, 0, 137, 0, 144, 0, 147, 0, 149, 0, 151, 0, 154, 0,
1303 157, 0, 159, 0, 161, 0, 163, 0, 165, 0, 167, 0, 169, 0, 178, 0, 199, 0,
1304 222, 0, 233, 0, 235, 0, 237, 0, 239, 0, 241, 0, 243, 0, 245, 0, 250, 1, 5,
1305 1, 14, 1, 22, 1, 25, 1, 34, 1, 182, 1, 190, 1, 195, 1, 206, 1, 207, 1, 209,
1306 1, 214, 1, 222, 1, 225, 1, 230, 1, 248, 1, 251, 2, 13, 0, 0, 0, 0, 0, 0, 2,
1307 1, 0, 0, 0, 0, 0, 0, 0, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2,
1308 15,
1309 ])],
1310 ],
1311 },
1312 Archived::Class(Class {
1313 name_index: 16,
1314 version: 0,
1315 parent_index: Some(3),
1316 }),
1317 ];
1318
1319 assert_eq!(typedstream.type_table, expected_types);
1320 assert_eq!(typedstream.object_table, expected_objects);
1321 }
1322
1323 #[test]
1324 fn test_parse_text_app_message() {
1325 let typedstream_path = current_dir()
1326 .unwrap()
1327 .as_path()
1328 .join("src/test_data/AppMessage");
1329 let mut file = File::open(typedstream_path).unwrap();
1330 let mut bytes = vec![];
1331 file.read_to_end(&mut bytes).unwrap();
1332
1333 let mut typedstream = TypedStreamDeserializer::new(&bytes);
1334 let root = typedstream.oxidize().unwrap();
1335 println!("\nResults:");
1336 println!("Root object: {:x?}", typedstream.object_table[root]);
1337 print_resolved(typedstream.resolve_properties(root).unwrap(), 2);
1338
1339 println!("\nFound {:?} types:", typedstream.type_table.len());
1340 typedstream
1341 .type_table
1342 .iter()
1343 .enumerate()
1344 .for_each(|(idx, item)| println!("\t{idx}: {item:?}"));
1345
1346 println!("\nFound {:?} objects:", typedstream.object_table.len());
1347 typedstream
1348 .object_table
1349 .iter()
1350 .enumerate()
1351 .for_each(|(idx, item)| println!("\t{idx}: {item:?}"));
1352
1353 let expected_types = vec![
1354 vec![Type::Object],
1355 vec![Type::String("NSAttributedString")],
1356 vec![Type::String("NSObject")],
1357 vec![Type::String("NSString")],
1358 vec![Type::Utf8String],
1359 vec![Type::SignedInt, Type::UnsignedInt],
1360 vec![Type::String("NSDictionary")],
1361 vec![Type::SignedInt],
1362 vec![Type::String("NSNumber")],
1363 vec![Type::String("NSValue")],
1364 vec![Type::EmbeddedData],
1365 vec![Type::SignedInt],
1366 ];
1367
1368 let expected_objects = vec![
1369 Archived::Object {
1370 class: 1,
1371 data: vec![
1372 vec![OutputData::Object(3)],
1373 vec![OutputData::SignedInteger(1), OutputData::UnsignedInteger(1)],
1374 vec![OutputData::Object(5)],
1375 ],
1376 },
1377 Archived::Class(Class {
1378 name_index: 1,
1379 version: 0,
1380 parent_index: Some(2),
1381 }),
1382 Archived::Class(Class {
1383 name_index: 2,
1384 version: 0,
1385 parent_index: None,
1386 }),
1387 Archived::Object {
1388 class: 4,
1389 data: vec![vec![OutputData::String("")]], },
1391 Archived::Class(Class {
1392 name_index: 3,
1393 version: 1,
1394 parent_index: Some(2),
1395 }),
1396 Archived::Object {
1397 class: 6,
1398 data: vec![
1399 vec![OutputData::SignedInteger(3)],
1400 vec![OutputData::Object(7)],
1401 vec![OutputData::Object(8)],
1402 vec![OutputData::Object(9)],
1403 vec![OutputData::Object(10)],
1404 vec![OutputData::Object(14)],
1405 vec![OutputData::Object(15)],
1406 ],
1407 },
1408 Archived::Class(Class {
1409 name_index: 6,
1410 version: 0,
1411 parent_index: Some(2),
1412 }),
1413 Archived::Object {
1414 class: 4,
1415 data: vec![vec![OutputData::String(
1416 "__kIMFileTransferGUIDAttributeName",
1417 )]],
1418 },
1419 Archived::Object {
1420 class: 4,
1421 data: vec![vec![OutputData::String(
1422 "F0B18A15-E9A5-4B18-A38F-685B7B3FF037",
1423 )]],
1424 },
1425 Archived::Object {
1426 class: 4,
1427 data: vec![vec![OutputData::String(
1428 "__kIMBaseWritingDirectionAttributeName",
1429 )]],
1430 },
1431 Archived::Object {
1432 class: 11,
1433 data: vec![vec![OutputData::SignedInteger(-1)]],
1434 },
1435 Archived::Class(Class {
1436 name_index: 8,
1437 version: 0,
1438 parent_index: Some(12),
1439 }),
1440 Archived::Class(Class {
1441 name_index: 9,
1442 version: 0,
1443 parent_index: Some(2),
1444 }),
1445 Archived::Type(11),
1446 Archived::Object {
1447 class: 4,
1448 data: vec![vec![OutputData::String("__kIMMessagePartAttributeName")]],
1449 },
1450 Archived::Object {
1451 class: 11,
1452 data: vec![vec![OutputData::SignedInteger(0)]],
1453 },
1454 ];
1455
1456 assert_eq!(typedstream.type_table, expected_types);
1457 assert_eq!(typedstream.object_table, expected_objects);
1458 }
1459
1460 #[test]
1461 fn test_parse_text_array() {
1462 let typedstream_path = current_dir().unwrap().as_path().join("src/test_data/Array");
1463 let mut file = File::open(typedstream_path).unwrap();
1464 let mut bytes = vec![];
1465 file.read_to_end(&mut bytes).unwrap();
1466
1467 let mut typedstream = TypedStreamDeserializer::new(&bytes);
1468 let root = typedstream.oxidize().unwrap();
1469 println!("\nResults:");
1470 println!("Root object: {:x?}", typedstream.object_table[root]);
1471 print_resolved(typedstream.resolve_properties(root).unwrap(), 2);
1472
1473 println!("\nFound {:?} types:", typedstream.type_table.len());
1474 typedstream
1475 .type_table
1476 .iter()
1477 .enumerate()
1478 .for_each(|(idx, item)| println!("\t{idx}: {item:?}"));
1479
1480 println!("\nFound {:?} objects:", typedstream.object_table.len());
1481 typedstream
1482 .object_table
1483 .iter()
1484 .enumerate()
1485 .for_each(|(idx, item)| println!("\t{idx}: {item:?}"));
1486
1487 let expected_types = vec![
1488 vec![Type::Object],
1489 vec![Type::String("NSMutableAttributedString")],
1490 vec![Type::String("NSAttributedString")],
1491 vec![Type::String("NSObject")],
1492 vec![Type::String("NSMutableString")],
1493 vec![Type::String("NSString")],
1494 vec![Type::Utf8String],
1495 vec![Type::SignedInt, Type::UnsignedInt],
1496 vec![Type::String("NSDictionary")],
1497 vec![Type::SignedInt],
1498 vec![Type::String("NSNumber")],
1499 vec![Type::String("NSValue")],
1500 vec![Type::EmbeddedData],
1501 vec![Type::String("NSData")],
1502 vec![Type::Array(904)],
1503 ];
1504
1505 let expected_objects = vec![
1506 Archived::Object {
1507 class: 1,
1508 data: vec![
1509 vec![OutputData::Object(4)],
1510 vec![
1511 OutputData::SignedInteger(1),
1512 OutputData::UnsignedInteger(32),
1513 ],
1514 vec![OutputData::Object(7)],
1515 vec![OutputData::SignedInteger(2), OutputData::UnsignedInteger(3)],
1516 vec![OutputData::Object(14)],
1517 vec![
1518 OutputData::SignedInteger(1),
1519 OutputData::UnsignedInteger(16),
1520 ],
1521 ],
1522 },
1523 Archived::Class(Class {
1524 name_index: 1,
1525 version: 0,
1526 parent_index: Some(2),
1527 }),
1528 Archived::Class(Class {
1529 name_index: 2,
1530 version: 0,
1531 parent_index: Some(3),
1532 }),
1533 Archived::Class(Class {
1534 name_index: 3,
1535 version: 0,
1536 parent_index: None,
1537 }),
1538 Archived::Object {
1539 class: 5,
1540 data: vec![vec![OutputData::String(
1541 "A single ChatGPT instance takes 5MW of power to run",
1542 )]],
1543 },
1544 Archived::Class(Class {
1545 name_index: 4,
1546 version: 1,
1547 parent_index: Some(6),
1548 }),
1549 Archived::Class(Class {
1550 name_index: 5,
1551 version: 1,
1552 parent_index: Some(3),
1553 }),
1554 Archived::Object {
1555 class: 8,
1556 data: vec![
1557 vec![OutputData::SignedInteger(1)],
1558 vec![OutputData::Object(9)],
1559 vec![OutputData::Object(10)],
1560 ],
1561 },
1562 Archived::Class(Class {
1563 name_index: 8,
1564 version: 0,
1565 parent_index: Some(3),
1566 }),
1567 Archived::Object {
1568 class: 6,
1569 data: vec![vec![OutputData::String("__kIMMessagePartAttributeName")]],
1570 },
1571 Archived::Object {
1572 class: 11,
1573 data: vec![vec![OutputData::SignedInteger(0)]],
1574 },
1575 Archived::Class(Class {
1576 name_index: 10,
1577 version: 0,
1578 parent_index: Some(12),
1579 }),
1580 Archived::Class(Class {
1581 name_index: 11,
1582 version: 0,
1583 parent_index: Some(3),
1584 }),
1585 Archived::Type(9),
1586 Archived::Object {
1587 class: 8,
1588 data: vec![
1589 vec![OutputData::SignedInteger(2)],
1590 vec![OutputData::Object(15)],
1591 vec![OutputData::Object(16)],
1592 vec![OutputData::Object(9)],
1593 vec![OutputData::Object(10)],
1594 ],
1595 },
1596 Archived::Object {
1597 class: 6,
1598 data: vec![vec![OutputData::String("__kIMDataDetectedAttributeName")]],
1599 },
1600 Archived::Object {
1601 class: 17,
1602 data: vec![
1603 vec![OutputData::SignedInteger(904)],
1604 vec![OutputData::Array(&[
1605 98, 112, 108, 105, 115, 116, 48, 48, 212, 1, 2, 3, 4, 5, 6, 7, 12, 88, 36,
1606 118, 101, 114, 115, 105, 111, 110, 89, 36, 97, 114, 99, 104, 105, 118, 101,
1607 114, 84, 36, 116, 111, 112, 88, 36, 111, 98, 106, 101, 99, 116, 115, 18, 0,
1608 1, 134, 160, 95, 16, 15, 78, 83, 75, 101, 121, 101, 100, 65, 114, 99, 104,
1609 105, 118, 101, 114, 210, 8, 9, 10, 11, 87, 118, 101, 114, 115, 105, 111,
1610 110, 89, 100, 100, 45, 114, 101, 115, 117, 108, 116, 128, 31, 128, 1, 175,
1611 16, 32, 13, 14, 28, 36, 37, 38, 44, 45, 46, 53, 59, 26, 63, 64, 65, 68, 72,
1612 76, 84, 88, 89, 90, 91, 94, 95, 102, 106, 107, 108, 109, 112, 113, 85, 36,
1613 110, 117, 108, 108, 215, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
1614 27, 26, 82, 77, 83, 86, 36, 99, 108, 97, 115, 115, 82, 65, 82, 81, 84, 81,
1615 80, 82, 83, 82, 82, 86, 78, 128, 6, 128, 16, 128, 2, 128, 7, 16, 1, 128, 8,
1616 212, 29, 30, 31, 16, 32, 33, 34, 35, 95, 16, 18, 78, 83, 46, 114, 97, 110,
1617 103, 101, 118, 97, 108, 46, 108, 101, 110, 103, 116, 104, 95, 16, 20, 78,
1618 83, 46, 114, 97, 110, 103, 101, 118, 97, 108, 46, 108, 111, 99, 97, 116,
1619 105, 111, 110, 90, 78, 83, 46, 115, 112, 101, 99, 105, 97, 108, 128, 3,
1620 128, 4, 16, 4, 128, 5, 16, 3, 16, 32, 210, 39, 40, 41, 42, 90, 36, 99, 108,
1621 97, 115, 115, 110, 97, 109, 101, 88, 36, 99, 108, 97, 115, 115, 101, 115,
1622 87, 78, 83, 86, 97, 108, 117, 101, 162, 41, 43, 88, 78, 83, 79, 98, 106,
1623 101, 99, 116, 83, 53, 77, 87, 94, 80, 104, 121, 115, 105, 99, 97, 108, 65,
1624 109, 111, 117, 110, 116, 210, 47, 16, 48, 52, 90, 78, 83, 46, 111, 98, 106,
1625 101, 99, 116, 115, 163, 49, 50, 51, 128, 9, 128, 17, 128, 24, 128, 15, 215,
1626 15, 16, 17, 18, 19, 20, 21, 54, 23, 56, 57, 26, 58, 26, 128, 12, 128, 16,
1627 128, 10, 128, 13, 128, 14, 212, 29, 30, 31, 16, 60, 33, 34, 35, 128, 11,
1628 128, 4, 128, 5, 81, 53, 93, 73, 110, 116, 101, 103, 114, 97, 108, 86, 97,
1629 108, 117, 101, 210, 47, 16, 66, 52, 160, 128, 15, 210, 39, 40, 69, 70, 94,
1630 78, 83, 77, 117, 116, 97, 98, 108, 101, 65, 114, 114, 97, 121, 163, 69, 71,
1631 43, 87, 78, 83, 65, 114, 114, 97, 121, 210, 39, 40, 73, 74, 95, 16, 15, 68,
1632 68, 83, 99, 97, 110, 110, 101, 114, 82, 101, 115, 117, 108, 116, 162, 75,
1633 43, 95, 16, 15, 68, 68, 83, 99, 97, 110, 110, 101, 114, 82, 101, 115, 117,
1634 108, 116, 216, 15, 16, 77, 17, 18, 19, 20, 21, 78, 23, 80, 81, 82, 26, 83,
1635 26, 81, 86, 128, 20, 128, 16, 128, 23, 128, 18, 128, 21, 128, 22, 212, 29,
1636 30, 31, 16, 60, 86, 34, 35, 128, 11, 128, 19, 128, 5, 16, 33, 81, 77, 90,
1637 77, 117, 108, 116, 105, 112, 108, 105, 101, 114, 210, 47, 16, 92, 52, 160,
1638 128, 15, 87, 49, 48, 48, 48, 48, 48, 48, 216, 15, 16, 77, 17, 18, 19, 20,
1639 21, 96, 23, 98, 99, 100, 26, 101, 26, 128, 27, 128, 16, 128, 30, 128, 25,
1640 128, 28, 128, 29, 212, 29, 30, 31, 16, 60, 104, 34, 35, 128, 11, 128, 26,
1641 128, 5, 16, 34, 81, 87, 84, 85, 110, 105, 116, 210, 47, 16, 110, 52, 160,
1642 128, 15, 84, 119, 97, 116, 116, 16, 1, 0, 8, 0, 17, 0, 26, 0, 36, 0, 41, 0,
1643 50, 0, 55, 0, 73, 0, 78, 0, 86, 0, 96, 0, 98, 0, 100, 0, 135, 0, 141, 0,
1644 156, 0, 159, 0, 166, 0, 169, 0, 171, 0, 173, 0, 176, 0, 179, 0, 181, 0,
1645 183, 0, 185, 0, 187, 0, 189, 0, 191, 0, 200, 0, 221, 0, 244, 0, 255, 1, 1,
1646 1, 3, 1, 5, 1, 7, 1, 9, 1, 11, 1, 16, 1, 27, 1, 36, 1, 44, 1, 47, 1, 56, 1,
1647 60, 1, 75, 1, 80, 1, 91, 1, 95, 1, 97, 1, 99, 1, 101, 1, 103, 1, 118, 1,
1648 120, 1, 122, 1, 124, 1, 126, 1, 128, 1, 137, 1, 139, 1, 141, 1, 143, 1,
1649 145, 1, 159, 1, 164, 1, 165, 1, 167, 1, 172, 1, 187, 1, 191, 1, 199, 1,
1650 204, 1, 222, 1, 225, 1, 243, 2, 4, 2, 6, 2, 8, 2, 10, 2, 12, 2, 14, 2, 16,
1651 2, 18, 2, 27, 2, 29, 2, 31, 2, 33, 2, 35, 2, 37, 2, 48, 2, 53, 2, 54, 2,
1652 56, 2, 64, 2, 81, 2, 83, 2, 85, 2, 87, 2, 89, 2, 91, 2, 93, 2, 102, 2, 104,
1653 2, 106, 2, 108, 2, 110, 2, 112, 2, 117, 2, 122, 2, 123, 2, 125, 2, 130, 0,
1654 0, 0, 0, 0, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1655 0, 0, 0, 0, 0, 2, 132,
1656 ])],
1657 ],
1658 },
1659 Archived::Class(Class {
1660 name_index: 13,
1661 version: 0,
1662 parent_index: Some(3),
1663 }),
1664 ];
1665
1666 assert_eq!(typedstream.type_table, expected_types);
1667 assert_eq!(typedstream.object_table, expected_objects);
1668 }
1669
1670 #[test]
1671 fn test_parse_text_attachment() {
1672 let typedstream_path = current_dir()
1673 .unwrap()
1674 .as_path()
1675 .join("src/test_data/Attachment");
1676 let mut file = File::open(typedstream_path).unwrap();
1677 let mut bytes = vec![];
1678 file.read_to_end(&mut bytes).unwrap();
1679
1680 let mut typedstream = TypedStreamDeserializer::new(&bytes);
1681 let root = typedstream.oxidize().unwrap();
1682 println!("\nResults:");
1683 println!("Root object: {:x?}", typedstream.object_table[root]);
1684 print_resolved(typedstream.resolve_properties(root).unwrap(), 2);
1685
1686 println!("\nFound {:?} types:", typedstream.type_table.len());
1687 typedstream
1688 .type_table
1689 .iter()
1690 .enumerate()
1691 .for_each(|(idx, item)| println!("\t{idx}: {item:?}"));
1692
1693 println!("\nFound {:?} objects:", typedstream.object_table.len());
1694 typedstream
1695 .object_table
1696 .iter()
1697 .enumerate()
1698 .for_each(|(idx, item)| println!("\t{idx}: {item:?}"));
1699
1700 let expected_types = vec![
1701 vec![Type::Object],
1702 vec![Type::String("NSMutableAttributedString")],
1703 vec![Type::String("NSAttributedString")],
1704 vec![Type::String("NSObject")],
1705 vec![Type::String("NSMutableString")],
1706 vec![Type::String("NSString")],
1707 vec![Type::Utf8String],
1708 vec![Type::SignedInt, Type::UnsignedInt],
1709 vec![Type::String("NSDictionary")],
1710 vec![Type::SignedInt],
1711 vec![Type::String("NSNumber")],
1712 vec![Type::String("NSValue")],
1713 vec![Type::EmbeddedData],
1714 vec![Type::Double],
1715 vec![Type::SignedInt],
1716 ];
1717
1718 let expected_objects = vec![
1719 Archived::Object {
1720 class: 1,
1721 data: vec![
1722 vec![OutputData::Object(4)],
1723 vec![OutputData::SignedInteger(1), OutputData::UnsignedInteger(1)],
1724 vec![OutputData::Object(7)],
1725 vec![
1726 OutputData::SignedInteger(2),
1727 OutputData::UnsignedInteger(77),
1728 ],
1729 vec![OutputData::Object(26)],
1730 ],
1731 },
1732 Archived::Class(Class {
1733 name_index: 1,
1734 version: 0,
1735 parent_index: Some(2),
1736 }),
1737 Archived::Class(Class {
1738 name_index: 2,
1739 version: 0,
1740 parent_index: Some(3),
1741 }),
1742 Archived::Class(Class {
1743 name_index: 3,
1744 version: 0,
1745 parent_index: None,
1746 }),
1747 Archived::Object {
1748 class: 5,
1749 data: vec![vec![OutputData::String(
1750 "This is how the notes look to me fyi, in case it helps make sense of anything",
1751 )]],
1752 },
1753 Archived::Class(Class {
1754 name_index: 4,
1755 version: 1,
1756 parent_index: Some(6),
1757 }),
1758 Archived::Class(Class {
1759 name_index: 5,
1760 version: 1,
1761 parent_index: Some(3),
1762 }),
1763 Archived::Object {
1764 class: 8,
1765 data: vec![
1766 vec![OutputData::SignedInteger(6)],
1767 vec![OutputData::Object(9)],
1768 vec![OutputData::Object(10)],
1769 vec![OutputData::Object(11)],
1770 vec![OutputData::Object(12)],
1771 vec![OutputData::Object(16)],
1772 vec![OutputData::Object(17)],
1773 vec![OutputData::Object(19)],
1774 vec![OutputData::Object(20)],
1775 vec![OutputData::Object(22)],
1776 vec![OutputData::Object(23)],
1777 vec![OutputData::Object(24)],
1778 vec![OutputData::Object(25)],
1779 ],
1780 },
1781 Archived::Class(Class {
1782 name_index: 8,
1783 version: 0,
1784 parent_index: Some(3),
1785 }),
1786 Archived::Object {
1787 class: 6,
1788 data: vec![vec![OutputData::String(
1789 "__kIMFileTransferGUIDAttributeName",
1790 )]],
1791 },
1792 Archived::Object {
1793 class: 6,
1794 data: vec![vec![OutputData::String(
1795 "at_0_2E5F12C3-E649-48AA-954D-3EA67C016BCC",
1796 )]],
1797 },
1798 Archived::Object {
1799 class: 6,
1800 data: vec![vec![OutputData::String(
1801 "__kIMInlineMediaHeightAttributeName",
1802 )]],
1803 },
1804 Archived::Object {
1805 class: 13,
1806 data: vec![vec![OutputData::Double(1139.0)]],
1807 },
1808 Archived::Class(Class {
1809 name_index: 10,
1810 version: 0,
1811 parent_index: Some(14),
1812 }),
1813 Archived::Class(Class {
1814 name_index: 11,
1815 version: 0,
1816 parent_index: Some(3),
1817 }),
1818 Archived::Type(13),
1819 Archived::Object {
1820 class: 6,
1821 data: vec![vec![OutputData::String(
1822 "__kIMBaseWritingDirectionAttributeName",
1823 )]],
1824 },
1825 Archived::Object {
1826 class: 13,
1827 data: vec![vec![OutputData::SignedInteger(-1)]],
1828 },
1829 Archived::Type(14),
1830 Archived::Object {
1831 class: 6,
1832 data: vec![vec![OutputData::String("__kIMMessagePartAttributeName")]],
1833 },
1834 Archived::Object {
1835 class: 13,
1836 data: vec![vec![OutputData::SignedInteger(0)]],
1837 },
1838 Archived::Type(9),
1839 Archived::Object {
1840 class: 6,
1841 data: vec![vec![OutputData::String("__kIMFilenameAttributeName")]],
1842 },
1843 Archived::Object {
1844 class: 6,
1845 data: vec![vec![OutputData::String("Messages Image(785748029).png")]],
1846 },
1847 Archived::Object {
1848 class: 6,
1849 data: vec![vec![OutputData::String(
1850 "__kIMInlineMediaWidthAttributeName",
1851 )]],
1852 },
1853 Archived::Object {
1854 class: 13,
1855 data: vec![vec![OutputData::Double(952.0)]],
1856 },
1857 Archived::Object {
1858 class: 8,
1859 data: vec![
1860 vec![OutputData::SignedInteger(2)],
1861 vec![OutputData::Object(27)],
1862 vec![OutputData::Object(17)],
1863 vec![OutputData::Object(28)],
1864 vec![OutputData::Object(29)],
1865 ],
1866 },
1867 Archived::Object {
1868 class: 6,
1869 data: vec![vec![OutputData::String(
1870 "__kIMBaseWritingDirectionAttributeName",
1871 )]],
1872 },
1873 Archived::Object {
1874 class: 6,
1875 data: vec![vec![OutputData::String("__kIMMessagePartAttributeName")]],
1876 },
1877 Archived::Object {
1878 class: 13,
1879 data: vec![vec![OutputData::SignedInteger(1)]],
1880 },
1881 ];
1882
1883 assert_eq!(typedstream.type_table, expected_types);
1884 assert_eq!(typedstream.object_table, expected_objects);
1885 }
1886
1887 #[test]
1888 fn test_parse_text_attachment_i16() {
1889 let typedstream_path = current_dir()
1890 .unwrap()
1891 .as_path()
1892 .join("src/test_data/AttachmentI16");
1893 let mut file = File::open(typedstream_path).unwrap();
1894 let mut bytes = vec![];
1895 file.read_to_end(&mut bytes).unwrap();
1896
1897 let mut typedstream = TypedStreamDeserializer::new(&bytes);
1898 let root = typedstream.oxidize().unwrap();
1899 println!("\nResults:");
1900 println!("Root object: {:x?}", typedstream.object_table[root]);
1901 print_resolved(typedstream.resolve_properties(root).unwrap(), 2);
1902
1903 println!("\nFound {:?} types:", typedstream.type_table.len());
1904 typedstream
1905 .type_table
1906 .iter()
1907 .enumerate()
1908 .for_each(|(idx, item)| println!("\t{idx}: {item:?}"));
1909
1910 println!("\nFound {:?} objects:", typedstream.object_table.len());
1911 typedstream
1912 .object_table
1913 .iter()
1914 .enumerate()
1915 .for_each(|(idx, item)| println!("\t{idx}: {item:?}"));
1916
1917 let expected_types = vec![
1918 vec![Type::Object],
1919 vec![Type::String("NSMutableAttributedString")],
1920 vec![Type::String("NSAttributedString")],
1921 vec![Type::String("NSObject")],
1922 vec![Type::String("NSMutableString")],
1923 vec![Type::String("NSString")],
1924 vec![Type::Utf8String],
1925 vec![Type::SignedInt, Type::UnsignedInt],
1926 vec![Type::String("NSDictionary")],
1927 vec![Type::SignedInt],
1928 vec![Type::String("NSNumber")],
1929 vec![Type::String("NSValue")],
1930 vec![Type::EmbeddedData],
1931 vec![Type::SignedInt],
1932 ];
1933
1934 let expected_objects = vec![
1935 Archived::Object {
1936 class: 1,
1937 data: vec![
1938 vec![OutputData::Object(4)],
1939 vec![OutputData::SignedInteger(1), OutputData::UnsignedInteger(1)],
1940 vec![OutputData::Object(7)],
1941 ],
1942 },
1943 Archived::Class(Class {
1944 name_index: 1,
1945 version: 0,
1946 parent_index: Some(2),
1947 }),
1948 Archived::Class(Class {
1949 name_index: 2,
1950 version: 0,
1951 parent_index: Some(3),
1952 }),
1953 Archived::Class(Class {
1954 name_index: 3,
1955 version: 0,
1956 parent_index: None,
1957 }),
1958 Archived::Object {
1959 class: 5,
1960 data: vec![vec![OutputData::String("")]],
1961 },
1962 Archived::Class(Class {
1963 name_index: 4,
1964 version: 1,
1965 parent_index: Some(6),
1966 }),
1967 Archived::Class(Class {
1968 name_index: 5,
1969 version: 1,
1970 parent_index: Some(3),
1971 }),
1972 Archived::Object {
1973 class: 8,
1974 data: vec![
1975 vec![OutputData::SignedInteger(6)],
1976 vec![OutputData::Object(9)],
1977 vec![OutputData::Object(10)],
1978 vec![OutputData::Object(11)],
1979 vec![OutputData::Object(12)],
1980 vec![OutputData::Object(16)],
1981 vec![OutputData::Object(17)],
1982 vec![OutputData::Object(18)],
1983 vec![OutputData::Object(19)],
1984 vec![OutputData::Object(20)],
1985 vec![OutputData::Object(21)],
1986 vec![OutputData::Object(22)],
1987 vec![OutputData::Object(23)],
1988 ],
1989 },
1990 Archived::Class(Class {
1991 name_index: 8,
1992 version: 0,
1993 parent_index: Some(3),
1994 }),
1995 Archived::Object {
1996 class: 6,
1997 data: vec![vec![OutputData::String(
1998 "__kIMFileTransferGUIDAttributeName",
1999 )]],
2000 },
2001 Archived::Object {
2002 class: 6,
2003 data: vec![vec![OutputData::String(
2004 "at_0_BE588799-C4BC-47DF-A56D-7EE90C74911D",
2005 )]],
2006 },
2007 Archived::Object {
2008 class: 6,
2009 data: vec![vec![OutputData::String(
2010 "__kIMInlineMediaHeightAttributeName",
2011 )]],
2012 },
2013 Archived::Object {
2014 class: 13,
2015 data: vec![vec![OutputData::SignedInteger(600)]],
2016 },
2017 Archived::Class(Class {
2018 name_index: 10,
2019 version: 0,
2020 parent_index: Some(14),
2021 }),
2022 Archived::Class(Class {
2023 name_index: 11,
2024 version: 0,
2025 parent_index: Some(3),
2026 }),
2027 Archived::Type(13),
2028 Archived::Object {
2029 class: 6,
2030 data: vec![vec![OutputData::String(
2031 "__kIMBaseWritingDirectionAttributeName",
2032 )]],
2033 },
2034 Archived::Object {
2035 class: 13,
2036 data: vec![vec![OutputData::SignedInteger(-1)]],
2037 },
2038 Archived::Object {
2039 class: 6,
2040 data: vec![vec![OutputData::String("__kIMMessagePartAttributeName")]],
2041 },
2042 Archived::Object {
2043 class: 13,
2044 data: vec![vec![OutputData::SignedInteger(1)]],
2045 },
2046 Archived::Object {
2047 class: 6,
2048 data: vec![vec![OutputData::String("__kIMFilenameAttributeName")]],
2049 },
2050 Archived::Object {
2051 class: 6,
2052 data: vec![vec![OutputData::String(
2053 "brilliant-kids-test-answers-32-93042.jpeg",
2054 )]],
2055 },
2056 Archived::Object {
2057 class: 6,
2058 data: vec![vec![OutputData::String(
2059 "__kIMInlineMediaWidthAttributeName",
2060 )]],
2061 },
2062 Archived::Object {
2063 class: 13,
2064 data: vec![vec![OutputData::SignedInteger(660)]],
2065 },
2066 ];
2067
2068 assert_eq!(typedstream.type_table, expected_types);
2069 assert_eq!(typedstream.object_table, expected_objects);
2070 }
2071
2072 #[test]
2073 fn test_parse_text_blank() {
2074 let typedstream_path = current_dir().unwrap().as_path().join("src/test_data/Blank");
2075 let mut file = File::open(typedstream_path).unwrap();
2076 let mut bytes = vec![];
2077 file.read_to_end(&mut bytes).unwrap();
2078
2079 let mut typedstream = TypedStreamDeserializer::new(&bytes);
2080 let root = typedstream.oxidize().unwrap();
2081 println!("\nResults:");
2082 println!("Root object: {:x?}", typedstream.object_table[root]);
2083 print_resolved(typedstream.resolve_properties(root).unwrap(), 2);
2084
2085 println!("\nFound {:?} types:", typedstream.type_table.len());
2086 typedstream
2087 .type_table
2088 .iter()
2089 .enumerate()
2090 .for_each(|(idx, item)| println!("\t{idx}: {item:?}"));
2091
2092 println!("\nFound {:?} objects:", typedstream.object_table.len());
2093 typedstream
2094 .object_table
2095 .iter()
2096 .enumerate()
2097 .for_each(|(idx, item)| println!("\t{idx}: {item:?}"));
2098
2099 let expected_types = vec![
2100 vec![Type::Object],
2101 vec![Type::String("NSAttributedString")],
2102 vec![Type::String("NSObject")],
2103 vec![Type::String("NSString")],
2104 vec![Type::Utf8String],
2105 ];
2106
2107 let expected_objects = vec![
2108 Archived::Object {
2109 class: 1,
2110 data: vec![vec![OutputData::Object(3)]],
2111 },
2112 Archived::Class(Class {
2113 name_index: 1,
2114 version: 0,
2115 parent_index: Some(2),
2116 }),
2117 Archived::Class(Class {
2118 name_index: 2,
2119 version: 0,
2120 parent_index: None,
2121 }),
2122 Archived::Object {
2123 class: 4,
2124 data: vec![vec![OutputData::String("")]],
2125 },
2126 Archived::Class(Class {
2127 name_index: 3,
2128 version: 1,
2129 parent_index: Some(2),
2130 }),
2131 ];
2132
2133 assert_eq!(typedstream.type_table, expected_types);
2134 assert_eq!(typedstream.object_table, expected_objects);
2135 }
2136
2137 #[test]
2138 fn test_parse_text_code() {
2139 let typedstream_path = current_dir().unwrap().as_path().join("src/test_data/Code");
2140 let mut file = File::open(typedstream_path).unwrap();
2141 let mut bytes = vec![];
2142 file.read_to_end(&mut bytes).unwrap();
2143
2144 let mut typedstream = TypedStreamDeserializer::new(&bytes);
2145 let root = typedstream.oxidize().unwrap();
2146 println!("\nResults:");
2147 println!("Root object: {:x?}", typedstream.object_table[root]);
2148 print_resolved(typedstream.resolve_properties(root).unwrap(), 2);
2149
2150 println!("\nFound {:?} types:", typedstream.type_table.len());
2151 typedstream
2152 .type_table
2153 .iter()
2154 .enumerate()
2155 .for_each(|(idx, item)| println!("\t{idx}: {item:?}"));
2156
2157 println!("\nFound {:?} objects:", typedstream.object_table.len());
2158 typedstream
2159 .object_table
2160 .iter()
2161 .enumerate()
2162 .for_each(|(idx, item)| println!("\t{idx}: {item:?}"));
2163
2164 let expected_types = vec![
2165 vec![Type::Object],
2166 vec![Type::String("NSMutableAttributedString")],
2167 vec![Type::String("NSAttributedString")],
2168 vec![Type::String("NSObject")],
2169 vec![Type::String("NSMutableString")],
2170 vec![Type::String("NSString")],
2171 vec![Type::Utf8String],
2172 vec![Type::SignedInt, Type::UnsignedInt],
2173 vec![Type::String("NSDictionary")],
2174 vec![Type::SignedInt],
2175 vec![Type::String("NSNumber")],
2176 vec![Type::String("NSValue")],
2177 vec![Type::EmbeddedData],
2178 vec![Type::String("NSData")],
2179 vec![Type::Array(535)],
2180 ];
2181
2182 let expected_objects = vec![
2183 Archived::Object {
2184 class: 1,
2185 data: vec![
2186 vec![OutputData::Object(4)],
2187 vec![OutputData::SignedInteger(1), OutputData::UnsignedInteger(6)],
2188 vec![OutputData::Object(7)],
2189 vec![
2190 OutputData::SignedInteger(2),
2191 OutputData::UnsignedInteger(46),
2192 ],
2193 vec![OutputData::Object(22)],
2194 ],
2195 },
2196 Archived::Class(Class {
2197 name_index: 1,
2198 version: 0,
2199 parent_index: Some(2),
2200 }),
2201 Archived::Class(Class {
2202 name_index: 2,
2203 version: 0,
2204 parent_index: Some(3),
2205 }),
2206 Archived::Class(Class {
2207 name_index: 3,
2208 version: 0,
2209 parent_index: None,
2210 }),
2211 Archived::Object {
2212 class: 5,
2213 data: vec![vec![OutputData::String(
2214 "000123 is your security code. Don't share your code.",
2215 )]],
2216 },
2217 Archived::Class(Class {
2218 name_index: 4,
2219 version: 1,
2220 parent_index: Some(6),
2221 }),
2222 Archived::Class(Class {
2223 name_index: 5,
2224 version: 1,
2225 parent_index: Some(3),
2226 }),
2227 Archived::Object {
2228 class: 8,
2229 data: vec![
2230 vec![OutputData::SignedInteger(3)],
2231 vec![OutputData::Object(9)],
2232 vec![OutputData::Object(10)],
2233 vec![OutputData::Object(14)],
2234 vec![OutputData::Object(15)],
2235 vec![OutputData::Object(19)],
2236 vec![OutputData::Object(20)],
2237 ],
2238 },
2239 Archived::Class(Class {
2240 name_index: 8,
2241 version: 0,
2242 parent_index: Some(3),
2243 }),
2244 Archived::Object {
2245 class: 6,
2246 data: vec![vec![OutputData::String("__kIMMessagePartAttributeName")]],
2247 },
2248 Archived::Object {
2249 class: 11,
2250 data: vec![vec![OutputData::SignedInteger(0)]],
2251 },
2252 Archived::Class(Class {
2253 name_index: 10,
2254 version: 0,
2255 parent_index: Some(12),
2256 }),
2257 Archived::Class(Class {
2258 name_index: 11,
2259 version: 0,
2260 parent_index: Some(3),
2261 }),
2262 Archived::Type(9),
2263 Archived::Object {
2264 class: 6,
2265 data: vec![vec![OutputData::String("__kIMOneTimeCodeAttributeName")]],
2266 },
2267 Archived::Object {
2268 class: 8,
2269 data: vec![
2270 vec![OutputData::SignedInteger(2)],
2271 vec![OutputData::Object(16)],
2272 vec![OutputData::Object(17)],
2273 vec![OutputData::Object(18)],
2274 vec![OutputData::Object(17)],
2275 ],
2276 },
2277 Archived::Object {
2278 class: 6,
2279 data: vec![vec![OutputData::String("displayCode")]],
2280 },
2281 Archived::Object {
2282 class: 6,
2283 data: vec![vec![OutputData::String("000123")]],
2284 },
2285 Archived::Object {
2286 class: 6,
2287 data: vec![vec![OutputData::String("code")]],
2288 },
2289 Archived::Object {
2290 class: 6,
2291 data: vec![vec![OutputData::String("__kIMDataDetectedAttributeName")]],
2292 },
2293 Archived::Object {
2294 class: 21,
2295 data: vec![
2296 vec![OutputData::SignedInteger(535)],
2297 vec![OutputData::Array(&[
2298 98, 112, 108, 105, 115, 116, 48, 48, 212, 1, 2, 3, 4, 5, 6, 7, 12, 88, 36,
2299 118, 101, 114, 115, 105, 111, 110, 89, 36, 97, 114, 99, 104, 105, 118, 101,
2300 114, 84, 36, 116, 111, 112, 88, 36, 111, 98, 106, 101, 99, 116, 115, 18, 0,
2301 1, 134, 160, 95, 16, 15, 78, 83, 75, 101, 121, 101, 100, 65, 114, 99, 104,
2302 105, 118, 101, 114, 210, 8, 9, 10, 11, 87, 118, 101, 114, 115, 105, 111,
2303 110, 89, 100, 100, 45, 114, 101, 115, 117, 108, 116, 128, 11, 128, 1, 172,
2304 13, 14, 28, 36, 37, 38, 44, 45, 46, 50, 53, 57, 85, 36, 110, 117, 108, 108,
2305 215, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 26, 82, 77, 83,
2306 86, 36, 99, 108, 97, 115, 115, 82, 65, 82, 81, 84, 81, 80, 82, 83, 82, 82,
2307 86, 78, 128, 6, 128, 10, 128, 2, 128, 7, 16, 1, 128, 8, 212, 29, 30, 31,
2308 16, 32, 33, 34, 35, 95, 16, 18, 78, 83, 46, 114, 97, 110, 103, 101, 118,
2309 97, 108, 46, 108, 101, 110, 103, 116, 104, 95, 16, 20, 78, 83, 46, 114, 97,
2310 110, 103, 101, 118, 97, 108, 46, 108, 111, 99, 97, 116, 105, 111, 110, 90,
2311 78, 83, 46, 115, 112, 101, 99, 105, 97, 108, 128, 3, 128, 4, 16, 4, 128, 5,
2312 16, 6, 16, 0, 210, 39, 40, 41, 42, 90, 36, 99, 108, 97, 115, 115, 110, 97,
2313 109, 101, 88, 36, 99, 108, 97, 115, 115, 101, 115, 87, 78, 83, 86, 97, 108,
2314 117, 101, 162, 41, 43, 88, 78, 83, 79, 98, 106, 101, 99, 116, 86, 48, 48,
2315 48, 49, 50, 51, 88, 65, 117, 116, 104, 67, 111, 100, 101, 210, 47, 16, 48,
2316 49, 90, 78, 83, 46, 111, 98, 106, 101, 99, 116, 115, 160, 128, 9, 210, 39,
2317 40, 51, 52, 87, 78, 83, 65, 114, 114, 97, 121, 162, 51, 43, 210, 39, 40,
2318 54, 55, 95, 16, 15, 68, 68, 83, 99, 97, 110, 110, 101, 114, 82, 101, 115,
2319 117, 108, 116, 162, 56, 43, 95, 16, 15, 68, 68, 83, 99, 97, 110, 110, 101,
2320 114, 82, 101, 115, 117, 108, 116, 16, 1, 0, 8, 0, 17, 0, 26, 0, 36, 0, 41,
2321 0, 50, 0, 55, 0, 73, 0, 78, 0, 86, 0, 96, 0, 98, 0, 100, 0, 113, 0, 119, 0,
2322 134, 0, 137, 0, 144, 0, 147, 0, 149, 0, 151, 0, 154, 0, 157, 0, 159, 0,
2323 161, 0, 163, 0, 165, 0, 167, 0, 169, 0, 178, 0, 199, 0, 222, 0, 233, 0,
2324 235, 0, 237, 0, 239, 0, 241, 0, 243, 0, 245, 0, 250, 1, 5, 1, 14, 1, 22, 1,
2325 25, 1, 34, 1, 41, 1, 50, 1, 55, 1, 66, 1, 67, 1, 69, 1, 74, 1, 82, 1, 85,
2326 1, 90, 1, 108, 1, 111, 1, 129, 0, 0, 0, 0, 0, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0,
2327 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 131,
2328 ])],
2329 ],
2330 },
2331 Archived::Class(Class {
2332 name_index: 13,
2333 version: 0,
2334 parent_index: Some(3),
2335 }),
2336 Archived::Object {
2337 class: 8,
2338 data: vec![
2339 vec![OutputData::SignedInteger(1)],
2340 vec![OutputData::Object(9)],
2341 vec![OutputData::Object(10)],
2342 ],
2343 },
2344 ];
2345
2346 assert_eq!(typedstream.type_table, expected_types);
2347 assert_eq!(typedstream.object_table, expected_objects);
2348 }
2349
2350 #[test]
2351 fn test_parse_text_custom_tapback() {
2352 let typedstream_path = current_dir()
2353 .unwrap()
2354 .as_path()
2355 .join("src/test_data/CustomTapback");
2356 let mut file = File::open(typedstream_path).unwrap();
2357 let mut bytes = vec![];
2358 file.read_to_end(&mut bytes).unwrap();
2359
2360 let mut typedstream = TypedStreamDeserializer::new(&bytes);
2361 let root = typedstream.oxidize().unwrap();
2362 println!("\nResults:");
2363 println!("Root object: {:x?}", typedstream.object_table[root]);
2364 print_resolved(typedstream.resolve_properties(root).unwrap(), 2);
2365
2366 println!("\nFound {:?} types:", typedstream.type_table.len());
2367 typedstream
2368 .type_table
2369 .iter()
2370 .enumerate()
2371 .for_each(|(idx, item)| println!("\t{idx}: {item:?}"));
2372
2373 println!("\nFound {:?} objects:", typedstream.object_table.len());
2374 typedstream
2375 .object_table
2376 .iter()
2377 .enumerate()
2378 .for_each(|(idx, item)| println!("\t{idx}: {item:?}"));
2379
2380 let expected_types = vec![
2381 vec![Type::Object],
2382 vec![Type::String("NSAttributedString")],
2383 vec![Type::String("NSObject")],
2384 vec![Type::String("NSString")],
2385 vec![Type::Utf8String],
2386 vec![Type::SignedInt, Type::UnsignedInt],
2387 vec![Type::String("NSDictionary")],
2388 vec![Type::SignedInt],
2389 vec![Type::String("NSNumber")],
2390 vec![Type::String("NSValue")],
2391 vec![Type::EmbeddedData],
2392 vec![Type::SignedInt],
2393 ];
2394
2395 let expected_objects = vec![
2396 Archived::Object {
2397 class: 1,
2398 data: vec![
2399 vec![OutputData::Object(3)],
2400 vec![
2401 OutputData::SignedInteger(1),
2402 OutputData::UnsignedInteger(75),
2403 ],
2404 vec![OutputData::Object(5)],
2405 vec![OutputData::SignedInteger(2), OutputData::UnsignedInteger(1)],
2406 vec![OutputData::Object(14)],
2407 ],
2408 },
2409 Archived::Class(Class {
2410 name_index: 1,
2411 version: 0,
2412 parent_index: Some(2),
2413 }),
2414 Archived::Class(Class {
2415 name_index: 2,
2416 version: 0,
2417 parent_index: None,
2418 }),
2419 Archived::Object {
2420 class: 4,
2421 data: vec![vec![OutputData::String(
2422 "Reacted with a sticker to “Like I wonder if the stickers can be reactions ”",
2423 )]],
2424 },
2425 Archived::Class(Class {
2426 name_index: 3,
2427 version: 1,
2428 parent_index: Some(2),
2429 }),
2430 Archived::Object {
2431 class: 6,
2432 data: vec![
2433 vec![OutputData::SignedInteger(2)],
2434 vec![OutputData::Object(7)],
2435 vec![OutputData::Object(8)],
2436 vec![OutputData::Object(12)],
2437 vec![OutputData::Object(13)],
2438 ],
2439 },
2440 Archived::Class(Class {
2441 name_index: 6,
2442 version: 0,
2443 parent_index: Some(2),
2444 }),
2445 Archived::Object {
2446 class: 4,
2447 data: vec![vec![OutputData::String(
2448 "__kIMBaseWritingDirectionAttributeName",
2449 )]],
2450 },
2451 Archived::Object {
2452 class: 9,
2453 data: vec![vec![OutputData::SignedInteger(-1)]],
2454 },
2455 Archived::Class(Class {
2456 name_index: 8,
2457 version: 0,
2458 parent_index: Some(10),
2459 }),
2460 Archived::Class(Class {
2461 name_index: 9,
2462 version: 0,
2463 parent_index: Some(2),
2464 }),
2465 Archived::Type(11),
2466 Archived::Object {
2467 class: 4,
2468 data: vec![vec![OutputData::String("__kIMMessagePartAttributeName")]],
2469 },
2470 Archived::Object {
2471 class: 9,
2472 data: vec![vec![OutputData::SignedInteger(0)]],
2473 },
2474 Archived::Object {
2475 class: 6,
2476 data: vec![
2477 vec![OutputData::SignedInteger(3)],
2478 vec![OutputData::Object(15)],
2479 vec![OutputData::Object(16)],
2480 vec![OutputData::Object(7)],
2481 vec![OutputData::Object(8)],
2482 vec![OutputData::Object(12)],
2483 vec![OutputData::Object(17)],
2484 ],
2485 },
2486 Archived::Object {
2487 class: 4,
2488 data: vec![vec![OutputData::String(
2489 "__kIMFileTransferGUIDAttributeName",
2490 )]],
2491 },
2492 Archived::Object {
2493 class: 4,
2494 data: vec![vec![OutputData::String(
2495 "41C4376E-397E-4C42-84E2-B16F7801F638",
2496 )]],
2497 },
2498 Archived::Object {
2499 class: 9,
2500 data: vec![vec![OutputData::SignedInteger(1)]],
2501 },
2502 ];
2503
2504 assert_eq!(typedstream.type_table, expected_types);
2505 assert_eq!(typedstream.object_table, expected_objects);
2506 }
2507
2508 #[test]
2509 fn test_parse_text_date() {
2510 let typedstream_path = current_dir().unwrap().as_path().join("src/test_data/Date");
2511 let mut file = File::open(typedstream_path).unwrap();
2512 let mut bytes = vec![];
2513 file.read_to_end(&mut bytes).unwrap();
2514
2515 let mut typedstream = TypedStreamDeserializer::new(&bytes);
2516 let root = typedstream.oxidize().unwrap();
2517 println!("\nResults:");
2518 println!("Root object: {:x?}", typedstream.object_table[root]);
2519 print_resolved(typedstream.resolve_properties(root).unwrap(), 2);
2520
2521 println!("\nFound {:?} types:", typedstream.type_table.len());
2522 typedstream
2523 .type_table
2524 .iter()
2525 .enumerate()
2526 .for_each(|(idx, item)| println!("\t{idx}: {item:?}"));
2527
2528 println!("\nFound {:?} objects:", typedstream.object_table.len());
2529 typedstream
2530 .object_table
2531 .iter()
2532 .enumerate()
2533 .for_each(|(idx, item)| println!("\t{idx}: {item:?}"));
2534
2535 let expected_types = vec![
2536 vec![Type::Object],
2537 vec![Type::String("NSMutableAttributedString")],
2538 vec![Type::String("NSAttributedString")],
2539 vec![Type::String("NSObject")],
2540 vec![Type::String("NSMutableString")],
2541 vec![Type::String("NSString")],
2542 vec![Type::Utf8String],
2543 vec![Type::SignedInt, Type::UnsignedInt],
2544 vec![Type::String("NSDictionary")],
2545 vec![Type::SignedInt],
2546 vec![Type::String("NSNumber")],
2547 vec![Type::String("NSValue")],
2548 vec![Type::EmbeddedData],
2549 vec![Type::String("NSMutableData")],
2550 vec![Type::String("NSData")],
2551 vec![Type::Array(669)],
2552 ];
2553
2554 let expected_objects = vec![
2555 Archived::Object {
2556 class: 1,
2557 data: vec![
2558 vec![OutputData::Object(4)],
2559 vec![
2560 OutputData::SignedInteger(1),
2561 OutputData::UnsignedInteger(17),
2562 ],
2563 vec![OutputData::Object(7)],
2564 vec![OutputData::SignedInteger(2), OutputData::UnsignedInteger(8)],
2565 vec![OutputData::Object(14)],
2566 vec![OutputData::SignedInteger(1), OutputData::UnsignedInteger(1)],
2567 ],
2568 },
2569 Archived::Class(Class {
2570 name_index: 1,
2571 version: 0,
2572 parent_index: Some(2),
2573 }),
2574 Archived::Class(Class {
2575 name_index: 2,
2576 version: 0,
2577 parent_index: Some(3),
2578 }),
2579 Archived::Class(Class {
2580 name_index: 3,
2581 version: 0,
2582 parent_index: None,
2583 }),
2584 Archived::Object {
2585 class: 5,
2586 data: vec![vec![OutputData::String("Hi. Right now or tomorrow?")]],
2587 },
2588 Archived::Class(Class {
2589 name_index: 4,
2590 version: 1,
2591 parent_index: Some(6),
2592 }),
2593 Archived::Class(Class {
2594 name_index: 5,
2595 version: 1,
2596 parent_index: Some(3),
2597 }),
2598 Archived::Object {
2599 class: 8,
2600 data: vec![
2601 vec![OutputData::SignedInteger(1)],
2602 vec![OutputData::Object(9)],
2603 vec![OutputData::Object(10)],
2604 ],
2605 },
2606 Archived::Class(Class {
2607 name_index: 8,
2608 version: 0,
2609 parent_index: Some(3),
2610 }),
2611 Archived::Object {
2612 class: 6,
2613 data: vec![vec![OutputData::String("__kIMMessagePartAttributeName")]],
2614 },
2615 Archived::Object {
2616 class: 11,
2617 data: vec![vec![OutputData::SignedInteger(0)]],
2618 },
2619 Archived::Class(Class {
2620 name_index: 10,
2621 version: 0,
2622 parent_index: Some(12),
2623 }),
2624 Archived::Class(Class {
2625 name_index: 11,
2626 version: 0,
2627 parent_index: Some(3),
2628 }),
2629 Archived::Type(9),
2630 Archived::Object {
2631 class: 8,
2632 data: vec![
2633 vec![OutputData::SignedInteger(2)],
2634 vec![OutputData::Object(15)],
2635 vec![OutputData::Object(16)],
2636 vec![OutputData::Object(19)],
2637 vec![OutputData::Object(10)],
2638 ],
2639 },
2640 Archived::Object {
2641 class: 6,
2642 data: vec![vec![OutputData::String("__kIMCalendarEventAttributeName")]],
2643 },
2644 Archived::Object {
2645 class: 17,
2646 data: vec![
2647 vec![OutputData::SignedInteger(669)],
2648 vec![OutputData::Array(&[
2649 98, 112, 108, 105, 115, 116, 48, 48, 212, 1, 2, 3, 4, 5, 6, 7, 12, 88, 36,
2650 118, 101, 114, 115, 105, 111, 110, 89, 36, 97, 114, 99, 104, 105, 118, 101,
2651 114, 84, 36, 116, 111, 112, 88, 36, 111, 98, 106, 101, 99, 116, 115, 18, 0,
2652 1, 134, 160, 95, 16, 15, 78, 83, 75, 101, 121, 101, 100, 65, 114, 99, 104,
2653 105, 118, 101, 114, 210, 8, 9, 10, 11, 87, 118, 101, 114, 115, 105, 111,
2654 110, 89, 100, 100, 45, 114, 101, 115, 117, 108, 116, 128, 16, 128, 1, 175,
2655 16, 17, 13, 14, 29, 37, 38, 39, 45, 46, 47, 52, 60, 64, 65, 68, 72, 73, 77,
2656 85, 36, 110, 117, 108, 108, 215, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
2657 25, 26, 27, 28, 82, 77, 83, 86, 36, 99, 108, 97, 115, 115, 82, 65, 82, 81,
2658 84, 81, 80, 82, 83, 82, 82, 86, 78, 128, 6, 128, 15, 128, 2, 128, 7, 16, 0,
2659 128, 8, 16, 1, 212, 30, 31, 32, 16, 33, 34, 35, 36, 95, 16, 18, 78, 83, 46,
2660 114, 97, 110, 103, 101, 118, 97, 108, 46, 108, 101, 110, 103, 116, 104, 95,
2661 16, 20, 78, 83, 46, 114, 97, 110, 103, 101, 118, 97, 108, 46, 108, 111, 99,
2662 97, 116, 105, 111, 110, 90, 78, 83, 46, 115, 112, 101, 99, 105, 97, 108,
2663 128, 3, 128, 4, 16, 4, 128, 5, 16, 8, 16, 17, 210, 40, 41, 42, 43, 90, 36,
2664 99, 108, 97, 115, 115, 110, 97, 109, 101, 88, 36, 99, 108, 97, 115, 115,
2665 101, 115, 87, 78, 83, 86, 97, 108, 117, 101, 162, 42, 44, 88, 78, 83, 79,
2666 98, 106, 101, 99, 116, 88, 116, 111, 109, 111, 114, 114, 111, 119, 84, 68,
2667 97, 116, 101, 210, 48, 16, 49, 51, 90, 78, 83, 46, 111, 98, 106, 101, 99,
2668 116, 115, 161, 50, 128, 9, 128, 13, 216, 15, 16, 53, 17, 18, 19, 20, 21,
2669 22, 23, 56, 57, 58, 28, 59, 28, 81, 86, 128, 6, 128, 15, 128, 14, 128, 10,
2670 128, 11, 128, 12, 212, 30, 31, 32, 16, 33, 34, 35, 36, 128, 3, 128, 4, 128,
2671 5, 91, 82, 101, 108, 97, 116, 105, 118, 101, 68, 97, 121, 210, 48, 16, 66,
2672 51, 160, 128, 13, 210, 40, 41, 69, 70, 94, 78, 83, 77, 117, 116, 97, 98,
2673 108, 101, 65, 114, 114, 97, 121, 163, 69, 71, 44, 87, 78, 83, 65, 114, 114,
2674 97, 121, 81, 49, 210, 40, 41, 74, 75, 95, 16, 15, 68, 68, 83, 99, 97, 110,
2675 110, 101, 114, 82, 101, 115, 117, 108, 116, 162, 76, 44, 95, 16, 15, 68,
2676 68, 83, 99, 97, 110, 110, 101, 114, 82, 101, 115, 117, 108, 116, 16, 1, 0,
2677 8, 0, 17, 0, 26, 0, 36, 0, 41, 0, 50, 0, 55, 0, 73, 0, 78, 0, 86, 0, 96, 0,
2678 98, 0, 100, 0, 120, 0, 126, 0, 141, 0, 144, 0, 151, 0, 154, 0, 156, 0, 158,
2679 0, 161, 0, 164, 0, 166, 0, 168, 0, 170, 0, 172, 0, 174, 0, 176, 0, 178, 0,
2680 187, 0, 208, 0, 231, 0, 242, 0, 244, 0, 246, 0, 248, 0, 250, 0, 252, 0,
2681 254, 1, 3, 1, 14, 1, 23, 1, 31, 1, 34, 1, 43, 1, 52, 1, 57, 1, 62, 1, 73,
2682 1, 75, 1, 77, 1, 79, 1, 96, 1, 98, 1, 100, 1, 102, 1, 104, 1, 106, 1, 108,
2683 1, 110, 1, 119, 1, 121, 1, 123, 1, 125, 1, 137, 1, 142, 1, 143, 1, 145, 1,
2684 150, 1, 165, 1, 169, 1, 177, 1, 179, 1, 184, 1, 202, 1, 205, 1, 223, 0, 0,
2685 0, 0, 0, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2686 0, 0, 0, 1, 225,
2687 ])],
2688 ],
2689 },
2690 Archived::Class(Class {
2691 name_index: 13,
2692 version: 0,
2693 parent_index: Some(18),
2694 }),
2695 Archived::Class(Class {
2696 name_index: 14,
2697 version: 0,
2698 parent_index: Some(3),
2699 }),
2700 Archived::Object {
2701 class: 6,
2702 data: vec![vec![OutputData::String("__kIMMessagePartAttributeName")]],
2703 },
2704 ];
2705
2706 assert_eq!(typedstream.type_table, expected_types);
2707 assert_eq!(typedstream.object_table, expected_objects);
2708 }
2709
2710 #[test]
2711 fn test_parse_text_edited_with_formatting() {
2712 let typedstream_path = current_dir()
2713 .unwrap()
2714 .as_path()
2715 .join("src/test_data/EditedWithFormatting");
2716 let mut file = File::open(typedstream_path).unwrap();
2717 let mut bytes = vec![];
2718 file.read_to_end(&mut bytes).unwrap();
2719
2720 let mut typedstream = TypedStreamDeserializer::new(&bytes);
2721 let root = typedstream.oxidize().unwrap();
2722 println!("\nResults:");
2723 println!("Root object: {:x?}", typedstream.object_table[root]);
2724 print_resolved(typedstream.resolve_properties(root).unwrap(), 2);
2725
2726 println!("\nFound {:?} types:", typedstream.type_table.len());
2727 typedstream
2728 .type_table
2729 .iter()
2730 .enumerate()
2731 .for_each(|(idx, item)| println!("\t{idx}: {item:?}"));
2732
2733 println!("\nFound {:?} objects:", typedstream.object_table.len());
2734 typedstream
2735 .object_table
2736 .iter()
2737 .enumerate()
2738 .for_each(|(idx, item)| println!("\t{idx}: {item:?}"));
2739
2740 let expected_types = vec![
2741 vec![Type::Object],
2742 vec![Type::String("NSAttributedString")],
2743 vec![Type::String("NSObject")],
2744 vec![Type::String("NSString")],
2745 vec![Type::Utf8String],
2746 vec![Type::SignedInt, Type::UnsignedInt],
2747 vec![Type::String("NSDictionary")],
2748 vec![Type::SignedInt],
2749 vec![Type::String("NSNumber")],
2750 vec![Type::String("NSValue")],
2751 vec![Type::EmbeddedData],
2752 ];
2753
2754 let expected_objects = vec![
2755 Archived::Object {
2756 class: 1,
2757 data: vec![
2758 vec![OutputData::Object(3)],
2759 vec![OutputData::SignedInteger(1), OutputData::UnsignedInteger(4)],
2760 vec![OutputData::Object(5)],
2761 ],
2762 },
2763 Archived::Class(Class {
2764 name_index: 1,
2765 version: 0,
2766 parent_index: Some(2),
2767 }),
2768 Archived::Class(Class {
2769 name_index: 2,
2770 version: 0,
2771 parent_index: None,
2772 }),
2773 Archived::Object {
2774 class: 4,
2775 data: vec![vec![OutputData::String("Test")]],
2776 },
2777 Archived::Class(Class {
2778 name_index: 3,
2779 version: 1,
2780 parent_index: Some(2),
2781 }),
2782 Archived::Object {
2783 class: 6,
2784 data: vec![
2785 vec![OutputData::SignedInteger(2)],
2786 vec![OutputData::Object(7)],
2787 vec![OutputData::Object(8)],
2788 vec![OutputData::Object(12)],
2789 vec![OutputData::Object(13)],
2790 ],
2791 },
2792 Archived::Class(Class {
2793 name_index: 6,
2794 version: 0,
2795 parent_index: Some(2),
2796 }),
2797 Archived::Object {
2798 class: 4,
2799 data: vec![vec![OutputData::String(
2800 "__kIMTextStrikethroughAttributeName",
2801 )]],
2802 },
2803 Archived::Object {
2804 class: 9,
2805 data: vec![vec![OutputData::SignedInteger(1)]],
2806 },
2807 Archived::Class(Class {
2808 name_index: 8,
2809 version: 0,
2810 parent_index: Some(10),
2811 }),
2812 Archived::Class(Class {
2813 name_index: 9,
2814 version: 0,
2815 parent_index: Some(2),
2816 }),
2817 Archived::Type(7),
2818 Archived::Object {
2819 class: 4,
2820 data: vec![vec![OutputData::String("__kIMMessagePartAttributeName")]],
2821 },
2822 Archived::Object {
2823 class: 9,
2824 data: vec![vec![OutputData::SignedInteger(0)]],
2825 },
2826 ];
2827
2828 assert_eq!(typedstream.type_table, expected_types);
2829 assert_eq!(typedstream.object_table, expected_objects);
2830 }
2831
2832 #[test]
2833 fn test_parse_text_email() {
2834 let typedstream_path = current_dir().unwrap().as_path().join("src/test_data/Email");
2835 let mut file = File::open(typedstream_path).unwrap();
2836 let mut bytes = vec![];
2837 file.read_to_end(&mut bytes).unwrap();
2838
2839 let mut typedstream = TypedStreamDeserializer::new(&bytes);
2840 let root = typedstream.oxidize().unwrap();
2841 println!("\nResults:");
2842 println!("Root object: {:x?}", typedstream.object_table[root]);
2843 print_resolved(typedstream.resolve_properties(root).unwrap(), 2);
2844
2845 println!("\nFound {:?} types:", typedstream.type_table.len());
2846 typedstream
2847 .type_table
2848 .iter()
2849 .enumerate()
2850 .for_each(|(idx, item)| println!("\t{idx}: {item:?}"));
2851
2852 println!("\nFound {:?} objects:", typedstream.object_table.len());
2853 typedstream
2854 .object_table
2855 .iter()
2856 .enumerate()
2857 .for_each(|(idx, item)| println!("\t{idx}: {item:?}"));
2858
2859 let expected_types = vec![
2860 vec![Type::Object],
2861 vec![Type::String("NSAttributedString")],
2862 vec![Type::String("NSObject")],
2863 vec![Type::String("NSString")],
2864 vec![Type::Utf8String],
2865 vec![Type::SignedInt, Type::UnsignedInt],
2866 vec![Type::String("NSDictionary")],
2867 vec![Type::SignedInt],
2868 vec![Type::String("NSMutableData")],
2869 vec![Type::String("NSData")],
2870 vec![Type::Array(667)],
2871 vec![Type::String("NSNumber")],
2872 vec![Type::String("NSValue")],
2873 vec![Type::EmbeddedData],
2874 vec![Type::String("NSURL")],
2875 vec![Type::SignedInt],
2876 ];
2877
2878 let expected_objects = vec![
2879 Archived::Object {
2880 class: 1,
2881 data: vec![
2882 vec![OutputData::Object(3)],
2883 vec![
2884 OutputData::SignedInteger(1),
2885 OutputData::UnsignedInteger(20),
2886 ],
2887 vec![OutputData::Object(5)],
2888 vec![
2889 OutputData::SignedInteger(2),
2890 OutputData::UnsignedInteger(11),
2891 ],
2892 vec![OutputData::Object(20)],
2893 ],
2894 },
2895 Archived::Class(Class {
2896 name_index: 1,
2897 version: 0,
2898 parent_index: Some(2),
2899 }),
2900 Archived::Class(Class {
2901 name_index: 2,
2902 version: 0,
2903 parent_index: None,
2904 }),
2905 Archived::Object {
2906 class: 4,
2907 data: vec![vec![OutputData::String("asdfghjklq@gmail.com might work")]],
2908 },
2909 Archived::Class(Class {
2910 name_index: 3,
2911 version: 1,
2912 parent_index: Some(2),
2913 }),
2914 Archived::Object {
2915 class: 6,
2916 data: vec![
2917 vec![OutputData::SignedInteger(3)],
2918 vec![OutputData::Object(7)],
2919 vec![OutputData::Object(8)],
2920 vec![OutputData::Object(11)],
2921 vec![OutputData::Object(12)],
2922 vec![OutputData::Object(16)],
2923 vec![OutputData::Object(17)],
2924 ],
2925 },
2926 Archived::Class(Class {
2927 name_index: 6,
2928 version: 0,
2929 parent_index: Some(2),
2930 }),
2931 Archived::Object {
2932 class: 4,
2933 data: vec![vec![OutputData::String("__kIMDataDetectedAttributeName")]],
2934 },
2935 Archived::Object {
2936 class: 9,
2937 data: vec![
2938 vec![OutputData::SignedInteger(667)],
2939 vec![OutputData::Array(&[
2940 98, 112, 108, 105, 115, 116, 48, 48, 212, 1, 2, 3, 4, 5, 6, 7, 12, 88, 36,
2941 118, 101, 114, 115, 105, 111, 110, 89, 36, 97, 114, 99, 104, 105, 118, 101,
2942 114, 84, 36, 116, 111, 112, 88, 36, 111, 98, 106, 101, 99, 116, 115, 18, 0,
2943 1, 134, 160, 95, 16, 15, 78, 83, 75, 101, 121, 101, 100, 65, 114, 99, 104,
2944 105, 118, 101, 114, 210, 8, 9, 13, 11, 87, 118, 101, 114, 115, 105, 111,
2945 110, 89, 100, 100, 45, 114, 101, 115, 117, 108, 116, 128, 16, 128, 1, 175,
2946 16, 17, 13, 14, 28, 36, 37, 38, 44, 45, 46, 51, 57, 61, 62, 63, 66, 69, 73,
2947 85, 36, 110, 117, 108, 108, 215, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
2948 25, 26, 27, 26, 82, 77, 83, 86, 36, 99, 108, 97, 115, 115, 82, 65, 82, 81,
2949 84, 81, 80, 82, 83, 82, 82, 86, 78, 128, 6, 128, 15, 128, 2, 128, 7, 16, 1,
2950 128, 8, 212, 29, 30, 31, 16, 32, 33, 34, 35, 95, 16, 18, 78, 83, 46, 114,
2951 97, 110, 103, 101, 118, 97, 108, 46, 108, 101, 110, 103, 116, 104, 95, 16,
2952 20, 78, 83, 46, 114, 97, 110, 103, 101, 118, 97, 108, 46, 108, 111, 99, 97,
2953 116, 105, 111, 110, 90, 78, 83, 46, 115, 112, 101, 99, 105, 97, 108, 128,
2954 3, 128, 4, 16, 4, 128, 5, 16, 20, 16, 0, 210, 39, 40, 41, 42, 90, 36, 99,
2955 108, 97, 115, 115, 110, 97, 109, 101, 88, 36, 99, 108, 97, 115, 115, 101,
2956 115, 87, 78, 83, 86, 97, 108, 117, 101, 162, 41, 43, 88, 78, 83, 79, 98,
2957 106, 101, 99, 116, 95, 16, 20, 97, 115, 100, 102, 103, 104, 106, 107, 108,
2958 113, 64, 103, 109, 97, 105, 108, 46, 99, 111, 109, 85, 69, 109, 97, 105,
2959 108, 210, 47, 16, 48, 50, 90, 78, 83, 46, 111, 98, 106, 101, 99, 116, 115,
2960 161, 49, 128, 9, 128, 14, 215, 15, 16, 17, 18, 19, 20, 21, 52, 23, 54, 55,
2961 26, 56, 26, 128, 11, 128, 15, 128, 13, 128, 12, 128, 13, 212, 29, 30, 31,
2962 16, 32, 33, 34, 35, 128, 3, 128, 4, 128, 5, 95, 16, 20, 97, 115, 100, 102,
2963 103, 104, 106, 107, 108, 113, 64, 103, 109, 97, 105, 108, 46, 99, 111, 109,
2964 85, 86, 97, 108, 117, 101, 210, 47, 16, 64, 50, 160, 128, 14, 210, 39, 40,
2965 67, 68, 87, 78, 83, 65, 114, 114, 97, 121, 162, 67, 43, 210, 39, 40, 70,
2966 71, 95, 16, 15, 68, 68, 83, 99, 97, 110, 110, 101, 114, 82, 101, 115, 117,
2967 108, 116, 162, 72, 43, 95, 16, 15, 68, 68, 83, 99, 97, 110, 110, 101, 114,
2968 82, 101, 115, 117, 108, 116, 16, 1, 0, 8, 0, 17, 0, 26, 0, 36, 0, 41, 0,
2969 50, 0, 55, 0, 73, 0, 78, 0, 86, 0, 96, 0, 98, 0, 100, 0, 120, 0, 126, 0,
2970 141, 0, 144, 0, 151, 0, 154, 0, 156, 0, 158, 0, 161, 0, 164, 0, 166, 0,
2971 168, 0, 170, 0, 172, 0, 174, 0, 176, 0, 185, 0, 206, 0, 229, 0, 240, 0,
2972 242, 0, 244, 0, 246, 0, 248, 0, 250, 0, 252, 1, 1, 1, 12, 1, 21, 1, 29, 1,
2973 32, 1, 41, 1, 64, 1, 70, 1, 75, 1, 86, 1, 88, 1, 90, 1, 92, 1, 107, 1, 109,
2974 1, 111, 1, 113, 1, 115, 1, 117, 1, 126, 1, 128, 1, 130, 1, 132, 1, 155, 1,
2975 161, 1, 166, 1, 167, 1, 169, 1, 174, 1, 182, 1, 185, 1, 190, 1, 208, 1,
2976 211, 1, 229, 0, 0, 0, 0, 0, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 74, 0, 0, 0, 0,
2977 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 231,
2978 ])],
2979 ],
2980 },
2981 Archived::Class(Class {
2982 name_index: 8,
2983 version: 0,
2984 parent_index: Some(10),
2985 }),
2986 Archived::Class(Class {
2987 name_index: 9,
2988 version: 0,
2989 parent_index: Some(2),
2990 }),
2991 Archived::Object {
2992 class: 4,
2993 data: vec![vec![OutputData::String("__kIMMessagePartAttributeName")]],
2994 },
2995 Archived::Object {
2996 class: 13,
2997 data: vec![vec![OutputData::SignedInteger(0)]],
2998 },
2999 Archived::Class(Class {
3000 name_index: 11,
3001 version: 0,
3002 parent_index: Some(14),
3003 }),
3004 Archived::Class(Class {
3005 name_index: 12,
3006 version: 0,
3007 parent_index: Some(2),
3008 }),
3009 Archived::Type(7),
3010 Archived::Object {
3011 class: 4,
3012 data: vec![vec![OutputData::String("__kIMLinkAttributeName")]],
3013 },
3014 Archived::Object {
3015 class: 18,
3016 data: vec![
3017 vec![OutputData::SignedInteger(0)],
3018 vec![OutputData::Object(19)],
3019 ],
3020 },
3021 Archived::Class(Class {
3022 name_index: 14,
3023 version: 0,
3024 parent_index: Some(2),
3025 }),
3026 Archived::Object {
3027 class: 4,
3028 data: vec![vec![OutputData::String("mailto:asdfghjklq@gmail.com")]],
3029 },
3030 Archived::Object {
3031 class: 6,
3032 data: vec![
3033 vec![OutputData::SignedInteger(1)],
3034 vec![OutputData::Object(21)],
3035 vec![OutputData::Object(12)],
3036 ],
3037 },
3038 Archived::Object {
3039 class: 4,
3040 data: vec![vec![OutputData::String("__kIMMessagePartAttributeName")]],
3041 },
3042 ];
3043
3044 assert_eq!(typedstream.type_table, expected_types);
3045 assert_eq!(typedstream.object_table, expected_objects);
3046 }
3047
3048 #[test]
3049 fn test_parse_text_emoji_bold_underline() {
3050 let typedstream_path = current_dir()
3051 .unwrap()
3052 .as_path()
3053 .join("src/test_data/EmojiBoldUnderline");
3054 let mut file = File::open(typedstream_path).unwrap();
3055 let mut bytes = vec![];
3056 file.read_to_end(&mut bytes).unwrap();
3057
3058 let mut typedstream = TypedStreamDeserializer::new(&bytes);
3059 let root = typedstream.oxidize().unwrap();
3060 println!("\nResults:");
3061 println!("Root object: {:x?}", typedstream.object_table[root]);
3062 print_resolved(typedstream.resolve_properties(root).unwrap(), 2);
3063
3064 println!("\nFound {:?} types:", typedstream.type_table.len());
3065 typedstream
3066 .type_table
3067 .iter()
3068 .enumerate()
3069 .for_each(|(idx, item)| println!("\t{idx}: {item:?}"));
3070
3071 println!("\nFound {:?} objects:", typedstream.object_table.len());
3072 typedstream
3073 .object_table
3074 .iter()
3075 .enumerate()
3076 .for_each(|(idx, item)| println!("\t{idx}: {item:?}"));
3077
3078 let expected_types = vec![
3079 vec![Type::Object],
3080 vec![Type::String("NSAttributedString")],
3081 vec![Type::String("NSObject")],
3082 vec![Type::String("NSString")],
3083 vec![Type::Utf8String],
3084 vec![Type::SignedInt, Type::UnsignedInt],
3085 vec![Type::String("NSDictionary")],
3086 vec![Type::SignedInt],
3087 vec![Type::String("NSNumber")],
3088 vec![Type::String("NSValue")],
3089 vec![Type::EmbeddedData],
3090 ];
3091
3092 let expected_objects = vec![
3093 Archived::Object {
3094 class: 1,
3095 data: vec![
3096 vec![OutputData::Object(3)],
3097 vec![OutputData::SignedInteger(1), OutputData::UnsignedInteger(3)],
3098 vec![OutputData::Object(5)],
3099 vec![OutputData::SignedInteger(2), OutputData::UnsignedInteger(4)],
3100 vec![OutputData::Object(12)],
3101 vec![OutputData::SignedInteger(1), OutputData::UnsignedInteger(1)],
3102 vec![OutputData::SignedInteger(3), OutputData::UnsignedInteger(9)],
3103 vec![OutputData::Object(16)],
3104 ],
3105 },
3106 Archived::Class(Class {
3107 name_index: 1,
3108 version: 0,
3109 parent_index: Some(2),
3110 }),
3111 Archived::Class(Class {
3112 name_index: 2,
3113 version: 0,
3114 parent_index: None,
3115 }),
3116 Archived::Object {
3117 class: 4,
3118 data: vec![vec![OutputData::String("🅱\u{fe0f}Bold_Underline")]],
3119 },
3120 Archived::Class(Class {
3121 name_index: 3,
3122 version: 1,
3123 parent_index: Some(2),
3124 }),
3125 Archived::Object {
3126 class: 6,
3127 data: vec![
3128 vec![OutputData::SignedInteger(1)],
3129 vec![OutputData::Object(7)],
3130 vec![OutputData::Object(8)],
3131 ],
3132 },
3133 Archived::Class(Class {
3134 name_index: 6,
3135 version: 0,
3136 parent_index: Some(2),
3137 }),
3138 Archived::Object {
3139 class: 4,
3140 data: vec![vec![OutputData::String("__kIMMessagePartAttributeName")]],
3141 },
3142 Archived::Object {
3143 class: 9,
3144 data: vec![vec![OutputData::SignedInteger(0)]],
3145 },
3146 Archived::Class(Class {
3147 name_index: 8,
3148 version: 0,
3149 parent_index: Some(10),
3150 }),
3151 Archived::Class(Class {
3152 name_index: 9,
3153 version: 0,
3154 parent_index: Some(2),
3155 }),
3156 Archived::Type(7),
3157 Archived::Object {
3158 class: 6,
3159 data: vec![
3160 vec![OutputData::SignedInteger(2)],
3161 vec![OutputData::Object(13)],
3162 vec![OutputData::Object(14)],
3163 vec![OutputData::Object(15)],
3164 vec![OutputData::Object(8)],
3165 ],
3166 },
3167 Archived::Object {
3168 class: 4,
3169 data: vec![vec![OutputData::String("__kIMTextBoldAttributeName")]],
3170 },
3171 Archived::Object {
3172 class: 9,
3173 data: vec![vec![OutputData::SignedInteger(1)]],
3174 },
3175 Archived::Object {
3176 class: 4,
3177 data: vec![vec![OutputData::String("__kIMMessagePartAttributeName")]],
3178 },
3179 Archived::Object {
3180 class: 6,
3181 data: vec![
3182 vec![OutputData::SignedInteger(2)],
3183 vec![OutputData::Object(17)],
3184 vec![OutputData::Object(14)],
3185 vec![OutputData::Object(15)],
3186 vec![OutputData::Object(8)],
3187 ],
3188 },
3189 Archived::Object {
3190 class: 4,
3191 data: vec![vec![OutputData::String("__kIMTextUnderlineAttributeName")]],
3192 },
3193 ];
3194
3195 assert_eq!(typedstream.type_table, expected_types);
3196 assert_eq!(typedstream.object_table, expected_objects);
3197 }
3198
3199 #[test]
3200 fn test_parse_text_extra_data() {
3201 let typedstream_path = current_dir()
3203 .unwrap()
3204 .as_path()
3205 .join("src/test_data/ExtraData");
3206 let mut file = File::open(typedstream_path).unwrap();
3207 let mut bytes = vec![];
3208 file.read_to_end(&mut bytes).unwrap();
3209
3210 let mut typedstream = TypedStreamDeserializer::new(&bytes);
3211 let root = typedstream.oxidize();
3212 assert!(root.is_err());
3213 }
3214
3215 #[test]
3216 fn test_parse_text_formatted() {
3217 let typedstream_path = current_dir()
3218 .unwrap()
3219 .as_path()
3220 .join("src/test_data/Formatted");
3221 let mut file = File::open(typedstream_path).unwrap();
3222 let mut bytes = vec![];
3223 file.read_to_end(&mut bytes).unwrap();
3224
3225 let mut typedstream = TypedStreamDeserializer::new(&bytes);
3226 let root = typedstream.oxidize().unwrap();
3227 println!("\nResults:");
3228 println!("Root object: {:x?}", typedstream.object_table[root]);
3229 print_resolved(typedstream.resolve_properties(root).unwrap(), 2);
3230
3231 println!("\nFound {:?} types:", typedstream.type_table.len());
3232 typedstream
3233 .type_table
3234 .iter()
3235 .enumerate()
3236 .for_each(|(idx, item)| println!("\t{idx}: {item:?}"));
3237
3238 println!("\nFound {:?} objects:", typedstream.object_table.len());
3239 typedstream
3240 .object_table
3241 .iter()
3242 .enumerate()
3243 .for_each(|(idx, item)| println!("\t{idx}: {item:?}"));
3244
3245 let expected_types = vec![
3246 vec![Type::Object],
3247 vec![Type::String("NSAttributedString")],
3248 vec![Type::String("NSObject")],
3249 vec![Type::String("NSString")],
3250 vec![Type::Utf8String],
3251 vec![Type::SignedInt, Type::UnsignedInt],
3252 vec![Type::String("NSDictionary")],
3253 vec![Type::SignedInt],
3254 vec![Type::String("NSNumber")],
3255 vec![Type::String("NSValue")],
3256 vec![Type::EmbeddedData],
3257 vec![Type::SignedInt],
3258 ];
3259
3260 let expected_objects = vec![
3261 Archived::Object {
3262 class: 1,
3263 data: vec![
3264 vec![OutputData::Object(3)],
3265 vec![OutputData::SignedInteger(1), OutputData::UnsignedInteger(9)], vec![OutputData::Object(5)],
3267 ],
3268 },
3269 Archived::Class(Class {
3270 name_index: 1,
3271 version: 0,
3272 parent_index: Some(2),
3273 }),
3274 Archived::Class(Class {
3275 name_index: 2,
3276 version: 0,
3277 parent_index: None,
3278 }),
3279 Archived::Object {
3280 class: 4,
3281 data: vec![vec![OutputData::String("Big small")]], },
3283 Archived::Class(Class {
3284 name_index: 3,
3285 version: 1,
3286 parent_index: Some(2),
3287 }),
3288 Archived::Object {
3289 class: 6,
3290 data: vec![
3291 vec![OutputData::SignedInteger(2)],
3292 vec![OutputData::Object(7)],
3293 vec![OutputData::Object(8)],
3294 vec![OutputData::Object(12)],
3295 vec![OutputData::Object(13)],
3296 ],
3297 },
3298 Archived::Class(Class {
3299 name_index: 6,
3300 version: 0,
3301 parent_index: Some(2),
3302 }),
3303 Archived::Object {
3304 class: 4,
3305 data: vec![vec![OutputData::String(
3306 "__kIMBaseWritingDirectionAttributeName",
3307 )]],
3308 },
3309 Archived::Object {
3310 class: 9,
3311 data: vec![vec![OutputData::SignedInteger(-1)]],
3312 },
3313 Archived::Class(Class {
3314 name_index: 8,
3315 version: 0,
3316 parent_index: Some(10),
3317 }),
3318 Archived::Class(Class {
3319 name_index: 9,
3320 version: 0,
3321 parent_index: Some(2),
3322 }),
3323 Archived::Type(11),
3324 Archived::Object {
3325 class: 4,
3326 data: vec![vec![OutputData::String("__kIMMessagePartAttributeName")]],
3327 },
3328 Archived::Object {
3329 class: 9,
3330 data: vec![vec![OutputData::SignedInteger(0)]],
3331 },
3332 ];
3333
3334 assert_eq!(typedstream.type_table, expected_types);
3335 assert_eq!(typedstream.object_table, expected_objects);
3336 }
3337
3338 #[test]
3339 fn test_parse_text_long_message() {
3340 let typedstream_path = current_dir()
3341 .unwrap()
3342 .as_path()
3343 .join("src/test_data/LongMessage");
3344 let mut file = File::open(typedstream_path).unwrap();
3345 let mut bytes = vec![];
3346 file.read_to_end(&mut bytes).unwrap();
3347
3348 let mut typedstream = TypedStreamDeserializer::new(&bytes);
3349 let root = typedstream.oxidize().unwrap();
3350 println!("\nResults:");
3351 println!("Root object: {:x?}", typedstream.object_table[root]);
3352 print_resolved(typedstream.resolve_properties(root).unwrap(), 2);
3353
3354 println!("\nFound {:?} types:", typedstream.type_table.len());
3355 typedstream
3356 .type_table
3357 .iter()
3358 .enumerate()
3359 .for_each(|(idx, item)| println!("\t{idx}: {item:?}"));
3360
3361 println!("\nFound {:?} objects:", typedstream.object_table.len());
3362 typedstream
3363 .object_table
3364 .iter()
3365 .enumerate()
3366 .for_each(|(idx, item)| println!("\t{idx}: {item:?}"));
3367
3368 let expected_types = vec![
3369 vec![Type::Object],
3370 vec![Type::String("NSMutableAttributedString")],
3371 vec![Type::String("NSAttributedString")],
3372 vec![Type::String("NSObject")],
3373 vec![Type::String("NSMutableString")],
3374 vec![Type::String("NSString")],
3375 vec![Type::Utf8String],
3376 vec![Type::SignedInt, Type::UnsignedInt],
3377 vec![Type::String("NSDictionary")],
3378 vec![Type::SignedInt],
3379 vec![Type::String("NSNumber")],
3380 vec![Type::String("NSValue")],
3381 vec![Type::EmbeddedData],
3382 ];
3383
3384 let expected_objects = vec![
3385 Archived::Object {
3386 class: 1,
3387 data: vec![
3388 vec![OutputData::Object(4)],
3389 vec![
3390 OutputData::SignedInteger(1),
3391 OutputData::UnsignedInteger(2359),
3392 ],
3393 vec![OutputData::Object(7)],
3394 ],
3395 },
3396 Archived::Class(Class {
3397 name_index: 1,
3398 version: 0,
3399 parent_index: Some(2),
3400 }),
3401 Archived::Class(Class {
3402 name_index: 2,
3403 version: 0,
3404 parent_index: Some(3),
3405 }),
3406 Archived::Class(Class {
3407 name_index: 3,
3408 version: 0,
3409 parent_index: None,
3410 }),
3411 Archived::Object {
3412 class: 5,
3413 data: vec![vec![OutputData::String(
3414 "Sed nibh velit, sodales et facilisis ut, sodales id libero. Mauris nec venenatis lorem, ac vulputate lorem. Maecenas in faucibus dui. In hac habitasse platea dictumst. Integer commodo erat eu elit tincidunt malesuada. Ut tellus mi, eleifend a ligula vitae, eleifend malesuada nibh. Duis leo magna, porttitor eu viverra varius, laoreet eget urna. Duis faucibus eleifend pretium. Nulla nec orci rhoncus, tincidunt lorem non, viverra velit. Aliquam id tincidunt lacus, vel accumsan enim.\nProin id ultrices nunc. Integer id posuere tellus. Donec vitae lacinia elit. In diam est, scelerisque non lacus ultrices, consequat hendrerit ex. Proin ut felis mi. Fusce id ultrices mi. Duis sagittis justo quis sapien tincidunt faucibus. Suspendisse id feugiat risus, ac vestibulum neque. Sed sit amet mauris mauris.\nAenean pharetra, nisl eu maximus commodo, est leo volutpat tortor, sodales semper risus eros non lorem. Phasellus auctor erat quis ante tristique ultrices. Nam at eleifend ligula. Donec posuere lobortis ante quis pulvinar. Maecenas cursus nibh sit amet finibus ultrices. Etiam ut volutpat risus, in molestie velit. Curabitur ornare justo lacus, vitae consequat augue commodo eget. Praesent tincidunt, urna et posuere mattis, orci diam efficitur lorem, eu tincidunt tortor mi id velit. Morbi justo felis, placerat accumsan blandit vel, accumsan eu mauris. Aliquam mattis nisl sed pulvinar hendrerit. Fusce hendrerit fermentum tellus, sit amet lacinia ante viverra ac. Vivamus ultricies tristique congue. Aliquam varius, odio ut porta consectetur, justo est dignissim massa, id dapibus orci risus dignissim dolor. Aliquam viverra tincidunt neque vel euismod. Integer semper ultricies libero vel cursus. Vestibulum sapien eros, dictum id ultricies in, accumsan vel est.\nCurabitur et lacus quis mauris viverra accumsan a non dui. Donec efficitur ex vitae maximus facilisis. Suspendisse molestie lectus quis bibendum porta. Donec a tellus vehicula, iaculis libero non, tincidunt dolor. Curabitur sit amet felis quis magna euismod feugiat vel vitae magna. Proin tellus nunc, mollis quis ipsum ac, blandit tristique libero. Etiam sit amet hendrerit nisl. Mauris dapibus tortor vel enim interdum faucibus. Nulla facilisi. Nulla ut nulla sit amet leo accumsan convallis eget in tortor. Donec sit amet ullamcorper urna. Curabitur consectetur cursus sem nec accumsan.",
3415 )]],
3416 },
3417 Archived::Class(Class {
3418 name_index: 4,
3419 version: 1,
3420 parent_index: Some(6),
3421 }),
3422 Archived::Class(Class {
3423 name_index: 5,
3424 version: 1,
3425 parent_index: Some(3),
3426 }),
3427 Archived::Object {
3428 class: 8,
3429 data: vec![
3430 vec![OutputData::SignedInteger(1)],
3431 vec![OutputData::Object(9)],
3432 vec![OutputData::Object(10)],
3433 ],
3434 },
3435 Archived::Class(Class {
3436 name_index: 8,
3437 version: 0,
3438 parent_index: Some(3),
3439 }),
3440 Archived::Object {
3441 class: 6,
3442 data: vec![vec![OutputData::String("__kIMMessagePartAttributeName")]],
3443 },
3444 Archived::Object {
3445 class: 11,
3446 data: vec![vec![OutputData::SignedInteger(0)]],
3447 },
3448 Archived::Class(Class {
3449 name_index: 10,
3450 version: 0,
3451 parent_index: Some(12),
3452 }),
3453 Archived::Class(Class {
3454 name_index: 11,
3455 version: 0,
3456 parent_index: Some(3),
3457 }),
3458 Archived::Type(9),
3459 ];
3460
3461 assert_eq!(typedstream.type_table, expected_types);
3462 assert_eq!(typedstream.object_table, expected_objects);
3463 }
3464
3465 #[test]
3466 fn test_parse_text_mention() {
3467 let typedstream_path = current_dir()
3468 .unwrap()
3469 .as_path()
3470 .join("src/test_data/Mention");
3471 let mut file = File::open(typedstream_path).unwrap();
3472 let mut bytes = vec![];
3473 file.read_to_end(&mut bytes).unwrap();
3474
3475 let mut typedstream = TypedStreamDeserializer::new(&bytes);
3476 let root = typedstream.oxidize().unwrap();
3477 println!("\nResults:");
3478 println!("Root object: {:x?}", typedstream.object_table[root]);
3479 print_resolved(typedstream.resolve_properties(root).unwrap(), 2);
3480
3481 println!("\nFound {:?} types:", typedstream.type_table.len());
3482 typedstream
3483 .type_table
3484 .iter()
3485 .enumerate()
3486 .for_each(|(idx, item)| println!("\t{idx}: {item:?}"));
3487
3488 println!("\nFound {:?} objects:", typedstream.object_table.len());
3489 typedstream
3490 .object_table
3491 .iter()
3492 .enumerate()
3493 .for_each(|(idx, item)| println!("\t{idx}: {item:?}"));
3494
3495 let expected_types = vec![
3496 vec![Type::Object],
3497 vec![Type::String("NSMutableAttributedString")],
3498 vec![Type::String("NSAttributedString")],
3499 vec![Type::String("NSObject")],
3500 vec![Type::String("NSMutableString")],
3501 vec![Type::String("NSString")],
3502 vec![Type::Utf8String],
3503 vec![Type::SignedInt, Type::UnsignedInt],
3504 vec![Type::String("NSDictionary")],
3505 vec![Type::SignedInt],
3506 vec![Type::String("NSNumber")],
3507 vec![Type::String("NSValue")],
3508 vec![Type::EmbeddedData],
3509 ];
3510
3511 let expected_objects = vec![
3512 Archived::Object {
3513 class: 1,
3514 data: vec![
3515 vec![OutputData::Object(4)],
3516 vec![OutputData::SignedInteger(1), OutputData::UnsignedInteger(5)],
3517 vec![OutputData::Object(7)],
3518 vec![OutputData::SignedInteger(2), OutputData::UnsignedInteger(3)],
3519 vec![OutputData::Object(14)],
3520 vec![OutputData::SignedInteger(1), OutputData::UnsignedInteger(1)],
3521 ],
3522 },
3523 Archived::Class(Class {
3524 name_index: 1,
3525 version: 0,
3526 parent_index: Some(2),
3527 }),
3528 Archived::Class(Class {
3529 name_index: 2,
3530 version: 0,
3531 parent_index: Some(3),
3532 }),
3533 Archived::Class(Class {
3534 name_index: 3,
3535 version: 0,
3536 parent_index: None,
3537 }),
3538 Archived::Object {
3539 class: 5,
3540 data: vec![vec![OutputData::String("Test Dad ")]],
3541 },
3542 Archived::Class(Class {
3543 name_index: 4,
3544 version: 1,
3545 parent_index: Some(6),
3546 }),
3547 Archived::Class(Class {
3548 name_index: 5,
3549 version: 1,
3550 parent_index: Some(3),
3551 }),
3552 Archived::Object {
3553 class: 8,
3554 data: vec![
3555 vec![OutputData::SignedInteger(1)],
3556 vec![OutputData::Object(9)],
3557 vec![OutputData::Object(10)],
3558 ],
3559 },
3560 Archived::Class(Class {
3561 name_index: 8,
3562 version: 0,
3563 parent_index: Some(3),
3564 }),
3565 Archived::Object {
3566 class: 6,
3567 data: vec![vec![OutputData::String("__kIMMessagePartAttributeName")]],
3568 },
3569 Archived::Object {
3570 class: 11,
3571 data: vec![vec![OutputData::SignedInteger(0)]],
3572 },
3573 Archived::Class(Class {
3574 name_index: 10,
3575 version: 0,
3576 parent_index: Some(12),
3577 }),
3578 Archived::Class(Class {
3579 name_index: 11,
3580 version: 0,
3581 parent_index: Some(3),
3582 }),
3583 Archived::Type(9),
3584 Archived::Object {
3585 class: 8,
3586 data: vec![
3587 vec![OutputData::SignedInteger(2)],
3588 vec![OutputData::Object(15)],
3589 vec![OutputData::Object(16)],
3590 vec![OutputData::Object(17)],
3591 vec![OutputData::Object(10)],
3592 ],
3593 },
3594 Archived::Object {
3595 class: 6,
3596 data: vec![vec![OutputData::String("__kIMMentionConfirmedMention")]],
3597 },
3598 Archived::Object {
3599 class: 6,
3600 data: vec![vec![OutputData::String("+15558675309")]],
3601 },
3602 Archived::Object {
3603 class: 6,
3604 data: vec![vec![OutputData::String("__kIMMessagePartAttributeName")]],
3605 },
3606 ];
3607
3608 assert_eq!(typedstream.type_table, expected_types);
3609 assert_eq!(typedstream.object_table, expected_objects);
3610 }
3611
3612 #[test]
3613 fn test_parse_text_multi_attachment() {
3614 let typedstream_path = current_dir()
3615 .unwrap()
3616 .as_path()
3617 .join("src/test_data/MultiAttachment");
3618 let mut file = File::open(typedstream_path).unwrap();
3619 let mut bytes = vec![];
3620 file.read_to_end(&mut bytes).unwrap();
3621
3622 let mut typedstream = TypedStreamDeserializer::new(&bytes);
3623 let root = typedstream.oxidize().unwrap();
3624 println!("\nResults:");
3625 println!("Root object: {:x?}", typedstream.object_table[root]);
3626 print_resolved(typedstream.resolve_properties(root).unwrap(), 2);
3627
3628 println!("\nFound {:?} types:", typedstream.type_table.len());
3629 typedstream
3630 .type_table
3631 .iter()
3632 .enumerate()
3633 .for_each(|(idx, item)| println!("\t{idx}: {item:?}"));
3634
3635 println!("\nFound {:?} objects:", typedstream.object_table.len());
3636 typedstream
3637 .object_table
3638 .iter()
3639 .enumerate()
3640 .for_each(|(idx, item)| println!("\t{idx}: {item:?}"));
3641
3642 let expected_types = vec![
3643 vec![Type::Object],
3644 vec![Type::String("NSMutableAttributedString")],
3645 vec![Type::String("NSAttributedString")],
3646 vec![Type::String("NSObject")],
3647 vec![Type::String("NSMutableString")],
3648 vec![Type::String("NSString")],
3649 vec![Type::Utf8String],
3650 vec![Type::SignedInt, Type::UnsignedInt],
3651 vec![Type::String("NSDictionary")],
3652 vec![Type::SignedInt],
3653 vec![Type::String("NSNumber")],
3654 vec![Type::String("NSValue")],
3655 vec![Type::EmbeddedData],
3656 vec![Type::SignedInt],
3657 ];
3658
3659 let expected_objects = vec![
3660 Archived::Object {
3661 class: 1,
3662 data: vec![
3663 vec![OutputData::Object(4)],
3664 vec![OutputData::SignedInteger(1), OutputData::UnsignedInteger(1)],
3665 vec![OutputData::Object(7)],
3666 vec![OutputData::SignedInteger(2), OutputData::UnsignedInteger(1)],
3667 vec![OutputData::Object(18)],
3668 vec![OutputData::SignedInteger(3), OutputData::UnsignedInteger(1)],
3669 vec![OutputData::Object(21)],
3670 vec![OutputData::SignedInteger(4), OutputData::UnsignedInteger(1)],
3671 vec![OutputData::Object(26)],
3672 vec![OutputData::SignedInteger(5), OutputData::UnsignedInteger(1)],
3673 vec![OutputData::Object(29)],
3674 vec![OutputData::SignedInteger(6), OutputData::UnsignedInteger(1)],
3675 vec![OutputData::Object(32)],
3676 vec![OutputData::SignedInteger(7), OutputData::UnsignedInteger(1)],
3677 vec![OutputData::Object(35)],
3678 vec![OutputData::SignedInteger(8), OutputData::UnsignedInteger(1)],
3679 vec![OutputData::Object(38)],
3680 vec![OutputData::SignedInteger(9), OutputData::UnsignedInteger(1)],
3681 vec![OutputData::Object(41)],
3682 vec![
3683 OutputData::SignedInteger(10),
3684 OutputData::UnsignedInteger(1),
3685 ],
3686 vec![OutputData::Object(44)],
3687 vec![
3688 OutputData::SignedInteger(11),
3689 OutputData::UnsignedInteger(1),
3690 ],
3691 vec![OutputData::Object(47)],
3692 vec![
3693 OutputData::SignedInteger(12),
3694 OutputData::UnsignedInteger(1),
3695 ],
3696 vec![OutputData::Object(50)],
3697 vec![
3698 OutputData::SignedInteger(13),
3699 OutputData::UnsignedInteger(1),
3700 ],
3701 vec![OutputData::Object(53)],
3702 vec![
3703 OutputData::SignedInteger(14),
3704 OutputData::UnsignedInteger(1),
3705 ],
3706 vec![OutputData::Object(56)],
3707 vec![
3708 OutputData::SignedInteger(15),
3709 OutputData::UnsignedInteger(1),
3710 ],
3711 vec![OutputData::Object(59)],
3712 vec![
3713 OutputData::SignedInteger(16),
3714 OutputData::UnsignedInteger(1),
3715 ],
3716 vec![OutputData::Object(62)],
3717 vec![
3718 OutputData::SignedInteger(17),
3719 OutputData::UnsignedInteger(1),
3720 ],
3721 vec![OutputData::Object(65)],
3722 vec![
3723 OutputData::SignedInteger(18),
3724 OutputData::UnsignedInteger(1),
3725 ],
3726 vec![OutputData::Object(68)],
3727 vec![
3728 OutputData::SignedInteger(19),
3729 OutputData::UnsignedInteger(1),
3730 ],
3731 vec![OutputData::Object(71)],
3732 ],
3733 },
3734 Archived::Class(Class {
3735 name_index: 1,
3736 version: 0,
3737 parent_index: Some(2),
3738 }),
3739 Archived::Class(Class {
3740 name_index: 2,
3741 version: 0,
3742 parent_index: Some(3),
3743 }),
3744 Archived::Class(Class {
3745 name_index: 3,
3746 version: 0,
3747 parent_index: None,
3748 }),
3749 Archived::Object {
3750 class: 5,
3751 data: vec![vec![OutputData::String("")]],
3752 },
3753 Archived::Class(Class {
3754 name_index: 4,
3755 version: 1,
3756 parent_index: Some(6),
3757 }),
3758 Archived::Class(Class {
3759 name_index: 5,
3760 version: 1,
3761 parent_index: Some(3),
3762 }),
3763 Archived::Object {
3764 class: 8,
3765 data: vec![
3766 vec![OutputData::SignedInteger(3)],
3767 vec![OutputData::Object(9)],
3768 vec![OutputData::Object(10)],
3769 vec![OutputData::Object(14)],
3770 vec![OutputData::Object(15)],
3771 vec![OutputData::Object(16)],
3772 vec![OutputData::Object(17)],
3773 ],
3774 },
3775 Archived::Class(Class {
3776 name_index: 8,
3777 version: 0,
3778 parent_index: Some(3),
3779 }),
3780 Archived::Object {
3781 class: 6,
3782 data: vec![vec![OutputData::String(
3783 "__kIMBaseWritingDirectionAttributeName",
3784 )]],
3785 },
3786 Archived::Object {
3787 class: 11,
3788 data: vec![vec![OutputData::SignedInteger(-1)]],
3789 },
3790 Archived::Class(Class {
3791 name_index: 10,
3792 version: 0,
3793 parent_index: Some(12),
3794 }),
3795 Archived::Class(Class {
3796 name_index: 11,
3797 version: 0,
3798 parent_index: Some(3),
3799 }),
3800 Archived::Type(13),
3801 Archived::Object {
3802 class: 6,
3803 data: vec![vec![OutputData::String("__kIMMessagePartAttributeName")]],
3804 },
3805 Archived::Object {
3806 class: 11,
3807 data: vec![vec![OutputData::SignedInteger(0)]],
3808 },
3809 Archived::Object {
3810 class: 6,
3811 data: vec![vec![OutputData::String(
3812 "__kIMFileTransferGUIDAttributeName",
3813 )]],
3814 },
3815 Archived::Object {
3816 class: 6,
3817 data: vec![vec![OutputData::String(
3818 "at_0_48B9C973-3466-438C-BE72-E5B498D30772",
3819 )]],
3820 },
3821 Archived::Object {
3822 class: 8,
3823 data: vec![
3824 vec![OutputData::SignedInteger(3)],
3825 vec![OutputData::Object(9)],
3826 vec![OutputData::Object(10)],
3827 vec![OutputData::Object(14)],
3828 vec![OutputData::Object(19)],
3829 vec![OutputData::Object(16)],
3830 vec![OutputData::Object(20)],
3831 ],
3832 },
3833 Archived::Object {
3834 class: 11,
3835 data: vec![vec![OutputData::SignedInteger(1)]],
3836 },
3837 Archived::Object {
3838 class: 6,
3839 data: vec![vec![OutputData::String(
3840 "at_1_48B9C973-3466-438C-BE72-E5B498D30772",
3841 )]],
3842 },
3843 Archived::Object {
3844 class: 8,
3845 data: vec![
3846 vec![OutputData::SignedInteger(3)],
3847 vec![OutputData::Object(22)],
3848 vec![OutputData::Object(10)],
3849 vec![OutputData::Object(23)],
3850 vec![OutputData::Object(24)],
3851 vec![OutputData::Object(16)],
3852 vec![OutputData::Object(25)],
3853 ],
3854 },
3855 Archived::Object {
3856 class: 6,
3857 data: vec![vec![OutputData::String(
3858 "__kIMBaseWritingDirectionAttributeName",
3859 )]],
3860 },
3861 Archived::Object {
3862 class: 6,
3863 data: vec![vec![OutputData::String("__kIMMessagePartAttributeName")]],
3864 },
3865 Archived::Object {
3866 class: 11,
3867 data: vec![vec![OutputData::SignedInteger(2)]],
3868 },
3869 Archived::Object {
3870 class: 6,
3871 data: vec![vec![OutputData::String(
3872 "at_2_48B9C973-3466-438C-BE72-E5B498D30772",
3873 )]],
3874 },
3875 Archived::Object {
3876 class: 8,
3877 data: vec![
3878 vec![OutputData::SignedInteger(3)],
3879 vec![OutputData::Object(9)],
3880 vec![OutputData::Object(10)],
3881 vec![OutputData::Object(14)],
3882 vec![OutputData::Object(27)],
3883 vec![OutputData::Object(16)],
3884 vec![OutputData::Object(28)],
3885 ],
3886 },
3887 Archived::Object {
3888 class: 11,
3889 data: vec![vec![OutputData::SignedInteger(3)]],
3890 },
3891 Archived::Object {
3892 class: 6,
3893 data: vec![vec![OutputData::String(
3894 "at_3_48B9C973-3466-438C-BE72-E5B498D30772",
3895 )]],
3896 },
3897 Archived::Object {
3898 class: 8,
3899 data: vec![
3900 vec![OutputData::SignedInteger(3)],
3901 vec![OutputData::Object(9)],
3902 vec![OutputData::Object(10)],
3903 vec![OutputData::Object(14)],
3904 vec![OutputData::Object(30)],
3905 vec![OutputData::Object(16)],
3906 vec![OutputData::Object(31)],
3907 ],
3908 },
3909 Archived::Object {
3910 class: 11,
3911 data: vec![vec![OutputData::SignedInteger(4)]],
3912 },
3913 Archived::Object {
3914 class: 6,
3915 data: vec![vec![OutputData::String(
3916 "at_4_48B9C973-3466-438C-BE72-E5B498D30772",
3917 )]],
3918 },
3919 Archived::Object {
3920 class: 8,
3921 data: vec![
3922 vec![OutputData::SignedInteger(3)],
3923 vec![OutputData::Object(9)],
3924 vec![OutputData::Object(10)],
3925 vec![OutputData::Object(14)],
3926 vec![OutputData::Object(33)],
3927 vec![OutputData::Object(16)],
3928 vec![OutputData::Object(34)],
3929 ],
3930 },
3931 Archived::Object {
3932 class: 11,
3933 data: vec![vec![OutputData::SignedInteger(5)]],
3934 },
3935 Archived::Object {
3936 class: 6,
3937 data: vec![vec![OutputData::String(
3938 "at_5_48B9C973-3466-438C-BE72-E5B498D30772",
3939 )]],
3940 },
3941 Archived::Object {
3942 class: 8,
3943 data: vec![
3944 vec![OutputData::SignedInteger(3)],
3945 vec![OutputData::Object(9)],
3946 vec![OutputData::Object(10)],
3947 vec![OutputData::Object(14)],
3948 vec![OutputData::Object(36)],
3949 vec![OutputData::Object(16)],
3950 vec![OutputData::Object(37)],
3951 ],
3952 },
3953 Archived::Object {
3954 class: 11,
3955 data: vec![vec![OutputData::SignedInteger(6)]],
3956 },
3957 Archived::Object {
3958 class: 6,
3959 data: vec![vec![OutputData::String(
3960 "at_6_48B9C973-3466-438C-BE72-E5B498D30772",
3961 )]],
3962 },
3963 Archived::Object {
3964 class: 8,
3965 data: vec![
3966 vec![OutputData::SignedInteger(3)],
3967 vec![OutputData::Object(9)],
3968 vec![OutputData::Object(10)],
3969 vec![OutputData::Object(14)],
3970 vec![OutputData::Object(39)],
3971 vec![OutputData::Object(16)],
3972 vec![OutputData::Object(40)],
3973 ],
3974 },
3975 Archived::Object {
3976 class: 11,
3977 data: vec![vec![OutputData::SignedInteger(7)]],
3978 },
3979 Archived::Object {
3980 class: 6,
3981 data: vec![vec![OutputData::String(
3982 "at_7_48B9C973-3466-438C-BE72-E5B498D30772",
3983 )]],
3984 },
3985 Archived::Object {
3986 class: 8,
3987 data: vec![
3988 vec![OutputData::SignedInteger(3)],
3989 vec![OutputData::Object(9)],
3990 vec![OutputData::Object(10)],
3991 vec![OutputData::Object(14)],
3992 vec![OutputData::Object(42)],
3993 vec![OutputData::Object(16)],
3994 vec![OutputData::Object(43)],
3995 ],
3996 },
3997 Archived::Object {
3998 class: 11,
3999 data: vec![vec![OutputData::SignedInteger(8)]],
4000 },
4001 Archived::Object {
4002 class: 6,
4003 data: vec![vec![OutputData::String(
4004 "at_8_48B9C973-3466-438C-BE72-E5B498D30772",
4005 )]],
4006 },
4007 Archived::Object {
4008 class: 8,
4009 data: vec![
4010 vec![OutputData::SignedInteger(3)],
4011 vec![OutputData::Object(9)],
4012 vec![OutputData::Object(10)],
4013 vec![OutputData::Object(14)],
4014 vec![OutputData::Object(45)],
4015 vec![OutputData::Object(16)],
4016 vec![OutputData::Object(46)],
4017 ],
4018 },
4019 Archived::Object {
4020 class: 11,
4021 data: vec![vec![OutputData::SignedInteger(9)]],
4022 },
4023 Archived::Object {
4024 class: 6,
4025 data: vec![vec![OutputData::String(
4026 "at_9_48B9C973-3466-438C-BE72-E5B498D30772",
4027 )]],
4028 },
4029 Archived::Object {
4030 class: 8,
4031 data: vec![
4032 vec![OutputData::SignedInteger(3)],
4033 vec![OutputData::Object(9)],
4034 vec![OutputData::Object(10)],
4035 vec![OutputData::Object(14)],
4036 vec![OutputData::Object(48)],
4037 vec![OutputData::Object(16)],
4038 vec![OutputData::Object(49)],
4039 ],
4040 },
4041 Archived::Object {
4042 class: 11,
4043 data: vec![vec![OutputData::SignedInteger(10)]],
4044 },
4045 Archived::Object {
4046 class: 6,
4047 data: vec![vec![OutputData::String(
4048 "at_10_48B9C973-3466-438C-BE72-E5B498D30772",
4049 )]],
4050 },
4051 Archived::Object {
4052 class: 8,
4053 data: vec![
4054 vec![OutputData::SignedInteger(3)],
4055 vec![OutputData::Object(9)],
4056 vec![OutputData::Object(10)],
4057 vec![OutputData::Object(14)],
4058 vec![OutputData::Object(51)],
4059 vec![OutputData::Object(16)],
4060 vec![OutputData::Object(52)],
4061 ],
4062 },
4063 Archived::Object {
4064 class: 11,
4065 data: vec![vec![OutputData::SignedInteger(11)]],
4066 },
4067 Archived::Object {
4068 class: 6,
4069 data: vec![vec![OutputData::String(
4070 "at_11_48B9C973-3466-438C-BE72-E5B498D30772",
4071 )]],
4072 },
4073 Archived::Object {
4074 class: 8,
4075 data: vec![
4076 vec![OutputData::SignedInteger(3)],
4077 vec![OutputData::Object(9)],
4078 vec![OutputData::Object(10)],
4079 vec![OutputData::Object(14)],
4080 vec![OutputData::Object(54)],
4081 vec![OutputData::Object(16)],
4082 vec![OutputData::Object(55)],
4083 ],
4084 },
4085 Archived::Object {
4086 class: 11,
4087 data: vec![vec![OutputData::SignedInteger(12)]],
4088 },
4089 Archived::Object {
4090 class: 6,
4091 data: vec![vec![OutputData::String(
4092 "at_12_48B9C973-3466-438C-BE72-E5B498D30772",
4093 )]],
4094 },
4095 Archived::Object {
4096 class: 8,
4097 data: vec![
4098 vec![OutputData::SignedInteger(3)],
4099 vec![OutputData::Object(9)],
4100 vec![OutputData::Object(10)],
4101 vec![OutputData::Object(14)],
4102 vec![OutputData::Object(57)],
4103 vec![OutputData::Object(16)],
4104 vec![OutputData::Object(58)],
4105 ],
4106 },
4107 Archived::Object {
4108 class: 11,
4109 data: vec![vec![OutputData::SignedInteger(13)]],
4110 },
4111 Archived::Object {
4112 class: 6,
4113 data: vec![vec![OutputData::String(
4114 "at_13_48B9C973-3466-438C-BE72-E5B498D30772",
4115 )]],
4116 },
4117 Archived::Object {
4118 class: 8,
4119 data: vec![
4120 vec![OutputData::SignedInteger(3)],
4121 vec![OutputData::Object(9)],
4122 vec![OutputData::Object(10)],
4123 vec![OutputData::Object(14)],
4124 vec![OutputData::Object(60)],
4125 vec![OutputData::Object(16)],
4126 vec![OutputData::Object(61)],
4127 ],
4128 },
4129 Archived::Object {
4130 class: 11,
4131 data: vec![vec![OutputData::SignedInteger(14)]],
4132 },
4133 Archived::Object {
4134 class: 6,
4135 data: vec![vec![OutputData::String(
4136 "at_14_48B9C973-3466-438C-BE72-E5B498D30772",
4137 )]],
4138 },
4139 Archived::Object {
4140 class: 8,
4141 data: vec![
4142 vec![OutputData::SignedInteger(3)],
4143 vec![OutputData::Object(9)],
4144 vec![OutputData::Object(10)],
4145 vec![OutputData::Object(14)],
4146 vec![OutputData::Object(63)],
4147 vec![OutputData::Object(16)],
4148 vec![OutputData::Object(64)],
4149 ],
4150 },
4151 Archived::Object {
4152 class: 11,
4153 data: vec![vec![OutputData::SignedInteger(15)]],
4154 },
4155 Archived::Object {
4156 class: 6,
4157 data: vec![vec![OutputData::String(
4158 "at_15_48B9C973-3466-438C-BE72-E5B498D30772",
4159 )]],
4160 },
4161 Archived::Object {
4162 class: 8,
4163 data: vec![
4164 vec![OutputData::SignedInteger(3)],
4165 vec![OutputData::Object(9)],
4166 vec![OutputData::Object(10)],
4167 vec![OutputData::Object(14)],
4168 vec![OutputData::Object(66)],
4169 vec![OutputData::Object(16)],
4170 vec![OutputData::Object(67)],
4171 ],
4172 },
4173 Archived::Object {
4174 class: 11,
4175 data: vec![vec![OutputData::SignedInteger(16)]],
4176 },
4177 Archived::Object {
4178 class: 6,
4179 data: vec![vec![OutputData::String(
4180 "at_16_48B9C973-3466-438C-BE72-E5B498D30772",
4181 )]],
4182 },
4183 Archived::Object {
4184 class: 8,
4185 data: vec![
4186 vec![OutputData::SignedInteger(3)],
4187 vec![OutputData::Object(9)],
4188 vec![OutputData::Object(10)],
4189 vec![OutputData::Object(14)],
4190 vec![OutputData::Object(69)],
4191 vec![OutputData::Object(16)],
4192 vec![OutputData::Object(70)],
4193 ],
4194 },
4195 Archived::Object {
4196 class: 11,
4197 data: vec![vec![OutputData::SignedInteger(17)]],
4198 },
4199 Archived::Object {
4200 class: 6,
4201 data: vec![vec![OutputData::String(
4202 "at_17_48B9C973-3466-438C-BE72-E5B498D30772",
4203 )]],
4204 },
4205 Archived::Object {
4206 class: 8,
4207 data: vec![
4208 vec![OutputData::SignedInteger(3)],
4209 vec![OutputData::Object(9)],
4210 vec![OutputData::Object(10)],
4211 vec![OutputData::Object(14)],
4212 vec![OutputData::Object(72)],
4213 vec![OutputData::Object(16)],
4214 vec![OutputData::Object(73)],
4215 ],
4216 },
4217 Archived::Object {
4218 class: 11,
4219 data: vec![vec![OutputData::SignedInteger(18)]],
4220 },
4221 Archived::Object {
4222 class: 6,
4223 data: vec![vec![OutputData::String(
4224 "at_18_48B9C973-3466-438C-BE72-E5B498D30772",
4225 )]],
4226 },
4227 ];
4228
4229 assert_eq!(typedstream.type_table, expected_types);
4230 assert_eq!(typedstream.object_table, expected_objects);
4231 }
4232
4233 #[test]
4234 fn test_parse_text_multi_part() {
4235 let typedstream_path = current_dir()
4236 .unwrap()
4237 .as_path()
4238 .join("src/test_data/MultiPart");
4239 let mut file = File::open(typedstream_path).unwrap();
4240 let mut bytes = vec![];
4241 file.read_to_end(&mut bytes).unwrap();
4242
4243 let mut typedstream = TypedStreamDeserializer::new(&bytes);
4244 let root = typedstream.oxidize().unwrap();
4245 println!("\nResults:");
4246 println!("Root object: {:x?}", typedstream.object_table[root]);
4247 print_resolved(typedstream.resolve_properties(root).unwrap(), 2);
4248
4249 println!("\nFound {:?} types:", typedstream.type_table.len());
4250 typedstream
4251 .type_table
4252 .iter()
4253 .enumerate()
4254 .for_each(|(idx, item)| println!("\t{idx}: {item:?}"));
4255
4256 println!("\nFound {:?} objects:", typedstream.object_table.len());
4257 typedstream
4258 .object_table
4259 .iter()
4260 .enumerate()
4261 .for_each(|(idx, item)| println!("\t{idx}: {item:?}"));
4262
4263 let expected_types = vec![
4264 vec![Type::Object],
4265 vec![Type::String("NSMutableAttributedString")],
4266 vec![Type::String("NSAttributedString")],
4267 vec![Type::String("NSObject")],
4268 vec![Type::String("NSMutableString")],
4269 vec![Type::String("NSString")],
4270 vec![Type::Utf8String],
4271 vec![Type::SignedInt, Type::UnsignedInt],
4272 vec![Type::String("NSDictionary")],
4273 vec![Type::SignedInt],
4274 vec![Type::String("NSNumber")],
4275 vec![Type::String("NSValue")],
4276 vec![Type::EmbeddedData],
4277 ];
4278
4279 let expected_objects = vec![
4280 Archived::Object {
4281 class: 1,
4282 data: vec![
4283 vec![OutputData::Object(4)],
4284 vec![OutputData::SignedInteger(1), OutputData::UnsignedInteger(1)],
4285 vec![OutputData::Object(7)],
4286 vec![OutputData::SignedInteger(2), OutputData::UnsignedInteger(6)],
4287 vec![OutputData::Object(16)],
4288 vec![OutputData::SignedInteger(3), OutputData::UnsignedInteger(1)],
4289 vec![OutputData::Object(19)],
4290 vec![OutputData::SignedInteger(4), OutputData::UnsignedInteger(7)],
4291 vec![OutputData::Object(22)],
4292 vec![OutputData::SignedInteger(5), OutputData::UnsignedInteger(1)],
4293 vec![OutputData::Object(24)],
4294 vec![OutputData::SignedInteger(6), OutputData::UnsignedInteger(6)],
4295 vec![OutputData::Object(27)],
4296 ],
4297 },
4298 Archived::Class(Class {
4299 name_index: 1,
4300 version: 0,
4301 parent_index: Some(2),
4302 }),
4303 Archived::Class(Class {
4304 name_index: 2,
4305 version: 0,
4306 parent_index: Some(3),
4307 }),
4308 Archived::Class(Class {
4309 name_index: 3,
4310 version: 0,
4311 parent_index: None,
4312 }),
4313 Archived::Object {
4314 class: 5,
4315 data: vec![vec![OutputData::String("test 1test 2 test 3")]],
4316 },
4317 Archived::Class(Class {
4318 name_index: 4,
4319 version: 1,
4320 parent_index: Some(6),
4321 }),
4322 Archived::Class(Class {
4323 name_index: 5,
4324 version: 1,
4325 parent_index: Some(3),
4326 }),
4327 Archived::Object {
4328 class: 8,
4329 data: vec![
4330 vec![OutputData::SignedInteger(2)],
4331 vec![OutputData::Object(9)],
4332 vec![OutputData::Object(10)],
4333 vec![OutputData::Object(11)],
4334 vec![OutputData::Object(12)],
4335 ],
4336 },
4337 Archived::Class(Class {
4338 name_index: 8,
4339 version: 0,
4340 parent_index: Some(3),
4341 }),
4342 Archived::Object {
4343 class: 6,
4344 data: vec![vec![OutputData::String(
4345 "__kIMFileTransferGUIDAttributeName",
4346 )]],
4347 },
4348 Archived::Object {
4349 class: 6,
4350 data: vec![vec![OutputData::String(
4351 "at_0_F0668F79-20C2-49C9-A87F-1B007ABB0CED",
4352 )]],
4353 },
4354 Archived::Object {
4355 class: 6,
4356 data: vec![vec![OutputData::String("__kIMMessagePartAttributeName")]],
4357 },
4358 Archived::Object {
4359 class: 13,
4360 data: vec![vec![OutputData::SignedInteger(0)]],
4361 },
4362 Archived::Class(Class {
4363 name_index: 10,
4364 version: 0,
4365 parent_index: Some(14),
4366 }),
4367 Archived::Class(Class {
4368 name_index: 11,
4369 version: 0,
4370 parent_index: Some(3),
4371 }),
4372 Archived::Type(9),
4373 Archived::Object {
4374 class: 8,
4375 data: vec![
4376 vec![OutputData::SignedInteger(1)],
4377 vec![OutputData::Object(17)],
4378 vec![OutputData::Object(18)],
4379 ],
4380 },
4381 Archived::Object {
4382 class: 6,
4383 data: vec![vec![OutputData::String("__kIMMessagePartAttributeName")]],
4384 },
4385 Archived::Object {
4386 class: 13,
4387 data: vec![vec![OutputData::SignedInteger(1)]],
4388 },
4389 Archived::Object {
4390 class: 8,
4391 data: vec![
4392 vec![OutputData::SignedInteger(2)],
4393 vec![OutputData::Object(9)],
4394 vec![OutputData::Object(20)],
4395 vec![OutputData::Object(11)],
4396 vec![OutputData::Object(21)],
4397 ],
4398 },
4399 Archived::Object {
4400 class: 6,
4401 data: vec![vec![OutputData::String(
4402 "at_2_F0668F79-20C2-49C9-A87F-1B007ABB0CED",
4403 )]],
4404 },
4405 Archived::Object {
4406 class: 13,
4407 data: vec![vec![OutputData::SignedInteger(2)]],
4408 },
4409 Archived::Object {
4410 class: 8,
4411 data: vec![
4412 vec![OutputData::SignedInteger(1)],
4413 vec![OutputData::Object(11)],
4414 vec![OutputData::Object(23)],
4415 ],
4416 },
4417 Archived::Object {
4418 class: 13,
4419 data: vec![vec![OutputData::SignedInteger(3)]],
4420 },
4421 Archived::Object {
4422 class: 8,
4423 data: vec![
4424 vec![OutputData::SignedInteger(2)],
4425 vec![OutputData::Object(9)],
4426 vec![OutputData::Object(25)],
4427 vec![OutputData::Object(11)],
4428 vec![OutputData::Object(26)],
4429 ],
4430 },
4431 Archived::Object {
4432 class: 6,
4433 data: vec![vec![OutputData::String(
4434 "at_4_F0668F79-20C2-49C9-A87F-1B007ABB0CED",
4435 )]],
4436 },
4437 Archived::Object {
4438 class: 13,
4439 data: vec![vec![OutputData::SignedInteger(4)]],
4440 },
4441 Archived::Object {
4442 class: 8,
4443 data: vec![
4444 vec![OutputData::SignedInteger(1)],
4445 vec![OutputData::Object(11)],
4446 vec![OutputData::Object(28)],
4447 ],
4448 },
4449 Archived::Object {
4450 class: 13,
4451 data: vec![vec![OutputData::SignedInteger(5)]],
4452 },
4453 ];
4454
4455 assert_eq!(typedstream.type_table, expected_types);
4456 assert_eq!(typedstream.object_table, expected_objects);
4457 }
4458
4459 #[test]
4460 fn test_parse_text_multi_part_with_deleted() {
4461 let typedstream_path = current_dir()
4462 .unwrap()
4463 .as_path()
4464 .join("src/test_data/MultiPartWithDeleted");
4465 let mut file = File::open(typedstream_path).unwrap();
4466 let mut bytes = vec![];
4467 file.read_to_end(&mut bytes).unwrap();
4468
4469 let mut typedstream = TypedStreamDeserializer::new(&bytes);
4470 let root = typedstream.oxidize().unwrap();
4471 println!("\nResults:");
4472 println!("Root object: {:x?}", typedstream.object_table[root]);
4473 print_resolved(typedstream.resolve_properties(root).unwrap(), 2);
4474
4475 println!("\nFound {:?} types:", typedstream.type_table.len());
4476 typedstream
4477 .type_table
4478 .iter()
4479 .enumerate()
4480 .for_each(|(idx, item)| println!("\t{idx}: {item:?}"));
4481
4482 println!("\nFound {:?} objects:", typedstream.object_table.len());
4483 typedstream
4484 .object_table
4485 .iter()
4486 .enumerate()
4487 .for_each(|(idx, item)| println!("\t{idx}: {item:?}"));
4488
4489 let expected_types = vec![
4490 vec![Type::Object],
4491 vec![Type::String("NSMutableAttributedString")],
4492 vec![Type::String("NSAttributedString")],
4493 vec![Type::String("NSObject")],
4494 vec![Type::String("NSMutableString")],
4495 vec![Type::String("NSString")],
4496 vec![Type::Utf8String],
4497 vec![Type::SignedInt, Type::UnsignedInt],
4498 vec![Type::String("NSDictionary")],
4499 vec![Type::SignedInt],
4500 vec![Type::String("NSNumber")],
4501 vec![Type::String("NSValue")],
4502 vec![Type::EmbeddedData],
4503 ];
4504
4505 let expected_objects = vec![
4506 Archived::Object {
4507 class: 1,
4508 data: vec![
4509 vec![OutputData::Object(4)],
4510 vec![
4511 OutputData::SignedInteger(1),
4512 OutputData::UnsignedInteger(28),
4513 ],
4514 vec![OutputData::Object(7)],
4515 vec![OutputData::SignedInteger(2), OutputData::UnsignedInteger(1)],
4516 vec![OutputData::Object(14)],
4517 vec![
4518 OutputData::SignedInteger(3),
4519 OutputData::UnsignedInteger(32),
4520 ],
4521 vec![OutputData::Object(19)],
4522 ],
4523 },
4524 Archived::Class(Class {
4525 name_index: 1,
4526 version: 0,
4527 parent_index: Some(2),
4528 }),
4529 Archived::Class(Class {
4530 name_index: 2,
4531 version: 0,
4532 parent_index: Some(3),
4533 }),
4534 Archived::Class(Class {
4535 name_index: 3,
4536 version: 0,
4537 parent_index: None,
4538 }),
4539 Archived::Object {
4540 class: 5,
4541 data: vec![vec![OutputData::String(
4542 "From arbitrary byte stream:\rTo native Rust data structures:\r",
4543 )]],
4544 },
4545 Archived::Class(Class {
4546 name_index: 4,
4547 version: 1,
4548 parent_index: Some(6),
4549 }),
4550 Archived::Class(Class {
4551 name_index: 5,
4552 version: 1,
4553 parent_index: Some(3),
4554 }),
4555 Archived::Object {
4556 class: 8,
4557 data: vec![
4558 vec![OutputData::SignedInteger(1)],
4559 vec![OutputData::Object(9)],
4560 vec![OutputData::Object(10)],
4561 ],
4562 },
4563 Archived::Class(Class {
4564 name_index: 8,
4565 version: 0,
4566 parent_index: Some(3),
4567 }),
4568 Archived::Object {
4569 class: 6,
4570 data: vec![vec![OutputData::String("__kIMMessagePartAttributeName")]],
4571 },
4572 Archived::Object {
4573 class: 11,
4574 data: vec![vec![OutputData::SignedInteger(0)]],
4575 },
4576 Archived::Class(Class {
4577 name_index: 10,
4578 version: 0,
4579 parent_index: Some(12),
4580 }),
4581 Archived::Class(Class {
4582 name_index: 11,
4583 version: 0,
4584 parent_index: Some(3),
4585 }),
4586 Archived::Type(9),
4587 Archived::Object {
4588 class: 8,
4589 data: vec![
4590 vec![OutputData::SignedInteger(2)],
4591 vec![OutputData::Object(15)],
4592 vec![OutputData::Object(16)],
4593 vec![OutputData::Object(17)],
4594 vec![OutputData::Object(18)],
4595 ],
4596 },
4597 Archived::Object {
4598 class: 6,
4599 data: vec![vec![OutputData::String(
4600 "__kIMFileTransferGUIDAttributeName",
4601 )]],
4602 },
4603 Archived::Object {
4604 class: 6,
4605 data: vec![vec![OutputData::String(
4606 "D0551D89-4E11-43D0-9A0E-06F19704E97B",
4607 )]],
4608 },
4609 Archived::Object {
4610 class: 6,
4611 data: vec![vec![OutputData::String("__kIMMessagePartAttributeName")]],
4612 },
4613 Archived::Object {
4614 class: 11,
4615 data: vec![vec![OutputData::SignedInteger(1)]],
4616 },
4617 Archived::Object {
4618 class: 8,
4619 data: vec![
4620 vec![OutputData::SignedInteger(1)],
4621 vec![OutputData::Object(20)],
4622 vec![OutputData::Object(21)],
4623 ],
4624 },
4625 Archived::Object {
4626 class: 6,
4627 data: vec![vec![OutputData::String("__kIMMessagePartAttributeName")]],
4628 },
4629 Archived::Object {
4630 class: 11,
4631 data: vec![vec![OutputData::SignedInteger(2)]],
4632 },
4633 ];
4634
4635 assert_eq!(typedstream.type_table, expected_types);
4636 assert_eq!(typedstream.object_table, expected_objects);
4637 }
4638
4639 #[test]
4640 fn test_parse_text_overlapping_format() {
4641 let typedstream_path = current_dir()
4642 .unwrap()
4643 .as_path()
4644 .join("src/test_data/OverlappingFormat");
4645 let mut file = File::open(typedstream_path).unwrap();
4646 let mut bytes = vec![];
4647 file.read_to_end(&mut bytes).unwrap();
4648
4649 let mut typedstream = TypedStreamDeserializer::new(&bytes);
4650 let root = typedstream.oxidize().unwrap();
4651 println!("\nResults:");
4652 println!("Root object: {:x?}", typedstream.object_table[root]);
4653 print_resolved(typedstream.resolve_properties(root).unwrap(), 2);
4654
4655 println!("\nFound {:?} types:", typedstream.type_table.len());
4656 typedstream
4657 .type_table
4658 .iter()
4659 .enumerate()
4660 .for_each(|(idx, item)| println!("\t{idx}: {item:?}"));
4661
4662 println!("\nFound {:?} objects:", typedstream.object_table.len());
4663 typedstream
4664 .object_table
4665 .iter()
4666 .enumerate()
4667 .for_each(|(idx, item)| println!("\t{idx}: {item:?}"));
4668
4669 let expected_types = vec![
4670 vec![Type::Object],
4671 vec![Type::String("NSMutableAttributedString")],
4672 vec![Type::String("NSAttributedString")],
4673 vec![Type::String("NSObject")],
4674 vec![Type::String("NSMutableString")],
4675 vec![Type::String("NSString")],
4676 vec![Type::Utf8String],
4677 vec![Type::SignedInt, Type::UnsignedInt],
4678 vec![Type::String("NSDictionary")],
4679 vec![Type::SignedInt],
4680 vec![Type::String("NSNumber")],
4681 vec![Type::String("NSValue")],
4682 vec![Type::EmbeddedData],
4683 vec![Type::SignedInt],
4684 vec![Type::String("NSData")],
4685 vec![Type::Array(820)],
4686 ];
4687
4688 let expected_objects = vec![
4689 Archived::Object {
4690 class: 1,
4691 data: vec![
4692 vec![OutputData::Object(4)],
4693 vec![OutputData::SignedInteger(1), OutputData::UnsignedInteger(1)],
4694 vec![OutputData::Object(7)],
4695 vec![OutputData::SignedInteger(2), OutputData::UnsignedInteger(1)],
4696 vec![OutputData::Object(22)],
4697 vec![OutputData::SignedInteger(3), OutputData::UnsignedInteger(2)],
4698 vec![OutputData::Object(23)],
4699 vec![OutputData::SignedInteger(2), OutputData::UnsignedInteger(1)],
4700 vec![OutputData::SignedInteger(4), OutputData::UnsignedInteger(2)],
4701 vec![OutputData::Object(25)],
4702 ],
4703 },
4704 Archived::Class(Class {
4705 name_index: 1,
4706 version: 0,
4707 parent_index: Some(2),
4708 }),
4709 Archived::Class(Class {
4710 name_index: 2,
4711 version: 0,
4712 parent_index: Some(3),
4713 }),
4714 Archived::Class(Class {
4715 name_index: 3,
4716 version: 0,
4717 parent_index: None,
4718 }),
4719 Archived::Object {
4720 class: 5,
4721 data: vec![vec![OutputData::String("8:00 pm")]],
4722 },
4723 Archived::Class(Class {
4724 name_index: 4,
4725 version: 1,
4726 parent_index: Some(6),
4727 }),
4728 Archived::Class(Class {
4729 name_index: 5,
4730 version: 1,
4731 parent_index: Some(3),
4732 }),
4733 Archived::Object {
4734 class: 8,
4735 data: vec![
4736 vec![OutputData::SignedInteger(4)],
4737 vec![OutputData::Object(9)],
4738 vec![OutputData::Object(10)],
4739 vec![OutputData::Object(14)],
4740 vec![OutputData::Object(15)],
4741 vec![OutputData::Object(17)],
4742 vec![OutputData::Object(18)],
4743 vec![OutputData::Object(19)],
4744 vec![OutputData::Object(20)],
4745 ],
4746 },
4747 Archived::Class(Class {
4748 name_index: 8,
4749 version: 0,
4750 parent_index: Some(3),
4751 }),
4752 Archived::Object {
4753 class: 6,
4754 data: vec![vec![OutputData::String("__kIMTextBoldAttributeName")]],
4755 },
4756 Archived::Object {
4757 class: 11,
4758 data: vec![vec![OutputData::SignedInteger(1)]],
4759 },
4760 Archived::Class(Class {
4761 name_index: 10,
4762 version: 0,
4763 parent_index: Some(12),
4764 }),
4765 Archived::Class(Class {
4766 name_index: 11,
4767 version: 0,
4768 parent_index: Some(3),
4769 }),
4770 Archived::Type(9),
4771 Archived::Object {
4772 class: 6,
4773 data: vec![vec![OutputData::String("__kIMMessagePartAttributeName")]],
4774 },
4775 Archived::Object {
4776 class: 11,
4777 data: vec![vec![OutputData::SignedInteger(0)]],
4778 },
4779 Archived::Type(13),
4780 Archived::Object {
4781 class: 6,
4782 data: vec![vec![OutputData::String(
4783 "__kIMBaseWritingDirectionAttributeName",
4784 )]],
4785 },
4786 Archived::Object {
4787 class: 11,
4788 data: vec![vec![OutputData::SignedInteger(-1)]],
4789 },
4790 Archived::Object {
4791 class: 6,
4792 data: vec![vec![OutputData::String("__kIMCalendarEventAttributeName")]],
4793 },
4794 Archived::Object {
4795 class: 21,
4796 data: vec![
4797 vec![OutputData::SignedInteger(820)],
4798 vec![OutputData::Array(&[
4799 98, 112, 108, 105, 115, 116, 48, 48, 212, 1, 2, 3, 4, 5, 6, 7, 12, 88, 36,
4800 118, 101, 114, 115, 105, 111, 110, 89, 36, 97, 114, 99, 104, 105, 118, 101,
4801 114, 84, 36, 116, 111, 112, 88, 36, 111, 98, 106, 101, 99, 116, 115, 18, 0,
4802 1, 134, 160, 95, 16, 15, 78, 83, 75, 101, 121, 101, 100, 65, 114, 99, 104,
4803 105, 118, 101, 114, 210, 8, 9, 10, 11, 87, 118, 101, 114, 115, 105, 111,
4804 110, 89, 100, 100, 45, 114, 101, 115, 117, 108, 116, 128, 27, 128, 1, 175,
4805 16, 28, 13, 14, 28, 36, 37, 38, 44, 45, 46, 53, 59, 26, 63, 64, 65, 68, 71,
4806 75, 81, 85, 86, 87, 88, 96, 100, 101, 102, 103, 85, 36, 110, 117, 108, 108,
4807 215, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 26, 82, 77, 83,
4808 86, 36, 99, 108, 97, 115, 115, 82, 65, 82, 81, 84, 81, 80, 82, 83, 82, 82,
4809 86, 78, 128, 6, 128, 16, 128, 2, 128, 7, 16, 1, 128, 8, 212, 29, 30, 31,
4810 16, 32, 33, 34, 35, 95, 16, 18, 78, 83, 46, 114, 97, 110, 103, 101, 118,
4811 97, 108, 46, 108, 101, 110, 103, 116, 104, 95, 16, 20, 78, 83, 46, 114, 97,
4812 110, 103, 101, 118, 97, 108, 46, 108, 111, 99, 97, 116, 105, 111, 110, 90,
4813 78, 83, 46, 115, 112, 101, 99, 105, 97, 108, 128, 3, 128, 4, 16, 4, 128, 5,
4814 16, 7, 16, 0, 210, 39, 40, 41, 42, 90, 36, 99, 108, 97, 115, 115, 110, 97,
4815 109, 101, 88, 36, 99, 108, 97, 115, 115, 101, 115, 87, 78, 83, 86, 97, 108,
4816 117, 101, 162, 41, 43, 88, 78, 83, 79, 98, 106, 101, 99, 116, 87, 56, 58,
4817 48, 48, 32, 112, 109, 84, 84, 105, 109, 101, 210, 47, 16, 48, 52, 90, 78,
4818 83, 46, 111, 98, 106, 101, 99, 116, 115, 163, 49, 50, 51, 128, 9, 128, 17,
4819 128, 22, 128, 15, 215, 15, 16, 17, 18, 19, 20, 21, 54, 23, 56, 57, 26, 58,
4820 26, 128, 12, 128, 16, 128, 10, 128, 13, 128, 14, 212, 29, 30, 31, 16, 60,
4821 33, 34, 35, 128, 11, 128, 4, 128, 5, 81, 56, 85, 72, 111, 117, 114, 115,
4822 210, 47, 16, 66, 52, 160, 128, 15, 210, 39, 40, 69, 70, 87, 78, 83, 65,
4823 114, 114, 97, 121, 162, 69, 43, 210, 39, 40, 72, 73, 95, 16, 15, 68, 68,
4824 83, 99, 97, 110, 110, 101, 114, 82, 101, 115, 117, 108, 116, 162, 74, 43,
4825 95, 16, 15, 68, 68, 83, 99, 97, 110, 110, 101, 114, 82, 101, 115, 117, 108,
4826 116, 215, 15, 16, 17, 18, 19, 20, 21, 76, 23, 78, 79, 26, 58, 26, 128, 20,
4827 128, 16, 128, 18, 128, 21, 128, 14, 212, 29, 30, 31, 16, 82, 82, 34, 35,
4828 128, 19, 128, 19, 128, 5, 16, 2, 82, 48, 48, 87, 77, 105, 110, 117, 116,
4829 101, 115, 216, 15, 16, 89, 17, 18, 19, 20, 21, 90, 23, 90, 93, 94, 26, 58,
4830 26, 81, 86, 128, 25, 128, 16, 128, 25, 128, 23, 128, 26, 128, 14, 212, 29,
4831 30, 31, 16, 82, 98, 34, 35, 128, 19, 128, 24, 128, 5, 16, 5, 82, 112, 109,
4832 88, 77, 101, 114, 105, 100, 105, 97, 110, 16, 1, 0, 8, 0, 17, 0, 26, 0, 36,
4833 0, 41, 0, 50, 0, 55, 0, 73, 0, 78, 0, 86, 0, 96, 0, 98, 0, 100, 0, 131, 0,
4834 137, 0, 152, 0, 155, 0, 162, 0, 165, 0, 167, 0, 169, 0, 172, 0, 175, 0,
4835 177, 0, 179, 0, 181, 0, 183, 0, 185, 0, 187, 0, 196, 0, 217, 0, 240, 0,
4836 251, 0, 253, 0, 255, 1, 1, 1, 3, 1, 5, 1, 7, 1, 12, 1, 23, 1, 32, 1, 40, 1,
4837 43, 1, 52, 1, 60, 1, 65, 1, 70, 1, 81, 1, 85, 1, 87, 1, 89, 1, 91, 1, 93,
4838 1, 108, 1, 110, 1, 112, 1, 114, 1, 116, 1, 118, 1, 127, 1, 129, 1, 131, 1,
4839 133, 1, 135, 1, 141, 1, 146, 1, 147, 1, 149, 1, 154, 1, 162, 1, 165, 1,
4840 170, 1, 188, 1, 191, 1, 209, 1, 224, 1, 226, 1, 228, 1, 230, 1, 232, 1,
4841 234, 1, 243, 1, 245, 1, 247, 1, 249, 1, 251, 1, 254, 2, 6, 2, 23, 2, 25, 2,
4842 27, 2, 29, 2, 31, 2, 33, 2, 35, 2, 37, 2, 46, 2, 48, 2, 50, 2, 52, 2, 54,
4843 2, 57, 2, 66, 0, 0, 0, 0, 0, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 104, 0, 0, 0, 0,
4844 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 68,
4845 ])],
4846 ],
4847 },
4848 Archived::Class(Class {
4849 name_index: 14,
4850 version: 0,
4851 parent_index: Some(3),
4852 }),
4853 Archived::Object {
4854 class: 8,
4855 data: vec![
4856 vec![OutputData::SignedInteger(3)],
4857 vec![OutputData::Object(17)],
4858 vec![OutputData::Object(18)],
4859 vec![OutputData::Object(14)],
4860 vec![OutputData::Object(15)],
4861 vec![OutputData::Object(19)],
4862 vec![OutputData::Object(20)],
4863 ],
4864 },
4865 Archived::Object {
4866 class: 8,
4867 data: vec![
4868 vec![OutputData::SignedInteger(4)],
4869 vec![OutputData::Object(19)],
4870 vec![OutputData::Object(20)],
4871 vec![OutputData::Object(14)],
4872 vec![OutputData::Object(15)],
4873 vec![OutputData::Object(17)],
4874 vec![OutputData::Object(18)],
4875 vec![OutputData::Object(24)],
4876 vec![OutputData::Object(10)],
4877 ],
4878 },
4879 Archived::Object {
4880 class: 6,
4881 data: vec![vec![OutputData::String("__kIMTextUnderlineAttributeName")]],
4882 },
4883 Archived::Object {
4884 class: 8,
4885 data: vec![
4886 vec![OutputData::SignedInteger(4)],
4887 vec![OutputData::Object(19)],
4888 vec![OutputData::Object(20)],
4889 vec![OutputData::Object(14)],
4890 vec![OutputData::Object(15)],
4891 vec![OutputData::Object(17)],
4892 vec![OutputData::Object(18)],
4893 vec![OutputData::Object(26)],
4894 vec![OutputData::Object(10)],
4895 ],
4896 },
4897 Archived::Object {
4898 class: 6,
4899 data: vec![vec![OutputData::String("__kIMTextItalicAttributeName")]],
4900 },
4901 ];
4902
4903 assert_eq!(typedstream.type_table, expected_types);
4904 assert_eq!(typedstream.object_table, expected_objects);
4905 }
4906
4907 #[test]
4908 fn test_parse_text_phone_number() {
4909 let typedstream_path = current_dir()
4910 .unwrap()
4911 .as_path()
4912 .join("src/test_data/PhoneNumber");
4913 let mut file = File::open(typedstream_path).unwrap();
4914 let mut bytes = vec![];
4915 file.read_to_end(&mut bytes).unwrap();
4916
4917 let mut typedstream = TypedStreamDeserializer::new(&bytes);
4918 let root = typedstream.oxidize().unwrap();
4919 println!("\nResults:");
4920 println!("Root object: {:x?}", typedstream.object_table[root]);
4921 print_resolved(typedstream.resolve_properties(root).unwrap(), 2);
4922
4923 println!("\nFound {:?} types:", typedstream.type_table.len());
4924 typedstream
4925 .type_table
4926 .iter()
4927 .enumerate()
4928 .for_each(|(idx, item)| println!("\t{idx}: {item:?}"));
4929
4930 println!("\nFound {:?} objects:", typedstream.object_table.len());
4931 typedstream
4932 .object_table
4933 .iter()
4934 .enumerate()
4935 .for_each(|(idx, item)| println!("\t{idx}: {item:?}"));
4936
4937 let expected_types = vec![
4938 vec![Type::Object],
4939 vec![Type::String("NSMutableAttributedString")],
4940 vec![Type::String("NSAttributedString")],
4941 vec![Type::String("NSObject")],
4942 vec![Type::String("NSMutableString")],
4943 vec![Type::String("NSString")],
4944 vec![Type::Utf8String],
4945 vec![Type::SignedInt, Type::UnsignedInt],
4946 vec![Type::String("NSDictionary")],
4947 vec![Type::SignedInt],
4948 vec![Type::String("NSNumber")],
4949 vec![Type::String("NSValue")],
4950 vec![Type::EmbeddedData],
4951 vec![Type::SignedInt],
4952 vec![Type::String("NSURL")],
4953 vec![Type::SignedInt],
4954 vec![Type::String("NSData")],
4955 vec![Type::Array(649)],
4956 ];
4957
4958 let expected_objects = vec![
4959 Archived::Object {
4960 class: 1,
4961 data: vec![
4962 vec![OutputData::Object(4)],
4963 vec![
4964 OutputData::SignedInteger(1),
4965 OutputData::UnsignedInteger(11),
4966 ],
4967 vec![OutputData::Object(7)],
4968 vec![
4969 OutputData::SignedInteger(2),
4970 OutputData::UnsignedInteger(10),
4971 ],
4972 vec![OutputData::Object(16)],
4973 ],
4974 },
4975 Archived::Class(Class {
4976 name_index: 1,
4977 version: 0,
4978 parent_index: Some(2),
4979 }),
4980 Archived::Class(Class {
4981 name_index: 2,
4982 version: 0,
4983 parent_index: Some(3),
4984 }),
4985 Archived::Class(Class {
4986 name_index: 3,
4987 version: 0,
4988 parent_index: None,
4989 }),
4990 Archived::Object {
4991 class: 5,
4992 data: vec![vec![OutputData::String("What about 0000000000")]],
4993 },
4994 Archived::Class(Class {
4995 name_index: 4,
4996 version: 1,
4997 parent_index: Some(6),
4998 }),
4999 Archived::Class(Class {
5000 name_index: 5,
5001 version: 1,
5002 parent_index: Some(3),
5003 }),
5004 Archived::Object {
5005 class: 8,
5006 data: vec![
5007 vec![OutputData::SignedInteger(2)],
5008 vec![OutputData::Object(9)],
5009 vec![OutputData::Object(10)],
5010 vec![OutputData::Object(14)],
5011 vec![OutputData::Object(15)],
5012 ],
5013 },
5014 Archived::Class(Class {
5015 name_index: 8,
5016 version: 0,
5017 parent_index: Some(3),
5018 }),
5019 Archived::Object {
5020 class: 6,
5021 data: vec![vec![OutputData::String(
5022 "__kIMBaseWritingDirectionAttributeName",
5023 )]],
5024 },
5025 Archived::Object {
5026 class: 11,
5027 data: vec![vec![OutputData::SignedInteger(-1)]],
5028 },
5029 Archived::Class(Class {
5030 name_index: 10,
5031 version: 0,
5032 parent_index: Some(12),
5033 }),
5034 Archived::Class(Class {
5035 name_index: 11,
5036 version: 0,
5037 parent_index: Some(3),
5038 }),
5039 Archived::Type(13),
5040 Archived::Object {
5041 class: 6,
5042 data: vec![vec![OutputData::String("__kIMMessagePartAttributeName")]],
5043 },
5044 Archived::Object {
5045 class: 11,
5046 data: vec![vec![OutputData::SignedInteger(0)]],
5047 },
5048 Archived::Object {
5049 class: 8,
5050 data: vec![
5051 vec![OutputData::SignedInteger(4)],
5052 vec![OutputData::Object(17)],
5053 vec![OutputData::Object(18)],
5054 vec![OutputData::Object(14)],
5055 vec![OutputData::Object(15)],
5056 vec![OutputData::Object(9)],
5057 vec![OutputData::Object(10)],
5058 vec![OutputData::Object(21)],
5059 vec![OutputData::Object(22)],
5060 ],
5061 },
5062 Archived::Object {
5063 class: 6,
5064 data: vec![vec![OutputData::String("__kIMLinkAttributeName")]],
5065 },
5066 Archived::Object {
5067 class: 19,
5068 data: vec![
5069 vec![OutputData::SignedInteger(0)],
5070 vec![OutputData::Object(20)],
5071 ],
5072 },
5073 Archived::Class(Class {
5074 name_index: 14,
5075 version: 0,
5076 parent_index: Some(3),
5077 }),
5078 Archived::Object {
5079 class: 6,
5080 data: vec![vec![OutputData::String("tel:0000000000")]],
5081 },
5082 Archived::Object {
5083 class: 6,
5084 data: vec![vec![OutputData::String("__kIMPhoneNumberAttributeName")]],
5085 },
5086 Archived::Object {
5087 class: 23,
5088 data: vec![
5089 vec![OutputData::SignedInteger(649)],
5090 vec![OutputData::Array(&[
5091 98, 112, 108, 105, 115, 116, 48, 48, 212, 1, 2, 3, 4, 5, 6, 7, 12, 88, 36,
5092 118, 101, 114, 115, 105, 111, 110, 89, 36, 97, 114, 99, 104, 105, 118, 101,
5093 114, 84, 36, 116, 111, 112, 88, 36, 111, 98, 106, 101, 99, 116, 115, 18, 0,
5094 1, 134, 160, 95, 16, 15, 78, 83, 75, 101, 121, 101, 100, 65, 114, 99, 104,
5095 105, 118, 101, 114, 210, 8, 9, 10, 11, 87, 118, 101, 114, 115, 105, 111,
5096 110, 89, 100, 100, 45, 114, 101, 115, 117, 108, 116, 128, 16, 128, 1, 175,
5097 16, 17, 13, 14, 28, 36, 37, 38, 44, 45, 46, 51, 57, 61, 62, 63, 66, 69, 73,
5098 85, 36, 110, 117, 108, 108, 215, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
5099 25, 26, 27, 26, 82, 77, 83, 86, 36, 99, 108, 97, 115, 115, 82, 65, 82, 81,
5100 84, 81, 80, 82, 83, 82, 82, 86, 78, 128, 6, 128, 15, 128, 2, 128, 7, 16, 1,
5101 128, 8, 212, 29, 30, 31, 16, 32, 33, 34, 35, 95, 16, 18, 78, 83, 46, 114,
5102 97, 110, 103, 101, 118, 97, 108, 46, 108, 101, 110, 103, 116, 104, 95, 16,
5103 20, 78, 83, 46, 114, 97, 110, 103, 101, 118, 97, 108, 46, 108, 111, 99, 97,
5104 116, 105, 111, 110, 90, 78, 83, 46, 115, 112, 101, 99, 105, 97, 108, 128,
5105 3, 128, 4, 16, 4, 128, 5, 16, 10, 16, 11, 210, 39, 40, 41, 42, 90, 36, 99,
5106 108, 97, 115, 115, 110, 97, 109, 101, 88, 36, 99, 108, 97, 115, 115, 101,
5107 115, 87, 78, 83, 86, 97, 108, 117, 101, 162, 41, 43, 88, 78, 83, 79, 98,
5108 106, 101, 99, 116, 90, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 91, 80, 104,
5109 111, 110, 101, 78, 117, 109, 98, 101, 114, 210, 47, 16, 48, 50, 90, 78, 83,
5110 46, 111, 98, 106, 101, 99, 116, 115, 161, 49, 128, 9, 128, 14, 215, 15, 16,
5111 17, 18, 19, 20, 21, 52, 23, 54, 55, 26, 56, 26, 128, 11, 128, 15, 128, 10,
5112 128, 12, 128, 13, 212, 29, 30, 31, 16, 32, 33, 34, 35, 128, 3, 128, 4, 128,
5113 5, 90, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 85, 86, 97, 108, 117, 101,
5114 210, 47, 16, 64, 50, 160, 128, 14, 210, 39, 40, 67, 68, 87, 78, 83, 65,
5115 114, 114, 97, 121, 162, 67, 43, 210, 39, 40, 70, 71, 95, 16, 15, 68, 68,
5116 83, 99, 97, 110, 110, 101, 114, 82, 101, 115, 117, 108, 116, 162, 72, 43,
5117 95, 16, 15, 68, 68, 83, 99, 97, 110, 110, 101, 114, 82, 101, 115, 117, 108,
5118 116, 16, 1, 0, 8, 0, 17, 0, 26, 0, 36, 0, 41, 0, 50, 0, 55, 0, 73, 0, 78,
5119 0, 86, 0, 96, 0, 98, 0, 100, 0, 120, 0, 126, 0, 141, 0, 144, 0, 151, 0,
5120 154, 0, 156, 0, 158, 0, 161, 0, 164, 0, 166, 0, 168, 0, 170, 0, 172, 0,
5121 174, 0, 176, 0, 185, 0, 206, 0, 229, 0, 240, 0, 242, 0, 244, 0, 246, 0,
5122 248, 0, 250, 0, 252, 1, 1, 1, 12, 1, 21, 1, 29, 1, 32, 1, 41, 1, 52, 1, 64,
5123 1, 69, 1, 80, 1, 82, 1, 84, 1, 86, 1, 101, 1, 103, 1, 105, 1, 107, 1, 109,
5124 1, 111, 1, 120, 1, 122, 1, 124, 1, 126, 1, 137, 1, 143, 1, 148, 1, 149, 1,
5125 151, 1, 156, 1, 164, 1, 167, 1, 172, 1, 190, 1, 193, 1, 211, 0, 0, 0, 0, 0,
5126 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 74, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5127 1, 213,
5128 ])],
5129 ],
5130 },
5131 Archived::Class(Class {
5132 name_index: 16,
5133 version: 0,
5134 parent_index: Some(3),
5135 }),
5136 ];
5137
5138 assert_eq!(typedstream.type_table, expected_types);
5139 assert_eq!(typedstream.object_table, expected_objects);
5140 }
5141
5142 #[test]
5143 fn test_parse_text_styled_link() {
5144 let typedstream_path = current_dir()
5145 .unwrap()
5146 .as_path()
5147 .join("src/test_data/StyledLink");
5148 let mut file = File::open(typedstream_path).unwrap();
5149 let mut bytes = vec![];
5150 file.read_to_end(&mut bytes).unwrap();
5151
5152 let mut typedstream = TypedStreamDeserializer::new(&bytes);
5153 let root = typedstream.oxidize().unwrap();
5154 println!("\nResults:");
5155 println!("Root object: {:x?}", typedstream.object_table[root]);
5156 print_resolved(typedstream.resolve_properties(root).unwrap(), 2);
5157
5158 println!("\nFound {:?} types:", typedstream.type_table.len());
5159 typedstream
5160 .type_table
5161 .iter()
5162 .enumerate()
5163 .for_each(|(idx, item)| println!("\t{idx}: {item:?}"));
5164
5165 println!("\nFound {:?} objects:", typedstream.object_table.len());
5166 typedstream
5167 .object_table
5168 .iter()
5169 .enumerate()
5170 .for_each(|(idx, item)| println!("\t{idx}: {item:?}"));
5171
5172 let expected_types = vec![
5173 vec![Type::Object],
5174 vec![Type::String("NSMutableAttributedString")],
5175 vec![Type::String("NSAttributedString")],
5176 vec![Type::String("NSObject")],
5177 vec![Type::String("NSMutableString")],
5178 vec![Type::String("NSString")],
5179 vec![Type::Utf8String],
5180 vec![Type::SignedInt, Type::UnsignedInt],
5181 vec![Type::String("NSDictionary")],
5182 vec![Type::SignedInt],
5183 vec![Type::String("NSNumber")],
5184 vec![Type::String("NSValue")],
5185 vec![Type::EmbeddedData],
5186 vec![Type::SignedInt],
5187 vec![Type::SignedInt],
5188 vec![Type::String("NSData")],
5189 vec![Type::Array(591)],
5190 vec![Type::String("NSURL")],
5191 ];
5192
5193 let expected_objects = vec![
5194 Archived::Object {
5195 class: 1,
5196 data: vec![
5197 vec![OutputData::Object(4)],
5198 vec![
5199 OutputData::SignedInteger(1),
5200 OutputData::UnsignedInteger(61),
5201 ],
5202 vec![OutputData::Object(7)],
5203 ],
5204 },
5205 Archived::Class(Class {
5206 name_index: 1,
5207 version: 0,
5208 parent_index: Some(2),
5209 }),
5210 Archived::Class(Class {
5211 name_index: 2,
5212 version: 0,
5213 parent_index: Some(3),
5214 }),
5215 Archived::Class(Class {
5216 name_index: 3,
5217 version: 0,
5218 parent_index: None,
5219 }),
5220 Archived::Object {
5221 class: 5,
5222 data: vec![vec![OutputData::String(
5223 "https://github.com/ReagentX/imessage-exporter/discussions/553",
5224 )]],
5225 },
5226 Archived::Class(Class {
5227 name_index: 4,
5228 version: 1,
5229 parent_index: Some(6),
5230 }),
5231 Archived::Class(Class {
5232 name_index: 5,
5233 version: 1,
5234 parent_index: Some(3),
5235 }),
5236 Archived::Object {
5237 class: 8,
5238 data: vec![
5239 vec![OutputData::SignedInteger(6)],
5240 vec![OutputData::Object(9)],
5241 vec![OutputData::Object(10)],
5242 vec![OutputData::Object(14)],
5243 vec![OutputData::Object(15)],
5244 vec![OutputData::Object(17)],
5245 vec![OutputData::Object(18)],
5246 vec![OutputData::Object(20)],
5247 vec![OutputData::Object(21)],
5248 vec![OutputData::Object(22)],
5249 vec![OutputData::Object(23)],
5250 vec![OutputData::Object(24)],
5251 vec![OutputData::Object(25)],
5252 ],
5253 },
5254 Archived::Class(Class {
5255 name_index: 8,
5256 version: 0,
5257 parent_index: Some(3),
5258 }),
5259 Archived::Object {
5260 class: 6,
5261 data: vec![vec![OutputData::String(
5262 "__kIMBaseWritingDirectionAttributeName",
5263 )]],
5264 },
5265 Archived::Object {
5266 class: 11,
5267 data: vec![vec![OutputData::SignedInteger(-1)]],
5268 },
5269 Archived::Class(Class {
5270 name_index: 10,
5271 version: 0,
5272 parent_index: Some(12),
5273 }),
5274 Archived::Class(Class {
5275 name_index: 11,
5276 version: 0,
5277 parent_index: Some(3),
5278 }),
5279 Archived::Type(13),
5280 Archived::Object {
5281 class: 6,
5282 data: vec![vec![OutputData::String("__kIMLinkIsRichLinkAttributeName")]],
5283 },
5284 Archived::Object {
5285 class: 11,
5286 data: vec![vec![OutputData::SignedInteger(0)]],
5287 },
5288 Archived::Type(14),
5289 Archived::Object {
5290 class: 6,
5291 data: vec![vec![OutputData::String("__kIMDataDetectedAttributeName")]],
5292 },
5293 Archived::Object {
5294 class: 19,
5295 data: vec![
5296 vec![OutputData::SignedInteger(591)],
5297 vec![OutputData::Array(&[
5298 98, 112, 108, 105, 115, 116, 48, 48, 212, 1, 2, 3, 4, 5, 6, 7, 12, 88, 36,
5299 118, 101, 114, 115, 105, 111, 110, 89, 36, 97, 114, 99, 104, 105, 118, 101,
5300 114, 84, 36, 116, 111, 112, 88, 36, 111, 98, 106, 101, 99, 116, 115, 18, 0,
5301 1, 134, 160, 95, 16, 15, 78, 83, 75, 101, 121, 101, 100, 65, 114, 99, 104,
5302 105, 118, 101, 114, 210, 8, 9, 10, 11, 87, 118, 101, 114, 115, 105, 111,
5303 110, 89, 100, 100, 45, 114, 101, 115, 117, 108, 116, 128, 11, 128, 1, 172,
5304 13, 14, 28, 36, 37, 38, 44, 45, 46, 50, 53, 57, 85, 36, 110, 117, 108, 108,
5305 215, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 26, 82, 77, 83,
5306 86, 36, 99, 108, 97, 115, 115, 82, 65, 82, 81, 84, 81, 80, 82, 83, 82, 82,
5307 86, 78, 128, 6, 128, 10, 128, 2, 128, 7, 16, 1, 128, 8, 212, 29, 30, 31,
5308 16, 32, 33, 34, 35, 95, 16, 18, 78, 83, 46, 114, 97, 110, 103, 101, 118,
5309 97, 108, 46, 108, 101, 110, 103, 116, 104, 95, 16, 20, 78, 83, 46, 114, 97,
5310 110, 103, 101, 118, 97, 108, 46, 108, 111, 99, 97, 116, 105, 111, 110, 90,
5311 78, 83, 46, 115, 112, 101, 99, 105, 97, 108, 128, 3, 128, 4, 16, 4, 128, 5,
5312 16, 61, 16, 0, 210, 39, 40, 41, 42, 90, 36, 99, 108, 97, 115, 115, 110, 97,
5313 109, 101, 88, 36, 99, 108, 97, 115, 115, 101, 115, 87, 78, 83, 86, 97, 108,
5314 117, 101, 162, 41, 43, 88, 78, 83, 79, 98, 106, 101, 99, 116, 95, 16, 61,
5315 104, 116, 116, 112, 115, 58, 47, 47, 103, 105, 116, 104, 117, 98, 46, 99,
5316 111, 109, 47, 82, 101, 97, 103, 101, 110, 116, 88, 47, 105, 109, 101, 115,
5317 115, 97, 103, 101, 45, 101, 120, 112, 111, 114, 116, 101, 114, 47, 100,
5318 105, 115, 99, 117, 115, 115, 105, 111, 110, 115, 47, 53, 53, 51, 87, 72,
5319 116, 116, 112, 85, 82, 76, 210, 47, 16, 48, 49, 90, 78, 83, 46, 111, 98,
5320 106, 101, 99, 116, 115, 160, 128, 9, 210, 39, 40, 51, 52, 87, 78, 83, 65,
5321 114, 114, 97, 121, 162, 51, 43, 210, 39, 40, 54, 55, 95, 16, 15, 68, 68,
5322 83, 99, 97, 110, 110, 101, 114, 82, 101, 115, 117, 108, 116, 162, 56, 43,
5323 95, 16, 15, 68, 68, 83, 99, 97, 110, 110, 101, 114, 82, 101, 115, 117, 108,
5324 116, 16, 1, 0, 8, 0, 17, 0, 26, 0, 36, 0, 41, 0, 50, 0, 55, 0, 73, 0, 78,
5325 0, 86, 0, 96, 0, 98, 0, 100, 0, 113, 0, 119, 0, 134, 0, 137, 0, 144, 0,
5326 147, 0, 149, 0, 151, 0, 154, 0, 157, 0, 159, 0, 161, 0, 163, 0, 165, 0,
5327 167, 0, 169, 0, 178, 0, 199, 0, 222, 0, 233, 0, 235, 0, 237, 0, 239, 0,
5328 241, 0, 243, 0, 245, 0, 250, 1, 5, 1, 14, 1, 22, 1, 25, 1, 34, 1, 98, 1,
5329 106, 1, 111, 1, 122, 1, 123, 1, 125, 1, 130, 1, 138, 1, 141, 1, 146, 1,
5330 164, 1, 167, 1, 185, 0, 0, 0, 0, 0, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 58, 0, 0,
5331 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 187,
5332 ])],
5333 ],
5334 },
5335 Archived::Class(Class {
5336 name_index: 15,
5337 version: 0,
5338 parent_index: Some(3),
5339 }),
5340 Archived::Object {
5341 class: 6,
5342 data: vec![vec![OutputData::String("__kIMMessagePartAttributeName")]],
5343 },
5344 Archived::Object {
5345 class: 11,
5346 data: vec![vec![OutputData::SignedInteger(0)]],
5347 },
5348 Archived::Object {
5349 class: 6,
5350 data: vec![vec![OutputData::String("__kIMTextEffectAttributeName")]],
5351 },
5352 Archived::Object {
5353 class: 11,
5354 data: vec![vec![OutputData::SignedInteger(5)]],
5355 },
5356 Archived::Object {
5357 class: 6,
5358 data: vec![vec![OutputData::String("__kIMLinkAttributeName")]],
5359 },
5360 Archived::Object {
5361 class: 26,
5362 data: vec![
5363 vec![OutputData::SignedInteger(0)],
5364 vec![OutputData::Object(27)],
5365 ],
5366 },
5367 Archived::Class(Class {
5368 name_index: 17,
5369 version: 0,
5370 parent_index: Some(3),
5371 }),
5372 Archived::Object {
5373 class: 6,
5374 data: vec![vec![OutputData::String(
5375 "https://github.com/ReagentX/imessage-exporter/discussions/553",
5376 )]],
5377 },
5378 ];
5379
5380 assert_eq!(typedstream.type_table, expected_types);
5381 assert_eq!(typedstream.object_table, expected_objects);
5382 }
5383
5384 #[test]
5385 fn test_parse_text_effects() {
5386 let typedstream_path = current_dir()
5387 .unwrap()
5388 .as_path()
5389 .join("src/test_data/TextEffects");
5390 let mut file = File::open(typedstream_path).unwrap();
5391 let mut bytes = vec![];
5392 file.read_to_end(&mut bytes).unwrap();
5393
5394 let mut typedstream = TypedStreamDeserializer::new(&bytes);
5395 let root = typedstream.oxidize().unwrap();
5396 println!("\nResults:");
5397 println!("Root object: {:x?}", typedstream.object_table[root]);
5398 print_resolved(typedstream.resolve_properties(root).unwrap(), 2);
5399
5400 println!("\nFound {:?} types:", typedstream.type_table.len());
5401 typedstream
5402 .type_table
5403 .iter()
5404 .enumerate()
5405 .for_each(|(idx, item)| println!("\t{idx}: {item:?}"));
5406
5407 println!("\nFound {:?} objects:", typedstream.object_table.len());
5408 typedstream
5409 .object_table
5410 .iter()
5411 .enumerate()
5412 .for_each(|(idx, item)| println!("\t{idx}: {item:?}"));
5413
5414 let expected_types = vec![
5415 vec![Type::Object],
5416 vec![Type::String("NSAttributedString")],
5417 vec![Type::String("NSObject")],
5418 vec![Type::String("NSString")],
5419 vec![Type::Utf8String],
5420 vec![Type::SignedInt, Type::UnsignedInt],
5421 vec![Type::String("NSDictionary")],
5422 vec![Type::SignedInt],
5423 vec![Type::String("NSNumber")],
5424 vec![Type::String("NSValue")],
5425 vec![Type::EmbeddedData],
5426 vec![Type::SignedInt],
5427 ];
5428
5429 let expected_objects = vec![
5430 Archived::Object {
5431 class: 1,
5432 data: vec![
5433 vec![OutputData::Object(3)],
5434 vec![OutputData::SignedInteger(1), OutputData::UnsignedInteger(3)],
5435 vec![OutputData::Object(5)],
5436 vec![OutputData::SignedInteger(2), OutputData::UnsignedInteger(1)],
5437 vec![OutputData::Object(15)],
5438 vec![OutputData::SignedInteger(3), OutputData::UnsignedInteger(6)],
5439 vec![OutputData::Object(17)],
5440 vec![OutputData::SignedInteger(4), OutputData::UnsignedInteger(5)],
5441 vec![OutputData::Object(19)],
5442 vec![OutputData::SignedInteger(3), OutputData::UnsignedInteger(1)],
5443 vec![OutputData::SignedInteger(5), OutputData::UnsignedInteger(3)],
5444 vec![OutputData::Object(21)],
5445 vec![OutputData::SignedInteger(3), OutputData::UnsignedInteger(1)],
5446 vec![OutputData::SignedInteger(6), OutputData::UnsignedInteger(8)],
5447 vec![OutputData::Object(23)],
5448 vec![OutputData::SignedInteger(7), OutputData::UnsignedInteger(6)],
5449 vec![OutputData::Object(25)],
5450 vec![OutputData::SignedInteger(6), OutputData::UnsignedInteger(1)],
5451 vec![OutputData::SignedInteger(8), OutputData::UnsignedInteger(5)],
5452 vec![OutputData::Object(27)],
5453 vec![OutputData::SignedInteger(6), OutputData::UnsignedInteger(1)],
5454 vec![OutputData::SignedInteger(9), OutputData::UnsignedInteger(6)],
5455 vec![OutputData::Object(29)],
5456 ],
5457 },
5458 Archived::Class(Class {
5459 name_index: 1,
5460 version: 0,
5461 parent_index: Some(2),
5462 }),
5463 Archived::Class(Class {
5464 name_index: 2,
5465 version: 0,
5466 parent_index: None,
5467 }),
5468 Archived::Object {
5469 class: 4,
5470 data: vec![vec![OutputData::String(
5471 "Big small shake nod explode ripple bloom jitter",
5472 )]],
5473 },
5474 Archived::Class(Class {
5475 name_index: 3,
5476 version: 1,
5477 parent_index: Some(2),
5478 }),
5479 Archived::Object {
5480 class: 6,
5481 data: vec![
5482 vec![OutputData::SignedInteger(2)],
5483 vec![OutputData::Object(7)],
5484 vec![OutputData::Object(8)],
5485 vec![OutputData::Object(12)],
5486 vec![OutputData::Object(13)],
5487 ],
5488 },
5489 Archived::Class(Class {
5490 name_index: 6,
5491 version: 0,
5492 parent_index: Some(2),
5493 }),
5494 Archived::Object {
5495 class: 4,
5496 data: vec![vec![OutputData::String("__kIMTextEffectAttributeName")]],
5497 },
5498 Archived::Object {
5499 class: 9,
5500 data: vec![vec![OutputData::SignedInteger(5)]],
5501 },
5502 Archived::Class(Class {
5503 name_index: 8,
5504 version: 0,
5505 parent_index: Some(10),
5506 }),
5507 Archived::Class(Class {
5508 name_index: 9,
5509 version: 0,
5510 parent_index: Some(2),
5511 }),
5512 Archived::Type(11),
5513 Archived::Object {
5514 class: 4,
5515 data: vec![vec![OutputData::String("__kIMMessagePartAttributeName")]],
5516 },
5517 Archived::Object {
5518 class: 9,
5519 data: vec![vec![OutputData::SignedInteger(0)]],
5520 },
5521 Archived::Type(7),
5522 Archived::Object {
5523 class: 6,
5524 data: vec![
5525 vec![OutputData::SignedInteger(1)],
5526 vec![OutputData::Object(16)],
5527 vec![OutputData::Object(13)],
5528 ],
5529 },
5530 Archived::Object {
5531 class: 4,
5532 data: vec![vec![OutputData::String("__kIMMessagePartAttributeName")]],
5533 },
5534 Archived::Object {
5535 class: 6,
5536 data: vec![
5537 vec![OutputData::SignedInteger(2)],
5538 vec![OutputData::Object(7)],
5539 vec![OutputData::Object(18)],
5540 vec![OutputData::Object(12)],
5541 vec![OutputData::Object(13)],
5542 ],
5543 },
5544 Archived::Object {
5545 class: 9,
5546 data: vec![vec![OutputData::SignedInteger(11)]],
5547 },
5548 Archived::Object {
5549 class: 6,
5550 data: vec![
5551 vec![OutputData::SignedInteger(2)],
5552 vec![OutputData::Object(7)],
5553 vec![OutputData::Object(20)],
5554 vec![OutputData::Object(12)],
5555 vec![OutputData::Object(13)],
5556 ],
5557 },
5558 Archived::Object {
5559 class: 9,
5560 data: vec![vec![OutputData::SignedInteger(9)]],
5561 },
5562 Archived::Object {
5563 class: 6,
5564 data: vec![
5565 vec![OutputData::SignedInteger(2)],
5566 vec![OutputData::Object(7)],
5567 vec![OutputData::Object(22)],
5568 vec![OutputData::Object(12)],
5569 vec![OutputData::Object(13)],
5570 ],
5571 },
5572 Archived::Object {
5573 class: 9,
5574 data: vec![vec![OutputData::SignedInteger(8)]],
5575 },
5576 Archived::Object {
5577 class: 6,
5578 data: vec![
5579 vec![OutputData::SignedInteger(2)],
5580 vec![OutputData::Object(7)],
5581 vec![OutputData::Object(24)],
5582 vec![OutputData::Object(12)],
5583 vec![OutputData::Object(13)],
5584 ],
5585 },
5586 Archived::Object {
5587 class: 9,
5588 data: vec![vec![OutputData::SignedInteger(12)]],
5589 },
5590 Archived::Object {
5591 class: 6,
5592 data: vec![
5593 vec![OutputData::SignedInteger(2)],
5594 vec![OutputData::Object(7)],
5595 vec![OutputData::Object(26)],
5596 vec![OutputData::Object(12)],
5597 vec![OutputData::Object(13)],
5598 ],
5599 },
5600 Archived::Object {
5601 class: 9,
5602 data: vec![vec![OutputData::SignedInteger(4)]],
5603 },
5604 Archived::Object {
5605 class: 6,
5606 data: vec![
5607 vec![OutputData::SignedInteger(2)],
5608 vec![OutputData::Object(7)],
5609 vec![OutputData::Object(28)],
5610 vec![OutputData::Object(12)],
5611 vec![OutputData::Object(13)],
5612 ],
5613 },
5614 Archived::Object {
5615 class: 9,
5616 data: vec![vec![OutputData::SignedInteger(6)]],
5617 },
5618 Archived::Object {
5619 class: 6,
5620 data: vec![
5621 vec![OutputData::SignedInteger(2)],
5622 vec![OutputData::Object(7)],
5623 vec![OutputData::Object(30)],
5624 vec![OutputData::Object(12)],
5625 vec![OutputData::Object(13)],
5626 ],
5627 },
5628 Archived::Object {
5629 class: 9,
5630 data: vec![vec![OutputData::SignedInteger(10)]],
5631 },
5632 ];
5633
5634 assert_eq!(typedstream.type_table, expected_types);
5635 assert_eq!(typedstream.object_table, expected_objects);
5636 }
5637
5638 #[test]
5639 fn test_parse_text_styles() {
5640 let typedstream_path = current_dir()
5641 .unwrap()
5642 .as_path()
5643 .join("src/test_data/TextStyles");
5644 let mut file = File::open(typedstream_path).unwrap();
5645 let mut bytes = vec![];
5646 file.read_to_end(&mut bytes).unwrap();
5647
5648 let mut typedstream = TypedStreamDeserializer::new(&bytes);
5649 let root = typedstream.oxidize().unwrap();
5650 println!("\nResults:");
5651 println!("Root object: {:x?}", typedstream.object_table[root]);
5652 print_resolved(typedstream.resolve_properties(root).unwrap(), 2);
5653
5654 println!("\nFound {:?} types:", typedstream.type_table.len());
5655 typedstream
5656 .type_table
5657 .iter()
5658 .enumerate()
5659 .for_each(|(idx, item)| println!("\t{idx}: {item:?}"));
5660
5661 println!("\nFound {:?} objects:", typedstream.object_table.len());
5662 typedstream
5663 .object_table
5664 .iter()
5665 .enumerate()
5666 .for_each(|(idx, item)| println!("\t{idx}: {item:?}"));
5667
5668 let expected_types = vec![
5669 vec![Type::Object],
5670 vec![Type::String("NSAttributedString")],
5671 vec![Type::String("NSObject")],
5672 vec![Type::String("NSString")],
5673 vec![Type::Utf8String],
5674 vec![Type::SignedInt, Type::UnsignedInt],
5675 vec![Type::String("NSDictionary")],
5676 vec![Type::SignedInt],
5677 vec![Type::String("NSNumber")],
5678 vec![Type::String("NSValue")],
5679 vec![Type::EmbeddedData],
5680 ];
5681
5682 let expected_objects = vec![
5683 Archived::Object {
5684 class: 1,
5685 data: vec![
5686 vec![OutputData::Object(3)],
5687 vec![OutputData::SignedInteger(1), OutputData::UnsignedInteger(4)],
5688 vec![OutputData::Object(5)],
5689 vec![OutputData::SignedInteger(2), OutputData::UnsignedInteger(1)],
5690 vec![OutputData::Object(14)],
5691 vec![OutputData::SignedInteger(3), OutputData::UnsignedInteger(9)],
5692 vec![OutputData::Object(16)],
5693 vec![OutputData::SignedInteger(2), OutputData::UnsignedInteger(1)],
5694 vec![OutputData::SignedInteger(4), OutputData::UnsignedInteger(6)],
5695 vec![OutputData::Object(18)],
5696 vec![OutputData::SignedInteger(2), OutputData::UnsignedInteger(1)],
5697 vec![
5698 OutputData::SignedInteger(5),
5699 OutputData::UnsignedInteger(13),
5700 ],
5701 vec![OutputData::Object(20)],
5702 vec![OutputData::SignedInteger(2), OutputData::UnsignedInteger(5)],
5703 vec![OutputData::SignedInteger(6), OutputData::UnsignedInteger(4)],
5704 vec![OutputData::Object(22)],
5705 ],
5706 },
5707 Archived::Class(Class {
5708 name_index: 1,
5709 version: 0,
5710 parent_index: Some(2),
5711 }),
5712 Archived::Class(Class {
5713 name_index: 2,
5714 version: 0,
5715 parent_index: None,
5716 }),
5717 Archived::Object {
5718 class: 4,
5719 data: vec![vec![OutputData::String(
5720 "Bold underline italic strikethrough all four",
5721 )]],
5722 },
5723 Archived::Class(Class {
5724 name_index: 3,
5725 version: 1,
5726 parent_index: Some(2),
5727 }),
5728 Archived::Object {
5729 class: 6,
5730 data: vec![
5731 vec![OutputData::SignedInteger(2)],
5732 vec![OutputData::Object(7)],
5733 vec![OutputData::Object(8)],
5734 vec![OutputData::Object(12)],
5735 vec![OutputData::Object(13)],
5736 ],
5737 },
5738 Archived::Class(Class {
5739 name_index: 6,
5740 version: 0,
5741 parent_index: Some(2),
5742 }),
5743 Archived::Object {
5744 class: 4,
5745 data: vec![vec![OutputData::String("__kIMTextBoldAttributeName")]],
5746 },
5747 Archived::Object {
5748 class: 9,
5749 data: vec![vec![OutputData::SignedInteger(1)]],
5750 },
5751 Archived::Class(Class {
5752 name_index: 8,
5753 version: 0,
5754 parent_index: Some(10),
5755 }),
5756 Archived::Class(Class {
5757 name_index: 9,
5758 version: 0,
5759 parent_index: Some(2),
5760 }),
5761 Archived::Type(7),
5762 Archived::Object {
5763 class: 4,
5764 data: vec![vec![OutputData::String("__kIMMessagePartAttributeName")]],
5765 },
5766 Archived::Object {
5767 class: 9,
5768 data: vec![vec![OutputData::SignedInteger(0)]],
5769 },
5770 Archived::Object {
5771 class: 6,
5772 data: vec![
5773 vec![OutputData::SignedInteger(1)],
5774 vec![OutputData::Object(15)],
5775 vec![OutputData::Object(13)],
5776 ],
5777 },
5778 Archived::Object {
5779 class: 4,
5780 data: vec![vec![OutputData::String("__kIMMessagePartAttributeName")]],
5781 },
5782 Archived::Object {
5783 class: 6,
5784 data: vec![
5785 vec![OutputData::SignedInteger(2)],
5786 vec![OutputData::Object(17)],
5787 vec![OutputData::Object(8)],
5788 vec![OutputData::Object(12)],
5789 vec![OutputData::Object(13)],
5790 ],
5791 },
5792 Archived::Object {
5793 class: 4,
5794 data: vec![vec![OutputData::String("__kIMTextUnderlineAttributeName")]],
5795 },
5796 Archived::Object {
5797 class: 6,
5798 data: vec![
5799 vec![OutputData::SignedInteger(2)],
5800 vec![OutputData::Object(19)],
5801 vec![OutputData::Object(8)],
5802 vec![OutputData::Object(12)],
5803 vec![OutputData::Object(13)],
5804 ],
5805 },
5806 Archived::Object {
5807 class: 4,
5808 data: vec![vec![OutputData::String("__kIMTextItalicAttributeName")]],
5809 },
5810 Archived::Object {
5811 class: 6,
5812 data: vec![
5813 vec![OutputData::SignedInteger(2)],
5814 vec![OutputData::Object(21)],
5815 vec![OutputData::Object(8)],
5816 vec![OutputData::Object(12)],
5817 vec![OutputData::Object(13)],
5818 ],
5819 },
5820 Archived::Object {
5821 class: 4,
5822 data: vec![vec![OutputData::String(
5823 "__kIMTextStrikethroughAttributeName",
5824 )]],
5825 },
5826 Archived::Object {
5827 class: 6,
5828 data: vec![
5829 vec![OutputData::SignedInteger(5)],
5830 vec![OutputData::Object(7)],
5831 vec![OutputData::Object(8)],
5832 vec![OutputData::Object(21)],
5833 vec![OutputData::Object(8)],
5834 vec![OutputData::Object(12)],
5835 vec![OutputData::Object(13)],
5836 vec![OutputData::Object(17)],
5837 vec![OutputData::Object(8)],
5838 vec![OutputData::Object(19)],
5839 vec![OutputData::Object(8)],
5840 ],
5841 },
5842 ];
5843
5844 assert_eq!(typedstream.type_table, expected_types);
5845 assert_eq!(typedstream.object_table, expected_objects);
5846 }
5847
5848 #[test]
5849 fn test_parse_text_styles_mixed() {
5850 let typedstream_path = current_dir()
5851 .unwrap()
5852 .as_path()
5853 .join("src/test_data/TextStylesMixed");
5854 let mut file = File::open(typedstream_path).unwrap();
5855 let mut bytes = vec![];
5856 file.read_to_end(&mut bytes).unwrap();
5857
5858 let mut typedstream = TypedStreamDeserializer::new(&bytes);
5859 let root = typedstream.oxidize().unwrap();
5860 println!("\nResults:");
5861 println!("Root object: {:x?}", typedstream.object_table[root]);
5862 print_resolved(typedstream.resolve_properties(root).unwrap(), 2);
5863
5864 println!("\nFound {:?} types:", typedstream.type_table.len());
5865 typedstream
5866 .type_table
5867 .iter()
5868 .enumerate()
5869 .for_each(|(idx, item)| println!("\t{idx}: {item:?}"));
5870
5871 println!("\nFound {:?} objects:", typedstream.object_table.len());
5872 typedstream
5873 .object_table
5874 .iter()
5875 .enumerate()
5876 .for_each(|(idx, item)| println!("\t{idx}: {item:?}"));
5877
5878 let expected_types = vec![
5879 vec![Type::Object],
5880 vec![Type::String("NSAttributedString")],
5881 vec![Type::String("NSObject")],
5882 vec![Type::String("NSString")],
5883 vec![Type::Utf8String],
5884 vec![Type::SignedInt, Type::UnsignedInt],
5885 vec![Type::String("NSDictionary")],
5886 vec![Type::SignedInt],
5887 vec![Type::String("NSNumber")],
5888 vec![Type::String("NSValue")],
5889 vec![Type::EmbeddedData],
5890 vec![Type::SignedInt],
5891 ];
5892
5893 let expected_objects = vec![
5894 Archived::Object {
5895 class: 1,
5896 data: vec![
5897 vec![OutputData::Object(3)],
5898 vec![OutputData::SignedInteger(1), OutputData::UnsignedInteger(9)],
5899 vec![OutputData::Object(5)],
5900 vec![OutputData::SignedInteger(2), OutputData::UnsignedInteger(8)],
5901 vec![OutputData::Object(17)],
5902 vec![OutputData::SignedInteger(3), OutputData::UnsignedInteger(6)],
5903 vec![OutputData::Object(18)],
5904 vec![OutputData::SignedInteger(2), OutputData::UnsignedInteger(7)],
5905 ],
5906 },
5907 Archived::Class(Class {
5908 name_index: 1,
5909 version: 0,
5910 parent_index: Some(2),
5911 }),
5912 Archived::Class(Class {
5913 name_index: 2,
5914 version: 0,
5915 parent_index: None,
5916 }),
5917 Archived::Object {
5918 class: 4,
5919 data: vec![vec![OutputData::String("Underline normal jitter normal")]],
5920 },
5921 Archived::Class(Class {
5922 name_index: 3,
5923 version: 1,
5924 parent_index: Some(2),
5925 }),
5926 Archived::Object {
5927 class: 6,
5928 data: vec![
5929 vec![OutputData::SignedInteger(3)],
5930 vec![OutputData::Object(7)],
5931 vec![OutputData::Object(8)],
5932 vec![OutputData::Object(12)],
5933 vec![OutputData::Object(13)],
5934 vec![OutputData::Object(14)],
5935 vec![OutputData::Object(15)],
5936 ],
5937 },
5938 Archived::Class(Class {
5939 name_index: 6,
5940 version: 0,
5941 parent_index: Some(2),
5942 }),
5943 Archived::Object {
5944 class: 4,
5945 data: vec![vec![OutputData::String(
5946 "__kIMBaseWritingDirectionAttributeName",
5947 )]],
5948 },
5949 Archived::Object {
5950 class: 9,
5951 data: vec![vec![OutputData::SignedInteger(-1)]],
5952 },
5953 Archived::Class(Class {
5954 name_index: 8,
5955 version: 0,
5956 parent_index: Some(10),
5957 }),
5958 Archived::Class(Class {
5959 name_index: 9,
5960 version: 0,
5961 parent_index: Some(2),
5962 }),
5963 Archived::Type(11),
5964 Archived::Object {
5965 class: 4,
5966 data: vec![vec![OutputData::String("__kIMMessagePartAttributeName")]],
5967 },
5968 Archived::Object {
5969 class: 9,
5970 data: vec![vec![OutputData::SignedInteger(0)]],
5971 },
5972 Archived::Object {
5973 class: 4,
5974 data: vec![vec![OutputData::String("__kIMTextUnderlineAttributeName")]],
5975 },
5976 Archived::Object {
5977 class: 9,
5978 data: vec![vec![OutputData::SignedInteger(1)]],
5979 },
5980 Archived::Type(7),
5981 Archived::Object {
5982 class: 6,
5983 data: vec![
5984 vec![OutputData::SignedInteger(2)],
5985 vec![OutputData::Object(7)],
5986 vec![OutputData::Object(8)],
5987 vec![OutputData::Object(12)],
5988 vec![OutputData::Object(13)],
5989 ],
5990 },
5991 Archived::Object {
5992 class: 6,
5993 data: vec![
5994 vec![OutputData::SignedInteger(3)],
5995 vec![OutputData::Object(7)],
5996 vec![OutputData::Object(8)],
5997 vec![OutputData::Object(12)],
5998 vec![OutputData::Object(13)],
5999 vec![OutputData::Object(19)],
6000 vec![OutputData::Object(20)],
6001 ],
6002 },
6003 Archived::Object {
6004 class: 4,
6005 data: vec![vec![OutputData::String("__kIMTextEffectAttributeName")]],
6006 },
6007 Archived::Object {
6008 class: 9,
6009 data: vec![vec![OutputData::SignedInteger(10)]],
6010 },
6011 ];
6012
6013 assert_eq!(typedstream.type_table, expected_types);
6014 assert_eq!(typedstream.object_table, expected_objects);
6015 }
6016
6017 #[test]
6018 fn test_parse_text_styles_single_range() {
6019 let typedstream_path = current_dir()
6020 .unwrap()
6021 .as_path()
6022 .join("src/test_data/TextStylesSingleRange");
6023 let mut file = File::open(typedstream_path).unwrap();
6024 let mut bytes = vec![];
6025 file.read_to_end(&mut bytes).unwrap();
6026
6027 let mut typedstream = TypedStreamDeserializer::new(&bytes);
6028 let root = typedstream.oxidize().unwrap();
6029 println!("\nResults:");
6030 println!("Root object: {:x?}", typedstream.object_table[root]);
6031 print_resolved(typedstream.resolve_properties(root).unwrap(), 2);
6032
6033 println!("\nFound {:?} types:", typedstream.type_table.len());
6034 typedstream
6035 .type_table
6036 .iter()
6037 .enumerate()
6038 .for_each(|(idx, item)| println!("\t{idx}: {item:?}"));
6039
6040 println!("\nFound {:?} objects:", typedstream.object_table.len());
6041 typedstream
6042 .object_table
6043 .iter()
6044 .enumerate()
6045 .for_each(|(idx, item)| println!("\t{idx}: {item:?}"));
6046
6047 let expected_types = vec![
6048 vec![Type::Object],
6049 vec![Type::String("NSAttributedString")],
6050 vec![Type::String("NSObject")],
6051 vec![Type::String("NSString")],
6052 vec![Type::Utf8String],
6053 vec![Type::SignedInt, Type::UnsignedInt],
6054 vec![Type::String("NSDictionary")],
6055 vec![Type::SignedInt],
6056 vec![Type::String("NSNumber")],
6057 vec![Type::String("NSValue")],
6058 vec![Type::EmbeddedData],
6059 ];
6060
6061 let expected_objects = vec![
6062 Archived::Object {
6063 class: 1,
6064 data: vec![
6065 vec![OutputData::Object(3)],
6066 vec![
6067 OutputData::SignedInteger(1),
6068 OutputData::UnsignedInteger(10),
6069 ],
6070 vec![OutputData::Object(5)],
6071 ],
6072 },
6073 Archived::Class(Class {
6074 name_index: 1,
6075 version: 0,
6076 parent_index: Some(2),
6077 }),
6078 Archived::Class(Class {
6079 name_index: 2,
6080 version: 0,
6081 parent_index: None,
6082 }),
6083 Archived::Object {
6084 class: 4,
6085 data: vec![vec![OutputData::String("Everything")]],
6086 },
6087 Archived::Class(Class {
6088 name_index: 3,
6089 version: 1,
6090 parent_index: Some(2),
6091 }),
6092 Archived::Object {
6093 class: 6,
6094 data: vec![
6095 vec![OutputData::SignedInteger(5)],
6096 vec![OutputData::Object(7)],
6097 vec![OutputData::Object(8)],
6098 vec![OutputData::Object(12)],
6099 vec![OutputData::Object(8)],
6100 vec![OutputData::Object(13)],
6101 vec![OutputData::Object(14)],
6102 vec![OutputData::Object(15)],
6103 vec![OutputData::Object(8)],
6104 vec![OutputData::Object(16)],
6105 vec![OutputData::Object(8)],
6106 ],
6107 },
6108 Archived::Class(Class {
6109 name_index: 6,
6110 version: 0,
6111 parent_index: Some(2),
6112 }),
6113 Archived::Object {
6114 class: 4,
6115 data: vec![vec![OutputData::String("__kIMTextBoldAttributeName")]],
6116 },
6117 Archived::Object {
6118 class: 9,
6119 data: vec![vec![OutputData::SignedInteger(1)]],
6120 },
6121 Archived::Class(Class {
6122 name_index: 8,
6123 version: 0,
6124 parent_index: Some(10),
6125 }),
6126 Archived::Class(Class {
6127 name_index: 9,
6128 version: 0,
6129 parent_index: Some(2),
6130 }),
6131 Archived::Type(7),
6132 Archived::Object {
6133 class: 4,
6134 data: vec![vec![OutputData::String(
6135 "__kIMTextStrikethroughAttributeName",
6136 )]],
6137 },
6138 Archived::Object {
6139 class: 4,
6140 data: vec![vec![OutputData::String("__kIMMessagePartAttributeName")]],
6141 },
6142 Archived::Object {
6143 class: 9,
6144 data: vec![vec![OutputData::SignedInteger(0)]],
6145 },
6146 Archived::Object {
6147 class: 4,
6148 data: vec![vec![OutputData::String("__kIMTextUnderlineAttributeName")]],
6149 },
6150 Archived::Object {
6151 class: 4,
6152 data: vec![vec![OutputData::String("__kIMTextItalicAttributeName")]],
6153 },
6154 ];
6155
6156 assert_eq!(typedstream.type_table, expected_types);
6157 assert_eq!(typedstream.object_table, expected_objects);
6158 }
6159
6160 #[test]
6161 fn test_parse_text_transcription() {
6162 let typedstream_path = current_dir()
6163 .unwrap()
6164 .as_path()
6165 .join("src/test_data/Transcription");
6166 let mut file = File::open(typedstream_path).unwrap();
6167 let mut bytes = vec![];
6168 file.read_to_end(&mut bytes).unwrap();
6169
6170 let mut typedstream = TypedStreamDeserializer::new(&bytes);
6171 let root = typedstream.oxidize().unwrap();
6172 println!("\nResults:");
6173 println!("Root object: {:x?}", typedstream.object_table[root]);
6174 print_resolved(typedstream.resolve_properties(root).unwrap(), 2);
6175
6176 println!("\nFound {:?} types:", typedstream.type_table.len());
6177 typedstream
6178 .type_table
6179 .iter()
6180 .enumerate()
6181 .for_each(|(idx, item)| println!("\t{idx}: {item:?}"));
6182
6183 println!("\nFound {:?} objects:", typedstream.object_table.len());
6184 typedstream
6185 .object_table
6186 .iter()
6187 .enumerate()
6188 .for_each(|(idx, item)| println!("\t{idx}: {item:?}"));
6189
6190 let expected_types = vec![
6191 vec![Type::Object],
6192 vec![Type::String("NSAttributedString")],
6193 vec![Type::String("NSObject")],
6194 vec![Type::String("NSString")],
6195 vec![Type::Utf8String],
6196 vec![Type::SignedInt, Type::UnsignedInt],
6197 vec![Type::String("NSDictionary")],
6198 vec![Type::SignedInt],
6199 vec![Type::String("NSNumber")],
6200 vec![Type::String("NSValue")],
6201 vec![Type::EmbeddedData],
6202 vec![Type::SignedInt],
6203 ];
6204
6205 let expected_objects = vec![
6206 Archived::Object {
6207 class: 1,
6208 data: vec![
6209 vec![OutputData::Object(3)],
6210 vec![OutputData::SignedInteger(1), OutputData::UnsignedInteger(1)],
6211 vec![OutputData::Object(5)],
6212 ],
6213 },
6214 Archived::Class(Class {
6215 name_index: 1,
6216 version: 0,
6217 parent_index: Some(2),
6218 }),
6219 Archived::Class(Class {
6220 name_index: 2,
6221 version: 0,
6222 parent_index: None,
6223 }),
6224 Archived::Object {
6225 class: 4,
6226 data: vec![vec![OutputData::String("")]],
6227 },
6228 Archived::Class(Class {
6229 name_index: 3,
6230 version: 1,
6231 parent_index: Some(2),
6232 }),
6233 Archived::Object {
6234 class: 6,
6235 data: vec![
6236 vec![OutputData::SignedInteger(4)],
6237 vec![OutputData::Object(7)],
6238 vec![OutputData::Object(8)],
6239 vec![OutputData::Object(9)],
6240 vec![OutputData::Object(10)],
6241 vec![OutputData::Object(11)],
6242 vec![OutputData::Object(12)],
6243 vec![OutputData::Object(16)],
6244 vec![OutputData::Object(17)],
6245 ],
6246 },
6247 Archived::Class(Class {
6248 name_index: 6,
6249 version: 0,
6250 parent_index: Some(2),
6251 }),
6252 Archived::Object {
6253 class: 4,
6254 data: vec![vec![OutputData::String(
6255 "__kIMFileTransferGUIDAttributeName",
6256 )]],
6257 },
6258 Archived::Object {
6259 class: 4,
6260 data: vec![vec![OutputData::String(
6261 "4C339597-EBBB-4978-9B87-521C0471A848",
6262 )]],
6263 },
6264 Archived::Object {
6265 class: 4,
6266 data: vec![vec![OutputData::String("IMAudioTranscription")]],
6267 },
6268 Archived::Object {
6269 class: 4,
6270 data: vec![vec![OutputData::String("This is a test")]],
6271 },
6272 Archived::Object {
6273 class: 4,
6274 data: vec![vec![OutputData::String(
6275 "__kIMBaseWritingDirectionAttributeName",
6276 )]],
6277 },
6278 Archived::Object {
6279 class: 13,
6280 data: vec![vec![OutputData::SignedInteger(-1)]],
6281 },
6282 Archived::Class(Class {
6283 name_index: 8,
6284 version: 0,
6285 parent_index: Some(14),
6286 }),
6287 Archived::Class(Class {
6288 name_index: 9,
6289 version: 0,
6290 parent_index: Some(2),
6291 }),
6292 Archived::Type(11),
6293 Archived::Object {
6294 class: 4,
6295 data: vec![vec![OutputData::String("__kIMMessagePartAttributeName")]],
6296 },
6297 Archived::Object {
6298 class: 13,
6299 data: vec![vec![OutputData::SignedInteger(0)]],
6300 },
6301 ];
6302
6303 assert_eq!(typedstream.type_table, expected_types);
6304 assert_eq!(typedstream.object_table, expected_objects);
6305 }
6306
6307 #[test]
6308 fn test_parse_text_url() {
6309 let typedstream_path = current_dir().unwrap().as_path().join("src/test_data/URL");
6310 let mut file = File::open(typedstream_path).unwrap();
6311 let mut bytes = vec![];
6312 file.read_to_end(&mut bytes).unwrap();
6313
6314 let mut typedstream = TypedStreamDeserializer::new(&bytes);
6315 let root = typedstream.oxidize().unwrap();
6316 println!("\nResults:");
6317 println!("Root object: {:x?}", typedstream.object_table[root]);
6318 print_resolved(typedstream.resolve_properties(root).unwrap(), 2);
6319
6320 println!("\nFound {:?} types:", typedstream.type_table.len());
6321 typedstream
6322 .type_table
6323 .iter()
6324 .enumerate()
6325 .for_each(|(idx, item)| println!("\t{idx}: {item:?}"));
6326
6327 println!("\nFound {:?} objects:", typedstream.object_table.len());
6328 typedstream
6329 .object_table
6330 .iter()
6331 .enumerate()
6332 .for_each(|(idx, item)| println!("\t{idx}: {item:?}"));
6333
6334 let expected_types = vec![
6335 vec![Type::Object],
6336 vec![Type::String("NSMutableAttributedString")],
6337 vec![Type::String("NSAttributedString")],
6338 vec![Type::String("NSObject")],
6339 vec![Type::String("NSMutableString")],
6340 vec![Type::String("NSString")],
6341 vec![Type::Utf8String],
6342 vec![Type::SignedInt, Type::UnsignedInt],
6343 vec![Type::String("NSDictionary")],
6344 vec![Type::SignedInt],
6345 vec![Type::String("NSURL")],
6346 vec![Type::SignedInt],
6347 vec![Type::String("NSNumber")],
6348 vec![Type::String("NSValue")],
6349 vec![Type::EmbeddedData],
6350 vec![Type::SignedInt],
6351 vec![Type::String("NSData")],
6352 vec![Type::Array(582)],
6353 ];
6354
6355 let expected_objects = vec![
6356 Archived::Object {
6357 class: 1,
6358 data: vec![
6359 vec![OutputData::Object(4)],
6360 vec![
6361 OutputData::SignedInteger(1),
6362 OutputData::UnsignedInteger(34),
6363 ],
6364 vec![OutputData::Object(7)],
6365 ],
6366 },
6367 Archived::Class(Class {
6368 name_index: 1,
6369 version: 0,
6370 parent_index: Some(2),
6371 }),
6372 Archived::Class(Class {
6373 name_index: 2,
6374 version: 0,
6375 parent_index: Some(3),
6376 }),
6377 Archived::Class(Class {
6378 name_index: 3,
6379 version: 0,
6380 parent_index: None,
6381 }),
6382 Archived::Object {
6383 class: 5,
6384 data: vec![vec![OutputData::String(
6385 "https://github.com/ReagentX/Logria",
6386 )]],
6387 },
6388 Archived::Class(Class {
6389 name_index: 4,
6390 version: 1,
6391 parent_index: Some(6),
6392 }),
6393 Archived::Class(Class {
6394 name_index: 5,
6395 version: 1,
6396 parent_index: Some(3),
6397 }),
6398 Archived::Object {
6399 class: 8,
6400 data: vec![
6401 vec![OutputData::SignedInteger(4)],
6402 vec![OutputData::Object(9)],
6403 vec![OutputData::Object(10)],
6404 vec![OutputData::Object(13)],
6405 vec![OutputData::Object(14)],
6406 vec![OutputData::Object(18)],
6407 vec![OutputData::Object(19)],
6408 vec![OutputData::Object(20)],
6409 vec![OutputData::Object(21)],
6410 ],
6411 },
6412 Archived::Class(Class {
6413 name_index: 8,
6414 version: 0,
6415 parent_index: Some(3),
6416 }),
6417 Archived::Object {
6418 class: 6,
6419 data: vec![vec![OutputData::String("__kIMLinkAttributeName")]],
6420 },
6421 Archived::Object {
6422 class: 11,
6423 data: vec![
6424 vec![OutputData::SignedInteger(0)],
6425 vec![OutputData::Object(12)],
6426 ],
6427 },
6428 Archived::Class(Class {
6429 name_index: 10,
6430 version: 0,
6431 parent_index: Some(3),
6432 }),
6433 Archived::Object {
6434 class: 6,
6435 data: vec![vec![OutputData::String(
6436 "https://github.com/ReagentX/Logria",
6437 )]],
6438 },
6439 Archived::Object {
6440 class: 6,
6441 data: vec![vec![OutputData::String("__kIMMessagePartAttributeName")]],
6442 },
6443 Archived::Object {
6444 class: 15,
6445 data: vec![vec![OutputData::SignedInteger(0)]],
6446 },
6447 Archived::Class(Class {
6448 name_index: 12,
6449 version: 0,
6450 parent_index: Some(16),
6451 }),
6452 Archived::Class(Class {
6453 name_index: 13,
6454 version: 0,
6455 parent_index: Some(3),
6456 }),
6457 Archived::Type(15),
6458 Archived::Object {
6459 class: 6,
6460 data: vec![vec![OutputData::String(
6461 "__kIMBaseWritingDirectionAttributeName",
6462 )]],
6463 },
6464 Archived::Object {
6465 class: 15,
6466 data: vec![vec![OutputData::SignedInteger(-1)]],
6467 },
6468 Archived::Object {
6469 class: 6,
6470 data: vec![vec![OutputData::String("__kIMDataDetectedAttributeName")]],
6471 },
6472 Archived::Object {
6473 class: 22,
6474 data: vec![
6475 vec![OutputData::SignedInteger(582)],
6476 vec![OutputData::Array(&[
6477 98, 112, 108, 105, 115, 116, 48, 48, 212, 1, 2, 3, 4, 5, 6, 7, 12, 88, 36,
6478 118, 101, 114, 115, 105, 111, 110, 89, 36, 97, 114, 99, 104, 105, 118, 101,
6479 114, 84, 36, 116, 111, 112, 88, 36, 111, 98, 106, 101, 99, 116, 115, 18, 0,
6480 1, 134, 160, 95, 16, 15, 78, 83, 75, 101, 121, 101, 100, 65, 114, 99, 104,
6481 105, 118, 101, 114, 210, 8, 9, 10, 11, 87, 118, 101, 114, 115, 105, 111,
6482 110, 89, 100, 100, 45, 114, 101, 115, 117, 108, 116, 128, 11, 128, 1, 172,
6483 13, 14, 28, 36, 37, 38, 44, 45, 46, 50, 54, 58, 85, 36, 110, 117, 108, 108,
6484 215, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 26, 82, 77, 83,
6485 86, 36, 99, 108, 97, 115, 115, 82, 65, 82, 81, 84, 81, 80, 82, 83, 82, 82,
6486 86, 78, 128, 6, 128, 10, 128, 2, 128, 7, 16, 1, 128, 8, 212, 29, 30, 31,
6487 16, 32, 33, 34, 35, 95, 16, 18, 78, 83, 46, 114, 97, 110, 103, 101, 118,
6488 97, 108, 46, 108, 101, 110, 103, 116, 104, 95, 16, 20, 78, 83, 46, 114, 97,
6489 110, 103, 101, 118, 97, 108, 46, 108, 111, 99, 97, 116, 105, 111, 110, 90,
6490 78, 83, 46, 115, 112, 101, 99, 105, 97, 108, 128, 3, 128, 4, 16, 4, 128, 5,
6491 16, 34, 16, 0, 210, 39, 40, 41, 42, 90, 36, 99, 108, 97, 115, 115, 110, 97,
6492 109, 101, 88, 36, 99, 108, 97, 115, 115, 101, 115, 87, 78, 83, 86, 97, 108,
6493 117, 101, 162, 41, 43, 88, 78, 83, 79, 98, 106, 101, 99, 116, 95, 16, 34,
6494 104, 116, 116, 112, 115, 58, 47, 47, 103, 105, 116, 104, 117, 98, 46, 99,
6495 111, 109, 47, 82, 101, 97, 103, 101, 110, 116, 88, 47, 76, 111, 103, 114,
6496 105, 97, 87, 72, 116, 116, 112, 85, 82, 76, 210, 47, 16, 48, 49, 90, 78,
6497 83, 46, 111, 98, 106, 101, 99, 116, 115, 160, 128, 9, 210, 39, 40, 51, 52,
6498 94, 78, 83, 77, 117, 116, 97, 98, 108, 101, 65, 114, 114, 97, 121, 163, 51,
6499 53, 43, 87, 78, 83, 65, 114, 114, 97, 121, 210, 39, 40, 55, 56, 95, 16, 15,
6500 68, 68, 83, 99, 97, 110, 110, 101, 114, 82, 101, 115, 117, 108, 116, 162,
6501 57, 43, 95, 16, 15, 68, 68, 83, 99, 97, 110, 110, 101, 114, 82, 101, 115,
6502 117, 108, 116, 16, 1, 0, 8, 0, 17, 0, 26, 0, 36, 0, 41, 0, 50, 0, 55, 0,
6503 73, 0, 78, 0, 86, 0, 96, 0, 98, 0, 100, 0, 113, 0, 119, 0, 134, 0, 137, 0,
6504 144, 0, 147, 0, 149, 0, 151, 0, 154, 0, 157, 0, 159, 0, 161, 0, 163, 0,
6505 165, 0, 167, 0, 169, 0, 178, 0, 199, 0, 222, 0, 233, 0, 235, 0, 237, 0,
6506 239, 0, 241, 0, 243, 0, 245, 0, 250, 1, 5, 1, 14, 1, 22, 1, 25, 1, 34, 1,
6507 71, 1, 79, 1, 84, 1, 95, 1, 96, 1, 98, 1, 103, 1, 118, 1, 122, 1, 130, 1,
6508 135, 1, 153, 1, 156, 1, 174, 0, 0, 0, 0, 0, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0,
6509 59, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 176,
6510 ])],
6511 ],
6512 },
6513 Archived::Class(Class {
6514 name_index: 16,
6515 version: 0,
6516 parent_index: Some(3),
6517 }),
6518 ];
6519
6520 assert_eq!(typedstream.type_table, expected_types);
6521 assert_eq!(typedstream.object_table, expected_objects);
6522 }
6523
6524 #[test]
6525 fn test_parse_text_url_message() {
6526 let typedstream_path = current_dir()
6527 .unwrap()
6528 .as_path()
6529 .join("src/test_data/URLMessage");
6530 let mut file = File::open(typedstream_path).unwrap();
6531 let mut bytes = vec![];
6532 file.read_to_end(&mut bytes).unwrap();
6533
6534 let mut typedstream = TypedStreamDeserializer::new(&bytes);
6535 let root = typedstream.oxidize().unwrap();
6536 println!("\nResults:");
6537 println!("Root object: {:x?}", typedstream.object_table[root]);
6538 print_resolved(typedstream.resolve_properties(root).unwrap(), 2);
6539
6540 println!("\nFound {:?} types:", typedstream.type_table.len());
6541 typedstream
6542 .type_table
6543 .iter()
6544 .enumerate()
6545 .for_each(|(idx, item)| println!("\t{idx}: {item:?}"));
6546
6547 println!("\nFound {:?} objects:", typedstream.object_table.len());
6548 typedstream
6549 .object_table
6550 .iter()
6551 .enumerate()
6552 .for_each(|(idx, item)| println!("\t{idx}: {item:?}"));
6553
6554 let expected_types = vec![
6555 vec![Type::Object],
6556 vec![Type::String("NSMutableAttributedString")],
6557 vec![Type::String("NSAttributedString")],
6558 vec![Type::String("NSObject")],
6559 vec![Type::String("NSMutableString")],
6560 vec![Type::String("NSString")],
6561 vec![Type::Utf8String],
6562 vec![Type::SignedInt, Type::UnsignedInt],
6563 vec![Type::String("NSDictionary")],
6564 vec![Type::SignedInt],
6565 vec![Type::String("NSURL")],
6566 vec![Type::SignedInt],
6567 vec![Type::String("NSNumber")],
6568 vec![Type::String("NSValue")],
6569 vec![Type::EmbeddedData],
6570 vec![Type::SignedInt],
6571 vec![Type::String("NSMutableData")],
6572 vec![Type::String("NSData")],
6573 vec![Type::Array(604)],
6574 ];
6575
6576 let expected_objects = vec![
6577 Archived::Object {
6578 class: 1,
6579 data: vec![
6580 vec![OutputData::Object(4)],
6581 vec![
6582 OutputData::SignedInteger(1),
6583 OutputData::UnsignedInteger(56),
6584 ],
6585 vec![OutputData::Object(7)],
6586 ],
6587 },
6588 Archived::Class(Class {
6589 name_index: 1,
6590 version: 0,
6591 parent_index: Some(2),
6592 }),
6593 Archived::Class(Class {
6594 name_index: 2,
6595 version: 0,
6596 parent_index: Some(3),
6597 }),
6598 Archived::Class(Class {
6599 name_index: 3,
6600 version: 0,
6601 parent_index: None,
6602 }),
6603 Archived::Object {
6604 class: 5,
6605 data: vec![vec![OutputData::String(
6606 "https://twitter.com/xxxxxxxxx/status/0000223300009216128",
6607 )]],
6608 },
6609 Archived::Class(Class {
6610 name_index: 4,
6611 version: 1,
6612 parent_index: Some(6),
6613 }),
6614 Archived::Class(Class {
6615 name_index: 5,
6616 version: 1,
6617 parent_index: Some(3),
6618 }),
6619 Archived::Object {
6620 class: 8,
6621 data: vec![
6622 vec![OutputData::SignedInteger(4)],
6623 vec![OutputData::Object(9)],
6624 vec![OutputData::Object(10)],
6625 vec![OutputData::Object(13)],
6626 vec![OutputData::Object(14)],
6627 vec![OutputData::Object(18)],
6628 vec![OutputData::Object(19)],
6629 vec![OutputData::Object(22)],
6630 vec![OutputData::Object(23)],
6631 ],
6632 },
6633 Archived::Class(Class {
6634 name_index: 8,
6635 version: 0,
6636 parent_index: Some(3),
6637 }),
6638 Archived::Object {
6639 class: 6,
6640 data: vec![vec![OutputData::String("__kIMLinkAttributeName")]],
6641 },
6642 Archived::Object {
6643 class: 11,
6644 data: vec![
6645 vec![OutputData::SignedInteger(0)],
6646 vec![OutputData::Object(12)],
6647 ],
6648 },
6649 Archived::Class(Class {
6650 name_index: 10,
6651 version: 0,
6652 parent_index: Some(3),
6653 }),
6654 Archived::Object {
6655 class: 6,
6656 data: vec![vec![OutputData::String(
6657 "https://twitter.com/xxxxxxxxx/status/0000223300009216128",
6658 )]],
6659 },
6660 Archived::Object {
6661 class: 6,
6662 data: vec![vec![OutputData::String("__kIMMessagePartAttributeName")]],
6663 },
6664 Archived::Object {
6665 class: 15,
6666 data: vec![vec![OutputData::SignedInteger(0)]],
6667 },
6668 Archived::Class(Class {
6669 name_index: 12,
6670 version: 0,
6671 parent_index: Some(16),
6672 }),
6673 Archived::Class(Class {
6674 name_index: 13,
6675 version: 0,
6676 parent_index: Some(3),
6677 }),
6678 Archived::Type(15),
6679 Archived::Object {
6680 class: 6,
6681 data: vec![vec![OutputData::String("__kIMDataDetectedAttributeName")]],
6682 },
6683 Archived::Object {
6684 class: 20,
6685 data: vec![
6686 vec![OutputData::SignedInteger(604)],
6687 vec![OutputData::Array(&[
6688 98, 112, 108, 105, 115, 116, 48, 48, 212, 1, 2, 3, 4, 5, 6, 7, 12, 88, 36,
6689 118, 101, 114, 115, 105, 111, 110, 89, 36, 97, 114, 99, 104, 105, 118, 101,
6690 114, 84, 36, 116, 111, 112, 88, 36, 111, 98, 106, 101, 99, 116, 115, 18, 0,
6691 1, 134, 160, 95, 16, 15, 78, 83, 75, 101, 121, 101, 100, 65, 114, 99, 104,
6692 105, 118, 101, 114, 210, 8, 9, 13, 11, 87, 118, 101, 114, 115, 105, 111,
6693 110, 89, 100, 100, 45, 114, 101, 115, 117, 108, 116, 128, 11, 128, 1, 172,
6694 13, 14, 28, 36, 37, 38, 44, 45, 46, 50, 54, 58, 85, 36, 110, 117, 108, 108,
6695 215, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 26, 82, 77, 83,
6696 86, 36, 99, 108, 97, 115, 115, 82, 65, 82, 81, 84, 81, 80, 82, 83, 82, 82,
6697 86, 78, 128, 6, 128, 13, 128, 2, 128, 7, 16, 1, 128, 8, 212, 29, 30, 31,
6698 16, 32, 33, 34, 35, 95, 16, 18, 78, 83, 46, 114, 97, 110, 103, 101, 118,
6699 97, 108, 46, 108, 101, 110, 103, 116, 104, 95, 16, 20, 78, 83, 46, 114, 97,
6700 110, 103, 101, 118, 97, 108, 46, 108, 111, 99, 97, 116, 105, 111, 110, 90,
6701 78, 83, 46, 115, 112, 101, 99, 105, 97, 108, 128, 3, 128, 4, 16, 4, 128, 5,
6702 16, 56, 16, 0, 210, 39, 40, 41, 42, 90, 36, 99, 108, 97, 115, 115, 110, 97,
6703 109, 101, 88, 36, 99, 108, 97, 115, 115, 101, 115, 87, 78, 83, 86, 97, 108,
6704 117, 101, 162, 41, 43, 88, 78, 83, 79, 98, 106, 101, 99, 116, 95, 16, 56,
6705 104, 116, 116, 112, 115, 58, 47, 47, 116, 119, 105, 116, 116, 101, 114, 46,
6706 99, 111, 109, 47, 120, 120, 120, 120, 120, 120, 120, 120, 120, 47, 115,
6707 116, 97, 116, 117, 115, 47, 48, 48, 48, 48, 50, 50, 51, 51, 48, 48, 48, 48,
6708 57, 50, 49, 54, 49, 50, 56, 87, 72, 116, 116, 112, 85, 82, 76, 210, 47, 16,
6709 48, 49, 90, 78, 83, 46, 111, 98, 106, 101, 99, 116, 115, 160, 128, 9, 210,
6710 39, 40, 51, 52, 94, 78, 83, 77, 117, 116, 97, 98, 108, 101, 65, 114, 114,
6711 97, 121, 163, 51, 53, 43, 87, 78, 83, 65, 114, 114, 97, 121, 210, 39, 40,
6712 55, 56, 95, 16, 15, 68, 68, 83, 99, 97, 110, 110, 101, 114, 82, 101, 115,
6713 117, 108, 116, 162, 57, 43, 95, 16, 15, 68, 68, 83, 99, 97, 110, 110, 101,
6714 114, 82, 101, 115, 117, 108, 116, 16, 1, 0, 8, 0, 17, 0, 26, 0, 36, 0, 41,
6715 0, 50, 0, 55, 0, 73, 0, 78, 0, 86, 0, 96, 0, 98, 0, 100, 0, 113, 0, 119, 0,
6716 134, 0, 137, 0, 144, 0, 147, 0, 149, 0, 151, 0, 154, 0, 157, 0, 159, 0,
6717 161, 0, 163, 0, 165, 0, 167, 0, 169, 0, 178, 0, 199, 0, 222, 0, 233, 0,
6718 235, 0, 237, 0, 239, 0, 241, 0, 243, 0, 245, 0, 250, 1, 5, 1, 14, 1, 22, 1,
6719 25, 1, 34, 1, 93, 1, 101, 1, 106, 1, 117, 1, 118, 1, 120, 1, 125, 1, 140,
6720 1, 144, 1, 152, 1, 157, 1, 175, 1, 178, 1, 196, 0, 0, 0, 0, 0, 0, 2, 1, 0,
6721 0, 0, 0, 0, 0, 0, 59, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 198,
6722 ])],
6723 ],
6724 },
6725 Archived::Class(Class {
6726 name_index: 16,
6727 version: 0,
6728 parent_index: Some(21),
6729 }),
6730 Archived::Class(Class {
6731 name_index: 17,
6732 version: 0,
6733 parent_index: Some(3),
6734 }),
6735 Archived::Object {
6736 class: 6,
6737 data: vec![vec![OutputData::String(
6738 "__kIMBaseWritingDirectionAttributeName",
6739 )]],
6740 },
6741 Archived::Object {
6742 class: 15,
6743 data: vec![vec![OutputData::SignedInteger(-1)]],
6744 },
6745 ];
6746
6747 assert_eq!(typedstream.type_table, expected_types);
6748 assert_eq!(typedstream.object_table, expected_objects);
6749 }
6750
6751 #[test]
6752 fn test_parse_text_weird() {
6753 let typedstream_path = current_dir()
6754 .unwrap()
6755 .as_path()
6756 .join("src/test_data/WeirdText");
6757 let mut file = File::open(typedstream_path).unwrap();
6758 let mut bytes = vec![];
6759 file.read_to_end(&mut bytes).unwrap();
6760
6761 let mut typedstream = TypedStreamDeserializer::new(&bytes);
6762 let root = typedstream.oxidize().unwrap();
6763 println!("\nResults:");
6764 println!("Root object: {:x?}", typedstream.object_table[root]);
6765 print_resolved(typedstream.resolve_properties(root).unwrap(), 2);
6766
6767 println!("\nFound {:?} types:", typedstream.type_table.len());
6768 typedstream
6769 .type_table
6770 .iter()
6771 .enumerate()
6772 .for_each(|(idx, item)| println!("\t{idx}: {item:?}"));
6773
6774 println!("\nFound {:?} objects:", typedstream.object_table.len());
6775 typedstream
6776 .object_table
6777 .iter()
6778 .enumerate()
6779 .for_each(|(idx, item)| println!("\t{idx}: {item:?}"));
6780
6781 let expected_types = vec![
6782 vec![Type::Object],
6783 vec![Type::String("NSMutableAttributedString")],
6784 vec![Type::String("NSAttributedString")],
6785 vec![Type::String("NSObject")],
6786 vec![Type::String("NSMutableString")],
6787 vec![Type::String("NSString")],
6788 vec![Type::Utf8String],
6789 vec![Type::SignedInt, Type::UnsignedInt],
6790 vec![Type::String("NSDictionary")],
6791 vec![Type::SignedInt],
6792 vec![Type::String("NSNumber")],
6793 vec![Type::String("NSValue")],
6794 vec![Type::EmbeddedData],
6795 ];
6796
6797 let expected_objects = vec![
6798 Archived::Object {
6799 class: 1,
6800 data: vec![
6801 vec![OutputData::Object(4)],
6802 vec![
6803 OutputData::SignedInteger(1),
6804 OutputData::UnsignedInteger(21),
6805 ],
6806 vec![OutputData::Object(7)],
6807 ],
6808 },
6809 Archived::Class(Class {
6810 name_index: 1,
6811 version: 0,
6812 parent_index: Some(2),
6813 }),
6814 Archived::Class(Class {
6815 name_index: 2,
6816 version: 0,
6817 parent_index: Some(3),
6818 }),
6819 Archived::Class(Class {
6820 name_index: 3,
6821 version: 0,
6822 parent_index: None,
6823 }),
6824 Archived::Object {
6825 class: 5,
6826 data: vec![vec![OutputData::String("𝖍𝖊𝖑𝖑𝖔 𝖜𝖔𝖗𝖑𝖉")]],
6827 },
6828 Archived::Class(Class {
6829 name_index: 4,
6830 version: 1,
6831 parent_index: Some(6),
6832 }),
6833 Archived::Class(Class {
6834 name_index: 5,
6835 version: 1,
6836 parent_index: Some(3),
6837 }),
6838 Archived::Object {
6839 class: 8,
6840 data: vec![
6841 vec![OutputData::SignedInteger(1)],
6842 vec![OutputData::Object(9)],
6843 vec![OutputData::Object(10)],
6844 ],
6845 },
6846 Archived::Class(Class {
6847 name_index: 8,
6848 version: 0,
6849 parent_index: Some(3),
6850 }),
6851 Archived::Object {
6852 class: 6,
6853 data: vec![vec![OutputData::String("__kIMMessagePartAttributeName")]],
6854 },
6855 Archived::Object {
6856 class: 11,
6857 data: vec![vec![OutputData::SignedInteger(0)]],
6858 },
6859 Archived::Class(Class {
6860 name_index: 10,
6861 version: 0,
6862 parent_index: Some(12),
6863 }),
6864 Archived::Class(Class {
6865 name_index: 11,
6866 version: 0,
6867 parent_index: Some(3),
6868 }),
6869 Archived::Type(9),
6870 ];
6871
6872 assert_eq!(typedstream.type_table, expected_types);
6873 assert_eq!(typedstream.object_table, expected_objects);
6874 }
6875
6876 #[test]
6877 fn test_parse_large_with_null() {
6878 let typedstream_path = current_dir()
6879 .unwrap()
6880 .as_path()
6881 .join("src/test_data/HugeWithRefs");
6882 let mut file = File::open(typedstream_path).unwrap();
6883 let mut bytes = vec![];
6884 file.read_to_end(&mut bytes).unwrap();
6885
6886 let mut typedstream = TypedStreamDeserializer::new(&bytes);
6887
6888 let root = typedstream.oxidize().unwrap();
6890 println!("\nResults: {root:?}");
6891 let root_obj = typedstream.resolve_properties(root).unwrap();
6893 println!("\nResults: {root_obj:?}");
6894
6895 let primitives = root_obj.primitives();
6897 println!("\nPrimitive Values: {primitives:?}");
6898 }
6899}