pEpObjCAdapter/PEPMessageUtil.m
author Dirk Zimmermann <dirk@pep-project.org>
Mon, 16 Apr 2018 11:01:23 +0200
changeset 581 0954976b8da9
parent 578 a05f108cc223
child 597 aa68b6d6a966
permissions -rw-r--r--
IOSAD-91 PEPAttachment.initWithData
     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 "PEPIdentity.h"
    12 #import "PEPMessage.h"
    13 #import "PEPAttachment.h"
    14 
    15 #import "pEp_string.h"
    16 
    17 #pragma mark -- Constants
    18 
    19 NSString *const kPepUsername = @"username";
    20 
    21 NSString *const kPepAddress = @"address";
    22 
    23 NSString *const kPepUserID = @"user_id";
    24 
    25 NSString *const kPepIsOwn = @"isOwn";
    26 
    27 NSString *const kPepFingerprint = @"fpr";
    28 
    29 NSString *const kPepFrom = @"from";
    30 
    31 NSString *const kPepTo = @"to";
    32 
    33 NSString *const kPepCC = @"cc";
    34 
    35 NSString *const kPepBCC = @"bcc";
    36 
    37 NSString *const kPepShortMessage = @"shortmsg";
    38 
    39 NSString *const kPepLongMessage = @"longmsg";
    40 
    41 NSString *const kPepLongMessageFormatted = @"longmsg_formatted";
    42 
    43 NSString *const kPepOutgoing = @"outgoing";
    44 
    45 NSString *const kPepSent = @"sent";
    46 
    47 NSString *const kPepReceived = @"recv";
    48 
    49 NSString *const kPepID = @"id";
    50 
    51 NSString *const kPepReceivedBy = @"recv_by";
    52 NSString *const kPepReplyTo = @"reply_to";
    53 NSString *const kPepInReplyTo = @"in_reply_to";
    54 NSString *const kPepReferences = @"references";
    55 NSString *const kPepKeywords = @"keywords";
    56 NSString *const kPepOptFields = @"opt_fields";
    57 
    58 NSString *const kPepAttachments = @"attachments";
    59 
    60 NSString *const kPepCommType = @"comm_type";
    61 
    62 NSString *const kPepRawMessage = @"raw_message";
    63 
    64 NSString *const kXpEpVersion = @"X-pEp-Version";
    65 
    66 NSString *const kXEncStatus = @"X-EncStatus";
    67 
    68 NSString *const kXKeylist = @"X-KeyList";
    69 
    70 NSString *const _Nonnull kPepIsOwnIdentity = @"kPepIsOwnIdentity";
    71 
    72 NSArray *PEP_arrayFromStringlist(stringlist_t *sl)
    73 {
    74     NSMutableArray *array = [NSMutableArray array];
    75     
    76     for (stringlist_t *_sl = sl; _sl && _sl->value; _sl = _sl->next) {
    77         [array addObject:[NSString stringWithUTF8String:_sl->value]];
    78     }
    79     
    80     return array;
    81 }
    82 
    83 stringlist_t *PEP_arrayToStringlist(NSArray *array)
    84 {
    85     stringlist_t *sl = new_stringlist(NULL);
    86     if (!sl)
    87         return NULL;
    88     
    89     stringlist_t *_sl = sl;
    90     for (NSString *str in array) {
    91         _sl = stringlist_add(_sl, [[str precomposedStringWithCanonicalMapping] UTF8String]);
    92     }
    93     
    94     return sl;
    95 }
    96 
    97 NSArray *PEP_arrayFromStringPairlist(stringpair_list_t *sl)
    98 {
    99     NSMutableArray *array = [NSMutableArray array];
   100 
   101     for (stringpair_list_t *_sl = sl; _sl && _sl->value; _sl = _sl->next) {
   102         [array addObject:[[NSMutableArray alloc ]initWithObjects:
   103                 [NSString stringWithUTF8String:_sl->value->key],
   104                 [NSString stringWithUTF8String:_sl->value->value],
   105                 nil]];
   106     }
   107 
   108     return array;
   109 }
   110 
   111 stringpair_list_t *PEP_arrayToStringPairlist(NSArray *array)
   112 {
   113     stringpair_list_t *sl = new_stringpair_list(NULL);
   114     if (!sl)
   115         return NULL;
   116     
   117     stringpair_list_t *_sl = sl;
   118     for (NSArray *pair in array) {
   119         stringpair_t *_sp = new_stringpair(
   120                [[pair[0] precomposedStringWithCanonicalMapping] UTF8String],
   121                [[pair[1] precomposedStringWithCanonicalMapping] UTF8String]);
   122         _sl = stringpair_list_add(_sl, _sp);
   123     }
   124     
   125     return sl;
   126 }
   127 
   128 
   129 NSArray *PEP_arrayFromBloblist(bloblist_t *bl)
   130 {
   131     NSMutableArray *array = [NSMutableArray array];
   132     
   133     for (bloblist_t *_bl = bl; _bl && _bl->value; _bl = _bl->next) {
   134         PEPAttachment* theAttachment = [[PEPAttachment alloc]
   135                                         initWithData:[NSData
   136                                                       dataWithBytes:_bl->value length:_bl->size]];
   137 
   138         if(_bl->filename && _bl->filename[0]) {
   139             theAttachment.filename = [NSString stringWithUTF8String:_bl->filename];
   140         }
   141 
   142         if(_bl->mime_type && _bl->mime_type[0]) {
   143             theAttachment.mimeType = [NSString stringWithUTF8String:_bl->mime_type];
   144         }
   145 
   146         theAttachment.contentDisposition = _bl->disposition;
   147         
   148         [array addObject:theAttachment];
   149     }
   150     return array;
   151 }
   152 
   153 bloblist_t *PEP_arrayToBloblist(NSArray *array)
   154 {
   155     if (array.count == 0) {
   156         return nil;
   157     }
   158 
   159     bloblist_t *_bl = new_bloblist(NULL, 0, NULL, NULL);
   160     bloblist_t *bl =_bl;
   161 
   162     // free() might be the default, but let's be explicit
   163     bl->release_value = (void (*) (char *)) free;
   164 
   165     for (PEPAttachment *theAttachment in array) {
   166         NSData *data = theAttachment.data;
   167         size_t size = [data length];
   168 
   169         char *buf = malloc(size);
   170         assert(buf);
   171         memcpy(buf, [data bytes], size);
   172         
   173         bl = bloblist_add(bl, buf, size,
   174                           [[theAttachment.mimeType
   175                             precomposedStringWithCanonicalMapping]
   176                            UTF8String],
   177                           [[theAttachment.filename
   178                             precomposedStringWithCanonicalMapping]
   179                            UTF8String]);
   180 
   181         bl->disposition = theAttachment.contentDisposition;
   182     }
   183     return _bl;
   184 }
   185 
   186 pEp_identity *PEP_identityDictToStruct(NSDictionary *dict)
   187 {
   188     pEp_identity *ident = new_identity([[[dict objectForKey:kPepAddress]
   189                                          precomposedStringWithCanonicalMapping] UTF8String],
   190                                        [[[dict objectForKey:kPepFingerprint]
   191                                          precomposedStringWithCanonicalMapping] UTF8String],
   192                                        [[[dict objectForKey:kPepUserID]
   193                                          precomposedStringWithCanonicalMapping] UTF8String],
   194                                        [[[dict objectForKey:kPepUsername]
   195                                          precomposedStringWithCanonicalMapping] UTF8String]);
   196     if ([dict objectForKey:kPepIsOwn]) {
   197         ident->me = ((NSNumber*)[dict objectForKey:kPepIsOwn]).boolValue;
   198     }
   199 
   200     if (dict && ident) {
   201         if ([dict objectForKey:@"lang"])
   202             strncpy(ident->lang, [[[dict objectForKey:@"lang"]
   203                                    precomposedStringWithCanonicalMapping] UTF8String], 2);
   204 
   205         if ([dict objectForKey:kPepCommType])
   206             ident->comm_type = [[dict objectForKey:kPepCommType] intValue];
   207     }
   208 
   209     return ident;
   210 }
   211 
   212 NSDictionary *PEP_identityDictFromStruct(pEp_identity *ident)
   213 {
   214     NSMutableDictionary *dict = [NSMutableDictionary new];
   215 
   216     if (ident) {
   217         if (ident->address && ident->address[0])
   218             [dict setObject:[NSString stringWithUTF8String:ident->address] forKey:kPepAddress];
   219 
   220         [dict setObject:[NSNumber numberWithBool: ident->me] forKey:kPepIsOwn];
   221         
   222         if (ident->fpr && ident->fpr[0])
   223             [dict setObject:[NSString stringWithUTF8String:ident->fpr] forKey:kPepFingerprint];
   224         
   225         if (ident->user_id && ident->user_id[0])
   226             [dict setObject:[NSString stringWithUTF8String:ident->user_id] forKey:kPepUserID];
   227         
   228         if (ident->username && ident->username[0])
   229             [dict setObject:[NSString stringWithUTF8String:ident->username] forKey:kPepUsername];
   230         
   231         if (ident->lang[0])
   232             [dict setObject:[NSString stringWithUTF8String:ident->lang] forKey:@"lang"];
   233         
   234         [dict setObject:[NSNumber numberWithInt: ident->comm_type] forKey:kPepCommType];
   235     }
   236     return dict;
   237 }
   238 
   239 pEp_identity *PEP_identityToStruct(PEPIdentity *identity)
   240 {
   241     pEp_identity *ident = new_identity([[identity.address
   242                                          precomposedStringWithCanonicalMapping] UTF8String],
   243                                        [[identity.fingerPrint
   244                                          precomposedStringWithCanonicalMapping] UTF8String],
   245                                        [[identity.userID
   246                                          precomposedStringWithCanonicalMapping] UTF8String],
   247                                        [[identity.userName
   248                                          precomposedStringWithCanonicalMapping] UTF8String]);
   249 
   250     ident->me = identity.isOwn;
   251 
   252     if (identity.language) {
   253         strncpy(ident->lang, [[identity.language
   254                                precomposedStringWithCanonicalMapping] UTF8String], 2);
   255     }
   256 
   257     ident->comm_type = (PEP_comm_type) identity.commType;
   258 
   259     return ident;
   260 }
   261 
   262 PEPIdentity *PEP_identityFromStruct(pEp_identity *ident)
   263 {
   264     PEPIdentity *identity = nil;
   265     if (ident->address && ident->address[0]) {
   266         identity = [[PEPIdentity alloc]
   267                     initWithAddress:[NSString stringWithUTF8String:ident->address]];
   268     }
   269 
   270     if (ident->fpr && ident->fpr[0]) {
   271         identity.fingerPrint = [NSString stringWithUTF8String:ident->fpr];
   272     }
   273 
   274     if (ident->user_id && ident->user_id[0]) {
   275         identity.userID = [NSString stringWithUTF8String:ident->user_id];
   276     }
   277 
   278     if (ident->username && ident->username[0]) {
   279         identity.userName = [NSString stringWithUTF8String:ident->username];
   280     }
   281 
   282     if (ident->lang[0]) {
   283         identity.language = [NSString stringWithUTF8String:ident->lang];
   284     }
   285 
   286     identity.commType = ident->comm_type;
   287 
   288     return identity;
   289 }
   290 
   291 NSArray *PEP_arrayFromIdentityList(identity_list *il)
   292 {
   293     NSMutableArray *array = [NSMutableArray array];
   294     
   295     for (identity_list *_il = il; _il && _il->ident; _il = _il->next) {
   296         [array addObject:PEP_identityFromStruct(il->ident)];
   297     }
   298     
   299     return array;
   300 }
   301 
   302 identity_list *PEP_arrayToIdentityList(NSArray *array)
   303 {
   304     identity_list *il = new_identity_list(NULL);
   305     if (!il)
   306         return NULL;
   307     
   308     identity_list *_il = il;
   309     for (NSDictionary *dict in array) {
   310         _il = identity_list_add(_il, PEP_identityDictToStruct(dict));
   311     }
   312     
   313     return il;
   314 }
   315 
   316 identity_list *PEP_identityArrayToList(NSArray *array)
   317 {
   318     identity_list *il = new_identity_list(NULL);
   319     if (!il)
   320         return NULL;
   321     
   322     identity_list *_il = il;
   323     for (NSMutableDictionary *address in array) {
   324         _il = identity_list_add(_il, PEP_identityDictToStruct(address));
   325     }
   326     
   327     return il;
   328 }
   329 
   330 NSArray *PEP_identityArrayFromList(identity_list *il)
   331 {
   332     NSMutableArray *array = [NSMutableArray array];
   333     
   334     for (identity_list *_il = il; _il && _il->ident; _il = _il->next) {
   335         PEPIdentity *ident = PEP_identityFromStruct(_il->ident);
   336         [array addObject:ident];
   337     }
   338     
   339     return array;
   340 }
   341 
   342 NSDictionary *PEP_messageDictFromStruct(message *msg)
   343 {
   344     NSMutableDictionary *dict = [NSMutableDictionary new];
   345     if (msg && dict) {
   346         [dict setObject:(msg->dir==PEP_dir_outgoing)?@YES:@NO forKey:@"outgoing"];
   347 
   348         if (msg->id)
   349             [dict setObject:[NSString stringWithUTF8String:msg->id] forKey:@"id"];
   350         
   351         if (msg->shortmsg)
   352             [dict setObject:[NSString stringWithUTF8String:msg->shortmsg] forKey:@"shortmsg"];
   353 
   354         if (msg->sent)
   355             [dict setObject:[NSDate dateWithTimeIntervalSince1970:timegm(msg->sent)] forKey:@"sent"];
   356         
   357         if (msg->recv)
   358             [dict setObject:[NSDate dateWithTimeIntervalSince1970:mktime(msg->recv)] forKey:@"recv"];
   359         
   360         if (msg->from)
   361             [dict setObject:PEP_identityFromStruct(msg->from) forKey:kPepFrom];
   362         
   363         if (msg->to && msg->to->ident)
   364             [dict setObject:PEP_identityArrayFromList(msg->to) forKey:@"to"];
   365         
   366         if (msg->recv_by)
   367             [dict setObject:PEP_identityFromStruct(msg->recv_by) forKey:@"recv_by"];
   368         
   369         if (msg->cc && msg->cc->ident)
   370             [dict setObject:PEP_identityArrayFromList(msg->cc) forKey:@"cc"];
   371         
   372         if (msg->bcc && msg->bcc->ident)
   373             [dict setObject:PEP_identityArrayFromList(msg->bcc) forKey:@"bcc"];
   374         
   375         if (msg->reply_to && msg->reply_to->ident)
   376             [dict setObject:PEP_identityArrayFromList(msg->reply_to) forKey:@"reply_to"];
   377         
   378         if (msg->in_reply_to)
   379             [dict setObject:PEP_arrayFromStringlist(msg->in_reply_to) forKey:@"in_reply_to"];
   380 
   381         if (msg->references && msg->references->value)
   382             [dict setObject:PEP_arrayFromStringlist(msg->references) forKey:kPepReferences];
   383 
   384         if (msg->keywords && msg->keywords->value)
   385             [dict setObject:PEP_arrayFromStringlist(msg->keywords) forKey:@"keywords"];
   386 
   387         if (msg->opt_fields)
   388             [dict setObject:PEP_arrayFromStringPairlist(msg->opt_fields) forKey:@"opt_fields"];
   389         
   390         if (msg->longmsg_formatted)
   391             [dict setObject:[NSString stringWithUTF8String:msg->longmsg_formatted]
   392                      forKey:@"longmsg_formatted"];
   393 
   394         if (msg->longmsg)
   395             [dict setObject:[NSString stringWithUTF8String:msg->longmsg] forKey:@"longmsg"];
   396         
   397         if (msg->attachments && msg->attachments->value)
   398             [dict setObject: PEP_arrayFromBloblist(msg->attachments) forKey:@"attachments"];
   399 
   400         if (msg->rawmsg_size > 0 && *msg->rawmsg_ref) {
   401             NSData *data = [NSData dataWithBytes:msg->rawmsg_ref length:msg->rawmsg_size];
   402             dict[kPepRawMessage] = data;
   403         }
   404     }
   405     return dict;
   406 }
   407 
   408 PEPMessage * _Nullable pEpMessageFromStruct(message * _Nullable msg)
   409 {
   410     if (!msg) {
   411         return nil;
   412     }
   413     NSDictionary *dict = PEP_messageDictFromStruct(msg);
   414     PEPMessage *theMessage = [PEPMessage new];
   415     [theMessage setValuesForKeysWithDictionary:dict];
   416     return theMessage;
   417 }
   418 
   419 message *PEP_messageDictToStruct(NSDictionary *dict)
   420 {
   421     // Direction default to incoming
   422     PEP_msg_direction dir = PEP_dir_incoming;
   423     
   424     if ([dict objectForKey:@"outgoing"])
   425         dir = [[dict objectForKey:@"outgoing"] boolValue] ? PEP_dir_outgoing : PEP_dir_incoming;
   426     
   427     message *msg = new_message(dir);
   428     
   429     if(!msg)
   430         return NULL;
   431     
   432     if ([dict objectForKey:@"id"])
   433         msg->id = new_string([[[dict objectForKey:@"id"] precomposedStringWithCanonicalMapping]
   434                               UTF8String], 0);
   435     
   436     if ([dict objectForKey:@"shortmsg"])
   437         msg->shortmsg = new_string([[[dict objectForKey:@"shortmsg"]
   438                                      precomposedStringWithCanonicalMapping] UTF8String], 0);
   439 
   440     if ([dict objectForKey:@"sent"])
   441         msg->sent = new_timestamp([[dict objectForKey:@"sent"] timeIntervalSince1970]);
   442     
   443     if ([dict objectForKey:@"recv"])
   444         msg->recv = new_timestamp([[dict objectForKey:@"recv"] timeIntervalSince1970]);
   445     
   446     if ([dict objectForKey:kPepFrom])
   447         msg->from = PEP_identityDictToStruct([dict objectForKey:kPepFrom]);
   448 
   449     if ([dict objectForKey:@"to"])
   450         msg->to = PEP_identityArrayToList([dict objectForKey:@"to"]);
   451 
   452     if ([dict objectForKey:@"recv_by"])
   453         msg->recv_by = PEP_identityDictToStruct([dict objectForKey:@"recv_by"]);
   454 
   455     if ([dict objectForKey:@"cc"])
   456         msg->cc = PEP_identityArrayToList([dict objectForKey:@"cc"]);
   457 
   458     if ([dict objectForKey:@"bcc"])
   459         msg->bcc = PEP_identityArrayToList([dict objectForKey:@"bcc"]);
   460     
   461     if ([dict objectForKey:@"reply_to"])
   462         msg->reply_to = PEP_identityArrayToList([dict objectForKey:@"reply_to"]);
   463     
   464     if ([dict objectForKey:@"in_reply_to"])
   465         msg->in_reply_to = PEP_arrayToStringlist([dict objectForKey:@"in_reply_to"]);
   466     
   467     if ([dict objectForKey:@"references"])
   468         msg->references = PEP_arrayToStringlist([dict objectForKey:@"references"]);
   469     
   470     if ([dict objectForKey:kPepKeywords])
   471         msg->keywords = PEP_arrayToStringlist([dict objectForKey:kPepKeywords]);
   472 
   473     if ([dict objectForKey:@"opt_fields"])
   474         msg->opt_fields = PEP_arrayToStringPairlist([dict objectForKey:@"opt_fields"]);
   475     
   476     if ([dict objectForKey:@"longmsg"])
   477         msg->longmsg = new_string([[[dict objectForKey:@"longmsg"]
   478                                     precomposedStringWithCanonicalMapping] UTF8String], 0);
   479     
   480     if ([dict objectForKey:@"longmsg_formatted"])
   481         msg->longmsg_formatted = new_string([[[dict objectForKey:@"longmsg_formatted"]
   482                                               precomposedStringWithCanonicalMapping]
   483                                              UTF8String], 0);
   484 
   485     if ([dict objectForKey:@"attachments"])
   486         msg->attachments = PEP_arrayToBloblist([dict objectForKey:@"attachments"]);
   487 
   488     return msg;
   489 }