Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,6 @@ keywords = ["typedstream", "macos", "ios", "apple"]
categories = ["parsing", "parser-implementations", "database"]

[dependencies]

[features]
std=[]
4 changes: 2 additions & 2 deletions src/deserializer/consumed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,15 +50,15 @@ impl<T> Consumed<T> {
}
}

impl<T> std::ops::Deref for Consumed<T> {
impl<T> core::ops::Deref for Consumed<T> {
type Target = T;

fn deref(&self) -> &Self::Target {
&self.value
}
}

impl<T> std::ops::DerefMut for Consumed<T> {
impl<T> core::ops::DerefMut for Consumed<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.value
}
Expand Down
4 changes: 3 additions & 1 deletion src/deserializer/header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,9 @@ pub fn validate_header(data: &[u8]) -> Result<Consumed<bool>> {

#[cfg(test)]
mod header_tests {
use std::{env::current_dir, fs::File, io::Read};
extern crate std;
use std::{env::current_dir, fs::File, io::Read,println};
use alloc::{vec};

use crate::deserializer::{constants::I_16, header::validate_header};

Expand Down
8 changes: 7 additions & 1 deletion src/deserializer/iter.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
//! Iterators for resolving properties in an [`Archived::Object`]

use std::slice::Iter;
use core::slice::Iter;

use alloc::vec::Vec;

use crate::models::{archived::Archived, class::Class, output_data::OutputData, types::Type};

Expand Down Expand Up @@ -250,6 +252,7 @@ impl<'a, 'b: 'a> Iterator for PropertyIterator<'a, 'b> {
/// Group:
/// Primitive: SignedInteger(0)
/// ```
#[cfg(any(feature = "std", test))]
pub fn print_resolved(iter: PropertyIterator<'_, '_>, indent: usize) {
print_resolved_with_limits(iter, indent, 100, 1000000);
}
Expand All @@ -262,12 +265,15 @@ pub fn print_resolved(iter: PropertyIterator<'_, '_>, indent: usize) {
/// * `indent` - Number of spaces to indent each level
/// * `max_depth` - Maximum depth to traverse (prevents infinite recursion on cycles)
/// * `max_items` - Maximum total items to print (prevents runaway output)
#[cfg(any(feature = "std", test))]
fn print_resolved_with_limits(
iter: PropertyIterator<'_, '_>,
indent: usize,
max_depth: usize,
max_items: usize,
) {
extern crate std;
use std::println;
// Use an explicit stack to avoid recursion and potential stack overflow
let mut stack: Vec<(Property<'_, '_>, usize)> = Vec::new();
let mut items_printed = 0;
Expand Down
4 changes: 3 additions & 1 deletion src/deserializer/string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ use crate::{
pub fn read_string(data: &[u8]) -> Result<Consumed<&str>> {
let length = read_unsigned_int(data)?;
Ok(Consumed::new(
std::str::from_utf8(
core::str::from_utf8(
data.get(length.bytes_consumed..(length.bytes_consumed + length.value as usize))
.ok_or({
crate::error::TypedStreamError::OutOfBounds(length.value as usize, data.len())
Expand All @@ -40,6 +40,8 @@ pub fn read_string(data: &[u8]) -> Result<Consumed<&str>> {

#[cfg(test)]
mod string_tests {
use alloc::vec::Vec;

use crate::deserializer::{
constants::{I_16, I_32},
string::read_string,
Expand Down
2 changes: 2 additions & 0 deletions src/deserializer/typedstream.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
A writeup about the reverse engineering of `typedstream` can be found [here](https://chrissardegna.com/blog/reverse-engineering-apples-typedstream-format/).
*/

use alloc::{vec::Vec,vec};

use crate::{
deserializer::{
constants::{EMPTY, END, START},
Expand Down
14 changes: 7 additions & 7 deletions src/error.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Error types and result alias for `typedstream` deserialization

use std::{array::TryFromSliceError, fmt::Display};
use core::{array::TryFromSliceError, fmt::Display};

/// A specialized [`Result`] type for `typedstream` operations.
///
Expand All @@ -15,7 +15,7 @@ use std::{array::TryFromSliceError, fmt::Display};
/// deserializer.oxidize()
/// }
/// ```
pub type Result<T> = std::result::Result<T, TypedStreamError>;
pub type Result<T> = core::result::Result<T, TypedStreamError>;

/// Errors that can occur while deserializing a `typedstream`.
#[derive(Debug)]
Expand All @@ -27,7 +27,7 @@ pub enum TypedStreamError {
/// Error converting a slice into an array of fixed size.
SliceError(TryFromSliceError),
/// Error parsing a string as UTF-8.
StringParseError(std::str::Utf8Error),
StringParseError(core::str::Utf8Error),
/// The `typedstream` header was invalid.
InvalidHeader,
/// Encountered an invalid pointer value.
Expand All @@ -39,7 +39,7 @@ pub enum TypedStreamError {
}

impl Display for TypedStreamError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
TypedStreamError::InvalidObject => {
write!(f, "Invalid object encountered in typedstream!")
Expand Down Expand Up @@ -72,10 +72,10 @@ impl From<TryFromSliceError> for TypedStreamError {
}
}

impl From<std::str::Utf8Error> for TypedStreamError {
fn from(error: std::str::Utf8Error) -> Self {
impl From<core::str::Utf8Error> for TypedStreamError {
fn from(error: core::str::Utf8Error) -> Self {
TypedStreamError::StringParseError(error)
}
}

impl std::error::Error for TypedStreamError {}
impl core::error::Error for TypedStreamError {}
8 changes: 7 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
#![forbid(unsafe_code)]
#![deny(missing_docs)]
#![doc = include_str!("../README.md")]
#![no_std]
extern crate alloc;
#[cfg(feature = "std")]
extern crate std;

pub mod deserializer;
pub mod error;
Expand All @@ -11,7 +15,9 @@ pub use models::{archived::Archived, output_data::OutputData};

#[cfg(test)]
mod test_typedstream_deserializer {
use std::{env::current_dir, fs::File, io::Read};
extern crate std;
use alloc::vec;
use std::{env::current_dir, fs::File, io::Read, println};

use crate::{
deserializer::{iter::print_resolved, typedstream::TypedStreamDeserializer},
Expand Down
2 changes: 2 additions & 0 deletions src/models/archived.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
//! Types that can be archived into a `typedstream`

use alloc::vec::Vec;

use crate::models::{class::Class, output_data::OutputData};

/// Types of data that can be archived into the `typedstream`
Expand Down
4 changes: 2 additions & 2 deletions src/models/output_data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -178,8 +178,8 @@ impl<'a> OutputData<'a> {
}

// Implement Display for human-friendly formatting
impl std::fmt::Display for OutputData<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
impl core::fmt::Display for OutputData<'_> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
OutputData::String(s) => write!(f, "{s}"),
OutputData::SignedInteger(i) => write!(f, "{i}"),
Expand Down
2 changes: 1 addition & 1 deletion src/models/types.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
//! Type tags that denote the type of data stored in a `typedstream`

use crate::{
deserializer::{
constants::ARRAY, consumed::Consumed, number::read_unsigned_int, read::read_exact_bytes,
},
error::{Result, TypedStreamError},
};
use alloc::{vec, vec::Vec};

/// Represents primitive types of data that can be stored in a `typedstream`
///
Expand Down