root/apps/iphone/superbook/trunk/DotTel_SDK/Classes/RecordTxt.m
@
382
| Revision 382, 5.8 kB (checked in by henri, 4 years ago) |
|---|
| 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 | |
| 31 | static 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.








