Google APIs Client Library for C++ | A C++ library for client applications to access Google APIs. |
This document discusses the basic types upon which the SDK is built. Some of these are introduced by the SDK itself, but are considered part of the foundation. They don't have much to do with interacting with cloud services as much as providing a programming environment.
Many of these types will appear throughout this Developer's Guide with the assumption that they are already understood. This is the only place many or all of these are documented.
Contents
Primitive Values
Type | Description |
---|---|
bool
| boolean values |
int
| Native integer values assumed to be 32-bits but shouldn't matter. |
int64
| 64-bit integer values.
|
double
| Native double values. |
googleapis::client::DateTime
|
Date and time values.
The |
Strings and Byte Sequence
Type | Description |
---|---|
char*
| These usually denote byte sequences. Sometimes, especially in the JSON related APIs, these are null-terminated C-strings. |
std::string
| Standard C++ string objects are usually used for text. Sometimes
string is used for the storage of
binary byte sequences.
|
StringPiece
|
The SDK defines this type in |
#include "googleapis/strings/stringpiece.h" // The use of asserts below is just for illustrative purposes. void ExampleUsage() { StringPiece empty_stringpiece; // This works because "" is promoted to a StringPiece, // which has an '==' operator. assert(empty_stringpiece == ""); string hello = "hello"; StringPiece from_string = hello; StringPiece from_cstr = "hello"; assert(from_string == hello); assert(from_str == hello); string bigstring = "hello, world!"; StringPiece from_substr(bigstring.c_str(), hello.size()); assert(from_substr == hello); assert(from_substr.data() == bigstring.c_str()); string from_stringpiece = from_substr.as_string(); }
Memory Management
Type | Description |
---|---|
scoped_ptr<T>
|
Scoped pointers are containers for dynamic objects. They overload
|
malloc vs new
|
Within the implementation of the googleapis::client
namespace, malloc is used when
out-of-memory errors are recoverable and new when
they are fatal. we assume new will never return
NULL however malloc may.
|
Pointers vs References vs Copy Constructors |
The client APIs typically take references or
Return results are similar where non-
Some parameters and results are objects passed by value. For
return results, this is in cases where the objects are very
lightweight or require copied memory but do not want to burden
the caller with having to manage a dynamic object. Typical
examples are
The |
#include "googleapis/base/scoped_ptr.h" void ProcessReference(const string& str); void ProcessPointer(const string* str); // The use of asserts below is just for illustrative purposes. void SampleScopedPtr() { string local_string("hello"); scoped_ptr<string> dynamic_string(new string("hello")); assert(*dynamic_string == local_string); assert(dynamic_string->size() == local_string.size()); ProcessReference(local_string); ProcessReference(*dynamic_string); ProcessPointer(&local_string); ProcessPointer(dynamic_string.get()); }
Error Status
Type | Description |
---|---|
googleapis::util::Status
|
A The types of errors returned by a given API currently undefined. Where there are specific values, they are only suggestive. Assume they will change in future versions of the API until further notice or explicitly documented.
The API always uses the full name
For more information on error handling, see the document Error Handling and Reporting. |
bool
| Methods returning a bool usually use
true for success and false otherwise.
|
#include "googleapis/client/util/status.h" #include "googleapis/util/status.h" using googleapis::client::StatusOk; using googleapis::client::StatusUnknown; googleapis::util::Status FunctionReturningStatus(int x) { if (x >= 0) return StatusOk(); else return StatusInvalidArgument("Non-negative numbers required."); } void Example(int x) { googleapis::util::Status status = FunctionReturningStatus(x); if (!status.ok()) { cerr << "Function failed: " << status.error_message(); } }
Synchronization
Type | Description |
---|---|
Mutex
|
A
The SDK implements mutex in |
Condition
| A Condition is a condition variable that can be
used for a thread to wait on. It requires another thread to
eventually change state and signal the condition so the first
may proceed. Like Mutex , condition variables are
not exposed in the public API interfaces but you are welcome
to use them from your code.
|
MutexLock
| MutexLock is used to grab and release a lock within
a C++ scope. The lock takes a mutex in its constructor. It will
lock the mutex when constructed and release the mutex when
destroyed. The constructor will block on contention so the code
between the lock and closing scope becomes a critical section.
|
#include "googleapis/base/mutex.h" class MyClass { void MyThreadsafeMethod() { MutexLock l(&mutex_); // critical section } void AnotherThreadsafeMethod() { // outside critical section { MutexLock l(&mutex_); // inside critical section } // outside critical section } void ConditionWaiter(const int64 timeout_millis) { MutexLock l(&mutex_); if (mutex_.AwaitWithTimeout(condition_, timeout_millis)) { // in critical section with condition met } else { // in critical section with timeout before condition met } } void ConditionNotifier() { MutexLock l(&mutex_); // Tell anyone waiting on this condition that it has now been met. condition_.Notify(); } private: Mutex mutex_; Condition condition_; }
Callbacks
Type | Description |
---|---|
Closure
|
A
Since
Closures are constructed using either
There are different variants of
Finally, closures may be constructed with additional variables
to pass when invoking their bound function. These bonus variables
do not count as part of the specific
|
#include "googleapis/base/callback.h" static void MyFunction(); class MyClass { public: void MyMethod(); void MyMethodWithArg(int foo); string MyOtherMethod(const string& a, int b); }; MyClass* me = new MyClass; Closure* function_closure = NewCallback(&MyFunction); function_closure->Run(); Closure* method_closure = NewCallback(me, &MyClass::MyMethod); method_closure->Run(); Closure* curried_closure = NewCallback(me, &MyClass::MyMethodWithArg, 1); curried_closure->Run(); Callback1<int>* callback_expecting_parameter = NewCallback(me, &MyClass::MyMethodWithArg); callback_expecting_parameter->Run(1); ResultCallback1<string, int>* curried_string = NewCallback(me, &MyClass::MyOtherMethod, "hello"); string x = curried_string->Run(1); ResultCallback2<string, const string&, int>* other_closure = NewCallback(me, &MyClass::MyOtherMethod); string y = other_closure->Run("hello", 1); scoped_ptr<Closure> permanent(NewPermanentCallback(&MyFunction)); permanent->Run(); permanent->Run(); permanent->Run();
Executors
An Executor
is an abstract class providing an interface that
can process one or more Closures. Concrete executors manage a queue and
processing resources to run the closures they are given.
Type | Description |
---|---|
Inline Executor | Executes closures immediately in the same thread making the request on the executor. |
#include "googleapis/base/callback.h" #include "googleapis/thread/executor.h" class MyExecutor : public googleapis::thread::Executor { public: virtual void Add(Closure* closure); ... }; googleapis::thread::Executor* executor = new MyExecutor; // I'm keeping ownrship so must guarantee the executor instance stays valid. googleapis::thread::Executor::SetDefaultExecutor(executor);