Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to read in files in TypedStream format

I have a file in the following format:

NeXT/Apple typedstream data, little endian, version 4, system 1000

Looking at it in a hex editor, it's clearly made up of NSsomething objects (NSArray, NSValue, etc). It also appears to have an embedded plist!

I'm guessing there's a straightforward way to read this file and output it in some more readable fashion (similar to the output of repr() or print_r()).

I assume I'll need to do this using Objective-C?

like image 754
Jordan Reiter Avatar asked Dec 06 '10 22:12

Jordan Reiter


2 Answers

First, some history:

Older versions of the Objective-C runtime (pre-OS X) included a psuedo-class called NXTypedStream, which is the pre-OPENSTEP ancestor of NSCoder. Older versions of Foundation contained a header called NSCompatibility.h, which had functions and categories for dealing with old NeXTStep formats. NSCompatibility.h no longer exists, but a (deprecated) subset of that functionality can still be found in NSCoder.h.

NSCoder debuted as part of the original Foundation Kit in OPENSTEP, but probably used typedstreams as its serialization format. At some point, it was switched over to a plist-based format. The current version of Interface Builder (as part of Xcode) is still able to read older, typedstream-based NIBs, which is a good clue that this functionality still exists in OS X.

Now, the solution:

I can't find this in any (current) Apple documentation, but it turns out that NSCoder/NSUnarchiver can still read typedstream files just fine. If you want to read a typedstream file in a Cocoa/Objective-C program, just do this:

NSUnarchiver *typedStreamUnarchiver = [[NSUnarchiver alloc] initForReadingWithData:[NSData dataWithContentsOfFile:@"<path to your typedstream file>"]];

That's it! The decoding is handled internally in a function called _decodeObject_old. Now you can unarchive using standard NSCoder methods, like:

id object = [typedStreamUnarchiver decodeObject];
NSLog(@"Decoded object: %@", object);

Note that if the class in the typedstream is not a valid class in your program, it will throw an NSArchiverArchiveInconsistency exception.

See also: http://www.stone.com/The_Cocoa_Files/Legacy_File_Formats.html

like image 157
AriX Avatar answered Sep 20 '22 21:09

AriX


If it's a binary plist, it should be easy to read it with Xcode / Plist Editor, plutil, or your own Objective-C code. Otherwise, depending on the file, it could be more challenging. The file stores a serialized representation of Objective-C objects. As such, it's only intended to be readable by the software that created it.

like image 22
lemnar Avatar answered Sep 17 '22 21:09

lemnar