diff --git a/ChangeLog b/ChangeLog
index 9b29f9e4a..c5e86515b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,8 +2,13 @@
* Headers/Foundation/GSMime.h: Tidy up and add convenience methods.
* Source/Additions/GSMime.m: Tidy up and add convenience methods.
+ Added methods to convert content between string and data for ease
+ of use from java.
* Source/NSBundle.m: ([+allBundles]) Don't enumeraste if map table
has not been created yet.
+ * Source/NSLog.m: Allow output descriptor to be changed.
+ * Source/NSProcessInfo.m: Add method to change log output to go to
+ another file for applications where stderr has been hijacked.
2002-05-26 Fred Kiefer
+ * A multipart document will be parsed to content consisting of an
+ * NSArray of GSMimeDocument instances representing each part.
+ * Otherwise, a document will become content of type NSData, unless
+ * it is of content type text, in which case it will be an
+ * NSString.
+ * If a document has no content type specified, it will be treated as
+ * text, unless it is identifiable as a file
+ * (eg. t has a content-disposition header containing a filename parameter).
+ *
* This method is called to parse a header line and split its
@@ -1449,32 +1495,7 @@ parseCharacterSet(NSString *token)
value = type;
}
- while ([scanner scanString: @";" intoString: 0] == YES)
- {
- NSString *paramName;
-
- paramName = [self scanToken: scanner];
- if ([paramName length] == 0)
- {
- NSLog(@"Invalid Mime content-type (parameter name)");
- return NO;
- }
- if ([scanner scanString: @"=" intoString: 0] == YES)
- {
- NSString *paramValue;
-
- paramValue = [self scanToken: scanner];
- if (paramValue == nil)
- {
- paramValue = @"";
- }
- [info setParameter: paramValue forKey: paramName];
- }
- else
- {
- NSLog(@"Ignoring Mime content-type parameter (%@)", paramName);
- }
- }
+ [self scanHeaderParameters: scanner into: info];
}
else if ([name isEqualToString: @"content-disposition"] == YES)
{
@@ -1497,33 +1518,7 @@ parseCharacterSet(NSString *token)
/*
* Expect anything else to be 'name=value' parameters.
*/
- while ([scanner scanString: @";" intoString: 0] == YES)
- {
- NSString *paramName;
-
- paramName = [self scanToken: scanner];
- if ([paramName length] == 0)
- {
- NSLog(@"Invalid Mime content-type (parameter name)");
- return NO;
- }
- if ([scanner scanString: @"=" intoString: 0] == YES)
- {
- NSString *paramValue;
-
- paramValue = [self scanToken: scanner];
- if (paramValue == nil)
- {
- paramValue = @"";
- }
- [info setParameter: paramValue forKey: paramName];
- }
- else
- {
- NSLog(@"Ignoring Mime content-disposition parameter (%@)",
- paramName);
- }
- }
+ [self scanHeaderParameters: scanner into: info];
}
else
{
@@ -1650,7 +1645,7 @@ parseCharacterSet(NSString *token)
done = YES;
}
}
- [scanner setScanLocation: r.length + 1];
+ [scanner setScanLocation: r.location + 1];
length = r.location - start;
if (length == 0)
{
@@ -1947,9 +1942,22 @@ parseCharacterSet(NSString *token)
NSDebugMLLog(@"GSMime", @"Parse body complete");
/*
- * If no content type is supplied, we assume text.
+ * If no content type is supplied, we assume text ... unless
+ * we have something that's known to be a file.
*/
- if (type == nil || [type isEqualToString: @"text"] == YES)
+ if (type == nil)
+ {
+ if ([document contentFile] != nil)
+ {
+ type = @"application";
+ }
+ else
+ {
+ type = @"text";
+ }
+ }
+
+ if ([type isEqualToString: @"text"] == YES)
{
NSDictionary *params;
NSString *charset;
@@ -2673,12 +2681,14 @@ static NSCharacterSet *tokenSet = nil;
}
/**
- * Search the content of this document to locate a part whose content name
- * matches the specified key. Recursively descend into other documents.
+ * Search the content of this document to locate a part whose content-type
+ * name or content-disposition name matches the specified key.
+ * Recursively descend into other documents.
* Return nil if no match is found, the matching GSMimeDocument otherwise.
*/
- (id) contentByName: (NSString*)key
{
+
if ([content isKindOfClass: [NSArray class]] == YES)
{
NSEnumerator *e = [content objectEnumerator];
@@ -2686,7 +2696,15 @@ static NSCharacterSet *tokenSet = nil;
while ((d = [e nextObject]) != nil)
{
- if ([[d contentName] isEqualToString: key] == YES)
+ GSMimeHeader *hdr;
+
+ hdr = [d headerNamed: @"content-type"];
+ if ([[hdr parameterForKey: @"name"] isEqualToString: key] == YES)
+ {
+ return d;
+ }
+ hdr = [d headerNamed: @"content-disposition"];
+ if ([[hdr parameterForKey: @"name"] isEqualToString: key] == YES)
{
return d;
}
@@ -2750,6 +2768,47 @@ static NSCharacterSet *tokenSet = nil;
return [hdr objectForKey: @"Type"];
}
+/**
+ * Return the content as an NSData object (unless it is multipart)
+ */
+- (NSData*) convertToData
+{
+ NSData *d = nil;
+
+ if ([content isKindOfClass: [NSString class]] == YES)
+ {
+ NSStringEncoding enc = NSUTF8StringEncoding;
+
+ d = [content dataUsingEncoding: enc];
+ }
+ else if ([content isKindOfClass: [NSData class]] == YES)
+ {
+ d = content;
+ }
+ return d;
+}
+
+/**
+ * Return the content as an NSString object (unless it is multipart)
+ */
+- (NSString*) convertToText
+{
+ NSString *s = nil;
+
+ if ([content isKindOfClass: [NSString class]] == YES)
+ {
+ s = content;
+ }
+ else if ([content isKindOfClass: [NSData class]] == YES)
+ {
+ NSStringEncoding enc = NSUTF8StringEncoding;
+
+ s = [[NSString alloc] initWithData: content encoding: enc];
+ AUTORELEASE(s);
+ }
+ return s;
+}
+
- (id) copyWithZone: (NSZone*)z
{
return RETAIN(self);
diff --git a/Source/NSLog.m b/Source/NSLog.m
index e58b117f6..2e408e37d 100644
--- a/Source/NSLog.m
+++ b/Source/NSLog.m
@@ -46,6 +46,8 @@
#include "GSPrivate.h"
+int _NSLogDescriptor = 2; // Default descriptor for logging
+
static void
_NSLog_standard_printf_handler (NSString* message)
{
@@ -78,7 +80,8 @@ _NSLog_standard_printf_handler (NSString* message)
#ifdef HAVE_SYSLOG
- if (GSUserDefaultsFlag(GSLogSyslog) == YES || write(2, buf, len) != len)
+ if (GSUserDefaultsFlag(GSLogSyslog) == YES
+ || write(_NSLogDescriptor, buf, len) != len)
{
int mask;
@@ -98,7 +101,7 @@ _NSLog_standard_printf_handler (NSString* message)
syslog(mask, "%s", buf);
}
#else
- write(2, buf, len);
+ write(_NSLogDescriptor, buf, len);
#endif
}
diff --git a/Source/NSProcessInfo.m b/Source/NSProcessInfo.m
index 5367a5f37..8e3c595c2 100644
--- a/Source/NSProcessInfo.m
+++ b/Source/NSProcessInfo.m
@@ -67,6 +67,8 @@
#include
+ * Returns YES on success, NO on failure.
+ * By default logging goes to standard error.
+ */
+- (BOOL) setLogFile: (NSString*)path
+{
+ extern int _NSLogDescriptor;
+ int desc;
+
+ desc = open([path fileSystemRepresentation], O_RDWR|O_CREAT|O_APPEND, 0644);
+ if (desc >= 0)
+ {
+ if (_NSLogDescriptor >= 0 && _NSLogDescriptor != 2)
+ {
+ close(_NSLogDescriptor);
+ }
+ _NSLogDescriptor = desc;
+ return YES;
+ }
+ return NO;
+}
@end
/**