Big refactor for new caching mechanism.

This commit is contained in:
Ludovic Marcotte
2014-05-13 21:06:59 -04:00
parent ef2188962a
commit 5f9fb4e1c4
30 changed files with 175 additions and 197 deletions
+50
View File
@@ -0,0 +1,50 @@
//
// BSONCodec.h
// BSON Codec for Objective-C.
//
// Created by Martin Kou on 8/17/10.
// MIT License, see LICENSE file for details.
//
#import <Foundation/Foundation.h>
#import <stdint.h>
@protocol BSONCoding
- (uint8_t) BSONTypeID;
- (NSData *) BSONEncode;
- (NSData *) BSONRepresentation;
+ (id) BSONFragment: (NSData *) data at: (const void **) base ofType: (uint8_t) typeID;
@end
@protocol BSONObjectCoding
- (id) initWithBSONDictionary: (NSDictionary *) data;
- (NSDictionary *) BSONDictionary;
@end
@interface NSObject (BSONObjectCoding)
- (NSData *) BSONEncode;
- (NSData *) BSONRepresentation;
@end
@interface NSDictionary (BSON) <BSONCoding>
@end
@interface NSData (BSON) <BSONCoding>
- (NSDictionary *) BSONValue;
@end
@interface NSNumber (BSON) <BSONCoding>
@end
@interface NSString (BSON) <BSONCoding>
@end
@interface NSArray (BSON) <BSONCoding>
@end
@interface NSNull (BSON) <BSONCoding>
@end
@interface NSCalendarDate (BSON) <BSONCoding>
@end
+589
View File
@@ -0,0 +1,589 @@
//
// BSONCodec.m
// BSON Codec for Objective-C.
//
// Created by Martin Kou on 8/17/10.
// MIT License, see LICENSE file for details.
//
#import "BSONCodec.h"
#import <ctype.h>
#import <string.h>
#import <objc/objc.h>
#define BSONTYPE(tag,className) [className class], [NSNumber numberWithChar: (tag)]
#ifndef objc_msgSend
#define objc_msgSend(obj, sel, ...) \
objc_msg_lookup(obj, sel)(obj, sel, ## __VA_ARGS__)
#endif
static NSDictionary *BSONTypes()
{
static NSDictionary *retval = nil;
if (retval == nil)
{
retval = [[NSDictionary dictionaryWithObjectsAndKeys:
BSONTYPE(0x01, NSNumber),
BSONTYPE(0x02, NSString),
BSONTYPE(0x03, NSDictionary),
BSONTYPE(0x04, NSArray),
BSONTYPE(0x05, NSData),
BSONTYPE(0x08, NSNumber),
BSONTYPE(0x0A, NSNull),
BSONTYPE(0x10, NSNumber),
BSONTYPE(0x11, NSCalendarDate),
BSONTYPE(0x12, NSNumber),
nil] retain];
}
return retval;
}
#define SWAP16(x) \
((uint16_t)((((uint16_t)(x) & 0xff00) >> 8) | \
(((uint16_t)(x) & 0x00ff) << 8)))
#define SWAP32(x) \
((uint32_t)((((uint32_t)(x) & 0xff000000) >> 24) | \
(((uint32_t)(x) & 0x00ff0000) >> 8) | \
(((uint32_t)(x) & 0x0000ff00) << 8) | \
(((uint32_t)(x) & 0x000000ff) << 24)))
#define SWAP64(x) \
((uint64_t)((((uint64_t)(x) & 0xff00000000000000ULL) >> 56) | \
(((uint64_t)(x) & 0x00ff000000000000ULL) >> 40) | \
(((uint64_t)(x) & 0x0000ff0000000000ULL) >> 24) | \
(((uint64_t)(x) & 0x000000ff00000000ULL) >> 8) | \
(((uint64_t)(x) & 0x00000000ff000000ULL) << 8) | \
(((uint64_t)(x) & 0x0000000000ff0000ULL) << 24) | \
(((uint64_t)(x) & 0x000000000000ff00ULL) << 40) | \
(((uint64_t)(x) & 0x00000000000000ffULL) << 56)))
#if BYTE_ORDER == LITTLE_ENDIAN
#define BSONTOHOST16(x) (x)
#define BSONTOHOST32(x) (x)
#define BSONTOHOST64(x) (x)
#define HOSTTOBSON16(x) (x)
#define HOSTTOBSON32(x) (x)
#define HOSTTOBSON64(x) (x)
#elif BYTE_ORDER == BIG_ENDIAN
#define BSONTOHOST16(x) SWAP16(x)
#define BSONTOHOST32(x) SWAP32(x)
#define BSONTOHOST64(x) SWAP64(x)
#define HOSTTOBSON16(x) SWAP16(x)
#define HOSTTOBSON32(x) SWAP16(x)
#define HOSTTOBSON64(x) SWAP16(x)
#endif
#define CLASS_NAME_MARKER @"$$__CLASS_NAME__$$"
@implementation NSObject (BSONObjectCoding)
- (NSData *) BSONEncode
{
if (![self conformsToProtocol: @protocol(BSONObjectCoding)])
[NSException raise: NSInvalidArgumentException format: @"BSON encoding is only valid on objects conforming to the BSONObjectEncoding protocol."];
id <BSONObjectCoding> myself = (id <BSONObjectCoding>) self;
NSMutableDictionary *values = [[myself BSONDictionary] mutableCopy];
#if (defined(__GNU_LIBOBJC__) && (__GNU_LIBOBJC__ >= 20100911)) || defined(APPLE_RUNTIME) || defined(__GNUSTEP_RUNTIME__)
const char* className = class_getName([self class]);
#else
const char* className = [self class]->name;
#endif
[values setObject: [NSData dataWithBytes: (void *)className length: strlen(className)] forKey: CLASS_NAME_MARKER];
NSData *retval = [values BSONEncode];
[values release];
return retval;
}
- (NSData *) BSONRepresentation
{
return [self BSONEncode];
}
@end
@implementation NSDictionary (BSON)
- (uint8_t) BSONTypeID
{
return 0x03;
}
- (NSData *) BSONEncode
{
// Initialize the components structure.
NSMutableArray *components = [[NSMutableArray alloc] init];
NSMutableData *lengthData = [[NSMutableData alloc] initWithLength: 4];
[components addObject: lengthData];
[lengthData release];
NSMutableData *contentsData = [[NSMutableData alloc] init];
[components addObject: contentsData];
[contentsData release];
[components addObject: [NSData dataWithBytes: "\x00" length: 1]];
// Ensure ordered keys. not in BSON spec, but ensures all BSONRepresentations
// of the same dict will be the same.
NSMutableArray *keys = [[NSMutableArray alloc] init];
[keys addObjectsFromArray: [self allKeys]];
//[keys sortUsingSelector: @selector(caseInsensitiveCompare:)];
// Encode data.- (NSData *) BSONEncode;
uint8_t elementType = 0;
int i;
for (i = 0; i < [keys count]; i++)
{
NSString *key = [keys objectAtIndex: i];
NSObject *value = [self objectForKey: key];
if ([value respondsToSelector: @selector(BSONTypeID)])
elementType = [(id <BSONCoding>) value BSONTypeID];
else
elementType = 3;
[contentsData appendBytes: &elementType length: 1];
[contentsData appendData: [key dataUsingEncoding: NSUTF8StringEncoding]];
[contentsData appendBytes: "\x00" length: 1];
[contentsData appendData: [value BSONEncode]];
}
[keys release];
// Write length.
uint32_t *length = (uint32_t *)[lengthData mutableBytes];
*length = HOSTTOBSON32([contentsData length]) + 4 + 1;
// Assemble the output data.
NSMutableData *retval = [NSMutableData data];
for (i = 0; i < [components count]; i++)
[retval appendData: [components objectAtIndex: i]];
[components release];
return retval;
}
- (NSData *) BSONRepresentation
{
return [self BSONEncode];
}
+ (id) BSONFragment: (NSData *) data at: (const void **) base ofType: (uint8_t) t
{
const void *current = [data bytes];
if ((id)base != nil)
current = *base;
else
base = &current;
uint32_t length = BSONTOHOST32(*((uint32_t *)current));
const void *endPoint = current + length;
current += 4;
NSMutableDictionary *retval = [NSMutableDictionary dictionary];
while (current < endPoint - 1)
{
uint8_t typeID = *((uint8_t *)current);
current++;
char *utf8Key = (char *) current;
while (*((char *)current) != 0 && current < endPoint - 1)
current++;
current++;
NSString *key = [NSString stringWithUTF8String: utf8Key];
*base = current;
Class typeClass = [BSONTypes() objectForKey: [NSNumber numberWithChar: typeID]];
id value = objc_msgSend(typeClass, @selector(BSONFragment:at:ofType:), data, base, typeID);
current = *base;
[retval setObject: value forKey: key];
}
*base = current + 1;
// If the dictionary has a class name marker, then it is to be converted to an object.
if ([retval objectForKey: CLASS_NAME_MARKER] != nil)
{
NSData *classNameData = [retval objectForKey: CLASS_NAME_MARKER];
char *className = malloc([classNameData length] + 1);
memcpy(className, [classNameData bytes], [classNameData length]);
className[[classNameData length]] = 0;
Class targetClass = objc_getClass(className);
if (targetClass == nil)
[NSException raise: NSInvalidArgumentException format: @"Class %s found in incoming data is undefined.", className];
id obj = [[targetClass alloc] initWithBSONDictionary: retval];
return obj;
}
return retval;
}
@end
@implementation NSData (BSON)
- (uint8_t) BSONTypeID
{
return 0x05;
}
- (NSData *) BSONEncode
{
uint32_t length = HOSTTOBSON32([self length]);
NSMutableData *retval = [NSMutableData data];
[retval appendBytes: &length length: 4];
[retval appendBytes: "\x00" length: 1];
[retval appendData: self];
return retval;
}
- (NSData *) BSONRepresentation
{
return [self BSONEncode];
}
+ (id) BSONFragment: (NSData *) data at: (const void **) base ofType: (uint8_t) t
{
const void *current = [data bytes];
if ((id)base != nil)
current = *base;
else
base = &current;
uint32_t length = BSONTOHOST32(*((uint32_t *)current));
current += 4 + 1;
NSData *retval = [NSData dataWithBytes: current length: length];
current += length;
*base = current;
return retval;
}
- (NSDictionary *) BSONValue
{
return [NSDictionary BSONFragment: self at: NULL ofType: 0x03];
}
@end
@implementation NSNumber (BSON)
- (uint8_t) BSONTypeID
{
const char encoding = tolower(*([self objCType]));
switch (encoding) {
case 'f':
case 'd': return 0x01;
case 'b': return 0x08;
case 'c':
case 's': return 0x10;
case 'i':
// Ok, if you're running Objective-C on 16-bit platforms...
// Then YOU have issues.
// So, yeah, we won't handle that case.
if (sizeof(int) == 4)
return 0x10;
else if (sizeof(int) == 8)
return 0x12;
case 'l':
if (sizeof(long) == 4)
return 0x10;
else if (sizeof(long) == 8)
return 0x12;
case 'q': return 0x12;
default:
[NSException raise: NSInvalidArgumentException format: @"%@::%s - invalid encoding type '%c'", [self class], _cmd, encoding];
}
return 0;
}
- (NSData *) BSONEncode
{
const char encoding = *([self objCType]);
if (encoding == 'd' || encoding == 'D')
{
double value = [self doubleValue];
return [NSData dataWithBytes: &value length: 8];
}
if (encoding == 'f' || encoding == 'F')
{
double value = [self floatValue];
return [NSData dataWithBytes: &value length: 8];
}
if (encoding == 'b' || encoding == 'B')
{
char value = [self boolValue];
return [NSData dataWithBytes: &value length: 1];
}
if (encoding == 'c' || encoding == 'C')
{
int32_t value = [self charValue];
value = HOSTTOBSON32(value);
return [NSData dataWithBytes: &value length: 4];
}
if (encoding == 's' || encoding == 'S')
{
int32_t value = [self shortValue];
value = HOSTTOBSON32(value);
return [NSData dataWithBytes: &value length: 4];
}
if (encoding == 'i' || encoding == 'I')
{
int value = [self intValue];
if (sizeof(int) == 4)
value = HOSTTOBSON32(value);
else if (sizeof(int) == 8)
value = HOSTTOBSON64(value);
return [NSData dataWithBytes: &value length: sizeof(int)];
}
if (encoding == 'l' || encoding == 'L')
{
long value = [self longValue];
if (sizeof(long) == 4)
value = HOSTTOBSON32(value);
else if (sizeof(long) == 8)
value = HOSTTOBSON64(value);
return [NSData dataWithBytes: &value length: sizeof(long)];
}
if (encoding == 'q')
{
long long value = HOSTTOBSON64([self longLongValue]);
return [NSData dataWithBytes: &value length: 8];
}
if (encoding == 'Q')
{
long long value = HOSTTOBSON64([self unsignedLongLongValue]);
return [NSData dataWithBytes: &value length: 8];
}
[NSException raise: NSInvalidArgumentException format: @"%@::%s - invalid encoding type '%c'", [self class], _cmd, encoding];
return nil;
}
- (NSData *) BSONRepresentation
{
return [self BSONEncode];
}
+ (id) BSONFragment: (NSData *) data at: (const void **) base ofType: (uint8_t) t
{
if (t == 0x01)
{
// #5: LLVM GCC requires double pointers to have a certain alignment in ARM CPUs.
// So we can't just read the double off directly from the data - need to copy it.
double value;
memcpy(&value, *base, sizeof(double));
*base += 8;
return [NSNumber numberWithDouble: value];
}
if (t == 0x08)
{
char value = ((char *) *base)[0];
*base += 1;
return [NSNumber numberWithBool: value];
}
if (t == 0x10)
{
int32_t value = BSONTOHOST32(((int32_t *) *base)[0]);
*base += 4;
if (sizeof(int) == 4)
return [NSNumber numberWithInt: value];
return [NSNumber numberWithLong: value];
}
if (t == 0x12)
{
int64_t value = BSONTOHOST64(((int64_t *) *base)[0]);
*base += 8;
return [NSNumber numberWithUnsignedLongLong: value];
}
return nil;
}
@end
@implementation NSString (BSON)
- (uint8_t) BSONTypeID
{
return 0x02;
}
- (NSData *) BSONEncode
{
NSData *utf8Data = [self dataUsingEncoding: NSUTF8StringEncoding];
uint32_t length = HOSTTOBSON32([utf8Data length] + 1);
NSMutableData *retval = [NSMutableData data];
[retval appendBytes: &length length: 4];
[retval appendData: utf8Data];
[retval appendBytes: "\x00" length: 1];
return retval;
}
- (NSData *) BSONRepresentation
{
return [self BSONEncode];
}
+ (id) BSONFragment: (NSData *) data at: (const void **) base ofType: (uint8_t) typeID
{
uint32_t length = BSONTOHOST32(((const uint32_t *) *base)[0]);
*base += 4;
const char *utf8Str = (const char *) *base;
*base += length;
return [NSString stringWithUTF8String: utf8Str];
}
@end
@implementation NSArray (BSON)
- (uint8_t) BSONTypeID
{
return 0x04;
}
- (NSData *) BSONEncode
{
// Initialize the components structure.
NSMutableArray *components = [[NSMutableArray alloc] init];
NSMutableData *lengthData = [[NSMutableData alloc] initWithLength: 4];
[components addObject: lengthData];
[lengthData release];
NSMutableData *contentsData = [[NSMutableData alloc] init];
[components addObject: contentsData];
[contentsData release];
[components addObject: [NSData dataWithBytes: "\x00" length: 1]];
// Encode data.
uint8_t elementType = 0;
int i, count = [self count];
for (i = 0 ; i < count ; i++)
{
NSObject *value = [self objectAtIndex: i];
if ([value respondsToSelector: @selector(BSONTypeID)])
elementType = [(id <BSONCoding>) value BSONTypeID];
else
elementType = 3;
[contentsData appendBytes: &elementType length: 1];
[contentsData appendData: [[NSString stringWithFormat: @"%d", i] dataUsingEncoding: NSUTF8StringEncoding]];
[contentsData appendBytes: "\x00" length: 1];
[contentsData appendData: [value BSONEncode]];
}
// Write length.
uint32_t *length = (uint32_t *)[lengthData mutableBytes];
*length = HOSTTOBSON32([contentsData length]) + 4 + 1;
// Assemble the output data.
NSMutableData *retval = [NSMutableData data];
for (i = 0; i < [components count]; i++)
[retval appendData: [components objectAtIndex: i]];
[components release];
return retval;
}
- (NSData *) BSONRepresentation
{
return [self BSONEncode];
}
+ (id) BSONFragment: (NSData *) data at: (const void **) base ofType: (uint8_t) typeID
{
NSDictionary *tmp = [NSDictionary BSONFragment: data at: base ofType: 0x03];
NSMutableArray *retval = [NSMutableArray arrayWithCapacity: [tmp count]];
int i;
for (i = 0; i < [tmp count]; i++)
[retval addObject: [tmp objectForKey: [NSString stringWithFormat: @"%d", i]]];
return retval;
}
@end
@implementation NSNull (BSON)
- (uint8_t) BSONTypeID
{
return 0x0a;
}
- (NSData *) BSONEncode
{
return [NSData data];
}
- (NSData *) BSONRepresentation
{
return [self BSONEncode];
}
+ (id) BSONFragment: (NSData *) data at: (const void **) base ofType: (uint8_t) typeID
{
return [NSNull null];
}
@end
@implementation NSCalendarDate (BSON)
- (uint8_t) BSONTypeID
{
return 0x11;
}
- (NSData *) BSONEncode
{
NSString *v;
v = [self descriptionWithCalendarFormat: @"%Y-%m-%d %H:%M:%S %Z"
locale: nil];
return [v BSONEncode];
}
- (NSData *) BSONRepresentation
{
return [self BSONEncode];
}
+ (id) BSONFragment: (NSData *) data at: (const void **) base ofType: (uint8_t) typeID
{
NSString *v;
v = [NSString BSONFragment: data at: base ofType: 0x02];
return [NSCalendarDate dateWithString: v
calendarFormat: @"%Y-%m-%d %H:%M:%S %Z"];
}
@end
+43
View File
@@ -0,0 +1,43 @@
/* EOBitmaskQualifier.h - this file is part of SOGo
*
* Copyright (C) 2010-2014 Inverse inc
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
* This file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef EOBITMASKQUALIFIER_H
#define EOBITMASKQUALIFIER_H
#import <EOControl/EOQualifier.h>
@interface EOBitmaskQualifier : EOQualifier
{
NSString *key;
uint32_t mask;
BOOL isZero;
}
- (id) initWithKey: (NSString *) newKey
mask: (uint32_t) newMask
isZero: (BOOL) newIsZero;
- (NSString *) key;
- (uint32_t ) mask;
- (BOOL) isZero;
@end
#endif /* EOBITMASKQUALIFIER_H */
+75
View File
@@ -0,0 +1,75 @@
/* EOBitmaskQualifier.m - this file is part of SOGo
*
* Copyright (C) 2010-2014 Inverse inc
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
* This file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#import <Foundation/NSString.h>
#import "EOBitmaskQualifier.h"
@implementation EOBitmaskQualifier
- (id) initWithKey: (NSString *) newKey
mask: (uint32_t) newMask
isZero: (BOOL) newIsZero
{
if ((self = [self init]))
{
ASSIGN (key, newKey);
isZero = newIsZero;
mask = newMask;
}
return self;
}
- (void) dealloc
{
[key release];
[super dealloc];
}
- (NSString *) key
{
return key;
}
- (uint32_t ) mask
{
return mask;
}
- (BOOL) isZero
{
return isZero;
}
- (NSString *) description
{
NSMutableString *desc;
desc = [NSMutableString stringWithCapacity: [key length] + 24];
if (isZero)
[desc appendString: @"!"];
[desc appendFormat: @"(%@ & 0x%.8x)", key, mask];
return desc;
}
@end
@@ -0,0 +1,34 @@
/* EOQualifier+SOGoCacheObject.h - this file is part of SOGo
*
* Copyright (C) 2010-2014 Inverse inc.
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
* This file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef EOQUALIFIER_SOGOCACHEOBJECT_H
#define EOQUALIFIER_SOGOCACHEOBJECT_H
#import <EOControl/EOQualifier.h>
@class SOGoCacheGCSObject;
@interface EOQualifier (SOGoCacheObjectRestrictions)
- (BOOL) evaluateSOGoMAPIDBObject: (SOGoCacheGCSObject *) object;
@end
#endif /* EOQUALIFIER_CACHEOBJECT_H */
@@ -0,0 +1,158 @@
/* EOQualifier+SOGoCacheObject.m - this file is part of SOGo
*
* Copyright (C) 2010-2014 Inverse inc
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
* This file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#import <Foundation/NSArray.h>
#import <Foundation/NSCharacterSet.h>
#import <Foundation/NSDictionary.h>
#import <Foundation/NSString.h>
#import <Foundation/NSValue.h>
#import <NGExtensions/NSObject+Logs.h>
#import "EOBitmaskQualifier.h"
#import "SOGoCacheGCSObject.h"
#import "EOQualifier+SOGoCacheObject.h"
@implementation EOQualifier (SOGoCacheObjectRestrictions)
- (BOOL) _evaluateSOGoMAPIDBObject: (NSDictionary *) properties
{
[self subclassResponsibility: _cmd];
return NO;
}
- (BOOL) evaluateSOGoMAPIDBObject: (SOGoCacheGCSObject *) object
{
NSDictionary *properties;
BOOL rc;
//[self logWithFormat: @"evaluating object '%@'", object];
properties = [object properties];
rc = [self _evaluateSOGoMAPIDBObject: properties];
//[self logWithFormat: @" evaluation result: %d", rc];
return rc;
}
@end
@implementation EOAndQualifier (SOGoCacheRestrictionsPrivate)
- (BOOL) _evaluateSOGoMAPIDBObject: (NSDictionary *) properties
{
NSUInteger i;
BOOL rc;
rc = YES;
for (i = 0; rc && i < count; i++)
rc = [[qualifiers objectAtIndex: i]
_evaluateSOGoMAPIDBObject: properties];
return rc;
}
@end
@implementation EOOrQualifier (SOGoCacheObjectRestrictionsPrivate)
- (BOOL) _evaluateSOGoMAPIDBObject: (NSDictionary *) properties
{
NSUInteger i;
BOOL rc;
rc = NO;
for (i = 0; !rc && i < count; i++)
rc = [[qualifiers objectAtIndex: i]
_evaluateSOGoMAPIDBObject: properties];
return rc;
}
@end
@implementation EONotQualifier (SOGoCacheObjectRestrictionsPrivate)
- (BOOL) _evaluateSOGoMAPIDBObject: (NSDictionary *) properties
{
return ![qualifier _evaluateSOGoMAPIDBObject: properties];
}
@end
@implementation EOKeyValueQualifier (SOGoCacheObjectRestrictionsPrivate)
typedef BOOL (*EOComparator) (id, SEL, id);
- (BOOL) _evaluateSOGoMAPIDBObject: (NSDictionary *) properties
{
id finalKey;
id propValue;
EOComparator comparator;
if ([key isKindOfClass: [NSNumber class]])
finalKey = key;
else if ([key isKindOfClass: [NSString class]])
{
finalKey = [key stringByTrimmingCharactersInSet: [NSCharacterSet decimalDigitCharacterSet]];
if ([finalKey length] > 0)
finalKey = key;
else
finalKey = [NSNumber numberWithInt: [key intValue]];
}
else
finalKey = @"";
propValue = [properties objectForKey: finalKey];
comparator = (EOComparator) [propValue methodForSelector: operator];
return (comparator ? comparator (propValue, operator, value) : NO);
}
@end
@implementation EOBitmaskQualifier (SOGoCacheObjectRestrictionsPrivate)
- (BOOL) _evaluateSOGoMAPIDBObject: (NSDictionary *) properties
{
NSNumber *propTag;
id propValue;
uint32_t intValue;
BOOL rc;
propTag = [NSNumber numberWithInt: [key intValue]];
propValue = [properties objectForKey: propTag];
intValue = [propValue unsignedIntValue];
rc = ((isZero && (intValue & mask) == 0)
|| (!isZero && (intValue & mask) != 0));
//[self logWithFormat: @"evaluation of bitmask qualifier:"
// @" (%.8x & %.8x) %s 0: %d",
// intValue, mask, (isZero ? "==" : "!="), rc];
return rc;
}
@end
@@ -1,8 +1,6 @@
/* GCSSpecialQueries+OpenChange.h - this file is part of SOGo
/* GCSSpecialQueries+SOGoCacheObject.h - this file is part of SOGo
*
* Copyright (C) 2012 Inverse inc
*
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
* Copyright (C) 2012-2014 Inverse inc
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,15 +18,15 @@
* Boston, MA 02111-1307, USA.
*/
#ifndef GCSSPECIALQUERIES_OPENCHANGE_H
#define GCSSPECIALQUERIES_OPENCHANGE_H
#ifndef GCSSPECIALQUERIES_SOGOCACHEOBJECT_H
#define GCSSPECIALQUERIES_SOGOCACHEOBJECT_H
#import <GDLContentStore/GCSSpecialQueries.h>
@interface GCSSpecialQueries (OpenChangeHelpers)
@interface GCSSpecialQueries (SOGoCacheObject)
- (NSString *) createOpenChangeFSTableWithName: (NSString *) tableName;
@end
#endif /* GCSSPECIALQUERIES_OPENCHANGE_H */
#endif /* GCSSPECIALQUERIES_SOGOCACHEOBJECT_H */
@@ -1,8 +1,6 @@
/* GCSSpecialQueries+OpenChange.m - this file is part of SOGo
/* GCSSpecialQueries+SOGoCacheObject.m - this file is part of SOGo
*
* Copyright (C) 2012 Inverse inc
*
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
* Copyright (C) 2012-2014 Inverse inc
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -22,18 +20,18 @@
#import <Foundation/NSString.h>
#import "GCSSpecialQueries+OpenChange.h"
#import "GCSSpecialQueries+SOGoCacheObject.h"
@interface GCSPostgreSQLSpecialQueries (OpenChangeHelpers)
@interface GCSPostgreSQLSpecialQueries (SOGoObjectCache)
@end
@interface GCSMySQLSpecialQueries (OpenChangeHelpers)
@interface GCSMySQLSpecialQueries (SOGoObjectCache)
@end
@interface GCSOracleSpecialQueries (OpenChangeHelpers)
@interface GCSOracleSpecialQueries (SOGoObjectCache)
@end
@implementation GCSSpecialQueries (OpenChangeHelpers)
@implementation GCSSpecialQueries (SOGoObjectCache)
/* FIXME: c_parent_path should be indexed */
@@ -46,7 +44,7 @@
@end
@implementation GCSPostgreSQLSpecialQueries (OpenChangeHelpers)
@implementation GCSPostgreSQLSpecialQueries (SOGoObjectCache)
- (NSString *) createOpenChangeFSTableWithName: (NSString *) tableName
{
@@ -66,7 +64,7 @@
@end
@implementation GCSMySQLSpecialQueries (OpenChangeHelpers)
@implementation GCSMySQLSpecialQueries (SOGoObjectCache)
- (NSString *) createOpenChangeFSTableWithName: (NSString *) tableName
{
@@ -86,7 +84,7 @@
@end
@implementation GCSOracleSpecialQueries (OpenChangeHelpers)
@implementation GCSOracleSpecialQueries (SOGoObjectCache)
- (NSString *) createOpenChangeFSTableWithName: (NSString *) tableName
{
+14
View File
@@ -15,7 +15,14 @@ SOGo_HEADER_FILES = \
SOGoBuild.h \
SOGoProductLoader.h \
\
BSONCodec.h \
EOBitmaskQualifier.h \
EOQualifier+SOGoCacheObject.h \
GCSSpecialQueries+SOGoCacheObject.h \
SOGoCache.h \
SOGoCacheGCSFolder.h \
SOGoCacheGCSObject.h \
SOGoCacheObject.h \
SOGoConstants.h \
SOGoObject.h \
SOGoContentObject.h \
@@ -80,7 +87,14 @@ SOGo_OBJC_FILES = \
SOGoBuild.m \
SOGoProductLoader.m \
\
BSONCodec.m \
EOBitmaskQualifier.m \
EOQualifier+SOGoCacheObject.m \
GCSSpecialQueries+SOGoCacheObject.m \
SOGoCache.m \
SOGoCacheGCSFolder.m \
SOGoCacheGCSObject.m \
SOGoCacheObject.m \
SOGoConstants.m \
SOGoObject.m \
SOGoContentObject.m \
+8 -12
View File
@@ -1,8 +1,6 @@
/* SOGoMAPIDBFolder.h - this file is part of SOGo
/* SOGoCacheGCSFolder.h - this file is part of SOGo
*
* Copyright (C) 2012 Inverse inc.
*
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
* Copyright (C) 2012-2014 Inverse inc.
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,10 +18,10 @@
* Boston, MA 02111-1307, USA.
*/
#ifndef SOGOMAPIDBFOLDER_H
#define SOGOMAPIDBFOLDER_H
#ifndef SOGOCACHEGCSFOLDER_H
#define SOGOCACHEGCSFOLDER_H
#import "SOGoMAPIDBObject.h"
#import "SOGoCacheGCSObject.h"
@class NSArray;
@class NSMutableString;
@@ -32,12 +30,10 @@
@class EOQualifier;
@class SOGoMAPIDBMessage;
@interface SOGoMAPIDBFolder : SOGoMAPIDBObject
@interface SOGoCacheGCSFolder : SOGoCacheGCSObject
{
NSString *pathPrefix; /* for root folders */
SOGoMAPIDBObject *aclMessage;
SOGoCacheGCSObject *aclMessage;
}
- (void) setPathPrefix: (NSString *) newPathPrefix;
@@ -56,4 +52,4 @@
@end
#endif /* SOGOMAPIDBFOLDER_H */
#endif /* SOGOCACHEGCSFOLDER_H */
+20 -23
View File
@@ -1,8 +1,6 @@
/* SOGoMAPIDBFolder.m - this file is part of SOGo
/* SOGoCacheGCSFolder.m - this file is part of SOGo
*
* Copyright (C) 2012 Inverse inc.
*
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
* Copyright (C) 2012-2014 Inverse inc.
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -38,28 +36,27 @@
#import <SOGo/NSString+Utilities.h>
#import <SOGo/SOGoDomainDefaults.h>
#import <SOGo/SOGoUser.h>
#import "EOQualifier+MAPI.h"
#import "GCSSpecialQueries+OpenChange.h"
#import "SOGoMAPIDBMessage.h"
#import "EOQualifier+SOGoCacheObject.h"
#import "GCSSpecialQueries+SOGoCacheObject.h"
#import "SOGoMAPIDBFolder.h"
#import "SOGoCacheGCSFolder.h"
#undef DEBUG
#include <stdbool.h>
#include <talloc.h>
#include <util/time.h>
#include <mapistore/mapistore.h>
#include <mapistore/mapistore_errors.h>
#include <libmapiproxy.h>
#include <param.h>
//#include <stdbool.h>
//#include <talloc.h>
//#include <util/time.h>
//#include <mapistore/mapistore.h>
//#include <mapistore/mapistore_errors.h>
//#include <libmapiproxy.h>
//#include <param.h>
Class SOGoMAPIDBObjectK = Nil;
Class SOGoCacheGCSObjectK = Nil;
@implementation SOGoMAPIDBFolder
@implementation SOGoCacheGCSFolder
+ (void) initialize
{
SOGoMAPIDBObjectK = [SOGoMAPIDBObject class];
SOGoCacheGCSObjectK = [SOGoCacheGCSObject class];
}
- (id) init
@@ -77,7 +74,7 @@ Class SOGoMAPIDBObjectK = Nil;
if ((self = [super initWithName: name inContainer: newContainer]))
{
objectType = MAPIFolderCacheObject;
aclMessage = [SOGoMAPIDBObject objectWithName: @"permissions"
aclMessage = [SOGoCacheGCSObject objectWithName: @"permissions"
inContainer: self];
[aclMessage setObjectType: MAPIInternalCacheObject];
[aclMessage retain];
@@ -147,7 +144,7 @@ Class SOGoMAPIDBObjectK = Nil;
NSArray *records;
NSDictionary *record;
NSUInteger childPathPrefixLen, count, max;
SOGoMAPIDBObject *currentChild;
SOGoCacheGCSObject *currentChild;
/* query construction */
sql = [NSMutableString stringWithCapacity: 256];
@@ -181,7 +178,7 @@ Class SOGoMAPIDBObjectK = Nil;
{
if (qualifier)
{
currentChild = [SOGoMAPIDBObject objectWithName: childKey
currentChild = [SOGoCacheGCSObject objectWithName: childKey
inContainer: self];
[currentChild setupFromRecord: record];
if ([qualifier evaluateSOGoMAPIDBObject: currentChild])
@@ -361,7 +358,7 @@ Class SOGoMAPIDBObjectK = Nil;
if ([[record objectForKey: @"c_type"] intValue] == MAPIFolderCacheObject)
objectClass = isa;
else
objectClass = SOGoMAPIDBObjectK;
objectClass = SOGoCacheGCSObjectK;
object = [objectClass objectWithName: childName
inContainer: self];
@@ -378,7 +375,7 @@ Class SOGoMAPIDBObjectK = Nil;
{
id object;
object = [SOGoMAPIDBFolder objectWithName: folderName
object = [SOGoCacheGCSFolder objectWithName: folderName
inContainer: self];
[object reloadIfNeeded];
+7 -9
View File
@@ -1,8 +1,6 @@
/* SOGoMAPIDBObject.h - this file is part of SOGo
/* SOGoCacheGCSObject.h - this file is part of SOGo
*
* Copyright (C) 2012 Inverse inc
*
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
* Copyright (C) 2012-2014 Inverse inc
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,10 +18,10 @@
* Boston, MA 02111-1307, USA.
*/
#ifndef SOGOMAPIDBOBJECT_H
#define SOGOMAPIDBOBJECT_H
#ifndef SOGOCACHEGCSOBJECT_H
#define SOGOCACHEGCSOBJECT_H
#import "SOGoMAPIObject.h"
#import "SOGoCacheObject.h"
@class NSArray;
@class NSMutableDictionary;
@@ -40,7 +38,7 @@ typedef enum {
MAPIInternalCacheObject = 99 /* object = property list */
} SOGoCacheObjectType;
@interface SOGoMAPIDBObject : SOGoMAPIObject
@interface SOGoCacheGCSObject : SOGoCacheObject
{
NSURL *tableUrl;
@@ -82,4 +80,4 @@ typedef enum {
@end
#endif /* SOGOMAPIDBOBJECT_H */
#endif /* SOGOCACHEGCSOBJECT_H */
+7 -46
View File
@@ -1,8 +1,6 @@
/* SOGoMAPIDBObject.m - this file is part of SOGo
/* SOGoCacheGCSObject.m - this file is part of SOGo
*
* Copyright (C) 2012 Inverse inc
*
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
* Copyright (C) 2012-2014 Inverse inc
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -43,16 +41,16 @@
#import <SOGo/SOGoDomainDefaults.h>
#import <SOGo/SOGoUser.h>
#import "GCSSpecialQueries+OpenChange.h"
#import "MAPIStoreTypes.h"
#import "SOGoMAPIDBFolder.h"
#import "GCSSpecialQueries+SOGoCacheObject.h"
//#import "MAPIStoreTypes.h"
#import "SOGoCacheGCSFolder.h"
#import "BSONCodec.h"
#import "SOGoMAPIDBObject.h"
#import "SOGoCacheGCSObject.h"
static EOAttribute *textColumn = nil;
@implementation SOGoMAPIDBObject
@implementation SOGoCacheGCSObject
+ (void) initialize
{
@@ -221,43 +219,6 @@ static EOAttribute *textColumn = nil;
return deleted;
}
- (Class) mapistoreMessageClass
{
NSString *className, *mapiMsgClass;
switch (objectType)
{
case MAPIMessageCacheObject:
mapiMsgClass = [properties
objectForKey: MAPIPropertyKey (PidTagMessageClass)];
if (mapiMsgClass)
{
if ([mapiMsgClass isEqualToString: @"IPM.StickyNote"])
className = @"MAPIStoreNotesMessage";
else
className = @"MAPIStoreDBMessage";
//[self logWithFormat: @"PidTagMessageClass = '%@', returning '%@'",
// mapiMsgClass, className];
}
else
{
//[self warnWithFormat: @"PidTagMessageClass is not set, falling back"
// @" to 'MAPIStoreDBMessage'"];
className = @"MAPIStoreDBMessage";
}
break;
case MAPIFAICacheObject:
className = @"MAPIStoreFAIMessage";
break;
default:
[NSException raise: @"MAPIStoreIOException"
format: @"message class should not be queried for objects"
@" of type '%d'", objectType];
}
return NSClassFromString (className);
}
/* actions */
- (void) setNameInContainer: (NSString *) newNameInContainer
{
+6 -8
View File
@@ -1,8 +1,6 @@
/* SOGoMAPIObject.h - this file is part of SOGo
/* SOGoCacheObject.h - this file is part of SOGo
*
* Copyright (C) 2012 Inverse inc
*
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
* Copyright (C) 2012-2014 Inverse inc
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,14 +18,14 @@
* Boston, MA 02111-1307, USA.
*/
#ifndef SOGOMAPIOBJECT_H
#define SOGOMAPIOBJECT_H
#ifndef SOGOCACHEOBJECT_H
#define SOGOCACHEOBJECT_H
#import <SOGo/SOGoObject.h>
@class NSMutableDictionary;
@interface SOGoMAPIObject : SOGoObject
@interface SOGoCacheObject : SOGoObject
{
BOOL isNew;
NSMutableDictionary *properties;
@@ -46,4 +44,4 @@
@end
#endif /* SOGOMAPIOBJECT_H */
#endif /* SOGOCACHEOBJECT_H */
+4 -6
View File
@@ -1,8 +1,6 @@
/* SOGoMAPIObject.m - this file is part of SOGo
/* SOGoCacgeObject.m - this file is part of SOGo
*
* Copyright (C) 2012 Inverse inc
*
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
* Copyright (C) 2012-2014 Inverse inc
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -23,9 +21,9 @@
#import <Foundation/NSDictionary.h>
#import <Foundation/NSCalendarDate.h>
#import "SOGoMAPIObject.h"
#import "SOGoCacheObject.h"
@implementation SOGoMAPIObject
@implementation SOGoCacheObject
- (id) init
{