]> err.no Git - sope/commitdiff
more work on vCard parsing
authorhelge <helge@e4a50df8-12e2-0310-a44c-efbce7f8a7e3>
Sun, 8 May 2005 23:02:51 +0000 (23:02 +0000)
committerhelge <helge@e4a50df8-12e2-0310-a44c-efbce7f8a7e3>
Sun, 8 May 2005 23:02:51 +0000 (23:02 +0000)
git-svn-id: http://svn.opengroupware.org/SOPE/trunk@805 e4a50df8-12e2-0310-a44c-efbce7f8a7e3

22 files changed:
sope-ical/NGiCal/ChangeLog
sope-ical/NGiCal/GNUmakefile
sope-ical/NGiCal/NGVCard.h
sope-ical/NGiCal/NGVCard.m
sope-ical/NGiCal/NGVCardAddress.h
sope-ical/NGiCal/NGVCardAddress.m
sope-ical/NGiCal/NGVCardCategories.h [new file with mode: 0644]
sope-ical/NGiCal/NGVCardCategories.m
sope-ical/NGiCal/NGVCardName.m
sope-ical/NGiCal/NGVCardOrg.h [new file with mode: 0644]
sope-ical/NGiCal/NGVCardOrg.m [new file with mode: 0644]
sope-ical/NGiCal/NGVCardPhone.h [new file with mode: 0644]
sope-ical/NGiCal/NGVCardPhone.m
sope-ical/NGiCal/NGVCardSaxHandler.h
sope-ical/NGiCal/NGVCardSaxHandler.m
sope-ical/NGiCal/NGVCardSimpleValue.h [new file with mode: 0644]
sope-ical/NGiCal/NGVCardSimpleValue.m
sope-ical/NGiCal/NGVCardValue.h
sope-ical/NGiCal/NGVCardValue.m
sope-ical/NGiCal/Version
sope-ical/samples/GNUmakefile
sope-ical/samples/vcfparsetest.m [new file with mode: 0644]

index 716f419a51fa00f90aa989a3d9b2817baa82e36c..cf4d0931eb2245f14a4b6ae17aab7d3a9dcf16ad 100644 (file)
@@ -1,5 +1,7 @@
 2005-05-08  Helge Hess  <helge.hess@opengroupware.org>
 
+       * more work on vCard parsing (v4.5.53)
+
        * work on vCard objects (incomplete) (v4.5.52)
 
 2005-04-25  Helge Hess  <helge.hess@opengroupware.org>
index b05baa16dc16698c40ec856676f7f85388c8756d..09c626e637a742439fec6ded0cbdd6708665fb5d 100644 (file)
@@ -35,9 +35,14 @@ libNGiCal_HEADER_FILES =             \
        NSCalendarDate+ICal.h           \
        \
        NGVCard.h                       \
-       NGVCardValue.h                  \
-       NGVCardName.h                   \
        NGVCardAddress.h                \
+       NGVCardCategories.h             \
+       NGVCardName.h                   \
+       NGVCardOrg.h                    \
+       NGVCardPhone.h                  \
+       NGVCardSaxHandler.h             \
+       NGVCardSimpleValue.h            \
+       NGVCardValue.h                  \
 
 #      IcalResponse.h                  \
 
@@ -65,14 +70,16 @@ libNGiCal_OBJC_FILES =              \
        iCalRecurrenceCalculator.m      \
        \
        NGICalSaxHandler.m              \
-       NGVCardSaxHandler.m             \
+       \
        NGVCard.m                       \
-       NGVCardValue.m                  \
-       NGVCardSimpleValue.m            \
        NGVCardAddress.m                \
-       NGVCardPhone.m                  \
        NGVCardCategories.m             \
        NGVCardName.m                   \
+       NGVCardOrg.m                    \
+       NGVCardPhone.m                  \
+       NGVCardSaxHandler.m             \
+       NGVCardSimpleValue.m            \
+       NGVCardValue.m                  \
 
 #      NSString+ICal.m                 \
 #      IcalElements.m
index c84df57179af2607b79b45b98a47663751fc53d2..f6fa1661c798c1c62661596e5fcb36923e09dd74 100644 (file)
   NGVCard
   
   Represents a vCard object.
+
+  XML DTD in Dawson-03 Draft:
+    <!ELEMENT vCard      (%prop.man;, (%prop.opt;)*)>
+    
+    <!ATTLIST vCard
+            %attr.lang;
+            xmlns     CDATA #FIXED 
+        'http://www.ietf.org/internet-drafts/draft-dawson-vcard-xml-dtd-02.txt'
+            xmlns:vcf CDATA #FIXED 
+        'http://www.ietf.org/internet-drafts/draft-dawson-vcard-xml-dtd-02.txt'
+            version   CDATA #REQUIRED
+            rev       CDATA #IMPLIED
+            uid       CDATA #IMPLIED
+            prodid    CDATA #IMPLIED
+            class (PUBLIC | PRIVATE | CONFIDENTIAL) "PUBLIC"
+            value NOTATION (VCARD) #IMPLIED>
+    <!-- version - Must be "3.0" if document conforms to this spec -->
+    <!-- rev - ISO 8601 formatted date or date/time string -->
+    <!-- uid - UID associated with the object described by the vCard -->
+    <!-- prodid - ISO 9070 FPI for product that generated vCard -->
+    <!-- class - Security classification for vCard information -->
+  
+  Mandatory elements:
+    n
+    fn
 */
 
+@class NSString, NSArray, NSDictionary;
+
 @interface NGVCard : NSObject
 {
+  NSString     *uid;
+  NSString     *version;
+  NSString     *vClass;
+  NSString     *prodID;
+  // TODO: 'rev' (datetime)
+  
+  NSArray      *tel;
+  NSArray      *adr;
+  NSArray      *email;
+  NSArray      *label;
+  NSDictionary *x;
 }
 
++ (NSArray *)parseVCardsFromSource:(id)_src;
+
+- (id)initWithUid:(NSString *)_uid version:(NSString *)_version;
+
+/* accessors */
+
+- (NSString *)version;
+
+- (void)setUid:(NSString *)_uid;
+- (NSString *)uid;
+
+- (void)setVClass:(NSString *)_s;
+- (NSString *)vClass;
+- (void)setProdID:(NSString *)_s;
+- (NSString *)prodID;
+
+- (void)setTel:(NSArray *)_tel;
+- (NSArray *)tel;
+- (void)setAdr:(NSArray *)_adr;
+- (NSArray *)adr;
+- (void)setEmail:(NSArray *)_array;
+- (NSArray *)email;
+- (void)setLabel:(NSArray *)_array;
+- (NSArray *)label;
+
+- (void)setX:(NSDictionary *)_dict;
+- (NSDictionary *)x;
+
 @end
 
 #endif /* __NGiCal_NGVCard_H__ */
index 268d5c90e0d8767c58b421126e698d40302dcf45..f1de3bcfa24f92a2750259d2d0471ebefda7260c 100644 (file)
 */
 
 #include "NGVCard.h"
+#include "NGVCardSaxHandler.h"
+#include <SaxObjC/SaxXMLReader.h>
+#include <SaxObjC/SaxXMLReaderFactory.h>
 #include "common.h"
 
 @implementation NGVCard
 
+static id<NSObject,SaxXMLReader> parser = nil; // THREAD
+static NGVCardSaxHandler         *sax   = nil; // THREAD
+
++ (id<NSObject,SaxXMLReader>)vCardParser {
+  if (sax == nil)
+    sax = [[NGVCardSaxHandler alloc] init];
+  
+  if (parser == nil) {
+    parser =
+      [[[SaxXMLReaderFactory standardXMLReaderFactory] 
+                            createXMLReaderForMimeType:@"text/x-vcard"]
+                             retain];
+    if (parser == nil) {
+      NSLog(@"%s: did not find a parser for text/x-vcard !",
+           __PRETTY_FUNCTION__);
+      return nil;
+    }
+    
+    [parser setContentHandler:sax];
+    [parser setErrorHandler:sax];
+  }
+  
+  return parser;
+}
+
++ (NSArray *)parseVCardsFromSource:(id)_src {
+  static id<NSObject,SaxXMLReader> parser;
+  
+  if ((parser = [self vCardParser]) == nil)
+    return nil;
+  
+  [parser parseFromSource:_src];
+  return [sax vCards];
+}
+
+- (id)initWithUid:(NSString *)_uid version:(NSString *)_version {
+  if ((self = [super init]) != nil) {
+    self->uid     = [_uid     copy];
+    self->version = [_version copy];
+  }
+  return self;
+}
+- (id)init {
+  return [self initWithUid:nil version:@"3.0"];
+}
+
 - (void)dealloc {
+  [self->vClass  release];
+  [self->prodID  release];
+  [self->x       release];
+  [self->tel     release];
+  [self->adr     release];
+  [self->email   release];
+  [self->label   release];
+  [self->version release];
+  [self->uid     release];
   [super dealloc];
 }
 
+/* accessors */
+
+- (NSString *)version {
+  return self->version;
+}
+
+- (void)setUid:(NSString *)_uid {
+  ASSIGNCOPY(self->uid, _uid);
+}
+- (NSString *)uid {
+  return self->uid;
+}
+
+- (void)setVClass:(NSString *)_vClass {
+  ASSIGNCOPY(self->vClass, _vClass);
+}
+- (NSString *)vClass {
+  return self->vClass;
+}
+
+- (void)setProdID:(NSString *)_prodID {
+  ASSIGNCOPY(self->prodID, _prodID);
+}
+- (NSString *)prodID {
+  return self->prodID;
+}
+
+- (void)setTel:(NSArray *)_tel {
+  ASSIGNCOPY(self->tel, _tel);
+}
+- (NSArray *)tel {
+  return self->tel;
+}
+
+- (void)setAdr:(NSArray *)_adr {
+  ASSIGNCOPY(self->adr, _adr);
+}
+- (NSArray *)adr {
+  return self->adr;
+}
+
+- (void)setEmail:(NSArray *)_email {
+  ASSIGNCOPY(self->email, _email);
+}
+- (NSArray *)email {
+  return self->email;
+}
+
+- (void)setLabel:(NSArray *)_label {
+  ASSIGNCOPY(self->label, _label);
+}
+- (NSArray *)label {
+  return self->label;
+}
+
+- (void)setX:(NSDictionary *)_dict {
+  ASSIGNCOPY(self->x, _dict);
+}
+- (NSDictionary *)x {
+  return self->x;
+}
+
+/* description */
+
+- (void)appendAttributesToDescription:(NSMutableString *)_ms {
+  if (self->uid   != nil) [_ms appendFormat:@" uid='%@'", self->uid];
+  
+  if ([self->tel   count] > 0) [_ms appendFormat:@" tel=%@",   self->tel];
+  if ([self->adr   count] > 0) [_ms appendFormat:@" adr=%@",   self->adr];
+  if ([self->email count] > 0) [_ms appendFormat:@" email=%@", self->email];
+  if ([self->label count] > 0) [_ms appendFormat:@" label=%@", self->label];
+  if ([self->x     count] > 0) [_ms appendFormat:@" x=%@",     self->x];
+}
+
+- (NSString *)description {
+  NSMutableString *str = nil;
+  
+  str = [NSMutableString stringWithCapacity:64];
+  [str appendFormat:@"<0x%08X[%@]:", self, NSStringFromClass([self class])];
+  [self appendAttributesToDescription:str];
+  [str appendString:@">"];
+  return str;
+}
+
 @end /* NGVCard */
index 6953a9957e3f81287656fd6f18f358359836eaba..44f04f47c19f7cd895526c7beda5a8357289f85c 100644 (file)
@@ -43,6 +43,9 @@
   NSString *country;
 }
 
+- (id)initWithPropertyList:(id)_plist group:(NSString *)_group 
+  types:(NSArray *)_types arguments:(NSDictionary *)_args;
+
 /* accessors */
 
 - (NSString *)pobox;
index 227c07d3e619cd4a577a128c25886c3f61cba712..3cfc7b22b1fbde8c63c54da4efebc9c0140fb946 100644 (file)
 
 @implementation NGVCardAddress
 
+- (id)initWithDictionary:(NSDictionary *)_plist group:(NSString *)_group 
+  types:(NSArray *)_types arguments:(NSDictionary *)_a
+{
+  if ((self = [super initWithGroup:_group types:_types arguments:_a]) != nil) {
+    self->pobox    = [[_plist objectForKey:@"pobox"]    copy];
+    self->extadd   = [[_plist objectForKey:@"extadd"]   copy];
+    self->street   = [[_plist objectForKey:@"street"]   copy];
+    self->locality = [[_plist objectForKey:@"locality"] copy];
+    self->region   = [[_plist objectForKey:@"region"]   copy];
+    self->pcode    = [[_plist objectForKey:@"pcode"]    copy];
+    self->country  = [[_plist objectForKey:@"country"]  copy];
+  }
+  return self;
+}
+- (id)initWithPropertyList:(id)_plist group:(NSString *)_group 
+  types:(NSArray *)_types arguments:(NSDictionary *)_a
+{
+  return [self initWithDictionary:_plist
+              group:_group types:_types arguments:_a];
+}
+
+- (id)initWithGroup:(NSString *)_group types:(NSArray *)_types
+  arguments:(NSDictionary *)_a
+{
+  return [self initWithPropertyList:nil 
+              group:_group types:_types arguments:_a];
+}
+- (id)init {
+  return [self initWithPropertyList:nil group:nil types:nil arguments:nil];
+}
+
 - (void)dealloc {
   [self->pobox    release];
   [self->extadd   release];
   return self;
 }
 
+/* description */
+
+- (void)appendAttributesToDescription:(NSMutableString *)_ms {
+  [super appendAttributesToDescription:_ms];
+  [_ms appendFormat:@" vcard=%@", [self vCardString]];
+}
+
 @end /* NGVCardAddress */
diff --git a/sope-ical/NGiCal/NGVCardCategories.h b/sope-ical/NGiCal/NGVCardCategories.h
new file mode 100644 (file)
index 0000000..05935df
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+  Copyright (C) 2005 Helge Hess
+
+  This file is part of SOPE.
+
+  SOPE is free software; you can redistribute it and/or modify it under
+  the terms of the GNU Lesser General Public License as published by the
+  Free Software Foundation; either version 2, or (at your option) any
+  later version.
+
+  SOPE is distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with SOPE; see the file COPYING.  If not, write to the
+  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+  02111-1307, USA.
+*/
+
+#ifndef __NGiCal_NGVCardCategories_H__
+#define __NGiCal_NGVCardCategories_H__
+
+#include <NGiCal/NGVCardValue.h>
+
+/*
+  NGVCardCategories
+
+  Note: vCard apparently cannot represent categories which contain commas.
+        At least Kontact and Evolution do not (no escaping of commas).
+*/
+
+@class NSArray;
+
+@interface NGVCardCategories : NGVCardValue
+{
+  NSArray *categories;
+}
+
+/* accessors */
+
+- (NSArray *)categories;
+
+/* values */
+
+- (NSArray *)asArray;
+
+/* fake being an array */
+
+- (id)objectAtIndex:(unsigned)_idx;
+- (unsigned)count;
+
+@end
+
+#endif /* __NGiCal_NGVCardCategories_H__ */
index c87710eb6e51a58ee931be3c35525357abc7187e..6e50b6929c80679fc1116962975e020496b911a7 100644 (file)
@@ -19,7 +19,7 @@
   02111-1307, USA.
 */
 
-#include "NGVCardValue.h"
+#include "NGVCardCategories.h"
 #include "common.h"
 
 @implementation NGVCardCategories
   return [self categories];
 }
 
+- (NSArray *)asArray {
+  return self->categories;
+}
+
 /* fake being an array */
 
 - (id)objectAtIndex:(unsigned)_idx {
   return self;
 }
 
+/* description */
+
+- (void)appendAttributesToDescription:(NSMutableString *)_ms {
+  [super appendAttributesToDescription:_ms];
+  [_ms appendFormat:@" vcard=%@", [self vCardString]];
+}
+
 @end /* NGVCardCategories */
index b40d590d5f641bf3163ad47d67f48a3faacf5c28..897e2ac379c177cb5274337924b6cf4a16e31ec8 100644 (file)
 
 @implementation NGVCardName
 
+- (id)initWithPropertyList:(id)_plist group:(NSString *)_group 
+  types:(NSArray *)_types arguments:(NSDictionary *)_a
+{
+  if ((self = [super initWithGroup:_group types:_types arguments:_a]) != nil) {
+    self->family = [[_plist objectForKey:@"family"] copy];
+    self->given  = [[_plist objectForKey:@"given"]  copy];
+    self->other  = [[_plist objectForKey:@"other"]  copy];
+    self->prefix = [[_plist objectForKey:@"prefix"] copy];
+    self->suffix = [[_plist objectForKey:@"suffix"] copy];
+  }
+  return self;
+}
+
+- (id)initWithGroup:(NSString *)_group types:(NSArray *)_types
+  arguments:(NSDictionary *)_a
+{
+  return [self initWithPropertyList:nil 
+              group:_group types:_types arguments:_a];
+}
+- (id)init {
+  return [self initWithPropertyList:nil group:nil types:nil arguments:nil];
+}
+
 - (void)dealloc {
   [self->family release];
   [self->given  release];
   return self;
 }
 
+/* description */
+
+- (void)appendAttributesToDescription:(NSMutableString *)_ms {
+  [super appendAttributesToDescription:_ms];
+  [_ms appendFormat:@" vcard=%@", [self vCardString]];
+}
+
 @end /* NGVCardName */
diff --git a/sope-ical/NGiCal/NGVCardOrg.h b/sope-ical/NGiCal/NGVCardOrg.h
new file mode 100644 (file)
index 0000000..b21ab0e
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+  Copyright (C) 2005 Helge Hess
+
+  This file is part of SOPE.
+
+  SOPE is free software; you can redistribute it and/or modify it under
+  the terms of the GNU Lesser General Public License as published by the
+  Free Software Foundation; either version 2, or (at your option) any
+  later version.
+
+  SOPE is distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with SOPE; see the file COPYING.  If not, write to the
+  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+  02111-1307, USA.
+*/
+
+#ifndef __NGiCal_NGVCardOrg_H__
+#define __NGiCal_NGVCardOrg_H__
+
+#include <NGiCal/NGVCardValue.h>
+
+@class NSDictionary;
+
+/*
+  NGVCardOrg
+  
+  Represents an organization as transported in the 'ORG' vCard tag.
+*/
+
+@class NSString, NSArray;
+
+@interface NGVCardOrg : NGVCardValue
+{
+  NSString *orgnam; // incorrect in dawson draft? (example mismatch)
+  NSArray  *orgunits;
+}
+
+/* accessors */
+
+- (NSString *)orgnam;
+- (NSArray *)orgunits;
+
+/* values */
+
+- (NSDictionary *)asDictionary;
+- (NSArray *)asArray;
+
+/* fake being an array */
+
+- (id)objectAtIndex:(unsigned)_idx;
+- (unsigned)count;
+
+@end
+
+#endif /* __NGiCal_NGVCardOrg_H__ */
diff --git a/sope-ical/NGiCal/NGVCardOrg.m b/sope-ical/NGiCal/NGVCardOrg.m
new file mode 100644 (file)
index 0000000..e76e56b
--- /dev/null
@@ -0,0 +1,138 @@
+/*
+  Copyright (C) 2005 Helge Hess
+
+  This file is part of SOPE.
+
+  SOPE is free software; you can redistribute it and/or modify it under
+  the terms of the GNU Lesser General Public License as published by the
+  Free Software Foundation; either version 2, or (at your option) any
+  later version.
+
+  SOPE is distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with SOPE; see the file COPYING.  If not, write to the
+  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+  02111-1307, USA.
+*/
+
+#include "NGVCardOrg.h"
+#include "common.h"
+
+@implementation NGVCardOrg
+
+- (void)dealloc {
+  [self->orgnam   release];
+  [self->orgunits release];
+  [super dealloc];
+}
+
+/* accessors */
+
+- (NSString *)orgnam {
+  return self->orgnam;
+}
+- (NSArray *)orgunits {
+  return self->orgunits;
+}
+
+/* fake being an array */
+
+- (id)objectAtIndex:(unsigned)_idx {
+  NSString *s;
+
+  if (_idx == 0)
+    return (s = [self orgnam]) ? s : (NSString *)[NSNull null];
+  
+  return [self->orgunits objectAtIndex:(_idx - 1)];
+}
+- (unsigned)count {
+  return 1 + [self->orgunits count];
+}
+
+/* values */
+
+- (NSString *)stringValue {
+  return [self vCardString];
+}
+
+- (NSString *)xmlString {
+  NSMutableString *ms;
+  NSString *s;
+  unsigned i;
+  
+  ms = [[NSMutableString alloc] initWithCapacity:256];
+  [self appendXMLTag:@"orgnam" value:[self orgnam] to:ms];
+  
+  for (i = 0; i < [self->orgunits count]; i++) {
+    [self appendXMLTag:@"orgunit" value:[self->orgunits objectAtIndex:i]
+         to:ms];
+  }
+  s = [[ms copy] autorelease];
+  [ms release];
+  return s;
+}
+
+- (NSString *)vCardString {
+  NSMutableString *ms;
+  NSString *s;
+  unsigned i;
+  
+  ms = [[NSMutableString alloc] initWithCapacity:64];
+  [self appendVCardValue:[self orgnam] to:ms];
+  for (i = 0; i < [self->orgunits count]; i++) {
+    [ms appendString:@";"];
+    [self appendVCardValue:[self->orgunits objectAtIndex:i] to:ms];
+  }
+  s = [[ms copy] autorelease];
+  [ms release];
+  return s;
+}
+
+- (NSDictionary *)asDictionary {
+  static NSString *keys[2] = { @"orgnam", @"orgunits" };
+  id values[2];
+  
+  values[0] = [self orgnam];
+  values[1] = [self orgunits];
+  
+  return [NSDictionary dictionaryWithObjects:values forKeys:keys 
+                      count:[self count]];
+}
+
+- (NSArray *)asArray {
+  id values[[self count] + 1];
+  unsigned i;
+
+  for (i = 0; i < [self count]; i++)
+    values[i] = [self objectAtIndex:i];
+  
+  return [NSArray arrayWithObjects:values count:[self count]];
+}
+
+/* NSCoding */
+
+- (void)encodeWithCoder:(NSCoder *)_coder {
+  [super encodeWithCoder:_coder];
+  
+  [_coder encodeObject:self->orgnam];
+  [_coder encodeObject:self->orgunits];
+}
+- (id)initWithCoder:(NSCoder *)_coder {
+  if ((self = [super initWithCoder:_coder]) != nil) {
+    self->orgnam   = [[_coder decodeObject] copy];
+    self->orgunits = [[_coder decodeObject] copy];
+  }
+  return self;
+}
+
+/* description */
+
+- (void)appendAttributesToDescription:(NSMutableString *)_ms {
+  [super appendAttributesToDescription:_ms];
+}
+
+@end /* NGVCardOrg */
diff --git a/sope-ical/NGiCal/NGVCardPhone.h b/sope-ical/NGiCal/NGVCardPhone.h
new file mode 100644 (file)
index 0000000..922cc45
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+  Copyright (C) 2005 Helge Hess
+
+  This file is part of SOPE.
+
+  SOPE is free software; you can redistribute it and/or modify it under
+  the terms of the GNU Lesser General Public License as published by the
+  Free Software Foundation; either version 2, or (at your option) any
+  later version.
+
+  SOPE is distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with SOPE; see the file COPYING.  If not, write to the
+  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+  02111-1307, USA.
+*/
+
+#ifndef __NGiCal_NGVCardPhone_H__
+#define __NGiCal_NGVCardPhone_H__
+
+#include <NGiCal/NGVCardSimpleValue.h>
+
+/*
+  NGVCardPhone
+
+  Represents a phone value as transmitted by the 'tel' tag in vCard.
+*/
+
+@interface NGVCardPhone : NGVCardSimpleValue
+@end
+
+#endif /* __NGiCal_NGVCardPhone_H__ */
index 2342feb24c445a1e1a167fd95caedfe5291baa52..1707609ac07d37c9bd09429fbc215037f826ca7e 100644 (file)
@@ -19,7 +19,7 @@
   02111-1307, USA.
 */
 
-#include "NGVCardValue.h"
+#include "NGVCardPhone.h"
 #include "common.h"
 
 @implementation NGVCardPhone
index 98fe3da21920c8aa75022bb0b95a4a7e3073702b..bbfa2c871cde24833d87062a06506e59949e21be 100644 (file)
 */
 
 @class NSString, NSMutableString, NSMutableArray;
+@class NSDictionary, NSMutableDictionary;
+@class NGVCard;
 
 @interface NGVCardSaxHandler : SaxDefaultHandler
 {
   NSMutableArray *vCards;
   
-  id       vCard;
+  NGVCard  *vCard;
   NSString *currentGroup;
   unichar  *content;
   unsigned contentLength;
+
+  NSMutableDictionary *xtags;
+  NSMutableDictionary *subvalues;
+  NSMutableArray      *types;
+  NSMutableDictionary *args;
+  NSMutableArray      *tel;
+  NSMutableArray      *adr;
+  NSMutableArray      *email;
+  NSMutableArray      *label;
+  NSMutableArray      *url;
   
   struct {
     int isInVCardSet:1;
     int isInVCard:1;
     int isInN:1;
+    int isInAdr:1;
+    int isInOrg:1;
     int isInGroup:1;
     int collectContent:1;
-    int reserved:27;
+    int reserved:25;
   } vcs;
 }
 
+/* results */
+
+- (NSArray *)vCards;
+
 /* content */
 
 - (void)startCollectingContent;
index 71ccd1cf5dfb3bc9f0f519e9295d6d9f681282fb..1c0dd60dc4814cffa1322de66dbe88421928c9fe 100644 (file)
 */
 
 #include "NGVCardSaxHandler.h"
+#include "NGVCard.h"
+#include "NGVCardValue.h"
+#include "NGVCardSimpleValue.h"
+#include "NGVCardAddress.h"
+#include "NGVCardPhone.h"
+#include "NGVCardName.h"
+#include "NGVCardOrg.h"
+#include "NGVCardCategories.h"
 #include "common.h"
 
+#ifndef XMLNS_VCARD_XML_03
+#  define XMLNS_VCARD_XML_03 \
+     @"http://www.ietf.org/internet-drafts/draft-dawson-vcard-xml-dtd-03.txt"
+#endif
+
 @implementation NGVCardSaxHandler
 
 - (void)dealloc {
   if (self->content != NULL) free(self->content);
+  [self->subvalues    release];
+  [self->xtags        release];
+  [self->tel          release];
+  [self->adr          release];
+  [self->email        release];
+  [self->label        release];
+  [self->types        release];
+  [self->args         release];
   [self->vCards       release];
   [self->vCard        release];
   [self->currentGroup release];
   [super dealloc];
 }
 
+/* results */
+
+- (NSArray *)vCards {
+  return self->vCards;
+}
+
 /* state */
 
 - (void)resetExceptResult {
   [self->currentGroup release]; self->currentGroup = nil;
   [self->vCard        release]; self->vCard        = nil;
 
+  [self->tel    removeAllObjects];
+  [self->adr    removeAllObjects];
+  [self->email  removeAllObjects];
+  [self->label  removeAllObjects];
+  [self->types  removeAllObjects];
+  [self->args   removeAllObjects];
+  
   if (self->content != NULL) {
     free(self->content);
     self->content = NULL;
@@ -46,6 +80,8 @@
   self->vcs.isInVCardSet   = 0;
   self->vcs.isInVCard      = 0;
   self->vcs.isInN          = 0;
+  self->vcs.isInAdr        = 0;
+  self->vcs.isInOrg        = 0;
   self->vcs.isInGroup      = 0;
   self->vcs.collectContent = 0;
 }
 
 - (void)startDocument {
   [self reset];
+  
   if (self->vCards == nil)
     self->vCards = [[NSMutableArray alloc] initWithCapacity:16];
+
+  if (self->tel == nil)
+    self->tel = [[NSMutableArray alloc] initWithCapacity:8];
+  if (self->adr == nil)
+    self->adr = [[NSMutableArray alloc] initWithCapacity:8];
+  if (self->email == nil)
+    self->email = [[NSMutableArray alloc] initWithCapacity:8];
+  if (self->label == nil)
+    self->label = [[NSMutableArray alloc] initWithCapacity:8];
+
+  if (self->types == nil)
+    self->types = [[NSMutableArray alloc] initWithCapacity:4];
+  if (self->args == nil)
+    self->args = [[NSMutableDictionary alloc] initWithCapacity:8];
+  
+  if (self->subvalues == nil)
+    self->subvalues = [[NSMutableDictionary alloc] initWithCapacity:16];
+  if (self->xtags == nil)
+    self->xtags = [[NSMutableDictionary alloc] initWithCapacity:32];
 }
 - (void)endDocument {
   [self resetExceptResult];
 }
 
+/* common tags */
+
+- (void)startValueTag:(NSString *)_tag attributes:(id<SaxAttributes>)_attrs {
+  unsigned i, count;
+  
+  [self->types removeAllObjects];
+  [self->args  removeAllObjects];
+  
+  for (i = 0, count = [_attrs count]; i < count; i++) {
+    NSString *n, *v;
+    
+    n = [_attrs nameAtIndex:i];
+    v = [_attrs valueAtIndex:i];
+    
+    if ([n hasSuffix:@".type"] || [n isEqualToString:@"TYPE"]) {
+      if (![self->types containsObject:v]) 
+       [self->types addObjectsFromArray:[v componentsSeparatedByString:@" "]];
+    }
+    else
+      [self->args setObject:v forKey:n];
+  }
+}
+- (void)endValueTag {
+  [self->types removeAllObjects];
+  [self->args  removeAllObjects];
+}
+
 /* handle elements */
 
 - (void)startGroup:(NSString *)_name {
 }
 
 - (void)startN {
+  [self->subvalues removeAllObjects];
   self->vcs.isInN = 1;
 }
 - (void)endN {
+  NGVCardName *n;
+  
   self->vcs.isInN = 0;
+
+  n = [[NGVCardName alloc] initWithPropertyList:self->subvalues
+                          group:self->currentGroup
+                          types:self->types arguments:self->args];
+  NSLog(@"N: %@", n);
+  
+  [self->subvalues removeAllObjects];
+  [n release];
+}
+
+- (void)startOrg {
+  [self->subvalues removeAllObjects];
+  self->vcs.isInOrg = 1;
+}
+- (void)endOrg {
+  NGVCardOrg *o;
+
+  self->vcs.isInOrg = 0;
+
+  o = [[NGVCardOrg alloc] initWithGroup:self->currentGroup
+                         types:self->types arguments:self->args];
+  
+  NSLog(@"O: %@: %@", o, self->subvalues);
+  
+  [self->subvalues removeAllObjects];
 }
 
 - (void)startVCard:(id<SaxAttributes>)_attrs {
+  NSString *uid, *version;
+  NSString *t;
+  
+  [self->tel   removeAllObjects];
+  [self->adr   removeAllObjects];
+  [self->email removeAllObjects];
+  [self->label removeAllObjects];
+  [self->xtags removeAllObjects];
+  
   self->vcs.isInVCard = 1;
+  if (self->vCard != nil) {
+    [self->vCards addObject:self->vCard];
+    [self logWithFormat:@"ERROR: vCard nesting not supported!"];
+    [self->vCard release]; self->vCard = nil;
+  }
+  
+  if ((uid = [_attrs valueForName:@"uid" uri:XMLNS_VCARD_XML_03]) == nil)
+    uid = [_attrs valueForName:@"X-ABUID" uri:XMLNS_VCARD_XML_03];
+  
+  version = [_attrs valueForName:@"version" uri:XMLNS_VCARD_XML_03];
+  
+  self->vCard = [[NGVCard alloc] initWithUid:uid version:version];
+
+  if ((t = [_attrs valueForName:@"class" uri:XMLNS_VCARD_XML_03]) != nil)
+    [self->vCard setVClass:t];
+  if ((t = [_attrs valueForName:@"rev" uri:XMLNS_VCARD_XML_03]) != nil) {
+    [self logWithFormat:@"WARNING: vCard revision not yet supported!"];
+    // TODO
+  }
+  if ((t = [_attrs valueForName:@"prodid" uri:XMLNS_VCARD_XML_03]) != nil)
+    [self->vCard setProdID:t];
+  
+  [self debugWithFormat:@"started vCard: %@", self->vCard];
 }
 - (void)endVCard {
   self->vcs.isInVCard = 0;
+
+  /* fill collected objects */
+  
+  if ([self->tel   count] > 0) [self->vCard setTel:self->tel];
+  if ([self->adr   count] > 0) [self->vCard setAdr:self->adr];
+  if ([self->email count] > 0) [self->vCard setEmail:self->email];
+  if ([self->label count] > 0) [self->vCard setLabel:self->label];
+  if ([self->xtags count] > 0) [self->vCard setX:self->xtags];
+  [self->tel   removeAllObjects];
+  [self->adr   removeAllObjects];
+  [self->email removeAllObjects];
+  [self->label removeAllObjects];
+  [self->xtags removeAllObjects];
+
+  /* finish vCard, add to results */
+  
+  [self debugWithFormat:@"finished vCard: %@", self->vCard];
+  [self->vCards addObject:self->vCard];
+  [self->vCard release]; self->vCard = nil;
 }
 
 - (void)startVCardSet:(id<SaxAttributes>)_attrs {
   self->vcs.isInVCardSet = 0;
 }
 
+- (void)endBaseContentTagWithClass:(Class)_clazz andAddTo:(NSMutableArray*)_a {
+  NGVCardSimpleValue *v;
+
+  v = [[_clazz alloc] initWithValue:[self finishCollectingContent]
+                     group:self->currentGroup
+                     types:self->types arguments:self->args];
+  [_a addObject:v];
+  
+  [self endValueTag];
+  [v release];
+}
+
+- (void)startTel:(id<SaxAttributes>)_attrs {
+  [self startValueTag:@"tel" attributes:_attrs];
+  [self startCollectingContent];
+}
+- (void)endTel {
+  [self endBaseContentTagWithClass:[NGVCardPhone class] andAddTo:self->tel];
+}
+
+- (void)startAdr:(id<SaxAttributes>)_attrs {
+  [self->subvalues removeAllObjects];
+
+  self->vcs.isInAdr = 1;
+  [self startValueTag:@"adr" attributes:_attrs];
+}
+- (void)endAdr {
+  NGVCardAddress *address;
+
+  self->vcs.isInAdr = 0;
+  
+  address = [[NGVCardAddress alloc] initWithPropertyList:self->subvalues
+                                   group:self->currentGroup
+                                   types:self->types arguments:self->args];
+  NSLog(@"A: %@", address);
+  [self->adr addObject:address];
+  
+  [self->subvalues removeAllObjects];
+  [self endValueTag];
+  [address release];
+}
+
+- (void)startEmail:(id<SaxAttributes>)_attrs {
+  [self startValueTag:@"email" attributes:_attrs];
+  [self startCollectingContent];
+}
+- (void)endEmail {
+  [self endBaseContentTagWithClass:[NGVCardSimpleValue class]
+       andAddTo:self->email];
+}
+
+- (void)startLabel:(id<SaxAttributes>)_attrs {
+  [self startValueTag:@"LABEL" attributes:_attrs];
+  [self startCollectingContent];
+}
+- (void)endLabel {
+  [self endBaseContentTagWithClass:[NGVCardSimpleValue class]
+       andAddTo:self->label];
+}
+
+- (void)startURL:(id<SaxAttributes>)_attrs {
+  [self startValueTag:@"url" attributes:_attrs];
+  [self startCollectingContent];
+}
+- (void)endURL {
+  // TODO: use special URL class?
+  [self endBaseContentTagWithClass:[NGVCardSimpleValue class]
+       andAddTo:self->url];
+}
+
+- (void)startSubContentTag:(id<SaxAttributes>)_attrs {
+  if ([_attrs count] > 0)
+    [self logWithFormat:@"WARNING: loosing attrs of subtag: %@", _attrs];
+  
+  [self startCollectingContent];
+}
+- (void)endSubContentTag:(NSString *)_key {
+  NSString *s;
+  id o;
+  
+  if ((s = [[self finishCollectingContent] copy]) == nil)
+    return;
+  
+  if ((o = [self->subvalues objectForKey:_key]) == nil) {
+    [self->subvalues setObject:s forKey:_key];
+  }
+  else {
+    /* multivalue (eg 'org') */
+    if ([o isKindOfClass:[NSMutableArray class]]) {
+      [o addObject:s];
+    }
+    else {
+      NSMutableArray *a;
+      
+      a = [[NSMutableArray alloc] initWithCapacity:4];
+      [a addObject:o];
+      [a addObject:s];
+      [self->subvalues setObject:a forKey:_key];
+      [a release]; a = nil;
+    }
+  }
+  [s release];
+}
+
+
+- (void)startX:(NSString *)_name attributes:(id<SaxAttributes>)_attrs {
+  [self startValueTag:_name attributes:_attrs];
+  [self startCollectingContent];
+}
+- (void)endX:(NSString *)_name {
+  NGVCardSimpleValue *v;
+  NSString *s;
+  id o;
+  
+  s = [self finishCollectingContent];
+  v = [[NGVCardSimpleValue alloc] initWithValue:s
+                                 group:self->currentGroup
+                                 types:self->types arguments:self->args];
+  
+  if ((o = [self->xtags objectForKey:_name]) == nil)
+    [self->xtags setObject:v forKey:_name];
+  else if ([o isKindOfClass:[NSMutableArray class]])
+    [o addObject:v];
+  else {
+    NSMutableArray *a;
+    
+    a = [[NSMutableArray alloc] initWithCapacity:4];
+    [a addObject:o];
+    [a addObject:v];
+    [self->xtags setObject:a forKey:_name];
+    [a release];
+  }
+  
+  [v release];
+  [self endValueTag];
+}
+
+
 /* element events */
 
 - (void)startElement:(NSString *)_localName
   rawName:(NSString *)_rawName
   attributes:(id<SaxAttributes>)_attrs
 {
-  if ([_localName isEqualToString:@"group"])
+  unichar c0 = [_localName characterAtIndex:0];
+
+  if (c0 == 'g' && [_localName isEqualToString:@"group"])
     [self startGroup:[_attrs valueForName:@"name" uri:_ns]];
-  else if ([_localName isEqualToString:@"n"])
+  else if (c0 == 'n' && [_localName length] == 1)
     [self startN];
-  else if ([_localName isEqualToString:@"tel"])
-    ;
-  else if ([_localName isEqualToString:@"vCard"])
+  else if (c0 == 'o' && [_localName isEqualToString:@"org"])
+    [self startOrg];
+  else if (c0 == 't' && [_localName isEqualToString:@"tel"])
+    [self startTel:_attrs];
+  else if (c0 == 'u' && [_localName isEqualToString:@"url"])
+    [self startURL:_attrs];
+  else if (c0 == 'a' && [_localName isEqualToString:@"adr"])
+    [self startAdr:_attrs];
+  else if (c0 == 'e' && [_localName isEqualToString:@"email"])
+    [self startEmail:_attrs];
+  else if (c0 == 'L' && [_localName isEqualToString:@"LABEL"])
+    [self startLabel:_attrs];
+  else if (c0 == 'v' && [_localName isEqualToString:@"vCard"])
     [self startVCard:_attrs];
-  else if ([_localName isEqualToString:@"vCardSet"])
+  else if (c0 == 'v' && [_localName isEqualToString:@"vCardSet"])
     [self startVCardSet:_attrs];
-  
-  if (self->vcs.isInN) {
+  else {
+    if (self->vcs.isInN || self->vcs.isInOrg || self->vcs.isInAdr)
+      [self startSubContentTag:_attrs];
+    else if (c0 == 'X')
+      [self startX:_localName attributes:_attrs];
+    else
+      NSLog(@"U: %@", _localName);
   }
 }
 
   namespace:(NSString *)_ns
   rawName:(NSString *)_rawName
 {
-  if (self->vcs.isInN) {
-  }
-  
-  if ([_localName isEqualToString:@"group"])
+  unichar c0 = [_localName characterAtIndex:0];
+
+  if (c0 == 'g' && [_localName isEqualToString:@"group"])
     [self endGroup];
-  else if ([_localName isEqualToString:@"n"])
+  else if (c0 == 'n' && [_localName isEqualToString:@"n"])
     [self endN];
-  else if ([_localName isEqualToString:@"tel"])
-    ;
-  else if ([_localName isEqualToString:@"vCard"])
+  else if (c0 == 'o' && [_localName isEqualToString:@"org"])
+    [self endOrg];
+  else if (c0 == 't' && [_localName isEqualToString:@"tel"])
+    [self endTel];
+  else if (c0 == 'u' && [_localName isEqualToString:@"url"])
+    [self endURL];
+  else if (c0 == 'a' && [_localName isEqualToString:@"adr"])
+    [self endAdr];
+  else if (c0 == 'e' && [_localName isEqualToString:@"email"])
+    [self endEmail];
+  else if (c0 == 'L' && [_localName isEqualToString:@"LABEL"])
+    [self endLabel];
+  else if (c0 == 'v' && [_localName isEqualToString:@"vCard"])
     [self endVCard];
-  else if ([_localName isEqualToString:@"vCardSet"])
+  else if (c0 == 'v' && [_localName isEqualToString:@"vCardSet"])
     [self endVCardSet];
+  else {
+    if (self->vcs.isInN || self->vcs.isInOrg || self->vcs.isInAdr)
+      [self endSubContentTag:_localName];
+    else if (c0 == 'X')
+      [self endX:_localName];
+  }
 }
 
 /* content */
diff --git a/sope-ical/NGiCal/NGVCardSimpleValue.h b/sope-ical/NGiCal/NGVCardSimpleValue.h
new file mode 100644 (file)
index 0000000..6465a1d
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+  Copyright (C) 2005 Helge Hess
+
+  This file is part of SOPE.
+
+  SOPE is free software; you can redistribute it and/or modify it under
+  the terms of the GNU Lesser General Public License as published by the
+  Free Software Foundation; either version 2, or (at your option) any
+  later version.
+
+  SOPE is distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with SOPE; see the file COPYING.  If not, write to the
+  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+  02111-1307, USA.
+*/
+
+#ifndef __NGiCal_NGVCardSimpleValue_H__
+#define __NGiCal_NGVCardSimpleValue_H__
+
+#include <NGiCal/NGVCardValue.h>
+
+#import <Foundation/NSString.h>
+
+/*
+  NGVCardSimpleValue
+  
+  An object to represent simple vCard string values.
+*/
+
+@interface NGVCardSimpleValue : NGVCardValue
+{
+  NSString *value;
+}
+
+- (id)initWithValue:(NSString *)_value group:(NSString *)_group 
+  types:(NSArray *)_types arguments:(NSDictionary *)_args;
+
+/* fake being an NSString */
+
+- (unsigned int)length;
+- (unichar)characterAtIndex:(unsigned)_idx;
+
+@end
+
+#endif /* __NGiCal_NGVCardSimpleValue_H__ */
index f4505ecbc1005a515534bcb6349d9a6edbccd4a4..05fcc077fbd5c99b4b5053581e7d0793a8cbde2a 100644 (file)
   02111-1307, USA.
 */
 
-#include "NGVCardValue.h"
+#include "NGVCardSimpleValue.h"
 #include "common.h"
 
 @implementation NGVCardSimpleValue
 
+- (id)initWithValue:(NSString *)_value group:(NSString *)_group 
+  types:(NSArray *)_types arguments:(NSDictionary *)_a
+{
+  if ((self = [super initWithGroup:_group types:_types arguments:_a]) != nil) {
+    self->value = [_value copy];
+  }
+  return self;
+}
+
+- (id)initWithGroup:(NSString *)_group types:(NSArray *)_types
+  arguments:(NSDictionary *)_a
+{
+  return [self initWithValue:nil group:_group types:_types arguments:_a];
+}
+- (id)init {
+  return [self initWithValue:nil group:nil types:nil arguments:nil];
+}
+
 - (void)dealloc {
   [self->value release];
   [super dealloc];
   return self;
 }
 
+/* description */
+
+- (void)appendAttributesToDescription:(NSMutableString *)_ms {
+  if (self->value != nil) [_ms appendFormat:@" value='%@'", self->value];
+  [super appendAttributesToDescription:_ms];
+}
+
 @end /* NGVCardSimpleValue */
index bd5fbed976b95cb689350e8ce7b864cd0fb58ea9..89727c10a689c69b00f5e5498124005ebcd5b788 100644 (file)
@@ -27,7 +27,7 @@
 /*
   NGVCardValue
   
-  Represents a value in a vCard object.
+  An abstract superclass to represents a value in a vCard object.
   
   Note: all NGVCardValue's are treated as immutable objects.
   
@@ -44,6 +44,9 @@
   NSDictionary *arguments;
 }
 
+- (id)initWithGroup:(NSString *)_group types:(NSArray *)_types
+  arguments:(NSDictionary *)_a;
+
 /* accessors */
 
 - (NSString *)group;
   to:(NSMutableString *)_ms;
 - (void)appendVCardValue:(NSString *)_val to:(NSMutableString *)_ms;
 
-@end
-
-#import <Foundation/NSString.h>
-
-@interface NGVCardSimpleValue : NGVCardValue
-{
-  NSString *value;
-}
-
-/* fake being an NSString */
-
-- (unsigned int)length;
-- (unichar)characterAtIndex:(unsigned)_idx;
-
-@end
-
-@interface NGVCardPhone : NGVCardSimpleValue
-@end
-
-@interface NGVCardCategories : NGVCardValue
-{
-  NSArray *categories;
-}
-
-/* accessors */
+/* description */
 
-- (NSArray *)categories;
+- (void)appendAttributesToDescription:(NSMutableString *)_ms;
 
 @end
 
index dd4457b9383a5aa5093a2003fc8c0faf89905952..b5476a8ed53fcf45dbeeb238e9bfee70dc1c219d 100644 (file)
 
 @implementation NGVCardValue
 
+- (id)initWithGroup:(NSString *)_group types:(NSArray *)_types
+  arguments:(NSDictionary *)_a
+{
+  if ((self = [super init]) != nil) {
+    self->group     = [_group copy];
+    self->types     = [_types copy];
+    self->arguments = [_a copy];
+  }
+  return self;
+}
+- (id)init {
+  return [self initWithGroup:nil types:nil arguments:nil];
+}
+
 - (void)dealloc {
   [self->group     release];
   [self->types     release];
   return self;
 }
 
+/* description */
+
+- (void)appendDictionary:(NSDictionary *)_d compactTo:(NSMutableString *)_s {
+  NSEnumerator *keys;
+  NSString *k;
+  
+  keys = [_d keyEnumerator];
+  while ((k = [keys nextObject]) != nil) {
+    NSString *v;
+    
+    v = [_d objectForKey:k];
+    [_s appendFormat:@"%@='%@';", k, v];
+  }
+}
+
+- (void)appendAttributesToDescription:(NSMutableString *)_ms {
+  if (self->group != nil) [_ms appendFormat:@" group='%@'", self->group];
+  if ([self->types count] > 0) {
+    [_ms appendFormat:@" types=%@", 
+          [self->types componentsJoinedByString:@","]];
+  }
+  if ([self->arguments count] > 0) {
+    [_ms appendString:@" args="];
+    [self appendDictionary:self->arguments compactTo:_ms];
+  }
+}
+
+- (NSString *)description {
+  NSMutableString *str = nil;
+  
+  str = [NSMutableString stringWithCapacity:64];
+  [str appendFormat:@"<0x%08X[%@]:", self, NSStringFromClass([self class])];
+  [self appendAttributesToDescription:str];
+  [str appendString:@">"];
+  return str;
+}
+
 @end /* NGVCardValue */
index 3a75896212eb14d10a670227cac0cce9605cc9d5..d2b964f05e61163c56d990ac2ab61c17533ff7c0 100644 (file)
@@ -2,7 +2,7 @@
 
 MAJOR_VERSION=4
 MINOR_VERSION=5
-SUBMINOR_VERSION:=52
+SUBMINOR_VERSION:=53
 
 # v4.5.40 requires NGExtensions v4.5.145
 # v4.5.37 requires NGExtensions v4.5.140
index e26d78bd66e2df34f3d504f1110e728bda80f92a..c3a3fbeff608fa9e4f699862eedcc11588f578f5 100644 (file)
@@ -3,15 +3,17 @@
 -include ../../config.make
 include $(GNUSTEP_MAKEFILES)/common.make
 
-TOOL_NAME = icalparsetest icalds vcf2xml
+TOOL_NAME = icalparsetest icalds vcf2xml vcfparsetest
 
 icalparsetest_OBJC_FILES = icalparsetest.m
 icalds_OBJC_FILES        = icalds.m
 vcf2xml_OBJC_FILES       = vcf2xml.m
+vcfparsetest_OBJC_FILES  = vcfparsetest.m
 
 icalparsetest_TOOL_LIBS += -lNGiCal -lSaxObjC
-icalds_TOOL_LIBS  += -lNGiCal -lSaxObjC
-vcf2xml_TOOL_LIBS += -lSaxObjC
+icalds_TOOL_LIBS        += -lNGiCal -lSaxObjC
+vcf2xml_TOOL_LIBS       += -lSaxObjC
+vcfparsetest_TOOL_LIBS  += -lNGiCal -lSaxObjC
 
 -include GNUmakefile.preamble
 include $(GNUSTEP_MAKEFILES)/tool.make
diff --git a/sope-ical/samples/vcfparsetest.m b/sope-ical/samples/vcfparsetest.m
new file mode 100644 (file)
index 0000000..26289af
--- /dev/null
@@ -0,0 +1,126 @@
+/*
+  Copyright (C) 2005 Helge Hess
+
+  This file is part of SOPE.
+
+  SOPE is free software; you can redistribute it and/or modify it under
+  the terms of the GNU Lesser General Public License as published by the
+  Free Software Foundation; either version 2, or (at your option) any
+  later version.
+
+  SOPE is distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with SOPE; see the file COPYING.  If not, write to the
+  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+  02111-1307, USA.
+*/
+
+#import <Foundation/Foundation.h>
+
+@interface vcsparsetest : NSObject
+{
+}
+
+- (int)runWithArguments:(NSArray *)_args;
+
+@end
+
+#include <NGiCal/NGVCard.h>
+
+@implementation vcsparsetest
+
+- (id)init {
+  if ((self = [super init])) {
+  }
+  return self;
+}
+- (void)dealloc {
+  [super dealloc];
+}
+
+/* parsing */
+
+- (id)parseFile:(NSString *)_path {
+  if ([_path length] == 0) return nil;
+  return [NGVCard parseVCardsFromSource:[NSURL fileURLWithPath:_path]];
+}
+
+- (void)printParsedObject:(NSArray *)_cards {
+  NSLog(@"cards: %@", _cards);
+  
+#if 0
+  NSLog(@"  subcomponents: %@", [_object subComponents]);
+  
+  printf("%s", [[_object icalString] cString]);
+#endif
+}
+
+/* run */
+
+- (int)runWithArguments:(NSArray *)_args {
+  NSEnumerator      *args;
+  NSString          *arg;
+  
+  args = [_args objectEnumerator];
+  [args nextObject]; // process name ...
+
+  while ((arg = [args nextObject])) {
+    NSAutoreleasePool *pool2;
+
+    if ([arg hasPrefix:@"-"]) { /* consume defaults */
+      [args nextObject];
+      continue;
+    }
+    
+    pool2 = [[NSAutoreleasePool alloc] init];
+    {    
+      NSArray *cards;
+      
+      NS_DURING
+       cards = [self parseFile:arg];
+      NS_HANDLER
+       abort();
+      NS_ENDHANDLER;
+      
+      if (cards == nil)
+       NSLog(@"could not parse file: '%@'", arg);
+      else
+       [self printParsedObject:cards];
+    }
+    [pool2 release];
+  }
+  return 0;
+}
+
+@end /* vcsparsetest */
+
+int main(int argc, char **argv, char **env)  {
+  NSAutoreleasePool *pool;
+  vcsparsetest *tool;
+  int rc;
+
+#if LIB_FOUNDATION_LIBRARY  
+  [NSProcessInfo initializeWithArguments:argv count:argc environment:env];
+#endif
+  
+  pool = [[NSAutoreleasePool alloc] init];
+  
+  if ((tool = [[vcsparsetest alloc] init])) {
+    NS_DURING
+      rc = [tool runWithArguments:[[NSProcessInfo processInfo] arguments]];
+    NS_HANDLER
+      abort();
+    NS_ENDHANDLER;
+    
+    [tool release];
+  }
+  else
+    rc = 1;
+  
+  [pool release];
+  return rc;
+}