Browse Source

Initial commit.

preble 8 years ago
commit
6eb2e6c022

+ 3 - 0
.gitignore

@@ -0,0 +1,3 @@
+build
+*.perspectivev3
+*.pbxuser

+ 2 - 0
English.lproj/InfoPlist.strings

@@ -0,0 +1,2 @@
+/* Localized versions of Info.plist keys */
+

File diff suppressed because it is too large
+ 4119 - 0
English.lproj/MainMenu.xib


+ 32 - 0
InsideJob-Info.plist

@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>English</string>
+	<key>CFBundleExecutable</key>
+	<string>${EXECUTABLE_NAME}</string>
+	<key>CFBundleIconFile</key>
+	<string></string>
+	<key>CFBundleIdentifier</key>
+	<string>com.yourcompany.${PRODUCT_NAME:rfc1034identifier}</string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundleName</key>
+	<string>${PRODUCT_NAME}</string>
+	<key>CFBundlePackageType</key>
+	<string>APPL</string>
+	<key>CFBundleShortVersionString</key>
+	<string>1.0</string>
+	<key>CFBundleSignature</key>
+	<string>????</string>
+	<key>CFBundleVersion</key>
+	<string>1</string>
+	<key>LSMinimumSystemVersion</key>
+	<string>${MACOSX_DEPLOYMENT_TARGET}</string>
+	<key>NSMainNibFile</key>
+	<string>MainMenu</string>
+	<key>NSPrincipalClass</key>
+	<string>NSApplication</string>
+</dict>
+</plist>

+ 324 - 0
InsideJob.xcodeproj/project.pbxproj

@@ -0,0 +1,324 @@
+// !$*UTF8*$!
+{
+	archiveVersion = 1;
+	classes = {
+	};
+	objectVersion = 45;
+	objects = {
+
+/* Begin PBXBuildFile section */
+		1DDD58160DA1D0A300B32029 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1DDD58140DA1D0A300B32029 /* MainMenu.xib */; };
+		256AC3DA0F4B6AC300CF3369 /* InsideJobAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 256AC3D90F4B6AC300CF3369 /* InsideJobAppDelegate.m */; };
+		668B2556125D5A3E0060BF71 /* NBTContainer.m in Sources */ = {isa = PBXBuildFile; fileRef = 668B2555125D5A3E0060BF71 /* NBTContainer.m */; };
+		668B255C125D5BCA0060BF71 /* NSData+CocoaDevAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 668B255B125D5BCA0060BF71 /* NSData+CocoaDevAdditions.m */; };
+		668B2560125D5C1C0060BF71 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 668B255F125D5C1C0060BF71 /* libz.dylib */; };
+		8D11072B0486CEB800E47090 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */; };
+		8D11072D0486CEB800E47090 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; settings = {ATTRIBUTES = (); }; };
+		8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXFileReference section */
+		089C165DFE840E0CC02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = "<group>"; };
+		1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = "<absolute>"; };
+		13E42FB307B3F0F600E4EEF1 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = /System/Library/Frameworks/CoreData.framework; sourceTree = "<absolute>"; };
+		1DDD58150DA1D0A300B32029 /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = English.lproj/MainMenu.xib; sourceTree = "<group>"; };
+		256AC3D80F4B6AC300CF3369 /* InsideJobAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InsideJobAppDelegate.h; sourceTree = "<group>"; };
+		256AC3D90F4B6AC300CF3369 /* InsideJobAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = InsideJobAppDelegate.m; sourceTree = "<group>"; };
+		256AC3F00F4B6AF500CF3369 /* InsideJob_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InsideJob_Prefix.pch; sourceTree = "<group>"; };
+		29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
+		29B97324FDCFA39411CA2CEA /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = "<absolute>"; };
+		29B97325FDCFA39411CA2CEA /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = "<absolute>"; };
+		668B2554125D5A3E0060BF71 /* NBTContainer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NBTContainer.h; sourceTree = "<group>"; };
+		668B2555125D5A3E0060BF71 /* NBTContainer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NBTContainer.m; sourceTree = "<group>"; };
+		668B255A125D5BCA0060BF71 /* NSData+CocoaDevAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSData+CocoaDevAdditions.h"; sourceTree = "<group>"; };
+		668B255B125D5BCA0060BF71 /* NSData+CocoaDevAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSData+CocoaDevAdditions.m"; sourceTree = "<group>"; };
+		668B255F125D5C1C0060BF71 /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = usr/lib/libz.dylib; sourceTree = SDKROOT; };
+		8D1107310486CEB800E47090 /* InsideJob-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "InsideJob-Info.plist"; sourceTree = "<group>"; };
+		8D1107320486CEB800E47090 /* InsideJob.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = InsideJob.app; sourceTree = BUILT_PRODUCTS_DIR; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+		8D11072E0486CEB800E47090 /* Frameworks */ = {
+			isa = PBXFrameworksBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */,
+				668B2560125D5C1C0060BF71 /* libz.dylib in Frameworks */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+		080E96DDFE201D6D7F000001 /* Classes */ = {
+			isa = PBXGroup;
+			children = (
+				256AC3D80F4B6AC300CF3369 /* InsideJobAppDelegate.h */,
+				256AC3D90F4B6AC300CF3369 /* InsideJobAppDelegate.m */,
+				668B2551125D59BF0060BF71 /* Model */,
+				668B2559125D5BB90060BF71 /* Categories */,
+			);
+			name = Classes;
+			sourceTree = "<group>";
+		};
+		1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */ = {
+			isa = PBXGroup;
+			children = (
+				668B255F125D5C1C0060BF71 /* libz.dylib */,
+				1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */,
+			);
+			name = "Linked Frameworks";
+			sourceTree = "<group>";
+		};
+		1058C7A2FEA54F0111CA2CBB /* Other Frameworks */ = {
+			isa = PBXGroup;
+			children = (
+				29B97324FDCFA39411CA2CEA /* AppKit.framework */,
+				13E42FB307B3F0F600E4EEF1 /* CoreData.framework */,
+				29B97325FDCFA39411CA2CEA /* Foundation.framework */,
+			);
+			name = "Other Frameworks";
+			sourceTree = "<group>";
+		};
+		19C28FACFE9D520D11CA2CBB /* Products */ = {
+			isa = PBXGroup;
+			children = (
+				8D1107320486CEB800E47090 /* InsideJob.app */,
+			);
+			name = Products;
+			sourceTree = "<group>";
+		};
+		29B97314FDCFA39411CA2CEA /* InsideJob */ = {
+			isa = PBXGroup;
+			children = (
+				080E96DDFE201D6D7F000001 /* Classes */,
+				29B97315FDCFA39411CA2CEA /* Other Sources */,
+				29B97317FDCFA39411CA2CEA /* Resources */,
+				29B97323FDCFA39411CA2CEA /* Frameworks */,
+				19C28FACFE9D520D11CA2CBB /* Products */,
+			);
+			name = InsideJob;
+			sourceTree = "<group>";
+		};
+		29B97315FDCFA39411CA2CEA /* Other Sources */ = {
+			isa = PBXGroup;
+			children = (
+				256AC3F00F4B6AF500CF3369 /* InsideJob_Prefix.pch */,
+				29B97316FDCFA39411CA2CEA /* main.m */,
+			);
+			name = "Other Sources";
+			sourceTree = "<group>";
+		};
+		29B97317FDCFA39411CA2CEA /* Resources */ = {
+			isa = PBXGroup;
+			children = (
+				8D1107310486CEB800E47090 /* InsideJob-Info.plist */,
+				089C165CFE840E0CC02AAC07 /* InfoPlist.strings */,
+				1DDD58140DA1D0A300B32029 /* MainMenu.xib */,
+			);
+			name = Resources;
+			sourceTree = "<group>";
+		};
+		29B97323FDCFA39411CA2CEA /* Frameworks */ = {
+			isa = PBXGroup;
+			children = (
+				1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */,
+				1058C7A2FEA54F0111CA2CBB /* Other Frameworks */,
+			);
+			name = Frameworks;
+			sourceTree = "<group>";
+		};
+		668B2551125D59BF0060BF71 /* Model */ = {
+			isa = PBXGroup;
+			children = (
+				668B2554125D5A3E0060BF71 /* NBTContainer.h */,
+				668B2555125D5A3E0060BF71 /* NBTContainer.m */,
+			);
+			name = Model;
+			sourceTree = "<group>";
+		};
+		668B2559125D5BB90060BF71 /* Categories */ = {
+			isa = PBXGroup;
+			children = (
+				668B255A125D5BCA0060BF71 /* NSData+CocoaDevAdditions.h */,
+				668B255B125D5BCA0060BF71 /* NSData+CocoaDevAdditions.m */,
+			);
+			name = Categories;
+			sourceTree = "<group>";
+		};
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+		8D1107260486CEB800E47090 /* InsideJob */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = C01FCF4A08A954540054247B /* Build configuration list for PBXNativeTarget "InsideJob" */;
+			buildPhases = (
+				8D1107290486CEB800E47090 /* Resources */,
+				8D11072C0486CEB800E47090 /* Sources */,
+				8D11072E0486CEB800E47090 /* Frameworks */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+			);
+			name = InsideJob;
+			productInstallPath = "$(HOME)/Applications";
+			productName = InsideJob;
+			productReference = 8D1107320486CEB800E47090 /* InsideJob.app */;
+			productType = "com.apple.product-type.application";
+		};
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+		29B97313FDCFA39411CA2CEA /* Project object */ = {
+			isa = PBXProject;
+			attributes = {
+				ORGANIZATIONNAME = "Adam Preble";
+			};
+			buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "InsideJob" */;
+			compatibilityVersion = "Xcode 3.1";
+			developmentRegion = English;
+			hasScannedForEncodings = 1;
+			knownRegions = (
+				English,
+				Japanese,
+				French,
+				German,
+			);
+			mainGroup = 29B97314FDCFA39411CA2CEA /* InsideJob */;
+			projectDirPath = "";
+			projectRoot = "";
+			targets = (
+				8D1107260486CEB800E47090 /* InsideJob */,
+			);
+		};
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+		8D1107290486CEB800E47090 /* Resources */ = {
+			isa = PBXResourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				8D11072B0486CEB800E47090 /* InfoPlist.strings in Resources */,
+				1DDD58160DA1D0A300B32029 /* MainMenu.xib in Resources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+		8D11072C0486CEB800E47090 /* Sources */ = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				8D11072D0486CEB800E47090 /* main.m in Sources */,
+				256AC3DA0F4B6AC300CF3369 /* InsideJobAppDelegate.m in Sources */,
+				668B2556125D5A3E0060BF71 /* NBTContainer.m in Sources */,
+				668B255C125D5BCA0060BF71 /* NSData+CocoaDevAdditions.m in Sources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXVariantGroup section */
+		089C165CFE840E0CC02AAC07 /* InfoPlist.strings */ = {
+			isa = PBXVariantGroup;
+			children = (
+				089C165DFE840E0CC02AAC07 /* English */,
+			);
+			name = InfoPlist.strings;
+			sourceTree = "<group>";
+		};
+		1DDD58140DA1D0A300B32029 /* MainMenu.xib */ = {
+			isa = PBXVariantGroup;
+			children = (
+				1DDD58150DA1D0A300B32029 /* English */,
+			);
+			name = MainMenu.xib;
+			sourceTree = "<group>";
+		};
+/* End PBXVariantGroup section */
+
+/* Begin XCBuildConfiguration section */
+		C01FCF4B08A954540054247B /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				COPY_PHASE_STRIP = NO;
+				GCC_DYNAMIC_NO_PIC = NO;
+				GCC_ENABLE_FIX_AND_CONTINUE = YES;
+				GCC_MODEL_TUNING = G5;
+				GCC_OPTIMIZATION_LEVEL = 0;
+				GCC_PRECOMPILE_PREFIX_HEADER = YES;
+				GCC_PREFIX_HEADER = InsideJob_Prefix.pch;
+				INFOPLIST_FILE = "InsideJob-Info.plist";
+				INSTALL_PATH = "$(HOME)/Applications";
+				PRODUCT_NAME = InsideJob;
+			};
+			name = Debug;
+		};
+		C01FCF4C08A954540054247B /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+				GCC_MODEL_TUNING = G5;
+				GCC_PRECOMPILE_PREFIX_HEADER = YES;
+				GCC_PREFIX_HEADER = InsideJob_Prefix.pch;
+				INFOPLIST_FILE = "InsideJob-Info.plist";
+				INSTALL_PATH = "$(HOME)/Applications";
+				PRODUCT_NAME = InsideJob;
+			};
+			name = Release;
+		};
+		C01FCF4F08A954540054247B /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
+				GCC_C_LANGUAGE_STANDARD = gnu99;
+				GCC_OPTIMIZATION_LEVEL = 0;
+				GCC_WARN_ABOUT_RETURN_TYPE = YES;
+				GCC_WARN_UNUSED_VARIABLE = YES;
+				ONLY_ACTIVE_ARCH = YES;
+				PREBINDING = NO;
+				SDKROOT = macosx10.6;
+			};
+			name = Debug;
+		};
+		C01FCF5008A954540054247B /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
+				GCC_C_LANGUAGE_STANDARD = gnu99;
+				GCC_WARN_ABOUT_RETURN_TYPE = YES;
+				GCC_WARN_UNUSED_VARIABLE = YES;
+				PREBINDING = NO;
+				SDKROOT = macosx10.6;
+			};
+			name = Release;
+		};
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+		C01FCF4A08A954540054247B /* Build configuration list for PBXNativeTarget "InsideJob" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				C01FCF4B08A954540054247B /* Debug */,
+				C01FCF4C08A954540054247B /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+		C01FCF4E08A954540054247B /* Build configuration list for PBXProject "InsideJob" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				C01FCF4F08A954540054247B /* Debug */,
+				C01FCF5008A954540054247B /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+/* End XCConfigurationList section */
+	};
+	rootObject = 29B97313FDCFA39411CA2CEA /* Project object */;
+}

+ 17 - 0
InsideJobAppDelegate.h

@@ -0,0 +1,17 @@
+//
+//  InsideJobAppDelegate.h
+//  InsideJob
+//
+//  Created by Adam Preble on 10/6/10.
+//  Copyright 2010 Adam Preble. All rights reserved.
+//
+
+#import <Cocoa/Cocoa.h>
+
+@interface InsideJobAppDelegate : NSObject <NSApplicationDelegate> {
+    NSWindow *window;
+}
+
+@property (assign) IBOutlet NSWindow *window;
+
+@end

+ 23 - 0
InsideJobAppDelegate.m

@@ -0,0 +1,23 @@
+//
+//  InsideJobAppDelegate.m
+//  InsideJob
+//
+//  Created by Adam Preble on 10/6/10.
+//  Copyright 2010 Adam Preble. All rights reserved.
+//
+
+#import "InsideJobAppDelegate.h"
+#import "NBTContainer.h"
+
+@implementation InsideJobAppDelegate
+
+@synthesize window;
+
+- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
+	// Insert code here to initialize your application 
+	
+	NSData *fileData = [NSData dataWithContentsOfURL:[NSURL fileURLWithPath:@"../../level.dat"]];
+	NBTContainer *nbtFile = [NBTContainer nbtContainerWithData:fileData];
+}
+
+@end

+ 7 - 0
InsideJob_Prefix.pch

@@ -0,0 +1,7 @@
+//
+// Prefix header for all source files of the 'InsideJob' target in the 'InsideJob' project
+//
+
+#ifdef __OBJC__
+    #import <Cocoa/Cocoa.h>
+#endif

+ 40 - 0
NBTContainer.h

@@ -0,0 +1,40 @@
+//
+//  NBTFile.h
+//  InsideJob
+//
+//  Created by Adam Preble on 10/6/10.
+//  Copyright 2010 Adam Preble. All rights reserved.
+//
+
+#import <Cocoa/Cocoa.h>
+
+typedef enum {
+	NBTTypeEnd = 0,
+	NBTTypeByte = 1,
+	NBTTypeShort = 2,
+	NBTTypeInt = 3,
+	NBTTypeLong = 4,
+	NBTTypeFloat = 5,
+	NBTTypeDouble = 6,
+	NBTTypeByteArray = 7,
+	NBTTypeString = 8,
+	NBTTypeList = 9,
+	NBTTypeCompound = 10,
+} NBTType; 
+
+@interface NBTContainer : NSObject {
+	NSString *name;
+	NSMutableArray *children;
+	NBTType type;
+	NSString *stringValue;
+	NSNumber *numberValue;
+}
+@property (nonatomic, copy) NSString *name;
+@property (nonatomic, retain) NSMutableArray *children;
+@property (nonatomic, assign) NBTType type;
+@property (nonatomic, retain) NSString *stringValue;
+@property (nonatomic, retain) NSNumber *numberValue;
+
++ (id)nbtContainerWithData:(NSData *)data;
+- (void)readFromData:(NSData *)data;
+@end

+ 192 - 0
NBTContainer.m

@@ -0,0 +1,192 @@
+//
+//  NBTFile.m
+//  InsideJob
+//
+//  Created by Adam Preble on 10/6/10.
+//  Copyright 2010 Adam Preble. All rights reserved.
+//
+//  Spec for the Named Binary Tag format: http://www.minecraft.net/docs/NBT.txt
+
+#import "NBTContainer.h"
+#import "NSData+CocoaDevAdditions.h"
+
+
+@interface NBTContainer ()
+- (void)populateWithBytes:(const uint8_t *)bytes offset:(uint32_t *)offsetPointer;
+- (uint8_t)byteFromBytes:(const uint8_t *)bytes offset:(uint32_t *)offsetPointer;
+- (uint16_t)shortFromBytes:(const uint8_t *)bytes offset:(uint32_t *)offsetPointer;
+- (uint32_t)intFromBytes:(const uint8_t *)bytes offset:(uint32_t *)offsetPointer;
+- (uint64_t)longFromBytes:(const uint8_t *)bytes offset:(uint32_t *)offsetPointer;
+- (NSString *)stringFromBytes:(const uint8_t *)bytes offset:(uint32_t *)offsetPointer;
+@end
+
+
+@implementation NBTContainer
+@synthesize name, children, type;
+@synthesize stringValue, numberValue;
+
+- (id)init
+{
+	if ((self = [super init]))
+	{
+	}
+	return self;
+}
+- (void)dealloc
+{
+	[name release];
+	[children release];
+	[stringValue release];
+	[numberValue release];
+	[super dealloc];
+}
+
+
++ (id)nbtContainerWithData:(NSData *)data;
+{
+	id obj = [[[self class] alloc] init];
+	[obj readFromData:data];
+	return obj;
+}
+
+- (void)readFromData:(NSData *)data
+{
+	data = [data gzipInflate];
+	
+	const uint8_t *bytes = (const uint8_t *)[data bytes];
+	
+	uint32_t offset = 0;
+	[self populateWithBytes:bytes offset:&offset];
+}
+
+- (void)populateWithBytes:(const uint8_t *)bytes offset:(uint32_t *)offsetPointer
+{
+	uint32_t offset = *offsetPointer;
+	self.type = bytes[offset];
+	offset += 1;
+	
+	self.name = [self stringFromBytes:bytes offset:&offset];
+	
+	if (self.type == NBTTypeCompound)
+	{
+		NSLog(@">> start compound named %@", self.name);
+		self.children = [NSMutableArray array];
+		
+		while (1)
+		{
+			NBTType childType = bytes[offset];
+			if (childType == NBTTypeEnd)
+				break;
+			
+			NBTContainer *child = [[NBTContainer alloc] init];
+			[child populateWithBytes:bytes offset:&offset];
+			[self.children addObject:child];
+			[child release];
+		}
+		NSLog(@"<< end compound %@", self.name);
+	}
+	else if (self.type == NBTTypeList)
+	{
+		NBTType listType = bytes[offset];
+		offset += 1;
+		uint32_t listLength = [self intFromBytes:bytes offset:&offset];
+		
+		NSLog(@">> start list named %@ with type=%d length=%d", self.name, listType, listLength);
+		
+		self.children = [NSMutableArray array];
+		while (listLength > 0)
+		{
+			if (listType == NBTTypeDouble)
+			{
+				NSNumber *num = [NSNumber numberWithDouble:(double)[self longFromBytes:bytes offset:&offset]];
+				[self.children addObject:num];
+			}
+			else
+			{
+				NSLog(@"Unhandled list type: %d", self.type);
+			}
+			listLength--;
+		}
+		
+		NSLog(@"<< end list %@", self.name);
+	}	
+	else if (self.type == NBTTypeString)
+	{
+		self.stringValue = [self stringFromBytes:bytes offset:&offset];
+		NSLog(@"   name=%@ stringValue=%@", self.name, self.stringValue);
+	}
+	else if (self.type == NBTTypeLong)
+	{
+		self.numberValue = [NSNumber numberWithUnsignedLongLong:[self longFromBytes:bytes offset:&offset]];
+		NSLog(@"   name=%@ long value=%qu", self.name, [self.numberValue unsignedLongLongValue]);
+	}
+	else if (self.type == NBTTypeShort)
+	{
+		self.numberValue = [NSNumber numberWithUnsignedShort:[self shortFromBytes:bytes offset:&offset]];
+		NSLog(@"   name=%@ short value=0x%x", self.name, [self.numberValue unsignedShortValue]);
+	}
+	else if (self.type == NBTTypeByte)
+	{
+		self.numberValue = [NSNumber numberWithUnsignedChar:[self byteFromBytes:bytes offset:&offset]];
+		NSLog(@"   name=%@ byte value=0x%x", self.name, [self.numberValue unsignedCharValue]);
+	}
+	else
+	{
+		NSLog(@"Unhandled type: %d", self.type);
+	}
+	
+	*offsetPointer = offset;
+}
+
+- (NSString *)stringFromBytes:(const uint8_t *)bytes offset:(uint32_t *)offsetPointer
+{
+	uint32_t offset = *offsetPointer;
+	uint16_t length = (bytes[offset] << 8) | bytes[offset + 1];
+	*offsetPointer += 2 + length;
+	return [[[NSString alloc] initWithBytes:bytes + offset + 2 length:length encoding:NSUTF8StringEncoding] autorelease];
+}
+- (uint8_t)byteFromBytes:(const uint8_t *)bytes offset:(uint32_t *)offsetPointer
+{
+	uint32_t offset = *offsetPointer;
+	uint8_t n = bytes[offset];
+	*offsetPointer += 1;
+	return n;
+}
+- (uint16_t)shortFromBytes:(const uint8_t *)bytes offset:(uint32_t *)offsetPointer
+{
+	uint32_t offset = *offsetPointer;
+	uint16_t n = (bytes[offset + 0] << 8) | bytes[offset + 1];
+	*offsetPointer += 2;
+	return n;
+}
+- (uint32_t)intFromBytes:(const uint8_t *)bytes offset:(uint32_t *)offsetPointer
+{
+	uint32_t offset = *offsetPointer;
+	uint32_t n = (bytes[offset] << 24) | (bytes[offset + 1] << 16) | (bytes[offset + 2] << 8) | bytes[offset + 3];
+	*offsetPointer += 4;
+	return n;
+}
+- (uint64_t)longFromBytes:(const uint8_t *)bytes offset:(uint32_t *)offsetPointer
+{
+	uint32_t offset = *offsetPointer;
+	uint64_t n = (bytes[offset] << 24) | (bytes[offset + 1] << 16) | (bytes[offset + 2] << 8) | bytes[offset + 3];
+	*offsetPointer += 4;
+	n += (uint64_t)((bytes[offset] << 24) | (bytes[offset + 1] << 16) | (bytes[offset + 2] << 8) | bytes[offset + 3]) << 32;
+	*offsetPointer += 4;
+	return n;
+}
+
+
+- (NSData *)data
+{
+	NSMutableData *data = [NSMutableData data];
+	uint8_t t = self.type;
+	[data appendBytes:&t length:1];
+	uint16_t nameLength = self.name.length;
+	[data appendBytes:&nameLength length:2];
+	[data appendBytes:[self.name UTF8String] length:self.name.length];
+	
+	return data;
+}
+
+@end

+ 16 - 0
NSData+CocoaDevAdditions.h

@@ -0,0 +1,16 @@
+//
+//  NSData+CocoaDevAdditions.h
+//  InsideJob
+//
+//  Created by Adam Preble on 10/6/10.
+//
+
+#import <Cocoa/Cocoa.h>
+
+
+@interface NSData (CocoaDevAdditions)
+
+- (NSData *)gzipInflate;
+- (NSData *)gzipDeflate;
+
+@end

+ 100 - 0
NSData+CocoaDevAdditions.m

@@ -0,0 +1,100 @@
+//
+//  NSData+CocoaDevAdditions.m
+//  InsideJob
+//
+//  Created by Adam Preble on 10/6/10.
+//
+//  Source: http://www.cocoadev.com/index.pl?NSDataCategory
+
+
+#import "NSData+CocoaDevAdditions.h"
+#import <zlib.h>
+
+@implementation NSData (CocoaDevAdditions)
+
+
+- (NSData *)gzipInflate
+{
+	if ([self length] == 0) return self;
+	
+	unsigned full_length = [self length];
+	unsigned half_length = [self length] / 2;
+	
+	NSMutableData *decompressed = [NSMutableData dataWithLength: full_length + half_length];
+	BOOL done = NO;
+	int status;
+	
+	z_stream strm;
+	strm.next_in = (Bytef *)[self bytes];
+	strm.avail_in = [self length];
+	strm.total_out = 0;
+	strm.zalloc = Z_NULL;
+	strm.zfree = Z_NULL;
+	
+	if (inflateInit2(&strm, (15+32)) != Z_OK) return nil;
+	while (!done)
+	{
+		// Make sure we have enough room and reset the lengths.
+		if (strm.total_out >= [decompressed length])
+			[decompressed increaseLengthBy: half_length];
+		strm.next_out = [decompressed mutableBytes] + strm.total_out;
+		strm.avail_out = [decompressed length] - strm.total_out;
+		
+		// Inflate another chunk.
+		status = inflate (&strm, Z_SYNC_FLUSH);
+		if (status == Z_STREAM_END) done = YES;
+		else if (status != Z_OK) break;
+	}
+	if (inflateEnd (&strm) != Z_OK) return nil;
+	
+	// Set real length.
+	if (done)
+	{
+		[decompressed setLength: strm.total_out];
+		return [NSData dataWithData: decompressed];
+	}
+	else return nil;
+}
+
+- (NSData *)gzipDeflate
+{
+	if ([self length] == 0) return self;
+	
+	z_stream strm;
+	
+	strm.zalloc = Z_NULL;
+	strm.zfree = Z_NULL;
+	strm.opaque = Z_NULL;
+	strm.total_out = 0;
+	strm.next_in=(Bytef *)[self bytes];
+	strm.avail_in = [self length];
+	
+	// Compresssion Levels:
+	//   Z_NO_COMPRESSION
+	//   Z_BEST_SPEED
+	//   Z_BEST_COMPRESSION
+	//   Z_DEFAULT_COMPRESSION
+	
+	if (deflateInit2(&strm, Z_DEFAULT_COMPRESSION, Z_DEFLATED, (15+16), 8, Z_DEFAULT_STRATEGY) != Z_OK) return nil;
+	
+	NSMutableData *compressed = [NSMutableData dataWithLength:16384];  // 16K chunks for expansion
+	
+	do {
+		
+		if (strm.total_out >= [compressed length])
+			[compressed increaseLengthBy: 16384];
+		
+		strm.next_out = [compressed mutableBytes] + strm.total_out;
+		strm.avail_out = [compressed length] - strm.total_out;
+		
+		deflate(&strm, Z_FINISH);  
+		
+	} while (strm.avail_out == 0);
+	
+	deflateEnd(&strm);
+	
+	[compressed setLength: strm.total_out];
+	return [NSData dataWithData:compressed];
+}
+
+@end

+ 14 - 0
main.m

@@ -0,0 +1,14 @@
+//
+//  main.m
+//  InsideJob
+//
+//  Created by Adam Preble on 10/6/10.
+//  Copyright 2010 Adam Preble. All rights reserved.
+//
+
+#import <Cocoa/Cocoa.h>
+
+int main(int argc, char *argv[])
+{
+    return NSApplicationMain(argc,  (const char **) argv);
+}

BIN
test.nbt