Jordan Reiter
Jordan Reiter

Reputation: 21032

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?

Upvotes: 15

Views: 3451

Answers (2)

AriX
AriX

Reputation: 1697

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

Upvotes: 11

lemnar
lemnar

Reputation: 4053

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.

Upvotes: 4

Related Questions