You've already forked FinalYearProject-MyMind
mirror of
https://github.com/MrLyallCSIT/FinalYearProject-MyMind.git
synced 2026-01-18 07:09:41 +00:00
App Completed
Basic Prototype App Completed. Proposal, Literature Review and Final Report to Follow.
This commit is contained in:
100
My Mind/Pods/GoogleToolboxForMac/DebugUtils/GTMDebugSelectorValidation.h
generated
Normal file
100
My Mind/Pods/GoogleToolboxForMac/DebugUtils/GTMDebugSelectorValidation.h
generated
Normal file
@@ -0,0 +1,100 @@
|
||||
//
|
||||
// GTMDebugSelectorValidation.h
|
||||
//
|
||||
// This file should only be included within an implimation file. In any
|
||||
// function that takes an object and selector to invoke, you should call:
|
||||
//
|
||||
// GTMAssertSelectorNilOrImplementedWithArguments(obj, sel, @encode(arg1type), ..., NULL)
|
||||
// or
|
||||
// GTMAssertSelectorNilOrImplementedWithReturnTypeAndArguments(obj, sel, @encode(returnType), @encode(arg1type), ..., NULL)
|
||||
//
|
||||
// This will then validate that the selector is defined and using the right
|
||||
// type(s), this can help catch errors much earlier then waiting for the
|
||||
// selector to actually fire (and in the case of error selectors, might never
|
||||
// really be tested until in the field).
|
||||
//
|
||||
// Copyright 2007-2008 Google Inc.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
#if DEBUG
|
||||
|
||||
#import <stdarg.h>
|
||||
#import "GTMDefines.h"
|
||||
|
||||
static void GTMAssertSelectorNilOrImplementedWithReturnTypeAndArguments(id obj, SEL sel, const char *retType, ...) {
|
||||
|
||||
// verify that the object's selector is implemented with the proper
|
||||
// number and type of arguments
|
||||
va_list argList;
|
||||
va_start(argList, retType);
|
||||
|
||||
if (obj && sel) {
|
||||
// check that the selector is implemented
|
||||
_GTMDevAssert([obj respondsToSelector:sel],
|
||||
@"\"%@\" selector \"%@\" is unimplemented or misnamed",
|
||||
NSStringFromClass([obj class]),
|
||||
NSStringFromSelector(sel));
|
||||
|
||||
const char *expectedArgType;
|
||||
NSUInteger argCount = 2; // skip self and _cmd
|
||||
NSMethodSignature *sig = [obj methodSignatureForSelector:sel];
|
||||
|
||||
// check that each expected argument is present and of the correct type
|
||||
while ((expectedArgType = va_arg(argList, const char*)) != 0) {
|
||||
|
||||
if ([sig numberOfArguments] > argCount) {
|
||||
const char *foundArgType = [sig getArgumentTypeAtIndex:argCount];
|
||||
|
||||
_GTMDevAssert(0 == strncmp(foundArgType, expectedArgType, strlen(expectedArgType)),
|
||||
@"\"%@\" selector \"%@\" argument %u should be type %s",
|
||||
NSStringFromClass([obj class]),
|
||||
NSStringFromSelector(sel),
|
||||
(uint32_t)(argCount - 2),
|
||||
expectedArgType);
|
||||
}
|
||||
argCount++;
|
||||
}
|
||||
|
||||
// check that the proper number of arguments are present in the selector
|
||||
_GTMDevAssert(argCount == [sig numberOfArguments],
|
||||
@"\"%@\" selector \"%@\" should have %u arguments",
|
||||
NSStringFromClass([obj class]),
|
||||
NSStringFromSelector(sel),
|
||||
(uint32_t)(argCount - 2));
|
||||
|
||||
// if asked, validate the return type
|
||||
if (retType && (strcmp("gtm_skip_return_test", retType) != 0)) {
|
||||
const char *foundRetType = [sig methodReturnType];
|
||||
_GTMDevAssert(0 == strncmp(foundRetType, retType, strlen(retType)),
|
||||
@"\"%@\" selector \"%@\" return type should be type %s",
|
||||
NSStringFromClass([obj class]),
|
||||
NSStringFromSelector(sel),
|
||||
retType);
|
||||
}
|
||||
}
|
||||
|
||||
va_end(argList);
|
||||
}
|
||||
|
||||
#define GTMAssertSelectorNilOrImplementedWithArguments(obj, sel, ...) \
|
||||
GTMAssertSelectorNilOrImplementedWithReturnTypeAndArguments((obj), (sel), "gtm_skip_return_test", __VA_ARGS__)
|
||||
|
||||
#else // DEBUG
|
||||
|
||||
// make it go away if not debug
|
||||
#define GTMAssertSelectorNilOrImplementedWithReturnTypeAndArguments(obj, sel, retType, ...) do { } while (0)
|
||||
#define GTMAssertSelectorNilOrImplementedWithArguments(obj, sel, ...) do { } while (0)
|
||||
|
||||
#endif // DEBUG
|
||||
44
My Mind/Pods/GoogleToolboxForMac/DebugUtils/GTMDebugThreadValidation.h
generated
Normal file
44
My Mind/Pods/GoogleToolboxForMac/DebugUtils/GTMDebugThreadValidation.h
generated
Normal file
@@ -0,0 +1,44 @@
|
||||
//
|
||||
// GTMDebugThreadValidation.h
|
||||
//
|
||||
// Copyright 2016 Google Inc.
|
||||
//
|
||||
// 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 "GTMDefines.h"
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
// GTMCheckCurrentQueue, GTMIsCurrentQueue
|
||||
//
|
||||
// GTMCheckCurrentQueue takes a target queue and uses _GTMDevAssert to
|
||||
// report if that is not the currently executing queue.
|
||||
//
|
||||
// GTMIsCurrentQueue takes a target queue and returns true if the target queue
|
||||
// is the currently executing dispatch queue. This can be passed to another
|
||||
// assertion call in debug builds; it should never be used in release code.
|
||||
//
|
||||
// The dispatch queue must have a label.
|
||||
#define GTMCheckCurrentQueue(targetQueue) \
|
||||
_GTMDevAssert(GTMIsCurrentQueue(targetQueue), \
|
||||
@"Current queue is %s (expected %s)", \
|
||||
_GTMQueueName(DISPATCH_CURRENT_QUEUE_LABEL), \
|
||||
_GTMQueueName(targetQueue))
|
||||
|
||||
#define GTMIsCurrentQueue(targetQueue) \
|
||||
(strcmp(_GTMQueueName(DISPATCH_CURRENT_QUEUE_LABEL), \
|
||||
_GTMQueueName(targetQueue)) == 0)
|
||||
|
||||
#define _GTMQueueName(queue) \
|
||||
(strlen(dispatch_queue_get_label(queue)) > 0 ? \
|
||||
dispatch_queue_get_label(queue) : "unnamed")
|
||||
69
My Mind/Pods/GoogleToolboxForMac/DebugUtils/GTMMethodCheck.h
generated
Normal file
69
My Mind/Pods/GoogleToolboxForMac/DebugUtils/GTMMethodCheck.h
generated
Normal file
@@ -0,0 +1,69 @@
|
||||
//
|
||||
// GTMMethodCheck.h
|
||||
//
|
||||
// Copyright 2006-2016 Google Inc.
|
||||
//
|
||||
// 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 <Foundation/Foundation.h>
|
||||
#import <stdio.h>
|
||||
#import <sysexits.h>
|
||||
|
||||
/// A macro for enforcing debug time checks to make sure all required methods are linked in
|
||||
//
|
||||
// When using categories, it can be very easy to forget to include the
|
||||
// implementation of a category.
|
||||
// Let's say you had a class foo that depended on method bar of class baz, and
|
||||
// method bar was implemented as a member of a category.
|
||||
// You could add the following code:
|
||||
//
|
||||
// GTM_METHOD_CHECK(baz, bar)
|
||||
//
|
||||
// and the code would check to make sure baz was implemented just before main
|
||||
// was called. This works for both dynamic libraries, and executables.
|
||||
//
|
||||
//
|
||||
// This is not compiled into release builds.
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
// This is the "magic".
|
||||
// A) we need a multi layer define here so that the preprocessor expands
|
||||
// __LINE__ the way we want it. We need __LINE__ so that each of our
|
||||
// GTM_METHOD_CHECKs generates a unique function name.
|
||||
#define GTM_METHOD_CHECK(class, method) GTM_METHOD_CHECK_INNER(class, method, __LINE__)
|
||||
#define GTM_METHOD_CHECK_INNER(class, method, line) \
|
||||
GTM_METHOD_CHECK_INNER_INNER(class, method, line)
|
||||
|
||||
// B) define a function that is called at startup to check that |class| has an
|
||||
// implementation for |method| (either a class method or an instance method).
|
||||
#define GTM_METHOD_CHECK_INNER_INNER(class, method, line) \
|
||||
__attribute__ ((constructor, visibility("hidden"))) \
|
||||
static void xxGTMMethodCheckMethod ## class ## line () { \
|
||||
@autoreleasepool { \
|
||||
if (![class instancesRespondToSelector:@selector(method)] \
|
||||
&& ![class respondsToSelector:@selector(method)]) { \
|
||||
fprintf(stderr, "%s:%d: error: We need method '%s' to be linked in for class '%s'\n", \
|
||||
__FILE__, line, #method, #class); \
|
||||
exit(EX_SOFTWARE); \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
#else // DEBUG
|
||||
|
||||
// Do nothing in release.
|
||||
#define GTM_METHOD_CHECK(class, method)
|
||||
|
||||
#endif // DEBUG
|
||||
508
My Mind/Pods/GoogleToolboxForMac/Foundation/GTMLogger.h
generated
Normal file
508
My Mind/Pods/GoogleToolboxForMac/Foundation/GTMLogger.h
generated
Normal file
@@ -0,0 +1,508 @@
|
||||
//
|
||||
// GTMLogger.h
|
||||
//
|
||||
// Copyright 2007-2008 Google Inc.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
// Key Abstractions
|
||||
// ----------------
|
||||
//
|
||||
// This file declares multiple classes and protocols that are used by the
|
||||
// GTMLogger logging system. The 4 main abstractions used in this file are the
|
||||
// following:
|
||||
//
|
||||
// * logger (GTMLogger) - The main logging class that users interact with. It
|
||||
// has methods for logging at different levels and uses a log writer, a log
|
||||
// formatter, and a log filter to get the job done.
|
||||
//
|
||||
// * log writer (GTMLogWriter) - Writes a given string to some log file, where
|
||||
// a "log file" can be a physical file on disk, a POST over HTTP to some URL,
|
||||
// or even some in-memory structure (e.g., a ring buffer).
|
||||
//
|
||||
// * log formatter (GTMLogFormatter) - Given a format string and arguments as
|
||||
// a va_list, returns a single formatted NSString. A "formatted string" could
|
||||
// be a string with the date prepended, a string with values in a CSV format,
|
||||
// or even a string of XML.
|
||||
//
|
||||
// * log filter (GTMLogFilter) - Given a formatted log message as an NSString
|
||||
// and the level at which the message is to be logged, this class will decide
|
||||
// whether the given message should be logged or not. This is a flexible way
|
||||
// to filter out messages logged at a certain level, messages that contain
|
||||
// certain text, or filter nothing out at all. This gives the caller the
|
||||
// flexibility to dynamically enable debug logging in Release builds.
|
||||
//
|
||||
// This file also declares some classes to handle the common log writer, log
|
||||
// formatter, and log filter cases. Callers can also create their own writers,
|
||||
// formatters, and filters and they can even build them on top of the ones
|
||||
// declared here. Keep in mind that your custom writer/formatter/filter may be
|
||||
// called from multiple threads, so it must be thread-safe.
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "GTMDefines.h"
|
||||
|
||||
// Predeclaration of used protocols that are declared later in this file.
|
||||
@protocol GTMLogWriter, GTMLogFormatter, GTMLogFilter;
|
||||
|
||||
// GTMLogger
|
||||
//
|
||||
// GTMLogger is the primary user-facing class for an object-oriented logging
|
||||
// system. It is built on the concept of log formatters (GTMLogFormatter), log
|
||||
// writers (GTMLogWriter), and log filters (GTMLogFilter). When a message is
|
||||
// sent to a GTMLogger to log a message, the message is formatted using the log
|
||||
// formatter, then the log filter is consulted to see if the message should be
|
||||
// logged, and if so, the message is sent to the log writer to be written out.
|
||||
//
|
||||
// GTMLogger is intended to be a flexible and thread-safe logging solution. Its
|
||||
// flexibility comes from the fact that GTMLogger instances can be customized
|
||||
// with user defined formatters, filters, and writers. And these writers,
|
||||
// filters, and formatters can be combined, stacked, and customized in arbitrary
|
||||
// ways to suit the needs at hand. For example, multiple writers can be used at
|
||||
// the same time, and a GTMLogger instance can even be used as another
|
||||
// GTMLogger's writer. This allows for arbitrarily deep logging trees.
|
||||
//
|
||||
// A standard GTMLogger uses a writer that sends messages to standard out, a
|
||||
// formatter that smacks a timestamp and a few other bits of interesting
|
||||
// information on the message, and a filter that filters out debug messages from
|
||||
// release builds. Using the standard log settings, a log message will look like
|
||||
// the following:
|
||||
//
|
||||
// 2007-12-30 10:29:24.177 myapp[4588/0xa07d0f60] [lvl=1] foo=<Foo: 0x123>
|
||||
//
|
||||
// The output contains the date and time of the log message, the name of the
|
||||
// process followed by its process ID/thread ID, the log level at which the
|
||||
// message was logged (in the previous example the level was 1:
|
||||
// kGTMLoggerLevelDebug), and finally, the user-specified log message itself (in
|
||||
// this case, the log message was @"foo=%@", foo).
|
||||
//
|
||||
// Multiple instances of GTMLogger can be created, each configured their own
|
||||
// way. Though GTMLogger is not a singleton (in the GoF sense), it does provide
|
||||
// access to a shared (i.e., globally accessible) GTMLogger instance. This makes
|
||||
// it convenient for all code in a process to use the same GTMLogger instance.
|
||||
// The shared GTMLogger instance can also be configured in an arbitrary, and
|
||||
// these configuration changes will affect all code that logs through the shared
|
||||
// instance.
|
||||
|
||||
//
|
||||
// Log Levels
|
||||
// ----------
|
||||
// GTMLogger has 3 different log levels: Debug, Info, and Error. GTMLogger
|
||||
// doesn't take any special action based on the log level; it simply forwards
|
||||
// this information on to formatters, filters, and writers, each of which may
|
||||
// optionally take action based on the level. Since log level filtering is
|
||||
// performed at runtime, log messages are typically not filtered out at compile
|
||||
// time. The exception to this rule is that calls to the GTMLoggerDebug() macro
|
||||
// *ARE* filtered out of non-DEBUG builds. This is to be backwards compatible
|
||||
// with behavior that many developers are currently used to. Note that this
|
||||
// means that GTMLoggerDebug(@"hi") will be compiled out of Release builds, but
|
||||
// [[GTMLogger sharedLogger] logDebug:@"hi"] will NOT be compiled out.
|
||||
//
|
||||
// Standard loggers are created with the GTMLogLevelFilter log filter, which
|
||||
// filters out certain log messages based on log level, and some other settings.
|
||||
//
|
||||
// In addition to the -logDebug:, -logInfo:, and -logError: methods defined on
|
||||
// GTMLogger itself, there are also C macros that make usage of the shared
|
||||
// GTMLogger instance very convenient. These macros are:
|
||||
//
|
||||
// GTMLoggerDebug(...)
|
||||
// GTMLoggerInfo(...)
|
||||
// GTMLoggerError(...)
|
||||
//
|
||||
// Again, a notable feature of these macros is that GTMLogDebug() calls *will be
|
||||
// compiled out of non-DEBUG builds*.
|
||||
//
|
||||
// Standard Loggers
|
||||
// ----------------
|
||||
// GTMLogger has the concept of "standard loggers". A standard logger is simply
|
||||
// a logger that is pre-configured with some standard/common writer, formatter,
|
||||
// and filter combination. Standard loggers are created using the creation
|
||||
// methods beginning with "standard". The alternative to a standard logger is a
|
||||
// regular logger, which will send messages to stdout, with no special
|
||||
// formatting, and no filtering.
|
||||
//
|
||||
// How do I use GTMLogger?
|
||||
// ----------------------
|
||||
// The typical way you will want to use GTMLogger is to simply use the
|
||||
// GTMLogger*() macros for logging from code. That way we can easily make
|
||||
// changes to the GTMLogger class and simply update the macros accordingly. Only
|
||||
// your application startup code (perhaps, somewhere in main()) should use the
|
||||
// GTMLogger class directly in order to configure the shared logger, which all
|
||||
// of the code using the macros will be using. Again, this is just the typical
|
||||
// situation.
|
||||
//
|
||||
// To be complete, there are cases where you may want to use GTMLogger directly,
|
||||
// or even create separate GTMLogger instances for some reason. That's fine,
|
||||
// too.
|
||||
//
|
||||
// Examples
|
||||
// --------
|
||||
// The following show some common GTMLogger use cases.
|
||||
//
|
||||
// 1. You want to log something as simply as possible. Also, this call will only
|
||||
// appear in debug builds. In non-DEBUG builds it will be completely removed.
|
||||
//
|
||||
// GTMLoggerDebug(@"foo = %@", foo);
|
||||
//
|
||||
// 2. The previous example is similar to the following. The major difference is
|
||||
// that the previous call (example 1) will be compiled out of Release builds
|
||||
// but this statement will not be compiled out.
|
||||
//
|
||||
// [[GTMLogger sharedLogger] logDebug:@"foo = %@", foo];
|
||||
//
|
||||
// 3. Send all logging output from the shared logger to a file. We do this by
|
||||
// creating an NSFileHandle for writing associated with a file, and setting
|
||||
// that file handle as the logger's writer.
|
||||
//
|
||||
// NSFileHandle *f = [NSFileHandle fileHandleForWritingAtPath:@"/tmp/f.log"
|
||||
// create:YES];
|
||||
// [[GTMLogger sharedLogger] setWriter:f];
|
||||
// GTMLoggerError(@"hi"); // This will be sent to /tmp/f.log
|
||||
//
|
||||
// 4. Create a new GTMLogger that will log to a file. This example differs from
|
||||
// the previous one because here we create a new GTMLogger that is different
|
||||
// from the shared logger.
|
||||
//
|
||||
// GTMLogger *logger = [GTMLogger standardLoggerWithPath:@"/tmp/temp.log"];
|
||||
// [logger logInfo:@"hi temp log file"];
|
||||
//
|
||||
// 5. Create a logger that writes to stdout and does NOT do any formatting to
|
||||
// the log message. This might be useful, for example, when writing a help
|
||||
// screen for a command-line tool to standard output.
|
||||
//
|
||||
// GTMLogger *logger = [GTMLogger logger];
|
||||
// [logger logInfo:@"%@ version 0.1 usage", progName];
|
||||
//
|
||||
// 6. Send log output to stdout AND to a log file. The trick here is that
|
||||
// NSArrays function as composite log writers, which means when an array is
|
||||
// set as the log writer, it forwards all logging messages to all of its
|
||||
// contained GTMLogWriters.
|
||||
//
|
||||
// // Create array of GTMLogWriters
|
||||
// NSArray *writers = [NSArray arrayWithObjects:
|
||||
// [NSFileHandle fileHandleForWritingAtPath:@"/tmp/f.log" create:YES],
|
||||
// [NSFileHandle fileHandleWithStandardOutput], nil];
|
||||
//
|
||||
// GTMLogger *logger = [GTMLogger standardLogger];
|
||||
// [logger setWriter:writers];
|
||||
// [logger logInfo:@"hi"]; // Output goes to stdout and /tmp/f.log
|
||||
//
|
||||
// For futher details on log writers, formatters, and filters, see the
|
||||
// documentation below.
|
||||
//
|
||||
// NOTE: GTMLogger is application level logging. By default it does nothing
|
||||
// with _GTMDevLog/_GTMDevAssert (see GTMDefines.h). An application can choose
|
||||
// to bridge _GTMDevLog/_GTMDevAssert to GTMLogger by providing macro
|
||||
// definitions in its prefix header (see GTMDefines.h for how one would do
|
||||
// that).
|
||||
//
|
||||
@interface GTMLogger : NSObject {
|
||||
@private
|
||||
id<GTMLogWriter> writer_;
|
||||
id<GTMLogFormatter> formatter_;
|
||||
id<GTMLogFilter> filter_;
|
||||
}
|
||||
|
||||
//
|
||||
// Accessors for the shared logger instance
|
||||
//
|
||||
|
||||
// Returns a shared/global standard GTMLogger instance. Callers should typically
|
||||
// use this method to get a GTMLogger instance, unless they explicitly want
|
||||
// their own instance to configure for their own needs. This is the only method
|
||||
// that returns a shared instance; all the rest return new GTMLogger instances.
|
||||
+ (id)sharedLogger;
|
||||
|
||||
// Sets the shared logger instance to |logger|. Future calls to +sharedLogger
|
||||
// will return |logger| instead.
|
||||
+ (void)setSharedLogger:(GTMLogger *)logger;
|
||||
|
||||
//
|
||||
// Creation methods
|
||||
//
|
||||
|
||||
// Returns a new autoreleased GTMLogger instance that will log to stdout, using
|
||||
// the GTMLogStandardFormatter, and the GTMLogLevelFilter filter.
|
||||
+ (id)standardLogger;
|
||||
|
||||
// Same as +standardLogger, but logs to stderr.
|
||||
+ (id)standardLoggerWithStderr;
|
||||
|
||||
// Same as +standardLogger but levels >= kGTMLoggerLevelError are routed to
|
||||
// stderr, everything else goes to stdout.
|
||||
+ (id)standardLoggerWithStdoutAndStderr;
|
||||
|
||||
// Returns a new standard GTMLogger instance with a log writer that will
|
||||
// write to the file at |path|, and will use the GTMLogStandardFormatter and
|
||||
// GTMLogLevelFilter classes. If |path| does not exist, it will be created.
|
||||
+ (id)standardLoggerWithPath:(NSString *)path;
|
||||
|
||||
// Returns an autoreleased GTMLogger instance that will use the specified
|
||||
// |writer|, |formatter|, and |filter|.
|
||||
+ (id)loggerWithWriter:(id<GTMLogWriter>)writer
|
||||
formatter:(id<GTMLogFormatter>)formatter
|
||||
filter:(id<GTMLogFilter>)filter;
|
||||
|
||||
// Returns an autoreleased GTMLogger instance that logs to stdout, with the
|
||||
// basic formatter, and no filter. The returned logger differs from the logger
|
||||
// returned by +standardLogger because this one does not do any filtering and
|
||||
// does not do any special log formatting; this is the difference between a
|
||||
// "regular" logger and a "standard" logger.
|
||||
+ (id)logger;
|
||||
|
||||
// Designated initializer. This method returns a GTMLogger initialized with the
|
||||
// specified |writer|, |formatter|, and |filter|. See the setter methods below
|
||||
// for what values will be used if nil is passed for a parameter.
|
||||
- (id)initWithWriter:(id<GTMLogWriter>)writer
|
||||
formatter:(id<GTMLogFormatter>)formatter
|
||||
filter:(id<GTMLogFilter>)filter;
|
||||
|
||||
//
|
||||
// Logging methods
|
||||
//
|
||||
|
||||
// Logs a message at the debug level (kGTMLoggerLevelDebug).
|
||||
- (void)logDebug:(NSString *)fmt, ... NS_FORMAT_FUNCTION(1, 2);
|
||||
// Logs a message at the info level (kGTMLoggerLevelInfo).
|
||||
- (void)logInfo:(NSString *)fmt, ... NS_FORMAT_FUNCTION(1, 2);
|
||||
// Logs a message at the error level (kGTMLoggerLevelError).
|
||||
- (void)logError:(NSString *)fmt, ... NS_FORMAT_FUNCTION(1, 2);
|
||||
// Logs a message at the assert level (kGTMLoggerLevelAssert).
|
||||
- (void)logAssert:(NSString *)fmt, ... NS_FORMAT_FUNCTION(1, 2);
|
||||
|
||||
|
||||
//
|
||||
// Accessors
|
||||
//
|
||||
|
||||
// Accessor methods for the log writer. If the log writer is set to nil,
|
||||
// [NSFileHandle fileHandleWithStandardOutput] is used.
|
||||
- (id<GTMLogWriter>)writer;
|
||||
- (void)setWriter:(id<GTMLogWriter>)writer;
|
||||
|
||||
// Accessor methods for the log formatter. If the log formatter is set to nil,
|
||||
// GTMLogBasicFormatter is used. This formatter will format log messages in a
|
||||
// plain printf style.
|
||||
- (id<GTMLogFormatter>)formatter;
|
||||
- (void)setFormatter:(id<GTMLogFormatter>)formatter;
|
||||
|
||||
// Accessor methods for the log filter. If the log filter is set to nil,
|
||||
// GTMLogNoFilter is used, which allows all log messages through.
|
||||
- (id<GTMLogFilter>)filter;
|
||||
- (void)setFilter:(id<GTMLogFilter>)filter;
|
||||
|
||||
@end // GTMLogger
|
||||
|
||||
|
||||
// Helper functions that are used by the convenience GTMLogger*() macros that
|
||||
// enable the logging of function names.
|
||||
@interface GTMLogger (GTMLoggerMacroHelpers)
|
||||
- (void)logFuncDebug:(const char *)func msg:(NSString *)fmt, ...
|
||||
NS_FORMAT_FUNCTION(2, 3);
|
||||
- (void)logFuncInfo:(const char *)func msg:(NSString *)fmt, ...
|
||||
NS_FORMAT_FUNCTION(2, 3);
|
||||
- (void)logFuncError:(const char *)func msg:(NSString *)fmt, ...
|
||||
NS_FORMAT_FUNCTION(2, 3);
|
||||
- (void)logFuncAssert:(const char *)func msg:(NSString *)fmt, ...
|
||||
NS_FORMAT_FUNCTION(2, 3);
|
||||
@end // GTMLoggerMacroHelpers
|
||||
|
||||
|
||||
// The convenience macros are only defined if they haven't already been defined.
|
||||
#ifndef GTMLoggerInfo
|
||||
|
||||
// Convenience macros that log to the shared GTMLogger instance. These macros
|
||||
// are how users should typically log to GTMLogger. Notice that GTMLoggerDebug()
|
||||
// calls will be compiled out of non-Debug builds.
|
||||
#define GTMLoggerDebug(...) \
|
||||
[[GTMLogger sharedLogger] logFuncDebug:__func__ msg:__VA_ARGS__]
|
||||
#define GTMLoggerInfo(...) \
|
||||
[[GTMLogger sharedLogger] logFuncInfo:__func__ msg:__VA_ARGS__]
|
||||
#define GTMLoggerError(...) \
|
||||
[[GTMLogger sharedLogger] logFuncError:__func__ msg:__VA_ARGS__]
|
||||
#define GTMLoggerAssert(...) \
|
||||
[[GTMLogger sharedLogger] logFuncAssert:__func__ msg:__VA_ARGS__]
|
||||
|
||||
// If we're not in a debug build, remove the GTMLoggerDebug statements. This
|
||||
// makes calls to GTMLoggerDebug "compile out" of Release builds
|
||||
#ifndef DEBUG
|
||||
#undef GTMLoggerDebug
|
||||
#define GTMLoggerDebug(...) do {} while(0)
|
||||
#endif
|
||||
|
||||
#endif // !defined(GTMLoggerInfo)
|
||||
|
||||
// Log levels.
|
||||
typedef enum {
|
||||
kGTMLoggerLevelUnknown,
|
||||
kGTMLoggerLevelDebug,
|
||||
kGTMLoggerLevelInfo,
|
||||
kGTMLoggerLevelError,
|
||||
kGTMLoggerLevelAssert,
|
||||
} GTMLoggerLevel;
|
||||
|
||||
|
||||
//
|
||||
// Log Writers
|
||||
//
|
||||
|
||||
// Protocol to be implemented by a GTMLogWriter instance.
|
||||
@protocol GTMLogWriter <NSObject>
|
||||
// Writes the given log message to where the log writer is configured to write.
|
||||
- (void)logMessage:(NSString *)msg level:(GTMLoggerLevel)level;
|
||||
@end // GTMLogWriter
|
||||
|
||||
|
||||
// Simple category on NSFileHandle that makes NSFileHandles valid log writers.
|
||||
// This is convenient because something like, say, +fileHandleWithStandardError
|
||||
// now becomes a valid log writer. Log messages are written to the file handle
|
||||
// with a newline appended.
|
||||
@interface NSFileHandle (GTMFileHandleLogWriter) <GTMLogWriter>
|
||||
// Opens the file at |path| in append mode, and creates the file with |mode|
|
||||
// if it didn't previously exist.
|
||||
+ (id)fileHandleForLoggingAtPath:(NSString *)path mode:(mode_t)mode;
|
||||
@end // NSFileHandle
|
||||
|
||||
|
||||
// This category makes NSArray a GTMLogWriter that can be composed of other
|
||||
// GTMLogWriters. This is the classic Composite GoF design pattern. When the
|
||||
// GTMLogWriter -logMessage:level: message is sent to the array, the array
|
||||
// forwards the message to all of its elements that implement the GTMLogWriter
|
||||
// protocol.
|
||||
//
|
||||
// This is useful in situations where you would like to send log output to
|
||||
// multiple log writers at the same time. Simply create an NSArray of the log
|
||||
// writers you wish to use, then set the array as the "writer" for your
|
||||
// GTMLogger instance.
|
||||
@interface NSArray (GTMArrayCompositeLogWriter) <GTMLogWriter>
|
||||
@end // GTMArrayCompositeLogWriter
|
||||
|
||||
|
||||
// This category adapts the GTMLogger interface so that it can be used as a log
|
||||
// writer; it's an "adapter" in the GoF Adapter pattern sense.
|
||||
//
|
||||
// This is useful when you want to configure a logger to log to a specific
|
||||
// writer with a specific formatter and/or filter. But you want to also compose
|
||||
// that with a different log writer that may have its own formatter and/or
|
||||
// filter.
|
||||
@interface GTMLogger (GTMLoggerLogWriter) <GTMLogWriter>
|
||||
@end // GTMLoggerLogWriter
|
||||
|
||||
|
||||
//
|
||||
// Log Formatters
|
||||
//
|
||||
|
||||
// Protocol to be implemented by a GTMLogFormatter instance.
|
||||
@protocol GTMLogFormatter <NSObject>
|
||||
// Returns a formatted string using the format specified in |fmt| and the va
|
||||
// args specified in |args|.
|
||||
- (NSString *)stringForFunc:(NSString *)func
|
||||
withFormat:(NSString *)fmt
|
||||
valist:(va_list)args
|
||||
level:(GTMLoggerLevel)level NS_FORMAT_FUNCTION(2, 0);
|
||||
@end // GTMLogFormatter
|
||||
|
||||
|
||||
// A basic log formatter that formats a string the same way that NSLog (or
|
||||
// printf) would. It does not do anything fancy, nor does it add any data of its
|
||||
// own.
|
||||
@interface GTMLogBasicFormatter : NSObject <GTMLogFormatter>
|
||||
|
||||
// Helper method for prettying C99 __func__ and GCC __PRETTY_FUNCTION__
|
||||
- (NSString *)prettyNameForFunc:(NSString *)func;
|
||||
|
||||
@end // GTMLogBasicFormatter
|
||||
|
||||
|
||||
// A log formatter that formats the log string like the basic formatter, but
|
||||
// also prepends a timestamp and some basic process info to the message, as
|
||||
// shown in the following sample output.
|
||||
// 2007-12-30 10:29:24.177 myapp[4588/0xa07d0f60] [lvl=1] log mesage here
|
||||
@interface GTMLogStandardFormatter : GTMLogBasicFormatter {
|
||||
@private
|
||||
NSDateFormatter *dateFormatter_; // yyyy-MM-dd HH:mm:ss.SSS
|
||||
NSString *pname_;
|
||||
pid_t pid_;
|
||||
}
|
||||
@end // GTMLogStandardFormatter
|
||||
|
||||
|
||||
//
|
||||
// Log Filters
|
||||
//
|
||||
|
||||
// Protocol to be implemented by a GTMLogFilter instance.
|
||||
@protocol GTMLogFilter <NSObject>
|
||||
// Returns YES if |msg| at |level| should be logged; NO otherwise.
|
||||
- (BOOL)filterAllowsMessage:(NSString *)msg level:(GTMLoggerLevel)level;
|
||||
@end // GTMLogFilter
|
||||
|
||||
|
||||
// A log filter that filters messages at the kGTMLoggerLevelDebug level out of
|
||||
// non-debug builds. Messages at the kGTMLoggerLevelInfo level are also filtered
|
||||
// out of non-debug builds unless GTMVerboseLogging is set in the environment or
|
||||
// the processes's defaults. Messages at the kGTMLoggerLevelError level are
|
||||
// never filtered.
|
||||
@interface GTMLogLevelFilter : NSObject <GTMLogFilter> {
|
||||
@private
|
||||
BOOL verboseLoggingEnabled_;
|
||||
NSUserDefaults *userDefaults_;
|
||||
}
|
||||
@end // GTMLogLevelFilter
|
||||
|
||||
// A simple log filter that does NOT filter anything out;
|
||||
// -filterAllowsMessage:level will always return YES. This can be a convenient
|
||||
// way to enable debug-level logging in release builds (if you so desire).
|
||||
@interface GTMLogNoFilter : NSObject <GTMLogFilter>
|
||||
@end // GTMLogNoFilter
|
||||
|
||||
|
||||
// Base class for custom level filters. Not for direct use, use the minimum
|
||||
// or maximum level subclasses below.
|
||||
@interface GTMLogAllowedLevelFilter : NSObject <GTMLogFilter> {
|
||||
@private
|
||||
NSIndexSet *allowedLevels_;
|
||||
}
|
||||
@end
|
||||
|
||||
// A log filter that allows you to set a minimum log level. Messages below this
|
||||
// level will be filtered.
|
||||
@interface GTMLogMininumLevelFilter : GTMLogAllowedLevelFilter
|
||||
|
||||
// Designated initializer, logs at levels < |level| will be filtered.
|
||||
- (id)initWithMinimumLevel:(GTMLoggerLevel)level;
|
||||
|
||||
@end
|
||||
|
||||
// A log filter that allows you to set a maximum log level. Messages whose level
|
||||
// exceeds this level will be filtered. This is really only useful if you have
|
||||
// a composite GTMLogger that is sending the other messages elsewhere.
|
||||
@interface GTMLogMaximumLevelFilter : GTMLogAllowedLevelFilter
|
||||
|
||||
// Designated initializer, logs at levels > |level| will be filtered.
|
||||
- (id)initWithMaximumLevel:(GTMLoggerLevel)level;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
// For subclasses only
|
||||
@interface GTMLogger (PrivateMethods)
|
||||
|
||||
- (void)logInternalFunc:(const char *)func
|
||||
format:(NSString *)fmt
|
||||
valist:(va_list)args
|
||||
level:(GTMLoggerLevel)level NS_FORMAT_FUNCTION(2, 0);
|
||||
|
||||
@end
|
||||
|
||||
648
My Mind/Pods/GoogleToolboxForMac/Foundation/GTMLogger.m
generated
Normal file
648
My Mind/Pods/GoogleToolboxForMac/Foundation/GTMLogger.m
generated
Normal file
@@ -0,0 +1,648 @@
|
||||
//
|
||||
// GTMLogger.m
|
||||
//
|
||||
// Copyright 2007-2008 Google Inc.
|
||||
//
|
||||
// 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 "GTMLogger.h"
|
||||
#import <fcntl.h>
|
||||
#import <unistd.h>
|
||||
#import <stdlib.h>
|
||||
#import <pthread.h>
|
||||
|
||||
|
||||
#if !defined(__clang__) && (__GNUC__*10+__GNUC_MINOR__ >= 42)
|
||||
// Some versions of GCC (4.2 and below AFAIK) aren't great about supporting
|
||||
// -Wmissing-format-attribute
|
||||
// when the function is anything more complex than foo(NSString *fmt, ...).
|
||||
// You see the error inside the function when you turn ... into va_args and
|
||||
// attempt to call another function (like vsprintf for example).
|
||||
// So we just shut off the warning for this file. We reenable it at the end.
|
||||
#pragma GCC diagnostic ignored "-Wmissing-format-attribute"
|
||||
#endif // !__clang__
|
||||
|
||||
// Reference to the shared GTMLogger instance. This is not a singleton, it's
|
||||
// just an easy reference to one shared instance.
|
||||
static GTMLogger *gSharedLogger = nil;
|
||||
|
||||
|
||||
@implementation GTMLogger
|
||||
|
||||
// Returns a pointer to the shared logger instance. If none exists, a standard
|
||||
// logger is created and returned.
|
||||
+ (id)sharedLogger {
|
||||
@synchronized(self) {
|
||||
if (gSharedLogger == nil) {
|
||||
gSharedLogger = [[self standardLogger] retain];
|
||||
}
|
||||
}
|
||||
return [[gSharedLogger retain] autorelease];
|
||||
}
|
||||
|
||||
+ (void)setSharedLogger:(GTMLogger *)logger {
|
||||
@synchronized(self) {
|
||||
[gSharedLogger autorelease];
|
||||
gSharedLogger = [logger retain];
|
||||
}
|
||||
}
|
||||
|
||||
+ (id)standardLogger {
|
||||
// Don't trust NSFileHandle not to throw
|
||||
@try {
|
||||
id<GTMLogWriter> writer = [NSFileHandle fileHandleWithStandardOutput];
|
||||
id<GTMLogFormatter> fr = [[[GTMLogStandardFormatter alloc] init]
|
||||
autorelease];
|
||||
id<GTMLogFilter> filter = [[[GTMLogLevelFilter alloc] init] autorelease];
|
||||
return [[[self alloc] initWithWriter:writer
|
||||
formatter:fr
|
||||
filter:filter] autorelease];
|
||||
}
|
||||
@catch (id e) {
|
||||
// Ignored
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
+ (id)standardLoggerWithStderr {
|
||||
// Don't trust NSFileHandle not to throw
|
||||
@try {
|
||||
id me = [self standardLogger];
|
||||
[me setWriter:[NSFileHandle fileHandleWithStandardError]];
|
||||
return me;
|
||||
}
|
||||
@catch (id e) {
|
||||
// Ignored
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
+ (id)standardLoggerWithStdoutAndStderr {
|
||||
// We're going to take advantage of the GTMLogger to GTMLogWriter adaptor
|
||||
// and create a composite logger that an outer "standard" logger can use
|
||||
// as a writer. Our inner loggers should apply no formatting since the main
|
||||
// logger does that and we want the caller to be able to change formatters
|
||||
// or add writers without knowing the inner structure of our composite.
|
||||
|
||||
// Don't trust NSFileHandle not to throw
|
||||
@try {
|
||||
GTMLogBasicFormatter *formatter = [[[GTMLogBasicFormatter alloc] init]
|
||||
autorelease];
|
||||
GTMLogger *stdoutLogger =
|
||||
[self loggerWithWriter:[NSFileHandle fileHandleWithStandardOutput]
|
||||
formatter:formatter
|
||||
filter:[[[GTMLogMaximumLevelFilter alloc]
|
||||
initWithMaximumLevel:kGTMLoggerLevelInfo]
|
||||
autorelease]];
|
||||
GTMLogger *stderrLogger =
|
||||
[self loggerWithWriter:[NSFileHandle fileHandleWithStandardError]
|
||||
formatter:formatter
|
||||
filter:[[[GTMLogMininumLevelFilter alloc]
|
||||
initWithMinimumLevel:kGTMLoggerLevelError]
|
||||
autorelease]];
|
||||
GTMLogger *compositeWriter =
|
||||
[self loggerWithWriter:[NSArray arrayWithObjects:
|
||||
stdoutLogger, stderrLogger, nil]
|
||||
formatter:formatter
|
||||
filter:[[[GTMLogNoFilter alloc] init] autorelease]];
|
||||
GTMLogger *outerLogger = [self standardLogger];
|
||||
[outerLogger setWriter:compositeWriter];
|
||||
return outerLogger;
|
||||
}
|
||||
@catch (id e) {
|
||||
// Ignored
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
+ (id)standardLoggerWithPath:(NSString *)path {
|
||||
@try {
|
||||
NSFileHandle *fh = [NSFileHandle fileHandleForLoggingAtPath:path mode:0644];
|
||||
if (fh == nil) return nil;
|
||||
id me = [self standardLogger];
|
||||
[me setWriter:fh];
|
||||
return me;
|
||||
}
|
||||
@catch (id e) {
|
||||
// Ignored
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
+ (id)loggerWithWriter:(id<GTMLogWriter>)writer
|
||||
formatter:(id<GTMLogFormatter>)formatter
|
||||
filter:(id<GTMLogFilter>)filter {
|
||||
return [[[self alloc] initWithWriter:writer
|
||||
formatter:formatter
|
||||
filter:filter] autorelease];
|
||||
}
|
||||
|
||||
+ (id)logger {
|
||||
return [[[self alloc] init] autorelease];
|
||||
}
|
||||
|
||||
- (id)init {
|
||||
return [self initWithWriter:nil formatter:nil filter:nil];
|
||||
}
|
||||
|
||||
- (id)initWithWriter:(id<GTMLogWriter>)writer
|
||||
formatter:(id<GTMLogFormatter>)formatter
|
||||
filter:(id<GTMLogFilter>)filter {
|
||||
if ((self = [super init])) {
|
||||
[self setWriter:writer];
|
||||
[self setFormatter:formatter];
|
||||
[self setFilter:filter];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
// Unlikely, but |writer_| may be an NSFileHandle, which can throw
|
||||
@try {
|
||||
[formatter_ release];
|
||||
[filter_ release];
|
||||
[writer_ release];
|
||||
}
|
||||
@catch (id e) {
|
||||
// Ignored
|
||||
}
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (id<GTMLogWriter>)writer {
|
||||
return [[writer_ retain] autorelease];
|
||||
}
|
||||
|
||||
- (void)setWriter:(id<GTMLogWriter>)writer {
|
||||
@synchronized(self) {
|
||||
[writer_ autorelease];
|
||||
writer_ = nil;
|
||||
if (writer == nil) {
|
||||
// Try to use stdout, but don't trust NSFileHandle
|
||||
@try {
|
||||
writer_ = [[NSFileHandle fileHandleWithStandardOutput] retain];
|
||||
}
|
||||
@catch (id e) {
|
||||
// Leave |writer_| nil
|
||||
}
|
||||
} else {
|
||||
writer_ = [writer retain];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (id<GTMLogFormatter>)formatter {
|
||||
return [[formatter_ retain] autorelease];
|
||||
}
|
||||
|
||||
- (void)setFormatter:(id<GTMLogFormatter>)formatter {
|
||||
@synchronized(self) {
|
||||
[formatter_ autorelease];
|
||||
formatter_ = nil;
|
||||
if (formatter == nil) {
|
||||
@try {
|
||||
formatter_ = [[GTMLogBasicFormatter alloc] init];
|
||||
}
|
||||
@catch (id e) {
|
||||
// Leave |formatter_| nil
|
||||
}
|
||||
} else {
|
||||
formatter_ = [formatter retain];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (id<GTMLogFilter>)filter {
|
||||
return [[filter_ retain] autorelease];
|
||||
}
|
||||
|
||||
- (void)setFilter:(id<GTMLogFilter>)filter {
|
||||
@synchronized(self) {
|
||||
[filter_ autorelease];
|
||||
filter_ = nil;
|
||||
if (filter == nil) {
|
||||
@try {
|
||||
filter_ = [[GTMLogNoFilter alloc] init];
|
||||
}
|
||||
@catch (id e) {
|
||||
// Leave |filter_| nil
|
||||
}
|
||||
} else {
|
||||
filter_ = [filter retain];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)logDebug:(NSString *)fmt, ... {
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
[self logInternalFunc:NULL format:fmt valist:args level:kGTMLoggerLevelDebug];
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
- (void)logInfo:(NSString *)fmt, ... {
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
[self logInternalFunc:NULL format:fmt valist:args level:kGTMLoggerLevelInfo];
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
- (void)logError:(NSString *)fmt, ... {
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
[self logInternalFunc:NULL format:fmt valist:args level:kGTMLoggerLevelError];
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
- (void)logAssert:(NSString *)fmt, ... {
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
[self logInternalFunc:NULL format:fmt valist:args level:kGTMLoggerLevelAssert];
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
@end // GTMLogger
|
||||
|
||||
@implementation GTMLogger (GTMLoggerMacroHelpers)
|
||||
|
||||
- (void)logFuncDebug:(const char *)func msg:(NSString *)fmt, ... {
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
[self logInternalFunc:func format:fmt valist:args level:kGTMLoggerLevelDebug];
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
- (void)logFuncInfo:(const char *)func msg:(NSString *)fmt, ... {
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
[self logInternalFunc:func format:fmt valist:args level:kGTMLoggerLevelInfo];
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
- (void)logFuncError:(const char *)func msg:(NSString *)fmt, ... {
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
[self logInternalFunc:func format:fmt valist:args level:kGTMLoggerLevelError];
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
- (void)logFuncAssert:(const char *)func msg:(NSString *)fmt, ... {
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
[self logInternalFunc:func format:fmt valist:args level:kGTMLoggerLevelAssert];
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
@end // GTMLoggerMacroHelpers
|
||||
|
||||
@implementation GTMLogger (PrivateMethods)
|
||||
|
||||
- (void)logInternalFunc:(const char *)func
|
||||
format:(NSString *)fmt
|
||||
valist:(va_list)args
|
||||
level:(GTMLoggerLevel)level {
|
||||
// Primary point where logging happens, logging should never throw, catch
|
||||
// everything.
|
||||
@try {
|
||||
NSString *fname = func ? [NSString stringWithUTF8String:func] : nil;
|
||||
NSString *msg = [formatter_ stringForFunc:fname
|
||||
withFormat:fmt
|
||||
valist:args
|
||||
level:level];
|
||||
if (msg && [filter_ filterAllowsMessage:msg level:level])
|
||||
[writer_ logMessage:msg level:level];
|
||||
}
|
||||
@catch (id e) {
|
||||
// Ignored
|
||||
}
|
||||
}
|
||||
|
||||
@end // PrivateMethods
|
||||
|
||||
|
||||
@implementation NSFileHandle (GTMFileHandleLogWriter)
|
||||
|
||||
+ (id)fileHandleForLoggingAtPath:(NSString *)path mode:(mode_t)mode {
|
||||
int fd = -1;
|
||||
if (path) {
|
||||
int flags = O_WRONLY | O_APPEND | O_CREAT;
|
||||
fd = open([path fileSystemRepresentation], flags, mode);
|
||||
}
|
||||
if (fd == -1) return nil;
|
||||
return [[[self alloc] initWithFileDescriptor:fd
|
||||
closeOnDealloc:YES] autorelease];
|
||||
}
|
||||
|
||||
- (void)logMessage:(NSString *)msg level:(GTMLoggerLevel)level {
|
||||
@synchronized(self) {
|
||||
// Closed pipes should not generate exceptions in our caller. Catch here
|
||||
// as well [GTMLogger logInternalFunc:...] so that an exception in this
|
||||
// writer does not prevent other writers from having a chance.
|
||||
@try {
|
||||
NSString *line = [NSString stringWithFormat:@"%@\n", msg];
|
||||
[self writeData:[line dataUsingEncoding:NSUTF8StringEncoding]];
|
||||
}
|
||||
@catch (id e) {
|
||||
// Ignored
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@end // GTMFileHandleLogWriter
|
||||
|
||||
|
||||
@implementation NSArray (GTMArrayCompositeLogWriter)
|
||||
|
||||
- (void)logMessage:(NSString *)msg level:(GTMLoggerLevel)level {
|
||||
@synchronized(self) {
|
||||
id<GTMLogWriter> child = nil;
|
||||
for (child in self) {
|
||||
if ([child conformsToProtocol:@protocol(GTMLogWriter)])
|
||||
[child logMessage:msg level:level];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@end // GTMArrayCompositeLogWriter
|
||||
|
||||
|
||||
@implementation GTMLogger (GTMLoggerLogWriter)
|
||||
|
||||
- (void)logMessage:(NSString *)msg level:(GTMLoggerLevel)level {
|
||||
switch (level) {
|
||||
case kGTMLoggerLevelDebug:
|
||||
[self logDebug:@"%@", msg];
|
||||
break;
|
||||
case kGTMLoggerLevelInfo:
|
||||
[self logInfo:@"%@", msg];
|
||||
break;
|
||||
case kGTMLoggerLevelError:
|
||||
[self logError:@"%@", msg];
|
||||
break;
|
||||
case kGTMLoggerLevelAssert:
|
||||
[self logAssert:@"%@", msg];
|
||||
break;
|
||||
default:
|
||||
// Ignore the message.
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@end // GTMLoggerLogWriter
|
||||
|
||||
|
||||
@implementation GTMLogBasicFormatter
|
||||
|
||||
- (NSString *)prettyNameForFunc:(NSString *)func {
|
||||
NSString *name = [func stringByTrimmingCharactersInSet:
|
||||
[NSCharacterSet whitespaceAndNewlineCharacterSet]];
|
||||
NSString *function = @"(unknown)";
|
||||
if ([name length]) {
|
||||
if (// Objective C __func__ and __PRETTY_FUNCTION__
|
||||
[name hasPrefix:@"-["] || [name hasPrefix:@"+["] ||
|
||||
// C++ __PRETTY_FUNCTION__ and other preadorned formats
|
||||
[name hasSuffix:@")"]) {
|
||||
function = name;
|
||||
} else {
|
||||
// Assume C99 __func__
|
||||
function = [NSString stringWithFormat:@"%@()", name];
|
||||
}
|
||||
}
|
||||
return function;
|
||||
}
|
||||
|
||||
- (NSString *)stringForFunc:(NSString *)func
|
||||
withFormat:(NSString *)fmt
|
||||
valist:(va_list)args
|
||||
level:(GTMLoggerLevel)level {
|
||||
// Performance note: We may want to do a quick check here to see if |fmt|
|
||||
// contains a '%', and if not, simply return 'fmt'.
|
||||
if (!(fmt && args)) return nil;
|
||||
return [[[NSString alloc] initWithFormat:fmt arguments:args] autorelease];
|
||||
}
|
||||
|
||||
@end // GTMLogBasicFormatter
|
||||
|
||||
|
||||
@implementation GTMLogStandardFormatter
|
||||
|
||||
- (id)init {
|
||||
if ((self = [super init])) {
|
||||
dateFormatter_ = [[NSDateFormatter alloc] init];
|
||||
[dateFormatter_ setFormatterBehavior:NSDateFormatterBehavior10_4];
|
||||
[dateFormatter_ setDateFormat:@"yyyy-MM-dd HH:mm:ss.SSS"];
|
||||
pname_ = [[[NSProcessInfo processInfo] processName] copy];
|
||||
pid_ = [[NSProcessInfo processInfo] processIdentifier];
|
||||
if (!(dateFormatter_ && pname_)) {
|
||||
[self release];
|
||||
return nil;
|
||||
}
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
[dateFormatter_ release];
|
||||
[pname_ release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (NSString *)stringForFunc:(NSString *)func
|
||||
withFormat:(NSString *)fmt
|
||||
valist:(va_list)args
|
||||
level:(GTMLoggerLevel)level {
|
||||
NSString *tstamp = nil;
|
||||
@synchronized (dateFormatter_) {
|
||||
tstamp = [dateFormatter_ stringFromDate:[NSDate date]];
|
||||
}
|
||||
return [NSString stringWithFormat:@"%@ %@[%d/%p] [lvl=%d] %@ %@",
|
||||
tstamp, pname_, pid_, pthread_self(),
|
||||
level, [self prettyNameForFunc:func],
|
||||
// |super| has guard for nil |fmt| and |args|
|
||||
[super stringForFunc:func withFormat:fmt valist:args level:level]];
|
||||
}
|
||||
|
||||
@end // GTMLogStandardFormatter
|
||||
|
||||
static NSString *const kVerboseLoggingKey = @"GTMVerboseLogging";
|
||||
|
||||
// Check the environment and the user preferences for the GTMVerboseLogging key
|
||||
// to see if verbose logging has been enabled. The environment variable will
|
||||
// override the defaults setting, so check the environment first.
|
||||
// COV_NF_START
|
||||
static BOOL IsVerboseLoggingEnabled(NSUserDefaults *userDefaults) {
|
||||
NSString *value = [[[NSProcessInfo processInfo] environment]
|
||||
objectForKey:kVerboseLoggingKey];
|
||||
if (value) {
|
||||
// Emulate [NSString boolValue] for pre-10.5
|
||||
value = [value stringByTrimmingCharactersInSet:
|
||||
[NSCharacterSet whitespaceAndNewlineCharacterSet]];
|
||||
if ([[value uppercaseString] hasPrefix:@"Y"] ||
|
||||
[[value uppercaseString] hasPrefix:@"T"] ||
|
||||
[value intValue]) {
|
||||
return YES;
|
||||
} else {
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
return [userDefaults boolForKey:kVerboseLoggingKey];
|
||||
}
|
||||
// COV_NF_END
|
||||
|
||||
@implementation GTMLogLevelFilter
|
||||
|
||||
- (id)init {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
// Keep a reference to standardUserDefaults, avoiding a crash if client code calls
|
||||
// "NSUserDefaults resetStandardUserDefaults" which releases it from memory. We are still
|
||||
// notified of changes through our instance. Note: resetStandardUserDefaults does not actually
|
||||
// clear settings:
|
||||
// https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSUserDefaults_Class/index.html#//apple_ref/occ/clm/NSUserDefaults/resetStandardUserDefaults
|
||||
// and so should only be called in test code if necessary.
|
||||
userDefaults_ = [[NSUserDefaults standardUserDefaults] retain];
|
||||
[userDefaults_ addObserver:self
|
||||
forKeyPath:kVerboseLoggingKey
|
||||
options:NSKeyValueObservingOptionNew
|
||||
context:nil];
|
||||
|
||||
verboseLoggingEnabled_ = IsVerboseLoggingEnabled(userDefaults_);
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
[userDefaults_ removeObserver:self forKeyPath:kVerboseLoggingKey];
|
||||
[userDefaults_ release];
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
// In DEBUG builds, log everything. If we're not in a debug build we'll assume
|
||||
// that we're in a Release build.
|
||||
- (BOOL)filterAllowsMessage:(NSString *)msg level:(GTMLoggerLevel)level {
|
||||
#if defined(DEBUG) && DEBUG
|
||||
return YES;
|
||||
#endif
|
||||
|
||||
BOOL allow = YES;
|
||||
|
||||
switch (level) {
|
||||
case kGTMLoggerLevelDebug:
|
||||
allow = NO;
|
||||
break;
|
||||
case kGTMLoggerLevelInfo:
|
||||
allow = verboseLoggingEnabled_;
|
||||
break;
|
||||
case kGTMLoggerLevelError:
|
||||
allow = YES;
|
||||
break;
|
||||
case kGTMLoggerLevelAssert:
|
||||
allow = YES;
|
||||
break;
|
||||
default:
|
||||
allow = YES;
|
||||
break;
|
||||
}
|
||||
|
||||
return allow;
|
||||
}
|
||||
|
||||
- (void)observeValueForKeyPath:(NSString *)keyPath
|
||||
ofObject:(id)object
|
||||
change:(NSDictionary *)change
|
||||
context:(void *)context
|
||||
{
|
||||
if([keyPath isEqual:kVerboseLoggingKey]) {
|
||||
verboseLoggingEnabled_ = IsVerboseLoggingEnabled(userDefaults_);
|
||||
}
|
||||
}
|
||||
|
||||
@end // GTMLogLevelFilter
|
||||
|
||||
|
||||
@implementation GTMLogNoFilter
|
||||
|
||||
- (BOOL)filterAllowsMessage:(NSString *)msg level:(GTMLoggerLevel)level {
|
||||
return YES; // Allow everything through
|
||||
}
|
||||
|
||||
@end // GTMLogNoFilter
|
||||
|
||||
|
||||
@implementation GTMLogAllowedLevelFilter
|
||||
|
||||
// Private designated initializer
|
||||
- (id)initWithAllowedLevels:(NSIndexSet *)levels {
|
||||
self = [super init];
|
||||
if (self != nil) {
|
||||
allowedLevels_ = [levels retain];
|
||||
// Cap min/max level
|
||||
if (!allowedLevels_ ||
|
||||
// NSIndexSet is unsigned so only check the high bound, but need to
|
||||
// check both first and last index because NSIndexSet appears to allow
|
||||
// wraparound.
|
||||
([allowedLevels_ firstIndex] > kGTMLoggerLevelAssert) ||
|
||||
([allowedLevels_ lastIndex] > kGTMLoggerLevelAssert)) {
|
||||
[self release];
|
||||
return nil;
|
||||
}
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (id)init {
|
||||
// Allow all levels in default init
|
||||
return [self initWithAllowedLevels:[NSIndexSet indexSetWithIndexesInRange:
|
||||
NSMakeRange(kGTMLoggerLevelUnknown,
|
||||
(kGTMLoggerLevelAssert - kGTMLoggerLevelUnknown + 1))]];
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
[allowedLevels_ release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (BOOL)filterAllowsMessage:(NSString *)msg level:(GTMLoggerLevel)level {
|
||||
return [allowedLevels_ containsIndex:level];
|
||||
}
|
||||
|
||||
@end // GTMLogAllowedLevelFilter
|
||||
|
||||
|
||||
@implementation GTMLogMininumLevelFilter
|
||||
|
||||
- (id)initWithMinimumLevel:(GTMLoggerLevel)level {
|
||||
return [super initWithAllowedLevels:[NSIndexSet indexSetWithIndexesInRange:
|
||||
NSMakeRange(level,
|
||||
(kGTMLoggerLevelAssert - level + 1))]];
|
||||
}
|
||||
|
||||
@end // GTMLogMininumLevelFilter
|
||||
|
||||
|
||||
@implementation GTMLogMaximumLevelFilter
|
||||
|
||||
- (id)initWithMaximumLevel:(GTMLoggerLevel)level {
|
||||
return [super initWithAllowedLevels:[NSIndexSet indexSetWithIndexesInRange:
|
||||
NSMakeRange(kGTMLoggerLevelUnknown, level + 1)]];
|
||||
}
|
||||
|
||||
@end // GTMLogMaximumLevelFilter
|
||||
|
||||
#if !defined(__clang__) && (__GNUC__*10+__GNUC_MINOR__ >= 42)
|
||||
// See comment at top of file.
|
||||
#pragma GCC diagnostic error "-Wmissing-format-attribute"
|
||||
#endif // !__clang__
|
||||
199
My Mind/Pods/GoogleToolboxForMac/Foundation/GTMNSData+zlib.h
generated
Normal file
199
My Mind/Pods/GoogleToolboxForMac/Foundation/GTMNSData+zlib.h
generated
Normal file
@@ -0,0 +1,199 @@
|
||||
//
|
||||
// GTMNSData+zlib.h
|
||||
//
|
||||
// Copyright 2007-2008 Google Inc.
|
||||
//
|
||||
// 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 <Foundation/Foundation.h>
|
||||
#import "GTMDefines.h"
|
||||
|
||||
/// Helpers for dealing w/ zlib inflate/deflate calls.
|
||||
@interface NSData (GTMZLibAdditions)
|
||||
|
||||
// NOTE: For 64bit, none of these apis handle input sizes >32bits, they will
|
||||
// return nil when given such data. To handle data of that size you really
|
||||
// should be streaming it rather then doing it all in memory.
|
||||
|
||||
#pragma mark Gzip Compression
|
||||
|
||||
/// Return an autoreleased NSData w/ the result of gzipping the bytes.
|
||||
//
|
||||
// Uses the default compression level.
|
||||
+ (NSData *)gtm_dataByGzippingBytes:(const void *)bytes
|
||||
length:(NSUInteger)length;
|
||||
+ (NSData *)gtm_dataByGzippingBytes:(const void *)bytes
|
||||
length:(NSUInteger)length
|
||||
error:(NSError **)error;
|
||||
|
||||
/// Return an autoreleased NSData w/ the result of gzipping the payload of |data|.
|
||||
//
|
||||
// Uses the default compression level.
|
||||
+ (NSData *)gtm_dataByGzippingData:(NSData *)data __attribute__((deprecated("Use error variant")));
|
||||
+ (NSData *)gtm_dataByGzippingData:(NSData *)data
|
||||
error:(NSError **)error;
|
||||
|
||||
/// Return an autoreleased NSData w/ the result of gzipping the bytes using |level| compression level.
|
||||
//
|
||||
// |level| can be 1-9, any other values will be clipped to that range.
|
||||
+ (NSData *)gtm_dataByGzippingBytes:(const void *)bytes
|
||||
length:(NSUInteger)length
|
||||
compressionLevel:(int)level __attribute__((deprecated("Use error variant")));
|
||||
+ (NSData *)gtm_dataByGzippingBytes:(const void *)bytes
|
||||
length:(NSUInteger)length
|
||||
compressionLevel:(int)level
|
||||
error:(NSError **)error;
|
||||
|
||||
/// Return an autoreleased NSData w/ the result of gzipping the payload of |data| using |level| compression level.
|
||||
+ (NSData *)gtm_dataByGzippingData:(NSData *)data
|
||||
compressionLevel:(int)level __attribute__((deprecated("Use error variant")));
|
||||
+ (NSData *)gtm_dataByGzippingData:(NSData *)data
|
||||
compressionLevel:(int)level
|
||||
error:(NSError **)error;
|
||||
|
||||
#pragma mark Zlib "Stream" Compression
|
||||
|
||||
// NOTE: deflate is *NOT* gzip. deflate is a "zlib" stream. pick which one
|
||||
// you really want to create. (the inflate api will handle either)
|
||||
|
||||
/// Return an autoreleased NSData w/ the result of deflating the bytes.
|
||||
//
|
||||
// Uses the default compression level.
|
||||
+ (NSData *)gtm_dataByDeflatingBytes:(const void *)bytes
|
||||
length:(NSUInteger)length __attribute__((deprecated("Use error variant")));
|
||||
+ (NSData *)gtm_dataByDeflatingBytes:(const void *)bytes
|
||||
length:(NSUInteger)length
|
||||
error:(NSError **)error;
|
||||
|
||||
/// Return an autoreleased NSData w/ the result of deflating the payload of |data|.
|
||||
//
|
||||
// Uses the default compression level.
|
||||
+ (NSData *)gtm_dataByDeflatingData:(NSData *)data __attribute__((deprecated("Use error variant")));
|
||||
+ (NSData *)gtm_dataByDeflatingData:(NSData *)data
|
||||
error:(NSError **)error;
|
||||
|
||||
/// Return an autoreleased NSData w/ the result of deflating the bytes using |level| compression level.
|
||||
//
|
||||
// |level| can be 1-9, any other values will be clipped to that range.
|
||||
+ (NSData *)gtm_dataByDeflatingBytes:(const void *)bytes
|
||||
length:(NSUInteger)length
|
||||
compressionLevel:(int)level __attribute__((deprecated("Use error variant")));
|
||||
+ (NSData *)gtm_dataByDeflatingBytes:(const void *)bytes
|
||||
length:(NSUInteger)length
|
||||
compressionLevel:(int)level
|
||||
error:(NSError **)error;
|
||||
|
||||
/// Return an autoreleased NSData w/ the result of deflating the payload of |data| using |level| compression level.
|
||||
+ (NSData *)gtm_dataByDeflatingData:(NSData *)data
|
||||
compressionLevel:(int)level __attribute__((deprecated("Use error variant")));
|
||||
+ (NSData *)gtm_dataByDeflatingData:(NSData *)data
|
||||
compressionLevel:(int)level
|
||||
error:(NSError **)error;
|
||||
|
||||
#pragma mark Uncompress of Gzip or Zlib
|
||||
|
||||
/// Return an autoreleased NSData w/ the result of decompressing the bytes.
|
||||
//
|
||||
// The bytes to decompress can be zlib or gzip payloads.
|
||||
+ (NSData *)gtm_dataByInflatingBytes:(const void *)bytes
|
||||
length:(NSUInteger)length __attribute__((deprecated("Use error variant")));
|
||||
+ (NSData *)gtm_dataByInflatingBytes:(const void *)bytes
|
||||
length:(NSUInteger)length
|
||||
error:(NSError **)error;
|
||||
|
||||
/// Return an autoreleased NSData w/ the result of decompressing the payload of |data|.
|
||||
//
|
||||
// The data to decompress can be zlib or gzip payloads.
|
||||
+ (NSData *)gtm_dataByInflatingData:(NSData *)data __attribute__((deprecated("Use error variant")));
|
||||
+ (NSData *)gtm_dataByInflatingData:(NSData *)data
|
||||
error:(NSError **)error;
|
||||
|
||||
#pragma mark "Raw" Compression Support
|
||||
|
||||
// NOTE: raw deflate is *NOT* gzip or deflate. it does not include a header
|
||||
// of any form and should only be used within streams here an external crc/etc.
|
||||
// is done to validate the data. The RawInflate apis can be used on data
|
||||
// processed like this.
|
||||
|
||||
/// Return an autoreleased NSData w/ the result of *raw* deflating the bytes.
|
||||
//
|
||||
// Uses the default compression level.
|
||||
// *No* header is added to the resulting data.
|
||||
+ (NSData *)gtm_dataByRawDeflatingBytes:(const void *)bytes
|
||||
length:(NSUInteger)length __attribute__((deprecated("Use error variant")));
|
||||
+ (NSData *)gtm_dataByRawDeflatingBytes:(const void *)bytes
|
||||
length:(NSUInteger)length
|
||||
error:(NSError **)error;
|
||||
|
||||
/// Return an autoreleased NSData w/ the result of *raw* deflating the payload of |data|.
|
||||
//
|
||||
// Uses the default compression level.
|
||||
// *No* header is added to the resulting data.
|
||||
+ (NSData *)gtm_dataByRawDeflatingData:(NSData *)data __attribute__((deprecated("Use error variant")));
|
||||
+ (NSData *)gtm_dataByRawDeflatingData:(NSData *)data
|
||||
error:(NSError **)error;
|
||||
|
||||
/// Return an autoreleased NSData w/ the result of *raw* deflating the bytes using |level| compression level.
|
||||
//
|
||||
// |level| can be 1-9, any other values will be clipped to that range.
|
||||
// *No* header is added to the resulting data.
|
||||
+ (NSData *)gtm_dataByRawDeflatingBytes:(const void *)bytes
|
||||
length:(NSUInteger)length
|
||||
compressionLevel:(int)level __attribute__((deprecated("Use error variant")));
|
||||
+ (NSData *)gtm_dataByRawDeflatingBytes:(const void *)bytes
|
||||
length:(NSUInteger)length
|
||||
compressionLevel:(int)level
|
||||
error:(NSError **)error;
|
||||
|
||||
/// Return an autoreleased NSData w/ the result of *raw* deflating the payload of |data| using |level| compression level.
|
||||
// *No* header is added to the resulting data.
|
||||
+ (NSData *)gtm_dataByRawDeflatingData:(NSData *)data
|
||||
compressionLevel:(int)level __attribute__((deprecated("Use error variant")));
|
||||
+ (NSData *)gtm_dataByRawDeflatingData:(NSData *)data
|
||||
compressionLevel:(int)level
|
||||
error:(NSError **)error;
|
||||
|
||||
/// Return an autoreleased NSData w/ the result of *raw* decompressing the bytes.
|
||||
//
|
||||
// The data to decompress, it should *not* have any header (zlib nor gzip).
|
||||
+ (NSData *)gtm_dataByRawInflatingBytes:(const void *)bytes
|
||||
length:(NSUInteger)length __attribute__((deprecated("Use error variant")));
|
||||
+ (NSData *)gtm_dataByRawInflatingBytes:(const void *)bytes
|
||||
length:(NSUInteger)length
|
||||
error:(NSError **)error;
|
||||
|
||||
/// Return an autoreleased NSData w/ the result of *raw* decompressing the payload of |data|.
|
||||
//
|
||||
// The data to decompress, it should *not* have any header (zlib nor gzip).
|
||||
+ (NSData *)gtm_dataByRawInflatingData:(NSData *)data __attribute__((deprecated("Use error variant")));
|
||||
+ (NSData *)gtm_dataByRawInflatingData:(NSData *)data
|
||||
error:(NSError **)error;
|
||||
|
||||
@end
|
||||
|
||||
FOUNDATION_EXPORT NSString *const GTMNSDataZlibErrorDomain;
|
||||
FOUNDATION_EXPORT NSString *const GTMNSDataZlibErrorKey; // NSNumber
|
||||
FOUNDATION_EXPORT NSString *const GTMNSDataZlibRemainingBytesKey; // NSNumber
|
||||
|
||||
typedef NS_ENUM(NSInteger, GTMNSDataZlibError) {
|
||||
GTMNSDataZlibErrorGreaterThan32BitsToCompress = 1024,
|
||||
// An internal zlib error.
|
||||
// GTMNSDataZlibErrorKey will contain the error value.
|
||||
// NSLocalizedDescriptionKey may contain an error string from zlib.
|
||||
// Look in zlib.h for list of errors.
|
||||
GTMNSDataZlibErrorInternal,
|
||||
// There was left over data in the buffer that was not used.
|
||||
// GTMNSDataZlibRemainingBytesKey will contain number of remaining bytes.
|
||||
GTMNSDataZlibErrorDataRemaining
|
||||
};
|
||||
531
My Mind/Pods/GoogleToolboxForMac/Foundation/GTMNSData+zlib.m
generated
Normal file
531
My Mind/Pods/GoogleToolboxForMac/Foundation/GTMNSData+zlib.m
generated
Normal file
@@ -0,0 +1,531 @@
|
||||
//
|
||||
// GTMNSData+zlib.m
|
||||
//
|
||||
// Copyright 2007-2008 Google Inc.
|
||||
//
|
||||
// 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 "GTMNSData+zlib.h"
|
||||
#import <zlib.h>
|
||||
#import "GTMDefines.h"
|
||||
|
||||
#define kChunkSize 1024
|
||||
|
||||
NSString *const GTMNSDataZlibErrorDomain = @"com.google.GTMNSDataZlibErrorDomain";
|
||||
NSString *const GTMNSDataZlibErrorKey = @"GTMNSDataZlibErrorKey";
|
||||
NSString *const GTMNSDataZlibRemainingBytesKey = @"GTMNSDataZlibRemainingBytesKey";
|
||||
|
||||
typedef enum {
|
||||
CompressionModeZlib,
|
||||
CompressionModeGzip,
|
||||
CompressionModeRaw,
|
||||
} CompressionMode;
|
||||
|
||||
@interface NSData (GTMZlibAdditionsPrivate)
|
||||
+ (NSData *)gtm_dataByCompressingBytes:(const void *)bytes
|
||||
length:(NSUInteger)length
|
||||
compressionLevel:(int)level
|
||||
mode:(CompressionMode)mode
|
||||
error:(NSError **)error;
|
||||
+ (NSData *)gtm_dataByInflatingBytes:(const void *)bytes
|
||||
length:(NSUInteger)length
|
||||
isRawData:(BOOL)isRawData
|
||||
error:(NSError **)error;
|
||||
@end
|
||||
|
||||
@implementation NSData (GTMZlibAdditionsPrivate)
|
||||
|
||||
+ (NSData *)gtm_dataByCompressingBytes:(const void *)bytes
|
||||
length:(NSUInteger)length
|
||||
compressionLevel:(int)level
|
||||
mode:(CompressionMode)mode
|
||||
error:(NSError **)error {
|
||||
if (!bytes || !length) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
#if defined(__LP64__) && __LP64__
|
||||
// Don't support > 32bit length for 64 bit, see note in header.
|
||||
if (length > UINT_MAX) {
|
||||
if (error) {
|
||||
*error = [NSError errorWithDomain:GTMNSDataZlibErrorDomain
|
||||
code:GTMNSDataZlibErrorGreaterThan32BitsToCompress
|
||||
userInfo:nil];
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (level == Z_DEFAULT_COMPRESSION) {
|
||||
// the default value is actually outside the range, so we have to let it
|
||||
// through specifically.
|
||||
} else if (level < Z_BEST_SPEED) {
|
||||
level = Z_BEST_SPEED;
|
||||
} else if (level > Z_BEST_COMPRESSION) {
|
||||
level = Z_BEST_COMPRESSION;
|
||||
}
|
||||
|
||||
z_stream strm;
|
||||
bzero(&strm, sizeof(z_stream));
|
||||
|
||||
int memLevel = 8; // the default
|
||||
int windowBits = 15; // the default
|
||||
switch (mode) {
|
||||
case CompressionModeZlib:
|
||||
// nothing to do
|
||||
break;
|
||||
|
||||
case CompressionModeGzip:
|
||||
windowBits += 16; // enable gzip header instead of zlib header
|
||||
break;
|
||||
|
||||
case CompressionModeRaw:
|
||||
windowBits *= -1; // Negative to mean no header.
|
||||
break;
|
||||
}
|
||||
int retCode;
|
||||
if ((retCode = deflateInit2(&strm, level, Z_DEFLATED, windowBits,
|
||||
memLevel, Z_DEFAULT_STRATEGY)) != Z_OK) {
|
||||
// COV_NF_START - no real way to force this in a unittest (we guard all args)
|
||||
if (error) {
|
||||
NSDictionary *userInfo = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:retCode]
|
||||
forKey:GTMNSDataZlibErrorKey];
|
||||
*error = [NSError errorWithDomain:GTMNSDataZlibErrorDomain
|
||||
code:GTMNSDataZlibErrorInternal
|
||||
userInfo:userInfo];
|
||||
}
|
||||
return nil;
|
||||
// COV_NF_END
|
||||
}
|
||||
|
||||
// hint the size at 1/4 the input size
|
||||
NSMutableData *result = [NSMutableData dataWithCapacity:(length/4)];
|
||||
unsigned char output[kChunkSize];
|
||||
|
||||
// setup the input
|
||||
strm.avail_in = (unsigned int)length;
|
||||
strm.next_in = (unsigned char*)bytes;
|
||||
|
||||
// loop to collect the data
|
||||
do {
|
||||
// update what we're passing in
|
||||
strm.avail_out = kChunkSize;
|
||||
strm.next_out = output;
|
||||
retCode = deflate(&strm, Z_FINISH);
|
||||
if ((retCode != Z_OK) && (retCode != Z_STREAM_END)) {
|
||||
// COV_NF_START - no real way to force this in a unittest
|
||||
// (in inflate, we can feed bogus/truncated data to test, but an error
|
||||
// here would be some internal issue w/in zlib, and there isn't any real
|
||||
// way to test it)
|
||||
if (error) {
|
||||
NSDictionary *userInfo = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:retCode]
|
||||
forKey:GTMNSDataZlibErrorKey];
|
||||
*error = [NSError errorWithDomain:GTMNSDataZlibErrorDomain
|
||||
code:GTMNSDataZlibErrorInternal
|
||||
userInfo:userInfo];
|
||||
}
|
||||
deflateEnd(&strm);
|
||||
return nil;
|
||||
// COV_NF_END
|
||||
}
|
||||
// collect what we got
|
||||
unsigned gotBack = kChunkSize - strm.avail_out;
|
||||
if (gotBack > 0) {
|
||||
[result appendBytes:output length:gotBack];
|
||||
}
|
||||
|
||||
} while (retCode == Z_OK);
|
||||
|
||||
// if the loop exits, we used all input and the stream ended
|
||||
_GTMDevAssert(strm.avail_in == 0,
|
||||
@"thought we finished deflate w/o using all input, %u bytes left",
|
||||
strm.avail_in);
|
||||
_GTMDevAssert(retCode == Z_STREAM_END,
|
||||
@"thought we finished deflate w/o getting a result of stream end, code %d",
|
||||
retCode);
|
||||
|
||||
// clean up
|
||||
deflateEnd(&strm);
|
||||
|
||||
return result;
|
||||
} // gtm_dataByCompressingBytes:length:compressionLevel:useGzip:
|
||||
|
||||
+ (NSData *)gtm_dataByInflatingBytes:(const void *)bytes
|
||||
length:(NSUInteger)length
|
||||
isRawData:(BOOL)isRawData
|
||||
error:(NSError **)error {
|
||||
if (!bytes || !length) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
#if defined(__LP64__) && __LP64__
|
||||
// Don't support > 32bit length for 64 bit, see note in header.
|
||||
if (length > UINT_MAX) {
|
||||
return nil;
|
||||
}
|
||||
#endif
|
||||
|
||||
z_stream strm;
|
||||
bzero(&strm, sizeof(z_stream));
|
||||
|
||||
// setup the input
|
||||
strm.avail_in = (unsigned int)length;
|
||||
strm.next_in = (unsigned char*)bytes;
|
||||
|
||||
int windowBits = 15; // 15 to enable any window size
|
||||
if (isRawData) {
|
||||
windowBits *= -1; // make it negative to signal no header.
|
||||
} else {
|
||||
windowBits += 32; // and +32 to enable zlib or gzip header detection.
|
||||
}
|
||||
|
||||
int retCode;
|
||||
if ((retCode = inflateInit2(&strm, windowBits)) != Z_OK) {
|
||||
// COV_NF_START - no real way to force this in a unittest (we guard all args)
|
||||
if (error) {
|
||||
NSDictionary *userInfo = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:retCode]
|
||||
forKey:GTMNSDataZlibErrorKey];
|
||||
*error = [NSError errorWithDomain:GTMNSDataZlibErrorDomain
|
||||
code:GTMNSDataZlibErrorInternal
|
||||
userInfo:userInfo];
|
||||
}
|
||||
return nil;
|
||||
// COV_NF_END
|
||||
}
|
||||
|
||||
// hint the size at 4x the input size
|
||||
NSMutableData *result = [NSMutableData dataWithCapacity:(length*4)];
|
||||
unsigned char output[kChunkSize];
|
||||
|
||||
// loop to collect the data
|
||||
do {
|
||||
// update what we're passing in
|
||||
strm.avail_out = kChunkSize;
|
||||
strm.next_out = output;
|
||||
retCode = inflate(&strm, Z_NO_FLUSH);
|
||||
if ((retCode != Z_OK) && (retCode != Z_STREAM_END)) {
|
||||
if (error) {
|
||||
NSMutableDictionary *userInfo =
|
||||
[NSMutableDictionary dictionaryWithObject:[NSNumber numberWithInt:retCode]
|
||||
forKey:GTMNSDataZlibErrorKey];
|
||||
if (strm.msg) {
|
||||
NSString *message = [NSString stringWithUTF8String:strm.msg];
|
||||
if (message) {
|
||||
[userInfo setObject:message forKey:NSLocalizedDescriptionKey];
|
||||
}
|
||||
}
|
||||
*error = [NSError errorWithDomain:GTMNSDataZlibErrorDomain
|
||||
code:GTMNSDataZlibErrorInternal
|
||||
userInfo:userInfo];
|
||||
}
|
||||
inflateEnd(&strm);
|
||||
return nil;
|
||||
}
|
||||
// collect what we got
|
||||
unsigned gotBack = kChunkSize - strm.avail_out;
|
||||
if (gotBack > 0) {
|
||||
[result appendBytes:output length:gotBack];
|
||||
}
|
||||
|
||||
} while (retCode == Z_OK);
|
||||
|
||||
// make sure there wasn't more data tacked onto the end of a valid compressed
|
||||
// stream.
|
||||
if (strm.avail_in != 0) {
|
||||
if (error) {
|
||||
NSDictionary *userInfo =
|
||||
[NSDictionary dictionaryWithObject:[NSNumber numberWithUnsignedInt:strm.avail_in]
|
||||
forKey:GTMNSDataZlibRemainingBytesKey];
|
||||
*error = [NSError errorWithDomain:GTMNSDataZlibErrorDomain
|
||||
code:GTMNSDataZlibErrorDataRemaining
|
||||
userInfo:userInfo];
|
||||
}
|
||||
result = nil;
|
||||
}
|
||||
// the only way out of the loop was by hitting the end of the stream
|
||||
_GTMDevAssert(retCode == Z_STREAM_END,
|
||||
@"thought we finished inflate w/o getting a result of stream end, code %d",
|
||||
retCode);
|
||||
|
||||
// clean up
|
||||
inflateEnd(&strm);
|
||||
|
||||
return result;
|
||||
} // gtm_dataByInflatingBytes:length:windowBits:
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@implementation NSData (GTMZLibAdditions)
|
||||
|
||||
+ (NSData *)gtm_dataByGzippingBytes:(const void *)bytes
|
||||
length:(NSUInteger)length {
|
||||
return [self gtm_dataByGzippingBytes:bytes length:length error:NULL];
|
||||
} // gtm_dataByGzippingBytes:length:
|
||||
|
||||
+ (NSData *)gtm_dataByGzippingBytes:(const void *)bytes
|
||||
length:(NSUInteger)length
|
||||
error:(NSError **)error {
|
||||
return [self gtm_dataByCompressingBytes:bytes
|
||||
length:length
|
||||
compressionLevel:Z_DEFAULT_COMPRESSION
|
||||
mode:CompressionModeGzip
|
||||
error:error];
|
||||
} // gtm_dataByGzippingBytes:length:error:
|
||||
|
||||
+ (NSData *)gtm_dataByGzippingData:(NSData *)data {
|
||||
return [self gtm_dataByGzippingData:data error:NULL];
|
||||
} // gtm_dataByGzippingData:
|
||||
|
||||
+ (NSData *)gtm_dataByGzippingData:(NSData *)data error:(NSError **)error {
|
||||
return [self gtm_dataByCompressingBytes:[data bytes]
|
||||
length:[data length]
|
||||
compressionLevel:Z_DEFAULT_COMPRESSION
|
||||
mode:CompressionModeGzip
|
||||
error:error];
|
||||
} // gtm_dataByGzippingData:error:
|
||||
|
||||
+ (NSData *)gtm_dataByGzippingBytes:(const void *)bytes
|
||||
length:(NSUInteger)length
|
||||
compressionLevel:(int)level {
|
||||
return [self gtm_dataByGzippingBytes:bytes
|
||||
length:length
|
||||
compressionLevel:level
|
||||
error:NULL];
|
||||
} // gtm_dataByGzippingBytes:length:level:
|
||||
|
||||
+ (NSData *)gtm_dataByGzippingBytes:(const void *)bytes
|
||||
length:(NSUInteger)length
|
||||
compressionLevel:(int)level
|
||||
error:(NSError **)error{
|
||||
return [self gtm_dataByCompressingBytes:bytes
|
||||
length:length
|
||||
compressionLevel:level
|
||||
mode:CompressionModeGzip
|
||||
error:error];
|
||||
} // gtm_dataByGzippingBytes:length:level:error
|
||||
|
||||
+ (NSData *)gtm_dataByGzippingData:(NSData *)data
|
||||
compressionLevel:(int)level {
|
||||
return [self gtm_dataByGzippingData:data
|
||||
compressionLevel:level
|
||||
error:NULL];
|
||||
} // gtm_dataByGzippingData:level:
|
||||
|
||||
+ (NSData *)gtm_dataByGzippingData:(NSData *)data
|
||||
compressionLevel:(int)level
|
||||
error:(NSError **)error{
|
||||
return [self gtm_dataByCompressingBytes:[data bytes]
|
||||
length:[data length]
|
||||
compressionLevel:level
|
||||
mode:CompressionModeGzip
|
||||
error:error];
|
||||
} // gtm_dataByGzippingData:level:error
|
||||
|
||||
#pragma mark -
|
||||
|
||||
+ (NSData *)gtm_dataByDeflatingBytes:(const void *)bytes
|
||||
length:(NSUInteger)length {
|
||||
return [self gtm_dataByDeflatingBytes:bytes
|
||||
length:length
|
||||
error:NULL];
|
||||
} // gtm_dataByDeflatingBytes:length:
|
||||
|
||||
+ (NSData *)gtm_dataByDeflatingBytes:(const void *)bytes
|
||||
length:(NSUInteger)length
|
||||
error:(NSError **)error{
|
||||
return [self gtm_dataByCompressingBytes:bytes
|
||||
length:length
|
||||
compressionLevel:Z_DEFAULT_COMPRESSION
|
||||
mode:CompressionModeZlib
|
||||
error:error];
|
||||
} // gtm_dataByDeflatingBytes:length:error
|
||||
|
||||
+ (NSData *)gtm_dataByDeflatingData:(NSData *)data {
|
||||
return [self gtm_dataByDeflatingData:data error:NULL];
|
||||
} // gtm_dataByDeflatingData:
|
||||
|
||||
+ (NSData *)gtm_dataByDeflatingData:(NSData *)data error:(NSError **)error {
|
||||
return [self gtm_dataByCompressingBytes:[data bytes]
|
||||
length:[data length]
|
||||
compressionLevel:Z_DEFAULT_COMPRESSION
|
||||
mode:CompressionModeZlib
|
||||
error:error];
|
||||
} // gtm_dataByDeflatingData:
|
||||
|
||||
+ (NSData *)gtm_dataByDeflatingBytes:(const void *)bytes
|
||||
length:(NSUInteger)length
|
||||
compressionLevel:(int)level {
|
||||
return [self gtm_dataByDeflatingBytes:bytes
|
||||
length:length
|
||||
compressionLevel:level
|
||||
error:NULL];
|
||||
} // gtm_dataByDeflatingBytes:length:level:
|
||||
|
||||
+ (NSData *)gtm_dataByDeflatingBytes:(const void *)bytes
|
||||
length:(NSUInteger)length
|
||||
compressionLevel:(int)level
|
||||
error:(NSError **)error {
|
||||
return [self gtm_dataByCompressingBytes:bytes
|
||||
length:length
|
||||
compressionLevel:level
|
||||
mode:CompressionModeZlib
|
||||
error:error];
|
||||
} // gtm_dataByDeflatingBytes:length:level:error:
|
||||
|
||||
+ (NSData *)gtm_dataByDeflatingData:(NSData *)data
|
||||
compressionLevel:(int)level {
|
||||
return [self gtm_dataByDeflatingData:data
|
||||
compressionLevel:level
|
||||
error:NULL];
|
||||
} // gtm_dataByDeflatingData:level:
|
||||
|
||||
+ (NSData *)gtm_dataByDeflatingData:(NSData *)data
|
||||
compressionLevel:(int)level
|
||||
error:(NSError **)error {
|
||||
return [self gtm_dataByCompressingBytes:[data bytes]
|
||||
length:[data length]
|
||||
compressionLevel:level
|
||||
mode:CompressionModeZlib
|
||||
error:error];
|
||||
} // gtm_dataByDeflatingData:level:error:
|
||||
|
||||
#pragma mark -
|
||||
|
||||
+ (NSData *)gtm_dataByInflatingBytes:(const void *)bytes
|
||||
length:(NSUInteger)length {
|
||||
return [self gtm_dataByInflatingBytes:bytes
|
||||
length:length
|
||||
error:NULL];
|
||||
} // gtm_dataByInflatingBytes:length:
|
||||
|
||||
+ (NSData *)gtm_dataByInflatingBytes:(const void *)bytes
|
||||
length:(NSUInteger)length
|
||||
error:(NSError **)error {
|
||||
return [self gtm_dataByInflatingBytes:bytes
|
||||
length:length
|
||||
isRawData:NO
|
||||
error:error];
|
||||
} // gtm_dataByInflatingBytes:length:error:
|
||||
|
||||
+ (NSData *)gtm_dataByInflatingData:(NSData *)data {
|
||||
return [self gtm_dataByInflatingData:data error:NULL];
|
||||
} // gtm_dataByInflatingData:
|
||||
|
||||
+ (NSData *)gtm_dataByInflatingData:(NSData *)data
|
||||
error:(NSError **)error {
|
||||
return [self gtm_dataByInflatingBytes:[data bytes]
|
||||
length:[data length]
|
||||
isRawData:NO
|
||||
error:error];
|
||||
} // gtm_dataByInflatingData:
|
||||
|
||||
#pragma mark -
|
||||
|
||||
+ (NSData *)gtm_dataByRawDeflatingBytes:(const void *)bytes
|
||||
length:(NSUInteger)length {
|
||||
return [self gtm_dataByRawDeflatingBytes:(const void *)bytes
|
||||
length:(NSUInteger)length
|
||||
error:NULL];
|
||||
} // gtm_dataByRawDeflatingBytes:length:
|
||||
|
||||
+ (NSData *)gtm_dataByRawDeflatingBytes:(const void *)bytes
|
||||
length:(NSUInteger)length
|
||||
error:(NSError **)error {
|
||||
return [self gtm_dataByCompressingBytes:bytes
|
||||
length:length
|
||||
compressionLevel:Z_DEFAULT_COMPRESSION
|
||||
mode:CompressionModeRaw
|
||||
error:error];
|
||||
} // gtm_dataByRawDeflatingBytes:length:error:
|
||||
|
||||
+ (NSData *)gtm_dataByRawDeflatingData:(NSData *)data {
|
||||
return [self gtm_dataByRawDeflatingData:data error:NULL];
|
||||
} // gtm_dataByRawDeflatingData:
|
||||
|
||||
+ (NSData *)gtm_dataByRawDeflatingData:(NSData *)data error:(NSError **)error {
|
||||
return [self gtm_dataByCompressingBytes:[data bytes]
|
||||
length:[data length]
|
||||
compressionLevel:Z_DEFAULT_COMPRESSION
|
||||
mode:CompressionModeRaw
|
||||
error:error];
|
||||
} // gtm_dataByRawDeflatingData:error:
|
||||
|
||||
+ (NSData *)gtm_dataByRawDeflatingBytes:(const void *)bytes
|
||||
length:(NSUInteger)length
|
||||
compressionLevel:(int)level {
|
||||
return [self gtm_dataByRawDeflatingBytes:bytes
|
||||
length:length
|
||||
compressionLevel:level
|
||||
error:NULL];
|
||||
} // gtm_dataByRawDeflatingBytes:length:compressionLevel:
|
||||
|
||||
+ (NSData *)gtm_dataByRawDeflatingBytes:(const void *)bytes
|
||||
length:(NSUInteger)length
|
||||
compressionLevel:(int)level
|
||||
error:(NSError **)error{
|
||||
return [self gtm_dataByCompressingBytes:bytes
|
||||
length:length
|
||||
compressionLevel:level
|
||||
mode:CompressionModeRaw
|
||||
error:error];
|
||||
} // gtm_dataByRawDeflatingBytes:length:compressionLevel:error:
|
||||
|
||||
+ (NSData *)gtm_dataByRawDeflatingData:(NSData *)data
|
||||
compressionLevel:(int)level {
|
||||
return [self gtm_dataByRawDeflatingData:data
|
||||
compressionLevel:level
|
||||
error:NULL];
|
||||
} // gtm_dataByRawDeflatingData:compressionLevel:
|
||||
|
||||
+ (NSData *)gtm_dataByRawDeflatingData:(NSData *)data
|
||||
compressionLevel:(int)level
|
||||
error:(NSError **)error {
|
||||
return [self gtm_dataByCompressingBytes:[data bytes]
|
||||
length:[data length]
|
||||
compressionLevel:level
|
||||
mode:CompressionModeRaw
|
||||
error:error];
|
||||
} // gtm_dataByRawDeflatingData:compressionLevel:error:
|
||||
|
||||
+ (NSData *)gtm_dataByRawInflatingBytes:(const void *)bytes
|
||||
length:(NSUInteger)length {
|
||||
return [self gtm_dataByInflatingBytes:bytes
|
||||
length:length
|
||||
error:NULL];
|
||||
} // gtm_dataByRawInflatingBytes:length:
|
||||
|
||||
+ (NSData *)gtm_dataByRawInflatingBytes:(const void *)bytes
|
||||
length:(NSUInteger)length
|
||||
error:(NSError **)error{
|
||||
return [self gtm_dataByInflatingBytes:bytes
|
||||
length:length
|
||||
isRawData:YES
|
||||
error:error];
|
||||
} // gtm_dataByRawInflatingBytes:length:error:
|
||||
|
||||
+ (NSData *)gtm_dataByRawInflatingData:(NSData *)data {
|
||||
return [self gtm_dataByRawInflatingData:data
|
||||
error:NULL];
|
||||
} // gtm_dataByRawInflatingData:
|
||||
|
||||
+ (NSData *)gtm_dataByRawInflatingData:(NSData *)data
|
||||
error:(NSError **)error {
|
||||
return [self gtm_dataByInflatingBytes:[data bytes]
|
||||
length:[data length]
|
||||
isRawData:YES
|
||||
error:error];
|
||||
} // gtm_dataByRawInflatingData:error:
|
||||
|
||||
@end
|
||||
40
My Mind/Pods/GoogleToolboxForMac/Foundation/GTMNSDictionary+URLArguments.h
generated
Normal file
40
My Mind/Pods/GoogleToolboxForMac/Foundation/GTMNSDictionary+URLArguments.h
generated
Normal file
@@ -0,0 +1,40 @@
|
||||
//
|
||||
// GTMNSDictionary+URLArguments.h
|
||||
//
|
||||
// Copyright 2006-2008 Google Inc.
|
||||
//
|
||||
// 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 <Foundation/Foundation.h>
|
||||
|
||||
/// Utility for building a URL or POST argument string.
|
||||
@interface NSDictionary (GTMNSDictionaryURLArgumentsAdditions)
|
||||
|
||||
/// Returns a dictionary of the decoded key-value pairs in a http arguments
|
||||
/// string of the form key1=value1&key2=value2&...&keyN=valueN.
|
||||
/// Keys and values will be unescaped automatically.
|
||||
/// Only the first value for a repeated key is returned.
|
||||
///
|
||||
/// NOTE: Apps targeting iOS 8 or OS X 10.10 and later should use
|
||||
/// NSURLComponents and NSURLQueryItem to create URLs with
|
||||
/// query arguments instead of using these category methods.
|
||||
+ (NSDictionary *)gtm_dictionaryWithHttpArgumentsString:(NSString *)argString;
|
||||
|
||||
/// Gets a string representation of the dictionary in the form
|
||||
/// key1=value1&key2=value2&...&keyN=valueN, suitable for use as either
|
||||
/// URL arguments (after a '?') or POST body. Keys and values will be escaped
|
||||
/// automatically, so should be unescaped in the dictionary.
|
||||
- (NSString *)gtm_httpArgumentsString;
|
||||
|
||||
@end
|
||||
77
My Mind/Pods/GoogleToolboxForMac/Foundation/GTMNSDictionary+URLArguments.m
generated
Normal file
77
My Mind/Pods/GoogleToolboxForMac/Foundation/GTMNSDictionary+URLArguments.m
generated
Normal file
@@ -0,0 +1,77 @@
|
||||
//
|
||||
// GTMNSDictionary+URLArguments.m
|
||||
//
|
||||
// Copyright 2006-2008 Google Inc.
|
||||
//
|
||||
// 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 "GTMNSDictionary+URLArguments.h"
|
||||
#import "GTMNSString+URLArguments.h"
|
||||
#import "GTMMethodCheck.h"
|
||||
#import "GTMDefines.h"
|
||||
|
||||
|
||||
// Export a nonsense symbol to suppress a libtool warning when this is linked alone in a static lib.
|
||||
__attribute__((visibility("default")))
|
||||
char GTMNSDictionaryURLArgumentsExportToSuppressLibToolWarning = 0;
|
||||
|
||||
|
||||
@implementation NSDictionary (GTMNSDictionaryURLArgumentsAdditions)
|
||||
|
||||
GTM_METHOD_CHECK(NSString, gtm_stringByEscapingForURLArgument);
|
||||
GTM_METHOD_CHECK(NSString, gtm_stringByUnescapingFromURLArgument);
|
||||
|
||||
+ (NSDictionary *)gtm_dictionaryWithHttpArgumentsString:(NSString *)argString {
|
||||
NSMutableDictionary* ret = [NSMutableDictionary dictionary];
|
||||
NSArray* components = [argString componentsSeparatedByString:@"&"];
|
||||
NSString* component;
|
||||
// Use reverse order so that the first occurrence of a key replaces
|
||||
// those subsequent.
|
||||
for (component in [components reverseObjectEnumerator]) {
|
||||
if ([component length] == 0)
|
||||
continue;
|
||||
NSRange pos = [component rangeOfString:@"="];
|
||||
NSString *key;
|
||||
NSString *val;
|
||||
if (pos.location == NSNotFound) {
|
||||
key = [component gtm_stringByUnescapingFromURLArgument];
|
||||
val = @"";
|
||||
} else {
|
||||
key = [[component substringToIndex:pos.location]
|
||||
gtm_stringByUnescapingFromURLArgument];
|
||||
val = [[component substringFromIndex:pos.location + pos.length]
|
||||
gtm_stringByUnescapingFromURLArgument];
|
||||
}
|
||||
// gtm_stringByUnescapingFromURLArgument returns nil on invalid UTF8
|
||||
// and NSMutableDictionary raises an exception when passed nil values.
|
||||
if (!key) key = @"";
|
||||
if (!val) val = @"";
|
||||
[ret setObject:val forKey:key];
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
- (NSString *)gtm_httpArgumentsString {
|
||||
NSMutableArray* arguments = [NSMutableArray arrayWithCapacity:[self count]];
|
||||
NSString* key;
|
||||
for (key in self) {
|
||||
[arguments addObject:[NSString stringWithFormat:@"%@=%@",
|
||||
[key gtm_stringByEscapingForURLArgument],
|
||||
[[[self objectForKey:key] description] gtm_stringByEscapingForURLArgument]]];
|
||||
}
|
||||
|
||||
return [arguments componentsJoinedByString:@"&"];
|
||||
}
|
||||
|
||||
@end
|
||||
45
My Mind/Pods/GoogleToolboxForMac/Foundation/GTMNSString+URLArguments.h
generated
Normal file
45
My Mind/Pods/GoogleToolboxForMac/Foundation/GTMNSString+URLArguments.h
generated
Normal file
@@ -0,0 +1,45 @@
|
||||
//
|
||||
// GTMNSString+URLArguments.h
|
||||
//
|
||||
// Copyright 2006-2008 Google Inc.
|
||||
//
|
||||
// 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 <Foundation/Foundation.h>
|
||||
|
||||
/// Utilities for encoding and decoding URL arguments.
|
||||
@interface NSString (GTMNSStringURLArgumentsAdditions)
|
||||
|
||||
/// Returns a string that is escaped properly to be a URL argument.
|
||||
///
|
||||
/// This differs from stringByAddingPercentEscapesUsingEncoding: in that it
|
||||
/// will escape all the reserved characters (per RFC 3986
|
||||
/// <http://www.ietf.org/rfc/rfc3986.txt>) which
|
||||
/// stringByAddingPercentEscapesUsingEncoding would leave.
|
||||
///
|
||||
/// This will also escape '%', so this should not be used on a string that has
|
||||
/// already been escaped unless double-escaping is the desired result.
|
||||
///
|
||||
/// NOTE: Apps targeting iOS 8 or OS X 10.10 and later should use
|
||||
/// NSURLComponents and NSURLQueryItem to create properly-escaped
|
||||
/// URLs instead of using these category methods.
|
||||
- (NSString*)gtm_stringByEscapingForURLArgument;
|
||||
|
||||
/// Returns the unescaped version of a URL argument
|
||||
///
|
||||
/// This has the same behavior as stringByReplacingPercentEscapesUsingEncoding:,
|
||||
/// except that it will also convert '+' to space.
|
||||
- (NSString*)gtm_stringByUnescapingFromURLArgument;
|
||||
|
||||
@end
|
||||
48
My Mind/Pods/GoogleToolboxForMac/Foundation/GTMNSString+URLArguments.m
generated
Normal file
48
My Mind/Pods/GoogleToolboxForMac/Foundation/GTMNSString+URLArguments.m
generated
Normal file
@@ -0,0 +1,48 @@
|
||||
//
|
||||
// GTMNSString+URLArguments.m
|
||||
//
|
||||
// Copyright 2006-2008 Google Inc.
|
||||
//
|
||||
// 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 "GTMNSString+URLArguments.h"
|
||||
|
||||
@implementation NSString (GTMNSStringURLArgumentsAdditions)
|
||||
|
||||
- (NSString *)gtm_stringByEscapingForURLArgument {
|
||||
// Encode all the reserved characters, per RFC 3986
|
||||
// (<http://www.ietf.org/rfc/rfc3986.txt>)
|
||||
CFStringRef escaped =
|
||||
CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault,
|
||||
(CFStringRef)self,
|
||||
NULL,
|
||||
(CFStringRef)@"!*'();:@&=+$,/?%#[]",
|
||||
kCFStringEncodingUTF8);
|
||||
#if defined(__has_feature) && __has_feature(objc_arc)
|
||||
return CFBridgingRelease(escaped);
|
||||
#else
|
||||
return [(NSString *)escaped autorelease];
|
||||
#endif
|
||||
}
|
||||
|
||||
- (NSString *)gtm_stringByUnescapingFromURLArgument {
|
||||
NSMutableString *resultString = [NSMutableString stringWithString:self];
|
||||
[resultString replaceOccurrencesOfString:@"+"
|
||||
withString:@" "
|
||||
options:NSLiteralSearch
|
||||
range:NSMakeRange(0, [resultString length])];
|
||||
return [resultString stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
|
||||
}
|
||||
|
||||
@end
|
||||
392
My Mind/Pods/GoogleToolboxForMac/GTMDefines.h
generated
Normal file
392
My Mind/Pods/GoogleToolboxForMac/GTMDefines.h
generated
Normal file
@@ -0,0 +1,392 @@
|
||||
//
|
||||
// GTMDefines.h
|
||||
//
|
||||
// Copyright 2008 Google Inc.
|
||||
//
|
||||
// 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 <AvailabilityMacros.h>
|
||||
#include <TargetConditionals.h>
|
||||
|
||||
#ifdef __OBJC__
|
||||
#include <Foundation/NSObjCRuntime.h>
|
||||
#endif // __OBJC__
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
#include <Availability.h>
|
||||
#endif // TARGET_OS_IPHONE
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// CPP symbols that can be overridden in a prefix to control how the toolbox
|
||||
// is compiled.
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
|
||||
// By setting the GTM_CONTAINERS_VALIDATION_FAILED_LOG and
|
||||
// GTM_CONTAINERS_VALIDATION_FAILED_ASSERT macros you can control what happens
|
||||
// when a validation fails. If you implement your own validators, you may want
|
||||
// to control their internals using the same macros for consistency.
|
||||
#ifndef GTM_CONTAINERS_VALIDATION_FAILED_ASSERT
|
||||
#define GTM_CONTAINERS_VALIDATION_FAILED_ASSERT 0
|
||||
#endif
|
||||
|
||||
// Ensure __has_feature and __has_extension are safe to use.
|
||||
// See http://clang-analyzer.llvm.org/annotations.html
|
||||
#ifndef __has_feature // Optional.
|
||||
#define __has_feature(x) 0 // Compatibility with non-clang compilers.
|
||||
#endif
|
||||
|
||||
#ifndef __has_extension
|
||||
#define __has_extension __has_feature // Compatibility with pre-3.0 compilers.
|
||||
#endif
|
||||
|
||||
// Give ourselves a consistent way to do inlines. Apple's macros even use
|
||||
// a few different actual definitions, so we're based off of the foundation
|
||||
// one.
|
||||
#if !defined(GTM_INLINE)
|
||||
#if (defined (__GNUC__) && (__GNUC__ == 4)) || defined (__clang__)
|
||||
#define GTM_INLINE static __inline__ __attribute__((always_inline))
|
||||
#else
|
||||
#define GTM_INLINE static __inline__
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Give ourselves a consistent way of doing externs that links up nicely
|
||||
// when mixing objc and objc++
|
||||
#if !defined (GTM_EXTERN)
|
||||
#if defined __cplusplus
|
||||
#define GTM_EXTERN extern "C"
|
||||
#define GTM_EXTERN_C_BEGIN extern "C" {
|
||||
#define GTM_EXTERN_C_END }
|
||||
#else
|
||||
#define GTM_EXTERN extern
|
||||
#define GTM_EXTERN_C_BEGIN
|
||||
#define GTM_EXTERN_C_END
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Give ourselves a consistent way of exporting things if we have visibility
|
||||
// set to hidden.
|
||||
#if !defined (GTM_EXPORT)
|
||||
#define GTM_EXPORT __attribute__((visibility("default")))
|
||||
#endif
|
||||
|
||||
// Give ourselves a consistent way of declaring something as unused. This
|
||||
// doesn't use __unused because that is only supported in gcc 4.2 and greater.
|
||||
#if !defined (GTM_UNUSED)
|
||||
#define GTM_UNUSED(x) ((void)(x))
|
||||
#endif
|
||||
|
||||
// _GTMDevLog & _GTMDevAssert
|
||||
//
|
||||
// _GTMDevLog & _GTMDevAssert are meant to be a very lightweight shell for
|
||||
// developer level errors. This implementation simply macros to NSLog/NSAssert.
|
||||
// It is not intended to be a general logging/reporting system.
|
||||
//
|
||||
// Please see http://code.google.com/p/google-toolbox-for-mac/wiki/DevLogNAssert
|
||||
// for a little more background on the usage of these macros.
|
||||
//
|
||||
// _GTMDevLog log some error/problem in debug builds
|
||||
// _GTMDevAssert assert if condition isn't met w/in a method/function
|
||||
// in all builds.
|
||||
//
|
||||
// To replace this system, just provide different macro definitions in your
|
||||
// prefix header. Remember, any implementation you provide *must* be thread
|
||||
// safe since this could be called by anything in what ever situtation it has
|
||||
// been placed in.
|
||||
//
|
||||
|
||||
// We only define the simple macros if nothing else has defined this.
|
||||
#ifndef _GTMDevLog
|
||||
|
||||
#ifdef DEBUG
|
||||
#define _GTMDevLog(...) NSLog(__VA_ARGS__)
|
||||
#else
|
||||
#define _GTMDevLog(...) do { } while (0)
|
||||
#endif
|
||||
|
||||
#endif // _GTMDevLog
|
||||
|
||||
#ifndef _GTMDevAssert
|
||||
// we directly invoke the NSAssert handler so we can pass on the varargs
|
||||
// (NSAssert doesn't have a macro we can use that takes varargs)
|
||||
#if !defined(NS_BLOCK_ASSERTIONS)
|
||||
#define _GTMDevAssert(condition, ...) \
|
||||
do { \
|
||||
if (!(condition)) { \
|
||||
[[NSAssertionHandler currentHandler] \
|
||||
handleFailureInFunction:(NSString *) \
|
||||
[NSString stringWithUTF8String:__PRETTY_FUNCTION__] \
|
||||
file:(NSString *)[NSString stringWithUTF8String:__FILE__] \
|
||||
lineNumber:__LINE__ \
|
||||
description:__VA_ARGS__]; \
|
||||
} \
|
||||
} while(0)
|
||||
#else // !defined(NS_BLOCK_ASSERTIONS)
|
||||
#define _GTMDevAssert(condition, ...) do { } while (0)
|
||||
#endif // !defined(NS_BLOCK_ASSERTIONS)
|
||||
|
||||
#endif // _GTMDevAssert
|
||||
|
||||
// _GTMCompileAssert
|
||||
//
|
||||
// Note: Software for current compilers should just use _Static_assert directly
|
||||
// instead of this macro.
|
||||
//
|
||||
// _GTMCompileAssert is an assert that is meant to fire at compile time if you
|
||||
// want to check things at compile instead of runtime. For example if you
|
||||
// want to check that a wchar is 4 bytes instead of 2 you would use
|
||||
// _GTMCompileAssert(sizeof(wchar_t) == 4, wchar_t_is_4_bytes_on_OS_X)
|
||||
// Note that the second "arg" is not in quotes, and must be a valid processor
|
||||
// symbol in it's own right (no spaces, punctuation etc).
|
||||
|
||||
// Wrapping this in an #ifndef allows external groups to define their own
|
||||
// compile time assert scheme.
|
||||
#ifndef _GTMCompileAssert
|
||||
#if __has_feature(c_static_assert) || __has_extension(c_static_assert)
|
||||
#define _GTMCompileAssert(test, msg) _Static_assert((test), #msg)
|
||||
#else
|
||||
// Pre-Xcode 7 support.
|
||||
//
|
||||
// We got this technique from here:
|
||||
// http://unixjunkie.blogspot.com/2007/10/better-compile-time-asserts_29.html
|
||||
#define _GTMCompileAssertSymbolInner(line, msg) _GTMCOMPILEASSERT ## line ## __ ## msg
|
||||
#define _GTMCompileAssertSymbol(line, msg) _GTMCompileAssertSymbolInner(line, msg)
|
||||
#define _GTMCompileAssert(test, msg) \
|
||||
typedef char _GTMCompileAssertSymbol(__LINE__, msg) [ ((test) ? 1 : -1) ]
|
||||
#endif // __has_feature(c_static_assert) || __has_extension(c_static_assert)
|
||||
#endif // _GTMCompileAssert
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// CPP symbols defined based on the project settings so the GTM code has
|
||||
// simple things to test against w/o scattering the knowledge of project
|
||||
// setting through all the code.
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// Provide a single constant CPP symbol that all of GTM uses for ifdefing
|
||||
// iPhone code.
|
||||
#if TARGET_OS_IPHONE // iPhone SDK
|
||||
// For iPhone specific stuff
|
||||
#define GTM_IPHONE_SDK 1
|
||||
#if TARGET_IPHONE_SIMULATOR
|
||||
#define GTM_IPHONE_DEVICE 0
|
||||
#define GTM_IPHONE_SIMULATOR 1
|
||||
#else
|
||||
#define GTM_IPHONE_DEVICE 1
|
||||
#define GTM_IPHONE_SIMULATOR 0
|
||||
#endif // TARGET_IPHONE_SIMULATOR
|
||||
// By default, GTM has provided it's own unittesting support, define this
|
||||
// to use the support provided by Xcode, especially for the Xcode4 support
|
||||
// for unittesting.
|
||||
#ifndef GTM_USING_XCTEST
|
||||
#define GTM_USING_XCTEST 0
|
||||
#endif
|
||||
#define GTM_MACOS_SDK 0
|
||||
#else
|
||||
// For MacOS specific stuff
|
||||
#define GTM_MACOS_SDK 1
|
||||
#define GTM_IPHONE_SDK 0
|
||||
#define GTM_IPHONE_SIMULATOR 0
|
||||
#define GTM_IPHONE_DEVICE 0
|
||||
#ifndef GTM_USING_XCTEST
|
||||
#define GTM_USING_XCTEST 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Some of our own availability macros
|
||||
#if GTM_MACOS_SDK
|
||||
#define GTM_AVAILABLE_ONLY_ON_IPHONE UNAVAILABLE_ATTRIBUTE
|
||||
#define GTM_AVAILABLE_ONLY_ON_MACOS
|
||||
#else
|
||||
#define GTM_AVAILABLE_ONLY_ON_IPHONE
|
||||
#define GTM_AVAILABLE_ONLY_ON_MACOS UNAVAILABLE_ATTRIBUTE
|
||||
#endif
|
||||
|
||||
// GC was dropped by Apple, define the old constant incase anyone still keys
|
||||
// off of it.
|
||||
#ifndef GTM_SUPPORT_GC
|
||||
#define GTM_SUPPORT_GC 0
|
||||
#endif
|
||||
|
||||
// Some support for advanced clang static analysis functionality
|
||||
#ifndef NS_RETURNS_RETAINED
|
||||
#if __has_feature(attribute_ns_returns_retained)
|
||||
#define NS_RETURNS_RETAINED __attribute__((ns_returns_retained))
|
||||
#else
|
||||
#define NS_RETURNS_RETAINED
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef NS_RETURNS_NOT_RETAINED
|
||||
#if __has_feature(attribute_ns_returns_not_retained)
|
||||
#define NS_RETURNS_NOT_RETAINED __attribute__((ns_returns_not_retained))
|
||||
#else
|
||||
#define NS_RETURNS_NOT_RETAINED
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef CF_RETURNS_RETAINED
|
||||
#if __has_feature(attribute_cf_returns_retained)
|
||||
#define CF_RETURNS_RETAINED __attribute__((cf_returns_retained))
|
||||
#else
|
||||
#define CF_RETURNS_RETAINED
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef CF_RETURNS_NOT_RETAINED
|
||||
#if __has_feature(attribute_cf_returns_not_retained)
|
||||
#define CF_RETURNS_NOT_RETAINED __attribute__((cf_returns_not_retained))
|
||||
#else
|
||||
#define CF_RETURNS_NOT_RETAINED
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef NS_CONSUMED
|
||||
#if __has_feature(attribute_ns_consumed)
|
||||
#define NS_CONSUMED __attribute__((ns_consumed))
|
||||
#else
|
||||
#define NS_CONSUMED
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef CF_CONSUMED
|
||||
#if __has_feature(attribute_cf_consumed)
|
||||
#define CF_CONSUMED __attribute__((cf_consumed))
|
||||
#else
|
||||
#define CF_CONSUMED
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef NS_CONSUMES_SELF
|
||||
#if __has_feature(attribute_ns_consumes_self)
|
||||
#define NS_CONSUMES_SELF __attribute__((ns_consumes_self))
|
||||
#else
|
||||
#define NS_CONSUMES_SELF
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef GTM_NONNULL
|
||||
#if defined(__has_attribute)
|
||||
#if __has_attribute(nonnull)
|
||||
#define GTM_NONNULL(x) __attribute__((nonnull x))
|
||||
#else
|
||||
#define GTM_NONNULL(x)
|
||||
#endif
|
||||
#else
|
||||
#define GTM_NONNULL(x)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Invalidates the initializer from which it's called.
|
||||
#ifndef GTMInvalidateInitializer
|
||||
#if __has_feature(objc_arc)
|
||||
#define GTMInvalidateInitializer() \
|
||||
do { \
|
||||
[self class]; /* Avoid warning of dead store to |self|. */ \
|
||||
_GTMDevAssert(NO, @"Invalid initializer."); \
|
||||
return nil; \
|
||||
} while (0)
|
||||
#else
|
||||
#define GTMInvalidateInitializer() \
|
||||
do { \
|
||||
[self release]; \
|
||||
_GTMDevAssert(NO, @"Invalid initializer."); \
|
||||
return nil; \
|
||||
} while (0)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef GTMCFAutorelease
|
||||
// GTMCFAutorelease returns an id. In contrast, Apple's CFAutorelease returns
|
||||
// a CFTypeRef.
|
||||
#if __has_feature(objc_arc)
|
||||
#define GTMCFAutorelease(x) CFBridgingRelease(x)
|
||||
#else
|
||||
#define GTMCFAutorelease(x) ([(id)x autorelease])
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __OBJC__
|
||||
|
||||
|
||||
// Macro to allow you to create NSStrings out of other macros.
|
||||
// #define FOO foo
|
||||
// NSString *fooString = GTM_NSSTRINGIFY(FOO);
|
||||
#if !defined (GTM_NSSTRINGIFY)
|
||||
#define GTM_NSSTRINGIFY_INNER(x) @#x
|
||||
#define GTM_NSSTRINGIFY(x) GTM_NSSTRINGIFY_INNER(x)
|
||||
#endif
|
||||
|
||||
// Macro to allow fast enumeration when building for 10.5 or later, and
|
||||
// reliance on NSEnumerator for 10.4. Remember, NSDictionary w/ FastEnumeration
|
||||
// does keys, so pick the right thing, nothing is done on the FastEnumeration
|
||||
// side to be sure you're getting what you wanted.
|
||||
#ifndef GTM_FOREACH_OBJECT
|
||||
#if TARGET_OS_IPHONE || !(MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5)
|
||||
#define GTM_FOREACH_ENUMEREE(element, enumeration) \
|
||||
for (element in enumeration)
|
||||
#define GTM_FOREACH_OBJECT(element, collection) \
|
||||
for (element in collection)
|
||||
#define GTM_FOREACH_KEY(element, collection) \
|
||||
for (element in collection)
|
||||
#else
|
||||
#define GTM_FOREACH_ENUMEREE(element, enumeration) \
|
||||
for (NSEnumerator *_ ## element ## _enum = enumeration; \
|
||||
(element = [_ ## element ## _enum nextObject]) != nil; )
|
||||
#define GTM_FOREACH_OBJECT(element, collection) \
|
||||
GTM_FOREACH_ENUMEREE(element, [collection objectEnumerator])
|
||||
#define GTM_FOREACH_KEY(element, collection) \
|
||||
GTM_FOREACH_ENUMEREE(element, [collection keyEnumerator])
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// ============================================================================
|
||||
|
||||
// GTM_SEL_STRING is for specifying selector (usually property) names to KVC
|
||||
// or KVO methods.
|
||||
// In debug it will generate warnings for undeclared selectors if
|
||||
// -Wunknown-selector is turned on.
|
||||
// In release it will have no runtime overhead.
|
||||
#ifndef GTM_SEL_STRING
|
||||
#ifdef DEBUG
|
||||
#define GTM_SEL_STRING(selName) NSStringFromSelector(@selector(selName))
|
||||
#else
|
||||
#define GTM_SEL_STRING(selName) @#selName
|
||||
#endif // DEBUG
|
||||
#endif // GTM_SEL_STRING
|
||||
|
||||
#ifndef GTM_WEAK
|
||||
#if __has_feature(objc_arc_weak)
|
||||
// With ARC enabled, __weak means a reference that isn't implicitly
|
||||
// retained. __weak objects are accessed through runtime functions, so
|
||||
// they are zeroed out, but this requires OS X 10.7+.
|
||||
// At clang r251041+, ARC-style zeroing weak references even work in
|
||||
// non-ARC mode.
|
||||
#define GTM_WEAK __weak
|
||||
#elif __has_feature(objc_arc)
|
||||
// ARC, but targeting 10.6 or older, where zeroing weak references don't
|
||||
// exist.
|
||||
#define GTM_WEAK __unsafe_unretained
|
||||
#else
|
||||
// With manual reference counting, __weak used to be silently ignored.
|
||||
// clang r251041 gives it the ARC semantics instead. This means they
|
||||
// now require a deployment target of 10.7, while some clients of GTM
|
||||
// still target 10.6. In these cases, expand to __unsafe_unretained instead
|
||||
#define GTM_WEAK
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif // __OBJC__
|
||||
202
My Mind/Pods/GoogleToolboxForMac/LICENSE
generated
Normal file
202
My Mind/Pods/GoogleToolboxForMac/LICENSE
generated
Normal file
@@ -0,0 +1,202 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
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.
|
||||
15
My Mind/Pods/GoogleToolboxForMac/README.md
generated
Normal file
15
My Mind/Pods/GoogleToolboxForMac/README.md
generated
Normal file
@@ -0,0 +1,15 @@
|
||||
# GTM: Google Toolbox for Mac #
|
||||
|
||||
**Project site** <https://github.com/google/google-toolbox-for-mac><br>
|
||||
**Discussion group** <http://groups.google.com/group/google-toolbox-for-mac>
|
||||
|
||||
# Google Toolbox for Mac #
|
||||
|
||||
A collection of source from different Google projects that may be of use to
|
||||
developers working other iOS or OS X projects.
|
||||
|
||||
If you find a problem/bug or want a new feature to be included in the Google
|
||||
Toolbox for Mac, please join the
|
||||
[discussion group](http://groups.google.com/group/google-toolbox-for-mac)
|
||||
or submit an
|
||||
[issue](https://github.com/google/google-toolbox-for-mac/issues).
|
||||
Reference in New Issue
Block a user