Developer Area

root/apps/iphone/superbook/trunk/DotTel_SDK/Classes/RecordTxt.m @ 382

Revision 382, 5.8 kB (checked in by henri, 5 years ago)

Major update: save .tel data to AddressBook?, with many other small fixes

Line 
1//
2//  RecordTxt.m
3//  DotTel SDK
4//
5//  Created by Henri Asseily on 9/13/08.
6/*
7 Copyright (c) 2008-2009, Telnic Ltd. All rights reserved.
8 
9 Redistribution and use in source and binary forms, with or without modification,
10 are permitted provided that the following conditions are met:
11 
12 Redistributions of source code must retain the above copyright notice, this list of conditions
13 and the following disclaimer. Redistributions in binary form must reproduce the above copyright
14 notice, this list of conditions and the following disclaimer in the documentation and/or other
15 materials provided with the distribution.
16 Neither the name of the Telnic Ltd. nor the names of its contributors may be used to endorse or
17 promote products derived from this software without specific prior written permission.
18 THIS DOCUMENTATION IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
19 OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
20 AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
21 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
24 IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27//
28
29#import "RecordTxt.h"
30
31static NSCharacterSet *trimCharacterSet;
32
33@interface RecordTxt (PrivateMethods)
34
35- (BOOL)parseKeywordsFromRecord:(const ldns_rr *)rr;
36
37- (NSString *)stringFromStringRdf:(const ldns_rdf *)rdf;
38
39@end
40
41@implementation RecordTxt
42
43@synthesize isValid;
44@synthesize isHeader;
45@synthesize isKeyword;
46@synthesize isSystemMessage;
47@synthesize expiryDate;
48
49@synthesize primaryDescription;
50@synthesize primaryValue;
51@synthesize textValue;
52@synthesize keysAndValues;
53
54+ (id)recordWithRr:(ldns_rr *)rr {
55        NSDate *lookupDate = [[NSDate date] retain];
56        self = [RecordTxt recordWithRr:rr date:lookupDate];
57        [lookupDate release];
58        return self;
59}
60
61+ (id)recordWithRr:(ldns_rr *)rr date:(NSDate *)lookupDate {
62        self = [[[RecordTxt alloc] initWithRr:rr date:lookupDate] autorelease];
63        return self;
64}
65
66- (id)init {
67        // Never initialize it empty
68        self = [super init];
69        isValid = NO;
70        return self;
71}
72
73- (id)initWithRr:(ldns_rr *)rr date:(NSDate *)lookupDate {
74        self = [super init];
75        trimCharacterSet = [[NSCharacterSet whitespaceCharacterSet] retain];
76        isValid = NO;
77        isKeyword = NO;
78
79        if (ldns_rr_get_type(rr) != LDNS_RR_TYPE_TXT)
80                return self;
81
82        NSTimeInterval ttl = (NSTimeInterval)ldns_rr_ttl(rr);
83        expiryDate = [lookupDate addTimeInterval:ttl];
84       
85        NSString *firstString = [self stringFromStringRdf:ldns_rr_rdf(rr,0)];
86        if ([firstString isEqualToString:@".tkw"]) {
87                // parse keywords
88                isKeyword = YES;
89                isValid = [self parseKeywordsFromRecord:rr];
90        } else if ([firstString isEqualToString:@".tsm"]) {
91                // system message, do nothing
92                return self;
93        } else if ([firstString isEqualToString:@".tad"]) {
94                // advert, do nothing for now
95                return self;
96        } else {
97                // header
98                isHeader = YES;
99                primaryDescription = [@"" retain];
100                primaryValue = NULL;
101                // Could have multiple strings in one record, they need to be joined together
102                NSMutableArray *stringComponents = [NSMutableArray arrayWithCapacity:2];
103                for (NSUInteger i=0; i < ldns_rr_rd_count(rr); i++) {
104                        [stringComponents addObject:[self stringFromStringRdf:ldns_rr_rdf(rr,i)]];
105                }
106
107                textValue = [stringComponents componentsJoinedByString:@" "];
108                isValid = YES;
109        }
110       
111        return self;
112}
113
114- (BOOL)parseKeywordsFromRecord:(const ldns_rr *)rr {
115        // Keywords always start with ".tkw" followed by the version number.
116        // After that, there are any number of pairs of type and value
117        // In general there should be a single pair, but compound keywords like addresses
118        // will have more. Here we opt to concatenate all the values for these compound keywords
119        // and only keep the first type string, discarding all other type strings if they exist
120        // However, we also keep a full array of type+value in case the user wants to store that
121        // info into the address book.
122       
123        // Check version
124        if ([[self stringFromStringRdf:ldns_rr_rdf(rr,1)] isEqualToString:@"1"]) {
125                // Version 1
126                keysAndValues = [[NSMutableArray arrayWithCapacity:ldns_rr_rd_count(rr)] retain];
127                for (NSUInteger i=2; i < ldns_rr_rd_count(rr); i=i+2) {
128                        [keysAndValues addObject:[self stringFromStringRdf:ldns_rr_rdf(rr,i)]];
129                        [keysAndValues addObject:[self stringFromStringRdf:ldns_rr_rdf(rr,i+1)]];
130                }
131                primaryDescription = [LocTelStr([keysAndValues objectAtIndex:0]) retain];
132                if ([keysAndValues count] < 3) {        // Only a single primary keyword/value
133                        primaryValue = NULL;
134                        textValue = [keysAndValues objectAtIndex:1];
135                } else {
136                        primaryValue = [keysAndValues objectAtIndex:1];
137                        NSMutableArray *keyValueComponents = [NSMutableArray arrayWithCapacity:2];
138                        for (NSUInteger i=1; i < [keysAndValues count]; i=i+2) {
139                                [keyValueComponents addObject:[keysAndValues objectAtIndex:i]];
140                        }
141                        textValue = [[[keyValueComponents componentsJoinedByString:@" "]
142                                                  stringByTrimmingCharactersInSet:trimCharacterSet] retain];
143                }
144                return TRUE;
145        } else {
146                // Unknown version
147                return FALSE;
148        }
149}
150
151# pragma mark ------------- Utility functions for parsing record data fields ------------
152
153- (NSString *)stringFromStringRdf:(const ldns_rdf *)rdf {
154        NSMutableString *res;
155        const uint8_t *data = ldns_rdf_data(rdf);
156        uint8_t length = data[0];
157        res = [[[NSMutableString alloc] initWithBytes:(const unichar *)(data+1)
158                                                                                   length:length
159                                                                                 encoding:NSUTF8StringEncoding] autorelease];
160        return res;
161}
162
163#pragma mark ---- cleanup ----
164
165- (void)dealloc {
166        [trimCharacterSet release];
167        [super dealloc];
168}
169
170@end
Note: See TracBrowser for help on using the browser.
Telnic
Search This Site
Partners
Neustar
ICANN
Main site | WHOIS | Sell .tel | FAQ | Archived Site | About Telnic | Contact Us