pEpObjCAdapter/PEPMessage.m
author Dirk Zimmermann <dirk@pep-project.org>
Tue, 24 Apr 2018 13:29:16 +0200
branchIOSAD-92
changeset 591 6f43608139c8
parent 589 addf605406d0
child 592 95dde8be4786
permissions -rw-r--r--
IOSAD-92 PEPMessage.isEqual with `[nil isEqual:nil] == YES`
     1 //
     2 //  PEPMessage.m
     3 //  pEpObjCAdapter
     4 //
     5 //  Created by Dirk Zimmermann on 10.11.17.
     6 //  Copyright © 2017 p≡p. All rights reserved.
     7 //
     8 
     9 #import "PEPMessage.h"
    10 #import "PEPIdentity.h"
    11 
    12 @implementation PEPMessage
    13 
    14 // MARK: - NSKeyValueCoding
    15 
    16 - (BOOL)outgoing
    17 {
    18     return self.direction == PEP_dir_outgoing;
    19 }
    20 
    21 - (void)setOutgoing:(BOOL)outgoing
    22 {
    23     self.direction = outgoing ? PEP_dir_outgoing:PEP_dir_incoming;
    24 }
    25 
    26 - (NSString *)id
    27 {
    28     return self.messageID;
    29 }
    30 
    31 - (void)setId:(NSString *)theID
    32 {
    33     self.messageID = theID;
    34 }
    35 
    36 - (NSString *)shortmsg
    37 {
    38     return self.shortMessage;
    39 }
    40 
    41 - (void)setShortmsg:(NSString *)shortMsg
    42 {
    43     self.shortMessage = shortMsg;
    44 }
    45 
    46 - (NSDate *)sent
    47 {
    48     return self.sentDate;
    49 }
    50 
    51 - (void)setSent:(NSDate *)sentDate
    52 {
    53     self.sentDate = sentDate;
    54 }
    55 
    56 - (NSDate *)recv
    57 {
    58     return self.receivedDate;
    59 }
    60 
    61 - (void)setRecv:(NSDate *)receivedDate
    62 {
    63     self.receivedDate = receivedDate;
    64 }
    65 
    66 - (PEPIdentity *)recv_by
    67 {
    68     return self.receivedBy;
    69 }
    70 
    71 - (void)setRecv_by:(PEPIdentity *)receivedBy
    72 {
    73     self.receivedBy = receivedBy;
    74 }
    75 
    76 - (NSArray *)reply_to
    77 {
    78     return self.replyTo;
    79 }
    80 
    81 - (void)setReply_to:(NSArray *)replyTo
    82 {
    83     self.replyTo = replyTo;
    84 }
    85 
    86 - (NSArray *)in_reply_to
    87 {
    88     return self.inReplyTo;
    89 }
    90 
    91 - (void)setIn_reply_to:(NSArray *)inReplyTo
    92 {
    93     self.inReplyTo = inReplyTo;
    94 }
    95 
    96 - (NSArray *)opt_fields
    97 {
    98     return self.optionalFields;
    99 }
   100 
   101 - (void)setOpt_fields:(NSArray *)optFields
   102 {
   103     self.optionalFields = optFields;
   104 }
   105 
   106 - (NSString *)longmsg
   107 {
   108     return self.longMessage;
   109 }
   110 
   111 - (void)setLongmsg:(NSString *)longMsg
   112 {
   113     self.longMessage = longMsg;
   114 }
   115 
   116 - (NSString *)longmsg_formatted
   117 {
   118     return self.longMessageFormatted;
   119 }
   120 
   121 - (void)setLongmsg_formatted:(NSString *)longMsgFormatted
   122 {
   123     self.longMessageFormatted = longMsgFormatted;
   124 }
   125 
   126 // MARK: Faking directory
   127 
   128 - (PEPDict * _Nonnull)dictionary
   129 {
   130     // most adapter use should be ok.
   131     return (PEPDict *) self;
   132 }
   133 
   134 - (PEPMutableDict * _Nonnull)mutableDictionary
   135 {
   136     // most adapter use should be ok.
   137     return (PEPMutableDict *) self;
   138 }
   139 
   140 // MARK: - NSDictionary - Helpers
   141 
   142 - (NSArray<NSArray<NSString *> *> *)keyValuePairs
   143 {
   144     NSMutableArray *result = [NSMutableArray new];
   145 
   146     if (self.from) {
   147         [result addObject:@[kPepFrom, self.from]];
   148     }
   149 
   150     if (self.to) {
   151         [result addObject:@[kPepTo, self.to]];
   152     }
   153 
   154     if (self.cc) {
   155         [result addObject:@[kPepCC, self.cc]];
   156     }
   157 
   158     if (self.shortMessage) {
   159         [result addObject:@[kPepShortMessage, self.shortMessage]];
   160     }
   161 
   162     if (self.longMessage) {
   163         [result addObject:@[kPepLongMessage, self.longMessage]];
   164     }
   165 
   166     if (self.longMessageFormatted) {
   167         [result addObject:@[kPepLongMessageFormatted, self.longMessageFormatted]];
   168     }
   169 
   170     BOOL outgoing = self.direction == PEP_dir_outgoing ? YES:NO;
   171     [result addObject:@[kPepOutgoing, [NSNumber numberWithBool:outgoing]]];
   172 
   173     return result;
   174 }
   175 
   176 // MARK: - NSDictionary
   177 
   178 - (nullable id)objectForKey:(NSString *)key
   179 {
   180     return [self valueForKey:key];
   181 }
   182 
   183 - (void)removeObjectForKey:(NSString *)key
   184 {
   185     if ([@"bcc" isEqualToString:key]) {
   186         self.bcc = nil;
   187     } else if ([@"cc" isEqualToString:key]) {
   188         self.cc = nil;
   189     } else if ([@"to" isEqualToString:key]) {
   190         self.to = nil;
   191     } else {
   192         NSAssert1(false, @"Unsupported key for removeObjectForKey: |%@|",  key);
   193     }
   194 }
   195 
   196 - (NSInteger)count
   197 {
   198     return [[self keyValuePairs] count];
   199 }
   200 
   201 - (void)enumerateKeysAndObjectsUsingBlock:(void (^)(id key, id obj, BOOL *stop))block
   202 {
   203     BOOL stop = NO;
   204     NSArray *pairs = [self keyValuePairs];
   205     for (NSArray *pair in pairs) {
   206         block(pair[0], pair[1], &stop);
   207         if (stop) {
   208             break;
   209         }
   210     }
   211 }
   212 
   213 // MARK: - NSMutableCopying
   214 
   215 - (id)mutableCopyWithZone:(nullable NSZone *)zone
   216 {
   217     PEPMessage *newMessage = [PEPMessage new];
   218     newMessage.messageID = self.messageID;
   219     newMessage.from = self.from;
   220     newMessage.to = self.to;
   221     newMessage.cc = self.cc;
   222     newMessage.bcc = self.bcc;
   223     newMessage.shortMessage = self.shortMessage;
   224     newMessage.longMessage = self.longMessage;
   225     newMessage.longMessageFormatted = self.longMessageFormatted;
   226     newMessage.replyTo = self.replyTo;
   227     newMessage.inReplyTo = self.inReplyTo;
   228     newMessage.references = self.references;
   229     newMessage.sentDate = self.sentDate;
   230     newMessage.receivedDate = self.receivedDate;
   231     newMessage.attachments = self.attachments;
   232     newMessage.optionalFields = self.optionalFields;
   233     newMessage.keywords = self.keywords;
   234     newMessage.receivedBy = self.receivedBy;
   235     newMessage.direction = self.direction;
   236     return newMessage;
   237 }
   238 
   239 // MARK: - Equality
   240 
   241 - (BOOL)isEqualToPEPMessage:(PEPMessage * _Nonnull)message
   242 {
   243     NSArray *keys = @[
   244                       @"attachments",
   245                       @"bcc",
   246                       @"cc",
   247                       @"direction",
   248                       @"from",
   249                       @"inReplyTo",
   250                       @"keywords",
   251                       @"longMessage",
   252                       @"longMessageFormatted",
   253                       @"messageID",
   254                       @"optionalFields",
   255                       @"receivedBy",
   256                       @"receivedDate",
   257                       @"references",
   258                       @"replyTo",
   259                       @"sentDate",
   260                       @"shortMessage",
   261                       @"to",
   262                       ];
   263 
   264     for (NSString *theKey in keys) {
   265         NSObject *objSelf = [self objectForKey:theKey];
   266         NSObject *objOther = [message objectForKey:theKey];
   267 
   268         if (objSelf == nil && objOther == nil) {
   269             // considered equal, continue
   270         } else if (![objSelf isEqual:objOther]) {
   271             // NSValue, NSArray, NSString all have correctly implemented isEqual, so this works
   272             return NO;
   273         }
   274     }
   275 
   276     return YES;
   277 }
   278 
   279 - (NSUInteger)hash
   280 {
   281     NSUInteger prime = 31;
   282     NSUInteger result = 1;
   283 
   284     result = prime * result + self.direction;
   285 
   286     result = prime * result + self.attachments.hash;
   287     result = prime * result + self.bcc.hash;
   288     result = prime * result + self.cc.hash;
   289     result = prime * result + self.from.hash;
   290     result = prime * result + self.inReplyTo.hash;
   291     result = prime * result + self.keywords.hash;
   292     result = prime * result + self.longMessage.hash;
   293     result = prime * result + self.longMessageFormatted.hash;
   294     result = prime * result + self.messageID.hash;
   295     result = prime * result + self.optionalFields.hash;
   296     result = prime * result + self.receivedBy.hash;
   297     result = prime * result + self.receivedDate.hash;
   298     result = prime * result + self.references.hash;
   299     result = prime * result + self.replyTo.hash;
   300     result = prime * result + self.shortMessage.hash;
   301     result = prime * result + self.to.hash;
   302 
   303     return result;
   304 }
   305 
   306 - (BOOL)isEqual:(id)object
   307 {
   308     if (object == self) {
   309         return YES;
   310     }
   311     if (!object || ![object isKindOfClass:[self class]]) {
   312         return NO;
   313     }
   314 
   315     return [self isEqualToPEPMessage:object];
   316 }
   317 
   318 @end