#if defined(GNUSTEP_BASE_LIBRARY) #import #import #import "Testing.h" static GSMimeDocument * parse(GSMimeParser **parserPointer, NSData *data) { GSMimeParser *parser; unsigned length = [data length]; unsigned index; if (0 == parserPointer) { parser = [[GSMimeParser new] autorelease]; } else { if (nil == *parserPointer) { *parserPointer = [[GSMimeParser new] autorelease]; } parser = *parserPointer; } for (index = 0; index < length-1; index++) { NSAutoreleasePool *arp = [NSAutoreleasePool new]; NSData *d; d = [data subdataWithRange: NSMakeRange(index, 1)]; if ([parser parse: d] == NO) { return [parser mimeDocument]; } [arp release]; } data = [data subdataWithRange: NSMakeRange(index, 1)]; if ([parser parse: data] == YES && NO == [parser isComplete]) { [parser parse: nil]; } return [parser mimeDocument]; } static GSMimeDocument * exact(GSMimeParser **parserPointer, NSData *data) { GSMimeParser *parser = nil; GSMimeDocument *doc; if (0 == parserPointer) { parserPointer = &parser; } doc = parse(parserPointer, data); if (nil != [parser excess]) { NSLog(@"Excess data in parser after parse completed"); doc = nil; } return doc; } int main() { NSAutoreleasePool *arp = [NSAutoreleasePool new]; NSData *cr; NSData *data; GSMimeParser *parser; GSMimeDocument *doc; GSMimeDocument *idoc; cr = [NSData dataWithBytes: "\r" length: 1]; data = [NSData dataWithBytes: "DQ==" length: 4]; PASS_EQUAL([GSMimeDocument decodeBase64: data], cr, "decodeBase64 works for padded data"); data = [NSData dataWithBytes: "DQ" length: 2]; PASS_EQUAL([GSMimeDocument decodeBase64: data], cr, "decodeBase64 works for unpadded data"); data = [NSData dataWithContentsOfFile: @"mime1.dat"]; idoc = exact(0, data); PASS_EQUAL([[[idoc content] objectAtIndex:0] content], @"a", "can parse one char base64 mime1.dat incrementally"); doc = [GSMimeParser documentFromData: data]; PASS_EQUAL([[[doc content] objectAtIndex:0] content], @"a", "can parse one char base64 mime1.dat in one go"); PASS_EQUAL(idoc, doc, "mime1.dat documents are the same"); parser = [GSMimeParser new]; data = [[data mutableCopy] autorelease]; [(NSMutableData*)data appendBytes: "\r\n\r\n" length: 4]; [parser parse: data]; doc = [parser document]; PASS([[parser excess] length] == 4, "Can detect excess data in multipart"); [parser release]; data = [NSData dataWithContentsOfFile: @"mime2.dat"]; idoc = exact(0, data); PASS_EQUAL([idoc content], @"aa", "can parse two char base64 mime2.dat incrementally"); doc = [GSMimeParser documentFromData: data]; PASS_EQUAL([doc content], @"aa", "can parse two char base64 mime2.dat in one go"); PASS_EQUAL(idoc, doc, "mime2.dat documents are the same"); data = [NSData dataWithContentsOfFile: @"mime3.dat"]; idoc = exact(0, data); PASS(([[idoc content] isEqual: @"aaa"]), "can parse three char base64 mime3.dat incrementally"); doc = [GSMimeParser documentFromData: data]; PASS(([[doc content] isEqual: @"aaa"]), "can parse three char base64 mime3.dat in one go"); PASS([idoc isEqual: doc], "mime3.dat documents are the same"); data = [NSData dataWithContentsOfFile: @"mime4.dat"]; idoc = exact(0, data); PASS(([[[[idoc content] objectAtIndex:0] content] isEqual: @"hello\n"] && [[[[idoc content] objectAtIndex:1] content] isEqual: @"there\n"]), "can parse multi-part text mime4.dat incrementally"); PASS(([[[[idoc content] objectAtIndex:0] contentFile] isEqual: @"a.a"]), "can extract content file name from mime4.dat (incrementally parsed)"); PASS(([[[[idoc content] objectAtIndex:0] contentType] isEqual: @"text"]), "can extract content type from mime4.dat (incrementally parsed)"); PASS(([[[[idoc content] objectAtIndex:0] contentSubtype] isEqual: @"plain"]), "can extract content sub type from mime4.dat (incrementally parsed)"); doc = [GSMimeParser documentFromData: data]; PASS(([[[[doc content] objectAtIndex:0] content] isEqual: @"hello\n"] && [[[[doc content] objectAtIndex:1] content] isEqual: @"there\n"]), "can parse multi-part text mime4.dat in one go"); PASS(([[[[doc content] objectAtIndex:0] contentFile] isEqual: @"a.a"]), "can extract content file name from mime4.dat (parsed in one go)"); PASS(([[[[doc content] objectAtIndex:0] contentType] isEqual: @"text"]), "can extract content type from mime4.dat (parsed in one go)"); PASS(([[[[doc content] objectAtIndex:0] contentSubtype] isEqual: @"plain"]), "can extract content sub type from mime4.dat (parsed in one go)"); PASS([idoc isEqual: doc], "mime4.dat documents are the same"); data = [NSData dataWithContentsOfFile: @"mime5.dat"]; idoc = exact(0, data); PASS(([[idoc contentSubtype] isEqual: @"xml"]), "can parse http document mime5.dat incrementally"); doc = [GSMimeParser documentFromData: data]; PASS(([[doc contentSubtype] isEqual: @"xml"]), "can parse http document mime5.dat in one go"); PASS([idoc isEqual: doc], "mime5.dat documents are the same"); data = [NSData dataWithContentsOfFile: @"mime6.dat"]; idoc = exact(0, data); PASS(([[idoc content] count] == 3), "can parse multipart mixed mime6.dat incrementally"); doc = [GSMimeParser documentFromData: data]; PASS(([[doc content] count] == 3), "can parse multipart mixed mime6.dat in one go"); PASS([idoc isEqual: doc], "mime6.dat documents are the same"); data = [NSData dataWithContentsOfFile: @"mime7.dat"]; PASS(([[[[doc content] objectAtIndex:1] content] isEqual: data]), "mime6.dat binary data part matches mime7.dat"); data = [NSData dataWithContentsOfFile: @"mime9.dat"]; idoc = exact(0, data); PASS(([[[idoc headerNamed: @"Long"] value] isEqual: @"first second third"]), "mime9.dat folded header unfolds correctly incrementally"); doc = [GSMimeParser documentFromData: data]; //NSLog(@"'%@'", [[doc headerNamed: @"Long"] value]); PASS(([[[doc headerNamed: @"Long"] value] isEqual: @"first second third"]), "mime9.dat folded header unfolds correctly in one go"); PASS([idoc isEqual: doc], "mime9.dat documents are the same"); /* Test a document containing nested multipart documents */ data = [NSData dataWithContentsOfFile: @"mime10.dat"]; idoc = exact(0, data); doc = [GSMimeParser documentFromData: data]; PASS([idoc isEqual: doc], "mime10.dat documents are the same"); data = [idoc rawMimeData]; doc = [GSMimeParser documentFromData: data]; PASS([idoc isEqual: doc], "rawMimeData reproduces docuement"); [arp release]; arp = nil; return 0; } #else int main(int argc,char **argv) { return 0; } #endif