Commit 0087da9d authored by Feng Xiao's avatar Feng Xiao

Merge remote-tracking branch 'origin/master' into beta-1

Conflicts:
	src/google/protobuf/extension_set.h
parents cee703d7 f0640b5a
...@@ -34,7 +34,6 @@ ...@@ -34,7 +34,6 @@
#include <google/protobuf/stubs/hash.h> #include <google/protobuf/stubs/hash.h>
#include <google/protobuf/stubs/common.h> #include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/once.h>
#include <google/protobuf/extension_set.h> #include <google/protobuf/extension_set.h>
#include <google/protobuf/message_lite.h> #include <google/protobuf/message_lite.h>
#include <google/protobuf/io/coded_stream.h> #include <google/protobuf/io/coded_stream.h>
...@@ -1747,66 +1746,68 @@ void ExtensionSet::Extension::Free() { ...@@ -1747,66 +1746,68 @@ void ExtensionSet::Extension::Free() {
// ================================================================== // ==================================================================
// Default repeated field instances for iterator-compatible accessors // Default repeated field instances for iterator-compatible accessors
const RepeatedStringTypeTraits::RepeatedFieldType* GOOGLE_PROTOBUF_DECLARE_ONCE(repeated_primitive_generic_type_traits_once_init_);
RepeatedStringTypeTraits::default_repeated_field_ = NULL; GOOGLE_PROTOBUF_DECLARE_ONCE(repeated_string_type_traits_once_init_);
GOOGLE_PROTOBUF_DECLARE_ONCE(repeated_message_generic_type_traits_once_init_);
const RepeatedMessageGenericTypeTraits::RepeatedFieldType* void RepeatedPrimitiveGenericTypeTraits::InitializeDefaultRepeatedFields() {
RepeatedMessageGenericTypeTraits::default_repeated_field_ = NULL; default_repeated_field_int32_ = new RepeatedField<int32>;
default_repeated_field_int64_ = new RepeatedField<int64>;
default_repeated_field_uint32_ = new RepeatedField<uint32>;
default_repeated_field_uint64_ = new RepeatedField<uint64>;
default_repeated_field_double_ = new RepeatedField<double>;
default_repeated_field_float_ = new RepeatedField<float>;
default_repeated_field_bool_ = new RepeatedField<bool>;
OnShutdown(&DestroyDefaultRepeatedFields);
}
void RepeatedPrimitiveGenericTypeTraits::DestroyDefaultRepeatedFields() {
delete default_repeated_field_int32_;
delete default_repeated_field_int64_;
delete default_repeated_field_uint32_;
delete default_repeated_field_uint64_;
delete default_repeated_field_double_;
delete default_repeated_field_float_;
delete default_repeated_field_bool_;
}
#define PROTOBUF_DEFINE_DEFAULT_REPEATED(TYPE) \ void RepeatedStringTypeTraits::InitializeDefaultRepeatedFields() {
const RepeatedField<TYPE>* \ default_repeated_field_ = new RepeatedFieldType;
RepeatedPrimitiveGenericTypeTraits::default_repeated_field_##TYPE##_ = NULL; OnShutdown(&DestroyDefaultRepeatedFields);
}
PROTOBUF_DEFINE_DEFAULT_REPEATED(int32) void RepeatedStringTypeTraits::DestroyDefaultRepeatedFields() {
PROTOBUF_DEFINE_DEFAULT_REPEATED(int64) delete default_repeated_field_;
PROTOBUF_DEFINE_DEFAULT_REPEATED(uint32) }
PROTOBUF_DEFINE_DEFAULT_REPEATED(uint64)
PROTOBUF_DEFINE_DEFAULT_REPEATED(double)
PROTOBUF_DEFINE_DEFAULT_REPEATED(float)
PROTOBUF_DEFINE_DEFAULT_REPEATED(bool)
#undef PROTOBUF_DEFINE_DEFAULT_REPEATED void RepeatedMessageGenericTypeTraits::InitializeDefaultRepeatedFields() {
default_repeated_field_ = new RepeatedFieldType;
OnShutdown(&DestroyDefaultRepeatedFields);
}
struct StaticDefaultRepeatedFieldsInitializer { void RepeatedMessageGenericTypeTraits::DestroyDefaultRepeatedFields() {
StaticDefaultRepeatedFieldsInitializer() { delete default_repeated_field_;
InitializeDefaultRepeatedFields();
OnShutdown(&DestroyDefaultRepeatedFields);
}
} static_repeated_fields_initializer;
void InitializeDefaultRepeatedFields() {
RepeatedStringTypeTraits::default_repeated_field_ =
new RepeatedStringTypeTraits::RepeatedFieldType;
RepeatedMessageGenericTypeTraits::default_repeated_field_ =
new RepeatedMessageGenericTypeTraits::RepeatedFieldType;
RepeatedPrimitiveGenericTypeTraits::default_repeated_field_int32_ =
new RepeatedField<int32>;
RepeatedPrimitiveGenericTypeTraits::default_repeated_field_int64_ =
new RepeatedField<int64>;
RepeatedPrimitiveGenericTypeTraits::default_repeated_field_uint32_ =
new RepeatedField<uint32>;
RepeatedPrimitiveGenericTypeTraits::default_repeated_field_uint64_ =
new RepeatedField<uint64>;
RepeatedPrimitiveGenericTypeTraits::default_repeated_field_double_ =
new RepeatedField<double>;
RepeatedPrimitiveGenericTypeTraits::default_repeated_field_float_ =
new RepeatedField<float>;
RepeatedPrimitiveGenericTypeTraits::default_repeated_field_bool_ =
new RepeatedField<bool>;
}
void DestroyDefaultRepeatedFields() {
delete RepeatedStringTypeTraits::default_repeated_field_;
delete RepeatedMessageGenericTypeTraits::default_repeated_field_;
delete RepeatedPrimitiveGenericTypeTraits::default_repeated_field_int32_;
delete RepeatedPrimitiveGenericTypeTraits::default_repeated_field_int64_;
delete RepeatedPrimitiveGenericTypeTraits::default_repeated_field_uint32_;
delete RepeatedPrimitiveGenericTypeTraits::default_repeated_field_uint64_;
delete RepeatedPrimitiveGenericTypeTraits::default_repeated_field_double_;
delete RepeatedPrimitiveGenericTypeTraits::default_repeated_field_float_;
delete RepeatedPrimitiveGenericTypeTraits::default_repeated_field_bool_;
} }
const RepeatedField<int32>*
RepeatedPrimitiveGenericTypeTraits::default_repeated_field_int32_ = NULL;
const RepeatedField<int64>*
RepeatedPrimitiveGenericTypeTraits::default_repeated_field_int64_ = NULL;
const RepeatedField<uint32>*
RepeatedPrimitiveGenericTypeTraits::default_repeated_field_uint32_ = NULL;
const RepeatedField<uint64>*
RepeatedPrimitiveGenericTypeTraits::default_repeated_field_uint64_ = NULL;
const RepeatedField<double>*
RepeatedPrimitiveGenericTypeTraits::default_repeated_field_double_ = NULL;
const RepeatedField<float>*
RepeatedPrimitiveGenericTypeTraits::default_repeated_field_float_ = NULL;
const RepeatedField<bool>*
RepeatedPrimitiveGenericTypeTraits::default_repeated_field_bool_ = NULL;
const RepeatedStringTypeTraits::RepeatedFieldType*
RepeatedStringTypeTraits::default_repeated_field_ = NULL;
const RepeatedMessageGenericTypeTraits::RepeatedFieldType*
RepeatedMessageGenericTypeTraits::default_repeated_field_ = NULL;
} // namespace internal } // namespace internal
} // namespace protobuf } // namespace protobuf
} // namespace google } // namespace google
...@@ -46,6 +46,7 @@ ...@@ -46,6 +46,7 @@
#include <google/protobuf/stubs/common.h> #include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/logging.h> #include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/once.h>
#include <google/protobuf/repeated_field.h> #include <google/protobuf/repeated_field.h>
...@@ -723,15 +724,14 @@ class RepeatedPrimitiveTypeTraits { ...@@ -723,15 +724,14 @@ class RepeatedPrimitiveTypeTraits {
static const RepeatedFieldType* GetDefaultRepeatedField(); static const RepeatedFieldType* GetDefaultRepeatedField();
}; };
// Declared here so that this can be friended below. LIBPROTOBUF_EXPORT extern ProtobufOnceType
void InitializeDefaultRepeatedFields(); repeated_primitive_generic_type_traits_once_init_;
void DestroyDefaultRepeatedFields();
class LIBPROTOBUF_EXPORT RepeatedPrimitiveGenericTypeTraits { class LIBPROTOBUF_EXPORT RepeatedPrimitiveGenericTypeTraits {
private: private:
template<typename Type> friend class RepeatedPrimitiveTypeTraits; template<typename Type> friend class RepeatedPrimitiveTypeTraits;
friend void InitializeDefaultRepeatedFields(); static void InitializeDefaultRepeatedFields();
friend void DestroyDefaultRepeatedFields(); static void DestroyDefaultRepeatedFields();
static const RepeatedField<int32>* default_repeated_field_int32_; static const RepeatedField<int32>* default_repeated_field_int32_;
static const RepeatedField<int64>* default_repeated_field_int64_; static const RepeatedField<int64>* default_repeated_field_int64_;
static const RepeatedField<uint32>* default_repeated_field_uint32_; static const RepeatedField<uint32>* default_repeated_field_uint32_;
...@@ -766,6 +766,9 @@ template<> inline void RepeatedPrimitiveTypeTraits<TYPE>::Add( \ ...@@ -766,6 +766,9 @@ template<> inline void RepeatedPrimitiveTypeTraits<TYPE>::Add( \
} \ } \
template<> inline const RepeatedField<TYPE>* \ template<> inline const RepeatedField<TYPE>* \
RepeatedPrimitiveTypeTraits<TYPE>::GetDefaultRepeatedField() { \ RepeatedPrimitiveTypeTraits<TYPE>::GetDefaultRepeatedField() { \
GoogleOnceInit( \
&repeated_primitive_generic_type_traits_once_init_, \
&RepeatedPrimitiveGenericTypeTraits::InitializeDefaultRepeatedFields); \
return RepeatedPrimitiveGenericTypeTraits:: \ return RepeatedPrimitiveGenericTypeTraits:: \
default_repeated_field_##TYPE##_; \ default_repeated_field_##TYPE##_; \
} \ } \
...@@ -819,6 +822,9 @@ class LIBPROTOBUF_EXPORT StringTypeTraits { ...@@ -819,6 +822,9 @@ class LIBPROTOBUF_EXPORT StringTypeTraits {
} }
}; };
LIBPROTOBUF_EXPORT extern ProtobufOnceType
repeated_string_type_traits_once_init_;
class LIBPROTOBUF_EXPORT RepeatedStringTypeTraits { class LIBPROTOBUF_EXPORT RepeatedStringTypeTraits {
public: public:
typedef const string& ConstType; typedef const string& ConstType;
...@@ -862,12 +868,14 @@ class LIBPROTOBUF_EXPORT RepeatedStringTypeTraits { ...@@ -862,12 +868,14 @@ class LIBPROTOBUF_EXPORT RepeatedStringTypeTraits {
} }
static const RepeatedFieldType* GetDefaultRepeatedField() { static const RepeatedFieldType* GetDefaultRepeatedField() {
GoogleOnceInit(&repeated_string_type_traits_once_init_,
&InitializeDefaultRepeatedFields);
return default_repeated_field_; return default_repeated_field_;
} }
private: private:
friend void InitializeDefaultRepeatedFields(); static void InitializeDefaultRepeatedFields();
friend void DestroyDefaultRepeatedFields(); static void DestroyDefaultRepeatedFields();
static const RepeatedFieldType *default_repeated_field_; static const RepeatedFieldType *default_repeated_field_;
}; };
...@@ -1026,6 +1034,9 @@ class RepeatedMessageTypeTraits { ...@@ -1026,6 +1034,9 @@ class RepeatedMessageTypeTraits {
static const RepeatedFieldType* GetDefaultRepeatedField(); static const RepeatedFieldType* GetDefaultRepeatedField();
}; };
LIBPROTOBUF_EXPORT extern ProtobufOnceType
repeated_message_generic_type_traits_once_init_;
// This class exists only to hold a generic default empty repeated field for all // This class exists only to hold a generic default empty repeated field for all
// message-type repeated field extensions. // message-type repeated field extensions.
class LIBPROTOBUF_EXPORT RepeatedMessageGenericTypeTraits { class LIBPROTOBUF_EXPORT RepeatedMessageGenericTypeTraits {
...@@ -1033,14 +1044,17 @@ class LIBPROTOBUF_EXPORT RepeatedMessageGenericTypeTraits { ...@@ -1033,14 +1044,17 @@ class LIBPROTOBUF_EXPORT RepeatedMessageGenericTypeTraits {
typedef RepeatedPtrField< ::google::protobuf::MessageLite*> RepeatedFieldType; typedef RepeatedPtrField< ::google::protobuf::MessageLite*> RepeatedFieldType;
private: private:
template<typename Type> friend class RepeatedMessageTypeTraits; template<typename Type> friend class RepeatedMessageTypeTraits;
friend void InitializeDefaultRepeatedFields(); static void InitializeDefaultRepeatedFields();
friend void DestroyDefaultRepeatedFields(); static void DestroyDefaultRepeatedFields();
static const RepeatedFieldType* default_repeated_field_; static const RepeatedFieldType* default_repeated_field_;
}; };
template<typename Type> inline template<typename Type> inline
const typename RepeatedMessageTypeTraits<Type>::RepeatedFieldType* const typename RepeatedMessageTypeTraits<Type>::RepeatedFieldType*
RepeatedMessageTypeTraits<Type>::GetDefaultRepeatedField() { RepeatedMessageTypeTraits<Type>::GetDefaultRepeatedField() {
GoogleOnceInit(
&repeated_message_generic_type_traits_once_init_,
&RepeatedMessageGenericTypeTraits::InitializeDefaultRepeatedFields);
return reinterpret_cast<const RepeatedFieldType*>( return reinterpret_cast<const RepeatedFieldType*>(
RepeatedMessageGenericTypeTraits::default_repeated_field_); RepeatedMessageGenericTypeTraits::default_repeated_field_);
} }
......
...@@ -58,18 +58,6 @@ bool IsMapFieldInApi(const FieldDescriptor* field) { ...@@ -58,18 +58,6 @@ bool IsMapFieldInApi(const FieldDescriptor* field) {
} }
} // anonymous namespace } // anonymous namespace
int StringSpaceUsedExcludingSelf(const string& str) {
const void* start = &str;
const void* end = &str + 1;
if (start <= str.data() && str.data() < end) {
// The string's data is stored inside the string object itself.
return 0;
} else {
return str.capacity();
}
}
bool ParseNamedEnum(const EnumDescriptor* descriptor, bool ParseNamedEnum(const EnumDescriptor* descriptor,
const string& name, const string& name,
int* value) { int* value) {
......
...@@ -60,6 +60,18 @@ void InitEmptyString() { ...@@ -60,6 +60,18 @@ void InitEmptyString() {
OnShutdown(&DeleteEmptyString); OnShutdown(&DeleteEmptyString);
} }
int StringSpaceUsedExcludingSelf(const string& str) {
const void* start = &str;
const void* end = &str + 1;
if (start <= str.data() && str.data() < end) {
// The string's data is stored inside the string object itself.
return 0;
} else {
return str.capacity();
}
}
} // namespace internal } // namespace internal
} // namespace protobuf } // namespace protobuf
......
...@@ -89,12 +89,6 @@ LIBPROTOBUF_EXPORT inline const ::std::string& GetEmptyString() { ...@@ -89,12 +89,6 @@ LIBPROTOBUF_EXPORT inline const ::std::string& GetEmptyString() {
return GetEmptyStringAlreadyInited(); return GetEmptyStringAlreadyInited();
} }
// Defined in generated_message_reflection.cc -- not actually part of the lite
// library.
//
// TODO(jasonh): The various callers get this declaration from a variety of
// places: probably in most cases repeated_field.h. Clean these up so they all
// get the declaration from this file.
LIBPROTOBUF_EXPORT int StringSpaceUsedExcludingSelf(const string& str); LIBPROTOBUF_EXPORT int StringSpaceUsedExcludingSelf(const string& str);
......
...@@ -649,7 +649,8 @@ inline const Message& GenericTypeHandler<Message>::default_instance() { ...@@ -649,7 +649,8 @@ inline const Message& GenericTypeHandler<Message>::default_instance() {
// StringTypeHandler is exported. So, we factor out StringTypeHandlerBase, // StringTypeHandler is exported. So, we factor out StringTypeHandlerBase,
// export that, then make StringTypeHandler be a subclass which is NOT // export that, then make StringTypeHandler be a subclass which is NOT
// exported. // exported.
// TODO(kenton): There has to be a better way. // TODO(kenton): Now that StringSpaceUsedExcludingSelf() is in the lite
// library, this can be cleaned up.
class LIBPROTOBUF_EXPORT StringTypeHandlerBase { class LIBPROTOBUF_EXPORT StringTypeHandlerBase {
public: public:
typedef string Type; typedef string Type;
......
...@@ -173,7 +173,7 @@ Atomic64 Release_Load(volatile const Atomic64* ptr); ...@@ -173,7 +173,7 @@ Atomic64 Release_Load(volatile const Atomic64* ptr);
// Include our platform specific implementation. // Include our platform specific implementation.
#define GOOGLE_PROTOBUF_ATOMICOPS_ERROR \ #define GOOGLE_PROTOBUF_ATOMICOPS_ERROR \
#error "Atomic operations are not supported on your platform" "Atomic operations are not supported on your platform"
// ThreadSanitizer, http://clang.llvm.org/docs/ThreadSanitizer.html. // ThreadSanitizer, http://clang.llvm.org/docs/ThreadSanitizer.html.
#if defined(THREAD_SANITIZER) #if defined(THREAD_SANITIZER)
...@@ -183,7 +183,7 @@ Atomic64 Release_Load(volatile const Atomic64* ptr); ...@@ -183,7 +183,7 @@ Atomic64 Release_Load(volatile const Atomic64* ptr);
#if defined(GOOGLE_PROTOBUF_ARCH_IA32) || defined(GOOGLE_PROTOBUF_ARCH_X64) #if defined(GOOGLE_PROTOBUF_ARCH_IA32) || defined(GOOGLE_PROTOBUF_ARCH_X64)
#include <google/protobuf/stubs/atomicops_internals_x86_msvc.h> #include <google/protobuf/stubs/atomicops_internals_x86_msvc.h>
#else #else
GOOGLE_PROTOBUF_ATOMICOPS_ERROR #error GOOGLE_PROTOBUF_ATOMICOPS_ERROR
#endif #endif
// Solaris // Solaris
...@@ -218,15 +218,15 @@ GOOGLE_PROTOBUF_ATOMICOPS_ERROR ...@@ -218,15 +218,15 @@ GOOGLE_PROTOBUF_ATOMICOPS_ERROR
#if __has_extension(c_atomic) #if __has_extension(c_atomic)
#include <google/protobuf/stubs/atomicops_internals_generic_gcc.h> #include <google/protobuf/stubs/atomicops_internals_generic_gcc.h>
#else #else
GOOGLE_PROTOBUF_ATOMICOPS_ERROR #error GOOGLE_PROTOBUF_ATOMICOPS_ERROR
#endif #endif
#else #else
GOOGLE_PROTOBUF_ATOMICOPS_ERROR #error GOOGLE_PROTOBUF_ATOMICOPS_ERROR
#endif #endif
// Unknown. // Unknown.
#else #else
GOOGLE_PROTOBUF_ATOMICOPS_ERROR #error GOOGLE_PROTOBUF_ATOMICOPS_ERROR
#endif #endif
// On some platforms we need additional declarations to make AtomicWord // On some platforms we need additional declarations to make AtomicWord
......
...@@ -82,6 +82,15 @@ ...@@ -82,6 +82,15 @@
#define LIBPROTOC_EXPORT #define LIBPROTOC_EXPORT
#endif #endif
// These #includes are for the byte swap functions declared later on.
#ifdef _MSC_VER
#include <stdlib.h> // NOLINT(build/include)
#elif defined(__APPLE__)
#include <libkern/OSByteOrder.h>
#elif defined(__GLIBC__) || defined(__CYGWIN__)
#include <byteswap.h> // IWYU pragma: export
#endif
// =================================================================== // ===================================================================
// from google3/base/port.h // from google3/base/port.h
namespace google { namespace google {
...@@ -179,7 +188,7 @@ static const uint64 kuint64max = GOOGLE_ULONGLONG(0xFFFFFFFFFFFFFFFF); ...@@ -179,7 +188,7 @@ static const uint64 kuint64max = GOOGLE_ULONGLONG(0xFFFFFFFFFFFFFFFF);
// Provided at least since GCC 3.0. // Provided at least since GCC 3.0.
#define GOOGLE_PREDICT_TRUE(x) (__builtin_expect(!!(x), 1)) #define GOOGLE_PREDICT_TRUE(x) (__builtin_expect(!!(x), 1))
#else #else
#define GOOGLE_PREDICT_TRUE #define GOOGLE_PREDICT_TRUE(x) (x)
#endif #endif
#endif #endif
...@@ -188,7 +197,7 @@ static const uint64 kuint64max = GOOGLE_ULONGLONG(0xFFFFFFFFFFFFFFFF); ...@@ -188,7 +197,7 @@ static const uint64 kuint64max = GOOGLE_ULONGLONG(0xFFFFFFFFFFFFFFFF);
// Provided at least since GCC 3.0. // Provided at least since GCC 3.0.
#define GOOGLE_PREDICT_FALSE(x) (__builtin_expect(x, 0)) #define GOOGLE_PREDICT_FALSE(x) (__builtin_expect(x, 0))
#else #else
#define GOOGLE_PREDICT_FALSE #define GOOGLE_PREDICT_FALSE(x) (x)
#endif #endif
#endif #endif
...@@ -270,7 +279,6 @@ inline void GOOGLE_UNALIGNED_STORE64(void *p, uint64 v) { ...@@ -270,7 +279,6 @@ inline void GOOGLE_UNALIGNED_STORE64(void *p, uint64 v) {
// The following guarantees declaration of the byte swap functions, and // The following guarantees declaration of the byte swap functions, and
// defines __BYTE_ORDER for MSVC // defines __BYTE_ORDER for MSVC
#ifdef _MSC_VER #ifdef _MSC_VER
#include <stdlib.h> // NOLINT(build/include)
#define __BYTE_ORDER __LITTLE_ENDIAN #define __BYTE_ORDER __LITTLE_ENDIAN
#define bswap_16(x) _byteswap_ushort(x) #define bswap_16(x) _byteswap_ushort(x)
#define bswap_32(x) _byteswap_ulong(x) #define bswap_32(x) _byteswap_ulong(x)
...@@ -278,15 +286,11 @@ inline void GOOGLE_UNALIGNED_STORE64(void *p, uint64 v) { ...@@ -278,15 +286,11 @@ inline void GOOGLE_UNALIGNED_STORE64(void *p, uint64 v) {
#elif defined(__APPLE__) #elif defined(__APPLE__)
// Mac OS X / Darwin features // Mac OS X / Darwin features
#include <libkern/OSByteOrder.h>
#define bswap_16(x) OSSwapInt16(x) #define bswap_16(x) OSSwapInt16(x)
#define bswap_32(x) OSSwapInt32(x) #define bswap_32(x) OSSwapInt32(x)
#define bswap_64(x) OSSwapInt64(x) #define bswap_64(x) OSSwapInt64(x)
#elif defined(__GLIBC__) || defined(__CYGWIN__) #elif !defined(__GLIBC__) && !defined(__CYGWIN__)
#include <byteswap.h> // IWYU pragma: export
#else
static inline uint16 bswap_16(uint16 x) { static inline uint16 bswap_16(uint16 x) {
return static_cast<uint16>(((x & 0xFF) << 8) | ((x & 0xFF00) >> 8)); return static_cast<uint16>(((x & 0xFF) << 8) | ((x & 0xFF00) >> 8));
......
...@@ -21,7 +21,6 @@ static const int64 kSecondsFromEraToEpoch = 62135596800LL; ...@@ -21,7 +21,6 @@ static const int64 kSecondsFromEraToEpoch = 62135596800LL;
static const int64 kMinTime = -62135596800LL; // 0001-01-01T00:00:00 static const int64 kMinTime = -62135596800LL; // 0001-01-01T00:00:00
static const int64 kMaxTime = 253402300799LL; // 9999-12-31T23:59:59 static const int64 kMaxTime = 253402300799LL; // 9999-12-31T23:59:59
static const int kNanosPerSecond = 1000000000;
static const int kNanosPerMillisecond = 1000000; static const int kNanosPerMillisecond = 1000000;
static const int kNanosPerMicrosecond = 1000; static const int kNanosPerMicrosecond = 1000;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment