From 2eb4e2a2f70ec08e7fcdaac969d2d76344664714 Mon Sep 17 00:00:00 2001 From: Christopher Sardegna Date: Sat, 6 Jun 2026 12:35:55 -0700 Subject: [PATCH] Add new binary test data files for various new categories --- src/lib.rs | 1157 +++++++++++++++++ src/test_data/Address | Bin 0 -> 1474 bytes src/test_data/Arabic | Bin 0 -> 200 bytes src/test_data/Currency | Bin 0 -> 205 bytes src/test_data/CurrencyTemperatureVolumeWeight | Bin 0 -> 2670 bytes src/test_data/Flight | Bin 0 -> 1046 bytes src/test_data/Tracking | Bin 0 -> 967 bytes 7 files changed, 1157 insertions(+) create mode 100644 src/test_data/Address create mode 100644 src/test_data/Arabic create mode 100644 src/test_data/Currency create mode 100644 src/test_data/CurrencyTemperatureVolumeWeight create mode 100644 src/test_data/Flight create mode 100644 src/test_data/Tracking diff --git a/src/lib.rs b/src/lib.rs index 61269ac..0ed20f5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -7103,4 +7103,1161 @@ mod test_typedstream_deserializer { let primitives = root_obj.primitives(); println!("\nPrimitive Values: {primitives:?}"); } + + #[test] + fn test_parse_text_address() { + let typedstream_path = current_dir() + .unwrap() + .as_path() + .join("src/test_data/Address"); + let mut file = File::open(typedstream_path).unwrap(); + let mut bytes = vec![]; + file.read_to_end(&mut bytes).unwrap(); + + let mut typedstream = TypedStreamDeserializer::new(&bytes); + let root = typedstream.oxidize().unwrap(); + println!("\nResults:"); + println!("Root object: {:x?}", typedstream.object_table[root]); + print_resolved(typedstream.resolve_properties(root).unwrap(), 2); + + println!("\nFound {:?} types:", typedstream.type_table.len()); + typedstream + .type_table + .iter() + .enumerate() + .for_each(|(idx, item)| println!("\t{idx}: {item:?}")); + + println!("\nFound {:?} objects:", typedstream.object_table.len()); + typedstream + .object_table + .iter() + .enumerate() + .for_each(|(idx, item)| println!("\t{idx}: {item:?}")); + + let expected_types = vec![ + TypeEntry::from_types(vec![Type::Object]), + TypeEntry::from_types(vec![Type::String("NSAttributedString")]), + TypeEntry::from_types(vec![Type::String("NSObject")]), + TypeEntry::from_types(vec![Type::String("NSString")]), + TypeEntry::from_types(vec![Type::Utf8String]), + TypeEntry::from_types(vec![Type::SignedInt, Type::UnsignedInt]), + TypeEntry::from_types(vec![Type::String("NSDictionary")]), + TypeEntry::from_types(vec![Type::SignedInt]), + TypeEntry::from_types(vec![Type::String("NSMutableData")]), + TypeEntry::from_types(vec![Type::String("NSData")]), + TypeEntry::from_types(vec![Type::Array(1187)]), + TypeEntry::from_types(vec![Type::String("NSNumber")]), + TypeEntry::from_types(vec![Type::String("NSValue")]), + TypeEntry::from_types(vec![Type::EmbeddedData]), + ]; + + let expected_objects = vec![ + Archived::Object { + class: 1, + data: ObjectData::from_groups(vec![ + vec![OutputData::Object(3)], + vec![ + OutputData::SignedInteger(1), + OutputData::UnsignedInteger(37), + ], + vec![OutputData::Object(5)], + ]), + }, + Archived::Class(Class { + name_index: 1, + version: 0, + parent_index: Some(2), + }), + Archived::Class(Class { + name_index: 2, + version: 0, + parent_index: None, + }), + Archived::Object { + class: 4, + data: ObjectData::from_groups(vec![vec![OutputData::String( + "1 Apple Park Way, Cupertino, CA 95014", + )]]), + }, + Archived::Class(Class { + name_index: 3, + version: 1, + parent_index: Some(2), + }), + Archived::Object { + class: 6, + data: ObjectData::from_groups(vec![ + vec![OutputData::SignedInteger(2)], + vec![OutputData::Object(7)], + vec![OutputData::Object(8)], + vec![OutputData::Object(11)], + vec![OutputData::Object(12)], + ]), + }, + Archived::Class(Class { + name_index: 6, + version: 0, + parent_index: Some(2), + }), + Archived::Object { + class: 4, + data: ObjectData::from_groups(vec![vec![OutputData::String( + "__kIMAddressAttributeName", + )]]), + }, + Archived::Object { + class: 9, + data: ObjectData::from_groups(vec![ + vec![OutputData::SignedInteger(1187)], + vec![OutputData::Array(&[ + 98, 112, 108, 105, 115, 116, 48, 48, 212, 1, 2, 3, 4, 5, 6, 7, 12, 88, 36, + 118, 101, 114, 115, 105, 111, 110, 89, 36, 97, 114, 99, 104, 105, 118, 101, + 114, 84, 36, 116, 111, 112, 88, 36, 111, 98, 106, 101, 99, 116, 115, 18, 0, + 1, 134, 160, 95, 16, 15, 78, 83, 75, 101, 121, 101, 100, 65, 114, 99, 104, + 105, 118, 101, 114, 210, 8, 9, 10, 11, 87, 118, 101, 114, 115, 105, 111, + 110, 89, 100, 100, 45, 114, 101, 115, 117, 108, 116, 128, 46, 128, 1, 175, + 16, 47, 13, 14, 28, 36, 37, 38, 44, 45, 46, 54, 60, 64, 65, 66, 67, 72, 78, + 26, 82, 83, 84, 87, 90, 94, 100, 104, 105, 106, 107, 108, 114, 118, 119, + 120, 121, 122, 128, 132, 133, 134, 135, 141, 145, 146, 147, 148, 149, 85, + 36, 110, 117, 108, 108, 215, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 26, 27, 26, 82, 77, 83, 86, 36, 99, 108, 97, 115, 115, 82, 65, 82, 81, 84, + 81, 80, 82, 83, 82, 82, 86, 78, 128, 6, 128, 22, 128, 2, 128, 7, 16, 1, + 128, 8, 212, 29, 30, 31, 16, 32, 33, 34, 35, 95, 16, 18, 78, 83, 46, 114, + 97, 110, 103, 101, 118, 97, 108, 46, 108, 101, 110, 103, 116, 104, 95, 16, + 20, 78, 83, 46, 114, 97, 110, 103, 101, 118, 97, 108, 46, 108, 111, 99, 97, + 116, 105, 111, 110, 90, 78, 83, 46, 115, 112, 101, 99, 105, 97, 108, 128, + 3, 128, 4, 16, 4, 128, 5, 16, 37, 16, 0, 210, 39, 40, 41, 42, 90, 36, 99, + 108, 97, 115, 115, 110, 97, 109, 101, 88, 36, 99, 108, 97, 115, 115, 101, + 115, 87, 78, 83, 86, 97, 108, 117, 101, 162, 41, 43, 88, 78, 83, 79, 98, + 106, 101, 99, 116, 95, 16, 37, 49, 32, 65, 112, 112, 108, 101, 32, 80, 97, + 114, 107, 32, 87, 97, 121, 44, 32, 67, 117, 112, 101, 114, 116, 105, 110, + 111, 44, 32, 67, 65, 32, 57, 53, 48, 49, 52, 91, 70, 117, 108, 108, 65, + 100, 100, 114, 101, 115, 115, 210, 47, 16, 48, 53, 90, 78, 83, 46, 111, 98, + 106, 101, 99, 116, 115, 164, 49, 50, 51, 52, 128, 9, 128, 29, 128, 35, 128, + 40, 128, 21, 215, 15, 16, 17, 18, 19, 20, 21, 55, 23, 57, 58, 26, 59, 26, + 128, 12, 128, 22, 128, 10, 128, 13, 128, 14, 212, 29, 30, 31, 16, 61, 33, + 34, 35, 128, 11, 128, 4, 128, 5, 16, 16, 95, 16, 16, 49, 32, 65, 112, 112, + 108, 101, 32, 80, 97, 114, 107, 32, 87, 97, 121, 86, 83, 116, 114, 101, + 101, 116, 210, 47, 16, 68, 53, 162, 69, 70, 128, 15, 128, 23, 128, 21, 215, + 15, 16, 17, 18, 19, 20, 21, 73, 23, 75, 76, 26, 77, 26, 128, 18, 128, 22, + 128, 16, 128, 19, 128, 20, 212, 29, 30, 31, 16, 79, 33, 34, 35, 128, 17, + 128, 4, 128, 5, 81, 49, 92, 83, 116, 114, 101, 101, 116, 78, 117, 109, 98, + 101, 114, 210, 47, 16, 85, 53, 160, 128, 21, 210, 39, 40, 88, 89, 87, 78, + 83, 65, 114, 114, 97, 121, 162, 88, 43, 210, 39, 40, 91, 92, 95, 16, 15, + 68, 68, 83, 99, 97, 110, 110, 101, 114, 82, 101, 115, 117, 108, 116, 162, + 93, 43, 95, 16, 15, 68, 68, 83, 99, 97, 110, 110, 101, 114, 82, 101, 115, + 117, 108, 116, 215, 15, 16, 17, 18, 19, 20, 21, 95, 23, 97, 98, 26, 77, 26, + 128, 27, 128, 22, 128, 24, 128, 28, 128, 20, 212, 29, 30, 31, 16, 101, 102, + 34, 35, 128, 25, 128, 26, 128, 5, 16, 14, 16, 2, 94, 65, 112, 112, 108, + 101, 32, 80, 97, 114, 107, 32, 87, 97, 121, 90, 83, 116, 114, 101, 101, + 116, 78, 97, 109, 101, 215, 15, 16, 17, 18, 19, 20, 21, 109, 23, 111, 112, + 26, 77, 26, 128, 33, 128, 22, 128, 30, 128, 34, 128, 20, 212, 29, 30, 31, + 16, 115, 116, 34, 35, 128, 31, 128, 32, 128, 5, 16, 9, 16, 18, 89, 67, 117, + 112, 101, 114, 116, 105, 110, 111, 84, 67, 105, 116, 121, 215, 15, 16, 17, + 18, 19, 20, 21, 123, 23, 125, 126, 26, 77, 26, 128, 38, 128, 22, 128, 36, + 128, 39, 128, 20, 212, 29, 30, 31, 16, 102, 130, 34, 35, 128, 26, 128, 37, + 128, 5, 16, 29, 82, 67, 65, 85, 83, 116, 97, 116, 101, 215, 15, 16, 17, 18, + 19, 20, 21, 136, 23, 138, 139, 26, 77, 26, 128, 44, 128, 22, 128, 41, 128, + 45, 128, 20, 212, 29, 30, 31, 16, 142, 143, 34, 35, 128, 42, 128, 43, 128, + 5, 16, 5, 16, 32, 85, 57, 53, 48, 49, 52, 87, 90, 105, 112, 67, 111, 100, + 101, 16, 1, 0, 8, 0, 17, 0, 26, 0, 36, 0, 41, 0, 50, 0, 55, 0, 73, 0, 78, + 0, 86, 0, 96, 0, 98, 0, 100, 0, 150, 0, 156, 0, 171, 0, 174, 0, 181, 0, + 184, 0, 186, 0, 188, 0, 191, 0, 194, 0, 196, 0, 198, 0, 200, 0, 202, 0, + 204, 0, 206, 0, 215, 0, 236, 1, 3, 1, 14, 1, 16, 1, 18, 1, 20, 1, 22, 1, + 24, 1, 26, 1, 31, 1, 42, 1, 51, 1, 59, 1, 62, 1, 71, 1, 111, 1, 123, 1, + 128, 1, 139, 1, 144, 1, 146, 1, 148, 1, 150, 1, 152, 1, 154, 1, 169, 1, + 171, 1, 173, 1, 175, 1, 177, 1, 179, 1, 188, 1, 190, 1, 192, 1, 194, 1, + 196, 1, 215, 1, 222, 1, 227, 1, 230, 1, 232, 1, 234, 1, 236, 1, 251, 1, + 253, 1, 255, 2, 1, 2, 3, 2, 5, 2, 14, 2, 16, 2, 18, 2, 20, 2, 22, 2, 35, 2, + 40, 2, 41, 2, 43, 2, 48, 2, 56, 2, 59, 2, 64, 2, 82, 2, 85, 2, 103, 2, 118, + 2, 120, 2, 122, 2, 124, 2, 126, 2, 128, 2, 137, 2, 139, 2, 141, 2, 143, 2, + 145, 2, 147, 2, 162, 2, 173, 2, 188, 2, 190, 2, 192, 2, 194, 2, 196, 2, + 198, 2, 207, 2, 209, 2, 211, 2, 213, 2, 215, 2, 217, 2, 227, 2, 232, 2, + 247, 2, 249, 2, 251, 2, 253, 2, 255, 3, 1, 3, 10, 3, 12, 3, 14, 3, 16, 3, + 18, 3, 21, 3, 27, 3, 42, 3, 44, 3, 46, 3, 48, 3, 50, 3, 52, 3, 61, 3, 63, + 3, 65, 3, 67, 3, 69, 3, 71, 3, 77, 3, 85, 0, 0, 0, 0, 0, 0, 2, 1, 0, 0, 0, + 0, 0, 0, 0, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 87, + ])], + ]), + }, + Archived::Class(Class { + name_index: 8, + version: 0, + parent_index: Some(10), + }), + Archived::Class(Class { + name_index: 9, + version: 0, + parent_index: Some(2), + }), + Archived::Object { + class: 4, + data: ObjectData::from_groups(vec![vec![OutputData::String( + "__kIMMessagePartAttributeName", + )]]), + }, + Archived::Object { + class: 13, + data: ObjectData::from_groups(vec![vec![OutputData::SignedInteger(0)]]), + }, + Archived::Class(Class { + name_index: 11, + version: 0, + parent_index: Some(14), + }), + Archived::Class(Class { + name_index: 12, + version: 0, + parent_index: Some(2), + }), + Archived::Type(7), + ]; + + assert_eq!(typedstream.type_table, expected_types); + assert_eq!(typedstream.object_table, expected_objects); + } + + #[test] + fn test_parse_text_arabic() { + let typedstream_path = current_dir() + .unwrap() + .as_path() + .join("src/test_data/Arabic"); + let mut file = File::open(typedstream_path).unwrap(); + let mut bytes = vec![]; + file.read_to_end(&mut bytes).unwrap(); + + let mut typedstream = TypedStreamDeserializer::new(&bytes); + let root = typedstream.oxidize().unwrap(); + println!("\nResults:"); + println!("Root object: {:x?}", typedstream.object_table[root]); + print_resolved(typedstream.resolve_properties(root).unwrap(), 2); + + println!("\nFound {:?} types:", typedstream.type_table.len()); + typedstream + .type_table + .iter() + .enumerate() + .for_each(|(idx, item)| println!("\t{idx}: {item:?}")); + + println!("\nFound {:?} objects:", typedstream.object_table.len()); + typedstream + .object_table + .iter() + .enumerate() + .for_each(|(idx, item)| println!("\t{idx}: {item:?}")); + + let expected_types = vec![ + TypeEntry::from_types(vec![Type::Object]), + TypeEntry::from_types(vec![Type::String("NSAttributedString")]), + TypeEntry::from_types(vec![Type::String("NSObject")]), + TypeEntry::from_types(vec![Type::String("NSString")]), + TypeEntry::from_types(vec![Type::Utf8String]), + TypeEntry::from_types(vec![Type::SignedInt, Type::UnsignedInt]), + TypeEntry::from_types(vec![Type::String("NSDictionary")]), + TypeEntry::from_types(vec![Type::SignedInt]), + TypeEntry::from_types(vec![Type::String("NSNumber")]), + TypeEntry::from_types(vec![Type::String("NSValue")]), + TypeEntry::from_types(vec![Type::EmbeddedData]), + ]; + + let expected_objects = vec![ + Archived::Object { + class: 1, + data: ObjectData::from_groups(vec![ + vec![OutputData::Object(3)], + vec![ + OutputData::SignedInteger(1), + OutputData::UnsignedInteger(13), + ], + vec![OutputData::Object(5)], + ]), + }, + Archived::Class(Class { + name_index: 1, + version: 0, + parent_index: Some(2), + }), + Archived::Class(Class { + name_index: 2, + version: 0, + parent_index: None, + }), + Archived::Object { + class: 4, + data: ObjectData::from_groups(vec![vec![OutputData::String("أهلا\u{64b} بالعالم")]]), + }, + Archived::Class(Class { + name_index: 3, + version: 1, + parent_index: Some(2), + }), + Archived::Object { + class: 6, + data: ObjectData::from_groups(vec![ + vec![OutputData::SignedInteger(1)], + vec![OutputData::Object(7)], + vec![OutputData::Object(8)], + ]), + }, + Archived::Class(Class { + name_index: 6, + version: 0, + parent_index: Some(2), + }), + Archived::Object { + class: 4, + data: ObjectData::from_groups(vec![vec![OutputData::String( + "__kIMMessagePartAttributeName", + )]]), + }, + Archived::Object { + class: 9, + data: ObjectData::from_groups(vec![vec![OutputData::SignedInteger(0)]]), + }, + Archived::Class(Class { + name_index: 8, + version: 0, + parent_index: Some(10), + }), + Archived::Class(Class { + name_index: 9, + version: 0, + parent_index: Some(2), + }), + Archived::Type(7), + ]; + + assert_eq!(typedstream.type_table, expected_types); + assert_eq!(typedstream.object_table, expected_objects); + } + + #[test] + fn test_parse_text_currency() { + let typedstream_path = current_dir() + .unwrap() + .as_path() + .join("src/test_data/Currency"); + let mut file = File::open(typedstream_path).unwrap(); + let mut bytes = vec![]; + file.read_to_end(&mut bytes).unwrap(); + + let mut typedstream = TypedStreamDeserializer::new(&bytes); + let root = typedstream.oxidize().unwrap(); + println!("\nResults:"); + println!("Root object: {:x?}", typedstream.object_table[root]); + print_resolved(typedstream.resolve_properties(root).unwrap(), 2); + + println!("\nFound {:?} types:", typedstream.type_table.len()); + typedstream + .type_table + .iter() + .enumerate() + .for_each(|(idx, item)| println!("\t{idx}: {item:?}")); + + println!("\nFound {:?} objects:", typedstream.object_table.len()); + typedstream + .object_table + .iter() + .enumerate() + .for_each(|(idx, item)| println!("\t{idx}: {item:?}")); + + let expected_types = vec![ + TypeEntry::from_types(vec![Type::Object]), + TypeEntry::from_types(vec![Type::String("NSAttributedString")]), + TypeEntry::from_types(vec![Type::String("NSObject")]), + TypeEntry::from_types(vec![Type::String("NSString")]), + TypeEntry::from_types(vec![Type::Utf8String]), + TypeEntry::from_types(vec![Type::SignedInt, Type::UnsignedInt]), + TypeEntry::from_types(vec![Type::String("NSDictionary")]), + TypeEntry::from_types(vec![Type::SignedInt]), + TypeEntry::from_types(vec![Type::String("NSNumber")]), + TypeEntry::from_types(vec![Type::String("NSValue")]), + TypeEntry::from_types(vec![Type::EmbeddedData]), + ]; + + let expected_objects = vec![ + Archived::Object { + class: 1, + data: ObjectData::from_groups(vec![ + vec![OutputData::Object(3)], + vec![ + OutputData::SignedInteger(1), + OutputData::UnsignedInteger(29), + ], + vec![OutputData::Object(5)], + ]), + }, + Archived::Class(Class { + name_index: 1, + version: 0, + parent_index: Some(2), + }), + Archived::Class(Class { + name_index: 2, + version: 0, + parent_index: None, + }), + Archived::Object { + class: 4, + data: ObjectData::from_groups(vec![vec![OutputData::String( + "Money: $1234.56, £20, 100 USD", + )]]), + }, + Archived::Class(Class { + name_index: 3, + version: 1, + parent_index: Some(2), + }), + Archived::Object { + class: 6, + data: ObjectData::from_groups(vec![ + vec![OutputData::SignedInteger(1)], + vec![OutputData::Object(7)], + vec![OutputData::Object(8)], + ]), + }, + Archived::Class(Class { + name_index: 6, + version: 0, + parent_index: Some(2), + }), + Archived::Object { + class: 4, + data: ObjectData::from_groups(vec![vec![OutputData::String( + "__kIMMessagePartAttributeName", + )]]), + }, + Archived::Object { + class: 9, + data: ObjectData::from_groups(vec![vec![OutputData::SignedInteger(0)]]), + }, + Archived::Class(Class { + name_index: 8, + version: 0, + parent_index: Some(10), + }), + Archived::Class(Class { + name_index: 9, + version: 0, + parent_index: Some(2), + }), + Archived::Type(7), + ]; + + assert_eq!(typedstream.type_table, expected_types); + assert_eq!(typedstream.object_table, expected_objects); + } + + #[test] + fn test_parse_text_currency_temperature_volume_weight() { + let typedstream_path = current_dir() + .unwrap() + .as_path() + .join("src/test_data/CurrencyTemperatureVolumeWeight"); + let mut file = File::open(typedstream_path).unwrap(); + let mut bytes = vec![]; + file.read_to_end(&mut bytes).unwrap(); + + let mut typedstream = TypedStreamDeserializer::new(&bytes); + let root = typedstream.oxidize().unwrap(); + println!("\nResults:"); + println!("Root object: {:x?}", typedstream.object_table[root]); + print_resolved(typedstream.resolve_properties(root).unwrap(), 2); + + println!("\nFound {:?} types:", typedstream.type_table.len()); + typedstream + .type_table + .iter() + .enumerate() + .for_each(|(idx, item)| println!("\t{idx}: {item:?}")); + + println!("\nFound {:?} objects:", typedstream.object_table.len()); + typedstream + .object_table + .iter() + .enumerate() + .for_each(|(idx, item)| println!("\t{idx}: {item:?}")); + + let expected_types = vec![ + TypeEntry::from_types(vec![Type::Object]), + TypeEntry::from_types(vec![Type::String("NSMutableAttributedString")]), + TypeEntry::from_types(vec![Type::String("NSAttributedString")]), + TypeEntry::from_types(vec![Type::String("NSObject")]), + TypeEntry::from_types(vec![Type::String("NSMutableString")]), + TypeEntry::from_types(vec![Type::String("NSString")]), + TypeEntry::from_types(vec![Type::Utf8String]), + TypeEntry::from_types(vec![Type::SignedInt, Type::UnsignedInt]), + TypeEntry::from_types(vec![Type::String("NSDictionary")]), + TypeEntry::from_types(vec![Type::SignedInt]), + TypeEntry::from_types(vec![Type::String("NSNumber")]), + TypeEntry::from_types(vec![Type::String("NSValue")]), + TypeEntry::from_types(vec![Type::EmbeddedData]), + TypeEntry::from_types(vec![Type::String("NSData")]), + TypeEntry::from_types(vec![Type::Array(764)]), + TypeEntry::from_types(vec![Type::Array(748)]), + TypeEntry::from_types(vec![Type::Array(760)]), + ]; + + let expected_objects = vec![ + Archived::Object { + class: 1, + data: ObjectData::from_groups(vec![ + vec![OutputData::Object(4)], + vec![OutputData::SignedInteger(1), OutputData::UnsignedInteger(6)], + vec![OutputData::Object(7)], + vec![OutputData::SignedInteger(2), OutputData::UnsignedInteger(3)], + vec![OutputData::Object(14)], + vec![OutputData::SignedInteger(1), OutputData::UnsignedInteger(2)], + vec![OutputData::SignedInteger(3), OutputData::UnsignedInteger(2)], + vec![OutputData::Object(18)], + vec![ + OutputData::SignedInteger(1), + OutputData::UnsignedInteger(11), + ], + vec![OutputData::SignedInteger(4), OutputData::UnsignedInteger(6)], + vec![OutputData::Object(20)], + ]), + }, + Archived::Class(Class { + name_index: 1, + version: 0, + parent_index: Some(2), + }), + Archived::Class(Class { + name_index: 2, + version: 0, + parent_index: Some(3), + }), + Archived::Class(Class { + name_index: 3, + version: 0, + parent_index: None, + }), + Archived::Object { + class: 5, + data: ObjectData::from_groups(vec![vec![OutputData::String( + "$100\n\n75℉\n\n1L of water\n\n225lbs", + )]]), + }, + Archived::Class(Class { + name_index: 4, + version: 1, + parent_index: Some(6), + }), + Archived::Class(Class { + name_index: 5, + version: 1, + parent_index: Some(3), + }), + Archived::Object { + class: 8, + data: ObjectData::from_groups(vec![ + vec![OutputData::SignedInteger(1)], + vec![OutputData::Object(9)], + vec![OutputData::Object(10)], + ]), + }, + Archived::Class(Class { + name_index: 8, + version: 0, + parent_index: Some(3), + }), + Archived::Object { + class: 6, + data: ObjectData::from_groups(vec![vec![OutputData::String( + "__kIMMessagePartAttributeName", + )]]), + }, + Archived::Object { + class: 11, + data: ObjectData::from_groups(vec![vec![OutputData::SignedInteger(0)]]), + }, + Archived::Class(Class { + name_index: 10, + version: 0, + parent_index: Some(12), + }), + Archived::Class(Class { + name_index: 11, + version: 0, + parent_index: Some(3), + }), + Archived::Type(9), + Archived::Object { + class: 8, + data: ObjectData::from_groups(vec![ + vec![OutputData::SignedInteger(2)], + vec![OutputData::Object(15)], + vec![OutputData::Object(16)], + vec![OutputData::Object(9)], + vec![OutputData::Object(10)], + ]), + }, + Archived::Object { + class: 6, + data: ObjectData::from_groups(vec![vec![OutputData::String( + "__kIMDataDetectedAttributeName", + )]]), + }, + Archived::Object { + class: 17, + data: ObjectData::from_groups(vec![ + vec![OutputData::SignedInteger(764)], + vec![OutputData::Array(&[ + 98, 112, 108, 105, 115, 116, 48, 48, 212, 1, 2, 3, 4, 5, 6, 7, 12, 88, 36, + 118, 101, 114, 115, 105, 111, 110, 89, 36, 97, 114, 99, 104, 105, 118, 101, + 114, 84, 36, 116, 111, 112, 88, 36, 111, 98, 106, 101, 99, 116, 115, 18, 0, + 1, 134, 160, 95, 16, 15, 78, 83, 75, 101, 121, 101, 100, 65, 114, 99, 104, + 105, 118, 101, 114, 210, 8, 9, 10, 11, 87, 118, 101, 114, 115, 105, 111, + 110, 89, 100, 100, 45, 114, 101, 115, 117, 108, 116, 128, 24, 128, 1, 175, + 16, 25, 13, 14, 28, 36, 37, 38, 44, 45, 46, 52, 58, 62, 63, 64, 65, 68, 71, + 75, 83, 26, 87, 88, 89, 90, 91, 85, 36, 110, 117, 108, 108, 215, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 26, 82, 77, 83, 86, 36, 99, + 108, 97, 115, 115, 82, 65, 82, 81, 84, 81, 80, 82, 83, 82, 82, 86, 78, 128, + 6, 128, 16, 128, 2, 128, 7, 16, 1, 128, 8, 212, 29, 30, 31, 16, 32, 33, 34, + 35, 95, 16, 18, 78, 83, 46, 114, 97, 110, 103, 101, 118, 97, 108, 46, 108, + 101, 110, 103, 116, 104, 95, 16, 20, 78, 83, 46, 114, 97, 110, 103, 101, + 118, 97, 108, 46, 108, 111, 99, 97, 116, 105, 111, 110, 90, 78, 83, 46, + 115, 112, 101, 99, 105, 97, 108, 128, 3, 128, 4, 16, 4, 128, 5, 16, 3, 16, + 6, 210, 39, 40, 41, 42, 90, 36, 99, 108, 97, 115, 115, 110, 97, 109, 101, + 88, 36, 99, 108, 97, 115, 115, 101, 115, 87, 78, 83, 86, 97, 108, 117, 101, + 162, 41, 43, 88, 78, 83, 79, 98, 106, 101, 99, 116, 99, 0, 55, 0, 53, 33, + 9, 94, 80, 104, 121, 115, 105, 99, 97, 108, 65, 109, 111, 117, 110, 116, + 210, 47, 16, 48, 51, 90, 78, 83, 46, 111, 98, 106, 101, 99, 116, 115, 162, + 49, 50, 128, 9, 128, 17, 128, 15, 215, 15, 16, 17, 18, 19, 20, 21, 53, 23, + 55, 56, 26, 57, 26, 128, 12, 128, 16, 128, 10, 128, 13, 128, 14, 212, 29, + 30, 31, 16, 59, 33, 34, 35, 128, 11, 128, 4, 128, 5, 16, 2, 82, 55, 53, 93, + 73, 110, 116, 101, 103, 114, 97, 108, 86, 97, 108, 117, 101, 210, 47, 16, + 66, 51, 160, 128, 15, 210, 39, 40, 69, 70, 87, 78, 83, 65, 114, 114, 97, + 121, 162, 69, 43, 210, 39, 40, 72, 73, 95, 16, 15, 68, 68, 83, 99, 97, 110, + 110, 101, 114, 82, 101, 115, 117, 108, 116, 162, 74, 43, 95, 16, 15, 68, + 68, 83, 99, 97, 110, 110, 101, 114, 82, 101, 115, 117, 108, 116, 216, 15, + 16, 76, 17, 18, 19, 20, 21, 77, 23, 79, 80, 81, 26, 57, 26, 81, 86, 128, + 21, 128, 16, 128, 23, 128, 18, 128, 22, 128, 14, 212, 29, 30, 31, 16, 84, + 85, 34, 35, 128, 19, 128, 20, 128, 5, 16, 8, 97, 33, 9, 84, 85, 110, 105, + 116, 90, 102, 97, 104, 114, 101, 110, 104, 101, 105, 116, 16, 1, 0, 8, 0, + 17, 0, 26, 0, 36, 0, 41, 0, 50, 0, 55, 0, 73, 0, 78, 0, 86, 0, 96, 0, 98, + 0, 100, 0, 128, 0, 134, 0, 149, 0, 152, 0, 159, 0, 162, 0, 164, 0, 166, 0, + 169, 0, 172, 0, 174, 0, 176, 0, 178, 0, 180, 0, 182, 0, 184, 0, 193, 0, + 214, 0, 237, 0, 248, 0, 250, 0, 252, 0, 254, 1, 0, 1, 2, 1, 4, 1, 9, 1, 20, + 1, 29, 1, 37, 1, 40, 1, 49, 1, 56, 1, 71, 1, 76, 1, 87, 1, 90, 1, 92, 1, + 94, 1, 96, 1, 111, 1, 113, 1, 115, 1, 117, 1, 119, 1, 121, 1, 130, 1, 132, + 1, 134, 1, 136, 1, 138, 1, 141, 1, 155, 1, 160, 1, 161, 1, 163, 1, 168, 1, + 176, 1, 179, 1, 184, 1, 202, 1, 205, 1, 223, 1, 240, 1, 242, 1, 244, 1, + 246, 1, 248, 1, 250, 1, 252, 1, 254, 2, 7, 2, 9, 2, 11, 2, 13, 2, 15, 2, + 18, 2, 23, 2, 34, 0, 0, 0, 0, 0, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 92, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 36, + ])], + ]), + }, + Archived::Class(Class { + name_index: 13, + version: 0, + parent_index: Some(3), + }), + Archived::Object { + class: 8, + data: ObjectData::from_groups(vec![ + vec![OutputData::SignedInteger(2)], + vec![OutputData::Object(15)], + vec![OutputData::Object(19)], + vec![OutputData::Object(9)], + vec![OutputData::Object(10)], + ]), + }, + Archived::Object { + class: 17, + data: ObjectData::from_groups(vec![ + vec![OutputData::SignedInteger(748)], + vec![OutputData::Array(&[ + 98, 112, 108, 105, 115, 116, 48, 48, 212, 1, 2, 3, 4, 5, 6, 7, 12, 88, 36, + 118, 101, 114, 115, 105, 111, 110, 89, 36, 97, 114, 99, 104, 105, 118, 101, + 114, 84, 36, 116, 111, 112, 88, 36, 111, 98, 106, 101, 99, 116, 115, 18, 0, + 1, 134, 160, 95, 16, 15, 78, 83, 75, 101, 121, 101, 100, 65, 114, 99, 104, + 105, 118, 101, 114, 210, 8, 9, 10, 11, 87, 118, 101, 114, 115, 105, 111, + 110, 89, 100, 100, 45, 114, 101, 115, 117, 108, 116, 128, 23, 128, 1, 175, + 16, 24, 13, 14, 28, 36, 37, 38, 44, 45, 46, 52, 58, 26, 62, 63, 64, 67, 70, + 74, 82, 86, 87, 88, 89, 90, 85, 36, 110, 117, 108, 108, 215, 15, 16, 17, + 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 26, 82, 77, 83, 86, 36, 99, 108, + 97, 115, 115, 82, 65, 82, 81, 84, 81, 80, 82, 83, 82, 82, 86, 78, 128, 6, + 128, 16, 128, 2, 128, 7, 16, 1, 128, 8, 212, 29, 30, 31, 16, 32, 33, 34, + 35, 95, 16, 18, 78, 83, 46, 114, 97, 110, 103, 101, 118, 97, 108, 46, 108, + 101, 110, 103, 116, 104, 95, 16, 20, 78, 83, 46, 114, 97, 110, 103, 101, + 118, 97, 108, 46, 108, 111, 99, 97, 116, 105, 111, 110, 90, 78, 83, 46, + 115, 112, 101, 99, 105, 97, 108, 128, 3, 128, 4, 16, 4, 128, 5, 16, 2, 16, + 11, 210, 39, 40, 41, 42, 90, 36, 99, 108, 97, 115, 115, 110, 97, 109, 101, + 88, 36, 99, 108, 97, 115, 115, 101, 115, 87, 78, 83, 86, 97, 108, 117, 101, + 162, 41, 43, 88, 78, 83, 79, 98, 106, 101, 99, 116, 82, 49, 76, 94, 80, + 104, 121, 115, 105, 99, 97, 108, 65, 109, 111, 117, 110, 116, 210, 47, 16, + 48, 51, 90, 78, 83, 46, 111, 98, 106, 101, 99, 116, 115, 162, 49, 50, 128, + 9, 128, 17, 128, 15, 215, 15, 16, 17, 18, 19, 20, 21, 53, 23, 55, 56, 26, + 57, 26, 128, 12, 128, 16, 128, 10, 128, 13, 128, 14, 212, 29, 30, 31, 16, + 59, 33, 34, 35, 128, 11, 128, 4, 128, 5, 81, 49, 93, 73, 110, 116, 101, + 103, 114, 97, 108, 86, 97, 108, 117, 101, 210, 47, 16, 65, 51, 160, 128, + 15, 210, 39, 40, 68, 69, 87, 78, 83, 65, 114, 114, 97, 121, 162, 68, 43, + 210, 39, 40, 71, 72, 95, 16, 15, 68, 68, 83, 99, 97, 110, 110, 101, 114, + 82, 101, 115, 117, 108, 116, 162, 73, 43, 95, 16, 15, 68, 68, 83, 99, 97, + 110, 110, 101, 114, 82, 101, 115, 117, 108, 116, 216, 15, 16, 75, 17, 18, + 19, 20, 21, 76, 23, 78, 79, 80, 26, 57, 26, 81, 86, 128, 20, 128, 16, 128, + 22, 128, 18, 128, 21, 128, 14, 212, 29, 30, 31, 16, 59, 84, 34, 35, 128, + 11, 128, 19, 128, 5, 16, 12, 81, 76, 84, 85, 110, 105, 116, 85, 108, 105, + 116, 101, 114, 16, 1, 0, 8, 0, 17, 0, 26, 0, 36, 0, 41, 0, 50, 0, 55, 0, + 73, 0, 78, 0, 86, 0, 96, 0, 98, 0, 100, 0, 127, 0, 133, 0, 148, 0, 151, 0, + 158, 0, 161, 0, 163, 0, 165, 0, 168, 0, 171, 0, 173, 0, 175, 0, 177, 0, + 179, 0, 181, 0, 183, 0, 192, 0, 213, 0, 236, 0, 247, 0, 249, 0, 251, 0, + 253, 0, 255, 1, 1, 1, 3, 1, 8, 1, 19, 1, 28, 1, 36, 1, 39, 1, 48, 1, 51, 1, + 66, 1, 71, 1, 82, 1, 85, 1, 87, 1, 89, 1, 91, 1, 106, 1, 108, 1, 110, 1, + 112, 1, 114, 1, 116, 1, 125, 1, 127, 1, 129, 1, 131, 1, 133, 1, 147, 1, + 152, 1, 153, 1, 155, 1, 160, 1, 168, 1, 171, 1, 176, 1, 194, 1, 197, 1, + 215, 1, 232, 1, 234, 1, 236, 1, 238, 1, 240, 1, 242, 1, 244, 1, 246, 1, + 255, 2, 1, 2, 3, 2, 5, 2, 7, 2, 9, 2, 14, 2, 20, 0, 0, 0, 0, 0, 0, 2, 1, 0, + 0, 0, 0, 0, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 22, + ])], + ]), + }, + Archived::Object { + class: 8, + data: ObjectData::from_groups(vec![ + vec![OutputData::SignedInteger(2)], + vec![OutputData::Object(15)], + vec![OutputData::Object(21)], + vec![OutputData::Object(9)], + vec![OutputData::Object(10)], + ]), + }, + Archived::Object { + class: 17, + data: ObjectData::from_groups(vec![ + vec![OutputData::SignedInteger(760)], + vec![OutputData::Array(&[ + 98, 112, 108, 105, 115, 116, 48, 48, 212, 1, 2, 3, 4, 5, 6, 7, 12, 88, 36, + 118, 101, 114, 115, 105, 111, 110, 89, 36, 97, 114, 99, 104, 105, 118, 101, + 114, 84, 36, 116, 111, 112, 88, 36, 111, 98, 106, 101, 99, 116, 115, 18, 0, + 1, 134, 160, 95, 16, 15, 78, 83, 75, 101, 121, 101, 100, 65, 114, 99, 104, + 105, 118, 101, 114, 210, 8, 9, 10, 11, 87, 118, 101, 114, 115, 105, 111, + 110, 89, 100, 100, 45, 114, 101, 115, 117, 108, 116, 128, 23, 128, 1, 175, + 16, 24, 13, 14, 28, 36, 37, 38, 44, 45, 46, 52, 58, 62, 63, 64, 65, 68, 71, + 75, 83, 87, 88, 89, 90, 91, 85, 36, 110, 117, 108, 108, 215, 15, 16, 17, + 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 26, 82, 77, 83, 86, 36, 99, 108, + 97, 115, 115, 82, 65, 82, 81, 84, 81, 80, 82, 83, 82, 82, 86, 78, 128, 6, + 128, 16, 128, 2, 128, 7, 16, 1, 128, 8, 212, 29, 30, 31, 16, 32, 33, 34, + 35, 95, 16, 18, 78, 83, 46, 114, 97, 110, 103, 101, 118, 97, 108, 46, 108, + 101, 110, 103, 116, 104, 95, 16, 20, 78, 83, 46, 114, 97, 110, 103, 101, + 118, 97, 108, 46, 108, 111, 99, 97, 116, 105, 111, 110, 90, 78, 83, 46, + 115, 112, 101, 99, 105, 97, 108, 128, 3, 128, 4, 16, 4, 128, 5, 16, 6, 16, + 24, 210, 39, 40, 41, 42, 90, 36, 99, 108, 97, 115, 115, 110, 97, 109, 101, + 88, 36, 99, 108, 97, 115, 115, 101, 115, 87, 78, 83, 86, 97, 108, 117, 101, + 162, 41, 43, 88, 78, 83, 79, 98, 106, 101, 99, 116, 86, 50, 50, 53, 108, + 98, 115, 94, 80, 104, 121, 115, 105, 99, 97, 108, 65, 109, 111, 117, 110, + 116, 210, 47, 16, 48, 51, 90, 78, 83, 46, 111, 98, 106, 101, 99, 116, 115, + 162, 49, 50, 128, 9, 128, 17, 128, 15, 215, 15, 16, 17, 18, 19, 20, 21, 53, + 23, 55, 56, 26, 57, 26, 128, 12, 128, 16, 128, 10, 128, 13, 128, 14, 212, + 29, 30, 31, 16, 59, 33, 34, 35, 128, 11, 128, 4, 128, 5, 16, 3, 83, 50, 50, + 53, 93, 73, 110, 116, 101, 103, 114, 97, 108, 86, 97, 108, 117, 101, 210, + 47, 16, 66, 51, 160, 128, 15, 210, 39, 40, 69, 70, 87, 78, 83, 65, 114, + 114, 97, 121, 162, 69, 43, 210, 39, 40, 72, 73, 95, 16, 15, 68, 68, 83, 99, + 97, 110, 110, 101, 114, 82, 101, 115, 117, 108, 116, 162, 74, 43, 95, 16, + 15, 68, 68, 83, 99, 97, 110, 110, 101, 114, 82, 101, 115, 117, 108, 116, + 216, 15, 16, 76, 17, 18, 19, 20, 21, 77, 23, 79, 80, 81, 26, 57, 26, 81, + 86, 128, 20, 128, 16, 128, 22, 128, 18, 128, 21, 128, 14, 212, 29, 30, 31, + 16, 59, 85, 34, 35, 128, 11, 128, 19, 128, 5, 16, 27, 83, 108, 98, 115, 84, + 85, 110, 105, 116, 85, 112, 111, 117, 110, 100, 16, 1, 0, 8, 0, 17, 0, 26, + 0, 36, 0, 41, 0, 50, 0, 55, 0, 73, 0, 78, 0, 86, 0, 96, 0, 98, 0, 100, 0, + 127, 0, 133, 0, 148, 0, 151, 0, 158, 0, 161, 0, 163, 0, 165, 0, 168, 0, + 171, 0, 173, 0, 175, 0, 177, 0, 179, 0, 181, 0, 183, 0, 192, 0, 213, 0, + 236, 0, 247, 0, 249, 0, 251, 0, 253, 0, 255, 1, 1, 1, 3, 1, 8, 1, 19, 1, + 28, 1, 36, 1, 39, 1, 48, 1, 55, 1, 70, 1, 75, 1, 86, 1, 89, 1, 91, 1, 93, + 1, 95, 1, 110, 1, 112, 1, 114, 1, 116, 1, 118, 1, 120, 1, 129, 1, 131, 1, + 133, 1, 135, 1, 137, 1, 141, 1, 155, 1, 160, 1, 161, 1, 163, 1, 168, 1, + 176, 1, 179, 1, 184, 1, 202, 1, 205, 1, 223, 1, 240, 1, 242, 1, 244, 1, + 246, 1, 248, 1, 250, 1, 252, 1, 254, 2, 7, 2, 9, 2, 11, 2, 13, 2, 15, 2, + 19, 2, 24, 2, 30, 0, 0, 0, 0, 0, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 92, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 32, + ])], + ]), + }, + ]; + + assert_eq!(typedstream.type_table, expected_types); + assert_eq!(typedstream.object_table, expected_objects); + } + + #[test] + fn test_parse_text_flight() { + let typedstream_path = current_dir() + .unwrap() + .as_path() + .join("src/test_data/Flight"); + let mut file = File::open(typedstream_path).unwrap(); + let mut bytes = vec![]; + file.read_to_end(&mut bytes).unwrap(); + + let mut typedstream = TypedStreamDeserializer::new(&bytes); + let root = typedstream.oxidize().unwrap(); + println!("\nResults:"); + println!("Root object: {:x?}", typedstream.object_table[root]); + print_resolved(typedstream.resolve_properties(root).unwrap(), 2); + + println!("\nFound {:?} types:", typedstream.type_table.len()); + typedstream + .type_table + .iter() + .enumerate() + .for_each(|(idx, item)| println!("\t{idx}: {item:?}")); + + println!("\nFound {:?} objects:", typedstream.object_table.len()); + typedstream + .object_table + .iter() + .enumerate() + .for_each(|(idx, item)| println!("\t{idx}: {item:?}")); + + let expected_types = vec![ + TypeEntry::from_types(vec![Type::Object]), + TypeEntry::from_types(vec![Type::String("NSMutableAttributedString")]), + TypeEntry::from_types(vec![Type::String("NSAttributedString")]), + TypeEntry::from_types(vec![Type::String("NSObject")]), + TypeEntry::from_types(vec![Type::String("NSMutableString")]), + TypeEntry::from_types(vec![Type::String("NSString")]), + TypeEntry::from_types(vec![Type::Utf8String]), + TypeEntry::from_types(vec![Type::SignedInt, Type::UnsignedInt]), + TypeEntry::from_types(vec![Type::String("NSDictionary")]), + TypeEntry::from_types(vec![Type::SignedInt]), + TypeEntry::from_types(vec![Type::String("NSData")]), + TypeEntry::from_types(vec![Type::Array(754)]), + TypeEntry::from_types(vec![Type::String("NSNumber")]), + TypeEntry::from_types(vec![Type::String("NSValue")]), + TypeEntry::from_types(vec![Type::EmbeddedData]), + ]; + + let expected_objects = vec![ + Archived::Object { + class: 1, + data: ObjectData::from_groups(vec![ + vec![OutputData::Object(4)], + vec![OutputData::SignedInteger(1), OutputData::UnsignedInteger(7)], + vec![OutputData::Object(7)], + ]), + }, + Archived::Class(Class { + name_index: 1, + version: 0, + parent_index: Some(2), + }), + Archived::Class(Class { + name_index: 2, + version: 0, + parent_index: Some(3), + }), + Archived::Class(Class { + name_index: 3, + version: 0, + parent_index: None, + }), + Archived::Object { + class: 5, + data: ObjectData::from_groups(vec![vec![OutputData::String("AS 1111")]]), + }, + Archived::Class(Class { + name_index: 4, + version: 1, + parent_index: Some(6), + }), + Archived::Class(Class { + name_index: 5, + version: 1, + parent_index: Some(3), + }), + Archived::Object { + class: 8, + data: ObjectData::from_groups(vec![ + vec![OutputData::SignedInteger(2)], + vec![OutputData::Object(9)], + vec![OutputData::Object(10)], + vec![OutputData::Object(12)], + vec![OutputData::Object(13)], + ]), + }, + Archived::Class(Class { + name_index: 8, + version: 0, + parent_index: Some(3), + }), + Archived::Object { + class: 6, + data: ObjectData::from_groups(vec![vec![OutputData::String( + "__kIMDataDetectedAttributeName", + )]]), + }, + Archived::Object { + class: 11, + data: ObjectData::from_groups(vec![ + vec![OutputData::SignedInteger(754)], + vec![OutputData::Array(&[ + 98, 112, 108, 105, 115, 116, 48, 48, 212, 1, 2, 3, 4, 5, 6, 7, 12, 88, 36, + 118, 101, 114, 115, 105, 111, 110, 89, 36, 97, 114, 99, 104, 105, 118, 101, + 114, 84, 36, 116, 111, 112, 88, 36, 111, 98, 106, 101, 99, 116, 115, 18, 0, + 1, 134, 160, 95, 16, 15, 78, 83, 75, 101, 121, 101, 100, 65, 114, 99, 104, + 105, 118, 101, 114, 210, 8, 9, 10, 11, 87, 118, 101, 114, 115, 105, 111, + 110, 89, 100, 100, 45, 114, 101, 115, 117, 108, 116, 128, 23, 128, 1, 175, + 16, 24, 13, 14, 28, 36, 37, 38, 44, 45, 46, 52, 58, 62, 63, 64, 65, 68, 71, + 75, 81, 34, 85, 86, 87, 88, 85, 36, 110, 117, 108, 108, 215, 15, 16, 17, + 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 26, 82, 77, 83, 86, 36, 99, 108, + 97, 115, 115, 82, 65, 82, 81, 84, 81, 80, 82, 83, 82, 82, 86, 78, 128, 6, + 128, 16, 128, 2, 128, 7, 16, 1, 128, 8, 212, 29, 30, 31, 16, 32, 33, 34, + 35, 95, 16, 18, 78, 83, 46, 114, 97, 110, 103, 101, 118, 97, 108, 46, 108, + 101, 110, 103, 116, 104, 95, 16, 20, 78, 83, 46, 114, 97, 110, 103, 101, + 118, 97, 108, 46, 108, 111, 99, 97, 116, 105, 111, 110, 90, 78, 83, 46, + 115, 112, 101, 99, 105, 97, 108, 128, 3, 128, 4, 16, 4, 128, 5, 16, 7, 16, + 0, 210, 39, 40, 41, 42, 90, 36, 99, 108, 97, 115, 115, 110, 97, 109, 101, + 88, 36, 99, 108, 97, 115, 115, 101, 115, 87, 78, 83, 86, 97, 108, 117, 101, + 162, 41, 43, 88, 78, 83, 79, 98, 106, 101, 99, 116, 87, 65, 83, 32, 49, 49, + 49, 49, 95, 16, 17, 70, 108, 105, 103, 104, 116, 73, 110, 102, 111, 114, + 109, 97, 116, 105, 111, 110, 210, 47, 16, 48, 51, 90, 78, 83, 46, 111, 98, + 106, 101, 99, 116, 115, 162, 49, 50, 128, 9, 128, 17, 128, 15, 215, 15, 16, + 17, 18, 19, 20, 21, 53, 23, 55, 56, 26, 57, 26, 128, 12, 128, 16, 128, 10, + 128, 13, 128, 14, 212, 29, 30, 31, 16, 59, 33, 34, 35, 128, 11, 128, 4, + 128, 5, 16, 2, 82, 65, 83, 91, 65, 105, 114, 108, 105, 110, 101, 67, 111, + 100, 101, 210, 47, 16, 66, 51, 160, 128, 15, 210, 39, 40, 69, 70, 87, 78, + 83, 65, 114, 114, 97, 121, 162, 69, 43, 210, 39, 40, 72, 73, 95, 16, 15, + 68, 68, 83, 99, 97, 110, 110, 101, 114, 82, 101, 115, 117, 108, 116, 162, + 74, 43, 95, 16, 15, 68, 68, 83, 99, 97, 110, 110, 101, 114, 82, 101, 115, + 117, 108, 116, 215, 15, 16, 17, 18, 19, 20, 21, 76, 23, 78, 79, 26, 57, 26, + 128, 21, 128, 16, 128, 18, 128, 22, 128, 14, 212, 29, 30, 31, 16, 82, 83, + 34, 35, 128, 19, 128, 20, 128, 5, 16, 3, 84, 49, 49, 49, 49, 92, 70, 108, + 105, 103, 104, 116, 78, 117, 109, 98, 101, 114, 16, 1, 0, 8, 0, 17, 0, 26, + 0, 36, 0, 41, 0, 50, 0, 55, 0, 73, 0, 78, 0, 86, 0, 96, 0, 98, 0, 100, 0, + 127, 0, 133, 0, 148, 0, 151, 0, 158, 0, 161, 0, 163, 0, 165, 0, 168, 0, + 171, 0, 173, 0, 175, 0, 177, 0, 179, 0, 181, 0, 183, 0, 192, 0, 213, 0, + 236, 0, 247, 0, 249, 0, 251, 0, 253, 0, 255, 1, 1, 1, 3, 1, 8, 1, 19, 1, + 28, 1, 36, 1, 39, 1, 48, 1, 56, 1, 76, 1, 81, 1, 92, 1, 95, 1, 97, 1, 99, + 1, 101, 1, 116, 1, 118, 1, 120, 1, 122, 1, 124, 1, 126, 1, 135, 1, 137, 1, + 139, 1, 141, 1, 143, 1, 146, 1, 158, 1, 163, 1, 164, 1, 166, 1, 171, 1, + 179, 1, 182, 1, 187, 1, 205, 1, 208, 1, 226, 1, 241, 1, 243, 1, 245, 1, + 247, 1, 249, 1, 251, 2, 4, 2, 6, 2, 8, 2, 10, 2, 12, 2, 17, 2, 30, 0, 0, 0, + 0, 0, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 2, 32, + ])], + ]), + }, + Archived::Class(Class { + name_index: 10, + version: 0, + parent_index: Some(3), + }), + Archived::Object { + class: 6, + data: ObjectData::from_groups(vec![vec![OutputData::String( + "__kIMMessagePartAttributeName", + )]]), + }, + Archived::Object { + class: 14, + data: ObjectData::from_groups(vec![vec![OutputData::SignedInteger(0)]]), + }, + Archived::Class(Class { + name_index: 12, + version: 0, + parent_index: Some(15), + }), + Archived::Class(Class { + name_index: 13, + version: 0, + parent_index: Some(3), + }), + Archived::Type(9), + ]; + + assert_eq!(typedstream.type_table, expected_types); + assert_eq!(typedstream.object_table, expected_objects); + } + + #[test] + fn test_parse_text_tracking() { + let typedstream_path = current_dir() + .unwrap() + .as_path() + .join("src/test_data/Tracking"); + let mut file = File::open(typedstream_path).unwrap(); + let mut bytes = vec![]; + file.read_to_end(&mut bytes).unwrap(); + + let mut typedstream = TypedStreamDeserializer::new(&bytes); + let root = typedstream.oxidize().unwrap(); + println!("\nResults:"); + println!("Root object: {:x?}", typedstream.object_table[root]); + print_resolved(typedstream.resolve_properties(root).unwrap(), 2); + + println!("\nFound {:?} types:", typedstream.type_table.len()); + typedstream + .type_table + .iter() + .enumerate() + .for_each(|(idx, item)| println!("\t{idx}: {item:?}")); + + println!("\nFound {:?} objects:", typedstream.object_table.len()); + typedstream + .object_table + .iter() + .enumerate() + .for_each(|(idx, item)| println!("\t{idx}: {item:?}")); + + let expected_types = vec![ + TypeEntry::from_types(vec![Type::Object]), + TypeEntry::from_types(vec![Type::String("NSMutableAttributedString")]), + TypeEntry::from_types(vec![Type::String("NSAttributedString")]), + TypeEntry::from_types(vec![Type::String("NSObject")]), + TypeEntry::from_types(vec![Type::String("NSMutableString")]), + TypeEntry::from_types(vec![Type::String("NSString")]), + TypeEntry::from_types(vec![Type::Utf8String]), + TypeEntry::from_types(vec![Type::SignedInt, Type::UnsignedInt]), + TypeEntry::from_types(vec![Type::String("NSDictionary")]), + TypeEntry::from_types(vec![Type::SignedInt]), + TypeEntry::from_types(vec![Type::String("NSData")]), + TypeEntry::from_types(vec![Type::Array(664)]), + TypeEntry::from_types(vec![Type::String("NSNumber")]), + TypeEntry::from_types(vec![Type::String("NSValue")]), + TypeEntry::from_types(vec![Type::EmbeddedData]), + ]; + + let expected_objects = vec![ + Archived::Object { + class: 1, + data: ObjectData::from_groups(vec![ + vec![OutputData::Object(4)], + vec![ + OutputData::SignedInteger(1), + OutputData::UnsignedInteger(18), + ], + vec![OutputData::Object(7)], + ]), + }, + Archived::Class(Class { + name_index: 1, + version: 0, + parent_index: Some(2), + }), + Archived::Class(Class { + name_index: 2, + version: 0, + parent_index: Some(3), + }), + Archived::Class(Class { + name_index: 3, + version: 0, + parent_index: None, + }), + Archived::Object { + class: 5, + data: ObjectData::from_groups(vec![vec![OutputData::String("1Z999AA10123456784")]]), + }, + Archived::Class(Class { + name_index: 4, + version: 1, + parent_index: Some(6), + }), + Archived::Class(Class { + name_index: 5, + version: 1, + parent_index: Some(3), + }), + Archived::Object { + class: 8, + data: ObjectData::from_groups(vec![ + vec![OutputData::SignedInteger(2)], + vec![OutputData::Object(9)], + vec![OutputData::Object(10)], + vec![OutputData::Object(12)], + vec![OutputData::Object(13)], + ]), + }, + Archived::Class(Class { + name_index: 8, + version: 0, + parent_index: Some(3), + }), + Archived::Object { + class: 6, + data: ObjectData::from_groups(vec![vec![OutputData::String( + "__kIMDataDetectedAttributeName", + )]]), + }, + Archived::Object { + class: 11, + data: ObjectData::from_groups(vec![ + vec![OutputData::SignedInteger(664)], + vec![OutputData::Array(&[ + 98, 112, 108, 105, 115, 116, 48, 48, 212, 1, 2, 3, 4, 5, 6, 7, 12, 88, 36, + 118, 101, 114, 115, 105, 111, 110, 89, 36, 97, 114, 99, 104, 105, 118, 101, + 114, 84, 36, 116, 111, 112, 88, 36, 111, 98, 106, 101, 99, 116, 115, 18, 0, + 1, 134, 160, 95, 16, 15, 78, 83, 75, 101, 121, 101, 100, 65, 114, 99, 104, + 105, 118, 101, 114, 210, 8, 9, 10, 11, 87, 118, 101, 114, 115, 105, 111, + 110, 89, 100, 100, 45, 114, 101, 115, 117, 108, 116, 128, 15, 128, 1, 175, + 16, 16, 13, 14, 28, 36, 37, 38, 44, 45, 46, 51, 57, 61, 62, 65, 69, 73, 85, + 36, 110, 117, 108, 108, 215, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 26, 27, 26, 82, 77, 83, 86, 36, 99, 108, 97, 115, 115, 82, 65, 82, 81, 84, + 81, 80, 82, 83, 82, 82, 86, 78, 128, 6, 128, 14, 128, 2, 128, 7, 16, 1, + 128, 8, 212, 29, 30, 31, 16, 32, 33, 34, 35, 95, 16, 18, 78, 83, 46, 114, + 97, 110, 103, 101, 118, 97, 108, 46, 108, 101, 110, 103, 116, 104, 95, 16, + 20, 78, 83, 46, 114, 97, 110, 103, 101, 118, 97, 108, 46, 108, 111, 99, 97, + 116, 105, 111, 110, 90, 78, 83, 46, 115, 112, 101, 99, 105, 97, 108, 128, + 3, 128, 4, 16, 4, 128, 5, 16, 18, 16, 0, 210, 39, 40, 41, 42, 90, 36, 99, + 108, 97, 115, 115, 110, 97, 109, 101, 88, 36, 99, 108, 97, 115, 115, 101, + 115, 87, 78, 83, 86, 97, 108, 117, 101, 162, 41, 43, 88, 78, 83, 79, 98, + 106, 101, 99, 116, 95, 16, 18, 49, 90, 57, 57, 57, 65, 65, 49, 48, 49, 50, + 51, 52, 53, 54, 55, 56, 52, 94, 84, 114, 97, 99, 107, 105, 110, 103, 78, + 117, 109, 98, 101, 114, 210, 47, 16, 48, 50, 90, 78, 83, 46, 111, 98, 106, + 101, 99, 116, 115, 161, 49, 128, 9, 128, 13, 215, 15, 16, 17, 18, 19, 20, + 21, 22, 23, 54, 55, 26, 56, 26, 128, 6, 128, 14, 128, 10, 128, 11, 128, 12, + 212, 29, 30, 31, 16, 32, 33, 34, 35, 128, 3, 128, 4, 128, 5, 83, 85, 80, + 83, 210, 47, 16, 63, 50, 160, 128, 13, 210, 39, 40, 66, 67, 94, 78, 83, 77, + 117, 116, 97, 98, 108, 101, 65, 114, 114, 97, 121, 163, 66, 68, 43, 87, 78, + 83, 65, 114, 114, 97, 121, 210, 39, 40, 70, 71, 95, 16, 15, 68, 68, 83, 99, + 97, 110, 110, 101, 114, 82, 101, 115, 117, 108, 116, 162, 72, 43, 95, 16, + 15, 68, 68, 83, 99, 97, 110, 110, 101, 114, 82, 101, 115, 117, 108, 116, + 16, 1, 0, 8, 0, 17, 0, 26, 0, 36, 0, 41, 0, 50, 0, 55, 0, 73, 0, 78, 0, 86, + 0, 96, 0, 98, 0, 100, 0, 119, 0, 125, 0, 140, 0, 143, 0, 150, 0, 153, 0, + 155, 0, 157, 0, 160, 0, 163, 0, 165, 0, 167, 0, 169, 0, 171, 0, 173, 0, + 175, 0, 184, 0, 205, 0, 228, 0, 239, 0, 241, 0, 243, 0, 245, 0, 247, 0, + 249, 0, 251, 1, 0, 1, 11, 1, 20, 1, 28, 1, 31, 1, 40, 1, 61, 1, 76, 1, 81, + 1, 92, 1, 94, 1, 96, 1, 98, 1, 113, 1, 115, 1, 117, 1, 119, 1, 121, 1, 123, + 1, 132, 1, 134, 1, 136, 1, 138, 1, 142, 1, 147, 1, 148, 1, 150, 1, 155, 1, + 170, 1, 174, 1, 182, 1, 187, 1, 205, 1, 208, 1, 226, 0, 0, 0, 0, 0, 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, 1, + 228, + ])], + ]), + }, + Archived::Class(Class { + name_index: 10, + version: 0, + parent_index: Some(3), + }), + Archived::Object { + class: 6, + data: ObjectData::from_groups(vec![vec![OutputData::String( + "__kIMMessagePartAttributeName", + )]]), + }, + Archived::Object { + class: 14, + data: ObjectData::from_groups(vec![vec![OutputData::SignedInteger(0)]]), + }, + Archived::Class(Class { + name_index: 12, + version: 0, + parent_index: Some(15), + }), + Archived::Class(Class { + name_index: 13, + version: 0, + parent_index: Some(3), + }), + Archived::Type(9), + ]; + + assert_eq!(typedstream.type_table, expected_types); + assert_eq!(typedstream.object_table, expected_objects); + } } diff --git a/src/test_data/Address b/src/test_data/Address new file mode 100644 index 0000000000000000000000000000000000000000..f4eea11f223057269ffb4626ea1123465316ba9f GIT binary patch literal 1474 zcma)6ZA?>F7(VZN`2M_9pio4r6a@-M5r&Sr(G_*XQKhA{fZE-*SGZEz=Ju9Z-OSNk zyAR@=$jDgs!?68Xj5Eu!WLbzagqUSnw#>PZ{n;Org)IJG7GvDGrLZvn?EbmuoO_?= zd7t+^@0(Q^R~1Q|Qj;+$ba9Pp(5q>h!RfZEsv-vxsuXhbMP!_4TAtH=EO15&s^s!4 z|A}wcKf#;^)&`r|9*cz~^Kns`G<(Hli`kKgNs1~*qI_vLALwegb*40w`=LRH7dhR1 za!{3{5m8AJP9fv0Ha}nO_fPf@*h3*jipMvDaEen>N=Fqt-2(|#41}dVQ5AVmIh;mc z%`IH~BumR3v)T4{2TulKVL7h0w?6=+S=l+cMLx^4q{O+{h(%O_6EfcoS=4CEXNjgQ z#SH{fH~d1W(|uG*N+EmZr~7&N1%=)XY$(*q!%Boz*2dtru(!BmyQN`wOKaP6FZ9}9 zcD&*=x!gnE(Nm!b`OIWknST9j@*LAHr{219ZT9-y2Odi#5e~1G3T1|E z$u-~}wgkgsJnpi)28RZZyWB3~0G9Wlc1N9H-npyZFYwB=DPm+?nij)t zVJR}MPWXlLEr-#dsAqMQAI4)+P!_|CvMeEsWeW`gxxc5esd;o=Fv7FyTVG0XuhTs& zh7;0alhwCTXut6P$~tzK`^wbp{$8QIOBc^1_ETHOzD}0UYFRyNWEC6kyNw5)H}#lU z5w}^uidjk8)A*&Nyg0u?}}8rUH_}NjzOQSOrgrZ-kq-D~gz0^jZ0S>;%6EeSPkr7>P)V zD_!x$lh$VsH_Z5rVnCO!;nG!Xdq!G1&84fEiJK`A@YL4!7|q1OOR&K*WsJsjmYtks z2iuiliL0EYj+r@2zF-*HY^ouLtR^?0=Z$Y((4o6I)WY^;pr4FC zcF<0GkiJCi)Ikr?BXodzNcurofAjood8n6~b?bs*lTNZDE0=QmKCc7gMxA literal 0 HcmV?d00001 diff --git a/src/test_data/Arabic b/src/test_data/Arabic new file mode 100644 index 0000000000000000000000000000000000000000..eaf2091eb597e761a7ccfc9d8975880df3ba86b5 GIT binary patch literal 200 zcmZSKE-oobP0TH+EJ#ghe8Jqp=+M&ABIFnBSW;4ynN(Vmni33T2B>qDls!woJxJEz_pS#>Z!S`ue687bm8t1|$}hz%BPn%uQ{BTIN@po0M7v YbO*a%a9CnaX)4G7t(KWH8QR*~0CQMU82|tP literal 0 HcmV?d00001 diff --git a/src/test_data/Currency b/src/test_data/Currency new file mode 100644 index 0000000000000000000000000000000000000000..00a492ba2d518c44fa073d3c3581c06da6df4073 GIT binary patch literal 205 zcmZSKE-oobP0TH+EJ#ghe8Jqp=+M&ABIFnBSW;4ynN(Vmni33TA_&19U^GHse{e0;X2uWxE`abkLEKw?n|+y#D#xv6bX g8~sXilTwR-j$!u;4ol1_O$8aC)iQG?Lt9%L0OEB>u>b%7 literal 0 HcmV?d00001 diff --git a/src/test_data/CurrencyTemperatureVolumeWeight b/src/test_data/CurrencyTemperatureVolumeWeight new file mode 100644 index 0000000000000000000000000000000000000000..fbd5a0ac7a18491b8c9c73e79099336bc1601577 GIT binary patch literal 2670 zcmd7UU2GIp6bJD0zuRux-9o1ybj$K#!9_kQb=y*lnkdEPqqJSx-F91Apv>+L?c#K{ z&dh>+Fids2iis~(V(S{Et(qECQ2gLgO?)x&g`oIm;uA4wj4_Ic;N976RZ2`SAnwb| z+{`_5?z#J$GdWI8S0!;!A0CpTBj;@pF zAH2?JzCXA#d_aomG&;s36wO7*%!6t2JF@3TO;lBSYP?>DqoMvA^N7Py(^47VUwKH> zCDq}mt*w{CTGC{(CfL)#3jIM}ETYHail`0~pB=-PIX=FuukVqj)>cW=#D1wwRQ0*E z{NkXLOwZ)c^d|*C9pc zhqLoU_ziS4HFBAm_TGkjH$?V?hvb;1d%b7DY&p61yuxnJK}pqkw!1u{8X1W3s}7GI zAL{nRtqN%+gygY4f!C;68s^W*-gG9vz~Stgog0m=S0ybW>qdov6T;#J3zvFU-F5f+ z>J9fl_|T?C-?rwUyQ_OwPj9D3NyzfKBB8jXv}{qit75Txi966540$55sA+-5Kzm1f zTOb$+g#3ox5DaGI2{7`{E?a(wP`P5|oqYn|(rQ&y`lW-STrEpVzdq0>l>Kcm9ud>Q@x( zZ5tTYVi8ep9E>Lv{mearw=Nw%TcoL)TBE=yHi~9fR_|)q=)TWw6!IlFj0MI*YXJ}N z1sF~vod*jv)bD9hbg5qzWoxT>%*}Pjj3S=imaROMMpYGur?yn_>+MZ^1AM+ z4Oo?)+EF!s@T(%B#j0$pYiC+Wk8DQ0w|w~$xR+wOSOFUP2{H#?V~V7$)F@1rEz+Nrs!3Ao!+1~>1{em@6vnp z0iC9g=}Y>KF485sOjkf)$UyIkdaxUNu@7-P3JnPy!Z4nIi6oxJ zGk6v$9K$50F@uvhh12*9pW|!%fFJP_e#S*y!ev}xd8~jr*#cI?N|=kSBMtBk+XS+1pGAuG%L?dLS~UZbIWR)cdQhxe^NHC)W}3h(XEFxxBs zAFaYJRNRn;Q080UW{VJPK^}OXid)hv=BY^c3McOtxx$hl|IW#{7~(B3dP`k2U@Mvt kvP|qj-<*kqcr0t;DIED1eWH|Au;tgtxVBGJW@IG)0Qwvc{Qv*} literal 0 HcmV?d00001 diff --git a/src/test_data/Flight b/src/test_data/Flight new file mode 100644 index 0000000000000000000000000000000000000000..68abb521c452a6efa84aa76e0f50e6b682fb4b76 GIT binary patch literal 1046 zcmZuw>u(HE6hCKn?XI?Twk>5*#duVydZiu-mi1V4=uBs;wH>Cj&CK0KMYxi& zA|jGTqe&B?9+8NM2tN4YACO2xeD}!*Ul0)y;qIdn;eI*yo}6=j=lst7`Kw*#P}0W+ z`)TI<2cL&qJkOh{>YaH;(iV*}=9uX`qZwUX>@0X*ovQ!G8&dUs=@ZmoaA8PPsQpu+ zoQIw#A}aS`4_kv#y?LcL1y3^L7%b-0sCvvan3=PQGYBHcl!m;Kk)~AYWV|y*7>Q9P z0BGh9yh{3Lp_m#FsUiS|N6&wjyujg(wQG!{>3+*}S$q2%lzje4fnZHi8K90U>K{~y zWAvKh)vd5xe^SYnT6gOJ3pZ1;XnqeJ6gZWj@zCU|>Yj<*OlG-5-MqzkBgaSbj44xR zD+?DbTi&*2!=}w!qOqNOy5=89^dt``cHXky)ym+0^>uj!hWPG4`UtNPgH-V;d}?WojbaR5 z&5PYgT2wzAH66>e>9$;kii%rT-{iHT#qB#pJ5k3WgJauU#d}v=>>w7?4Px8W(Mn{G z?QZ?oIRU=6QQcPrpC-WT`1A_6rVH?T-XOqz-NnClq&$|I?@LohMhHO|BA`GEtbz`R zg9-^a25HE^Ik*7V;5yuZTW}lh!hLuE58)9!h9~e8p2JIc3m@Sde1{+K6MiA04?|dw zvr)mt*pBOPFLvP(Od&x7DKZ?uQ+OKB;90zgm+&%P!K*lgH}E#z!F%`spWrimfv@m2 zzQ<4a1;64q{Ej~)zZ8%{Qk7IAg{3Aa9SO@84pwZ%NXV!Z literal 0 HcmV?d00001 diff --git a/src/test_data/Tracking b/src/test_data/Tracking new file mode 100644 index 0000000000000000000000000000000000000000..fd20f14e7594a7e17b25eb3ff283d004829570fb GIT binary patch literal 967 zcmZuw*-sN;5T7Xp%Dq%Ps2ma}Z3zvg8sHno7IToQ}D?%2B zy3Rau`n--dbL+6f;cz-z?X7L?9mhMnx;qlOA>u}J8eYl^u862cCZj}-1M`m<=JaH; zE)W=Zdt5{%E~>IzG_+L-PbO$04J}|$<^c1l*`z@)xZ2s-AzlwoNfAZ0+t<;MXUs1s zEcIKbsjRU0SFA)9$0F=CU{xol{MN}#7m67$u^8Z39~Wty<;gj%nTm=_hBmRGP_s;x zn51eI8m@3$S$U21(BY%aE$xn;6V5a4L2EQ7NuMgXO7o7Yox67LskZF3cs+v8DoR9A zyiRZbK!2ZC@Opi`R-lz@2Ca}o&9q)ySI_O+f8bz%V{Es`BpRmEL~4;}G^~yVxT=4Q zlOjnoHO!346cr;x((*JTXVmgJGY4x&8XB91vk9Y&B!5<=$`CL3h!mqsjW+-0@L0a> za~T_S-LHmZi=-Mt#qrGbWvKqFxV%s z2q)VXwK7&(@9B}PO>xRHi7)rMY^<`3&i=y>#BT-N+%Bpb{)# zg+^$DE^q@6J{W}{gkT14!+m%N3-AO|@Dvtd8J@!ncnPoJ4XnU>ScMJv3g6&6{D7bE z3w|SD307eZ)?)+q;3e$GYdC_V7{r^XU<_w4j<-<91m4Aa_y8Z_V_d)#zQVWo4nN>3 ze#Fm^`3#tqa3Lpi0yo&kCX=<9t@cnwAz|7_WOe&ev)jp%&+e}