@implementation JSbdecoder - (NSDictionary *) decodeTorrentFileData: (NSData *) torrentFileData { self.rawTorrentData = [torrentFileData bytes]; self.torrentData = torrentFileData; self.position = 0; return [NSDictionary dictionaryWithDictionary: [self convertDictionaryDataToStrings:[[NSArray arrayWithArray:[self bdecodeData]] objectAtIndex: 0]]]; } - (NSArray *) bdecodeData { NSMutableArray *methodArray = [NSMutableArray array]; do{ if(self.rawTorrentData[self.position] == 'i') { self.position++; [methodArray addObject:[self decodeInt]]; } else if(self.rawTorrentData[self.position] == 'l') { self.position++; [methodArray addObject:[self decodeList]]; } else if(self.rawTorrentData[self.position] == 'd') { self.position++; [methodArray addObject:[self decodeDictionary]]; } else if(isdigit(self.rawTorrentData[self.position])) { [methodArray addObject:[self decodeBytes]]; } else if(self.rawTorrentData[self.position] == 'e') { self.position++; //Should only hit this when at the end of lists or dictionaries. break; } else { NSLog(@"Error decoding torrent. Unexpected character '%c' at position %d.", self.rawTorrentData[self.position], self.position); exit(0); } } while(self.position < [self.torrentData length]); return [NSArray arrayWithArray: methodArray]; } - (NSNumber *) decodeInt { uint32 methodPosition = self.position; while(self.rawTorrentData[self.position] != 'e') { self.position++; } self.position++; return [NSNumber numberWithInteger: [[NSString stringWithUTF8String: [[self.torrentData subdataWithRange: NSMakeRange(methodPosition, (self.position - methodPosition))] bytes]] integerValue]]; } - (NSData *) decodeBytes { uint32 methodPosition = self.position; while(self.rawTorrentData[self.position] != ':') { self.position++; } NSUInteger bytesLength = [[NSString stringWithUTF8String: [[self.torrentData subdataWithRange: NSMakeRange(methodPosition, (self.position - methodPosition))] bytes]] integerValue]; self.position++; methodPosition = self.position; self.position += bytesLength; return [NSData dataWithData: [self.torrentData subdataWithRange: NSMakeRange(methodPosition, bytesLength)]]; } - (NSArray *) decodeList { return [NSArray arrayWithArray:[self bdecodeData]]; } - (NSDictionary *) decodeDictionary { NSMutableDictionary *methodDictionary = [NSMutableDictionary dictionary]; NSArray *methodArray = [NSArray arrayWithArray:[self bdecodeData]]; for(NSUInteger i = 0; i < [methodArray count]; i += 2) { [methodDictionary setObject: [methodArray objectAtIndex: i + 1] forKey: [methodArray objectAtIndex: i]]; } return [NSDictionary dictionaryWithDictionary: methodDictionary]; }