]> err.no Git - sope/blob - sope-ical/samples/vcf2xml.m
added support vcard type groupings
[sope] / sope-ical / samples / vcf2xml.m
1 /*
2   Copyright (C) 2005 Helge Hess
3
4   This file is part of SOPE.
5
6   SOPE is free software; you can redistribute it and/or modify it under
7   the terms of the GNU Lesser General Public License as published by the
8   Free Software Foundation; either version 2, or (at your option) any
9   later version.
10
11   SOPE is distributed in the hope that it will be useful, but WITHOUT ANY
12   WARRANTY; without even the implied warranty of MERCHANTABILITY or
13   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
14   License for more details.
15
16   You should have received a copy of the GNU Lesser General Public
17   License along with SOPE; see the file COPYING.  If not, write to the
18   Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
19   02111-1307, USA.
20 */
21
22 // Note: this does not yet produce valid XML output
23
24 #import <Foundation/NSObject.h>
25 #include <SaxObjC/SaxObjC.h>
26
27 @interface vcf2xml : NSObject
28 {
29   id<NSObject,SaxXMLReader> parser;
30   id sax;
31 }
32
33 - (int)runWithArguments:(NSArray *)_args;
34
35 @end
36
37 #include "common.h"
38
39 @interface MySAXHandler : SaxDefaultHandler
40 {
41   id  locator;
42   int indent;
43
44   NSString *lastNS;
45 }
46
47 - (void)indent;
48
49 @end
50
51 @implementation vcf2xml
52
53 - (id)init {
54   if ((self = [super init]) != nil) {
55     self->parser = [[[SaxXMLReaderFactory standardXMLReaderFactory] 
56                       createXMLReaderForMimeType:@"text/x-vcard"] retain];
57     if (parser == nil) {
58       fprintf(stderr, "Error: could not load a vCard SAX driver bundle!\n");
59       exit(2);
60     }
61     //NSLog(@"Using parser: %@", self->parser);
62     
63     self->sax = [[MySAXHandler alloc] init];
64     [parser setContentHandler:self->sax];
65     [parser setErrorHandler:self->sax];
66   }
67   return self;
68 }
69
70 - (void)dealloc {
71   [self->sax    release];
72   [self->parser release];
73   [super dealloc];
74 }
75
76 /* process files */
77
78 - (void)processFile:(NSString *)_path {
79   [self->parser parseFromSystemId:_path];
80 }
81
82 /* error handling */
83
84 - (NSException *)handleException:(NSException *)_exc onPath:(NSString *)_p {
85   fprintf(stderr, "Error: catched exception on path '%s': %s\n",
86           [_p cString], [[_exc description] cString]);
87   return nil;
88 }
89
90 /* main entry */
91
92 - (int)runWithArguments:(NSArray *)_args {
93   NSEnumerator *args;
94   NSString     *arg;
95   
96   /* begin processing */
97   
98   args = [_args objectEnumerator];
99   [args nextObject]; // skip tool name ...
100   
101   while ((arg = [args nextObject]) != nil) {
102     NSAutoreleasePool *pool2;
103     
104     if ([arg hasPrefix:@"-"]) { /* consume defaults */
105       [args nextObject];
106       continue;
107     }
108     
109     pool2 = [[NSAutoreleasePool alloc] init];
110
111
112     if (![arg isAbsolutePath]) {
113       arg = [[[NSFileManager defaultManager] currentDirectoryPath]
114               stringByAppendingPathComponent:arg];
115     }
116     
117     NS_DURING
118       [self->parser parseFromSystemId:arg];
119     NS_HANDLER
120       [[self handleException:localException onPath:arg] raise];
121     NS_ENDHANDLER;
122     
123     [pool2 release];
124   }
125   return 0;
126 }
127
128 @end /* vcf2xml */
129
130
131 @implementation MySAXHandler
132
133 - (void)dealloc {
134   [self->lastNS  release];
135   [self->locator release];
136   [super dealloc];
137 }
138
139 /* output */
140
141 - (void)indent {
142   int i;
143   
144   for (i = 0; i < (self->indent * 4); i++)
145     fputc(' ', stdout);
146 }
147
148 /* documents */
149
150 - (void)setDocumentLocator:(id<NSObject,SaxLocator>)_loc {
151   [self->locator autorelease];
152   self->locator = [_loc retain];
153 }
154
155 - (void)startDocument {
156   //puts("start document ..");
157   //self->indent++;
158 }
159 - (void)endDocument {
160   //self->indent--;
161   //puts("end document.");
162 }
163
164 - (void)startPrefixMapping:(NSString *)_prefix uri:(NSString *)_uri {
165   [self indent];
166   //printf("ns-map: %s=%s\n", [_prefix cString], [_uri cString]);
167 }
168 - (void)endPrefixMapping:(NSString *)_prefix {
169   [self indent];
170   //printf("ns-unmap: %s\n", [_prefix cString]);
171 }
172
173 - (void)startElement:(NSString *)_localName
174   namespace:(NSString *)_ns
175   rawName:(NSString *)_rawName
176   attributes:(id<SaxAttributes>)_attrs
177 {
178   int i, c;
179   [self indent];
180   printf("<%s", [_localName cString]);
181   
182   if ([_ns length] > 0) {
183     if ([_ns isEqualToString:self->lastNS])
184       ;
185     else {
186       printf(" xmlns='%s'", [_ns cString]);
187       ASSIGNCOPY(self->lastNS, _ns);
188     }
189   }
190   
191   for (i = 0, c = [_attrs count]; i < c; i++) {
192     NSString *type;
193     NSString *ans;
194
195     ans = [_attrs uriAtIndex:i];
196     
197     printf(" %s=\"%s\"",
198            [[_attrs nameAtIndex:i] cString],
199            [[_attrs valueAtIndex:i] cString]);
200     
201     if (![_ns isEqualToString:ans])
202       printf("(ns=%s)", [ans cString]);
203     
204     type = [_attrs typeAtIndex:i];
205     if (![type isEqualToString:@"CDATA"] && (type != nil))
206       printf("[%s]", [type cString]);
207   }
208   puts(">");
209   self->indent++;
210 }
211 - (void)endElement:(NSString *)_localName
212   namespace:(NSString *)_ns
213   rawName:(NSString *)_rawName
214 {
215   self->indent--;
216   [self indent];
217   printf("</%s>\n", [_localName cString]);
218 }
219
220 - (void)characters:(unichar *)_chars length:(int)_len {
221   NSString *str;
222   id tmp;
223   unsigned i, len;
224
225   if (_len == 0) {
226     [self indent];
227     printf("\"\"\n");
228     return;
229   }
230   
231   for (i = 0; i < (unsigned)_len; i++) {
232     if (_chars[i] > 255) {
233       NSLog(@"detected large char: o%04o d%03i h%04X",
234             _chars[i], _chars[i], _chars[i]);
235     }
236   }
237   
238   str = [NSString stringWithCharacters:_chars length:_len];
239   len = [str length];
240   
241   tmp = [str componentsSeparatedByString:@"\n"];
242   str = [tmp componentsJoinedByString:@"\\n"];
243   tmp = [str componentsSeparatedByString:@"\r"];
244   str = [tmp componentsJoinedByString:@"\\r"];
245   
246   [self indent];
247   printf("\"%s\"\n", [str cString]);
248 }
249 - (void)ignorableWhitespace:(unichar *)_chars length:(int)_len {
250   NSString *data;
251   id tmp;
252
253   data = [NSString stringWithCharacters:_chars length:_len];
254   tmp  = [data componentsSeparatedByString:@"\n"];
255   data = [tmp componentsJoinedByString:@"\\n"];
256   tmp  = [data componentsSeparatedByString:@"\r"];
257   data = [tmp componentsJoinedByString:@"\\r"];
258   
259   [self indent];
260   printf("whitespace: \"%s\"\n", [data cString]);
261 }
262
263 - (void)processingInstruction:(NSString *)_pi data:(NSString *)_data {
264   [self indent];
265   printf("PI: '%s' '%s'\n", [_pi cString], [_data cString]);
266 }
267
268 #if 0
269 - (xmlEntityPtr)getEntity:(NSString *)_name {
270   NSLog(@"get entity %@", _name);
271   return NULL;
272 }
273 - (xmlEntityPtr)getParameterEntity:(NSString *)_name {
274   NSLog(@"get para entity %@", _name);
275   return NULL;
276 }
277 #endif
278
279 /* entities */
280
281 - (id)resolveEntityWithPublicId:(NSString *)_pubId
282   systemId:(NSString *)_sysId
283 {
284   [self indent];
285   printf("shall resolve entity with '%s' '%s'",
286          [_pubId cString], [_sysId cString]);
287   return nil;
288 }
289
290 /* errors */
291
292 - (void)warning:(SaxParseException *)_exception {
293   NSLog(@"warning(%@:%i): %@",
294         [[_exception userInfo] objectForKey:@"publicId"],
295         [[[_exception userInfo] objectForKey:@"line"] intValue],
296         [_exception reason]);
297 }
298
299 - (void)error:(SaxParseException *)_exception {
300   NSLog(@"error(%@:%i): %@",
301         [[_exception userInfo] objectForKey:@"publicId"],
302         [[[_exception userInfo] objectForKey:@"line"] intValue],
303         [_exception reason]);
304 }
305
306 - (void)fatalError:(SaxParseException *)_exception {
307   NSLog(@"fatal error(%@:%i): %@",
308         [[_exception userInfo] objectForKey:@"publicId"],
309         [[[_exception userInfo] objectForKey:@"line"] intValue],
310         [_exception reason]);
311   [_exception raise];
312 }
313
314 @end /* MySAXHandler */
315
316
317
318 int main(int argc, char **argv, char **env)  {
319   NSAutoreleasePool *pool;
320   vcf2xml *tool;
321   int rc;
322
323   pool = [[NSAutoreleasePool alloc] init];
324 #if LIB_FOUNDATION_LIBRARY  
325   [NSProcessInfo initializeWithArguments:argv count:argc environment:env];
326 #endif
327   
328   if ((tool = [[vcf2xml alloc] init])) {
329     NS_DURING
330       rc = [tool runWithArguments:[[NSProcessInfo processInfo] arguments]];
331     NS_HANDLER
332       abort();
333     NS_ENDHANDLER;
334     
335     [tool release];
336   }
337   else
338     rc = 1;
339   
340   [pool release];
341   return rc;
342 }