From bde743ed25166a0b320ae157bfb1d68064f531c9 Mon Sep 17 00:00:00 2001 From: Gil Date: Tue, 3 Oct 2017 08:55:22 -0700 Subject: Release 4.3.0 (#327) Initial release of Firestore at 0.8.0 Bump FirebaseCommunity to 0.1.3 --- Firestore/Source/Util/FSTAssert.h | 77 ++++++++++++ Firestore/Source/Util/FSTAsyncQueryListener.h | 48 +++++++ Firestore/Source/Util/FSTAsyncQueryListener.m | 50 ++++++++ Firestore/Source/Util/FSTClasses.h | 40 ++++++ Firestore/Source/Util/FSTComparison.h | 66 ++++++++++ Firestore/Source/Util/FSTComparison.m | 175 ++++++++++++++++++++++++++ Firestore/Source/Util/FSTDispatchQueue.h | 58 +++++++++ Firestore/Source/Util/FSTDispatchQueue.m | 75 +++++++++++ Firestore/Source/Util/FSTLogger.h | 34 +++++ Firestore/Source/Util/FSTLogger.m | 40 ++++++ Firestore/Source/Util/FSTUsageValidation.h | 45 +++++++ Firestore/Source/Util/FSTUsageValidation.m | 30 +++++ Firestore/Source/Util/FSTUtil.h | 31 +++++ Firestore/Source/Util/FSTUtil.m | 44 +++++++ 14 files changed, 813 insertions(+) create mode 100644 Firestore/Source/Util/FSTAssert.h create mode 100644 Firestore/Source/Util/FSTAsyncQueryListener.h create mode 100644 Firestore/Source/Util/FSTAsyncQueryListener.m create mode 100644 Firestore/Source/Util/FSTClasses.h create mode 100644 Firestore/Source/Util/FSTComparison.h create mode 100644 Firestore/Source/Util/FSTComparison.m create mode 100644 Firestore/Source/Util/FSTDispatchQueue.h create mode 100644 Firestore/Source/Util/FSTDispatchQueue.m create mode 100644 Firestore/Source/Util/FSTLogger.h create mode 100644 Firestore/Source/Util/FSTLogger.m create mode 100644 Firestore/Source/Util/FSTUsageValidation.h create mode 100644 Firestore/Source/Util/FSTUsageValidation.m create mode 100644 Firestore/Source/Util/FSTUtil.h create mode 100644 Firestore/Source/Util/FSTUtil.m (limited to 'Firestore/Source/Util') diff --git a/Firestore/Source/Util/FSTAssert.h b/Firestore/Source/Util/FSTAssert.h new file mode 100644 index 0000000..77bbb1d --- /dev/null +++ b/Firestore/Source/Util/FSTAssert.h @@ -0,0 +1,77 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +NS_ASSUME_NONNULL_BEGIN + +// Fails the current Objective-C method if the given condition is false. +// +// Unlike NSAssert, this macro is never compiled out if assertions are disabled. +#define FSTAssert(condition, format, ...) \ + do { \ + if (!(condition)) { \ + FSTFail((format), ##__VA_ARGS__); \ + } \ + } while (0) + +// Fails the current C function if the given condition is false. +// +// Unlike NSCAssert, this macro is never compiled out if assertions are disabled. +#define FSTCAssert(condition, format, ...) \ + do { \ + if (!(condition)) { \ + FSTCFail((format), ##__VA_ARGS__); \ + } \ + } while (0) + +// Unconditionally fails the current Objective-C method. +// +// This macro fails by calling [[NSAssertionHandler currentHandler] handleFailureInMethod]. It +// also calls abort(3) in order to make this macro appear to never return, even though the call +// to handleFailureInMethod itself never returns. +#define FSTFail(format, ...) \ + do { \ + NSString *_file = [NSString stringWithUTF8String:__FILE__]; \ + NSString *_description = [NSString stringWithFormat:(format), ##__VA_ARGS__]; \ + [[NSAssertionHandler currentHandler] \ + handleFailureInMethod:_cmd \ + object:self \ + file:_file \ + lineNumber:__LINE__ \ + description:@"FIRESTORE INTERNAL ASSERTION FAILED: %@", _description]; \ + abort(); \ + } while (0) + +// Unconditionally fails the current C function. +// +// This macro fails by calling [[NSAssertionHandler currentHandler] handleFailureInFunction]. It +// also calls abort(3) in order to make this macro appear to never return, even though the call +// to handleFailureInFunction itself never returns. +#define FSTCFail(format, ...) \ + do { \ + NSString *_file = [NSString stringWithUTF8String:__FILE__]; \ + NSString *_function = [NSString stringWithUTF8String:__PRETTY_FUNCTION__]; \ + NSString *_description = [NSString stringWithFormat:(format), ##__VA_ARGS__]; \ + [[NSAssertionHandler currentHandler] \ + handleFailureInFunction:_function \ + file:_file \ + lineNumber:__LINE__ \ + description:@"FIRESTORE INTERNAL ASSERTION FAILED: %@", _description]; \ + abort(); \ + } while (0) + +NS_ASSUME_NONNULL_END diff --git a/Firestore/Source/Util/FSTAsyncQueryListener.h b/Firestore/Source/Util/FSTAsyncQueryListener.h new file mode 100644 index 0000000..0ff1551 --- /dev/null +++ b/Firestore/Source/Util/FSTAsyncQueryListener.h @@ -0,0 +1,48 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +#import "FSTViewSnapshot.h" + +NS_ASSUME_NONNULL_BEGIN + +@class FSTDispatchQueue; +@class FSTQueryListener; + +/** + * A wrapper class around FSTQueryListener that dispatches events asynchronously. + */ +@interface FSTAsyncQueryListener : NSObject + +- (instancetype)initWithDispatchQueue:(FSTDispatchQueue *)dispatchQueue + snapshotHandler:(FSTViewSnapshotHandler)snapshotHandler + NS_DESIGNATED_INITIALIZER; + +- (instancetype)init NS_UNAVAILABLE; + +/** + * Synchronously mutes the listener and raise no further events. This method is thread safe can be + * called from any queue. + */ +- (void)mute; + +/** Creates an asynchronous version of the provided snapshot handler. */ +- (FSTViewSnapshotHandler)asyncSnapshotHandler; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Firestore/Source/Util/FSTAsyncQueryListener.m b/Firestore/Source/Util/FSTAsyncQueryListener.m new file mode 100644 index 0000000..31951e1 --- /dev/null +++ b/Firestore/Source/Util/FSTAsyncQueryListener.m @@ -0,0 +1,50 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FSTAsyncQueryListener.h" + +#import "FSTDispatchQueue.h" + +@implementation FSTAsyncQueryListener { + volatile BOOL _muted; + FSTViewSnapshotHandler _snapshotHandler; + FSTDispatchQueue *_dispatchQueue; +} + +- (instancetype)initWithDispatchQueue:(FSTDispatchQueue *)dispatchQueue + snapshotHandler:(FSTViewSnapshotHandler)snapshotHandler { + if (self = [super init]) { + _dispatchQueue = dispatchQueue; + _snapshotHandler = snapshotHandler; + } + return self; +} + +- (FSTViewSnapshotHandler)asyncSnapshotHandler { + return ^(FSTViewSnapshot *_Nullable snapshot, NSError *_Nullable error) { + [_dispatchQueue dispatchAsync:^{ + if (!_muted) { + _snapshotHandler(snapshot, error); + } + }]; + }; +} + +- (void)mute { + _muted = true; +} + +@end diff --git a/Firestore/Source/Util/FSTClasses.h b/Firestore/Source/Util/FSTClasses.h new file mode 100644 index 0000000..77dca12 --- /dev/null +++ b/Firestore/Source/Util/FSTClasses.h @@ -0,0 +1,40 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +NS_ASSUME_NONNULL_BEGIN + +// A convenience macro for unimplemented methods. Use as follows: +// +// @throw FSTAbstractMethodException(); // NOLINT +#define FSTAbstractMethodException() \ + [NSException exceptionWithName:NSInternalInconsistencyException \ + reason:[NSString stringWithFormat:@"You must override %s in a subclass", \ + __func__] \ + userInfo:nil]; + +// Declare a weak pointer to the given variable +#define FSTWeakify(var) __weak typeof(var) fstWeakPointerTo##var = var; + +// Declare a strong pointer to a variable that's been FSTWeakified. This creates a shadow of the +// original. +#define FSTStrongify(var) \ + _Pragma("clang diagnostic push") _Pragma("clang diagnostic ignored \"-Wshadow\"") \ + __strong typeof(var) var = fstWeakPointerTo##var; \ + _Pragma("clang diagnostic pop") + +NS_ASSUME_NONNULL_END diff --git a/Firestore/Source/Util/FSTComparison.h b/Firestore/Source/Util/FSTComparison.h new file mode 100644 index 0000000..e6e57e6 --- /dev/null +++ b/Firestore/Source/Util/FSTComparison.h @@ -0,0 +1,66 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** Compares two NSStrings. */ +NSComparisonResult FSTCompareStrings(NSString *left, NSString *right); + +/** Compares two BOOLs. */ +NSComparisonResult FSTCompareBools(BOOL left, BOOL right); + +/** Compares two integers. */ +NSComparisonResult FSTCompareInts(int left, int right); + +/** Compares two int32_t. */ +NSComparisonResult FSTCompareInt32s(int32_t left, int32_t right); + +/** Compares two int64_t. */ +NSComparisonResult FSTCompareInt64s(int64_t left, int64_t right); + +/** Compares two NSUIntegers. */ +NSComparisonResult FSTCompareUIntegers(NSUInteger left, NSUInteger right); + +/** Compares two doubles (using Firestore semantics for NaN). */ +NSComparisonResult FSTCompareDoubles(double left, double right); + +/** Compares a double and an int64_t. */ +NSComparisonResult FSTCompareMixed(double doubleValue, int64_t longValue); + +/** Compare two NSData byte sequences. */ +NSComparisonResult FSTCompareBytes(NSData *left, NSData *right); + +/** A simple NSComparator for comparing NSNumber instances. */ +extern const NSComparator FSTNumberComparator; + +/** A simple NSComparator for comparing NSString instances. */ +extern const NSComparator FSTStringComparator; + +/** + * Compares the bitwise representation of two doubles, but normalizes NaN values. This is + * similar to what the backend and android clients do, including comparing -0.0 as not equal to 0.0. + */ +BOOL FSTDoubleBitwiseEquals(double left, double right); + +/** + * Computes a bitwise hash of a double, but normalizes NaN values, suitable for use when using + * FSTDoublesAreBitwiseEqual for equality. + */ +NSUInteger FSTDoubleBitwiseHash(double d); + +NS_ASSUME_NONNULL_END diff --git a/Firestore/Source/Util/FSTComparison.m b/Firestore/Source/Util/FSTComparison.m new file mode 100644 index 0000000..e4f4ccb --- /dev/null +++ b/Firestore/Source/Util/FSTComparison.m @@ -0,0 +1,175 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FSTComparison.h" + +NS_ASSUME_NONNULL_BEGIN + +union DoubleBits { + double d; + uint64_t bits; +}; + +const NSComparator FSTNumberComparator = ^NSComparisonResult(NSNumber *left, NSNumber *right) { + return [left compare:right]; +}; + +const NSComparator FSTStringComparator = ^NSComparisonResult(NSString *left, NSString *right) { + return FSTCompareStrings(left, right); +}; + +NSComparisonResult FSTCompareStrings(NSString *left, NSString *right) { + // NOTE: NSLiteralSearch is necessary to compare the raw character codes. By default, + // precomposed characters are considered equivalent to their decomposed equivalents. + return [left compare:right options:NSLiteralSearch]; +} + +NSComparisonResult FSTCompareBools(BOOL left, BOOL right) { + if (!left) { + return right ? NSOrderedAscending : NSOrderedSame; + } else { + return right ? NSOrderedSame : NSOrderedDescending; + } +} + +NSComparisonResult FSTCompareInts(int left, int right) { + if (left > right) { + return NSOrderedDescending; + } + if (right > left) { + return NSOrderedAscending; + } + return NSOrderedSame; +} + +NSComparisonResult FSTCompareInt32s(int32_t left, int32_t right) { + if (left > right) { + return NSOrderedDescending; + } + if (right > left) { + return NSOrderedAscending; + } + return NSOrderedSame; +} + +NSComparisonResult FSTCompareInt64s(int64_t left, int64_t right) { + if (left > right) { + return NSOrderedDescending; + } + if (right > left) { + return NSOrderedAscending; + } + return NSOrderedSame; +} + +NSComparisonResult FSTCompareUIntegers(NSUInteger left, NSUInteger right) { + if (left > right) { + return NSOrderedDescending; + } + if (right > left) { + return NSOrderedAscending; + } + return NSOrderedSame; +} + +NSComparisonResult FSTCompareDoubles(double left, double right) { + // NaN sorts equal to itself and before any other number. + if (left < right) { + return NSOrderedAscending; + } else if (left > right) { + return NSOrderedDescending; + } else if (left == right) { + return NSOrderedSame; + } else { + // One or both left and right is NaN. + if (isnan(left)) { + return isnan(right) ? NSOrderedSame : NSOrderedAscending; + } else { + return NSOrderedDescending; + } + } +} + +static const double LONG_MIN_VALUE_AS_DOUBLE = (double)LLONG_MIN; +static const double LONG_MAX_VALUE_AS_DOUBLE = (double)LLONG_MAX; + +NSComparisonResult FSTCompareMixed(double doubleValue, int64_t longValue) { + // LLONG_MIN has an exact representation as double, so to check for a value outside the range + // representable by long, we have to check for strictly less than LLONG_MIN. Note that this also + // handles negative infinity. + if (doubleValue < LONG_MIN_VALUE_AS_DOUBLE) { + return NSOrderedAscending; + } + + // LLONG_MAX has no exact representation as double (casting as we've done makes 2^63, which is + // larger than LLONG_MAX), so consider any value greater than or equal to the threshold to be out + // of range. This also handles positive infinity. + if (doubleValue >= LONG_MAX_VALUE_AS_DOUBLE) { + return NSOrderedDescending; + } + + // In Firestore NaN is defined to compare before all other numbers. + if (isnan(doubleValue)) { + return NSOrderedAscending; + } + + int64_t doubleAsLong = (int64_t)doubleValue; + NSComparisonResult cmp = FSTCompareInt64s(doubleAsLong, longValue); + if (cmp != NSOrderedSame) { + return cmp; + } + + // At this point the long representations are equal but this could be due to rounding. + double longAsDouble = (double)longValue; + return FSTCompareDoubles(doubleValue, longAsDouble); +} + +NSComparisonResult FSTCompareBytes(NSData *left, NSData *right) { + NSUInteger minLength = MIN(left.length, right.length); + int result = memcmp(left.bytes, right.bytes, minLength); + if (result < 0) { + return NSOrderedAscending; + } else if (result > 0) { + return NSOrderedDescending; + } else if (left.length < right.length) { + return NSOrderedAscending; + } else if (left.length > right.length) { + return NSOrderedDescending; + } else { + return NSOrderedSame; + } +} + +/** Helper to normalize a double and then return the raw bits as a uint64_t. */ +uint64_t FSTDoubleBits(double d) { + if (isnan(d)) { + d = NAN; + } + union DoubleBits converter = {.d = d}; + return converter.bits; +} + +BOOL FSTDoubleBitwiseEquals(double left, double right) { + return FSTDoubleBits(left) == FSTDoubleBits(right); +} + +NSUInteger FSTDoubleBitwiseHash(double d) { + uint64_t bits = FSTDoubleBits(d); + // Note that x ^ (x >> 32) works fine for both 32 and 64 bit definitions of NSUInteger + return (((NSUInteger)bits) ^ (NSUInteger)(bits >> 32)); +} + +NS_ASSUME_NONNULL_END diff --git a/Firestore/Source/Util/FSTDispatchQueue.h b/Firestore/Source/Util/FSTDispatchQueue.h new file mode 100644 index 0000000..da6b3fe --- /dev/null +++ b/Firestore/Source/Util/FSTDispatchQueue.h @@ -0,0 +1,58 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface FSTDispatchQueue : NSObject + +/** Creates and returns an FSTDispatchQueue wrapping the specified dispatch_queue_t. */ ++ (instancetype)queueWith:(dispatch_queue_t)dispatchQueue; + +- (instancetype)init __attribute__((unavailable("Use static constructor method."))); + +/** + * Asserts that we are already running on this queue (actually, we can only verify that the + * queue's label is the same, but hopefully that's good enough.) + */ +- (void)verifyIsCurrentQueue; + +/** + * Same as dispatch_async() except it asserts that we're not already on the queue, since this + * generally indicates a bug (and can lead to re-ordering of operations, etc). + * + * @param block The block to run. + */ +- (void)dispatchAsync:(void (^)())block; + +/** + * Unlike dispatchAsync: this method does not require you to dispatch to a different queue than + * the current one (thus it is equivalent to a raw dispatch_async()). + * + * This is useful, e.g. for dispatching to the user's queue directly from user API call (in which + * case we don't know if we're already on the user's queue or not). + * + * @param block The block to run. + */ +- (void)dispatchAsyncAllowingSameQueue:(void (^)())block; + +/** The underlying wrapped dispatch_queue_t */ +@property(nonatomic, strong, readonly) dispatch_queue_t queue; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Firestore/Source/Util/FSTDispatchQueue.m b/Firestore/Source/Util/FSTDispatchQueue.m new file mode 100644 index 0000000..8d55d28 --- /dev/null +++ b/Firestore/Source/Util/FSTDispatchQueue.m @@ -0,0 +1,75 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +#import "FSTAssert.h" +#import "FSTDispatchQueue.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface FSTDispatchQueue () +- (instancetype)initWithQueue:(dispatch_queue_t)queue NS_DESIGNATED_INITIALIZER; +@end + +@implementation FSTDispatchQueue + ++ (instancetype)queueWith:(dispatch_queue_t)dispatchQueue { + return [[FSTDispatchQueue alloc] initWithQueue:dispatchQueue]; +} + +- (instancetype)initWithQueue:(dispatch_queue_t)queue { + if (self = [super init]) { + _queue = queue; + } + return self; +} + +- (void)verifyIsCurrentQueue { + FSTAssert([self onTargetQueue], + @"We are running on the wrong dispatch queue. Expected '%@' Actual: '%@'", + [self targetQueueLabel], [self currentQueueLabel]); +} + +- (void)dispatchAsync:(void (^)())block { + FSTAssert(![self onTargetQueue], + @"dispatchAsync called when we are already running on target dispatch queue '%@'", + [self targetQueueLabel]); + + dispatch_async(self.queue, block); +} + +- (void)dispatchAsyncAllowingSameQueue:(void (^)())block { + dispatch_async(self.queue, block); +} + +#pragma mark - Private Methods + +- (NSString *)currentQueueLabel { + return [NSString stringWithUTF8String:dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL)]; +} + +- (NSString *)targetQueueLabel { + return [NSString stringWithUTF8String:dispatch_queue_get_label(self.queue)]; +} + +- (BOOL)onTargetQueue { + return [[self currentQueueLabel] isEqualToString:[self targetQueueLabel]]; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Firestore/Source/Util/FSTLogger.h b/Firestore/Source/Util/FSTLogger.h new file mode 100644 index 0000000..699570a --- /dev/null +++ b/Firestore/Source/Util/FSTLogger.h @@ -0,0 +1,34 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +NS_ASSUME_NONNULL_BEGIN + +#ifdef __cplusplus +extern "C" { +#endif + +/** Logs to NSLog if [FIRFirestore isLoggingEnabled] is YES. */ +void FSTLog(NSString *format, ...) NS_FORMAT_FUNCTION(1, 2); + +void FSTWarn(NSString *format, ...) NS_FORMAT_FUNCTION(1, 2); + +#ifdef __cplusplus +} // extern "C" +#endif + +NS_ASSUME_NONNULL_END diff --git a/Firestore/Source/Util/FSTLogger.m b/Firestore/Source/Util/FSTLogger.m new file mode 100644 index 0000000..396c788 --- /dev/null +++ b/Firestore/Source/Util/FSTLogger.m @@ -0,0 +1,40 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FSTLogger.h" + +#import "FIRFirestore+Internal.h" +#import "FIRLogger.h" + +NS_ASSUME_NONNULL_BEGIN + +void FSTLog(NSString *format, ...) { + if ([FIRFirestore isLoggingEnabled]) { + va_list args; + va_start(args, format); + FIRLogBasic(FIRLoggerLevelDebug, kFIRLoggerFirestore, @"I-FST000001", format, args); + va_end(args); + } +} + +void FSTWarn(NSString *format, ...) { + va_list args; + va_start(args, format); + FIRLogBasic(FIRLoggerLevelWarning, kFIRLoggerFirestore, @"I-FST000001", format, args); + va_end(args); +} + +NS_ASSUME_NONNULL_END diff --git a/Firestore/Source/Util/FSTUsageValidation.h b/Firestore/Source/Util/FSTUsageValidation.h new file mode 100644 index 0000000..a80dafa --- /dev/null +++ b/Firestore/Source/Util/FSTUsageValidation.h @@ -0,0 +1,45 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +NS_ASSUME_NONNULL_BEGIN + +/** Helper for creating a general exception for invalid usage of an API. */ +NSException *FSTInvalidUsage(NSString *exceptionName, NSString *format, ...); + +/** + * Macro to throw exceptions in response to API usage errors. Avoids the lint warning you usually + * get when using @throw and (unlike a function) doesn't trigger warnings about not all codepaths + * returning a value. + * + * Exceptions should only be used for programmer errors made by consumers of the SDK, e.g. + * invalid method arguments. + * + * For recoverable runtime errors, use NSError**. + * For internal programming errors, use FSTFail(). + */ +#define FSTThrowInvalidUsage(exceptionName, format, ...) \ + do { \ + @throw FSTInvalidUsage(exceptionName, format, ##__VA_ARGS__); \ + } while (0) + +#define FSTThrowInvalidArgument(format, ...) \ + do { \ + @throw FSTInvalidUsage(@"FIRInvalidArgumentException", format, ##__VA_ARGS__); \ + } while (0) + +NS_ASSUME_NONNULL_END diff --git a/Firestore/Source/Util/FSTUsageValidation.m b/Firestore/Source/Util/FSTUsageValidation.m new file mode 100644 index 0000000..82128f4 --- /dev/null +++ b/Firestore/Source/Util/FSTUsageValidation.m @@ -0,0 +1,30 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +NS_ASSUME_NONNULL_BEGIN + +NSException *FSTInvalidUsage(NSString *exceptionName, NSString *format, ...) { + va_list arg_list; + va_start(arg_list, format); + NSString *formattedString = [[NSString alloc] initWithFormat:format arguments:arg_list]; + va_end(arg_list); + + return [[NSException alloc] initWithName:exceptionName reason:formattedString userInfo:nil]; +} + +NS_ASSUME_NONNULL_END diff --git a/Firestore/Source/Util/FSTUtil.h b/Firestore/Source/Util/FSTUtil.h new file mode 100644 index 0000000..3985d10 --- /dev/null +++ b/Firestore/Source/Util/FSTUtil.h @@ -0,0 +1,31 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface FSTUtil : NSObject + +/** Generates a random double between 0 and 1. */ ++ (double)randomDouble; + +/** Generates a random ID suitable for use as a document ID. */ ++ (NSString *)autoID; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Firestore/Source/Util/FSTUtil.m b/Firestore/Source/Util/FSTUtil.m new file mode 100644 index 0000000..d14c429 --- /dev/null +++ b/Firestore/Source/Util/FSTUtil.m @@ -0,0 +1,44 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FSTUtil.h" + +NS_ASSUME_NONNULL_BEGIN + +static const double kArc4RandomMax = 0x100000000; + +static const int kAutoIDLength = 20; +static NSString *const kAutoIDAlphabet = + @"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + +@implementation FSTUtil + ++ (double)randomDouble { + return ((double)arc4random() / kArc4RandomMax); +} + ++ (NSString *)autoID { + unichar autoID[kAutoIDLength]; + for (int i = 0; i < kAutoIDLength; i++) { + uint32_t randIndex = arc4random_uniform((uint32_t)kAutoIDAlphabet.length); + autoID[i] = [kAutoIDAlphabet characterAtIndex:randIndex]; + } + return [NSString stringWithCharacters:autoID length:kAutoIDLength]; +} + +@end + +NS_ASSUME_NONNULL_END -- cgit v1.2.3