pEpObjCAdapter/PEPMessageUtil.m
author Dirk Zimmermann <dz@pep.security>
Thu, 14 May 2020 09:22:43 +0200
changeset 1441 822c0954acd1
parent 1397 b46446c1a8bc
permissions -rw-r--r--
Added tag Release_2.0.1 for changeset c8a55f65cab4
     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:kPepFlags]) {
   150             ident->flags = [[dict objectForKey:kPepFlags] intValue];
   151         }
   152 
   153         if ([dict objectForKey:@"lang"])
   154             strncpy(ident->lang, [[[dict objectForKey:@"lang"]
   155                                    precomposedStringWithCanonicalMapping] UTF8String], 2);
   156 
   157         if ([dict objectForKey:kPepCommType])
   158             ident->comm_type = [[dict objectForKey:kPepCommType] intValue];
   159     }
   160 
   161     return ident;
   162 }
   163 
   164 NSDictionary *PEP_identityDictFromStruct(pEp_identity *ident)
   165 {
   166     NSMutableDictionary *dict = [NSMutableDictionary new];
   167 
   168     if (ident) {
   169         if (ident->address && ident->address[0])
   170             [dict setObject:[NSString stringWithUTF8String:ident->address] forKey:kPepAddress];
   171 
   172         [dict setObject:[NSNumber numberWithBool: ident->me] forKey:kPepIsOwn];
   173         
   174         if (ident->fpr && ident->fpr[0])
   175             [dict setObject:[NSString stringWithUTF8String:ident->fpr] forKey:kPepFingerprint];
   176         
   177         if (ident->user_id && ident->user_id[0])
   178             [dict setObject:[NSString stringWithUTF8String:ident->user_id] forKey:kPepUserID];
   179         
   180         if (ident->username && ident->username[0])
   181             [dict setObject:[NSString stringWithUTF8String:ident->username] forKey:kPepUsername];
   182         
   183         if (ident->lang[0])
   184             [dict setObject:[NSString stringWithUTF8String:ident->lang] forKey:@"lang"];
   185         
   186         [dict setObject:[NSNumber numberWithInt: ident->comm_type] forKey:kPepCommType];
   187         [dict setObject:[NSNumber numberWithInt: ident->flags] forKey:kPepFlags];
   188     }
   189     return dict;
   190 }
   191 
   192 //!!!: move. PEP_identityToStruct is not PEPMessage(Util) related. Should be an internal method on PEPIdentity. Somthing like .toStruct()
   193 //!!!: also check for other methods here. 
   194 pEp_identity *PEP_identityToStruct(PEPIdentity *identity)
   195 {
   196     pEp_identity *ident = new_identity([[identity.address
   197                                          precomposedStringWithCanonicalMapping] UTF8String],
   198                                        [[identity.fingerPrint
   199                                          precomposedStringWithCanonicalMapping] UTF8String],
   200                                        [[identity.userID
   201                                          precomposedStringWithCanonicalMapping] UTF8String],
   202                                        [[identity.userName
   203                                          precomposedStringWithCanonicalMapping] UTF8String]);
   204 
   205     ident->me = identity.isOwn;
   206     ident->flags = identity.flags;
   207 
   208     if (identity.language) {
   209         strncpy(ident->lang, [[identity.language
   210                                precomposedStringWithCanonicalMapping] UTF8String], 2);
   211     }
   212 
   213     ident->comm_type = (PEP_comm_type) identity.commType;
   214 
   215     return ident;
   216 }
   217 
   218 PEPIdentity *PEP_identityFromStruct(pEp_identity *ident)
   219 {
   220     PEPIdentity *identity = nil;
   221     if (ident->address && ident->address[0]) {
   222         identity = [[PEPIdentity alloc]
   223                     initWithAddress:[NSString stringWithUTF8String:ident->address]];
   224     }
   225 
   226     if (ident->fpr && ident->fpr[0]) {
   227         identity.fingerPrint = [NSString stringWithUTF8String:ident->fpr];
   228     }
   229 
   230     if (ident->user_id && ident->user_id[0]) {
   231         identity.userID = [NSString stringWithUTF8String:ident->user_id];
   232     }
   233 
   234     if (ident->username && ident->username[0]) {
   235         identity.userName = [NSString stringWithUTF8String:ident->username];
   236     }
   237 
   238     if (ident->lang[0]) {
   239         identity.language = [NSString stringWithUTF8String:ident->lang];
   240     }
   241 
   242     identity.commType = (PEPCommType) ident->comm_type;
   243 
   244     identity.isOwn = ident->me;
   245     identity.flags = ident->flags;
   246 
   247     return identity;
   248 }
   249 
   250 NSArray<PEPIdentity *> *PEP_arrayFromIdentityList(identity_list *il)
   251 {
   252     NSMutableArray *array = [NSMutableArray array];
   253     
   254     for (identity_list *_il = il; _il && _il->ident; _il = _il->next) {
   255         [array addObject:PEP_identityFromStruct(il->ident)];
   256     }
   257     
   258     return array;
   259 }
   260 
   261 identity_list *PEP_identityArrayToList(NSArray<PEPIdentity *> *array)
   262 {
   263     identity_list *il = new_identity_list(NULL);
   264     if (!il)
   265         return NULL;
   266     
   267     identity_list *_il = il;
   268     for (NSMutableDictionary *address in array) {
   269         _il = identity_list_add(_il, PEP_identityDictToStruct(address));
   270     }
   271     
   272     return il;
   273 }
   274 
   275 NSArray *PEP_identityArrayFromList(identity_list *il)
   276 {
   277     NSMutableArray *array = [NSMutableArray array];
   278     
   279     for (identity_list *_il = il; _il && _il->ident; _il = _il->next) {
   280         PEPIdentity *ident = PEP_identityFromStruct(_il->ident);
   281         [array addObject:ident];
   282     }
   283     
   284     return array;
   285 }
   286 
   287 NSDictionary *PEP_messageDictFromStruct(message *msg)
   288 {
   289     NSMutableDictionary *dict = [NSMutableDictionary new];
   290     if (msg && dict) {
   291         [dict replaceWithMessage:msg];
   292     }
   293     return dict;
   294 }
   295 
   296 PEPMessage * _Nullable pEpMessageFromStruct(message * _Nullable msg)
   297 {
   298     if (!msg) {
   299         return nil;
   300     }
   301     NSDictionary *dict = PEP_messageDictFromStruct(msg);
   302     PEPMessage *theMessage = [PEPMessage new];
   303     [theMessage setValuesForKeysWithDictionary:dict];
   304     return theMessage;
   305 }
   306 
   307 message *PEP_messageToStruct(PEPMessage *message) {
   308     return PEP_messageDictToStruct((NSDictionary *) message);
   309 }
   310 
   311 message *PEP_messageDictToStruct(NSDictionary *dict)
   312 {
   313     // Direction default to incoming
   314     PEP_msg_direction dir = PEP_dir_incoming;
   315     
   316     if ([dict objectForKey:@"outgoing"])
   317         dir = [[dict objectForKey:@"outgoing"] boolValue] ? PEP_dir_outgoing : PEP_dir_incoming;
   318     
   319     message *msg = new_message(dir);
   320     
   321     if(!msg)
   322         return NULL;
   323     
   324     if ([dict objectForKey:@"id"])
   325         msg->id = new_string([[[dict objectForKey:@"id"] precomposedStringWithCanonicalMapping]
   326                               UTF8String], 0);
   327     
   328     if ([dict objectForKey:@"shortmsg"])
   329         msg->shortmsg = new_string([[[dict objectForKey:@"shortmsg"]
   330                                      precomposedStringWithCanonicalMapping] UTF8String], 0);
   331 
   332     if ([dict objectForKey:@"sent"])
   333         msg->sent = new_timestamp([[dict objectForKey:@"sent"] timeIntervalSince1970]);
   334     
   335     if ([dict objectForKey:@"recv"])
   336         msg->recv = new_timestamp([[dict objectForKey:@"recv"] timeIntervalSince1970]);
   337     
   338     if ([dict objectForKey:kPepFrom])
   339         msg->from = PEP_identityDictToStruct([dict objectForKey:kPepFrom]);
   340 
   341     if ([dict objectForKey:@"to"])
   342         msg->to = PEP_identityArrayToList([dict objectForKey:@"to"]);
   343 
   344     if ([dict objectForKey:@"recv_by"])
   345         msg->recv_by = PEP_identityDictToStruct([dict objectForKey:@"recv_by"]);
   346 
   347     if ([dict objectForKey:@"cc"])
   348         msg->cc = PEP_identityArrayToList([dict objectForKey:@"cc"]);
   349 
   350     if ([dict objectForKey:@"bcc"])
   351         msg->bcc = PEP_identityArrayToList([dict objectForKey:@"bcc"]);
   352     
   353     if ([dict objectForKey:@"reply_to"])
   354         msg->reply_to = PEP_identityArrayToList([dict objectForKey:@"reply_to"]);
   355     
   356     if ([dict objectForKey:@"in_reply_to"])
   357         msg->in_reply_to = PEP_arrayToStringlist([dict objectForKey:@"in_reply_to"]);
   358     
   359     if ([dict objectForKey:@"references"])
   360         msg->references = PEP_arrayToStringlist([dict objectForKey:@"references"]);
   361     
   362     if ([dict objectForKey:kPepKeywords])
   363         msg->keywords = PEP_arrayToStringlist([dict objectForKey:kPepKeywords]);
   364 
   365     if ([dict objectForKey:@"opt_fields"])
   366         msg->opt_fields = PEP_arrayToStringPairlist([dict objectForKey:@"opt_fields"]);
   367     
   368     if ([dict objectForKey:@"longmsg"])
   369         msg->longmsg = new_string([[[dict objectForKey:@"longmsg"]
   370                                     precomposedStringWithCanonicalMapping] UTF8String], 0);
   371     
   372     if ([dict objectForKey:@"longmsg_formatted"])
   373         msg->longmsg_formatted = new_string([[[dict objectForKey:@"longmsg_formatted"]
   374                                               precomposedStringWithCanonicalMapping]
   375                                              UTF8String], 0);
   376 
   377     if ([dict objectForKey:@"attachments"])
   378         msg->attachments = PEP_arrayToBloblist([dict objectForKey:@"attachments"]);
   379 
   380     return msg;
   381 }