]> err.no Git - sope/commitdiff
fixed OGo bug #1324
authorhelge <helge@e4a50df8-12e2-0310-a44c-efbce7f8a7e3>
Thu, 24 Mar 2005 18:17:35 +0000 (18:17 +0000)
committerhelge <helge@e4a50df8-12e2-0310-a44c-efbce7f8a7e3>
Thu, 24 Mar 2005 18:17:35 +0000 (18:17 +0000)
git-svn-id: http://svn.opengroupware.org/SOPE/trunk@698 e4a50df8-12e2-0310-a44c-efbce7f8a7e3

sope-mime/ChangeLog
sope-mime/NGImap4/ChangeLog
sope-mime/NGImap4/EOQualifier+IMAPAdditions.m
sope-mime/NGMail/ChangeLog
sope-mime/NGMail/NGMimeMessageGenerator.h
sope-mime/NGMail/NGMimeMessageGenerator.m
sope-mime/NGMime/ChangeLog
sope-mime/NGMime/NGMimePartGenerator.h
sope-mime/NGMime/NGMimePartGenerator.m
sope-mime/Version

index 2cfeee07f14bc05cad880cecce6d707d0541dd98..90118a350c9f2864f0971ad7f98568325833efe4 100644 (file)
@@ -1,5 +1,8 @@
 2005-03-24  Helge Hess  <helge.hess@skyrix.com>
 
+       * NGMime, NGMail: fixed OGo bug #1324 by adding support for multivalue
+         header fields (v4.5.219)
+
        * NGMime: minor code cleanups (v4.5.218)
 
 2005-03-05  Helge Hess  <helge.hess@opengroupware.org>
index d3b244994b50079e6e109bee8a485e9bfcdd8a40..f544c8610ebb34ce2789256638255da44c6952f4 100644 (file)
@@ -1,3 +1,7 @@
+2005-03-24  Helge Hess  <helge.hess@opengroupware.org>
+
+       * EOQualifier+IMAPAdditions.m: fixed a warning
+
 2005-03-05  Helge Hess  <helge.hess@opengroupware.org>
 
        * NGImap4Folder.m: properly create NSURL if the absolute name doesn't
index 87b86e4470cd3792e69d40a2ece0a293068fa193..0b6cd67112b35e170dc4ade332b5444fd85eeba6 100644 (file)
@@ -31,6 +31,8 @@
   insertNot:(BOOL)_insertNot;
 - (NSException *)appendToImap4SearchString:(NSMutableString *)_search;
 
+- (id)imap4SearchString;
+
 @end
 
 @implementation EOQualifier(IMAPAdditions)
index 966484519a5dae21c417edc48b28eb7d5b3cef0a..e1ef34ce33356305b3eff448e590b5407dec633a 100644 (file)
@@ -1,3 +1,8 @@
+2005-03-24  Helge Hess  <helge.hess@opengroupware.org>
+
+       * NGMimeMessageGenerator.m: mark To, Cc and Bcc as multivalue header
+         fields to fix #1324
+
 2005-03-24  Helge Hess  <helge.hess@skyrix.com>
        
        * NGMimeMessageGenerator.m: minor code cleanups
index 2b4635bb8aeaa25378a7f6f598ed4f64d724e1ca..015735858e103b8b66128539e52e3ffe0c925eee 100644 (file)
@@ -26,7 +26,7 @@
 #include <NGMime/NGMimeBodyGenerator.h>
 
 /*
-  Parses Rfc822 Mime Message Parts
+  Generates RFC 2822 MIME message parts.
 */
 
 @interface NGMimeMessageBodyGenerator : NGMimeBodyGenerator
index 50820cf04c4405d0075acbd3210ea0bb464edf5b..736a9da16f2d3e50fe186cb49f554b930f513360 100644 (file)
@@ -45,6 +45,39 @@ static BOOL debugOn = NO;
 
 /* header field specifics */
 
+- (BOOL)isMultiValueCommaHeaderField:(NSString *)_headerField {
+  /* 
+     This is called by the superclass when generating fields.
+     
+     Currently checks for: to, cc, bcc 
+  */
+  unsigned len;
+  unichar  c0, c1;
+  
+  if ((len = [_headerField length]) < 2)
+    return [super isMultiValueCommaHeaderField:_headerField];
+  
+  c0 = [_headerField characterAtIndex:0];
+  c1 = [_headerField characterAtIndex:1];
+  
+  switch (len) {
+  case 2:
+    if ((c0 == 't' || c0 == 'T') && ((c1 == 'o' || c1 == 'O')))
+      return YES;
+    if ((c0 == 'c' || c0 == 'C') && ((c1 == 'c' || c1 == 'C')))
+      return YES;
+    break;
+  case 3:
+    if ((c0 == 'b' || c0 == 'B') && ((c1 == 'c' || c1 == 'C'))) {
+      c0 = [_headerField characterAtIndex:2];
+      if (c0 == 'c' || c0 == 'C')
+       return YES;
+    }
+    break;
+  }
+  return [super isMultiValueCommaHeaderField:_headerField];
+}
+
 - (id)_escapeHeaderFieldValue:(NSData *)_data {
   const char   *bytes  = NULL;
   unsigned int length  = 0;
index 7f0e2c619a6ec520e2a7ddb2441b1ded4b9a6203..5e02edef422780c800541414b97cebf4855a3525 100644 (file)
@@ -1,3 +1,8 @@
+2005-03-24  Helge Hess  <helge.hess@opengroupware.org>
+
+       * NGMimePartGenerator.m: minor improvement in field generation API,
+         added support for multivalue headers (related to #1324)
+
 2005-03-05  Helge Hess  <helge.hess@opengroupware.org>
 
        * NGMimePartGenerator.m: properly terminate header fields with \r\n
index 973f7779146ed22525c9a1be39703317d7a1cc57..a5fc49269ffc193298f05f49ed6d41a6bd28a75e 100644 (file)
@@ -26,7 +26,8 @@
 #import <NGMime/NGPart.h>
 #import <NGMime/NGMimeGeneratorProtocols.h>
 
-@class NSMutableData, NSData, NSString, NGHashMap, NGMutableHashMap;
+@class NSMutableData, NSData, NSString, NSEnumerator;
+@class NGHashMap, NGMutableHashMap;
 @class NGMimeType, NGMimePartGenerator;
 
 @interface NGMimePartGenerator : NSObject <NGMimePartGenerator>
@@ -95,8 +96,9 @@
 
 /* build data with the specified header; */
 
-- (NSData *)generateDataWithHeaderField:(NSString *)_headerField
-  values:(NSEnumerator *)_enumerator;
+- (BOOL)isMultiValueCommaHeaderField:(NSString *)_headerField;
+- (BOOL)appendHeaderField:(NSString *)_field values:(NSEnumerator *)_values
+  toData:(NSMutableData *)_data;
 
 /* looking for a NGMimeBodyGenerator in dependece to the content-type */
 - (id<NGMimeBodyGenerator>)generatorForBodyOfPart:(id<NGMimePart>)_part;
index 0e915e7ebd7d8d09c78b24dbdd5ad6583a51bea5..bd3015e4ea217e2a01fff9c0687f946c57d4d5f7 100644 (file)
@@ -29,7 +29,7 @@
 @implementation NGMimePartGenerator
 
 static NSProcessInfo *Pi = nil;
-static BOOL debugOn = NO;
+static BOOL       debugOn = NO;
 
 + (int)version {
   return 2;
@@ -122,12 +122,13 @@ static BOOL debugOn = NO;
 - (NSData *)generateDataForHeaderField:(NSString *)_headerField
   value:(id)_value
 {
-  NSData *data = nil;
+  NSData *data;
 
-  if (self->delegateRespondsTo.generatorGenerateDataForHeaderField)
+  if (self->delegateRespondsTo.generatorGenerateDataForHeaderField) {
     data = [self->delegate mimePartGenerator:self
                            generateDataForHeaderField:_headerField
                            value:_value];
+  }
   else {
     data = [[self generatorForHeaderField:_headerField]
                   generateDataForHeaderFieldNamed:_headerField
@@ -136,54 +137,77 @@ static BOOL debugOn = NO;
   return data;
 }
 
-- (NSData *)generateDataWithHeaderField:(NSString *)_headerField
-  values:(NSEnumerator *)_values
+- (BOOL)isMultiValueCommaHeaderField:(NSString *)_headerField {
+  /* 
+     This is used by NGMimeMessageGenerator to encode multivalue To/Cc/Bcc
+     in a single line.
+  */
+  return NO;
+}
+
+- (BOOL)appendHeaderField:(NSString *)_field values:(NSEnumerator *)_values
+  toData:(NSMutableData *)_data
 {
-  NSMutableData *res   = nil;
-  NSData        *data  = nil;
-  id            value  = nil;
-  const char    *bytes = NULL;
-  unsigned      len    = 0;
+  /* returns whether data was generated */
+  const unsigned char *fcname;
+  id       value  = nil;
+  unsigned len;
+  BOOL     isMultiValue, isFirst;
   
-  res = [NSMutableData dataWithCapacity:64];
-  bytes = [_headerField cString];
-  len   = [_headerField length];
-  while (len > 0) {
-    if (*bytes != ' ')
+  /* get field name and strip leading spaces */
+  fcname = [_field cString];
+  for (len = [_field cStringLength]; len > 0; fcname++, len--) {
+    if (*fcname != ' ')
       break;
-    bytes++;
-    len--;
   }
+  
+  isMultiValue = [self isMultiValueCommaHeaderField:_field];
+  isFirst      = YES;
   while ((value = [_values nextObject]) != nil) {
-    data = [self generateDataForHeaderField:(NSString *)_headerField
-                 value:value];
-    [res appendBytes:bytes length:len];
-    [res appendBytes:": " length:2];
-    [res appendData:data];
-    [res appendBytes:"\r\n" length:2];
+    NSData *data;
+    
+    if ((data = [self generateDataForHeaderField:_field value:value]) == nil)
+      continue;
+    
+    if (isMultiValue) {
+      if (isFirst) {
+       [_data appendBytes:fcname length:len];
+       [_data appendBytes:": " length:2];
+       isFirst = NO;
+      }
+      else
+       [_data appendBytes:", " length:2];
+      
+      [_data appendData:data];
+    }
+    else {
+      [_data appendBytes:fcname length:len];
+      [_data appendBytes:": " length:2];
+      [_data appendData:data];
+      [_data appendBytes:"\r\n" length:2];
+    }
   }
-  return res;
+  if (!isFirst && isMultiValue) [_data appendBytes:"\r\n" length:2];
+  return isFirst;
 }
-  
 
 - (NSData *)generateHeaderData:(NGHashMap *)_additionalHeaders {
   NSEnumerator     *headerFieldNames = nil;
   NSString         *headerFieldName  = nil;
   NGMutableHashMap *addHeaders       = nil;
-  NSMutableData    *data             = nil;
-
+  NSMutableData    *data;
+  
   data = (self->useMimeData)
     ? [[[NGMimeJoinedData alloc] init] autorelease]
     : [NSMutableData dataWithCapacity:2048];
   
   headerFieldNames = [self->part headerFieldNames];
   addHeaders       = [_additionalHeaders mutableCopy];
-
-  while ((headerFieldName = [headerFieldNames nextObject])) {
-    NSData       *headerFieldData = nil;
-    NSEnumerator *enumerator      = nil;
+  
+  while ((headerFieldName = [headerFieldNames nextObject]) != nil) {
+    NSEnumerator *enumerator;
     BOOL         reset;
-      
+    
     if ([[_additionalHeaders objectsForKey:headerFieldName] count] > 0) {
       enumerator = [addHeaders objectEnumeratorForKey:headerFieldName];
       reset = YES;
@@ -192,29 +216,27 @@ static BOOL debugOn = NO;
       reset = NO;
       enumerator = [self->part valuesOfHeaderFieldWithName:headerFieldName];
     }
-    headerFieldData = [self generateDataWithHeaderField:headerFieldName
-                            values:enumerator];
-    if (reset)
-      [addHeaders removeAllObjectsForKey:headerFieldName];
     
-    if (headerFieldData)
-      [data appendData:headerFieldData];
+    [self appendHeaderField:headerFieldName values:enumerator toData:data];
+    
+    if (reset) [addHeaders removeAllObjectsForKey:headerFieldName];
   }
+  
   headerFieldNames = [addHeaders keyEnumerator];
-  while ((headerFieldName = [headerFieldNames nextObject])) {
-    NSData *headerFieldData = nil;
-    headerFieldData = [self generateDataWithHeaderField:headerFieldName
-                            values:[addHeaders objectEnumeratorForKey:
-                                              headerFieldName]];
-    if (headerFieldData)
-      [data appendData:headerFieldData];
+  while ((headerFieldName = [headerFieldNames nextObject]) != nil) {
+    [self appendHeaderField:headerFieldName
+         values:[addHeaders objectEnumeratorForKey:headerFieldName]
+         toData:data];
   }
   [addHeaders release]; addHeaders = nil;
   return data;
 }
 
 - (NGMimeType *)defaultContentTypeForPart:(id<NGMimePart>)_part {
-  return [NGMimeType mimeType:@"application/octet-stream"];
+  static NGMimeType *octetStreamType = nil;
+  if (octetStreamType == nil)
+    octetStreamType = [[NGMimeType mimeType:@"application/octet-stream"] copy];
+  return octetStreamType;
 }
 
 - (id<NGMimeBodyGenerator>)defaultBodyGenerator {
index f805eb4df47283f510103b26b07a411966b34ea7..6f8c65aae8019ee02d70f712c202cc8b22f0d256 100644 (file)
@@ -2,7 +2,7 @@
 
 MAJOR_VERSION:=4
 MINOR_VERSION:=5
-SUBMINOR_VERSION:=218
+SUBMINOR_VERSION:=219
 
 # v4.5.214 requires libNGExtensions v4.5.146
 # v4.2.149 requires libNGStreams    v4.2.34