pEpObjCAdapter/PEPMessageUtil.m
author Dirk Zimmermann <dz@pep.security>
Fri, 25 Oct 2019 12:05:24 +0200
branchIOS-1943
changeset 1325 79fbbc66bd39
parent 1043 27785d4d3e16
child 1048 6b93eb69aa75
child 1087 167f9d4b54aa
child 1114 47ad47b43e15
permissions -rw-r--r--
IOS-1943 Minimal test reproducing the problem.
     1 //
     2 //  PEPMessageUtil.m
     3 //  pEpiOSAdapter
     4 //
     5 //  Created by Volker Birk on 09.07.15.
     6 //  Copyright (c) 2015 p≡p. All rights reserved.
     7 //
     8 
     9 #import "PEPMessageUtil.h"
    10 
    11 #import "PEPConstants.h"
    12 #import "PEPIdentity.h"
    13 
    14 #import "PEPMessage.h"
    15 #import "PEPAttachment.h"
    16 #import "NSMutableDictionary+PEP.h"
    17 
    18 #import "pEp_string.h"
    19 
    20 NSArray *PEP_arrayFromStringlist(stringlist_t *sl)
    21 {
    22     NSMutableArray *array = [NSMutableArray array];
    23     
    24     for (stringlist_t *_sl = sl; _sl && _sl->value; _sl = _sl->next) {
    25         [array addObject:[NSString stringWithUTF8String:_sl->value]];
    26     }
    27     
    28     return array;
    29 }
    30 
    31 stringlist_t *PEP_arrayToStringlist(NSArray *array)
    32 {
    33     stringlist_t *sl = new_stringlist(NULL);
    34     if (!sl)
    35         return NULL;
    36     
    37     stringlist_t *_sl = sl;
    38     for (NSString *str in array) {
    39         _sl = stringlist_add(_sl, [[str precomposedStringWithCanonicalMapping] UTF8String]);
    40     }
    41     
    42     return sl;
    43 }
    44 
    45 NSArray *PEP_arrayFromStringPairlist(stringpair_list_t *sl)
    46 {
    47     NSMutableArray *array = [NSMutableArray array];
    48 
    49     for (stringpair_list_t *_sl = sl; _sl && _sl->value; _sl = _sl->next) {
    50         [array addObject:[[NSMutableArray alloc ]initWithObjects:
    51                 [NSString stringWithUTF8String:_sl->value->key],
    52                 [NSString stringWithUTF8String:_sl->value->value],
    53                 nil]];
    54     }
    55 
    56     return array;
    57 }
    58 
    59 stringpair_list_t *PEP_arrayToStringPairlist(NSArray *array)
    60 {
    61     stringpair_list_t *sl = new_stringpair_list(NULL);
    62     if (!sl)
    63         return NULL;
    64     
    65     stringpair_list_t *_sl = sl;
    66     for (NSArray *pair in array) {
    67         stringpair_t *_sp = new_stringpair(
    68                [[pair[0] precomposedStringWithCanonicalMapping] UTF8String],
    69                [[pair[1] precomposedStringWithCanonicalMapping] UTF8String]);
    70         _sl = stringpair_list_add(_sl, _sp);
    71     }
    72     
    73     return sl;
    74 }
    75 
    76 
    77 NSArray *PEP_arrayFromBloblist(bloblist_t *bl)
    78 {
    79     NSMutableArray *array = [NSMutableArray array];
    80     
    81     for (bloblist_t *_bl = bl; _bl && _bl->value; _bl = _bl->next) {
    82         PEPAttachment* theAttachment = [[PEPAttachment alloc]
    83                                         initWithData:[NSData
    84                                                       dataWithBytes:_bl->value length:_bl->size]];
    85 
    86         if(_bl->filename && _bl->filename[0]) {
    87             theAttachment.filename = [NSString stringWithUTF8String:_bl->filename];
    88         }
    89 
    90         if(_bl->mime_type && _bl->mime_type[0]) {
    91             theAttachment.mimeType = [NSString stringWithUTF8String:_bl->mime_type];
    92         }
    93 
    94         theAttachment.contentDisposition = (PEPContentDisposition) _bl->disposition;
    95         
    96         [array addObject:theAttachment];
    97     }
    98     return array;
    99 }
   100 
   101 bloblist_t *PEP_arrayToBloblist(NSArray *array)
   102 {
   103     if (array.count == 0) {
   104         return nil;
   105     }
   106 
   107     bloblist_t *_bl = new_bloblist(NULL, 0, NULL, NULL);
   108     bloblist_t *bl =_bl;
   109 
   110     // free() might be the default, but let's be explicit
   111     bl->release_value = (void (*) (char *)) free;
   112 
   113     for (PEPAttachment *theAttachment in array) {
   114         NSData *data = theAttachment.data;
   115         size_t size = [data length];
   116 
   117         char *buf = malloc(size);
   118         assert(buf);
   119         memcpy(buf, [data bytes], size);
   120         
   121         bl = bloblist_add(bl, buf, size,
   122                           [[theAttachment.mimeType
   123                             precomposedStringWithCanonicalMapping]
   124                            UTF8String],
   125                           [[theAttachment.filename
   126                             precomposedStringWithCanonicalMapping]
   127                            UTF8String]);
   128 
   129         bl->disposition = (content_disposition_type) theAttachment.contentDisposition;
   130     }
   131     return _bl;
   132 }
   133 
   134 pEp_identity *PEP_identityDictToStruct(NSDictionary *dict)
   135 {
   136     pEp_identity *ident = new_identity([[[dict objectForKey:kPepAddress]
   137                                          precomposedStringWithCanonicalMapping] UTF8String],
   138                                        [[[dict objectForKey:kPepFingerprint]
   139                                          precomposedStringWithCanonicalMapping] UTF8String],
   140                                        [[[dict objectForKey:kPepUserID]
   141                                          precomposedStringWithCanonicalMapping] UTF8String],
   142                                        [[[dict objectForKey:kPepUsername]
   143                                          precomposedStringWithCanonicalMapping] UTF8String]);
   144     if ([dict objectForKey:kPepIsOwn]) {
   145         ident->me = ((NSNumber*)[dict objectForKey:kPepIsOwn]).boolValue;
   146     }
   147 
   148     if (dict && ident) {
   149         if ([dict objectForKey:@"lang"])
   150             strncpy(ident->lang, [[[dict objectForKey:@"lang"]
   151                                    precomposedStringWithCanonicalMapping] UTF8String], 2);
   152 
   153         if ([dict objectForKey:kPepCommType])
   154             ident->comm_type = [[dict objectForKey:kPepCommType] intValue];
   155     }
   156 
   157     return ident;
   158 }
   159 
   160 NSDictionary *PEP_identityDictFromStruct(pEp_identity *ident)
   161 {
   162     NSMutableDictionary *dict = [NSMutableDictionary new];
   163 
   164     if (ident) {
   165         if (ident->address && ident->address[0])
   166             [dict setObject:[NSString stringWithUTF8String:ident->address] forKey:kPepAddress];
   167 
   168         [dict setObject:[NSNumber numberWithBool: ident->me] forKey:kPepIsOwn];
   169         
   170         if (ident->fpr && ident->fpr[0])
   171             [dict setObject:[NSString stringWithUTF8String:ident->fpr] forKey:kPepFingerprint];
   172         
   173         if (ident->user_id && ident->user_id[0])
   174             [dict setObject:[NSString stringWithUTF8String:ident->user_id] forKey:kPepUserID];
   175         
   176         if (ident->username && ident->username[0])
   177             [dict setObject:[NSString stringWithUTF8String:ident->username] forKey:kPepUsername];
   178         
   179         if (ident->lang[0])
   180             [dict setObject:[NSString stringWithUTF8String:ident->lang] forKey:@"lang"];
   181         
   182         [dict setObject:[NSNumber numberWithInt: ident->comm_type] forKey:kPepCommType];
   183     }
   184     return dict;
   185 }
   186 
   187 //!!!: move. PEP_identityToStruct is not PEPMessage(Util) related. Should be an internal method on PEPIdentity. Somthing like .toStruct()
   188 //!!!: also check for other methods here. 
   189 pEp_identity *PEP_identityToStruct(PEPIdentity *identity)
   190 {
   191     pEp_identity *ident = new_identity([[identity.address
   192                                          precomposedStringWithCanonicalMapping] UTF8String],
   193                                        [[identity.fingerPrint
   194                                          precomposedStringWithCanonicalMapping] UTF8String],
   195                                        [[identity.userID
   196                                          precomposedStringWithCanonicalMapping] UTF8String],
   197                                        [[identity.userName
   198                                          precomposedStringWithCanonicalMapping] UTF8String]);
   199 
   200     ident->me = identity.isOwn;
   201 
   202     if (identity.language) {
   203         strncpy(ident->lang, [[identity.language
   204                                precomposedStringWithCanonicalMapping] UTF8String], 2);
   205     }
   206 
   207     ident->comm_type = (PEP_comm_type) identity.commType;
   208 
   209     return ident;
   210 }
   211 
   212 PEPIdentity *PEP_identityFromStruct(pEp_identity *ident)
   213 {
   214     PEPIdentity *identity = nil;
   215     if (ident->address && ident->address[0]) {
   216         identity = [[PEPIdentity alloc]
   217                     initWithAddress:[NSString stringWithUTF8String:ident->address]];
   218     }
   219 
   220     if (ident->fpr && ident->fpr[0]) {
   221         identity.fingerPrint = [NSString stringWithUTF8String:ident->fpr];
   222     }
   223 
   224     if (ident->user_id && ident->user_id[0]) {
   225         identity.userID = [NSString stringWithUTF8String:ident->user_id];
   226     }
   227 
   228     if (ident->username && ident->username[0]) {
   229         identity.userName = [NSString stringWithUTF8String:ident->username];
   230     }
   231 
   232     if (ident->lang[0]) {
   233         identity.language = [NSString stringWithUTF8String:ident->lang];
   234     }
   235 
   236     identity.commType = (PEPCommType) ident->comm_type;
   237 
   238     identity.isOwn = ident->me;
   239 
   240     return identity;
   241 }
   242 
   243 NSArray<PEPIdentity *> *PEP_arrayFromIdentityList(identity_list *il)
   244 {
   245     NSMutableArray *array = [NSMutableArray array];
   246     
   247     for (identity_list *_il = il; _il && _il->ident; _il = _il->next) {
   248         [array addObject:PEP_identityFromStruct(il->ident)];
   249     }
   250     
   251     return array;
   252 }
   253 
   254 identity_list *PEP_identityArrayToList(NSArray<PEPIdentity *> *array)
   255 {
   256     identity_list *il = new_identity_list(NULL);
   257     if (!il)
   258         return NULL;
   259     
   260     identity_list *_il = il;
   261     for (NSMutableDictionary *address in array) {
   262         _il = identity_list_add(_il, PEP_identityDictToStruct(address));
   263     }
   264     
   265     return il;
   266 }
   267 
   268 NSArray *PEP_identityArrayFromList(identity_list *il)
   269 {
   270     NSMutableArray *array = [NSMutableArray array];
   271     
   272     for (identity_list *_il = il; _il && _il->ident; _il = _il->next) {
   273         PEPIdentity *ident = PEP_identityFromStruct(_il->ident);
   274         [array addObject:ident];
   275     }
   276     
   277     return array;
   278 }
   279 
   280 NSDictionary *PEP_messageDictFromStruct(message *msg)
   281 {
   282     NSMutableDictionary *dict = [NSMutableDictionary new];
   283     if (msg && dict) {
   284         [dict replaceWithMessage:msg];
   285     }
   286     return dict;
   287 }
   288 
   289 PEPMessage * _Nullable pEpMessageFromStruct(message * _Nullable msg)
   290 {
   291     if (!msg) {
   292         return nil;
   293     }
   294     NSDictionary *dict = PEP_messageDictFromStruct(msg);
   295     PEPMessage *theMessage = [PEPMessage new];
   296     [theMessage setValuesForKeysWithDictionary:dict];
   297     return theMessage;
   298 }
   299 
   300 message *PEP_messageToStruct(PEPMessage *message) {
   301     return PEP_messageDictToStruct((NSDictionary *) message);
   302 }
   303 
   304 message *PEP_messageDictToStruct(NSDictionary *dict)
   305 {
   306     // Direction default to incoming
   307     PEP_msg_direction dir = PEP_dir_incoming;
   308     
   309     if ([dict objectForKey:@"outgoing"])
   310         dir = [[dict objectForKey:@"outgoing"] boolValue] ? PEP_dir_outgoing : PEP_dir_incoming;
   311     
   312     message *msg = new_message(dir);
   313     
   314     if(!msg)
   315         return NULL;
   316     
   317     if ([dict objectForKey:@"id"])
   318         msg->id = new_string([[[dict objectForKey:@"id"] precomposedStringWithCanonicalMapping]
   319                               UTF8String], 0);
   320     
   321     if ([dict objectForKey:@"shortmsg"])
   322         msg->shortmsg = new_string([[[dict objectForKey:@"shortmsg"]
   323                                      precomposedStringWithCanonicalMapping] UTF8String], 0);
   324 
   325     if ([dict objectForKey:@"sent"])
   326         msg->sent = new_timestamp([[dict objectForKey:@"sent"] timeIntervalSince1970]);
   327     
   328     if ([dict objectForKey:@"recv"])
   329         msg->recv = new_timestamp([[dict objectForKey:@"recv"] timeIntervalSince1970]);
   330     
   331     if ([dict objectForKey:kPepFrom])
   332         msg->from = PEP_identityDictToStruct([dict objectForKey:kPepFrom]);
   333 
   334     if ([dict objectForKey:@"to"])
   335         msg->to = PEP_identityArrayToList([dict objectForKey:@"to"]);
   336 
   337     if ([dict objectForKey:@"recv_by"])
   338         msg->recv_by = PEP_identityDictToStruct([dict objectForKey:@"recv_by"]);
   339 
   340     if ([dict objectForKey:@"cc"])
   341         msg->cc = PEP_identityArrayToList([dict objectForKey:@"cc"]);
   342 
   343     if ([dict objectForKey:@"bcc"])
   344         msg->bcc = PEP_identityArrayToList([dict objectForKey:@"bcc"]);
   345     
   346     if ([dict objectForKey:@"reply_to"])
   347         msg->reply_to = PEP_identityArrayToList([dict objectForKey:@"reply_to"]);
   348     
   349     if ([dict objectForKey:@"in_reply_to"])
   350         msg->in_reply_to = PEP_arrayToStringlist([dict objectForKey:@"in_reply_to"]);
   351     
   352     if ([dict objectForKey:@"references"])
   353         msg->references = PEP_arrayToStringlist([dict objectForKey:@"references"]);
   354     
   355     if ([dict objectForKey:kPepKeywords])
   356         msg->keywords = PEP_arrayToStringlist([dict objectForKey:kPepKeywords]);
   357 
   358     if ([dict objectForKey:@"opt_fields"])
   359         msg->opt_fields = PEP_arrayToStringPairlist([dict objectForKey:@"opt_fields"]);
   360     
   361     if ([dict objectForKey:@"longmsg"])
   362         msg->longmsg = new_string([[[dict objectForKey:@"longmsg"]
   363                                     precomposedStringWithCanonicalMapping] UTF8String], 0);
   364     
   365     if ([dict objectForKey:@"longmsg_formatted"])
   366         msg->longmsg_formatted = new_string([[[dict objectForKey:@"longmsg_formatted"]
   367                                               precomposedStringWithCanonicalMapping]
   368                                              UTF8String], 0);
   369 
   370     if ([dict objectForKey:@"attachments"])
   371         msg->attachments = PEP_arrayToBloblist([dict objectForKey:@"attachments"]);
   372 
   373     return msg;
   374 }