diff options
author | Michael Lehenbauer <mikelehen@gmail.com> | 2018-01-09 17:00:18 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-01-09 17:00:18 -0800 |
commit | d6bf54e2872801bc915ffd695bf2aa3051ae22ab (patch) | |
tree | 166325a14805321cbf5045fdd4a52dd634747218 /Firestore/core/src | |
parent | 2c6682c66ea7b86b3b7cb52e623086b4184d500a (diff) | |
parent | aa00c7444982de08b21604965a708d1cad5188f7 (diff) |
Merge pull request #635 from firebase/mikelehen/merge-master-to-firestore-api-changes
Merge master to firestore api changes
Diffstat (limited to 'Firestore/core/src')
11 files changed, 737 insertions, 2 deletions
diff --git a/Firestore/core/src/firebase/firestore/base/port.h b/Firestore/core/src/firebase/firestore/base/port.h index 37d1041..5e3959d 100644 --- a/Firestore/core/src/firebase/firestore/base/port.h +++ b/Firestore/core/src/firebase/firestore/base/port.h @@ -18,7 +18,7 @@ #define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_BASE_PORT_H_ #if defined(__APPLE__) -// On Apple platforms we support building via Cocoapods without CMake. When +// On Apple platforms we support building via CocoaPods without CMake. When // building this way we can't test the presence of features so predefine all // the platform-support feature macros to their expected values. diff --git a/Firestore/core/src/firebase/firestore/util/CMakeLists.txt b/Firestore/core/src/firebase/firestore/util/CMakeLists.txt index ce81363..3028a95 100644 --- a/Firestore/core/src/firebase/firestore/util/CMakeLists.txt +++ b/Firestore/core/src/firebase/firestore/util/CMakeLists.txt @@ -12,8 +12,73 @@ # See the License for the specific language governing permissions and # limitations under the License. +# firebase_firestore_util is the interface of this module. The rest of the +# libraries in here are an implementation detail of making this a +# mutli-platform build. + +add_library( + firebase_firestore_util_base + secure_random_arc4random.cc + string_printf.cc +) +target_link_libraries( + firebase_firestore_util_base + PUBLIC + absl_base +) + +# stdio-dependent bits can be built and tested everywhere +add_library( + firebase_firestore_util_stdio + assert_stdio.cc + log_stdio.cc +) +target_link_libraries( + firebase_firestore_util_stdio + PUBLIC + firebase_firestore_util_base +) + +# apple-dependent bits can only built and tested on apple plaforms +if(APPLE) + add_library( + firebase_firestore_util_apple + assert_apple.mm + log_apple.mm + ) + target_compile_options( + firebase_firestore_util_apple + PRIVATE + ${OBJC_FLAGS} + ) + target_link_libraries( + firebase_firestore_util_apple + PUBLIC + FirebaseCore + ) +endif(APPLE) + add_library( firebase_firestore_util autoid.cc - secure_random_arc4random.cc ) + +# Export a dependency on the correct logging library for this platform. All +# buildable libraries are built and tested but only the best fit is exported. +if(APPLE) + target_link_libraries( + firebase_firestore_util + PUBLIC + firebase_firestore_util_apple + firebase_firestore_util_base + ) + +else(NOT APPLE) + target_link_libraries( + firebase_firestore_util + PUBLIC + firebase_firestore_util_stdio + firebase_firestore_util_base + ) + +endif(APPLE) diff --git a/Firestore/core/src/firebase/firestore/util/assert_apple.mm b/Firestore/core/src/firebase/firestore/util/assert_apple.mm new file mode 100644 index 0000000..0447d6c --- /dev/null +++ b/Firestore/core/src/firebase/firestore/util/assert_apple.mm @@ -0,0 +1,44 @@ +/* + * Copyright 2018 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Firestore/core/src/firebase/firestore/util/firebase_assert.h" + +#import <Foundation/Foundation.h> + +#include <string.h> + +#include "Firestore/core/src/firebase/firestore/util/string_apple.h" + +namespace firebase { +namespace firestore { +namespace util { + +void FailAssert(const char* file, const char* func, const int line, const char* format, ...) { + va_list args; + va_start(args, format); + NSString *description = [[NSString alloc] initWithFormat:WrapNSStringNoCopy(format) arguments:args]; + va_end(args); + [[NSAssertionHandler currentHandler] + handleFailureInFunction:WrapNSStringNoCopy(func) + file:WrapNSStringNoCopy(file) + lineNumber:line + description:@"FIRESTORE INTERNAL ASSERTION FAILED: %@", description]; + abort(); +} + +} // namespace util +} // namespace firestore +} // namespace firebase diff --git a/Firestore/core/src/firebase/firestore/util/assert_stdio.cc b/Firestore/core/src/firebase/firestore/util/assert_stdio.cc new file mode 100644 index 0000000..b5d0b7c --- /dev/null +++ b/Firestore/core/src/firebase/firestore/util/assert_stdio.cc @@ -0,0 +1,53 @@ +/* + * Copyright 2018 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Firestore/core/src/firebase/firestore/util/firebase_assert.h" + +#include <stdarg.h> + +#include <exception> +#include <string> + +#include <absl/base/config.h> + +#include "Firestore/core/src/firebase/firestore/util/string_printf.h" + +namespace firebase { +namespace firestore { +namespace util { + +void FailAssert(const char* file, const char* func, const int line, + const char* format, ...) { + std::string message; + StringAppendF(&message, "ASSERT: %s(%d) %s: ", file, line, func); + + va_list args; + va_start(args, format); + StringAppendV(&message, format, args); + va_end(args); + +#if ABSL_HAVE_EXCEPTIONS + throw std::logic_error(message); + +#else + fprintf(stderr, "%s\n", message.c_str()); + std::terminate(); +#endif +} + +} // namespace util +} // namespace firestore +} // namespace firebase diff --git a/Firestore/core/src/firebase/firestore/util/firebase_assert.h b/Firestore/core/src/firebase/firestore/util/firebase_assert.h new file mode 100644 index 0000000..9f1bce8 --- /dev/null +++ b/Firestore/core/src/firebase/firestore/util/firebase_assert.h @@ -0,0 +1,102 @@ +/* + * Copyright 2018 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// To avoid naming-collision, this header is called firebase_assert.h instead +// of assert.h. + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_FIREBASE_ASSERT_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_FIREBASE_ASSERT_H_ + +#include <stdlib.h> + +#include "Firestore/core/src/firebase/firestore/util/log.h" + +#define FIREBASE_EXPAND_STRINGIFY_(X) #X +#define FIREBASE_EXPAND_STRINGIFY(X) FIREBASE_EXPAND_STRINGIFY_(X) + +// FIREBASE_ASSERT_* macros are not compiled out of release builds. They should +// be used for assertions that need to be propagated to end-users of SDKs. +// FIREBASE_DEV_ASSERT_* macros are compiled out of release builds, similar to +// the C assert() macro. They should be used for internal assertions that are +// only shown to SDK developers. + +// Assert condition is true, if it's false log an assert with the specified +// expression as a string. +#define FIREBASE_ASSERT_WITH_EXPRESSION(condition, expression) \ + do { \ + if (!(condition)) { \ + firebase::firestore::util::FailAssert( \ + __FILE__, __PRETTY_FUNCTION__, __LINE__, \ + FIREBASE_EXPAND_STRINGIFY(expression)); \ + } \ + } while(0) + +// Assert condition is true, if it's false log an assert with the specified +// expression as a string. Compiled out of release builds. +#if defined(NDEBUG) +#define FIREBASE_DEV_ASSERT_WITH_EXPRESSION(condition, expression) \ + { (void)(condition); } +#else +#define FIREBASE_DEV_ASSERT_WITH_EXPRESSION(condition, expression) \ + FIREBASE_ASSERT_WITH_EXPRESSION(condition, expression) +#endif // !defined(NDEBUG) + +// Custom assert() implementation that is not compiled out in release builds. +#define FIREBASE_ASSERT(expression) \ + FIREBASE_ASSERT_WITH_EXPRESSION(expression, expression) + +// Custom assert() implementation that is compiled out in release builds. +// Compiled out of release builds. +#define FIREBASE_DEV_ASSERT(expression) \ + FIREBASE_DEV_ASSERT_WITH_EXPRESSION(expression, expression) + +// Assert condition is true otherwise display the specified expression, +// message and abort. +#define FIREBASE_ASSERT_MESSAGE_WITH_EXPRESSION(condition, expression, ...) \ + do { \ + if (!(condition)) { \ + firebase::firestore::util::LogError( \ + FIREBASE_EXPAND_STRINGIFY(expression)); \ + firebase::firestore::util::FailAssert( \ + __FILE__, __PRETTY_FUNCTION__, __LINE__, __VA_ARGS__); \ + } \ + } while(0) + +// Assert condition is true otherwise display the specified expression, +// message and abort. Compiled out of release builds. +#if defined(NDEBUG) +#define FIREBASE_DEV_ASSERT_MESSAGE_WITH_EXPRESSION(condition, expression, \ + ...) \ + { (void)(condition); } +#else +#define FIREBASE_DEV_ASSERT_MESSAGE_WITH_EXPRESSION(condition, expression, \ + ...) \ + FIREBASE_ASSERT_MESSAGE_WITH_EXPRESSION(condition, expression, __VA_ARGS__) +#endif // !defined(NDEBUG) + +namespace firebase { +namespace firestore { +namespace util { + +// A no-return helper function. To raise an assertion, use Macro instead. +void FailAssert(const char* file, const char* func, const int line, + const char* format, ...); + +} // namespace util +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_FIREBASE_ASSERT_H_ diff --git a/Firestore/core/src/firebase/firestore/util/log.h b/Firestore/core/src/firebase/firestore/util/log.h new file mode 100644 index 0000000..d0cff4d --- /dev/null +++ b/Firestore/core/src/firebase/firestore/util/log.h @@ -0,0 +1,63 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_LOG_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_LOG_H_ + +#include <stdarg.h> + +namespace firebase { +namespace firestore { +namespace util { + +/// @brief Levels used when logging messages. +enum LogLevel { + /// Verbose Log Level + kLogLevelVerbose = 0, + /// Debug Log Level + kLogLevelDebug, + /// Info Log Level + kLogLevelInfo, + /// Warning Log Level + kLogLevelWarning, + /// Error Log Level + kLogLevelError, +}; + +// Common log methods. + +// All messages at or above the specified log level value are displayed. +void LogSetLevel(LogLevel level); +// Get the currently set log level. +LogLevel LogGetLevel(); +// Log a debug message to the system log. +void LogDebug(const char* format, ...); +// Log an info message to the system log. +void LogInfo(const char* format, ...); +// Log a warning to the system log. +void LogWarning(const char* format, ...); +// Log an error to the system log. +void LogError(const char* format, ...); +// Log a firebase message (implemented by the platform specific logger). +void LogMessageV(LogLevel log_level, const char* format, va_list args); +// Log a firebase message via LogMessageV(). +void LogMessage(LogLevel log_level, const char* format, ...); + +} // namespace util +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_LOG_H_ diff --git a/Firestore/core/src/firebase/firestore/util/log_apple.mm b/Firestore/core/src/firebase/firestore/util/log_apple.mm new file mode 100644 index 0000000..cb2c58e --- /dev/null +++ b/Firestore/core/src/firebase/firestore/util/log_apple.mm @@ -0,0 +1,123 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Firestore/core/src/firebase/firestore/util/log.h" + +#import <FirebaseCore/FIRLogger.h> +#import <Foundation/Foundation.h> + +#include <string> + +#include "Firestore/core/src/firebase/firestore/util/string_apple.h" + +namespace firebase { +namespace firestore { +namespace util { + +namespace { + +// Translates a C++ LogLevel to the equivalent Objective-C FIRLoggerLevel +FIRLoggerLevel ToFIRLoggerLevel(LogLevel level) { + switch (level) { + case kLogLevelVerbose: // fall through + case kLogLevelDebug: + return FIRLoggerLevelDebug; + case kLogLevelInfo: + return FIRLoggerLevelInfo; + case kLogLevelWarning: + return FIRLoggerLevelWarning; + case kLogLevelError: + return FIRLoggerLevelError; + default: + // Unsupported log level. FIRSetLoggerLevel will deal with it. + return static_cast<FIRLoggerLevel>(-1); + } +} + +} // namespace + +void LogSetLevel(LogLevel level) { + FIRSetLoggerLevel(ToFIRLoggerLevel(level)); +} + +LogLevel LogGetLevel() { + // We return the true log level. True log level is what the SDK used to + // determine whether to log instead of what parameter is used in the last call + // of LogSetLevel(). + if (FIRIsLoggableLevel(FIRLoggerLevelInfo, NO)) { + if (FIRIsLoggableLevel(FIRLoggerLevelDebug, NO)) { + // FIRLoggerLevelMax is actually kLogLevelDebug right now. We do not check + // further. + return kLogLevelDebug; + } else { + return kLogLevelInfo; + } + } else { + if (FIRIsLoggableLevel(FIRLoggerLevelWarning, NO)) { + return kLogLevelWarning; + } else { + return kLogLevelError; + } + } +} + +void LogDebug(const char* format, ...) { + va_list list; + va_start(list, format); + FIRLogBasic(FIRLoggerLevelDebug, kFIRLoggerFirestore, @"I-FST000001", + WrapNSStringNoCopy(format), list); + va_end(list); +} + +void LogInfo(const char* format, ...) { + va_list list; + va_start(list, format); + FIRLogBasic(FIRLoggerLevelInfo, kFIRLoggerFirestore, @"I-FST000001", + WrapNSStringNoCopy(format), list); + va_end(list); +} + +void LogWarning(const char* format, ...) { + va_list list; + va_start(list, format); + FIRLogBasic(FIRLoggerLevelWarning, kFIRLoggerFirestore, @"I-FST000001", + WrapNSStringNoCopy(format), list); + va_end(list); +} + +void LogError(const char* format, ...) { + va_list list; + va_start(list, format); + FIRLogBasic(FIRLoggerLevelError, kFIRLoggerFirestore, @"I-FST000001", + WrapNSStringNoCopy(format), list); + va_end(list); +} + +void LogMessageV(LogLevel log_level, const char* format, va_list args) { + FIRLogBasic(ToFIRLoggerLevel(log_level), kFIRLoggerFirestore, @"I-FST000001", + WrapNSStringNoCopy(format), args); +} + +void LogMessage(LogLevel log_level, const char* format, ...) { + va_list list; + va_start(list, format); + LogMessageV(log_level, format, list); + va_end(list); +} + +} // namespace util +} // namespace firestore +} // namespace firebase diff --git a/Firestore/core/src/firebase/firestore/util/log_stdio.cc b/Firestore/core/src/firebase/firestore/util/log_stdio.cc new file mode 100644 index 0000000..bca2dc9 --- /dev/null +++ b/Firestore/core/src/firebase/firestore/util/log_stdio.cc @@ -0,0 +1,97 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Firestore/core/src/firebase/firestore/util/log.h" + +#include <stdio.h> +#include <string> + +namespace firebase { +namespace firestore { +namespace util { + +LogLevel g_log_level = kLogLevelInfo; + +void LogSetLevel(LogLevel level) { + g_log_level = level; +} + +LogLevel LogGetLevel() { + return g_log_level; +} + +void LogDebug(const char* format, ...) { + va_list list; + va_start(list, format); + LogMessageV(kLogLevelDebug, format, list); + va_end(list); +} + +void LogInfo(const char* format, ...) { + va_list list; + va_start(list, format); + LogMessageV(kLogLevelInfo, format, list); + va_end(list); +} + +void LogWarning(const char* format, ...) { + va_list list; + va_start(list, format); + LogMessageV(kLogLevelWarning, format, list); + va_end(list); +} + +void LogError(const char* format, ...) { + va_list list; + va_start(list, format); + LogMessageV(kLogLevelError, format, list); + va_end(list); +} + +void LogMessageV(LogLevel log_level, const char* format, va_list args) { + if (log_level < g_log_level) { + return; + } + switch (log_level) { + case kLogLevelVerbose: + printf("VERBOSE: "); + break; + case kLogLevelDebug: + printf("DEBUG: "); + break; + case kLogLevelInfo: + break; + case kLogLevelWarning: + printf("WARNING: "); + break; + case kLogLevelError: + printf("ERROR: "); + break; + } + vprintf(format, args); + printf("\n"); +} + +void LogMessage(LogLevel log_level, const char* format, ...) { + va_list list; + va_start(list, format); + LogMessageV(log_level, format, list); + va_end(list); +} + +} // namespace util +} // namespace firestore +} // namespace firebase diff --git a/Firestore/core/src/firebase/firestore/util/string_apple.h b/Firestore/core/src/firebase/firestore/util/string_apple.h new file mode 100644 index 0000000..42b51dd --- /dev/null +++ b/Firestore/core/src/firebase/firestore/util/string_apple.h @@ -0,0 +1,39 @@ +/* + * Copyright 2018 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_STRING_APPLE_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_STRING_APPLE_H_ + +#import <Foundation/Foundation.h> + +namespace firebase { +namespace firestore { +namespace util { + +// Translates a C string to the equivalent NSString without making a copy. +inline NSString* WrapNSStringNoCopy(const char* c_str) { + return [[NSString alloc] initWithBytesNoCopy:const_cast<void*>(static_cast<const void*>(c_str)) + length:strlen(c_str) + encoding:NSUTF8StringEncoding + freeWhenDone:NO]; +} + + +} // namespace util +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_STRING_APPLE_H_ diff --git a/Firestore/core/src/firebase/firestore/util/string_printf.cc b/Firestore/core/src/firebase/firestore/util/string_printf.cc new file mode 100644 index 0000000..60cc564 --- /dev/null +++ b/Firestore/core/src/firebase/firestore/util/string_printf.cc @@ -0,0 +1,101 @@ +/* + * Copyright 2018 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Firestore/core/src/firebase/firestore/util/string_printf.h" + +#include <stdio.h> + +namespace firebase { +namespace firestore { +namespace util { + +void StringAppendV(std::string* dst, const char* format, va_list ap) { + // First try with a small fixed size buffer + static const int kSpaceLength = 1024; + char space[kSpaceLength]; + + // It's possible for methods that use a va_list to invalidate + // the data in it upon use. The fix is to make a copy + // of the structure before using it and use that copy instead. + va_list backup_ap; + va_copy(backup_ap, ap); + int result = vsnprintf(space, kSpaceLength, format, backup_ap); + va_end(backup_ap); + + if (result < kSpaceLength) { + if (result >= 0) { + // Normal case -- everything fit. + dst->append(space, result); + return; + } + +#ifdef _MSC_VER + // Error or MSVC running out of space. MSVC 8.0 and higher + // can be asked about space needed with the special idiom below: + va_copy(backup_ap, ap); + result = vsnprintf(nullptr, 0, format, backup_ap); + va_end(backup_ap); +#endif + + if (result < 0) { + // Just an error. + return; + } + } + + // Increase the buffer size to the size requested by vsnprintf, + // plus one for the closing \0. + size_t initial_size = dst->size(); + size_t target_size = initial_size + result; + + dst->resize(target_size + 1); + char* buf = &(*dst)[initial_size]; + int buf_remain = result + 1; + + // Restore the va_list before we use it again + va_copy(backup_ap, ap); + result = vsnprintf(buf, buf_remain, format, backup_ap); + va_end(backup_ap); + + if (result >= 0 && result < buf_remain) { + // It fit and vsnprintf copied in directly. Resize down one to + // remove the trailing \0. + dst->resize(target_size); + } else { + // Didn't fit. Leave the original string unchanged. + dst->resize(initial_size); + } +} + +std::string StringPrintf(const char* format, ...) { + va_list ap; + va_start(ap, format); + std::string result; + StringAppendV(&result, format, ap); + va_end(ap); + return result; +} + +void StringAppendF(std::string* dst, const char* format, ...) { + va_list ap; + va_start(ap, format); + StringAppendV(dst, format, ap); + va_end(ap); +} + +} // namespace util +} // namespace firestore +} // namespace firebase diff --git a/Firestore/core/src/firebase/firestore/util/string_printf.h b/Firestore/core/src/firebase/firestore/util/string_printf.h new file mode 100644 index 0000000..9e2b9c0 --- /dev/null +++ b/Firestore/core/src/firebase/firestore/util/string_printf.h @@ -0,0 +1,48 @@ +/* + * Copyright 2018 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_STRING_PRINTF_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_STRING_PRINTF_H_ + +#include <stdarg.h> + +#include <string> + +#include <absl/base/attributes.h> + +namespace firebase { +namespace firestore { +namespace util { + +/** Return a C++ string. */ +std::string StringPrintf(const char* format, ...) + ABSL_PRINTF_ATTRIBUTE(1, 2); + +/** Append result to a supplied string. */ +void StringAppendF(std::string* dst, const char* format, ...) + ABSL_PRINTF_ATTRIBUTE(2, 3); + +/** + * Lower-level routine that takes a va_list and appends to a specified + * string. All other routines are just convenience wrappers around it. + */ +void StringAppendV(std::string* dst, const char* format, va_list ap); + +} // namespace util +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_STRING_FORMAT_H_ |