revert runtime files

This commit is contained in:
yinjimmy 2015-04-17 18:26:47 +08:00
parent 5589796029
commit 1e32322350
62 changed files with 36938 additions and 0 deletions

View File

@ -5280,14 +5280,81 @@
"tools/simulator/libsimulator/lib/platform/win32/PlayerWin.h",
"tools/simulator/libsimulator/lib/platform/win32/SimulatorWin.cpp",
"tools/simulator/libsimulator/lib/platform/win32/SimulatorWin.h",
"tools/simulator/libsimulator/lib/protobuf-lite/config.h",
"tools/simulator/libsimulator/lib/protobuf-lite/google/protobuf/extension_set.cc",
"tools/simulator/libsimulator/lib/protobuf-lite/google/protobuf/extension_set.h",
"tools/simulator/libsimulator/lib/protobuf-lite/google/protobuf/generated_message_util.cc",
"tools/simulator/libsimulator/lib/protobuf-lite/google/protobuf/generated_message_util.h",
"tools/simulator/libsimulator/lib/protobuf-lite/google/protobuf/io/coded_stream.cc",
"tools/simulator/libsimulator/lib/protobuf-lite/google/protobuf/io/coded_stream.h",
"tools/simulator/libsimulator/lib/protobuf-lite/google/protobuf/io/coded_stream_inl.h",
"tools/simulator/libsimulator/lib/protobuf-lite/google/protobuf/io/zero_copy_stream.cc",
"tools/simulator/libsimulator/lib/protobuf-lite/google/protobuf/io/zero_copy_stream.h",
"tools/simulator/libsimulator/lib/protobuf-lite/google/protobuf/io/zero_copy_stream_impl.h",
"tools/simulator/libsimulator/lib/protobuf-lite/google/protobuf/io/zero_copy_stream_impl_lite.cc",
"tools/simulator/libsimulator/lib/protobuf-lite/google/protobuf/io/zero_copy_stream_impl_lite.h",
"tools/simulator/libsimulator/lib/protobuf-lite/google/protobuf/message_lite.cc",
"tools/simulator/libsimulator/lib/protobuf-lite/google/protobuf/message_lite.h",
"tools/simulator/libsimulator/lib/protobuf-lite/google/protobuf/repeated_field.cc",
"tools/simulator/libsimulator/lib/protobuf-lite/google/protobuf/repeated_field.h",
"tools/simulator/libsimulator/lib/protobuf-lite/google/protobuf/stubs/atomicops.h",
"tools/simulator/libsimulator/lib/protobuf-lite/google/protobuf/stubs/atomicops_internals_arm_gcc.h",
"tools/simulator/libsimulator/lib/protobuf-lite/google/protobuf/stubs/atomicops_internals_atomicword_compat.h",
"tools/simulator/libsimulator/lib/protobuf-lite/google/protobuf/stubs/atomicops_internals_generic_gcc.h",
"tools/simulator/libsimulator/lib/protobuf-lite/google/protobuf/stubs/atomicops_internals_macosx.h",
"tools/simulator/libsimulator/lib/protobuf-lite/google/protobuf/stubs/atomicops_internals_x86_gcc.cc",
"tools/simulator/libsimulator/lib/protobuf-lite/google/protobuf/stubs/atomicops_internals_x86_gcc.h",
"tools/simulator/libsimulator/lib/protobuf-lite/google/protobuf/stubs/atomicops_internals_x86_msvc.cc",
"tools/simulator/libsimulator/lib/protobuf-lite/google/protobuf/stubs/atomicops_internals_x86_msvc.h",
"tools/simulator/libsimulator/lib/protobuf-lite/google/protobuf/stubs/common.cc",
"tools/simulator/libsimulator/lib/protobuf-lite/google/protobuf/stubs/common.h",
"tools/simulator/libsimulator/lib/protobuf-lite/google/protobuf/stubs/hash.h",
"tools/simulator/libsimulator/lib/protobuf-lite/google/protobuf/stubs/map-util.h",
"tools/simulator/libsimulator/lib/protobuf-lite/google/protobuf/stubs/once.cc",
"tools/simulator/libsimulator/lib/protobuf-lite/google/protobuf/stubs/once.h",
"tools/simulator/libsimulator/lib/protobuf-lite/google/protobuf/stubs/platform_macros.h",
"tools/simulator/libsimulator/lib/protobuf-lite/google/protobuf/stubs/stl_util.h",
"tools/simulator/libsimulator/lib/protobuf-lite/google/protobuf/stubs/stringprintf.cc",
"tools/simulator/libsimulator/lib/protobuf-lite/google/protobuf/stubs/stringprintf.h",
"tools/simulator/libsimulator/lib/protobuf-lite/google/protobuf/stubs/template_util.h",
"tools/simulator/libsimulator/lib/protobuf-lite/google/protobuf/stubs/type_traits.h",
"tools/simulator/libsimulator/lib/protobuf-lite/google/protobuf/wire_format_lite.cc",
"tools/simulator/libsimulator/lib/protobuf-lite/google/protobuf/wire_format_lite.h",
"tools/simulator/libsimulator/lib/protobuf-lite/google/protobuf/wire_format_lite_inl.h",
"tools/simulator/libsimulator/lib/runtime/ConfigParser.cpp",
"tools/simulator/libsimulator/lib/runtime/ConfigParser.h",
"tools/simulator/libsimulator/lib/runtime/ConnectWaitLayer.cpp",
"tools/simulator/libsimulator/lib/runtime/ConnectWaitLayer.h",
"tools/simulator/libsimulator/lib/runtime/ConsoleCommand.cpp",
"tools/simulator/libsimulator/lib/runtime/ConsoleCommand.h",
"tools/simulator/libsimulator/lib/runtime/FileServer.cpp",
"tools/simulator/libsimulator/lib/runtime/FileServer.h",
"tools/simulator/libsimulator/lib/runtime/Landscape_png.cpp",
"tools/simulator/libsimulator/lib/runtime/PlayDisable_png.cpp",
"tools/simulator/libsimulator/lib/runtime/PlayEnable_png.cpp",
"tools/simulator/libsimulator/lib/runtime/Portrait_png.cpp",
"tools/simulator/libsimulator/lib/runtime/Protos.pb.cc",
"tools/simulator/libsimulator/lib/runtime/Protos.pb.h",
"tools/simulator/libsimulator/lib/runtime/ResData.h",
"tools/simulator/libsimulator/lib/runtime/Runtime.cpp",
"tools/simulator/libsimulator/lib/runtime/Runtime.h",
"tools/simulator/libsimulator/lib/runtime/RuntimeCCSImpl.cpp",
"tools/simulator/libsimulator/lib/runtime/RuntimeCCSImpl.h",
"tools/simulator/libsimulator/lib/runtime/RuntimeLuaImpl.cpp",
"tools/simulator/libsimulator/lib/runtime/RuntimeLuaImpl.h",
"tools/simulator/libsimulator/lib/runtime/RuntimeProtocol.cpp",
"tools/simulator/libsimulator/lib/runtime/RuntimeProtocol.h",
"tools/simulator/libsimulator/lib/runtime/Shine_png.cpp",
"tools/simulator/libsimulator/lib/runtime/VisibleRect.cpp",
"tools/simulator/libsimulator/lib/runtime/VisibleRect.h",
"tools/simulator/libsimulator/lib/runtime/lua_debugger.c",
"tools/simulator/libsimulator/lib/runtime/lua_debugger.h",
"tools/simulator/libsimulator/proj.android/Android.mk",
"tools/simulator/libsimulator/proj.android/hellolua/Runtime_android.cpp",
"tools/simulator/libsimulator/proj.ios_mac/ios/Prefix.pch",
"tools/simulator/libsimulator/proj.ios_mac/libsimulator.xcodeproj/project.pbxproj",
"tools/simulator/libsimulator/proj.ios_mac/mac/Prefix.pch",
"tools/simulator/libsimulator/proj.win32/Runtime_win32.cpp",
"tools/simulator/libsimulator/proj.win32/libsimulator.vcxproj",
"tools/simulator/libsimulator/proj.win32/libsimulator.vcxproj.filters",
"tools/simulator/libsimulator/proj.win32/stdafx.cpp",

View File

@ -0,0 +1,185 @@
/* Version number of package */
#define VERSION "2.5.0"
#ifdef _WIN32
/* protobuf config.h for MSVC. On other platforms, this is generated
* automatically by autoheader / autoconf / configure. */
/* the location of <hash_map> */
#define HASH_MAP_H <hash_map>
/* the namespace of hash_map/hash_set */
// Apparently Microsoft decided to move hash_map *back* to the std namespace
// in MSVC 2010:
// http://blogs.msdn.com/vcblog/archive/2009/05/25/stl-breaking-changes-in-visual-studio-2010-beta-1.aspx
// TODO(kenton): Use unordered_map instead, which is available in MSVC 2010.
#if _MSC_VER < 1310 || _MSC_VER >= 1600
#define HASH_NAMESPACE std
#else
#define HASH_NAMESPACE stdext
#endif
/* the location of <hash_set> */
#define HASH_SET_H <hash_set>
/* define if the compiler has hash_map */
#define HAVE_HASH_MAP 1
/* define if the compiler has hash_set */
#define HAVE_HASH_SET 1
/* define if you want to use zlib. See readme.txt for additional
* requirements. */
// #define HAVE_ZLIB 1
#else
/* config.h. Generated from config.h.in by configure. */
/* config.h.in. Generated from configure.ac by autoheader. */
/* the name of <hash_map> */
#define HASH_MAP_CLASS unordered_map
/* the location of <unordered_map> or <hash_map> */
#define HASH_MAP_H <unordered_map>
/* the namespace of hash_map/hash_set */
#define HASH_NAMESPACE std
/* the name of <hash_set> */
#define HASH_SET_CLASS unordered_set
/* the location of <unordered_set> or <hash_set> */
#define HASH_SET_H <unordered_set>
/* Define to 1 if you have the <dlfcn.h> header file. */
#define HAVE_DLFCN_H 1
/* Define to 1 if you have the <fcntl.h> header file. */
#define HAVE_FCNTL_H 1
/* Define to 1 if you have the `ftruncate' function. */
#define HAVE_FTRUNCATE 1
/* define if the compiler has hash_map */
#define HAVE_HASH_MAP 1
/* define if the compiler has hash_set */
#define HAVE_HASH_SET 1
/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1
/* Define to 1 if you have the <limits.h> header file. */
#define HAVE_LIMITS_H 1
/* Define to 1 if you have the <memory.h> header file. */
#define HAVE_MEMORY_H 1
/* Define to 1 if you have the `memset' function. */
#define HAVE_MEMSET 1
/* Define to 1 if you have the `mkdir' function. */
#define HAVE_MKDIR 1
/* Define if you have POSIX threads libraries and header files. */
#define HAVE_PTHREAD 1
/* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1
/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1
/* Define to 1 if you have the `strchr' function. */
#define HAVE_STRCHR 1
/* Define to 1 if you have the `strerror' function. */
#define HAVE_STRERROR 1
/* Define to 1 if you have the <strings.h> header file. */
#define HAVE_STRINGS_H 1
/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1
/* Define to 1 if you have the `strtol' function. */
#define HAVE_STRTOL 1
/* Define to 1 if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 1
/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
/* Define to 1 if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1
/* Enable classes using zlib compression. */
#define HAVE_ZLIB 1
/* Define to the sub-directory in which libtool stores uninstalled libraries.
*/
#define LT_OBJDIR ".libs/"
/* Name of package */
#define PACKAGE "protobuf"
/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT "protobuf@googlegroups.com"
/* Define to the full name of this package. */
#define PACKAGE_NAME "Protocol Buffers"
/* Define to the full name and version of this package. */
#define PACKAGE_STRING "Protocol Buffers 2.5.0"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "protobuf"
/* Define to the home page for this package. */
#define PACKAGE_URL ""
/* Define to the version of this package. */
#define PACKAGE_VERSION "2.5.0"
/* Define to necessary symbol if this constant uses a non-standard name on
your system. */
/* #undef PTHREAD_CREATE_JOINABLE */
/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1
/* Enable extensions on AIX 3, Interix. */
#ifndef _ALL_SOURCE
# define _ALL_SOURCE 1
#endif
/* Enable GNU extensions on systems that have them. */
#ifndef _GNU_SOURCE
# define _GNU_SOURCE 1
#endif
/* Enable threading extensions on Solaris. */
#ifndef _POSIX_PTHREAD_SEMANTICS
# define _POSIX_PTHREAD_SEMANTICS 1
#endif
/* Enable extensions on HP NonStop. */
#ifndef _TANDEM_SOURCE
# define _TANDEM_SOURCE 1
#endif
/* Enable general extensions on Solaris. */
#ifndef __EXTENSIONS__
# define __EXTENSIONS__ 1
#endif
/* Define to 1 if on MINIX. */
/* #undef _MINIX */
/* Define to 2 if the system does not provide POSIX.1 features except with
this defined. */
/* #undef _POSIX_1_SOURCE */
/* Define to 1 if you need to in order for `stat' and other things to work. */
/* #undef _POSIX_SOURCE */
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,54 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// http://code.google.com/p/protobuf/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Author: kenton@google.com (Kenton Varda)
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
#include <google/protobuf/generated_message_util.h>
#include <limits>
namespace google {
namespace protobuf {
namespace internal {
double Infinity() {
return std::numeric_limits<double>::infinity();
}
double NaN() {
return std::numeric_limits<double>::quiet_NaN();
}
const ::std::string kEmptyString;
} // namespace internal
} // namespace protobuf
} // namespace google

View File

@ -0,0 +1,77 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// http://code.google.com/p/protobuf/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Author: kenton@google.com (Kenton Varda)
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
//
// This file contains miscellaneous helper code used by generated code --
// including lite types -- but which should not be used directly by users.
#ifndef GOOGLE_PROTOBUF_GENERATED_MESSAGE_UTIL_H__
#define GOOGLE_PROTOBUF_GENERATED_MESSAGE_UTIL_H__
#include <string>
#include <google/protobuf/stubs/common.h>
namespace google {
namespace protobuf {
namespace internal {
// Annotation for the compiler to emit a deprecation message if a field marked
// with option 'deprecated=true' is used in the code, or for other things in
// generated code which are deprecated.
//
// For internal use in the pb.cc files, deprecation warnings are suppressed
// there.
#undef DEPRECATED_PROTOBUF_FIELD
#define PROTOBUF_DEPRECATED
// Constants for special floating point values.
LIBPROTOBUF_EXPORT double Infinity();
LIBPROTOBUF_EXPORT double NaN();
// Constant used for empty default strings.
LIBPROTOBUF_EXPORT extern const ::std::string kEmptyString;
// 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);
} // namespace internal
} // namespace protobuf
} // namespace google
#endif // GOOGLE_PROTOBUF_GENERATED_MESSAGE_UTIL_H__

View File

@ -0,0 +1,857 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// http://code.google.com/p/protobuf/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Author: kenton@google.com (Kenton Varda)
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
//
// This implementation is heavily optimized to make reads and writes
// of small values (especially varints) as fast as possible. In
// particular, we optimize for the common case that a read or a write
// will not cross the end of the buffer, since we can avoid a lot
// of branching in this case.
#include <google/protobuf/io/coded_stream_inl.h>
#include <algorithm>
#include <limits.h>
#include <google/protobuf/io/zero_copy_stream.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/stl_util.h>
namespace google {
namespace protobuf {
namespace io {
namespace {
static const int kMaxVarintBytes = 10;
static const int kMaxVarint32Bytes = 5;
inline bool NextNonEmpty(ZeroCopyInputStream* input,
const void** data, int* size) {
bool success;
do {
success = input->Next(data, size);
} while (success && *size == 0);
return success;
}
} // namespace
// CodedInputStream ==================================================
CodedInputStream::~CodedInputStream() {
if (input_ != NULL) {
BackUpInputToCurrentPosition();
}
if (total_bytes_warning_threshold_ == -2) {
GOOGLE_LOG(WARNING) << "The total number of bytes read was " << total_bytes_read_;
}
}
// Static.
int CodedInputStream::default_recursion_limit_ = 100;
void CodedInputStream::BackUpInputToCurrentPosition() {
int backup_bytes = BufferSize() + buffer_size_after_limit_ + overflow_bytes_;
if (backup_bytes > 0) {
input_->BackUp(backup_bytes);
// total_bytes_read_ doesn't include overflow_bytes_.
total_bytes_read_ -= BufferSize() + buffer_size_after_limit_;
buffer_end_ = buffer_;
buffer_size_after_limit_ = 0;
overflow_bytes_ = 0;
}
}
inline void CodedInputStream::RecomputeBufferLimits() {
buffer_end_ += buffer_size_after_limit_;
int closest_limit = min(current_limit_, total_bytes_limit_);
if (closest_limit < total_bytes_read_) {
// The limit position is in the current buffer. We must adjust
// the buffer size accordingly.
buffer_size_after_limit_ = total_bytes_read_ - closest_limit;
buffer_end_ -= buffer_size_after_limit_;
} else {
buffer_size_after_limit_ = 0;
}
}
CodedInputStream::Limit CodedInputStream::PushLimit(int byte_limit) {
// Current position relative to the beginning of the stream.
int current_position = CurrentPosition();
Limit old_limit = current_limit_;
// security: byte_limit is possibly evil, so check for negative values
// and overflow.
if (byte_limit >= 0 &&
byte_limit <= INT_MAX - current_position) {
current_limit_ = current_position + byte_limit;
} else {
// Negative or overflow.
current_limit_ = INT_MAX;
}
// We need to enforce all limits, not just the new one, so if the previous
// limit was before the new requested limit, we continue to enforce the
// previous limit.
current_limit_ = min(current_limit_, old_limit);
RecomputeBufferLimits();
return old_limit;
}
void CodedInputStream::PopLimit(Limit limit) {
// The limit passed in is actually the *old* limit, which we returned from
// PushLimit().
current_limit_ = limit;
RecomputeBufferLimits();
// We may no longer be at a legitimate message end. ReadTag() needs to be
// called again to find out.
legitimate_message_end_ = false;
}
int CodedInputStream::BytesUntilLimit() const {
if (current_limit_ == INT_MAX) return -1;
int current_position = CurrentPosition();
return current_limit_ - current_position;
}
void CodedInputStream::SetTotalBytesLimit(
int total_bytes_limit, int warning_threshold) {
// Make sure the limit isn't already past, since this could confuse other
// code.
int current_position = CurrentPosition();
total_bytes_limit_ = max(current_position, total_bytes_limit);
if (warning_threshold >= 0) {
total_bytes_warning_threshold_ = warning_threshold;
} else {
// warning_threshold is negative
total_bytes_warning_threshold_ = -1;
}
RecomputeBufferLimits();
}
void CodedInputStream::PrintTotalBytesLimitError() {
GOOGLE_LOG(ERROR) << "A protocol message was rejected because it was too "
"big (more than " << total_bytes_limit_
<< " bytes). To increase the limit (or to disable these "
"warnings), see CodedInputStream::SetTotalBytesLimit() "
"in google/protobuf/io/coded_stream.h.";
}
bool CodedInputStream::Skip(int count) {
if (count < 0) return false; // security: count is often user-supplied
const int original_buffer_size = BufferSize();
if (count <= original_buffer_size) {
// Just skipping within the current buffer. Easy.
Advance(count);
return true;
}
if (buffer_size_after_limit_ > 0) {
// We hit a limit inside this buffer. Advance to the limit and fail.
Advance(original_buffer_size);
return false;
}
count -= original_buffer_size;
buffer_ = NULL;
buffer_end_ = buffer_;
// Make sure this skip doesn't try to skip past the current limit.
int closest_limit = min(current_limit_, total_bytes_limit_);
int bytes_until_limit = closest_limit - total_bytes_read_;
if (bytes_until_limit < count) {
// We hit the limit. Skip up to it then fail.
if (bytes_until_limit > 0) {
total_bytes_read_ = closest_limit;
input_->Skip(bytes_until_limit);
}
return false;
}
total_bytes_read_ += count;
return input_->Skip(count);
}
bool CodedInputStream::GetDirectBufferPointer(const void** data, int* size) {
if (BufferSize() == 0 && !Refresh()) return false;
*data = buffer_;
*size = BufferSize();
return true;
}
bool CodedInputStream::ReadRaw(void* buffer, int size) {
int current_buffer_size;
while ((current_buffer_size = BufferSize()) < size) {
// Reading past end of buffer. Copy what we have, then refresh.
memcpy(buffer, buffer_, current_buffer_size);
buffer = reinterpret_cast<uint8*>(buffer) + current_buffer_size;
size -= current_buffer_size;
Advance(current_buffer_size);
if (!Refresh()) return false;
}
memcpy(buffer, buffer_, size);
Advance(size);
return true;
}
bool CodedInputStream::ReadString(string* buffer, int size) {
if (size < 0) return false; // security: size is often user-supplied
return InternalReadStringInline(buffer, size);
}
bool CodedInputStream::ReadStringFallback(string* buffer, int size) {
if (!buffer->empty()) {
buffer->clear();
}
int current_buffer_size;
while ((current_buffer_size = BufferSize()) < size) {
// Some STL implementations "helpfully" crash on buffer->append(NULL, 0).
if (current_buffer_size != 0) {
// Note: string1.append(string2) is O(string2.size()) (as opposed to
// O(string1.size() + string2.size()), which would be bad).
buffer->append(reinterpret_cast<const char*>(buffer_),
current_buffer_size);
}
size -= current_buffer_size;
Advance(current_buffer_size);
if (!Refresh()) return false;
}
buffer->append(reinterpret_cast<const char*>(buffer_), size);
Advance(size);
return true;
}
bool CodedInputStream::ReadLittleEndian32Fallback(uint32* value) {
uint8 bytes[sizeof(*value)];
const uint8* ptr;
if (BufferSize() >= sizeof(*value)) {
// Fast path: Enough bytes in the buffer to read directly.
ptr = buffer_;
Advance(sizeof(*value));
} else {
// Slow path: Had to read past the end of the buffer.
if (!ReadRaw(bytes, sizeof(*value))) return false;
ptr = bytes;
}
ReadLittleEndian32FromArray(ptr, value);
return true;
}
bool CodedInputStream::ReadLittleEndian64Fallback(uint64* value) {
uint8 bytes[sizeof(*value)];
const uint8* ptr;
if (BufferSize() >= sizeof(*value)) {
// Fast path: Enough bytes in the buffer to read directly.
ptr = buffer_;
Advance(sizeof(*value));
} else {
// Slow path: Had to read past the end of the buffer.
if (!ReadRaw(bytes, sizeof(*value))) return false;
ptr = bytes;
}
ReadLittleEndian64FromArray(ptr, value);
return true;
}
namespace {
inline const uint8* ReadVarint32FromArray(
const uint8* buffer, uint32* value) GOOGLE_ATTRIBUTE_ALWAYS_INLINE;
inline const uint8* ReadVarint32FromArray(const uint8* buffer, uint32* value) {
// Fast path: We have enough bytes left in the buffer to guarantee that
// this read won't cross the end, so we can skip the checks.
const uint8* ptr = buffer;
uint32 b;
uint32 result;
b = *(ptr++); result = (b & 0x7F) ; if (!(b & 0x80)) goto done;
b = *(ptr++); result |= (b & 0x7F) << 7; if (!(b & 0x80)) goto done;
b = *(ptr++); result |= (b & 0x7F) << 14; if (!(b & 0x80)) goto done;
b = *(ptr++); result |= (b & 0x7F) << 21; if (!(b & 0x80)) goto done;
b = *(ptr++); result |= b << 28; if (!(b & 0x80)) goto done;
// If the input is larger than 32 bits, we still need to read it all
// and discard the high-order bits.
for (int i = 0; i < kMaxVarintBytes - kMaxVarint32Bytes; i++) {
b = *(ptr++); if (!(b & 0x80)) goto done;
}
// We have overrun the maximum size of a varint (10 bytes). Assume
// the data is corrupt.
return NULL;
done:
*value = result;
return ptr;
}
} // namespace
bool CodedInputStream::ReadVarint32Slow(uint32* value) {
uint64 result;
// Directly invoke ReadVarint64Fallback, since we already tried to optimize
// for one-byte varints.
if (!ReadVarint64Fallback(&result)) return false;
*value = (uint32)result;
return true;
}
bool CodedInputStream::ReadVarint32Fallback(uint32* value) {
if (BufferSize() >= kMaxVarintBytes ||
// Optimization: If the varint ends at exactly the end of the buffer,
// we can detect that and still use the fast path.
(buffer_end_ > buffer_ && !(buffer_end_[-1] & 0x80))) {
const uint8* end = ReadVarint32FromArray(buffer_, value);
if (end == NULL) return false;
buffer_ = end;
return true;
} else {
// Really slow case: we will incur the cost of an extra function call here,
// but moving this out of line reduces the size of this function, which
// improves the common case. In micro benchmarks, this is worth about 10-15%
return ReadVarint32Slow(value);
}
}
uint32 CodedInputStream::ReadTagSlow() {
if (buffer_ == buffer_end_) {
// Call refresh.
if (!Refresh()) {
// Refresh failed. Make sure that it failed due to EOF, not because
// we hit total_bytes_limit_, which, unlike normal limits, is not a
// valid place to end a message.
int current_position = total_bytes_read_ - buffer_size_after_limit_;
if (current_position >= total_bytes_limit_) {
// Hit total_bytes_limit_. But if we also hit the normal limit,
// we're still OK.
legitimate_message_end_ = current_limit_ == total_bytes_limit_;
} else {
legitimate_message_end_ = true;
}
return 0;
}
}
// For the slow path, just do a 64-bit read. Try to optimize for one-byte tags
// again, since we have now refreshed the buffer.
uint64 result = 0;
if (!ReadVarint64(&result)) return 0;
return static_cast<uint32>(result);
}
uint32 CodedInputStream::ReadTagFallback() {
const int buf_size = BufferSize();
if (buf_size >= kMaxVarintBytes ||
// Optimization: If the varint ends at exactly the end of the buffer,
// we can detect that and still use the fast path.
(buf_size > 0 && !(buffer_end_[-1] & 0x80))) {
uint32 tag;
const uint8* end = ReadVarint32FromArray(buffer_, &tag);
if (end == NULL) {
return 0;
}
buffer_ = end;
return tag;
} else {
// We are commonly at a limit when attempting to read tags. Try to quickly
// detect this case without making another function call.
if ((buf_size == 0) &&
((buffer_size_after_limit_ > 0) ||
(total_bytes_read_ == current_limit_)) &&
// Make sure that the limit we hit is not total_bytes_limit_, since
// in that case we still need to call Refresh() so that it prints an
// error.
total_bytes_read_ - buffer_size_after_limit_ < total_bytes_limit_) {
// We hit a byte limit.
legitimate_message_end_ = true;
return 0;
}
return ReadTagSlow();
}
}
bool CodedInputStream::ReadVarint64Slow(uint64* value) {
// Slow path: This read might cross the end of the buffer, so we
// need to check and refresh the buffer if and when it does.
uint64 result = 0;
int count = 0;
uint32 b;
do {
if (count == kMaxVarintBytes) return false;
while (buffer_ == buffer_end_) {
if (!Refresh()) return false;
}
b = *buffer_;
result |= static_cast<uint64>(b & 0x7F) << (7 * count);
Advance(1);
++count;
} while (b & 0x80);
*value = result;
return true;
}
bool CodedInputStream::ReadVarint64Fallback(uint64* value) {
if (BufferSize() >= kMaxVarintBytes ||
// Optimization: If the varint ends at exactly the end of the buffer,
// we can detect that and still use the fast path.
(buffer_end_ > buffer_ && !(buffer_end_[-1] & 0x80))) {
// Fast path: We have enough bytes left in the buffer to guarantee that
// this read won't cross the end, so we can skip the checks.
const uint8* ptr = buffer_;
uint32 b;
// Splitting into 32-bit pieces gives better performance on 32-bit
// processors.
uint32 part0 = 0, part1 = 0, part2 = 0;
b = *(ptr++); part0 = (b & 0x7F) ; if (!(b & 0x80)) goto done;
b = *(ptr++); part0 |= (b & 0x7F) << 7; if (!(b & 0x80)) goto done;
b = *(ptr++); part0 |= (b & 0x7F) << 14; if (!(b & 0x80)) goto done;
b = *(ptr++); part0 |= (b & 0x7F) << 21; if (!(b & 0x80)) goto done;
b = *(ptr++); part1 = (b & 0x7F) ; if (!(b & 0x80)) goto done;
b = *(ptr++); part1 |= (b & 0x7F) << 7; if (!(b & 0x80)) goto done;
b = *(ptr++); part1 |= (b & 0x7F) << 14; if (!(b & 0x80)) goto done;
b = *(ptr++); part1 |= (b & 0x7F) << 21; if (!(b & 0x80)) goto done;
b = *(ptr++); part2 = (b & 0x7F) ; if (!(b & 0x80)) goto done;
b = *(ptr++); part2 |= (b & 0x7F) << 7; if (!(b & 0x80)) goto done;
// We have overrun the maximum size of a varint (10 bytes). The data
// must be corrupt.
return false;
done:
Advance(ptr - buffer_);
*value = (static_cast<uint64>(part0) ) |
(static_cast<uint64>(part1) << 28) |
(static_cast<uint64>(part2) << 56);
return true;
} else {
return ReadVarint64Slow(value);
}
}
bool CodedInputStream::Refresh() {
GOOGLE_DCHECK_EQ(0, BufferSize());
if (buffer_size_after_limit_ > 0 || overflow_bytes_ > 0 ||
total_bytes_read_ == current_limit_) {
// We've hit a limit. Stop.
int current_position = total_bytes_read_ - buffer_size_after_limit_;
if (current_position >= total_bytes_limit_ &&
total_bytes_limit_ != current_limit_) {
// Hit total_bytes_limit_.
PrintTotalBytesLimitError();
}
return false;
}
if (total_bytes_warning_threshold_ >= 0 &&
total_bytes_read_ >= total_bytes_warning_threshold_) {
GOOGLE_LOG(WARNING) << "Reading dangerously large protocol message. If the "
"message turns out to be larger than "
<< total_bytes_limit_ << " bytes, parsing will be halted "
"for security reasons. To increase the limit (or to "
"disable these warnings), see "
"CodedInputStream::SetTotalBytesLimit() in "
"google/protobuf/io/coded_stream.h.";
// Don't warn again for this stream, and print total size at the end.
total_bytes_warning_threshold_ = -2;
}
const void* void_buffer;
int buffer_size;
if (NextNonEmpty(input_, &void_buffer, &buffer_size)) {
buffer_ = reinterpret_cast<const uint8*>(void_buffer);
buffer_end_ = buffer_ + buffer_size;
GOOGLE_CHECK_GE(buffer_size, 0);
if (total_bytes_read_ <= INT_MAX - buffer_size) {
total_bytes_read_ += buffer_size;
} else {
// Overflow. Reset buffer_end_ to not include the bytes beyond INT_MAX.
// We can't get that far anyway, because total_bytes_limit_ is guaranteed
// to be less than it. We need to keep track of the number of bytes
// we discarded, though, so that we can call input_->BackUp() to back
// up over them on destruction.
// The following line is equivalent to:
// overflow_bytes_ = total_bytes_read_ + buffer_size - INT_MAX;
// except that it avoids overflows. Signed integer overflow has
// undefined results according to the C standard.
overflow_bytes_ = total_bytes_read_ - (INT_MAX - buffer_size);
buffer_end_ -= overflow_bytes_;
total_bytes_read_ = INT_MAX;
}
RecomputeBufferLimits();
return true;
} else {
buffer_ = NULL;
buffer_end_ = NULL;
return false;
}
}
// CodedOutputStream =================================================
CodedOutputStream::CodedOutputStream(ZeroCopyOutputStream* output)
: output_(output),
buffer_(NULL),
buffer_size_(0),
total_bytes_(0),
had_error_(false) {
// Eagerly Refresh() so buffer space is immediately available.
Refresh();
// The Refresh() may have failed. If the client doesn't write any data,
// though, don't consider this an error. If the client does write data, then
// another Refresh() will be attempted and it will set the error once again.
had_error_ = false;
}
CodedOutputStream::~CodedOutputStream() {
if (buffer_size_ > 0) {
output_->BackUp(buffer_size_);
}
}
bool CodedOutputStream::Skip(int count) {
if (count < 0) return false;
while (count > buffer_size_) {
count -= buffer_size_;
if (!Refresh()) return false;
}
Advance(count);
return true;
}
bool CodedOutputStream::GetDirectBufferPointer(void** data, int* size) {
if (buffer_size_ == 0 && !Refresh()) return false;
*data = buffer_;
*size = buffer_size_;
return true;
}
void CodedOutputStream::WriteRaw(const void* data, int size) {
while (buffer_size_ < size) {
memcpy(buffer_, data, buffer_size_);
size -= buffer_size_;
data = reinterpret_cast<const uint8*>(data) + buffer_size_;
if (!Refresh()) return;
}
memcpy(buffer_, data, size);
Advance(size);
}
uint8* CodedOutputStream::WriteRawToArray(
const void* data, int size, uint8* target) {
memcpy(target, data, size);
return target + size;
}
void CodedOutputStream::WriteLittleEndian32(uint32 value) {
uint8 bytes[sizeof(value)];
bool use_fast = buffer_size_ >= sizeof(value);
uint8* ptr = use_fast ? buffer_ : bytes;
WriteLittleEndian32ToArray(value, ptr);
if (use_fast) {
Advance(sizeof(value));
} else {
WriteRaw(bytes, sizeof(value));
}
}
void CodedOutputStream::WriteLittleEndian64(uint64 value) {
uint8 bytes[sizeof(value)];
bool use_fast = buffer_size_ >= sizeof(value);
uint8* ptr = use_fast ? buffer_ : bytes;
WriteLittleEndian64ToArray(value, ptr);
if (use_fast) {
Advance(sizeof(value));
} else {
WriteRaw(bytes, sizeof(value));
}
}
inline uint8* CodedOutputStream::WriteVarint32FallbackToArrayInline(
uint32 value, uint8* target) {
target[0] = static_cast<uint8>(value | 0x80);
if (value >= (1 << 7)) {
target[1] = static_cast<uint8>((value >> 7) | 0x80);
if (value >= (1 << 14)) {
target[2] = static_cast<uint8>((value >> 14) | 0x80);
if (value >= (1 << 21)) {
target[3] = static_cast<uint8>((value >> 21) | 0x80);
if (value >= (1 << 28)) {
target[4] = static_cast<uint8>(value >> 28);
return target + 5;
} else {
target[3] &= 0x7F;
return target + 4;
}
} else {
target[2] &= 0x7F;
return target + 3;
}
} else {
target[1] &= 0x7F;
return target + 2;
}
} else {
target[0] &= 0x7F;
return target + 1;
}
}
void CodedOutputStream::WriteVarint32(uint32 value) {
if (buffer_size_ >= kMaxVarint32Bytes) {
// Fast path: We have enough bytes left in the buffer to guarantee that
// this write won't cross the end, so we can skip the checks.
uint8* target = buffer_;
uint8* end = WriteVarint32FallbackToArrayInline(value, target);
int size = end - target;
Advance(size);
} else {
// Slow path: This write might cross the end of the buffer, so we
// compose the bytes first then use WriteRaw().
uint8 bytes[kMaxVarint32Bytes];
int size = 0;
while (value > 0x7F) {
bytes[size++] = (static_cast<uint8>(value) & 0x7F) | 0x80;
value >>= 7;
}
bytes[size++] = static_cast<uint8>(value) & 0x7F;
WriteRaw(bytes, size);
}
}
uint8* CodedOutputStream::WriteVarint32FallbackToArray(
uint32 value, uint8* target) {
return WriteVarint32FallbackToArrayInline(value, target);
}
inline uint8* CodedOutputStream::WriteVarint64ToArrayInline(
uint64 value, uint8* target) {
// Splitting into 32-bit pieces gives better performance on 32-bit
// processors.
uint32 part0 = static_cast<uint32>(value );
uint32 part1 = static_cast<uint32>(value >> 28);
uint32 part2 = static_cast<uint32>(value >> 56);
int size;
// Here we can't really optimize for small numbers, since the value is
// split into three parts. Cheking for numbers < 128, for instance,
// would require three comparisons, since you'd have to make sure part1
// and part2 are zero. However, if the caller is using 64-bit integers,
// it is likely that they expect the numbers to often be very large, so
// we probably don't want to optimize for small numbers anyway. Thus,
// we end up with a hardcoded binary search tree...
if (part2 == 0) {
if (part1 == 0) {
if (part0 < (1 << 14)) {
if (part0 < (1 << 7)) {
size = 1; goto size1;
} else {
size = 2; goto size2;
}
} else {
if (part0 < (1 << 21)) {
size = 3; goto size3;
} else {
size = 4; goto size4;
}
}
} else {
if (part1 < (1 << 14)) {
if (part1 < (1 << 7)) {
size = 5; goto size5;
} else {
size = 6; goto size6;
}
} else {
if (part1 < (1 << 21)) {
size = 7; goto size7;
} else {
size = 8; goto size8;
}
}
}
} else {
if (part2 < (1 << 7)) {
size = 9; goto size9;
} else {
size = 10; goto size10;
}
}
GOOGLE_LOG(FATAL) << "Can't get here.";
size10: target[9] = static_cast<uint8>((part2 >> 7) | 0x80);
size9 : target[8] = static_cast<uint8>((part2 ) | 0x80);
size8 : target[7] = static_cast<uint8>((part1 >> 21) | 0x80);
size7 : target[6] = static_cast<uint8>((part1 >> 14) | 0x80);
size6 : target[5] = static_cast<uint8>((part1 >> 7) | 0x80);
size5 : target[4] = static_cast<uint8>((part1 ) | 0x80);
size4 : target[3] = static_cast<uint8>((part0 >> 21) | 0x80);
size3 : target[2] = static_cast<uint8>((part0 >> 14) | 0x80);
size2 : target[1] = static_cast<uint8>((part0 >> 7) | 0x80);
size1 : target[0] = static_cast<uint8>((part0 ) | 0x80);
target[size-1] &= 0x7F;
return target + size;
}
void CodedOutputStream::WriteVarint64(uint64 value) {
if (buffer_size_ >= kMaxVarintBytes) {
// Fast path: We have enough bytes left in the buffer to guarantee that
// this write won't cross the end, so we can skip the checks.
uint8* target = buffer_;
uint8* end = WriteVarint64ToArrayInline(value, target);
int size = end - target;
Advance(size);
} else {
// Slow path: This write might cross the end of the buffer, so we
// compose the bytes first then use WriteRaw().
uint8 bytes[kMaxVarintBytes];
int size = 0;
while (value > 0x7F) {
bytes[size++] = (static_cast<uint8>(value) & 0x7F) | 0x80;
value >>= 7;
}
bytes[size++] = static_cast<uint8>(value) & 0x7F;
WriteRaw(bytes, size);
}
}
uint8* CodedOutputStream::WriteVarint64ToArray(
uint64 value, uint8* target) {
return WriteVarint64ToArrayInline(value, target);
}
bool CodedOutputStream::Refresh() {
void* void_buffer;
if (output_->Next(&void_buffer, &buffer_size_)) {
buffer_ = reinterpret_cast<uint8*>(void_buffer);
total_bytes_ += buffer_size_;
return true;
} else {
buffer_ = NULL;
buffer_size_ = 0;
had_error_ = true;
return false;
}
}
int CodedOutputStream::VarintSize32Fallback(uint32 value) {
if (value < (1 << 7)) {
return 1;
} else if (value < (1 << 14)) {
return 2;
} else if (value < (1 << 21)) {
return 3;
} else if (value < (1 << 28)) {
return 4;
} else {
return 5;
}
}
int CodedOutputStream::VarintSize64(uint64 value) {
if (value < (1ull << 35)) {
if (value < (1ull << 7)) {
return 1;
} else if (value < (1ull << 14)) {
return 2;
} else if (value < (1ull << 21)) {
return 3;
} else if (value < (1ull << 28)) {
return 4;
} else {
return 5;
}
} else {
if (value < (1ull << 42)) {
return 6;
} else if (value < (1ull << 49)) {
return 7;
} else if (value < (1ull << 56)) {
return 8;
} else if (value < (1ull << 63)) {
return 9;
} else {
return 10;
}
}
}
} // namespace io
} // namespace protobuf
} // namespace google

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,68 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// http://code.google.com/p/protobuf/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Author: jasonh@google.com (Jason Hsueh)
//
// Implements methods of coded_stream.h that need to be inlined for performance
// reasons, but should not be defined in a public header.
#ifndef GOOGLE_PROTOBUF_IO_CODED_STREAM_INL_H__
#define GOOGLE_PROTOBUF_IO_CODED_STREAM_INL_H__
#include <google/protobuf/io/coded_stream.h>
#include <string>
#include <google/protobuf/stubs/stl_util.h>
namespace google {
namespace protobuf {
namespace io {
inline bool CodedInputStream::InternalReadStringInline(string* buffer,
int size) {
if (size < 0) return false; // security: size is often user-supplied
if (BufferSize() >= size) {
STLStringResizeUninitialized(buffer, size);
// When buffer is empty, string_as_array(buffer) will return NULL but memcpy
// requires non-NULL pointers even when size is 0. Hench this check.
if (size > 0) {
memcpy(string_as_array(buffer), buffer_, size);
Advance(size);
}
return true;
}
return ReadStringFallback(buffer, size);
}
} // namespace io
} // namespace protobuf
} // namespace google
#endif // GOOGLE_PROTOBUF_IO_CODED_STREAM_INL_H__

View File

@ -0,0 +1,48 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// http://code.google.com/p/protobuf/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Author: kenton@google.com (Kenton Varda)
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
#include <google/protobuf/io/zero_copy_stream.h>
namespace google {
namespace protobuf {
namespace io {
ZeroCopyInputStream::~ZeroCopyInputStream() {}
ZeroCopyOutputStream::~ZeroCopyOutputStream() {}
} // namespace io
} // namespace protobuf
} // namespace google

View File

@ -0,0 +1,238 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// http://code.google.com/p/protobuf/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Author: kenton@google.com (Kenton Varda)
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
//
// This file contains the ZeroCopyInputStream and ZeroCopyOutputStream
// interfaces, which represent abstract I/O streams to and from which
// protocol buffers can be read and written. For a few simple
// implementations of these interfaces, see zero_copy_stream_impl.h.
//
// These interfaces are different from classic I/O streams in that they
// try to minimize the amount of data copying that needs to be done.
// To accomplish this, responsibility for allocating buffers is moved to
// the stream object, rather than being the responsibility of the caller.
// So, the stream can return a buffer which actually points directly into
// the final data structure where the bytes are to be stored, and the caller
// can interact directly with that buffer, eliminating an intermediate copy
// operation.
//
// As an example, consider the common case in which you are reading bytes
// from an array that is already in memory (or perhaps an mmap()ed file).
// With classic I/O streams, you would do something like:
// char buffer[BUFFER_SIZE];
// input->Read(buffer, BUFFER_SIZE);
// DoSomething(buffer, BUFFER_SIZE);
// Then, the stream basically just calls memcpy() to copy the data from
// the array into your buffer. With a ZeroCopyInputStream, you would do
// this instead:
// const void* buffer;
// int size;
// input->Next(&buffer, &size);
// DoSomething(buffer, size);
// Here, no copy is performed. The input stream returns a pointer directly
// into the backing array, and the caller ends up reading directly from it.
//
// If you want to be able to read the old-fashion way, you can create
// a CodedInputStream or CodedOutputStream wrapping these objects and use
// their ReadRaw()/WriteRaw() methods. These will, of course, add a copy
// step, but Coded*Stream will handle buffering so at least it will be
// reasonably efficient.
//
// ZeroCopyInputStream example:
// // Read in a file and print its contents to stdout.
// int fd = open("myfile", O_RDONLY);
// ZeroCopyInputStream* input = new FileInputStream(fd);
//
// const void* buffer;
// int size;
// while (input->Next(&buffer, &size)) {
// cout.write(buffer, size);
// }
//
// delete input;
// close(fd);
//
// ZeroCopyOutputStream example:
// // Copy the contents of "infile" to "outfile", using plain read() for
// // "infile" but a ZeroCopyOutputStream for "outfile".
// int infd = open("infile", O_RDONLY);
// int outfd = open("outfile", O_WRONLY);
// ZeroCopyOutputStream* output = new FileOutputStream(outfd);
//
// void* buffer;
// int size;
// while (output->Next(&buffer, &size)) {
// int bytes = read(infd, buffer, size);
// if (bytes < size) {
// // Reached EOF.
// output->BackUp(size - bytes);
// break;
// }
// }
//
// delete output;
// close(infd);
// close(outfd);
#ifndef GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_H__
#define GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_H__
#include <string>
#include <google/protobuf/stubs/common.h>
namespace google {
namespace protobuf {
namespace io {
// Defined in this file.
class ZeroCopyInputStream;
class ZeroCopyOutputStream;
// Abstract interface similar to an input stream but designed to minimize
// copying.
class LIBPROTOBUF_EXPORT ZeroCopyInputStream {
public:
inline ZeroCopyInputStream() {}
virtual ~ZeroCopyInputStream();
// Obtains a chunk of data from the stream.
//
// Preconditions:
// * "size" and "data" are not NULL.
//
// Postconditions:
// * If the returned value is false, there is no more data to return or
// an error occurred. All errors are permanent.
// * Otherwise, "size" points to the actual number of bytes read and "data"
// points to a pointer to a buffer containing these bytes.
// * Ownership of this buffer remains with the stream, and the buffer
// remains valid only until some other method of the stream is called
// or the stream is destroyed.
// * It is legal for the returned buffer to have zero size, as long
// as repeatedly calling Next() eventually yields a buffer with non-zero
// size.
virtual bool Next(const void** data, int* size) = 0;
// Backs up a number of bytes, so that the next call to Next() returns
// data again that was already returned by the last call to Next(). This
// is useful when writing procedures that are only supposed to read up
// to a certain point in the input, then return. If Next() returns a
// buffer that goes beyond what you wanted to read, you can use BackUp()
// to return to the point where you intended to finish.
//
// Preconditions:
// * The last method called must have been Next().
// * count must be less than or equal to the size of the last buffer
// returned by Next().
//
// Postconditions:
// * The last "count" bytes of the last buffer returned by Next() will be
// pushed back into the stream. Subsequent calls to Next() will return
// the same data again before producing new data.
virtual void BackUp(int count) = 0;
// Skips a number of bytes. Returns false if the end of the stream is
// reached or some input error occurred. In the end-of-stream case, the
// stream is advanced to the end of the stream (so ByteCount() will return
// the total size of the stream).
virtual bool Skip(int count) = 0;
// Returns the total number of bytes read since this object was created.
virtual int64 ByteCount() const = 0;
private:
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ZeroCopyInputStream);
};
// Abstract interface similar to an output stream but designed to minimize
// copying.
class LIBPROTOBUF_EXPORT ZeroCopyOutputStream {
public:
inline ZeroCopyOutputStream() {}
virtual ~ZeroCopyOutputStream();
// Obtains a buffer into which data can be written. Any data written
// into this buffer will eventually (maybe instantly, maybe later on)
// be written to the output.
//
// Preconditions:
// * "size" and "data" are not NULL.
//
// Postconditions:
// * If the returned value is false, an error occurred. All errors are
// permanent.
// * Otherwise, "size" points to the actual number of bytes in the buffer
// and "data" points to the buffer.
// * Ownership of this buffer remains with the stream, and the buffer
// remains valid only until some other method of the stream is called
// or the stream is destroyed.
// * Any data which the caller stores in this buffer will eventually be
// written to the output (unless BackUp() is called).
// * It is legal for the returned buffer to have zero size, as long
// as repeatedly calling Next() eventually yields a buffer with non-zero
// size.
virtual bool Next(void** data, int* size) = 0;
// Backs up a number of bytes, so that the end of the last buffer returned
// by Next() is not actually written. This is needed when you finish
// writing all the data you want to write, but the last buffer was bigger
// than you needed. You don't want to write a bunch of garbage after the
// end of your data, so you use BackUp() to back up.
//
// Preconditions:
// * The last method called must have been Next().
// * count must be less than or equal to the size of the last buffer
// returned by Next().
// * The caller must not have written anything to the last "count" bytes
// of that buffer.
//
// Postconditions:
// * The last "count" bytes of the last buffer returned by Next() will be
// ignored.
virtual void BackUp(int count) = 0;
// Returns the total number of bytes written since this object was created.
virtual int64 ByteCount() const = 0;
private:
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ZeroCopyOutputStream);
};
} // namespace io
} // namespace protobuf
} // namespace google
#endif // GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_H__

View File

@ -0,0 +1,357 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// http://code.google.com/p/protobuf/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Author: kenton@google.com (Kenton Varda)
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
//
// This file contains common implementations of the interfaces defined in
// zero_copy_stream.h which are only included in the full (non-lite)
// protobuf library. These implementations include Unix file descriptors
// and C++ iostreams. See also: zero_copy_stream_impl_lite.h
#ifndef GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_IMPL_H__
#define GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_IMPL_H__
#include <string>
#include <iosfwd>
#include <google/protobuf/io/zero_copy_stream.h>
#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
#include <google/protobuf/stubs/common.h>
namespace google {
namespace protobuf {
namespace io {
// ===================================================================
// A ZeroCopyInputStream which reads from a file descriptor.
//
// FileInputStream is preferred over using an ifstream with IstreamInputStream.
// The latter will introduce an extra layer of buffering, harming performance.
// Also, it's conceivable that FileInputStream could someday be enhanced
// to use zero-copy file descriptors on OSs which support them.
class LIBPROTOBUF_EXPORT FileInputStream : public ZeroCopyInputStream {
public:
// Creates a stream that reads from the given Unix file descriptor.
// If a block_size is given, it specifies the number of bytes that
// should be read and returned with each call to Next(). Otherwise,
// a reasonable default is used.
explicit FileInputStream(int file_descriptor, int block_size = -1);
~FileInputStream();
// Flushes any buffers and closes the underlying file. Returns false if
// an error occurs during the process; use GetErrno() to examine the error.
// Even if an error occurs, the file descriptor is closed when this returns.
bool Close();
// By default, the file descriptor is not closed when the stream is
// destroyed. Call SetCloseOnDelete(true) to change that. WARNING:
// This leaves no way for the caller to detect if close() fails. If
// detecting close() errors is important to you, you should arrange
// to close the descriptor yourself.
void SetCloseOnDelete(bool value) { copying_input_.SetCloseOnDelete(value); }
// If an I/O error has occurred on this file descriptor, this is the
// errno from that error. Otherwise, this is zero. Once an error
// occurs, the stream is broken and all subsequent operations will
// fail.
int GetErrno() { return copying_input_.GetErrno(); }
// implements ZeroCopyInputStream ----------------------------------
bool Next(const void** data, int* size);
void BackUp(int count);
bool Skip(int count);
int64 ByteCount() const;
private:
class LIBPROTOBUF_EXPORT CopyingFileInputStream : public CopyingInputStream {
public:
CopyingFileInputStream(int file_descriptor);
~CopyingFileInputStream();
bool Close();
void SetCloseOnDelete(bool value) { close_on_delete_ = value; }
int GetErrno() { return errno_; }
// implements CopyingInputStream ---------------------------------
int Read(void* buffer, int size);
int Skip(int count);
private:
// The file descriptor.
const int file_;
bool close_on_delete_;
bool is_closed_;
// The errno of the I/O error, if one has occurred. Otherwise, zero.
int errno_;
// Did we try to seek once and fail? If so, we assume this file descriptor
// doesn't support seeking and won't try again.
bool previous_seek_failed_;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CopyingFileInputStream);
};
CopyingFileInputStream copying_input_;
CopyingInputStreamAdaptor impl_;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FileInputStream);
};
// ===================================================================
// A ZeroCopyOutputStream which writes to a file descriptor.
//
// FileOutputStream is preferred over using an ofstream with
// OstreamOutputStream. The latter will introduce an extra layer of buffering,
// harming performance. Also, it's conceivable that FileOutputStream could
// someday be enhanced to use zero-copy file descriptors on OSs which
// support them.
class LIBPROTOBUF_EXPORT FileOutputStream : public ZeroCopyOutputStream {
public:
// Creates a stream that writes to the given Unix file descriptor.
// If a block_size is given, it specifies the size of the buffers
// that should be returned by Next(). Otherwise, a reasonable default
// is used.
explicit FileOutputStream(int file_descriptor, int block_size = -1);
~FileOutputStream();
// Flushes any buffers and closes the underlying file. Returns false if
// an error occurs during the process; use GetErrno() to examine the error.
// Even if an error occurs, the file descriptor is closed when this returns.
bool Close();
// Flushes FileOutputStream's buffers but does not close the
// underlying file. No special measures are taken to ensure that
// underlying operating system file object is synchronized to disk.
bool Flush();
// By default, the file descriptor is not closed when the stream is
// destroyed. Call SetCloseOnDelete(true) to change that. WARNING:
// This leaves no way for the caller to detect if close() fails. If
// detecting close() errors is important to you, you should arrange
// to close the descriptor yourself.
void SetCloseOnDelete(bool value) { copying_output_.SetCloseOnDelete(value); }
// If an I/O error has occurred on this file descriptor, this is the
// errno from that error. Otherwise, this is zero. Once an error
// occurs, the stream is broken and all subsequent operations will
// fail.
int GetErrno() { return copying_output_.GetErrno(); }
// implements ZeroCopyOutputStream ---------------------------------
bool Next(void** data, int* size);
void BackUp(int count);
int64 ByteCount() const;
private:
class LIBPROTOBUF_EXPORT CopyingFileOutputStream : public CopyingOutputStream {
public:
CopyingFileOutputStream(int file_descriptor);
~CopyingFileOutputStream();
bool Close();
void SetCloseOnDelete(bool value) { close_on_delete_ = value; }
int GetErrno() { return errno_; }
// implements CopyingOutputStream --------------------------------
bool Write(const void* buffer, int size);
private:
// The file descriptor.
const int file_;
bool close_on_delete_;
bool is_closed_;
// The errno of the I/O error, if one has occurred. Otherwise, zero.
int errno_;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CopyingFileOutputStream);
};
CopyingFileOutputStream copying_output_;
CopyingOutputStreamAdaptor impl_;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FileOutputStream);
};
// ===================================================================
// A ZeroCopyInputStream which reads from a C++ istream.
//
// Note that for reading files (or anything represented by a file descriptor),
// FileInputStream is more efficient.
class LIBPROTOBUF_EXPORT IstreamInputStream : public ZeroCopyInputStream {
public:
// Creates a stream that reads from the given C++ istream.
// If a block_size is given, it specifies the number of bytes that
// should be read and returned with each call to Next(). Otherwise,
// a reasonable default is used.
explicit IstreamInputStream(istream* stream, int block_size = -1);
~IstreamInputStream();
// implements ZeroCopyInputStream ----------------------------------
bool Next(const void** data, int* size);
void BackUp(int count);
bool Skip(int count);
int64 ByteCount() const;
private:
class LIBPROTOBUF_EXPORT CopyingIstreamInputStream : public CopyingInputStream {
public:
CopyingIstreamInputStream(istream* input);
~CopyingIstreamInputStream();
// implements CopyingInputStream ---------------------------------
int Read(void* buffer, int size);
// (We use the default implementation of Skip().)
private:
// The stream.
istream* input_;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CopyingIstreamInputStream);
};
CopyingIstreamInputStream copying_input_;
CopyingInputStreamAdaptor impl_;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(IstreamInputStream);
};
// ===================================================================
// A ZeroCopyOutputStream which writes to a C++ ostream.
//
// Note that for writing files (or anything represented by a file descriptor),
// FileOutputStream is more efficient.
class LIBPROTOBUF_EXPORT OstreamOutputStream : public ZeroCopyOutputStream {
public:
// Creates a stream that writes to the given C++ ostream.
// If a block_size is given, it specifies the size of the buffers
// that should be returned by Next(). Otherwise, a reasonable default
// is used.
explicit OstreamOutputStream(ostream* stream, int block_size = -1);
~OstreamOutputStream();
// implements ZeroCopyOutputStream ---------------------------------
bool Next(void** data, int* size);
void BackUp(int count);
int64 ByteCount() const;
private:
class LIBPROTOBUF_EXPORT CopyingOstreamOutputStream : public CopyingOutputStream {
public:
CopyingOstreamOutputStream(ostream* output);
~CopyingOstreamOutputStream();
// implements CopyingOutputStream --------------------------------
bool Write(const void* buffer, int size);
private:
// The stream.
ostream* output_;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CopyingOstreamOutputStream);
};
CopyingOstreamOutputStream copying_output_;
CopyingOutputStreamAdaptor impl_;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(OstreamOutputStream);
};
// ===================================================================
// A ZeroCopyInputStream which reads from several other streams in sequence.
// ConcatenatingInputStream is unable to distinguish between end-of-stream
// and read errors in the underlying streams, so it assumes any errors mean
// end-of-stream. So, if the underlying streams fail for any other reason,
// ConcatenatingInputStream may do odd things. It is suggested that you do
// not use ConcatenatingInputStream on streams that might produce read errors
// other than end-of-stream.
class LIBPROTOBUF_EXPORT ConcatenatingInputStream : public ZeroCopyInputStream {
public:
// All streams passed in as well as the array itself must remain valid
// until the ConcatenatingInputStream is destroyed.
ConcatenatingInputStream(ZeroCopyInputStream* const streams[], int count);
~ConcatenatingInputStream();
// implements ZeroCopyInputStream ----------------------------------
bool Next(const void** data, int* size);
void BackUp(int count);
bool Skip(int count);
int64 ByteCount() const;
private:
// As streams are retired, streams_ is incremented and count_ is
// decremented.
ZeroCopyInputStream* const* streams_;
int stream_count_;
int64 bytes_retired_; // Bytes read from previous streams.
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ConcatenatingInputStream);
};
// ===================================================================
// A ZeroCopyInputStream which wraps some other stream and limits it to
// a particular byte count.
class LIBPROTOBUF_EXPORT LimitingInputStream : public ZeroCopyInputStream {
public:
LimitingInputStream(ZeroCopyInputStream* input, int64 limit);
~LimitingInputStream();
// implements ZeroCopyInputStream ----------------------------------
bool Next(const void** data, int* size);
void BackUp(int count);
bool Skip(int count);
int64 ByteCount() const;
private:
ZeroCopyInputStream* input_;
int64 limit_; // Decreases as we go, becomes negative if we overshoot.
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(LimitingInputStream);
};
// ===================================================================
} // namespace io
} // namespace protobuf
} // namespace google
#endif // GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_IMPL_H__

View File

@ -0,0 +1,393 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// http://code.google.com/p/protobuf/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Author: kenton@google.com (Kenton Varda)
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/stl_util.h>
namespace google {
namespace protobuf {
namespace io {
namespace {
// Default block size for Copying{In,Out}putStreamAdaptor.
static const int kDefaultBlockSize = 8192;
} // namespace
// ===================================================================
ArrayInputStream::ArrayInputStream(const void* data, int size,
int block_size)
: data_(reinterpret_cast<const uint8*>(data)),
size_(size),
block_size_(block_size > 0 ? block_size : size),
position_(0),
last_returned_size_(0) {
}
ArrayInputStream::~ArrayInputStream() {
}
bool ArrayInputStream::Next(const void** data, int* size) {
if (position_ < size_) {
last_returned_size_ = min(block_size_, size_ - position_);
*data = data_ + position_;
*size = last_returned_size_;
position_ += last_returned_size_;
return true;
} else {
// We're at the end of the array.
last_returned_size_ = 0; // Don't let caller back up.
return false;
}
}
void ArrayInputStream::BackUp(int count) {
GOOGLE_CHECK_GT(last_returned_size_, 0)
<< "BackUp() can only be called after a successful Next().";
GOOGLE_CHECK_LE(count, last_returned_size_);
GOOGLE_CHECK_GE(count, 0);
position_ -= count;
last_returned_size_ = 0; // Don't let caller back up further.
}
bool ArrayInputStream::Skip(int count) {
GOOGLE_CHECK_GE(count, 0);
last_returned_size_ = 0; // Don't let caller back up.
if (count > size_ - position_) {
position_ = size_;
return false;
} else {
position_ += count;
return true;
}
}
int64 ArrayInputStream::ByteCount() const {
return position_;
}
// ===================================================================
ArrayOutputStream::ArrayOutputStream(void* data, int size, int block_size)
: data_(reinterpret_cast<uint8*>(data)),
size_(size),
block_size_(block_size > 0 ? block_size : size),
position_(0),
last_returned_size_(0) {
}
ArrayOutputStream::~ArrayOutputStream() {
}
bool ArrayOutputStream::Next(void** data, int* size) {
if (position_ < size_) {
last_returned_size_ = min(block_size_, size_ - position_);
*data = data_ + position_;
*size = last_returned_size_;
position_ += last_returned_size_;
return true;
} else {
// We're at the end of the array.
last_returned_size_ = 0; // Don't let caller back up.
return false;
}
}
void ArrayOutputStream::BackUp(int count) {
GOOGLE_CHECK_GT(last_returned_size_, 0)
<< "BackUp() can only be called after a successful Next().";
GOOGLE_CHECK_LE(count, last_returned_size_);
GOOGLE_CHECK_GE(count, 0);
position_ -= count;
last_returned_size_ = 0; // Don't let caller back up further.
}
int64 ArrayOutputStream::ByteCount() const {
return position_;
}
// ===================================================================
StringOutputStream::StringOutputStream(string* target)
: target_(target) {
}
StringOutputStream::~StringOutputStream() {
}
bool StringOutputStream::Next(void** data, int* size) {
int old_size = target_->size();
// Grow the string.
if (old_size < target_->capacity()) {
// Resize the string to match its capacity, since we can get away
// without a memory allocation this way.
STLStringResizeUninitialized(target_, target_->capacity());
} else {
// Size has reached capacity, so double the size. Also make sure
// that the new size is at least kMinimumSize.
STLStringResizeUninitialized(
target_,
max(old_size * 2,
kMinimumSize + 0)); // "+ 0" works around GCC4 weirdness.
}
*data = string_as_array(target_) + old_size;
*size = target_->size() - old_size;
return true;
}
void StringOutputStream::BackUp(int count) {
GOOGLE_CHECK_GE(count, 0);
GOOGLE_CHECK_LE(count, target_->size());
target_->resize(target_->size() - count);
}
int64 StringOutputStream::ByteCount() const {
return target_->size();
}
// ===================================================================
CopyingInputStream::~CopyingInputStream() {}
int CopyingInputStream::Skip(int count) {
char junk[4096];
int skipped = 0;
while (skipped < count) {
int bytes = Read(junk, min(count - skipped,
implicit_cast<int>(sizeof(junk))));
if (bytes <= 0) {
// EOF or read error.
return skipped;
}
skipped += bytes;
}
return skipped;
}
CopyingInputStreamAdaptor::CopyingInputStreamAdaptor(
CopyingInputStream* copying_stream, int block_size)
: copying_stream_(copying_stream),
owns_copying_stream_(false),
failed_(false),
position_(0),
buffer_size_(block_size > 0 ? block_size : kDefaultBlockSize),
buffer_used_(0),
backup_bytes_(0) {
}
CopyingInputStreamAdaptor::~CopyingInputStreamAdaptor() {
if (owns_copying_stream_) {
delete copying_stream_;
}
}
bool CopyingInputStreamAdaptor::Next(const void** data, int* size) {
if (failed_) {
// Already failed on a previous read.
return false;
}
AllocateBufferIfNeeded();
if (backup_bytes_ > 0) {
// We have data left over from a previous BackUp(), so just return that.
*data = buffer_.get() + buffer_used_ - backup_bytes_;
*size = backup_bytes_;
backup_bytes_ = 0;
return true;
}
// Read new data into the buffer.
buffer_used_ = copying_stream_->Read(buffer_.get(), buffer_size_);
if (buffer_used_ <= 0) {
// EOF or read error. We don't need the buffer anymore.
if (buffer_used_ < 0) {
// Read error (not EOF).
failed_ = true;
}
FreeBuffer();
return false;
}
position_ += buffer_used_;
*size = buffer_used_;
*data = buffer_.get();
return true;
}
void CopyingInputStreamAdaptor::BackUp(int count) {
GOOGLE_CHECK(backup_bytes_ == 0 && buffer_.get() != NULL)
<< " BackUp() can only be called after Next().";
GOOGLE_CHECK_LE(count, buffer_used_)
<< " Can't back up over more bytes than were returned by the last call"
" to Next().";
GOOGLE_CHECK_GE(count, 0)
<< " Parameter to BackUp() can't be negative.";
backup_bytes_ = count;
}
bool CopyingInputStreamAdaptor::Skip(int count) {
GOOGLE_CHECK_GE(count, 0);
if (failed_) {
// Already failed on a previous read.
return false;
}
// First skip any bytes left over from a previous BackUp().
if (backup_bytes_ >= count) {
// We have more data left over than we're trying to skip. Just chop it.
backup_bytes_ -= count;
return true;
}
count -= backup_bytes_;
backup_bytes_ = 0;
int skipped = copying_stream_->Skip(count);
position_ += skipped;
return skipped == count;
}
int64 CopyingInputStreamAdaptor::ByteCount() const {
return position_ - backup_bytes_;
}
void CopyingInputStreamAdaptor::AllocateBufferIfNeeded() {
if (buffer_.get() == NULL) {
buffer_.reset(new uint8[buffer_size_]);
}
}
void CopyingInputStreamAdaptor::FreeBuffer() {
GOOGLE_CHECK_EQ(backup_bytes_, 0);
buffer_used_ = 0;
buffer_.reset();
}
// ===================================================================
CopyingOutputStream::~CopyingOutputStream() {}
CopyingOutputStreamAdaptor::CopyingOutputStreamAdaptor(
CopyingOutputStream* copying_stream, int block_size)
: copying_stream_(copying_stream),
owns_copying_stream_(false),
failed_(false),
position_(0),
buffer_size_(block_size > 0 ? block_size : kDefaultBlockSize),
buffer_used_(0) {
}
CopyingOutputStreamAdaptor::~CopyingOutputStreamAdaptor() {
WriteBuffer();
if (owns_copying_stream_) {
delete copying_stream_;
}
}
bool CopyingOutputStreamAdaptor::Flush() {
return WriteBuffer();
}
bool CopyingOutputStreamAdaptor::Next(void** data, int* size) {
if (buffer_used_ == buffer_size_) {
if (!WriteBuffer()) return false;
}
AllocateBufferIfNeeded();
*data = buffer_.get() + buffer_used_;
*size = buffer_size_ - buffer_used_;
buffer_used_ = buffer_size_;
return true;
}
void CopyingOutputStreamAdaptor::BackUp(int count) {
GOOGLE_CHECK_GE(count, 0);
GOOGLE_CHECK_EQ(buffer_used_, buffer_size_)
<< " BackUp() can only be called after Next().";
GOOGLE_CHECK_LE(count, buffer_used_)
<< " Can't back up over more bytes than were returned by the last call"
" to Next().";
buffer_used_ -= count;
}
int64 CopyingOutputStreamAdaptor::ByteCount() const {
return position_ + buffer_used_;
}
bool CopyingOutputStreamAdaptor::WriteBuffer() {
if (failed_) {
// Already failed on a previous write.
return false;
}
if (buffer_used_ == 0) return true;
if (copying_stream_->Write(buffer_.get(), buffer_used_)) {
position_ += buffer_used_;
buffer_used_ = 0;
return true;
} else {
failed_ = true;
FreeBuffer();
return false;
}
}
void CopyingOutputStreamAdaptor::AllocateBufferIfNeeded() {
if (buffer_ == NULL) {
buffer_.reset(new uint8[buffer_size_]);
}
}
void CopyingOutputStreamAdaptor::FreeBuffer() {
buffer_used_ = 0;
buffer_.reset();
}
// ===================================================================
} // namespace io
} // namespace protobuf
} // namespace google

View File

@ -0,0 +1,340 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// http://code.google.com/p/protobuf/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Author: kenton@google.com (Kenton Varda)
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
//
// This file contains common implementations of the interfaces defined in
// zero_copy_stream.h which are included in the "lite" protobuf library.
// These implementations cover I/O on raw arrays and strings, as well as
// adaptors which make it easy to implement streams based on traditional
// streams. Of course, many users will probably want to write their own
// implementations of these interfaces specific to the particular I/O
// abstractions they prefer to use, but these should cover the most common
// cases.
#ifndef GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_IMPL_LITE_H__
#define GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_IMPL_LITE_H__
#include <string>
#include <iosfwd>
#include <google/protobuf/io/zero_copy_stream.h>
#include <google/protobuf/stubs/common.h>
namespace google {
namespace protobuf {
namespace io {
// ===================================================================
// A ZeroCopyInputStream backed by an in-memory array of bytes.
class LIBPROTOBUF_EXPORT ArrayInputStream : public ZeroCopyInputStream {
public:
// Create an InputStream that returns the bytes pointed to by "data".
// "data" remains the property of the caller but must remain valid until
// the stream is destroyed. If a block_size is given, calls to Next()
// will return data blocks no larger than the given size. Otherwise, the
// first call to Next() returns the entire array. block_size is mainly
// useful for testing; in production you would probably never want to set
// it.
ArrayInputStream(const void* data, int size, int block_size = -1);
~ArrayInputStream();
// implements ZeroCopyInputStream ----------------------------------
bool Next(const void** data, int* size);
void BackUp(int count);
bool Skip(int count);
int64 ByteCount() const;
private:
const uint8* const data_; // The byte array.
const int size_; // Total size of the array.
const int block_size_; // How many bytes to return at a time.
int position_;
int last_returned_size_; // How many bytes we returned last time Next()
// was called (used for error checking only).
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ArrayInputStream);
};
// ===================================================================
// A ZeroCopyOutputStream backed by an in-memory array of bytes.
class LIBPROTOBUF_EXPORT ArrayOutputStream : public ZeroCopyOutputStream {
public:
// Create an OutputStream that writes to the bytes pointed to by "data".
// "data" remains the property of the caller but must remain valid until
// the stream is destroyed. If a block_size is given, calls to Next()
// will return data blocks no larger than the given size. Otherwise, the
// first call to Next() returns the entire array. block_size is mainly
// useful for testing; in production you would probably never want to set
// it.
ArrayOutputStream(void* data, int size, int block_size = -1);
~ArrayOutputStream();
// implements ZeroCopyOutputStream ---------------------------------
bool Next(void** data, int* size);
void BackUp(int count);
int64 ByteCount() const;
private:
uint8* const data_; // The byte array.
const int size_; // Total size of the array.
const int block_size_; // How many bytes to return at a time.
int position_;
int last_returned_size_; // How many bytes we returned last time Next()
// was called (used for error checking only).
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ArrayOutputStream);
};
// ===================================================================
// A ZeroCopyOutputStream which appends bytes to a string.
class LIBPROTOBUF_EXPORT StringOutputStream : public ZeroCopyOutputStream {
public:
// Create a StringOutputStream which appends bytes to the given string.
// The string remains property of the caller, but it MUST NOT be accessed
// in any way until the stream is destroyed.
//
// Hint: If you call target->reserve(n) before creating the stream,
// the first call to Next() will return at least n bytes of buffer
// space.
explicit StringOutputStream(string* target);
~StringOutputStream();
// implements ZeroCopyOutputStream ---------------------------------
bool Next(void** data, int* size);
void BackUp(int count);
int64 ByteCount() const;
private:
static const int kMinimumSize = 16;
string* target_;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(StringOutputStream);
};
// Note: There is no StringInputStream. Instead, just create an
// ArrayInputStream as follows:
// ArrayInputStream input(str.data(), str.size());
// ===================================================================
// A generic traditional input stream interface.
//
// Lots of traditional input streams (e.g. file descriptors, C stdio
// streams, and C++ iostreams) expose an interface where every read
// involves copying bytes into a buffer. If you want to take such an
// interface and make a ZeroCopyInputStream based on it, simply implement
// CopyingInputStream and then use CopyingInputStreamAdaptor.
//
// CopyingInputStream implementations should avoid buffering if possible.
// CopyingInputStreamAdaptor does its own buffering and will read data
// in large blocks.
class LIBPROTOBUF_EXPORT CopyingInputStream {
public:
virtual ~CopyingInputStream();
// Reads up to "size" bytes into the given buffer. Returns the number of
// bytes read. Read() waits until at least one byte is available, or
// returns zero if no bytes will ever become available (EOF), or -1 if a
// permanent read error occurred.
virtual int Read(void* buffer, int size) = 0;
// Skips the next "count" bytes of input. Returns the number of bytes
// actually skipped. This will always be exactly equal to "count" unless
// EOF was reached or a permanent read error occurred.
//
// The default implementation just repeatedly calls Read() into a scratch
// buffer.
virtual int Skip(int count);
};
// A ZeroCopyInputStream which reads from a CopyingInputStream. This is
// useful for implementing ZeroCopyInputStreams that read from traditional
// streams. Note that this class is not really zero-copy.
//
// If you want to read from file descriptors or C++ istreams, this is
// already implemented for you: use FileInputStream or IstreamInputStream
// respectively.
class LIBPROTOBUF_EXPORT CopyingInputStreamAdaptor : public ZeroCopyInputStream {
public:
// Creates a stream that reads from the given CopyingInputStream.
// If a block_size is given, it specifies the number of bytes that
// should be read and returned with each call to Next(). Otherwise,
// a reasonable default is used. The caller retains ownership of
// copying_stream unless SetOwnsCopyingStream(true) is called.
explicit CopyingInputStreamAdaptor(CopyingInputStream* copying_stream,
int block_size = -1);
~CopyingInputStreamAdaptor();
// Call SetOwnsCopyingStream(true) to tell the CopyingInputStreamAdaptor to
// delete the underlying CopyingInputStream when it is destroyed.
void SetOwnsCopyingStream(bool value) { owns_copying_stream_ = value; }
// implements ZeroCopyInputStream ----------------------------------
bool Next(const void** data, int* size);
void BackUp(int count);
bool Skip(int count);
int64 ByteCount() const;
private:
// Insures that buffer_ is not NULL.
void AllocateBufferIfNeeded();
// Frees the buffer and resets buffer_used_.
void FreeBuffer();
// The underlying copying stream.
CopyingInputStream* copying_stream_;
bool owns_copying_stream_;
// True if we have seen a permenant error from the underlying stream.
bool failed_;
// The current position of copying_stream_, relative to the point where
// we started reading.
int64 position_;
// Data is read into this buffer. It may be NULL if no buffer is currently
// in use. Otherwise, it points to an array of size buffer_size_.
scoped_array<uint8> buffer_;
const int buffer_size_;
// Number of valid bytes currently in the buffer (i.e. the size last
// returned by Next()). 0 <= buffer_used_ <= buffer_size_.
int buffer_used_;
// Number of bytes in the buffer which were backed up over by a call to
// BackUp(). These need to be returned again.
// 0 <= backup_bytes_ <= buffer_used_
int backup_bytes_;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CopyingInputStreamAdaptor);
};
// ===================================================================
// A generic traditional output stream interface.
//
// Lots of traditional output streams (e.g. file descriptors, C stdio
// streams, and C++ iostreams) expose an interface where every write
// involves copying bytes from a buffer. If you want to take such an
// interface and make a ZeroCopyOutputStream based on it, simply implement
// CopyingOutputStream and then use CopyingOutputStreamAdaptor.
//
// CopyingOutputStream implementations should avoid buffering if possible.
// CopyingOutputStreamAdaptor does its own buffering and will write data
// in large blocks.
class LIBPROTOBUF_EXPORT CopyingOutputStream {
public:
virtual ~CopyingOutputStream();
// Writes "size" bytes from the given buffer to the output. Returns true
// if successful, false on a write error.
virtual bool Write(const void* buffer, int size) = 0;
};
// A ZeroCopyOutputStream which writes to a CopyingOutputStream. This is
// useful for implementing ZeroCopyOutputStreams that write to traditional
// streams. Note that this class is not really zero-copy.
//
// If you want to write to file descriptors or C++ ostreams, this is
// already implemented for you: use FileOutputStream or OstreamOutputStream
// respectively.
class LIBPROTOBUF_EXPORT CopyingOutputStreamAdaptor : public ZeroCopyOutputStream {
public:
// Creates a stream that writes to the given Unix file descriptor.
// If a block_size is given, it specifies the size of the buffers
// that should be returned by Next(). Otherwise, a reasonable default
// is used.
explicit CopyingOutputStreamAdaptor(CopyingOutputStream* copying_stream,
int block_size = -1);
~CopyingOutputStreamAdaptor();
// Writes all pending data to the underlying stream. Returns false if a
// write error occurred on the underlying stream. (The underlying
// stream itself is not necessarily flushed.)
bool Flush();
// Call SetOwnsCopyingStream(true) to tell the CopyingOutputStreamAdaptor to
// delete the underlying CopyingOutputStream when it is destroyed.
void SetOwnsCopyingStream(bool value) { owns_copying_stream_ = value; }
// implements ZeroCopyOutputStream ---------------------------------
bool Next(void** data, int* size);
void BackUp(int count);
int64 ByteCount() const;
private:
// Write the current buffer, if it is present.
bool WriteBuffer();
// Insures that buffer_ is not NULL.
void AllocateBufferIfNeeded();
// Frees the buffer.
void FreeBuffer();
// The underlying copying stream.
CopyingOutputStream* copying_stream_;
bool owns_copying_stream_;
// True if we have seen a permenant error from the underlying stream.
bool failed_;
// The current position of copying_stream_, relative to the point where
// we started writing.
int64 position_;
// Data is written from this buffer. It may be NULL if no buffer is
// currently in use. Otherwise, it points to an array of size buffer_size_.
scoped_array<uint8> buffer_;
const int buffer_size_;
// Number of valid bytes currently in the buffer (i.e. the size last
// returned by Next()). When BackUp() is called, we just reduce this.
// 0 <= buffer_used_ <= buffer_size_.
int buffer_used_;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CopyingOutputStreamAdaptor);
};
// ===================================================================
} // namespace io
} // namespace protobuf
} // namespace google
#endif // GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_IMPL_LITE_H__

View File

@ -0,0 +1,334 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// http://code.google.com/p/protobuf/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Authors: wink@google.com (Wink Saville),
// kenton@google.com (Kenton Varda)
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
#include <google/protobuf/message_lite.h>
#include <string>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
#include <google/protobuf/stubs/stl_util.h>
namespace google {
namespace protobuf {
MessageLite::~MessageLite() {}
string MessageLite::InitializationErrorString() const {
return "(cannot determine missing fields for lite message)";
}
namespace {
// When serializing, we first compute the byte size, then serialize the message.
// If serialization produces a different number of bytes than expected, we
// call this function, which crashes. The problem could be due to a bug in the
// protobuf implementation but is more likely caused by concurrent modification
// of the message. This function attempts to distinguish between the two and
// provide a useful error message.
void ByteSizeConsistencyError(int byte_size_before_serialization,
int byte_size_after_serialization,
int bytes_produced_by_serialization) {
GOOGLE_CHECK_EQ(byte_size_before_serialization, byte_size_after_serialization)
<< "Protocol message was modified concurrently during serialization.";
GOOGLE_CHECK_EQ(bytes_produced_by_serialization, byte_size_before_serialization)
<< "Byte size calculation and serialization were inconsistent. This "
"may indicate a bug in protocol buffers or it may be caused by "
"concurrent modification of the message.";
GOOGLE_LOG(FATAL) << "This shouldn't be called if all the sizes are equal.";
}
string InitializationErrorMessage(const char* action,
const MessageLite& message) {
// Note: We want to avoid depending on strutil in the lite library, otherwise
// we'd use:
//
// return strings::Substitute(
// "Can't $0 message of type \"$1\" because it is missing required "
// "fields: $2",
// action, message.GetTypeName(),
// message.InitializationErrorString());
string result;
result += "Can't ";
result += action;
result += " message of type \"";
result += message.GetTypeName();
result += "\" because it is missing required fields: ";
result += message.InitializationErrorString();
return result;
}
// Several of the Parse methods below just do one thing and then call another
// method. In a naive implementation, we might have ParseFromString() call
// ParseFromArray() which would call ParseFromZeroCopyStream() which would call
// ParseFromCodedStream() which would call MergeFromCodedStream() which would
// call MergePartialFromCodedStream(). However, when parsing very small
// messages, every function call introduces significant overhead. To avoid
// this without reproducing code, we use these forced-inline helpers.
//
// Note: GCC only allows GOOGLE_ATTRIBUTE_ALWAYS_INLINE on declarations, not
// definitions.
inline bool InlineMergeFromCodedStream(io::CodedInputStream* input,
MessageLite* message)
GOOGLE_ATTRIBUTE_ALWAYS_INLINE;
inline bool InlineParseFromCodedStream(io::CodedInputStream* input,
MessageLite* message)
GOOGLE_ATTRIBUTE_ALWAYS_INLINE;
inline bool InlineParsePartialFromCodedStream(io::CodedInputStream* input,
MessageLite* message)
GOOGLE_ATTRIBUTE_ALWAYS_INLINE;
inline bool InlineParseFromArray(const void* data, int size,
MessageLite* message)
GOOGLE_ATTRIBUTE_ALWAYS_INLINE;
inline bool InlineParsePartialFromArray(const void* data, int size,
MessageLite* message)
GOOGLE_ATTRIBUTE_ALWAYS_INLINE;
bool InlineMergeFromCodedStream(io::CodedInputStream* input,
MessageLite* message) {
if (!message->MergePartialFromCodedStream(input)) return false;
if (!message->IsInitialized()) {
GOOGLE_LOG(ERROR) << InitializationErrorMessage("parse", *message);
return false;
}
return true;
}
bool InlineParseFromCodedStream(io::CodedInputStream* input,
MessageLite* message) {
message->Clear();
return InlineMergeFromCodedStream(input, message);
}
bool InlineParsePartialFromCodedStream(io::CodedInputStream* input,
MessageLite* message) {
message->Clear();
return message->MergePartialFromCodedStream(input);
}
bool InlineParseFromArray(const void* data, int size, MessageLite* message) {
io::CodedInputStream input(reinterpret_cast<const uint8*>(data), size);
return InlineParseFromCodedStream(&input, message) &&
input.ConsumedEntireMessage();
}
bool InlineParsePartialFromArray(const void* data, int size,
MessageLite* message) {
io::CodedInputStream input(reinterpret_cast<const uint8*>(data), size);
return InlineParsePartialFromCodedStream(&input, message) &&
input.ConsumedEntireMessage();
}
} // namespace
bool MessageLite::MergeFromCodedStream(io::CodedInputStream* input) {
return InlineMergeFromCodedStream(input, this);
}
bool MessageLite::ParseFromCodedStream(io::CodedInputStream* input) {
return InlineParseFromCodedStream(input, this);
}
bool MessageLite::ParsePartialFromCodedStream(io::CodedInputStream* input) {
return InlineParsePartialFromCodedStream(input, this);
}
bool MessageLite::ParseFromZeroCopyStream(io::ZeroCopyInputStream* input) {
io::CodedInputStream decoder(input);
return ParseFromCodedStream(&decoder) && decoder.ConsumedEntireMessage();
}
bool MessageLite::ParsePartialFromZeroCopyStream(
io::ZeroCopyInputStream* input) {
io::CodedInputStream decoder(input);
return ParsePartialFromCodedStream(&decoder) &&
decoder.ConsumedEntireMessage();
}
bool MessageLite::ParseFromBoundedZeroCopyStream(
io::ZeroCopyInputStream* input, int size) {
io::CodedInputStream decoder(input);
decoder.PushLimit(size);
return ParseFromCodedStream(&decoder) &&
decoder.ConsumedEntireMessage() &&
decoder.BytesUntilLimit() == 0;
}
bool MessageLite::ParsePartialFromBoundedZeroCopyStream(
io::ZeroCopyInputStream* input, int size) {
io::CodedInputStream decoder(input);
decoder.PushLimit(size);
return ParsePartialFromCodedStream(&decoder) &&
decoder.ConsumedEntireMessage() &&
decoder.BytesUntilLimit() == 0;
}
bool MessageLite::ParseFromString(const string& data) {
return InlineParseFromArray(data.data(), data.size(), this);
}
bool MessageLite::ParsePartialFromString(const string& data) {
return InlineParsePartialFromArray(data.data(), data.size(), this);
}
bool MessageLite::ParseFromArray(const void* data, int size) {
return InlineParseFromArray(data, size, this);
}
bool MessageLite::ParsePartialFromArray(const void* data, int size) {
return InlineParsePartialFromArray(data, size, this);
}
// ===================================================================
uint8* MessageLite::SerializeWithCachedSizesToArray(uint8* target) const {
// We only optimize this when using optimize_for = SPEED. In other cases
// we just use the CodedOutputStream path.
int size = GetCachedSize();
io::ArrayOutputStream out(target, size);
io::CodedOutputStream coded_out(&out);
SerializeWithCachedSizes(&coded_out);
GOOGLE_CHECK(!coded_out.HadError());
return target + size;
}
bool MessageLite::SerializeToCodedStream(io::CodedOutputStream* output) const {
GOOGLE_DCHECK(IsInitialized()) << InitializationErrorMessage("serialize", *this);
return SerializePartialToCodedStream(output);
}
bool MessageLite::SerializePartialToCodedStream(
io::CodedOutputStream* output) const {
const int size = ByteSize(); // Force size to be cached.
uint8* buffer = output->GetDirectBufferForNBytesAndAdvance(size);
if (buffer != NULL) {
uint8* end = SerializeWithCachedSizesToArray(buffer);
if (end - buffer != size) {
ByteSizeConsistencyError(size, ByteSize(), end - buffer);
}
return true;
} else {
int original_byte_count = output->ByteCount();
SerializeWithCachedSizes(output);
if (output->HadError()) {
return false;
}
int final_byte_count = output->ByteCount();
if (final_byte_count - original_byte_count != size) {
ByteSizeConsistencyError(size, ByteSize(),
final_byte_count - original_byte_count);
}
return true;
}
}
bool MessageLite::SerializeToZeroCopyStream(
io::ZeroCopyOutputStream* output) const {
io::CodedOutputStream encoder(output);
return SerializeToCodedStream(&encoder);
}
bool MessageLite::SerializePartialToZeroCopyStream(
io::ZeroCopyOutputStream* output) const {
io::CodedOutputStream encoder(output);
return SerializePartialToCodedStream(&encoder);
}
bool MessageLite::AppendToString(string* output) const {
GOOGLE_DCHECK(IsInitialized()) << InitializationErrorMessage("serialize", *this);
return AppendPartialToString(output);
}
bool MessageLite::AppendPartialToString(string* output) const {
int old_size = output->size();
int byte_size = ByteSize();
STLStringResizeUninitialized(output, old_size + byte_size);
uint8* start = reinterpret_cast<uint8*>(string_as_array(output) + old_size);
uint8* end = SerializeWithCachedSizesToArray(start);
if (end - start != byte_size) {
ByteSizeConsistencyError(byte_size, ByteSize(), end - start);
}
return true;
}
bool MessageLite::SerializeToString(string* output) const {
output->clear();
return AppendToString(output);
}
bool MessageLite::SerializePartialToString(string* output) const {
output->clear();
return AppendPartialToString(output);
}
bool MessageLite::SerializeToArray(void* data, int size) const {
GOOGLE_DCHECK(IsInitialized()) << InitializationErrorMessage("serialize", *this);
return SerializePartialToArray(data, size);
}
bool MessageLite::SerializePartialToArray(void* data, int size) const {
int byte_size = ByteSize();
if (size < byte_size) return false;
uint8* start = reinterpret_cast<uint8*>(data);
uint8* end = SerializeWithCachedSizesToArray(start);
if (end - start != byte_size) {
ByteSizeConsistencyError(byte_size, ByteSize(), end - start);
}
return true;
}
string MessageLite::SerializeAsString() const {
// If the compiler implements the (Named) Return Value Optimization,
// the local variable 'result' will not actually reside on the stack
// of this function, but will be overlaid with the object that the
// caller supplied for the return value to be constructed in.
string output;
if (!AppendToString(&output))
output.clear();
return output;
}
string MessageLite::SerializePartialAsString() const {
string output;
if (!AppendPartialToString(&output))
output.clear();
return output;
}
} // namespace protobuf
} // namespace google

View File

@ -0,0 +1,246 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// http://code.google.com/p/protobuf/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Authors: wink@google.com (Wink Saville),
// kenton@google.com (Kenton Varda)
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
//
// Defines MessageLite, the abstract interface implemented by all (lite
// and non-lite) protocol message objects.
#ifndef GOOGLE_PROTOBUF_MESSAGE_LITE_H__
#define GOOGLE_PROTOBUF_MESSAGE_LITE_H__
#include <google/protobuf/stubs/common.h>
namespace google {
namespace protobuf {
namespace io {
class CodedInputStream;
class CodedOutputStream;
class ZeroCopyInputStream;
class ZeroCopyOutputStream;
}
// Interface to light weight protocol messages.
//
// This interface is implemented by all protocol message objects. Non-lite
// messages additionally implement the Message interface, which is a
// subclass of MessageLite. Use MessageLite instead when you only need
// the subset of features which it supports -- namely, nothing that uses
// descriptors or reflection. You can instruct the protocol compiler
// to generate classes which implement only MessageLite, not the full
// Message interface, by adding the following line to the .proto file:
//
// option optimize_for = LITE_RUNTIME;
//
// This is particularly useful on resource-constrained systems where
// the full protocol buffers runtime library is too big.
//
// Note that on non-constrained systems (e.g. servers) when you need
// to link in lots of protocol definitions, a better way to reduce
// total code footprint is to use optimize_for = CODE_SIZE. This
// will make the generated code smaller while still supporting all the
// same features (at the expense of speed). optimize_for = LITE_RUNTIME
// is best when you only have a small number of message types linked
// into your binary, in which case the size of the protocol buffers
// runtime itself is the biggest problem.
class LIBPROTOBUF_EXPORT MessageLite {
public:
inline MessageLite() {}
virtual ~MessageLite();
// Basic Operations ------------------------------------------------
// Get the name of this message type, e.g. "foo.bar.BazProto".
virtual string GetTypeName() const = 0;
// Construct a new instance of the same type. Ownership is passed to the
// caller.
virtual MessageLite* New() const = 0;
// Clear all fields of the message and set them to their default values.
// Clear() avoids freeing memory, assuming that any memory allocated
// to hold parts of the message will be needed again to hold the next
// message. If you actually want to free the memory used by a Message,
// you must delete it.
virtual void Clear() = 0;
// Quickly check if all required fields have values set.
virtual bool IsInitialized() const = 0;
// This is not implemented for Lite messages -- it just returns "(cannot
// determine missing fields for lite message)". However, it is implemented
// for full messages. See message.h.
virtual string InitializationErrorString() const;
// If |other| is the exact same class as this, calls MergeFrom(). Otherwise,
// results are undefined (probably crash).
virtual void CheckTypeAndMergeFrom(const MessageLite& other) = 0;
// Parsing ---------------------------------------------------------
// Methods for parsing in protocol buffer format. Most of these are
// just simple wrappers around MergeFromCodedStream().
// Fill the message with a protocol buffer parsed from the given input
// stream. Returns false on a read error or if the input is in the
// wrong format.
bool ParseFromCodedStream(io::CodedInputStream* input);
// Like ParseFromCodedStream(), but accepts messages that are missing
// required fields.
bool ParsePartialFromCodedStream(io::CodedInputStream* input);
// Read a protocol buffer from the given zero-copy input stream. If
// successful, the entire input will be consumed.
bool ParseFromZeroCopyStream(io::ZeroCopyInputStream* input);
// Like ParseFromZeroCopyStream(), but accepts messages that are missing
// required fields.
bool ParsePartialFromZeroCopyStream(io::ZeroCopyInputStream* input);
// Read a protocol buffer from the given zero-copy input stream, expecting
// the message to be exactly "size" bytes long. If successful, exactly
// this many bytes will have been consumed from the input.
bool ParseFromBoundedZeroCopyStream(io::ZeroCopyInputStream* input, int size);
// Like ParseFromBoundedZeroCopyStream(), but accepts messages that are
// missing required fields.
bool ParsePartialFromBoundedZeroCopyStream(io::ZeroCopyInputStream* input,
int size);
// Parse a protocol buffer contained in a string.
bool ParseFromString(const string& data);
// Like ParseFromString(), but accepts messages that are missing
// required fields.
bool ParsePartialFromString(const string& data);
// Parse a protocol buffer contained in an array of bytes.
bool ParseFromArray(const void* data, int size);
// Like ParseFromArray(), but accepts messages that are missing
// required fields.
bool ParsePartialFromArray(const void* data, int size);
// Reads a protocol buffer from the stream and merges it into this
// Message. Singular fields read from the input overwrite what is
// already in the Message and repeated fields are appended to those
// already present.
//
// It is the responsibility of the caller to call input->LastTagWas()
// (for groups) or input->ConsumedEntireMessage() (for non-groups) after
// this returns to verify that the message's end was delimited correctly.
//
// ParsefromCodedStream() is implemented as Clear() followed by
// MergeFromCodedStream().
bool MergeFromCodedStream(io::CodedInputStream* input);
// Like MergeFromCodedStream(), but succeeds even if required fields are
// missing in the input.
//
// MergeFromCodedStream() is just implemented as MergePartialFromCodedStream()
// followed by IsInitialized().
virtual bool MergePartialFromCodedStream(io::CodedInputStream* input) = 0;
// Serialization ---------------------------------------------------
// Methods for serializing in protocol buffer format. Most of these
// are just simple wrappers around ByteSize() and SerializeWithCachedSizes().
// Write a protocol buffer of this message to the given output. Returns
// false on a write error. If the message is missing required fields,
// this may GOOGLE_CHECK-fail.
bool SerializeToCodedStream(io::CodedOutputStream* output) const;
// Like SerializeToCodedStream(), but allows missing required fields.
bool SerializePartialToCodedStream(io::CodedOutputStream* output) const;
// Write the message to the given zero-copy output stream. All required
// fields must be set.
bool SerializeToZeroCopyStream(io::ZeroCopyOutputStream* output) const;
// Like SerializeToZeroCopyStream(), but allows missing required fields.
bool SerializePartialToZeroCopyStream(io::ZeroCopyOutputStream* output) const;
// Serialize the message and store it in the given string. All required
// fields must be set.
bool SerializeToString(string* output) const;
// Like SerializeToString(), but allows missing required fields.
bool SerializePartialToString(string* output) const;
// Serialize the message and store it in the given byte array. All required
// fields must be set.
bool SerializeToArray(void* data, int size) const;
// Like SerializeToArray(), but allows missing required fields.
bool SerializePartialToArray(void* data, int size) const;
// Make a string encoding the message. Is equivalent to calling
// SerializeToString() on a string and using that. Returns the empty
// string if SerializeToString() would have returned an error.
// Note: If you intend to generate many such strings, you may
// reduce heap fragmentation by instead re-using the same string
// object with calls to SerializeToString().
string SerializeAsString() const;
// Like SerializeAsString(), but allows missing required fields.
string SerializePartialAsString() const;
// Like SerializeToString(), but appends to the data to the string's existing
// contents. All required fields must be set.
bool AppendToString(string* output) const;
// Like AppendToString(), but allows missing required fields.
bool AppendPartialToString(string* output) const;
// Computes the serialized size of the message. This recursively calls
// ByteSize() on all embedded messages. If a subclass does not override
// this, it MUST override SetCachedSize().
virtual int ByteSize() const = 0;
// Serializes the message without recomputing the size. The message must
// not have changed since the last call to ByteSize(); if it has, the results
// are undefined.
virtual void SerializeWithCachedSizes(
io::CodedOutputStream* output) const = 0;
// Like SerializeWithCachedSizes, but writes directly to *target, returning
// a pointer to the byte immediately after the last byte written. "target"
// must point at a byte array of at least ByteSize() bytes.
virtual uint8* SerializeWithCachedSizesToArray(uint8* target) const;
// Returns the result of the last call to ByteSize(). An embedded message's
// size is needed both to serialize it (because embedded messages are
// length-delimited) and to compute the outer message's size. Caching
// the size avoids computing it multiple times.
//
// ByteSize() does not automatically use the cached size when available
// because this would require invalidating it every time the message was
// modified, which would be too hard and expensive. (E.g. if a deeply-nested
// sub-message is changed, all of its parents' cached sizes would need to be
// invalidated, which is too much work for an otherwise inlined setter
// method.)
virtual int GetCachedSize() const = 0;
private:
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageLite);
};
} // namespace protobuf
} // namespace google
#endif // GOOGLE_PROTOBUF_MESSAGE_LITE_H__

View File

@ -0,0 +1,87 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// http://code.google.com/p/protobuf/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Author: kenton@google.com (Kenton Varda)
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
#include <algorithm>
#include <google/protobuf/repeated_field.h>
#include <google/protobuf/stubs/common.h>
namespace google {
namespace protobuf {
namespace internal {
void RepeatedPtrFieldBase::Reserve(int new_size) {
if (total_size_ >= new_size) return;
void** old_elements = elements_;
total_size_ = max(kMinRepeatedFieldAllocationSize,
max(total_size_ * 2, new_size));
elements_ = new void*[total_size_];
if (old_elements != NULL) {
memcpy(elements_, old_elements, allocated_size_ * sizeof(elements_[0]));
delete [] old_elements;
}
}
void RepeatedPtrFieldBase::Swap(RepeatedPtrFieldBase* other) {
if (this == other) return;
void** swap_elements = elements_;
int swap_current_size = current_size_;
int swap_allocated_size = allocated_size_;
int swap_total_size = total_size_;
elements_ = other->elements_;
current_size_ = other->current_size_;
allocated_size_ = other->allocated_size_;
total_size_ = other->total_size_;
other->elements_ = swap_elements;
other->current_size_ = swap_current_size;
other->allocated_size_ = swap_allocated_size;
other->total_size_ = swap_total_size;
}
string* StringTypeHandlerBase::New() {
return new string;
}
void StringTypeHandlerBase::Delete(string* value) {
delete value;
}
} // namespace internal
} // namespace protobuf
} // namespace google

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,206 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2012 Google Inc. All rights reserved.
// http://code.google.com/p/protobuf/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// The routines exported by this module are subtle. If you use them, even if
// you get the code right, it will depend on careful reasoning about atomicity
// and memory ordering; it will be less readable, and harder to maintain. If
// you plan to use these routines, you should have a good reason, such as solid
// evidence that performance would otherwise suffer, or there being no
// alternative. You should assume only properties explicitly guaranteed by the
// specifications in this file. You are almost certainly _not_ writing code
// just for the x86; if you assume x86 semantics, x86 hardware bugs and
// implementations on other archtectures will cause your code to break. If you
// do not know what you are doing, avoid these routines, and use a Mutex.
//
// It is incorrect to make direct assignments to/from an atomic variable.
// You should use one of the Load or Store routines. The NoBarrier
// versions are provided when no barriers are needed:
// NoBarrier_Store()
// NoBarrier_Load()
// Although there are currently no compiler enforcement, you are encouraged
// to use these.
// This header and the implementations for each platform (located in
// atomicops_internals_*) must be kept in sync with the upstream code (V8).
#ifndef GOOGLE_PROTOBUF_ATOMICOPS_H_
#define GOOGLE_PROTOBUF_ATOMICOPS_H_
// Don't include this file for people not concerned about thread safety.
#ifndef GOOGLE_PROTOBUF_NO_THREAD_SAFETY
#include <google/protobuf/stubs/platform_macros.h>
namespace google {
namespace protobuf {
namespace internal {
typedef int32 Atomic32;
#ifdef GOOGLE_PROTOBUF_ARCH_64_BIT
// We need to be able to go between Atomic64 and AtomicWord implicitly. This
// means Atomic64 and AtomicWord should be the same type on 64-bit.
#if defined(GOOGLE_PROTOBUF_OS_NACL)
// NaCl's intptr_t is not actually 64-bits on 64-bit!
// http://code.google.com/p/nativeclient/issues/detail?id=1162
typedef int64 Atomic64;
#else
typedef intptr_t Atomic64;
#endif
#endif
// Use AtomicWord for a machine-sized pointer. It will use the Atomic32 or
// Atomic64 routines below, depending on your architecture.
typedef intptr_t AtomicWord;
// Atomically execute:
// result = *ptr;
// if (*ptr == old_value)
// *ptr = new_value;
// return result;
//
// I.e., replace "*ptr" with "new_value" if "*ptr" used to be "old_value".
// Always return the old value of "*ptr"
//
// This routine implies no memory barriers.
Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,
Atomic32 old_value,
Atomic32 new_value);
// Atomically store new_value into *ptr, returning the previous value held in
// *ptr. This routine implies no memory barriers.
Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr, Atomic32 new_value);
// Atomically increment *ptr by "increment". Returns the new value of
// *ptr with the increment applied. This routine implies no memory barriers.
Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr, Atomic32 increment);
Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr,
Atomic32 increment);
// These following lower-level operations are typically useful only to people
// implementing higher-level synchronization operations like spinlocks,
// mutexes, and condition-variables. They combine CompareAndSwap(), a load, or
// a store with appropriate memory-ordering instructions. "Acquire" operations
// ensure that no later memory access can be reordered ahead of the operation.
// "Release" operations ensure that no previous memory access can be reordered
// after the operation. "Barrier" operations have both "Acquire" and "Release"
// semantics. A MemoryBarrier() has "Barrier" semantics, but does no memory
// access.
Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
Atomic32 old_value,
Atomic32 new_value);
Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
Atomic32 old_value,
Atomic32 new_value);
void MemoryBarrier();
void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value);
void Acquire_Store(volatile Atomic32* ptr, Atomic32 value);
void Release_Store(volatile Atomic32* ptr, Atomic32 value);
Atomic32 NoBarrier_Load(volatile const Atomic32* ptr);
Atomic32 Acquire_Load(volatile const Atomic32* ptr);
Atomic32 Release_Load(volatile const Atomic32* ptr);
// 64-bit atomic operations (only available on 64-bit processors).
#ifdef GOOGLE_PROTOBUF_ARCH_64_BIT
Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr,
Atomic64 old_value,
Atomic64 new_value);
Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr, Atomic64 new_value);
Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr, Atomic64 increment);
Atomic64 Barrier_AtomicIncrement(volatile Atomic64* ptr, Atomic64 increment);
Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr,
Atomic64 old_value,
Atomic64 new_value);
Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr,
Atomic64 old_value,
Atomic64 new_value);
void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value);
void Acquire_Store(volatile Atomic64* ptr, Atomic64 value);
void Release_Store(volatile Atomic64* ptr, Atomic64 value);
Atomic64 NoBarrier_Load(volatile const Atomic64* ptr);
Atomic64 Acquire_Load(volatile const Atomic64* ptr);
Atomic64 Release_Load(volatile const Atomic64* ptr);
#endif // GOOGLE_PROTOBUF_ARCH_64_BIT
} // namespace internal
} // namespace protobuf
} // namespace google
// Include our platform specific implementation.
#define GOOGLE_PROTOBUF_ATOMICOPS_ERROR \
#error "Atomic operations are not supported on your platform"
// MSVC.
#if defined(_MSC_VER)
#if defined(GOOGLE_PROTOBUF_ARCH_IA32) || defined(GOOGLE_PROTOBUF_ARCH_X64)
#include <google/protobuf/stubs/atomicops_internals_x86_msvc.h>
#else
GOOGLE_PROTOBUF_ATOMICOPS_ERROR
#endif
// Apple.
#elif defined(GOOGLE_PROTOBUF_OS_APPLE)
#include <google/protobuf/stubs/atomicops_internals_macosx.h>
// GCC.
#elif defined(__GNUC__)
#if defined(GOOGLE_PROTOBUF_ARCH_IA32) || defined(GOOGLE_PROTOBUF_ARCH_X64)
#include <google/protobuf/stubs/atomicops_internals_x86_gcc.h>
#elif defined(GOOGLE_PROTOBUF_ARCH_ARM)
#include <google/protobuf/stubs/atomicops_internals_arm_gcc.h>
#elif defined(GOOGLE_PROTOBUF_ARCH_ARM_QNX)
#include <google/protobuf/stubs/atomicops_internals_arm_qnx.h>
#elif defined(GOOGLE_PROTOBUF_ARCH_MIPS)
#include <google/protobuf/stubs/atomicops_internals_mips_gcc.h>
#elif defined(__pnacl__)
#include <google/protobuf/stubs/atomicops_internals_pnacl.h>
#else
#include <google/protobuf/stubs/atomicops_internals_generic_gcc.h>
#endif
// Unknown.
#else
GOOGLE_PROTOBUF_ATOMICOPS_ERROR
#endif
// On some platforms we need additional declarations to make AtomicWord
// compatible with our other Atomic* types.
#if defined(GOOGLE_PROTOBUF_OS_APPLE)
#include <google/protobuf/stubs/atomicops_internals_atomicword_compat.h>
#endif
#undef GOOGLE_PROTOBUF_ATOMICOPS_ERROR
#endif // GOOGLE_PROTOBUF_NO_THREAD_SAFETY
#endif // GOOGLE_PROTOBUF_ATOMICOPS_H_

View File

@ -0,0 +1,151 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2012 Google Inc. All rights reserved.
// http://code.google.com/p/protobuf/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// This file is an internal atomic implementation, use atomicops.h instead.
//
// LinuxKernelCmpxchg and Barrier_AtomicIncrement are from Google Gears.
#ifndef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_ARM_GCC_H_
#define GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_ARM_GCC_H_
namespace google {
namespace protobuf {
namespace internal {
// 0xffff0fc0 is the hard coded address of a function provided by
// the kernel which implements an atomic compare-exchange. On older
// ARM architecture revisions (pre-v6) this may be implemented using
// a syscall. This address is stable, and in active use (hard coded)
// by at least glibc-2.7 and the Android C library.
typedef Atomic32 (*LinuxKernelCmpxchgFunc)(Atomic32 old_value,
Atomic32 new_value,
volatile Atomic32* ptr);
LinuxKernelCmpxchgFunc pLinuxKernelCmpxchg __attribute__((weak)) =
(LinuxKernelCmpxchgFunc) 0xffff0fc0;
typedef void (*LinuxKernelMemoryBarrierFunc)(void);
LinuxKernelMemoryBarrierFunc pLinuxKernelMemoryBarrier __attribute__((weak)) =
(LinuxKernelMemoryBarrierFunc) 0xffff0fa0;
inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,
Atomic32 old_value,
Atomic32 new_value) {
Atomic32 prev_value = *ptr;
do {
if (!pLinuxKernelCmpxchg(old_value, new_value,
const_cast<Atomic32*>(ptr))) {
return old_value;
}
prev_value = *ptr;
} while (prev_value == old_value);
return prev_value;
}
inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr,
Atomic32 new_value) {
Atomic32 old_value;
do {
old_value = *ptr;
} while (pLinuxKernelCmpxchg(old_value, new_value,
const_cast<Atomic32*>(ptr)));
return old_value;
}
inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr,
Atomic32 increment) {
return Barrier_AtomicIncrement(ptr, increment);
}
inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr,
Atomic32 increment) {
for (;;) {
// Atomic exchange the old value with an incremented one.
Atomic32 old_value = *ptr;
Atomic32 new_value = old_value + increment;
if (pLinuxKernelCmpxchg(old_value, new_value,
const_cast<Atomic32*>(ptr)) == 0) {
// The exchange took place as expected.
return new_value;
}
// Otherwise, *ptr changed mid-loop and we need to retry.
}
}
inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
Atomic32 old_value,
Atomic32 new_value) {
return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
}
inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
Atomic32 old_value,
Atomic32 new_value) {
return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
}
inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) {
*ptr = value;
}
inline void MemoryBarrier() {
pLinuxKernelMemoryBarrier();
}
inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) {
*ptr = value;
MemoryBarrier();
}
inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) {
MemoryBarrier();
*ptr = value;
}
inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) {
return *ptr;
}
inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) {
Atomic32 value = *ptr;
MemoryBarrier();
return value;
}
inline Atomic32 Release_Load(volatile const Atomic32* ptr) {
MemoryBarrier();
return *ptr;
}
} // namespace internal
} // namespace protobuf
} // namespace google
#endif // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_ARM_GCC_H_

View File

@ -0,0 +1,122 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2012 Google Inc. All rights reserved.
// http://code.google.com/p/protobuf/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// This file is an internal atomic implementation, use atomicops.h instead.
#ifndef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_ATOMICWORD_COMPAT_H_
#define GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_ATOMICWORD_COMPAT_H_
// AtomicWord is a synonym for intptr_t, and Atomic32 is a synonym for int32,
// which in turn means int. On some LP32 platforms, intptr_t is an int, but
// on others, it's a long. When AtomicWord and Atomic32 are based on different
// fundamental types, their pointers are incompatible.
//
// This file defines function overloads to allow both AtomicWord and Atomic32
// data to be used with this interface.
//
// On LP64 platforms, AtomicWord and Atomic64 are both always long,
// so this problem doesn't occur.
#if !defined(GOOGLE_PROTOBUF_ARCH_64_BIT)
namespace google {
namespace protobuf {
namespace internal {
inline AtomicWord NoBarrier_CompareAndSwap(volatile AtomicWord* ptr,
AtomicWord old_value,
AtomicWord new_value) {
return NoBarrier_CompareAndSwap(
reinterpret_cast<volatile Atomic32*>(ptr), old_value, new_value);
}
inline AtomicWord NoBarrier_AtomicExchange(volatile AtomicWord* ptr,
AtomicWord new_value) {
return NoBarrier_AtomicExchange(
reinterpret_cast<volatile Atomic32*>(ptr), new_value);
}
inline AtomicWord NoBarrier_AtomicIncrement(volatile AtomicWord* ptr,
AtomicWord increment) {
return NoBarrier_AtomicIncrement(
reinterpret_cast<volatile Atomic32*>(ptr), increment);
}
inline AtomicWord Barrier_AtomicIncrement(volatile AtomicWord* ptr,
AtomicWord increment) {
return Barrier_AtomicIncrement(
reinterpret_cast<volatile Atomic32*>(ptr), increment);
}
inline AtomicWord Acquire_CompareAndSwap(volatile AtomicWord* ptr,
AtomicWord old_value,
AtomicWord new_value) {
return Acquire_CompareAndSwap(
reinterpret_cast<volatile Atomic32*>(ptr), old_value, new_value);
}
inline AtomicWord Release_CompareAndSwap(volatile AtomicWord* ptr,
AtomicWord old_value,
AtomicWord new_value) {
return Release_CompareAndSwap(
reinterpret_cast<volatile Atomic32*>(ptr), old_value, new_value);
}
inline void NoBarrier_Store(volatile AtomicWord *ptr, AtomicWord value) {
NoBarrier_Store(reinterpret_cast<volatile Atomic32*>(ptr), value);
}
inline void Acquire_Store(volatile AtomicWord* ptr, AtomicWord value) {
return Acquire_Store(reinterpret_cast<volatile Atomic32*>(ptr), value);
}
inline void Release_Store(volatile AtomicWord* ptr, AtomicWord value) {
return Release_Store(reinterpret_cast<volatile Atomic32*>(ptr), value);
}
inline AtomicWord NoBarrier_Load(volatile const AtomicWord *ptr) {
return NoBarrier_Load(reinterpret_cast<volatile const Atomic32*>(ptr));
}
inline AtomicWord Acquire_Load(volatile const AtomicWord* ptr) {
return Acquire_Load(reinterpret_cast<volatile const Atomic32*>(ptr));
}
inline AtomicWord Release_Load(volatile const AtomicWord* ptr) {
return Release_Load(reinterpret_cast<volatile const Atomic32*>(ptr));
}
} // namespace internal
} // namespace protobuf
} // namespace google
#endif // !defined(GOOGLE_PROTOBUF_ARCH_64_BIT)
#endif // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_ATOMICWORD_COMPAT_H_

View File

@ -0,0 +1,139 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2013 Red Hat Inc. All rights reserved.
// http://code.google.com/p/protobuf/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Red Hat Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// This file is an internal atomic implementation, use atomicops.h instead.
#ifndef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_GENERIC_GCC_H_
#define GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_GENERIC_GCC_H_
namespace google {
namespace protobuf {
namespace internal {
inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,
Atomic32 old_value,
Atomic32 new_value) {
__atomic_compare_exchange_n(ptr, &old_value, new_value, true,
__ATOMIC_RELAXED, __ATOMIC_RELAXED);
return old_value;
}
inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr,
Atomic32 new_value) {
return __atomic_exchange_n(ptr, new_value, __ATOMIC_RELAXED);
}
inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr,
Atomic32 increment) {
return __atomic_add_fetch(ptr, increment, __ATOMIC_RELAXED);
}
inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr,
Atomic32 increment) {
return __atomic_add_fetch(ptr, increment, __ATOMIC_SEQ_CST);
}
inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
Atomic32 old_value,
Atomic32 new_value) {
__atomic_compare_exchange(ptr, &old_value, &new_value, true,
__ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE);
return old_value;
}
inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
Atomic32 old_value,
Atomic32 new_value) {
__atomic_compare_exchange_n(ptr, &old_value, new_value, true,
__ATOMIC_RELEASE, __ATOMIC_ACQUIRE);
return old_value;
}
inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) {
__atomic_store_n(ptr, value, __ATOMIC_RELAXED);
}
inline void MemoryBarrier() {
__sync_synchronize();
}
inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) {
__atomic_store_n(ptr, value, __ATOMIC_ACQUIRE);
}
inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) {
__atomic_store_n(ptr, value, __ATOMIC_RELEASE);
}
inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) {
return __atomic_load_n(ptr, __ATOMIC_RELAXED);
}
inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) {
return __atomic_load_n(ptr, __ATOMIC_ACQUIRE);
}
inline Atomic32 Release_Load(volatile const Atomic32* ptr) {
return __atomic_load_n(ptr, __ATOMIC_RELEASE);
}
#ifdef __LP64__
inline void Release_Store(volatile Atomic64* ptr, Atomic64 value) {
__atomic_store_n(ptr, value, __ATOMIC_RELEASE);
}
inline Atomic64 Acquire_Load(volatile const Atomic64* ptr) {
return __atomic_load_n(ptr, __ATOMIC_ACQUIRE);
}
inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr,
Atomic64 old_value,
Atomic64 new_value) {
__atomic_compare_exchange_n(ptr, &old_value, new_value, true,
__ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE);
return old_value;
}
inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr,
Atomic64 old_value,
Atomic64 new_value) {
__atomic_compare_exchange_n(ptr, &old_value, new_value, true,
__ATOMIC_RELAXED, __ATOMIC_RELAXED);
return old_value;
}
#endif // defined(__LP64__)
} // namespace internal
} // namespace protobuf
} // namespace google
#endif // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_GENERIC_GCC_H_

View File

@ -0,0 +1,225 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2012 Google Inc. All rights reserved.
// http://code.google.com/p/protobuf/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// This file is an internal atomic implementation, use atomicops.h instead.
#ifndef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_MACOSX_H_
#define GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_MACOSX_H_
#include <libkern/OSAtomic.h>
namespace google {
namespace protobuf {
namespace internal {
inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,
Atomic32 old_value,
Atomic32 new_value) {
Atomic32 prev_value;
do {
if (OSAtomicCompareAndSwap32(old_value, new_value,
const_cast<Atomic32*>(ptr))) {
return old_value;
}
prev_value = *ptr;
} while (prev_value == old_value);
return prev_value;
}
inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr,
Atomic32 new_value) {
Atomic32 old_value;
do {
old_value = *ptr;
} while (!OSAtomicCompareAndSwap32(old_value, new_value,
const_cast<Atomic32*>(ptr)));
return old_value;
}
inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr,
Atomic32 increment) {
return OSAtomicAdd32(increment, const_cast<Atomic32*>(ptr));
}
inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr,
Atomic32 increment) {
return OSAtomicAdd32Barrier(increment, const_cast<Atomic32*>(ptr));
}
inline void MemoryBarrier() {
OSMemoryBarrier();
}
inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
Atomic32 old_value,
Atomic32 new_value) {
Atomic32 prev_value;
do {
if (OSAtomicCompareAndSwap32Barrier(old_value, new_value,
const_cast<Atomic32*>(ptr))) {
return old_value;
}
prev_value = *ptr;
} while (prev_value == old_value);
return prev_value;
}
inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
Atomic32 old_value,
Atomic32 new_value) {
return Acquire_CompareAndSwap(ptr, old_value, new_value);
}
inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) {
*ptr = value;
}
inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) {
*ptr = value;
MemoryBarrier();
}
inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) {
MemoryBarrier();
*ptr = value;
}
inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) {
return *ptr;
}
inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) {
Atomic32 value = *ptr;
MemoryBarrier();
return value;
}
inline Atomic32 Release_Load(volatile const Atomic32* ptr) {
MemoryBarrier();
return *ptr;
}
#ifdef __LP64__
// 64-bit implementation on 64-bit platform
inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr,
Atomic64 old_value,
Atomic64 new_value) {
Atomic64 prev_value;
do {
if (OSAtomicCompareAndSwap64(old_value, new_value,
reinterpret_cast<volatile int64_t*>(ptr))) {
return old_value;
}
prev_value = *ptr;
} while (prev_value == old_value);
return prev_value;
}
inline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr,
Atomic64 new_value) {
Atomic64 old_value;
do {
old_value = *ptr;
} while (!OSAtomicCompareAndSwap64(old_value, new_value,
reinterpret_cast<volatile int64_t*>(ptr)));
return old_value;
}
inline Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr,
Atomic64 increment) {
return OSAtomicAdd64(increment, reinterpret_cast<volatile int64_t*>(ptr));
}
inline Atomic64 Barrier_AtomicIncrement(volatile Atomic64* ptr,
Atomic64 increment) {
return OSAtomicAdd64Barrier(increment,
reinterpret_cast<volatile int64_t*>(ptr));
}
inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr,
Atomic64 old_value,
Atomic64 new_value) {
Atomic64 prev_value;
do {
if (OSAtomicCompareAndSwap64Barrier(
old_value, new_value, reinterpret_cast<volatile int64_t*>(ptr))) {
return old_value;
}
prev_value = *ptr;
} while (prev_value == old_value);
return prev_value;
}
inline Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr,
Atomic64 old_value,
Atomic64 new_value) {
// The lib kern interface does not distinguish between
// Acquire and Release memory barriers; they are equivalent.
return Acquire_CompareAndSwap(ptr, old_value, new_value);
}
inline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) {
*ptr = value;
}
inline void Acquire_Store(volatile Atomic64* ptr, Atomic64 value) {
*ptr = value;
MemoryBarrier();
}
inline void Release_Store(volatile Atomic64* ptr, Atomic64 value) {
MemoryBarrier();
*ptr = value;
}
inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) {
return *ptr;
}
inline Atomic64 Acquire_Load(volatile const Atomic64* ptr) {
Atomic64 value = *ptr;
MemoryBarrier();
return value;
}
inline Atomic64 Release_Load(volatile const Atomic64* ptr) {
MemoryBarrier();
return *ptr;
}
#endif // defined(__LP64__)
} // namespace internal
} // namespace protobuf
} // namespace google
#endif // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_MACOSX_H_

View File

@ -0,0 +1,137 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2012 Google Inc. All rights reserved.
// http://code.google.com/p/protobuf/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// This module gets enough CPU information to optimize the
// atomicops module on x86.
#include <cstring>
#include <google/protobuf/stubs/atomicops.h>
// This file only makes sense with atomicops_internals_x86_gcc.h -- it
// depends on structs that are defined in that file. If atomicops.h
// doesn't sub-include that file, then we aren't needed, and shouldn't
// try to do anything.
#ifdef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_X86_GCC_H_
// Inline cpuid instruction. In PIC compilations, %ebx contains the address
// of the global offset table. To avoid breaking such executables, this code
// must preserve that register's value across cpuid instructions.
#if defined(__i386__)
#define cpuid(a, b, c, d, inp) \
asm("mov %%ebx, %%edi\n" \
"cpuid\n" \
"xchg %%edi, %%ebx\n" \
: "=a" (a), "=D" (b), "=c" (c), "=d" (d) : "a" (inp))
#elif defined(__x86_64__)
#define cpuid(a, b, c, d, inp) \
asm("mov %%rbx, %%rdi\n" \
"cpuid\n" \
"xchg %%rdi, %%rbx\n" \
: "=a" (a), "=D" (b), "=c" (c), "=d" (d) : "a" (inp))
#endif
#if defined(cpuid) // initialize the struct only on x86
namespace google {
namespace protobuf {
namespace internal {
// Set the flags so that code will run correctly and conservatively, so even
// if we haven't been initialized yet, we're probably single threaded, and our
// default values should hopefully be pretty safe.
struct AtomicOps_x86CPUFeatureStruct AtomicOps_Internalx86CPUFeatures = {
false, // bug can't exist before process spawns multiple threads
false, // no SSE2
};
namespace {
// Initialize the AtomicOps_Internalx86CPUFeatures struct.
void AtomicOps_Internalx86CPUFeaturesInit() {
uint32_t eax;
uint32_t ebx;
uint32_t ecx;
uint32_t edx;
// Get vendor string (issue CPUID with eax = 0)
cpuid(eax, ebx, ecx, edx, 0);
char vendor[13];
memcpy(vendor, &ebx, 4);
memcpy(vendor + 4, &edx, 4);
memcpy(vendor + 8, &ecx, 4);
vendor[12] = 0;
// get feature flags in ecx/edx, and family/model in eax
cpuid(eax, ebx, ecx, edx, 1);
int family = (eax >> 8) & 0xf; // family and model fields
int model = (eax >> 4) & 0xf;
if (family == 0xf) { // use extended family and model fields
family += (eax >> 20) & 0xff;
model += ((eax >> 16) & 0xf) << 4;
}
// Opteron Rev E has a bug in which on very rare occasions a locked
// instruction doesn't act as a read-acquire barrier if followed by a
// non-locked read-modify-write instruction. Rev F has this bug in
// pre-release versions, but not in versions released to customers,
// so we test only for Rev E, which is family 15, model 32..63 inclusive.
if (strcmp(vendor, "AuthenticAMD") == 0 && // AMD
family == 15 &&
32 <= model && model <= 63) {
AtomicOps_Internalx86CPUFeatures.has_amd_lock_mb_bug = true;
} else {
AtomicOps_Internalx86CPUFeatures.has_amd_lock_mb_bug = false;
}
// edx bit 26 is SSE2 which we use to tell use whether we can use mfence
AtomicOps_Internalx86CPUFeatures.has_sse2 = ((edx >> 26) & 1);
}
class AtomicOpsx86Initializer {
public:
AtomicOpsx86Initializer() {
AtomicOps_Internalx86CPUFeaturesInit();
}
};
// A global to get use initialized on startup via static initialization :/
AtomicOpsx86Initializer g_initer;
} // namespace
} // namespace internal
} // namespace protobuf
} // namespace google
#endif // __i386__
#endif // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_X86_GCC_H_

View File

@ -0,0 +1,293 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2012 Google Inc. All rights reserved.
// http://code.google.com/p/protobuf/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// This file is an internal atomic implementation, use atomicops.h instead.
#ifndef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_X86_GCC_H_
#define GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_X86_GCC_H_
namespace google {
namespace protobuf {
namespace internal {
// This struct is not part of the public API of this module; clients may not
// use it.
// Features of this x86. Values may not be correct before main() is run,
// but are set conservatively.
struct AtomicOps_x86CPUFeatureStruct {
bool has_amd_lock_mb_bug; // Processor has AMD memory-barrier bug; do lfence
// after acquire compare-and-swap.
bool has_sse2; // Processor has SSE2.
};
extern struct AtomicOps_x86CPUFeatureStruct AtomicOps_Internalx86CPUFeatures;
#define ATOMICOPS_COMPILER_BARRIER() __asm__ __volatile__("" : : : "memory")
// 32-bit low-level operations on any platform.
inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,
Atomic32 old_value,
Atomic32 new_value) {
Atomic32 prev;
__asm__ __volatile__("lock; cmpxchgl %1,%2"
: "=a" (prev)
: "q" (new_value), "m" (*ptr), "0" (old_value)
: "memory");
return prev;
}
inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr,
Atomic32 new_value) {
__asm__ __volatile__("xchgl %1,%0" // The lock prefix is implicit for xchg.
: "=r" (new_value)
: "m" (*ptr), "0" (new_value)
: "memory");
return new_value; // Now it's the previous value.
}
inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr,
Atomic32 increment) {
Atomic32 temp = increment;
__asm__ __volatile__("lock; xaddl %0,%1"
: "+r" (temp), "+m" (*ptr)
: : "memory");
// temp now holds the old value of *ptr
return temp + increment;
}
inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr,
Atomic32 increment) {
Atomic32 temp = increment;
__asm__ __volatile__("lock; xaddl %0,%1"
: "+r" (temp), "+m" (*ptr)
: : "memory");
// temp now holds the old value of *ptr
if (AtomicOps_Internalx86CPUFeatures.has_amd_lock_mb_bug) {
__asm__ __volatile__("lfence" : : : "memory");
}
return temp + increment;
}
inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
Atomic32 old_value,
Atomic32 new_value) {
Atomic32 x = NoBarrier_CompareAndSwap(ptr, old_value, new_value);
if (AtomicOps_Internalx86CPUFeatures.has_amd_lock_mb_bug) {
__asm__ __volatile__("lfence" : : : "memory");
}
return x;
}
inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
Atomic32 old_value,
Atomic32 new_value) {
return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
}
inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) {
*ptr = value;
}
#if defined(__x86_64__)
// 64-bit implementations of memory barrier can be simpler, because it
// "mfence" is guaranteed to exist.
inline void MemoryBarrier() {
__asm__ __volatile__("mfence" : : : "memory");
}
inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) {
*ptr = value;
MemoryBarrier();
}
#else
inline void MemoryBarrier() {
if (AtomicOps_Internalx86CPUFeatures.has_sse2) {
__asm__ __volatile__("mfence" : : : "memory");
} else { // mfence is faster but not present on PIII
Atomic32 x = 0;
NoBarrier_AtomicExchange(&x, 0); // acts as a barrier on PIII
}
}
inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) {
if (AtomicOps_Internalx86CPUFeatures.has_sse2) {
*ptr = value;
__asm__ __volatile__("mfence" : : : "memory");
} else {
NoBarrier_AtomicExchange(ptr, value);
// acts as a barrier on PIII
}
}
#endif
inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) {
ATOMICOPS_COMPILER_BARRIER();
*ptr = value; // An x86 store acts as a release barrier.
// See comments in Atomic64 version of Release_Store(), below.
}
inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) {
return *ptr;
}
inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) {
Atomic32 value = *ptr; // An x86 load acts as a acquire barrier.
// See comments in Atomic64 version of Release_Store(), below.
ATOMICOPS_COMPILER_BARRIER();
return value;
}
inline Atomic32 Release_Load(volatile const Atomic32* ptr) {
MemoryBarrier();
return *ptr;
}
#if defined(__x86_64__)
// 64-bit low-level operations on 64-bit platform.
inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr,
Atomic64 old_value,
Atomic64 new_value) {
Atomic64 prev;
__asm__ __volatile__("lock; cmpxchgq %1,%2"
: "=a" (prev)
: "q" (new_value), "m" (*ptr), "0" (old_value)
: "memory");
return prev;
}
inline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr,
Atomic64 new_value) {
__asm__ __volatile__("xchgq %1,%0" // The lock prefix is implicit for xchg.
: "=r" (new_value)
: "m" (*ptr), "0" (new_value)
: "memory");
return new_value; // Now it's the previous value.
}
inline Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr,
Atomic64 increment) {
Atomic64 temp = increment;
__asm__ __volatile__("lock; xaddq %0,%1"
: "+r" (temp), "+m" (*ptr)
: : "memory");
// temp now contains the previous value of *ptr
return temp + increment;
}
inline Atomic64 Barrier_AtomicIncrement(volatile Atomic64* ptr,
Atomic64 increment) {
Atomic64 temp = increment;
__asm__ __volatile__("lock; xaddq %0,%1"
: "+r" (temp), "+m" (*ptr)
: : "memory");
// temp now contains the previous value of *ptr
if (AtomicOps_Internalx86CPUFeatures.has_amd_lock_mb_bug) {
__asm__ __volatile__("lfence" : : : "memory");
}
return temp + increment;
}
inline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) {
*ptr = value;
}
inline void Acquire_Store(volatile Atomic64* ptr, Atomic64 value) {
*ptr = value;
MemoryBarrier();
}
inline void Release_Store(volatile Atomic64* ptr, Atomic64 value) {
ATOMICOPS_COMPILER_BARRIER();
*ptr = value; // An x86 store acts as a release barrier
// for current AMD/Intel chips as of Jan 2008.
// See also Acquire_Load(), below.
// When new chips come out, check:
// IA-32 Intel Architecture Software Developer's Manual, Volume 3:
// System Programming Guide, Chatper 7: Multiple-processor management,
// Section 7.2, Memory Ordering.
// Last seen at:
// http://developer.intel.com/design/pentium4/manuals/index_new.htm
//
// x86 stores/loads fail to act as barriers for a few instructions (clflush
// maskmovdqu maskmovq movntdq movnti movntpd movntps movntq) but these are
// not generated by the compiler, and are rare. Users of these instructions
// need to know about cache behaviour in any case since all of these involve
// either flushing cache lines or non-temporal cache hints.
}
inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) {
return *ptr;
}
inline Atomic64 Acquire_Load(volatile const Atomic64* ptr) {
Atomic64 value = *ptr; // An x86 load acts as a acquire barrier,
// for current AMD/Intel chips as of Jan 2008.
// See also Release_Store(), above.
ATOMICOPS_COMPILER_BARRIER();
return value;
}
inline Atomic64 Release_Load(volatile const Atomic64* ptr) {
MemoryBarrier();
return *ptr;
}
inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr,
Atomic64 old_value,
Atomic64 new_value) {
Atomic64 x = NoBarrier_CompareAndSwap(ptr, old_value, new_value);
if (AtomicOps_Internalx86CPUFeatures.has_amd_lock_mb_bug) {
__asm__ __volatile__("lfence" : : : "memory");
}
return x;
}
inline Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr,
Atomic64 old_value,
Atomic64 new_value) {
return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
}
#endif // defined(__x86_64__)
} // namespace internal
} // namespace protobuf
} // namespace google
#undef ATOMICOPS_COMPILER_BARRIER
#endif // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_X86_GCC_H_

View File

@ -0,0 +1,112 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2012 Google Inc. All rights reserved.
// http://code.google.com/p/protobuf/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// The compilation of extension_set.cc fails when windows.h is included.
// Therefore we move the code depending on windows.h to this separate cc file.
// Don't compile this file for people not concerned about thread safety.
#ifndef GOOGLE_PROTOBUF_NO_THREAD_SAFETY
#include <google/protobuf/stubs/atomicops.h>
#ifdef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_X86_MSVC_H_
#include <windows.h>
namespace google {
namespace protobuf {
namespace internal {
inline void MemoryBarrier() {
// We use MemoryBarrier from WinNT.h
::MemoryBarrier();
}
Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,
Atomic32 old_value,
Atomic32 new_value) {
LONG result = InterlockedCompareExchange(
reinterpret_cast<volatile LONG*>(ptr),
static_cast<LONG>(new_value),
static_cast<LONG>(old_value));
return static_cast<Atomic32>(result);
}
Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr,
Atomic32 new_value) {
LONG result = InterlockedExchange(
reinterpret_cast<volatile LONG*>(ptr),
static_cast<LONG>(new_value));
return static_cast<Atomic32>(result);
}
Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr,
Atomic32 increment) {
return InterlockedExchangeAdd(
reinterpret_cast<volatile LONG*>(ptr),
static_cast<LONG>(increment)) + increment;
}
#if defined(_WIN64)
// 64-bit low-level operations on 64-bit platform.
Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr,
Atomic64 old_value,
Atomic64 new_value) {
PVOID result = InterlockedCompareExchangePointer(
reinterpret_cast<volatile PVOID*>(ptr),
reinterpret_cast<PVOID>(new_value), reinterpret_cast<PVOID>(old_value));
return reinterpret_cast<Atomic64>(result);
}
Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr,
Atomic64 new_value) {
PVOID result = InterlockedExchangePointer(
reinterpret_cast<volatile PVOID*>(ptr),
reinterpret_cast<PVOID>(new_value));
return reinterpret_cast<Atomic64>(result);
}
Atomic64 Barrier_AtomicIncrement(volatile Atomic64* ptr,
Atomic64 increment) {
return InterlockedExchangeAdd64(
reinterpret_cast<volatile LONGLONG*>(ptr),
static_cast<LONGLONG>(increment)) + increment;
}
#endif // defined(_WIN64)
} // namespace internal
} // namespace protobuf
} // namespace google
#endif // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_X86_MSVC_H_
#endif // GOOGLE_PROTOBUF_NO_THREAD_SAFETY

View File

@ -0,0 +1,150 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2012 Google Inc. All rights reserved.
// http://code.google.com/p/protobuf/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// This file is an internal atomic implementation, use atomicops.h instead.
#ifndef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_X86_MSVC_H_
#define GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_X86_MSVC_H_
namespace google {
namespace protobuf {
namespace internal {
inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr,
Atomic32 increment) {
return Barrier_AtomicIncrement(ptr, increment);
}
#if !(defined(_MSC_VER) && _MSC_VER >= 1400)
#error "We require at least vs2005 for MemoryBarrier"
#endif
inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
Atomic32 old_value,
Atomic32 new_value) {
return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
}
inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
Atomic32 old_value,
Atomic32 new_value) {
return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
}
inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) {
*ptr = value;
}
inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) {
NoBarrier_AtomicExchange(ptr, value);
// acts as a barrier in this implementation
}
inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) {
*ptr = value; // works w/o barrier for current Intel chips as of June 2005
// See comments in Atomic64 version of Release_Store() below.
}
inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) {
return *ptr;
}
inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) {
Atomic32 value = *ptr;
return value;
}
inline Atomic32 Release_Load(volatile const Atomic32* ptr) {
MemoryBarrier();
return *ptr;
}
#if defined(_WIN64)
// 64-bit low-level operations on 64-bit platform.
inline Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr,
Atomic64 increment) {
return Barrier_AtomicIncrement(ptr, increment);
}
inline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) {
*ptr = value;
}
inline void Acquire_Store(volatile Atomic64* ptr, Atomic64 value) {
NoBarrier_AtomicExchange(ptr, value);
// acts as a barrier in this implementation
}
inline void Release_Store(volatile Atomic64* ptr, Atomic64 value) {
*ptr = value; // works w/o barrier for current Intel chips as of June 2005
// When new chips come out, check:
// IA-32 Intel Architecture Software Developer's Manual, Volume 3:
// System Programming Guide, Chatper 7: Multiple-processor management,
// Section 7.2, Memory Ordering.
// Last seen at:
// http://developer.intel.com/design/pentium4/manuals/index_new.htm
}
inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) {
return *ptr;
}
inline Atomic64 Acquire_Load(volatile const Atomic64* ptr) {
Atomic64 value = *ptr;
return value;
}
inline Atomic64 Release_Load(volatile const Atomic64* ptr) {
MemoryBarrier();
return *ptr;
}
inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr,
Atomic64 old_value,
Atomic64 new_value) {
return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
}
inline Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr,
Atomic64 old_value,
Atomic64 new_value) {
return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
}
#endif // defined(_WIN64)
} // namespace internal
} // namespace protobuf
} // namespace google
#endif // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_X86_MSVC_H_

View File

@ -0,0 +1,395 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// http://code.google.com/p/protobuf/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Author: kenton@google.com (Kenton Varda)
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/once.h>
#include <stdio.h>
#include <errno.h>
#include <vector>
#include "config.h"
#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN // We only need minimal includes
#include <windows.h>
#define snprintf _snprintf // see comment in strutil.cc
#elif defined(HAVE_PTHREAD)
#include <pthread.h>
#else
#error "No suitable threading library available."
#endif
namespace google {
namespace protobuf {
namespace internal {
void VerifyVersion(int headerVersion,
int minLibraryVersion,
const char* filename) {
if (GOOGLE_PROTOBUF_VERSION < minLibraryVersion) {
// Library is too old for headers.
GOOGLE_LOG(FATAL)
<< "This program requires version " << VersionString(minLibraryVersion)
<< " of the Protocol Buffer runtime library, but the installed version "
"is " << VersionString(GOOGLE_PROTOBUF_VERSION) << ". Please update "
"your library. If you compiled the program yourself, make sure that "
"your headers are from the same version of Protocol Buffers as your "
"link-time library. (Version verification failed in \""
<< filename << "\".)";
}
if (headerVersion < kMinHeaderVersionForLibrary) {
// Headers are too old for library.
GOOGLE_LOG(FATAL)
<< "This program was compiled against version "
<< VersionString(headerVersion) << " of the Protocol Buffer runtime "
"library, which is not compatible with the installed version ("
<< VersionString(GOOGLE_PROTOBUF_VERSION) << "). Contact the program "
"author for an update. If you compiled the program yourself, make "
"sure that your headers are from the same version of Protocol Buffers "
"as your link-time library. (Version verification failed in \""
<< filename << "\".)";
}
}
string VersionString(int version) {
int major = version / 1000000;
int minor = (version / 1000) % 1000;
int micro = version % 1000;
// 128 bytes should always be enough, but we use snprintf() anyway to be
// safe.
char buffer[128];
snprintf(buffer, sizeof(buffer), "%d.%d.%d", major, minor, micro);
// Guard against broken MSVC snprintf().
buffer[sizeof(buffer)-1] = '\0';
return buffer;
}
} // namespace internal
// ===================================================================
// emulates google3/base/logging.cc
namespace internal {
void DefaultLogHandler(LogLevel level, const char* filename, int line,
const string& message) {
static const char* level_names[] = { "INFO", "WARNING", "ERROR", "FATAL" };
// We use fprintf() instead of cerr because we want this to work at static
// initialization time.
fprintf(stderr, "[libprotobuf %s %s:%d] %s\n",
level_names[level], filename, line, message.c_str());
fflush(stderr); // Needed on MSVC.
}
void NullLogHandler(LogLevel level, const char* filename, int line,
const string& message) {
// Nothing.
}
static LogHandler* log_handler_ = &DefaultLogHandler;
static int log_silencer_count_ = 0;
static Mutex* log_silencer_count_mutex_ = NULL;
GOOGLE_PROTOBUF_DECLARE_ONCE(log_silencer_count_init_);
void DeleteLogSilencerCount() {
delete log_silencer_count_mutex_;
log_silencer_count_mutex_ = NULL;
}
void InitLogSilencerCount() {
log_silencer_count_mutex_ = new Mutex;
OnShutdown(&DeleteLogSilencerCount);
}
void InitLogSilencerCountOnce() {
GoogleOnceInit(&log_silencer_count_init_, &InitLogSilencerCount);
}
LogMessage& LogMessage::operator<<(const string& value) {
message_ += value;
return *this;
}
LogMessage& LogMessage::operator<<(const char* value) {
message_ += value;
return *this;
}
// Since this is just for logging, we don't care if the current locale changes
// the results -- in fact, we probably prefer that. So we use snprintf()
// instead of Simple*toa().
#undef DECLARE_STREAM_OPERATOR
#define DECLARE_STREAM_OPERATOR(TYPE, FORMAT) \
LogMessage& LogMessage::operator<<(TYPE value) { \
/* 128 bytes should be big enough for any of the primitive */ \
/* values which we print with this, but well use snprintf() */ \
/* anyway to be extra safe. */ \
char buffer[128]; \
snprintf(buffer, sizeof(buffer), FORMAT, value); \
/* Guard against broken MSVC snprintf(). */ \
buffer[sizeof(buffer)-1] = '\0'; \
message_ += buffer; \
return *this; \
}
DECLARE_STREAM_OPERATOR(char , "%c" )
DECLARE_STREAM_OPERATOR(int , "%d" )
DECLARE_STREAM_OPERATOR(uint , "%u" )
DECLARE_STREAM_OPERATOR(long , "%ld")
DECLARE_STREAM_OPERATOR(unsigned long, "%lu")
DECLARE_STREAM_OPERATOR(double , "%g" )
#undef DECLARE_STREAM_OPERATOR
LogMessage::LogMessage(LogLevel level, const char* filename, int line)
: level_(level), filename_(filename), line_(line) {}
LogMessage::~LogMessage() {}
void LogMessage::Finish() {
bool suppress = false;
if (level_ != LOGLEVEL_FATAL) {
InitLogSilencerCountOnce();
MutexLock lock(log_silencer_count_mutex_);
suppress = log_silencer_count_ > 0;
}
if (!suppress) {
log_handler_(level_, filename_, line_, message_);
}
if (level_ == LOGLEVEL_FATAL) {
#if PROTOBUF_USE_EXCEPTIONS
throw FatalException(filename_, line_, message_);
#else
abort();
#endif
}
}
void LogFinisher::operator=(LogMessage& other) {
other.Finish();
}
} // namespace internal
LogHandler* SetLogHandler(LogHandler* new_func) {
LogHandler* old = internal::log_handler_;
if (old == &internal::NullLogHandler) {
old = NULL;
}
if (new_func == NULL) {
internal::log_handler_ = &internal::NullLogHandler;
} else {
internal::log_handler_ = new_func;
}
return old;
}
LogSilencer::LogSilencer() {
internal::InitLogSilencerCountOnce();
MutexLock lock(internal::log_silencer_count_mutex_);
++internal::log_silencer_count_;
};
LogSilencer::~LogSilencer() {
internal::InitLogSilencerCountOnce();
MutexLock lock(internal::log_silencer_count_mutex_);
--internal::log_silencer_count_;
};
// ===================================================================
// emulates google3/base/callback.cc
Closure::~Closure() {}
namespace internal { FunctionClosure0::~FunctionClosure0() {} }
void DoNothing() {}
// ===================================================================
// emulates google3/base/mutex.cc
#ifdef _WIN32
struct Mutex::Internal {
CRITICAL_SECTION mutex;
#ifndef NDEBUG
// Used only to implement AssertHeld().
DWORD thread_id;
#endif
};
Mutex::Mutex()
: mInternal(new Internal) {
InitializeCriticalSection(&mInternal->mutex);
}
Mutex::~Mutex() {
DeleteCriticalSection(&mInternal->mutex);
delete mInternal;
}
void Mutex::Lock() {
EnterCriticalSection(&mInternal->mutex);
#ifndef NDEBUG
mInternal->thread_id = GetCurrentThreadId();
#endif
}
void Mutex::Unlock() {
#ifndef NDEBUG
mInternal->thread_id = 0;
#endif
LeaveCriticalSection(&mInternal->mutex);
}
void Mutex::AssertHeld() {
#ifndef NDEBUG
GOOGLE_DCHECK_EQ(mInternal->thread_id, GetCurrentThreadId());
#endif
}
#elif defined(HAVE_PTHREAD)
struct Mutex::Internal {
pthread_mutex_t mutex;
};
Mutex::Mutex()
: mInternal(new Internal) {
pthread_mutex_init(&mInternal->mutex, NULL);
}
Mutex::~Mutex() {
pthread_mutex_destroy(&mInternal->mutex);
delete mInternal;
}
void Mutex::Lock() {
int result = pthread_mutex_lock(&mInternal->mutex);
if (result != 0) {
GOOGLE_LOG(FATAL) << "pthread_mutex_lock: " << strerror(result);
}
}
void Mutex::Unlock() {
int result = pthread_mutex_unlock(&mInternal->mutex);
if (result != 0) {
GOOGLE_LOG(FATAL) << "pthread_mutex_unlock: " << strerror(result);
}
}
void Mutex::AssertHeld() {
// pthreads dosn't provide a way to check which thread holds the mutex.
// TODO(kenton): Maybe keep track of locking thread ID like with WIN32?
}
#endif
// ===================================================================
// emulates google3/util/endian/endian.h
//
// TODO(xiaofeng): PROTOBUF_LITTLE_ENDIAN is unfortunately defined in
// google/protobuf/io/coded_stream.h and therefore can not be used here.
// Maybe move that macro definition here in the furture.
uint32 ghtonl(uint32 x) {
union {
uint32 result;
uint8 result_array[4];
};
result_array[0] = static_cast<uint8>(x >> 24);
result_array[1] = static_cast<uint8>((x >> 16) & 0xFF);
result_array[2] = static_cast<uint8>((x >> 8) & 0xFF);
result_array[3] = static_cast<uint8>(x & 0xFF);
return result;
}
// ===================================================================
// Shutdown support.
namespace internal {
typedef void OnShutdownFunc();
vector<void (*)()>* shutdown_functions = NULL;
Mutex* shutdown_functions_mutex = NULL;
GOOGLE_PROTOBUF_DECLARE_ONCE(shutdown_functions_init);
void InitShutdownFunctions() {
shutdown_functions = new vector<void (*)()>;
shutdown_functions_mutex = new Mutex;
}
inline void InitShutdownFunctionsOnce() {
GoogleOnceInit(&shutdown_functions_init, &InitShutdownFunctions);
}
void OnShutdown(void (*func)()) {
InitShutdownFunctionsOnce();
MutexLock lock(shutdown_functions_mutex);
shutdown_functions->push_back(func);
}
} // namespace internal
void ShutdownProtobufLibrary() {
internal::InitShutdownFunctionsOnce();
// We don't need to lock shutdown_functions_mutex because it's up to the
// caller to make sure that no one is using the library before this is
// called.
// Make it safe to call this multiple times.
if (internal::shutdown_functions == NULL) return;
for (int i = 0; i < internal::shutdown_functions->size(); i++) {
internal::shutdown_functions->at(i)();
}
delete internal::shutdown_functions;
internal::shutdown_functions = NULL;
delete internal::shutdown_functions_mutex;
internal::shutdown_functions_mutex = NULL;
}
#if PROTOBUF_USE_EXCEPTIONS
FatalException::~FatalException() throw() {}
const char* FatalException::what() const throw() {
return message_.c_str();
}
#endif
} // namespace protobuf
} // namespace google

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,232 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// http://code.google.com/p/protobuf/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Author: kenton@google.com (Kenton Varda)
//
// Deals with the fact that hash_map is not defined everywhere.
#ifndef GOOGLE_PROTOBUF_STUBS_HASH_H__
#define GOOGLE_PROTOBUF_STUBS_HASH_H__
#include <string.h>
#include <google/protobuf/stubs/common.h>
#include "config.h"
#if defined(HAVE_HASH_MAP) && defined(HAVE_HASH_SET)
#include HASH_MAP_H
#include HASH_SET_H
#else
#define MISSING_HASH
#include <map>
#include <set>
#endif
namespace google {
namespace protobuf {
#ifdef MISSING_HASH
// This system doesn't have hash_map or hash_set. Emulate them using map and
// set.
// Make hash<T> be the same as less<T>. Note that everywhere where custom
// hash functions are defined in the protobuf code, they are also defined such
// that they can be used as "less" functions, which is required by MSVC anyway.
template <typename Key>
struct hash {
// Dummy, just to make derivative hash functions compile.
int operator()(const Key& key) {
GOOGLE_LOG(FATAL) << "Should never be called.";
return 0;
}
inline bool operator()(const Key& a, const Key& b) const {
return a < b;
}
};
// Make sure char* is compared by value.
template <>
struct hash<const char*> {
// Dummy, just to make derivative hash functions compile.
int operator()(const char* key) {
GOOGLE_LOG(FATAL) << "Should never be called.";
return 0;
}
inline bool operator()(const char* a, const char* b) const {
return strcmp(a, b) < 0;
}
};
template <typename Key, typename Data,
typename HashFcn = hash<Key>,
typename EqualKey = int >
class hash_map : public std::map<Key, Data, HashFcn> {
public:
hash_map(int = 0) {}
};
template <typename Key,
typename HashFcn = hash<Key>,
typename EqualKey = int >
class hash_set : public std::set<Key, HashFcn> {
public:
hash_set(int = 0) {}
};
#elif defined(_MSC_VER) && !defined(_STLPORT_VERSION)
template <typename Key>
struct hash : public HASH_NAMESPACE::hash_compare<Key> {
};
// MSVC's hash_compare<const char*> hashes based on the string contents but
// compares based on the string pointer. WTF?
class CstringLess {
public:
inline bool operator()(const char* a, const char* b) const {
return strcmp(a, b) < 0;
}
};
template <>
struct hash<const char*>
: public HASH_NAMESPACE::hash_compare<const char*, CstringLess> {
};
template <typename Key, typename Data,
typename HashFcn = hash<Key>,
typename EqualKey = int >
class hash_map : public HASH_NAMESPACE::hash_map<
Key, Data, HashFcn> {
public:
hash_map(int = 0) {}
};
template <typename Key,
typename HashFcn = hash<Key>,
typename EqualKey = int >
class hash_set : public HASH_NAMESPACE::hash_set<
Key, HashFcn> {
public:
hash_set(int = 0) {}
};
#else
template <typename Key>
struct hash : public HASH_NAMESPACE::hash<Key> {
};
template <typename Key>
struct hash<const Key*> {
inline size_t operator()(const Key* key) const {
return reinterpret_cast<size_t>(key);
}
};
// Unlike the old SGI version, the TR1 "hash" does not special-case char*. So,
// we go ahead and provide our own implementation.
template <>
struct hash<const char*> {
inline size_t operator()(const char* str) const {
size_t result = 0;
for (; *str != '\0'; str++) {
result = 5 * result + *str;
}
return result;
}
};
template <typename Key, typename Data,
typename HashFcn = hash<Key>,
typename EqualKey = std::equal_to<Key> >
class hash_map : public HASH_NAMESPACE::HASH_MAP_CLASS<
Key, Data, HashFcn, EqualKey> {
public:
hash_map(int = 0) {}
};
template <typename Key,
typename HashFcn = hash<Key>,
typename EqualKey = std::equal_to<Key> >
class hash_set : public HASH_NAMESPACE::HASH_SET_CLASS<
Key, HashFcn, EqualKey> {
public:
hash_set(int = 0) {}
};
#endif
template <>
struct hash<string> {
inline size_t operator()(const string& key) const {
return hash<const char*>()(key.c_str());
}
static const size_t bucket_size = 4;
static const size_t min_buckets = 8;
inline size_t operator()(const string& a, const string& b) const {
return a < b;
}
};
template <typename First, typename Second>
struct hash<pair<First, Second> > {
inline size_t operator()(const pair<First, Second>& key) const {
size_t first_hash = hash<First>()(key.first);
size_t second_hash = hash<Second>()(key.second);
// FIXME(kenton): What is the best way to compute this hash? I have
// no idea! This seems a bit better than an XOR.
return first_hash * ((1 << 16) - 1) + second_hash;
}
static const size_t bucket_size = 4;
static const size_t min_buckets = 8;
inline size_t operator()(const pair<First, Second>& a,
const pair<First, Second>& b) const {
return a < b;
}
};
// Used by GCC/SGI STL only. (Why isn't this provided by the standard
// library? :( )
struct streq {
inline bool operator()(const char* a, const char* b) const {
return strcmp(a, b) == 0;
}
};
} // namespace protobuf
} // namespace google
#endif // GOOGLE_PROTOBUF_STUBS_HASH_H__

View File

@ -0,0 +1,143 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// http://code.google.com/p/protobuf/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// from google3/util/gtl/map-util.h
// Author: Anton Carver
#ifndef GOOGLE_PROTOBUF_STUBS_MAP_UTIL_H__
#define GOOGLE_PROTOBUF_STUBS_MAP_UTIL_H__
#include <google/protobuf/stubs/common.h>
namespace google {
namespace protobuf {
// Perform a lookup in a map or hash_map.
// If the key is present in the map then the value associated with that
// key is returned, otherwise the value passed as a default is returned.
template <class Collection>
const typename Collection::value_type::second_type&
FindWithDefault(const Collection& collection,
const typename Collection::value_type::first_type& key,
const typename Collection::value_type::second_type& value) {
typename Collection::const_iterator it = collection.find(key);
if (it == collection.end()) {
return value;
}
return it->second;
}
// Perform a lookup in a map or hash_map.
// If the key is present a const pointer to the associated value is returned,
// otherwise a NULL pointer is returned.
template <class Collection>
const typename Collection::value_type::second_type*
FindOrNull(const Collection& collection,
const typename Collection::value_type::first_type& key) {
typename Collection::const_iterator it = collection.find(key);
if (it == collection.end()) {
return 0;
}
return &it->second;
}
// Perform a lookup in a map or hash_map, assuming that the key exists.
// Crash if it does not.
//
// This is intended as a replacement for operator[] as an rvalue (for reading)
// when the key is guaranteed to exist.
//
// operator[] is discouraged for several reasons:
// * It has a side-effect of inserting missing keys
// * It is not thread-safe (even when it is not inserting, it can still
// choose to resize the underlying storage)
// * It invalidates iterators (when it chooses to resize)
// * It default constructs a value object even if it doesn't need to
//
// This version assumes the key is printable, and includes it in the fatal log
// message.
template <class Collection>
const typename Collection::value_type::second_type&
FindOrDie(const Collection& collection,
const typename Collection::value_type::first_type& key) {
typename Collection::const_iterator it = collection.find(key);
GOOGLE_CHECK(it != collection.end()) << "Map key not found: " << key;
return it->second;
}
// Perform a lookup in a map or hash_map whose values are pointers.
// If the key is present a const pointer to the associated value is returned,
// otherwise a NULL pointer is returned.
// This function does not distinguish between a missing key and a key mapped
// to a NULL value.
template <class Collection>
const typename Collection::value_type::second_type
FindPtrOrNull(const Collection& collection,
const typename Collection::value_type::first_type& key) {
typename Collection::const_iterator it = collection.find(key);
if (it == collection.end()) {
return 0;
}
return it->second;
}
// Change the value associated with a particular key in a map or hash_map.
// If the key is not present in the map the key and value are inserted,
// otherwise the value is updated to be a copy of the value provided.
// True indicates that an insert took place, false indicates an update.
template <class Collection, class Key, class Value>
bool InsertOrUpdate(Collection * const collection,
const Key& key, const Value& value) {
pair<typename Collection::iterator, bool> ret =
collection->insert(typename Collection::value_type(key, value));
if (!ret.second) {
// update
ret.first->second = value;
return false;
}
return true;
}
// Insert a new key and value into a map or hash_map.
// If the key is not present in the map the key and value are
// inserted, otherwise nothing happens. True indicates that an insert
// took place, false indicates the key was already present.
template <class Collection, class Key, class Value>
bool InsertIfNotPresent(Collection * const collection,
const Key& key, const Value& value) {
pair<typename Collection::iterator, bool> ret =
collection->insert(typename Collection::value_type(key, value));
return ret.second;
}
} // namespace protobuf
} // namespace google
#endif // GOOGLE_PROTOBUF_STUBS_MAP_UTIL_H__

View File

@ -0,0 +1,99 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// http://code.google.com/p/protobuf/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Author: kenton@google.com (Kenton Varda)
//
// emulates google3/base/once.h
//
// This header is intended to be included only by internal .cc files and
// generated .pb.cc files. Users should not use this directly.
#include <google/protobuf/stubs/once.h>
#ifndef GOOGLE_PROTOBUF_NO_THREAD_SAFETY
#ifdef _WIN32
#include <windows.h>
#else
#include <sched.h>
#endif
#include <google/protobuf/stubs/atomicops.h>
namespace google {
namespace protobuf {
namespace {
void SchedYield() {
#ifdef _WIN32
Sleep(0);
#else // POSIX
sched_yield();
#endif
}
} // namespace
void GoogleOnceInitImpl(ProtobufOnceType* once, Closure* closure) {
internal::AtomicWord state = internal::Acquire_Load(once);
// Fast path. The provided closure was already executed.
if (state == ONCE_STATE_DONE) {
return;
}
// The closure execution did not complete yet. The once object can be in one
// of the two following states:
// - UNINITIALIZED: We are the first thread calling this function.
// - EXECUTING_CLOSURE: Another thread is already executing the closure.
//
// First, try to change the state from UNINITIALIZED to EXECUTING_CLOSURE
// atomically.
state = internal::Acquire_CompareAndSwap(
once, ONCE_STATE_UNINITIALIZED, ONCE_STATE_EXECUTING_CLOSURE);
if (state == ONCE_STATE_UNINITIALIZED) {
// We are the first thread to call this function, so we have to call the
// closure.
closure->Run();
internal::Release_Store(once, ONCE_STATE_DONE);
} else {
// Another thread has already started executing the closure. We need to
// wait until it completes the initialization.
while (state == ONCE_STATE_EXECUTING_CLOSURE) {
// Note that futex() could be used here on Linux as an improvement.
SchedYield();
state = internal::Acquire_Load(once);
}
}
}
} // namespace protobuf
} // namespace google
#endif // GOOGLE_PROTOBUF_NO_THREAD_SAFETY

View File

@ -0,0 +1,148 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// http://code.google.com/p/protobuf/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Author: kenton@google.com (Kenton Varda)
//
// emulates google3/base/once.h
//
// This header is intended to be included only by internal .cc files and
// generated .pb.cc files. Users should not use this directly.
//
// This is basically a portable version of pthread_once().
//
// This header declares:
// * A type called ProtobufOnceType.
// * A macro GOOGLE_PROTOBUF_DECLARE_ONCE() which declares a variable of type
// ProtobufOnceType. This is the only legal way to declare such a variable.
// The macro may only be used at the global scope (you cannot create local or
// class member variables of this type).
// * A function GoogleOnceInit(ProtobufOnceType* once, void (*init_func)()).
// This function, when invoked multiple times given the same ProtobufOnceType
// object, will invoke init_func on the first call only, and will make sure
// none of the calls return before that first call to init_func has finished.
// * The user can provide a parameter which GoogleOnceInit() forwards to the
// user-provided function when it is called. Usage example:
// int a = 10;
// GoogleOnceInit(&my_once, &MyFunctionExpectingIntArgument, &a);
// * This implementation guarantees that ProtobufOnceType is a POD (i.e. no
// static initializer generated).
//
// This implements a way to perform lazy initialization. It's more efficient
// than using mutexes as no lock is needed if initialization has already
// happened.
//
// Example usage:
// void Init();
// GOOGLE_PROTOBUF_DECLARE_ONCE(once_init);
//
// // Calls Init() exactly once.
// void InitOnce() {
// GoogleOnceInit(&once_init, &Init);
// }
//
// Note that if GoogleOnceInit() is called before main() has begun, it must
// only be called by the thread that will eventually call main() -- that is,
// the thread that performs dynamic initialization. In general this is a safe
// assumption since people don't usually construct threads before main() starts,
// but it is technically not guaranteed. Unfortunately, Win32 provides no way
// whatsoever to statically-initialize its synchronization primitives, so our
// only choice is to assume that dynamic initialization is single-threaded.
#ifndef GOOGLE_PROTOBUF_STUBS_ONCE_H__
#define GOOGLE_PROTOBUF_STUBS_ONCE_H__
#include <google/protobuf/stubs/atomicops.h>
#include <google/protobuf/stubs/common.h>
namespace google {
namespace protobuf {
#ifdef GOOGLE_PROTOBUF_NO_THREAD_SAFETY
typedef bool ProtobufOnceType;
#define GOOGLE_PROTOBUF_ONCE_INIT false
inline void GoogleOnceInit(ProtobufOnceType* once, void (*init_func)()) {
if (!*once) {
*once = true;
init_func();
}
}
template <typename Arg>
inline void GoogleOnceInit(ProtobufOnceType* once, void (*init_func)(Arg),
Arg arg) {
if (!*once) {
*once = true;
init_func(arg);
}
}
#else
enum {
ONCE_STATE_UNINITIALIZED = 0,
ONCE_STATE_EXECUTING_CLOSURE = 1,
ONCE_STATE_DONE = 2
};
typedef internal::AtomicWord ProtobufOnceType;
#define GOOGLE_PROTOBUF_ONCE_INIT ::google::protobuf::ONCE_STATE_UNINITIALIZED
LIBPROTOBUF_EXPORT
void GoogleOnceInitImpl(ProtobufOnceType* once, Closure* closure);
inline void GoogleOnceInit(ProtobufOnceType* once, void (*init_func)()) {
if (internal::Acquire_Load(once) != ONCE_STATE_DONE) {
internal::FunctionClosure0 func(init_func, false);
GoogleOnceInitImpl(once, &func);
}
}
template <typename Arg>
inline void GoogleOnceInit(ProtobufOnceType* once, void (*init_func)(Arg*),
Arg* arg) {
if (internal::Acquire_Load(once) != ONCE_STATE_DONE) {
internal::FunctionClosure1<Arg*> func(init_func, false, arg);
GoogleOnceInitImpl(once, &func);
}
}
#endif // GOOGLE_PROTOBUF_NO_THREAD_SAFETY
#define GOOGLE_PROTOBUF_DECLARE_ONCE(NAME) \
::google::protobuf::ProtobufOnceType NAME = GOOGLE_PROTOBUF_ONCE_INIT
} // namespace protobuf
} // namespace google
#endif // GOOGLE_PROTOBUF_STUBS_ONCE_H__

View File

@ -0,0 +1,82 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2012 Google Inc. All rights reserved.
// http://code.google.com/p/protobuf/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef GOOGLE_PROTOBUF_PLATFORM_MACROS_H_
#define GOOGLE_PROTOBUF_PLATFORM_MACROS_H_
#include <google/protobuf/stubs/common.h>
// Processor architecture detection. For more info on what's defined, see:
// http://msdn.microsoft.com/en-us/library/b0084kay.aspx
// http://www.agner.org/optimize/calling_conventions.pdf
// or with gcc, run: "echo | gcc -E -dM -"
#if defined(_M_X64) || defined(__x86_64__)
#define GOOGLE_PROTOBUF_ARCH_X64 1
#define GOOGLE_PROTOBUF_ARCH_64_BIT 1
#elif defined(_M_IX86) || defined(__i386__)
#define GOOGLE_PROTOBUF_ARCH_IA32 1
#define GOOGLE_PROTOBUF_ARCH_32_BIT 1
#elif defined(__aarch64__)
#define GOOGLE_PROTOBUF_ARCH_AARCH64 1
#define GOOGLE_PROTOBUF_ARCH_64_BIT 1
#elif defined(__QNX__)
#define GOOGLE_PROTOBUF_ARCH_ARM_QNX 1
#define GOOGLE_PROTOBUF_ARCH_32_BIT 1
#elif defined(__ARMEL__)
#define GOOGLE_PROTOBUF_ARCH_ARM 1
#define GOOGLE_PROTOBUF_ARCH_32_BIT 1
#elif defined(__MIPSEL__)
#define GOOGLE_PROTOBUF_ARCH_MIPS 1
#define GOOGLE_PROTOBUF_ARCH_32_BIT 1
#elif defined(__pnacl__)
#define GOOGLE_PROTOBUF_ARCH_32_BIT 1
#elif defined(__ppc64__) || defined(__PPC64__)
#define GOOGLE_PROTOBUF_ARCH_PPC64 1
#define GOOGLE_PROTOBUF_ARCH_64_BIT 1
#elif defined(__ppc__) || defined(__PPC__)
#define GOOGLE_PROTOBUF_ARCH_PPC 1
#define GOOGLE_PROTOBUF_ARCH_32_BIT 1
#elif defined(__s390x__)
#define GOOGLE_PROTOBUF_ARCH_64_BIT 1
#define GOOGLE_PROTOBUF_ARCH_S390X 1
#elif defined(__s390__)
#define GOOGLE_PROTOBUF_ARCH_32_BIT 1
#define GOOGLE_PROTOBUF_ARCH_S390 1
#else
#error Host architecture was not detected as supported by protobuf
#endif
#if defined(__APPLE__)
#define GOOGLE_PROTOBUF_OS_APPLE
#elif defined(__native_client__)
#define GOOGLE_PROTOBUF_OS_NACL
#endif
#endif // GOOGLE_PROTOBUF_PLATFORM_MACROS_H_

View File

@ -0,0 +1,121 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// http://code.google.com/p/protobuf/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// from google3/util/gtl/stl_util.h
#ifndef GOOGLE_PROTOBUF_STUBS_STL_UTIL_H__
#define GOOGLE_PROTOBUF_STUBS_STL_UTIL_H__
#include <google/protobuf/stubs/common.h>
namespace google {
namespace protobuf {
// STLDeleteContainerPointers()
// For a range within a container of pointers, calls delete
// (non-array version) on these pointers.
// NOTE: for these three functions, we could just implement a DeleteObject
// functor and then call for_each() on the range and functor, but this
// requires us to pull in all of algorithm.h, which seems expensive.
// For hash_[multi]set, it is important that this deletes behind the iterator
// because the hash_set may call the hash function on the iterator when it is
// advanced, which could result in the hash function trying to deference a
// stale pointer.
template <class ForwardIterator>
void STLDeleteContainerPointers(ForwardIterator begin,
ForwardIterator end) {
while (begin != end) {
ForwardIterator temp = begin;
++begin;
delete *temp;
}
}
// Inside Google, this function implements a horrible, disgusting hack in which
// we reach into the string's private implementation and resize it without
// initializing the new bytes. In some cases doing this can significantly
// improve performance. However, since it's totally non-portable it has no
// place in open source code. Feel free to fill this function in with your
// own disgusting hack if you want the perf boost.
inline void STLStringResizeUninitialized(string* s, size_t new_size) {
s->resize(new_size);
}
// Return a mutable char* pointing to a string's internal buffer,
// which may not be null-terminated. Writing through this pointer will
// modify the string.
//
// string_as_array(&str)[i] is valid for 0 <= i < str.size() until the
// next call to a string method that invalidates iterators.
//
// As of 2006-04, there is no standard-blessed way of getting a
// mutable reference to a string's internal buffer. However, issue 530
// (http://www.open-std.org/JTC1/SC22/WG21/docs/lwg-active.html#530)
// proposes this as the method. According to Matt Austern, this should
// already work on all current implementations.
inline char* string_as_array(string* str) {
// DO NOT USE const_cast<char*>(str->data())! See the unittest for why.
return str->empty() ? NULL : &*str->begin();
}
// STLDeleteElements() deletes all the elements in an STL container and clears
// the container. This function is suitable for use with a vector, set,
// hash_set, or any other STL container which defines sensible begin(), end(),
// and clear() methods.
//
// If container is NULL, this function is a no-op.
//
// As an alternative to calling STLDeleteElements() directly, consider
// ElementDeleter (defined below), which ensures that your container's elements
// are deleted when the ElementDeleter goes out of scope.
template <class T>
void STLDeleteElements(T *container) {
if (!container) return;
STLDeleteContainerPointers(container->begin(), container->end());
container->clear();
}
// Given an STL container consisting of (key, value) pairs, STLDeleteValues
// deletes all the "value" components and clears the container. Does nothing
// in the case it's given a NULL pointer.
template <class T>
void STLDeleteValues(T *v) {
if (!v) return;
for (typename T::iterator i = v->begin(); i != v->end(); ++i) {
delete i->second;
}
v->clear();
}
} // namespace protobuf
} // namespace google
#endif // GOOGLE_PROTOBUF_STUBS_STL_UTIL_H__

View File

@ -0,0 +1,175 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2012 Google Inc. All rights reserved.
// http://code.google.com/p/protobuf/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// from google3/base/stringprintf.cc
#include <google/protobuf/stubs/stringprintf.h>
#include <errno.h>
#include <stdarg.h> // For va_list and related operations
#include <stdio.h> // MSVC requires this for _vsnprintf
#include <vector>
#include <google/protobuf/stubs/common.h>
//#include <google/protobuf/testing/googletest.h>
namespace google {
namespace protobuf {
#ifdef _MSC_VER
enum { IS_COMPILER_MSVC = 1 };
#ifndef va_copy
// Define va_copy for MSVC. This is a hack, assuming va_list is simply a
// pointer into the stack and is safe to copy.
#define va_copy(dest, src) ((dest) = (src))
#endif
#else
enum { IS_COMPILER_MSVC = 0 };
#endif
void StringAppendV(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;
}
if (IS_COMPILER_MSVC) {
// 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(NULL, 0, format, backup_ap);
va_end(backup_ap);
}
if (result < 0) {
// Just an error.
return;
}
}
// Increase the buffer size to the size requested by vsnprintf,
// plus one for the closing \0.
int length = result+1;
char* buf = new char[length];
// Restore the va_list before we use it again
va_copy(backup_ap, ap);
result = vsnprintf(buf, length, format, backup_ap);
va_end(backup_ap);
if (result >= 0 && result < length) {
// It fit
dst->append(buf, result);
}
delete[] buf;
}
string StringPrintf(const char* format, ...) {
va_list ap;
va_start(ap, format);
string result;
StringAppendV(&result, format, ap);
va_end(ap);
return result;
}
const string& SStringPrintf(string* dst, const char* format, ...) {
va_list ap;
va_start(ap, format);
dst->clear();
StringAppendV(dst, format, ap);
va_end(ap);
return *dst;
}
void StringAppendF(string* dst, const char* format, ...) {
va_list ap;
va_start(ap, format);
StringAppendV(dst, format, ap);
va_end(ap);
}
// Max arguments supported by StringPrintVector
const int kStringPrintfVectorMaxArgs = 32;
// An empty block of zero for filler arguments. This is const so that if
// printf tries to write to it (via %n) then the program gets a SIGSEGV
// and we can fix the problem or protect against an attack.
static const char string_printf_empty_block[256] = { '\0' };
string StringPrintfVector(const char* format, const vector<string>& v) {
GOOGLE_CHECK_LE(v.size(), kStringPrintfVectorMaxArgs)
<< "StringPrintfVector currently only supports up to "
<< kStringPrintfVectorMaxArgs << " arguments. "
<< "Feel free to add support for more if you need it.";
// Add filler arguments so that bogus format+args have a harder time
// crashing the program, corrupting the program (%n),
// or displaying random chunks of memory to users.
const char* cstr[kStringPrintfVectorMaxArgs];
for (int i = 0; i < v.size(); ++i) {
cstr[i] = v[i].c_str();
}
for (int i = v.size(); i < GOOGLE_ARRAYSIZE(cstr); ++i) {
cstr[i] = &string_printf_empty_block[0];
}
// I do not know any way to pass kStringPrintfVectorMaxArgs arguments,
// or any way to build a va_list by hand, or any API for printf
// that accepts an array of arguments. The best I can do is stick
// this COMPILE_ASSERT right next to the actual statement.
GOOGLE_COMPILE_ASSERT(kStringPrintfVectorMaxArgs == 32, arg_count_mismatch);
return StringPrintf(format,
cstr[0], cstr[1], cstr[2], cstr[3], cstr[4],
cstr[5], cstr[6], cstr[7], cstr[8], cstr[9],
cstr[10], cstr[11], cstr[12], cstr[13], cstr[14],
cstr[15], cstr[16], cstr[17], cstr[18], cstr[19],
cstr[20], cstr[21], cstr[22], cstr[23], cstr[24],
cstr[25], cstr[26], cstr[27], cstr[28], cstr[29],
cstr[30], cstr[31]);
}
} // namespace protobuf
} // namespace google

View File

@ -0,0 +1,76 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2012 Google Inc. All rights reserved.
// http://code.google.com/p/protobuf/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// from google3/base/stringprintf.h
//
// Printf variants that place their output in a C++ string.
//
// Usage:
// string result = StringPrintf("%d %s\n", 10, "hello");
// SStringPrintf(&result, "%d %s\n", 10, "hello");
// StringAppendF(&result, "%d %s\n", 20, "there");
#ifndef GOOGLE_PROTOBUF_STUBS_STRINGPRINTF_H
#define GOOGLE_PROTOBUF_STUBS_STRINGPRINTF_H
#include <stdarg.h>
#include <string>
#include <vector>
#include <google/protobuf/stubs/common.h>
namespace google {
namespace protobuf {
// Return a C++ string
LIBPROTOBUF_EXPORT extern string StringPrintf(const char* format, ...);
// Store result into a supplied string and return it
LIBPROTOBUF_EXPORT extern const string& SStringPrintf(string* dst, const char* format, ...);
// Append result to a supplied string
LIBPROTOBUF_EXPORT extern void StringAppendF(string* dst, const char* format, ...);
// Lower-level routine that takes a va_list and appends to a specified
// string. All other routines are just convenience wrappers around it.
LIBPROTOBUF_EXPORT extern void StringAppendV(string* dst, const char* format, va_list ap);
// The max arguments supported by StringPrintfVector
LIBPROTOBUF_EXPORT extern const int kStringPrintfVectorMaxArgs;
// You can use this version when all your arguments are strings, but
// you don't know how many arguments you'll have at compile time.
// StringPrintfVector will LOG(FATAL) if v.size() > kStringPrintfVectorMaxArgs
LIBPROTOBUF_EXPORT extern string StringPrintfVector(const char* format, const vector<string>& v);
} // namespace protobuf
} // namespace google
#endif // GOOGLE_PROTOBUF_STUBS_STRINGPRINTF_H

View File

@ -0,0 +1,138 @@
// Copyright 2005 Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// ----
// Author: lar@google.com (Laramie Leavitt)
//
// Template metaprogramming utility functions.
//
// This code is compiled directly on many platforms, including client
// platforms like Windows, Mac, and embedded systems. Before making
// any changes here, make sure that you're not breaking any platforms.
//
//
// The names choosen here reflect those used in tr1 and the boost::mpl
// library, there are similar operations used in the Loki library as
// well. I prefer the boost names for 2 reasons:
// 1. I think that portions of the Boost libraries are more likely to
// be included in the c++ standard.
// 2. It is not impossible that some of the boost libraries will be
// included in our own build in the future.
// Both of these outcomes means that we may be able to directly replace
// some of these with boost equivalents.
//
#ifndef GOOGLE_PROTOBUF_TEMPLATE_UTIL_H_
#define GOOGLE_PROTOBUF_TEMPLATE_UTIL_H_
namespace google {
namespace protobuf {
namespace internal {
// Types small_ and big_ are guaranteed such that sizeof(small_) <
// sizeof(big_)
typedef char small_;
struct big_ {
char dummy[2];
};
// Identity metafunction.
template <class T>
struct identity_ {
typedef T type;
};
// integral_constant, defined in tr1, is a wrapper for an integer
// value. We don't really need this generality; we could get away
// with hardcoding the integer type to bool. We use the fully
// general integer_constant for compatibility with tr1.
template<class T, T v>
struct integral_constant {
static const T value = v;
typedef T value_type;
typedef integral_constant<T, v> type;
};
template <class T, T v> const T integral_constant<T, v>::value;
// Abbreviations: true_type and false_type are structs that represent boolean
// true and false values. Also define the boost::mpl versions of those names,
// true_ and false_.
typedef integral_constant<bool, true> true_type;
typedef integral_constant<bool, false> false_type;
typedef true_type true_;
typedef false_type false_;
// if_ is a templatized conditional statement.
// if_<cond, A, B> is a compile time evaluation of cond.
// if_<>::type contains A if cond is true, B otherwise.
template<bool cond, typename A, typename B>
struct if_{
typedef A type;
};
template<typename A, typename B>
struct if_<false, A, B> {
typedef B type;
};
// type_equals_ is a template type comparator, similar to Loki IsSameType.
// type_equals_<A, B>::value is true iff "A" is the same type as "B".
//
// New code should prefer base::is_same, defined in base/type_traits.h.
// It is functionally identical, but is_same is the standard spelling.
template<typename A, typename B>
struct type_equals_ : public false_ {
};
template<typename A>
struct type_equals_<A, A> : public true_ {
};
// and_ is a template && operator.
// and_<A, B>::value evaluates "A::value && B::value".
template<typename A, typename B>
struct and_ : public integral_constant<bool, (A::value && B::value)> {
};
// or_ is a template || operator.
// or_<A, B>::value evaluates "A::value || B::value".
template<typename A, typename B>
struct or_ : public integral_constant<bool, (A::value || B::value)> {
};
} // namespace internal
} // namespace protobuf
} // namespace google
#endif // GOOGLE_PROTOBUF_TEMPLATE_UTIL_H_

View File

@ -0,0 +1,336 @@
// Copyright (c) 2006, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// ----
// Author: Matt Austern
//
// This code is compiled directly on many platforms, including client
// platforms like Windows, Mac, and embedded systems. Before making
// any changes here, make sure that you're not breaking any platforms.
//
// Define a small subset of tr1 type traits. The traits we define are:
// is_integral
// is_floating_point
// is_pointer
// is_enum
// is_reference
// is_pod
// has_trivial_constructor
// has_trivial_copy
// has_trivial_assign
// has_trivial_destructor
// remove_const
// remove_volatile
// remove_cv
// remove_reference
// add_reference
// remove_pointer
// is_same
// is_convertible
// We can add more type traits as required.
#ifndef GOOGLE_PROTOBUF_TYPE_TRAITS_H_
#define GOOGLE_PROTOBUF_TYPE_TRAITS_H_
#include <utility> // For pair
#include <google/protobuf/stubs/template_util.h> // For true_type and false_type
namespace google {
namespace protobuf {
namespace internal {
template <class T> struct is_integral;
template <class T> struct is_floating_point;
template <class T> struct is_pointer;
// MSVC can't compile this correctly, and neither can gcc 3.3.5 (at least)
#if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3)
// is_enum uses is_convertible, which is not available on MSVC.
template <class T> struct is_enum;
#endif
template <class T> struct is_reference;
template <class T> struct is_pod;
template <class T> struct has_trivial_constructor;
template <class T> struct has_trivial_copy;
template <class T> struct has_trivial_assign;
template <class T> struct has_trivial_destructor;
template <class T> struct remove_const;
template <class T> struct remove_volatile;
template <class T> struct remove_cv;
template <class T> struct remove_reference;
template <class T> struct add_reference;
template <class T> struct remove_pointer;
template <class T, class U> struct is_same;
#if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3)
template <class From, class To> struct is_convertible;
#endif
// is_integral is false except for the built-in integer types. A
// cv-qualified type is integral if and only if the underlying type is.
template <class T> struct is_integral : false_type { };
template<> struct is_integral<bool> : true_type { };
template<> struct is_integral<char> : true_type { };
template<> struct is_integral<unsigned char> : true_type { };
template<> struct is_integral<signed char> : true_type { };
#if defined(_MSC_VER)
// wchar_t is not by default a distinct type from unsigned short in
// Microsoft C.
// See http://msdn2.microsoft.com/en-us/library/dh8che7s(VS.80).aspx
template<> struct is_integral<__wchar_t> : true_type { };
#else
template<> struct is_integral<wchar_t> : true_type { };
#endif
template<> struct is_integral<short> : true_type { };
template<> struct is_integral<unsigned short> : true_type { };
template<> struct is_integral<int> : true_type { };
template<> struct is_integral<unsigned int> : true_type { };
template<> struct is_integral<long> : true_type { };
template<> struct is_integral<unsigned long> : true_type { };
#ifdef HAVE_LONG_LONG
template<> struct is_integral<long long> : true_type { };
template<> struct is_integral<unsigned long long> : true_type { };
#endif
template <class T> struct is_integral<const T> : is_integral<T> { };
template <class T> struct is_integral<volatile T> : is_integral<T> { };
template <class T> struct is_integral<const volatile T> : is_integral<T> { };
// is_floating_point is false except for the built-in floating-point types.
// A cv-qualified type is integral if and only if the underlying type is.
template <class T> struct is_floating_point : false_type { };
template<> struct is_floating_point<float> : true_type { };
template<> struct is_floating_point<double> : true_type { };
template<> struct is_floating_point<long double> : true_type { };
template <class T> struct is_floating_point<const T>
: is_floating_point<T> { };
template <class T> struct is_floating_point<volatile T>
: is_floating_point<T> { };
template <class T> struct is_floating_point<const volatile T>
: is_floating_point<T> { };
// is_pointer is false except for pointer types. A cv-qualified type (e.g.
// "int* const", as opposed to "int const*") is cv-qualified if and only if
// the underlying type is.
template <class T> struct is_pointer : false_type { };
template <class T> struct is_pointer<T*> : true_type { };
template <class T> struct is_pointer<const T> : is_pointer<T> { };
template <class T> struct is_pointer<volatile T> : is_pointer<T> { };
template <class T> struct is_pointer<const volatile T> : is_pointer<T> { };
#if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3)
namespace internal {
template <class T> struct is_class_or_union {
template <class U> static small_ tester(void (U::*)());
template <class U> static big_ tester(...);
static const bool value = sizeof(tester<T>(0)) == sizeof(small_);
};
// is_convertible chokes if the first argument is an array. That's why
// we use add_reference here.
template <bool NotUnum, class T> struct is_enum_impl
: is_convertible<typename add_reference<T>::type, int> { };
template <class T> struct is_enum_impl<true, T> : false_type { };
} // namespace internal
// Specified by TR1 [4.5.1] primary type categories.
// Implementation note:
//
// Each type is either void, integral, floating point, array, pointer,
// reference, member object pointer, member function pointer, enum,
// union or class. Out of these, only integral, floating point, reference,
// class and enum types are potentially convertible to int. Therefore,
// if a type is not a reference, integral, floating point or class and
// is convertible to int, it's a enum. Adding cv-qualification to a type
// does not change whether it's an enum.
//
// Is-convertible-to-int check is done only if all other checks pass,
// because it can't be used with some types (e.g. void or classes with
// inaccessible conversion operators).
template <class T> struct is_enum
: internal::is_enum_impl<
is_same<T, void>::value ||
is_integral<T>::value ||
is_floating_point<T>::value ||
is_reference<T>::value ||
internal::is_class_or_union<T>::value,
T> { };
template <class T> struct is_enum<const T> : is_enum<T> { };
template <class T> struct is_enum<volatile T> : is_enum<T> { };
template <class T> struct is_enum<const volatile T> : is_enum<T> { };
#endif
// is_reference is false except for reference types.
template<typename T> struct is_reference : false_type {};
template<typename T> struct is_reference<T&> : true_type {};
// We can't get is_pod right without compiler help, so fail conservatively.
// We will assume it's false except for arithmetic types, enumerations,
// pointers and cv-qualified versions thereof. Note that std::pair<T,U>
// is not a POD even if T and U are PODs.
template <class T> struct is_pod
: integral_constant<bool, (is_integral<T>::value ||
is_floating_point<T>::value ||
#if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3)
// is_enum is not available on MSVC.
is_enum<T>::value ||
#endif
is_pointer<T>::value)> { };
template <class T> struct is_pod<const T> : is_pod<T> { };
template <class T> struct is_pod<volatile T> : is_pod<T> { };
template <class T> struct is_pod<const volatile T> : is_pod<T> { };
// We can't get has_trivial_constructor right without compiler help, so
// fail conservatively. We will assume it's false except for: (1) types
// for which is_pod is true. (2) std::pair of types with trivial
// constructors. (3) array of a type with a trivial constructor.
// (4) const versions thereof.
template <class T> struct has_trivial_constructor : is_pod<T> { };
template <class T, class U> struct has_trivial_constructor<std::pair<T, U> >
: integral_constant<bool,
(has_trivial_constructor<T>::value &&
has_trivial_constructor<U>::value)> { };
template <class A, int N> struct has_trivial_constructor<A[N]>
: has_trivial_constructor<A> { };
template <class T> struct has_trivial_constructor<const T>
: has_trivial_constructor<T> { };
// We can't get has_trivial_copy right without compiler help, so fail
// conservatively. We will assume it's false except for: (1) types
// for which is_pod is true. (2) std::pair of types with trivial copy
// constructors. (3) array of a type with a trivial copy constructor.
// (4) const versions thereof.
template <class T> struct has_trivial_copy : is_pod<T> { };
template <class T, class U> struct has_trivial_copy<std::pair<T, U> >
: integral_constant<bool,
(has_trivial_copy<T>::value &&
has_trivial_copy<U>::value)> { };
template <class A, int N> struct has_trivial_copy<A[N]>
: has_trivial_copy<A> { };
template <class T> struct has_trivial_copy<const T> : has_trivial_copy<T> { };
// We can't get has_trivial_assign right without compiler help, so fail
// conservatively. We will assume it's false except for: (1) types
// for which is_pod is true. (2) std::pair of types with trivial copy
// constructors. (3) array of a type with a trivial assign constructor.
template <class T> struct has_trivial_assign : is_pod<T> { };
template <class T, class U> struct has_trivial_assign<std::pair<T, U> >
: integral_constant<bool,
(has_trivial_assign<T>::value &&
has_trivial_assign<U>::value)> { };
template <class A, int N> struct has_trivial_assign<A[N]>
: has_trivial_assign<A> { };
// We can't get has_trivial_destructor right without compiler help, so
// fail conservatively. We will assume it's false except for: (1) types
// for which is_pod is true. (2) std::pair of types with trivial
// destructors. (3) array of a type with a trivial destructor.
// (4) const versions thereof.
template <class T> struct has_trivial_destructor : is_pod<T> { };
template <class T, class U> struct has_trivial_destructor<std::pair<T, U> >
: integral_constant<bool,
(has_trivial_destructor<T>::value &&
has_trivial_destructor<U>::value)> { };
template <class A, int N> struct has_trivial_destructor<A[N]>
: has_trivial_destructor<A> { };
template <class T> struct has_trivial_destructor<const T>
: has_trivial_destructor<T> { };
// Specified by TR1 [4.7.1]
template<typename T> struct remove_const { typedef T type; };
template<typename T> struct remove_const<T const> { typedef T type; };
template<typename T> struct remove_volatile { typedef T type; };
template<typename T> struct remove_volatile<T volatile> { typedef T type; };
template<typename T> struct remove_cv {
typedef typename remove_const<typename remove_volatile<T>::type>::type type;
};
// Specified by TR1 [4.7.2] Reference modifications.
template<typename T> struct remove_reference { typedef T type; };
template<typename T> struct remove_reference<T&> { typedef T type; };
template <typename T> struct add_reference { typedef T& type; };
template <typename T> struct add_reference<T&> { typedef T& type; };
// Specified by TR1 [4.7.4] Pointer modifications.
template<typename T> struct remove_pointer { typedef T type; };
template<typename T> struct remove_pointer<T*> { typedef T type; };
template<typename T> struct remove_pointer<T* const> { typedef T type; };
template<typename T> struct remove_pointer<T* volatile> { typedef T type; };
template<typename T> struct remove_pointer<T* const volatile> {
typedef T type; };
// Specified by TR1 [4.6] Relationships between types
template<typename T, typename U> struct is_same : public false_type { };
template<typename T> struct is_same<T, T> : public true_type { };
// Specified by TR1 [4.6] Relationships between types
#if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3)
namespace internal {
// This class is an implementation detail for is_convertible, and you
// don't need to know how it works to use is_convertible. For those
// who care: we declare two different functions, one whose argument is
// of type To and one with a variadic argument list. We give them
// return types of different size, so we can use sizeof to trick the
// compiler into telling us which function it would have chosen if we
// had called it with an argument of type From. See Alexandrescu's
// _Modern C++ Design_ for more details on this sort of trick.
template <typename From, typename To>
struct ConvertHelper {
static small_ Test(To);
static big_ Test(...);
static From Create();
};
} // namespace internal
// Inherits from true_type if From is convertible to To, false_type otherwise.
template <typename From, typename To>
struct is_convertible
: integral_constant<bool,
sizeof(internal::ConvertHelper<From, To>::Test(
internal::ConvertHelper<From, To>::Create()))
== sizeof(small_)> {
};
#endif
} // namespace internal
} // namespace protobuf
} // namespace google
#endif // GOOGLE_PROTOBUF_TYPE_TRAITS_H_

View File

@ -0,0 +1,361 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// http://code.google.com/p/protobuf/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Author: kenton@google.com (Kenton Varda)
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
#include <google/protobuf/wire_format_lite_inl.h>
#include <stack>
#include <string>
#include <vector>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/io/coded_stream_inl.h>
#include <google/protobuf/io/zero_copy_stream.h>
#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
namespace google {
namespace protobuf {
namespace internal {
#ifndef _MSC_VER // MSVC doesn't like definitions of inline constants, GCC
// requires them.
const int WireFormatLite::kMessageSetItemStartTag;
const int WireFormatLite::kMessageSetItemEndTag;
const int WireFormatLite::kMessageSetTypeIdTag;
const int WireFormatLite::kMessageSetMessageTag;
#endif
const int WireFormatLite::kMessageSetItemTagsSize =
io::CodedOutputStream::StaticVarintSize32<kMessageSetItemStartTag>::value +
io::CodedOutputStream::StaticVarintSize32<kMessageSetItemEndTag>::value +
io::CodedOutputStream::StaticVarintSize32<kMessageSetTypeIdTag>::value +
io::CodedOutputStream::StaticVarintSize32<kMessageSetMessageTag>::value;
const WireFormatLite::CppType
WireFormatLite::kFieldTypeToCppTypeMap[MAX_FIELD_TYPE + 1] = {
static_cast<CppType>(0), // 0 is reserved for errors
CPPTYPE_DOUBLE, // TYPE_DOUBLE
CPPTYPE_FLOAT, // TYPE_FLOAT
CPPTYPE_INT64, // TYPE_INT64
CPPTYPE_UINT64, // TYPE_UINT64
CPPTYPE_INT32, // TYPE_INT32
CPPTYPE_UINT64, // TYPE_FIXED64
CPPTYPE_UINT32, // TYPE_FIXED32
CPPTYPE_BOOL, // TYPE_BOOL
CPPTYPE_STRING, // TYPE_STRING
CPPTYPE_MESSAGE, // TYPE_GROUP
CPPTYPE_MESSAGE, // TYPE_MESSAGE
CPPTYPE_STRING, // TYPE_BYTES
CPPTYPE_UINT32, // TYPE_UINT32
CPPTYPE_ENUM, // TYPE_ENUM
CPPTYPE_INT32, // TYPE_SFIXED32
CPPTYPE_INT64, // TYPE_SFIXED64
CPPTYPE_INT32, // TYPE_SINT32
CPPTYPE_INT64, // TYPE_SINT64
};
const WireFormatLite::WireType
WireFormatLite::kWireTypeForFieldType[MAX_FIELD_TYPE + 1] = {
static_cast<WireFormatLite::WireType>(-1), // invalid
WireFormatLite::WIRETYPE_FIXED64, // TYPE_DOUBLE
WireFormatLite::WIRETYPE_FIXED32, // TYPE_FLOAT
WireFormatLite::WIRETYPE_VARINT, // TYPE_INT64
WireFormatLite::WIRETYPE_VARINT, // TYPE_UINT64
WireFormatLite::WIRETYPE_VARINT, // TYPE_INT32
WireFormatLite::WIRETYPE_FIXED64, // TYPE_FIXED64
WireFormatLite::WIRETYPE_FIXED32, // TYPE_FIXED32
WireFormatLite::WIRETYPE_VARINT, // TYPE_BOOL
WireFormatLite::WIRETYPE_LENGTH_DELIMITED, // TYPE_STRING
WireFormatLite::WIRETYPE_START_GROUP, // TYPE_GROUP
WireFormatLite::WIRETYPE_LENGTH_DELIMITED, // TYPE_MESSAGE
WireFormatLite::WIRETYPE_LENGTH_DELIMITED, // TYPE_BYTES
WireFormatLite::WIRETYPE_VARINT, // TYPE_UINT32
WireFormatLite::WIRETYPE_VARINT, // TYPE_ENUM
WireFormatLite::WIRETYPE_FIXED32, // TYPE_SFIXED32
WireFormatLite::WIRETYPE_FIXED64, // TYPE_SFIXED64
WireFormatLite::WIRETYPE_VARINT, // TYPE_SINT32
WireFormatLite::WIRETYPE_VARINT, // TYPE_SINT64
};
bool WireFormatLite::SkipField(
io::CodedInputStream* input, uint32 tag) {
switch (WireFormatLite::GetTagWireType(tag)) {
case WireFormatLite::WIRETYPE_VARINT: {
uint64 value;
if (!input->ReadVarint64(&value)) return false;
return true;
}
case WireFormatLite::WIRETYPE_FIXED64: {
uint64 value;
if (!input->ReadLittleEndian64(&value)) return false;
return true;
}
case WireFormatLite::WIRETYPE_LENGTH_DELIMITED: {
uint32 length;
if (!input->ReadVarint32(&length)) return false;
if (!input->Skip(length)) return false;
return true;
}
case WireFormatLite::WIRETYPE_START_GROUP: {
if (!input->IncrementRecursionDepth()) return false;
if (!SkipMessage(input)) return false;
input->DecrementRecursionDepth();
// Check that the ending tag matched the starting tag.
if (!input->LastTagWas(WireFormatLite::MakeTag(
WireFormatLite::GetTagFieldNumber(tag),
WireFormatLite::WIRETYPE_END_GROUP))) {
return false;
}
return true;
}
case WireFormatLite::WIRETYPE_END_GROUP: {
return false;
}
case WireFormatLite::WIRETYPE_FIXED32: {
uint32 value;
if (!input->ReadLittleEndian32(&value)) return false;
return true;
}
default: {
return false;
}
}
}
bool WireFormatLite::SkipMessage(io::CodedInputStream* input) {
while(true) {
uint32 tag = input->ReadTag();
if (tag == 0) {
// End of input. This is a valid place to end, so return true.
return true;
}
WireFormatLite::WireType wire_type = WireFormatLite::GetTagWireType(tag);
if (wire_type == WireFormatLite::WIRETYPE_END_GROUP) {
// Must be the end of the message.
return true;
}
if (!SkipField(input, tag)) return false;
}
}
bool FieldSkipper::SkipField(
io::CodedInputStream* input, uint32 tag) {
return WireFormatLite::SkipField(input, tag);
}
bool FieldSkipper::SkipMessage(io::CodedInputStream* input) {
return WireFormatLite::SkipMessage(input);
}
void FieldSkipper::SkipUnknownEnum(
int field_number, int value) {
// Nothing.
}
bool WireFormatLite::ReadPackedEnumNoInline(io::CodedInputStream* input,
bool (*is_valid)(int),
RepeatedField<int>* values) {
uint32 length;
if (!input->ReadVarint32(&length)) return false;
io::CodedInputStream::Limit limit = input->PushLimit(length);
while (input->BytesUntilLimit() > 0) {
int value;
if (!google::protobuf::internal::WireFormatLite::ReadPrimitive<
int, WireFormatLite::TYPE_ENUM>(input, &value)) {
return false;
}
if (is_valid(value)) {
values->Add(value);
}
}
input->PopLimit(limit);
return true;
}
void WireFormatLite::WriteInt32(int field_number, int32 value,
io::CodedOutputStream* output) {
WriteTag(field_number, WIRETYPE_VARINT, output);
WriteInt32NoTag(value, output);
}
void WireFormatLite::WriteInt64(int field_number, int64 value,
io::CodedOutputStream* output) {
WriteTag(field_number, WIRETYPE_VARINT, output);
WriteInt64NoTag(value, output);
}
void WireFormatLite::WriteUInt32(int field_number, uint32 value,
io::CodedOutputStream* output) {
WriteTag(field_number, WIRETYPE_VARINT, output);
WriteUInt32NoTag(value, output);
}
void WireFormatLite::WriteUInt64(int field_number, uint64 value,
io::CodedOutputStream* output) {
WriteTag(field_number, WIRETYPE_VARINT, output);
WriteUInt64NoTag(value, output);
}
void WireFormatLite::WriteSInt32(int field_number, int32 value,
io::CodedOutputStream* output) {
WriteTag(field_number, WIRETYPE_VARINT, output);
WriteSInt32NoTag(value, output);
}
void WireFormatLite::WriteSInt64(int field_number, int64 value,
io::CodedOutputStream* output) {
WriteTag(field_number, WIRETYPE_VARINT, output);
WriteSInt64NoTag(value, output);
}
void WireFormatLite::WriteFixed32(int field_number, uint32 value,
io::CodedOutputStream* output) {
WriteTag(field_number, WIRETYPE_FIXED32, output);
WriteFixed32NoTag(value, output);
}
void WireFormatLite::WriteFixed64(int field_number, uint64 value,
io::CodedOutputStream* output) {
WriteTag(field_number, WIRETYPE_FIXED64, output);
WriteFixed64NoTag(value, output);
}
void WireFormatLite::WriteSFixed32(int field_number, int32 value,
io::CodedOutputStream* output) {
WriteTag(field_number, WIRETYPE_FIXED32, output);
WriteSFixed32NoTag(value, output);
}
void WireFormatLite::WriteSFixed64(int field_number, int64 value,
io::CodedOutputStream* output) {
WriteTag(field_number, WIRETYPE_FIXED64, output);
WriteSFixed64NoTag(value, output);
}
void WireFormatLite::WriteFloat(int field_number, float value,
io::CodedOutputStream* output) {
WriteTag(field_number, WIRETYPE_FIXED32, output);
WriteFloatNoTag(value, output);
}
void WireFormatLite::WriteDouble(int field_number, double value,
io::CodedOutputStream* output) {
WriteTag(field_number, WIRETYPE_FIXED64, output);
WriteDoubleNoTag(value, output);
}
void WireFormatLite::WriteBool(int field_number, bool value,
io::CodedOutputStream* output) {
WriteTag(field_number, WIRETYPE_VARINT, output);
WriteBoolNoTag(value, output);
}
void WireFormatLite::WriteEnum(int field_number, int value,
io::CodedOutputStream* output) {
WriteTag(field_number, WIRETYPE_VARINT, output);
WriteEnumNoTag(value, output);
}
void WireFormatLite::WriteString(int field_number, const string& value,
io::CodedOutputStream* output) {
// String is for UTF-8 text only
WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output);
GOOGLE_CHECK(value.size() <= kint32max);
output->WriteVarint32(value.size());
output->WriteString(value);
}
void WireFormatLite::WriteBytes(int field_number, const string& value,
io::CodedOutputStream* output) {
WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output);
GOOGLE_CHECK(value.size() <= kint32max);
output->WriteVarint32(value.size());
output->WriteString(value);
}
void WireFormatLite::WriteGroup(int field_number,
const MessageLite& value,
io::CodedOutputStream* output) {
WriteTag(field_number, WIRETYPE_START_GROUP, output);
value.SerializeWithCachedSizes(output);
WriteTag(field_number, WIRETYPE_END_GROUP, output);
}
void WireFormatLite::WriteMessage(int field_number,
const MessageLite& value,
io::CodedOutputStream* output) {
WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output);
const int size = value.GetCachedSize();
output->WriteVarint32(size);
value.SerializeWithCachedSizes(output);
}
void WireFormatLite::WriteGroupMaybeToArray(int field_number,
const MessageLite& value,
io::CodedOutputStream* output) {
WriteTag(field_number, WIRETYPE_START_GROUP, output);
const int size = value.GetCachedSize();
uint8* target = output->GetDirectBufferForNBytesAndAdvance(size);
if (target != NULL) {
uint8* end = value.SerializeWithCachedSizesToArray(target);
GOOGLE_DCHECK_EQ(end - target, size);
} else {
value.SerializeWithCachedSizes(output);
}
WriteTag(field_number, WIRETYPE_END_GROUP, output);
}
void WireFormatLite::WriteMessageMaybeToArray(int field_number,
const MessageLite& value,
io::CodedOutputStream* output) {
WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output);
const int size = value.GetCachedSize();
output->WriteVarint32(size);
uint8* target = output->GetDirectBufferForNBytesAndAdvance(size);
if (target != NULL) {
uint8* end = value.SerializeWithCachedSizesToArray(target);
GOOGLE_DCHECK_EQ(end - target, size);
} else {
value.SerializeWithCachedSizes(output);
}
}
bool WireFormatLite::ReadString(io::CodedInputStream* input,
string* value) {
// String is for UTF-8 text only
uint32 length;
if (!input->ReadVarint32(&length)) return false;
if (!input->InternalReadStringInline(value, length)) return false;
return true;
}
bool WireFormatLite::ReadBytes(io::CodedInputStream* input,
string* value) {
uint32 length;
if (!input->ReadVarint32(&length)) return false;
return input->InternalReadStringInline(value, length);
}
} // namespace internal
} // namespace protobuf
} // namespace google

View File

@ -0,0 +1,622 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// http://code.google.com/p/protobuf/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Author: kenton@google.com (Kenton Varda)
// atenasio@google.com (Chris Atenasio) (ZigZag transform)
// wink@google.com (Wink Saville) (refactored from wire_format.h)
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
//
// This header is logically internal, but is made public because it is used
// from protocol-compiler-generated code, which may reside in other components.
#ifndef GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_H__
#define GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_H__
#include <string>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/message_lite.h>
#include <google/protobuf/io/coded_stream.h> // for CodedOutputStream::Varint32Size
namespace google {
namespace protobuf {
template <typename T> class RepeatedField; // repeated_field.h
}
namespace protobuf {
namespace internal {
class StringPieceField;
// This class is for internal use by the protocol buffer library and by
// protocol-complier-generated message classes. It must not be called
// directly by clients.
//
// This class contains helpers for implementing the binary protocol buffer
// wire format without the need for reflection. Use WireFormat when using
// reflection.
//
// This class is really a namespace that contains only static methods.
class LIBPROTOBUF_EXPORT WireFormatLite {
public:
// -----------------------------------------------------------------
// Helper constants and functions related to the format. These are
// mostly meant for internal and generated code to use.
// The wire format is composed of a sequence of tag/value pairs, each
// of which contains the value of one field (or one element of a repeated
// field). Each tag is encoded as a varint. The lower bits of the tag
// identify its wire type, which specifies the format of the data to follow.
// The rest of the bits contain the field number. Each type of field (as
// declared by FieldDescriptor::Type, in descriptor.h) maps to one of
// these wire types. Immediately following each tag is the field's value,
// encoded in the format specified by the wire type. Because the tag
// identifies the encoding of this data, it is possible to skip
// unrecognized fields for forwards compatibility.
enum WireType {
WIRETYPE_VARINT = 0,
WIRETYPE_FIXED64 = 1,
WIRETYPE_LENGTH_DELIMITED = 2,
WIRETYPE_START_GROUP = 3,
WIRETYPE_END_GROUP = 4,
WIRETYPE_FIXED32 = 5,
};
// Lite alternative to FieldDescriptor::Type. Must be kept in sync.
enum FieldType {
TYPE_DOUBLE = 1,
TYPE_FLOAT = 2,
TYPE_INT64 = 3,
TYPE_UINT64 = 4,
TYPE_INT32 = 5,
TYPE_FIXED64 = 6,
TYPE_FIXED32 = 7,
TYPE_BOOL = 8,
TYPE_STRING = 9,
TYPE_GROUP = 10,
TYPE_MESSAGE = 11,
TYPE_BYTES = 12,
TYPE_UINT32 = 13,
TYPE_ENUM = 14,
TYPE_SFIXED32 = 15,
TYPE_SFIXED64 = 16,
TYPE_SINT32 = 17,
TYPE_SINT64 = 18,
MAX_FIELD_TYPE = 18,
};
// Lite alternative to FieldDescriptor::CppType. Must be kept in sync.
enum CppType {
CPPTYPE_INT32 = 1,
CPPTYPE_INT64 = 2,
CPPTYPE_UINT32 = 3,
CPPTYPE_UINT64 = 4,
CPPTYPE_DOUBLE = 5,
CPPTYPE_FLOAT = 6,
CPPTYPE_BOOL = 7,
CPPTYPE_ENUM = 8,
CPPTYPE_STRING = 9,
CPPTYPE_MESSAGE = 10,
MAX_CPPTYPE = 10,
};
// Helper method to get the CppType for a particular Type.
static CppType FieldTypeToCppType(FieldType type);
// Given a FieldSescriptor::Type return its WireType
static inline WireFormatLite::WireType WireTypeForFieldType(
WireFormatLite::FieldType type) {
return kWireTypeForFieldType[type];
}
// Number of bits in a tag which identify the wire type.
static const int kTagTypeBits = 3;
// Mask for those bits.
static const uint32 kTagTypeMask = (1 << kTagTypeBits) - 1;
// Helper functions for encoding and decoding tags. (Inlined below and in
// _inl.h)
//
// This is different from MakeTag(field->number(), field->type()) in the case
// of packed repeated fields.
static uint32 MakeTag(int field_number, WireType type);
static WireType GetTagWireType(uint32 tag);
static int GetTagFieldNumber(uint32 tag);
// Compute the byte size of a tag. For groups, this includes both the start
// and end tags.
static inline int TagSize(int field_number, WireFormatLite::FieldType type);
// Skips a field value with the given tag. The input should start
// positioned immediately after the tag. Skipped values are simply discarded,
// not recorded anywhere. See WireFormat::SkipField() for a version that
// records to an UnknownFieldSet.
static bool SkipField(io::CodedInputStream* input, uint32 tag);
// Reads and ignores a message from the input. Skipped values are simply
// discarded, not recorded anywhere. See WireFormat::SkipMessage() for a
// version that records to an UnknownFieldSet.
static bool SkipMessage(io::CodedInputStream* input);
// This macro does the same thing as WireFormatLite::MakeTag(), but the
// result is usable as a compile-time constant, which makes it usable
// as a switch case or a template input. WireFormatLite::MakeTag() is more
// type-safe, though, so prefer it if possible.
#define GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(FIELD_NUMBER, TYPE) \
static_cast<uint32>( \
((FIELD_NUMBER) << ::google::protobuf::internal::WireFormatLite::kTagTypeBits) \
| (TYPE))
// These are the tags for the old MessageSet format, which was defined as:
// message MessageSet {
// repeated group Item = 1 {
// required int32 type_id = 2;
// required string message = 3;
// }
// }
static const int kMessageSetItemNumber = 1;
static const int kMessageSetTypeIdNumber = 2;
static const int kMessageSetMessageNumber = 3;
static const int kMessageSetItemStartTag =
GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(kMessageSetItemNumber,
WireFormatLite::WIRETYPE_START_GROUP);
static const int kMessageSetItemEndTag =
GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(kMessageSetItemNumber,
WireFormatLite::WIRETYPE_END_GROUP);
static const int kMessageSetTypeIdTag =
GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(kMessageSetTypeIdNumber,
WireFormatLite::WIRETYPE_VARINT);
static const int kMessageSetMessageTag =
GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(kMessageSetMessageNumber,
WireFormatLite::WIRETYPE_LENGTH_DELIMITED);
// Byte size of all tags of a MessageSet::Item combined.
static const int kMessageSetItemTagsSize;
// Helper functions for converting between floats/doubles and IEEE-754
// uint32s/uint64s so that they can be written. (Assumes your platform
// uses IEEE-754 floats.)
static uint32 EncodeFloat(float value);
static float DecodeFloat(uint32 value);
static uint64 EncodeDouble(double value);
static double DecodeDouble(uint64 value);
// Helper functions for mapping signed integers to unsigned integers in
// such a way that numbers with small magnitudes will encode to smaller
// varints. If you simply static_cast a negative number to an unsigned
// number and varint-encode it, it will always take 10 bytes, defeating
// the purpose of varint. So, for the "sint32" and "sint64" field types,
// we ZigZag-encode the values.
static uint32 ZigZagEncode32(int32 n);
static int32 ZigZagDecode32(uint32 n);
static uint64 ZigZagEncode64(int64 n);
static int64 ZigZagDecode64(uint64 n);
// =================================================================
// Methods for reading/writing individual field. The implementations
// of these methods are defined in wire_format_lite_inl.h; you must #include
// that file to use these.
// Avoid ugly line wrapping
#define input io::CodedInputStream* input
#define output io::CodedOutputStream* output
#define field_number int field_number
#define INL GOOGLE_ATTRIBUTE_ALWAYS_INLINE
// Read fields, not including tags. The assumption is that you already
// read the tag to determine what field to read.
// For primitive fields, we just use a templatized routine parameterized by
// the represented type and the FieldType. These are specialized with the
// appropriate definition for each declared type.
template <typename CType, enum FieldType DeclaredType>
static inline bool ReadPrimitive(input, CType* value) INL;
// Reads repeated primitive values, with optimizations for repeats.
// tag_size and tag should both be compile-time constants provided by the
// protocol compiler.
template <typename CType, enum FieldType DeclaredType>
static inline bool ReadRepeatedPrimitive(int tag_size,
uint32 tag,
input,
RepeatedField<CType>* value) INL;
// Identical to ReadRepeatedPrimitive, except will not inline the
// implementation.
template <typename CType, enum FieldType DeclaredType>
static bool ReadRepeatedPrimitiveNoInline(int tag_size,
uint32 tag,
input,
RepeatedField<CType>* value);
// Reads a primitive value directly from the provided buffer. It returns a
// pointer past the segment of data that was read.
//
// This is only implemented for the types with fixed wire size, e.g.
// float, double, and the (s)fixed* types.
template <typename CType, enum FieldType DeclaredType>
static inline const uint8* ReadPrimitiveFromArray(const uint8* buffer,
CType* value) INL;
// Reads a primitive packed field.
//
// This is only implemented for packable types.
template <typename CType, enum FieldType DeclaredType>
static inline bool ReadPackedPrimitive(input,
RepeatedField<CType>* value) INL;
// Identical to ReadPackedPrimitive, except will not inline the
// implementation.
template <typename CType, enum FieldType DeclaredType>
static bool ReadPackedPrimitiveNoInline(input, RepeatedField<CType>* value);
// Read a packed enum field. Values for which is_valid() returns false are
// dropped.
static bool ReadPackedEnumNoInline(input,
bool (*is_valid)(int),
RepeatedField<int>* value);
static bool ReadString(input, string* value);
static bool ReadBytes (input, string* value);
static inline bool ReadGroup (field_number, input, MessageLite* value);
static inline bool ReadMessage(input, MessageLite* value);
// Like above, but de-virtualize the call to MergePartialFromCodedStream().
// The pointer must point at an instance of MessageType, *not* a subclass (or
// the subclass must not override MergePartialFromCodedStream()).
template<typename MessageType>
static inline bool ReadGroupNoVirtual(field_number, input,
MessageType* value);
template<typename MessageType>
static inline bool ReadMessageNoVirtual(input, MessageType* value);
// Write a tag. The Write*() functions typically include the tag, so
// normally there's no need to call this unless using the Write*NoTag()
// variants.
static inline void WriteTag(field_number, WireType type, output) INL;
// Write fields, without tags.
static inline void WriteInt32NoTag (int32 value, output) INL;
static inline void WriteInt64NoTag (int64 value, output) INL;
static inline void WriteUInt32NoTag (uint32 value, output) INL;
static inline void WriteUInt64NoTag (uint64 value, output) INL;
static inline void WriteSInt32NoTag (int32 value, output) INL;
static inline void WriteSInt64NoTag (int64 value, output) INL;
static inline void WriteFixed32NoTag (uint32 value, output) INL;
static inline void WriteFixed64NoTag (uint64 value, output) INL;
static inline void WriteSFixed32NoTag(int32 value, output) INL;
static inline void WriteSFixed64NoTag(int64 value, output) INL;
static inline void WriteFloatNoTag (float value, output) INL;
static inline void WriteDoubleNoTag (double value, output) INL;
static inline void WriteBoolNoTag (bool value, output) INL;
static inline void WriteEnumNoTag (int value, output) INL;
// Write fields, including tags.
static void WriteInt32 (field_number, int32 value, output);
static void WriteInt64 (field_number, int64 value, output);
static void WriteUInt32 (field_number, uint32 value, output);
static void WriteUInt64 (field_number, uint64 value, output);
static void WriteSInt32 (field_number, int32 value, output);
static void WriteSInt64 (field_number, int64 value, output);
static void WriteFixed32 (field_number, uint32 value, output);
static void WriteFixed64 (field_number, uint64 value, output);
static void WriteSFixed32(field_number, int32 value, output);
static void WriteSFixed64(field_number, int64 value, output);
static void WriteFloat (field_number, float value, output);
static void WriteDouble (field_number, double value, output);
static void WriteBool (field_number, bool value, output);
static void WriteEnum (field_number, int value, output);
static void WriteString(field_number, const string& value, output);
static void WriteBytes (field_number, const string& value, output);
static void WriteGroup(
field_number, const MessageLite& value, output);
static void WriteMessage(
field_number, const MessageLite& value, output);
// Like above, but these will check if the output stream has enough
// space to write directly to a flat array.
static void WriteGroupMaybeToArray(
field_number, const MessageLite& value, output);
static void WriteMessageMaybeToArray(
field_number, const MessageLite& value, output);
// Like above, but de-virtualize the call to SerializeWithCachedSizes(). The
// pointer must point at an instance of MessageType, *not* a subclass (or
// the subclass must not override SerializeWithCachedSizes()).
template<typename MessageType>
static inline void WriteGroupNoVirtual(
field_number, const MessageType& value, output);
template<typename MessageType>
static inline void WriteMessageNoVirtual(
field_number, const MessageType& value, output);
#undef output
#define output uint8* target
// Like above, but use only *ToArray methods of CodedOutputStream.
static inline uint8* WriteTagToArray(field_number, WireType type, output) INL;
// Write fields, without tags.
static inline uint8* WriteInt32NoTagToArray (int32 value, output) INL;
static inline uint8* WriteInt64NoTagToArray (int64 value, output) INL;
static inline uint8* WriteUInt32NoTagToArray (uint32 value, output) INL;
static inline uint8* WriteUInt64NoTagToArray (uint64 value, output) INL;
static inline uint8* WriteSInt32NoTagToArray (int32 value, output) INL;
static inline uint8* WriteSInt64NoTagToArray (int64 value, output) INL;
static inline uint8* WriteFixed32NoTagToArray (uint32 value, output) INL;
static inline uint8* WriteFixed64NoTagToArray (uint64 value, output) INL;
static inline uint8* WriteSFixed32NoTagToArray(int32 value, output) INL;
static inline uint8* WriteSFixed64NoTagToArray(int64 value, output) INL;
static inline uint8* WriteFloatNoTagToArray (float value, output) INL;
static inline uint8* WriteDoubleNoTagToArray (double value, output) INL;
static inline uint8* WriteBoolNoTagToArray (bool value, output) INL;
static inline uint8* WriteEnumNoTagToArray (int value, output) INL;
// Write fields, including tags.
static inline uint8* WriteInt32ToArray(
field_number, int32 value, output) INL;
static inline uint8* WriteInt64ToArray(
field_number, int64 value, output) INL;
static inline uint8* WriteUInt32ToArray(
field_number, uint32 value, output) INL;
static inline uint8* WriteUInt64ToArray(
field_number, uint64 value, output) INL;
static inline uint8* WriteSInt32ToArray(
field_number, int32 value, output) INL;
static inline uint8* WriteSInt64ToArray(
field_number, int64 value, output) INL;
static inline uint8* WriteFixed32ToArray(
field_number, uint32 value, output) INL;
static inline uint8* WriteFixed64ToArray(
field_number, uint64 value, output) INL;
static inline uint8* WriteSFixed32ToArray(
field_number, int32 value, output) INL;
static inline uint8* WriteSFixed64ToArray(
field_number, int64 value, output) INL;
static inline uint8* WriteFloatToArray(
field_number, float value, output) INL;
static inline uint8* WriteDoubleToArray(
field_number, double value, output) INL;
static inline uint8* WriteBoolToArray(
field_number, bool value, output) INL;
static inline uint8* WriteEnumToArray(
field_number, int value, output) INL;
static inline uint8* WriteStringToArray(
field_number, const string& value, output) INL;
static inline uint8* WriteBytesToArray(
field_number, const string& value, output) INL;
static inline uint8* WriteGroupToArray(
field_number, const MessageLite& value, output) INL;
static inline uint8* WriteMessageToArray(
field_number, const MessageLite& value, output) INL;
// Like above, but de-virtualize the call to SerializeWithCachedSizes(). The
// pointer must point at an instance of MessageType, *not* a subclass (or
// the subclass must not override SerializeWithCachedSizes()).
template<typename MessageType>
static inline uint8* WriteGroupNoVirtualToArray(
field_number, const MessageType& value, output) INL;
template<typename MessageType>
static inline uint8* WriteMessageNoVirtualToArray(
field_number, const MessageType& value, output) INL;
#undef output
#undef input
#undef INL
#undef field_number
// Compute the byte size of a field. The XxSize() functions do NOT include
// the tag, so you must also call TagSize(). (This is because, for repeated
// fields, you should only call TagSize() once and multiply it by the element
// count, but you may have to call XxSize() for each individual element.)
static inline int Int32Size ( int32 value);
static inline int Int64Size ( int64 value);
static inline int UInt32Size (uint32 value);
static inline int UInt64Size (uint64 value);
static inline int SInt32Size ( int32 value);
static inline int SInt64Size ( int64 value);
static inline int EnumSize ( int value);
// These types always have the same size.
static const int kFixed32Size = 4;
static const int kFixed64Size = 8;
static const int kSFixed32Size = 4;
static const int kSFixed64Size = 8;
static const int kFloatSize = 4;
static const int kDoubleSize = 8;
static const int kBoolSize = 1;
static inline int StringSize(const string& value);
static inline int BytesSize (const string& value);
static inline int GroupSize (const MessageLite& value);
static inline int MessageSize(const MessageLite& value);
// Like above, but de-virtualize the call to ByteSize(). The
// pointer must point at an instance of MessageType, *not* a subclass (or
// the subclass must not override ByteSize()).
template<typename MessageType>
static inline int GroupSizeNoVirtual (const MessageType& value);
template<typename MessageType>
static inline int MessageSizeNoVirtual(const MessageType& value);
// Given the length of data, calculate the byte size of the data on the
// wire if we encode the data as a length delimited field.
static inline int LengthDelimitedSize(int length);
private:
// A helper method for the repeated primitive reader. This method has
// optimizations for primitive types that have fixed size on the wire, and
// can be read using potentially faster paths.
template <typename CType, enum FieldType DeclaredType>
static inline bool ReadRepeatedFixedSizePrimitive(
int tag_size,
uint32 tag,
google::protobuf::io::CodedInputStream* input,
RepeatedField<CType>* value) GOOGLE_ATTRIBUTE_ALWAYS_INLINE;
static const CppType kFieldTypeToCppTypeMap[];
static const WireFormatLite::WireType kWireTypeForFieldType[];
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(WireFormatLite);
};
// A class which deals with unknown values. The default implementation just
// discards them. WireFormat defines a subclass which writes to an
// UnknownFieldSet. This class is used by ExtensionSet::ParseField(), since
// ExtensionSet is part of the lite library but UnknownFieldSet is not.
class LIBPROTOBUF_EXPORT FieldSkipper {
public:
FieldSkipper() {}
virtual ~FieldSkipper() {}
// Skip a field whose tag has already been consumed.
virtual bool SkipField(io::CodedInputStream* input, uint32 tag);
// Skip an entire message or group, up to an end-group tag (which is consumed)
// or end-of-stream.
virtual bool SkipMessage(io::CodedInputStream* input);
// Deal with an already-parsed unrecognized enum value. The default
// implementation does nothing, but the UnknownFieldSet-based implementation
// saves it as an unknown varint.
virtual void SkipUnknownEnum(int field_number, int value);
};
// inline methods ====================================================
inline WireFormatLite::CppType
WireFormatLite::FieldTypeToCppType(FieldType type) {
return kFieldTypeToCppTypeMap[type];
}
inline uint32 WireFormatLite::MakeTag(int field_number, WireType type) {
return GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(field_number, type);
}
inline WireFormatLite::WireType WireFormatLite::GetTagWireType(uint32 tag) {
return static_cast<WireType>(tag & kTagTypeMask);
}
inline int WireFormatLite::GetTagFieldNumber(uint32 tag) {
return static_cast<int>(tag >> kTagTypeBits);
}
inline int WireFormatLite::TagSize(int field_number,
WireFormatLite::FieldType type) {
int result = io::CodedOutputStream::VarintSize32(
field_number << kTagTypeBits);
if (type == TYPE_GROUP) {
// Groups have both a start and an end tag.
return result * 2;
} else {
return result;
}
}
inline uint32 WireFormatLite::EncodeFloat(float value) {
union {float f; uint32 i;};
f = value;
return i;
}
inline float WireFormatLite::DecodeFloat(uint32 value) {
union {float f; uint32 i;};
i = value;
return f;
}
inline uint64 WireFormatLite::EncodeDouble(double value) {
union {double f; uint64 i;};
f = value;
return i;
}
inline double WireFormatLite::DecodeDouble(uint64 value) {
union {double f; uint64 i;};
i = value;
return f;
}
// ZigZag Transform: Encodes signed integers so that they can be
// effectively used with varint encoding.
//
// varint operates on unsigned integers, encoding smaller numbers into
// fewer bytes. If you try to use it on a signed integer, it will treat
// this number as a very large unsigned integer, which means that even
// small signed numbers like -1 will take the maximum number of bytes
// (10) to encode. ZigZagEncode() maps signed integers to unsigned
// in such a way that those with a small absolute value will have smaller
// encoded values, making them appropriate for encoding using varint.
//
// int32 -> uint32
// -------------------------
// 0 -> 0
// -1 -> 1
// 1 -> 2
// -2 -> 3
// ... -> ...
// 2147483647 -> 4294967294
// -2147483648 -> 4294967295
//
// >> encode >>
// << decode <<
inline uint32 WireFormatLite::ZigZagEncode32(int32 n) {
// Note: the right-shift must be arithmetic
return (n << 1) ^ (n >> 31);
}
inline int32 WireFormatLite::ZigZagDecode32(uint32 n) {
return (n >> 1) ^ -static_cast<int32>(n & 1);
}
inline uint64 WireFormatLite::ZigZagEncode64(int64 n) {
// Note: the right-shift must be arithmetic
return (n << 1) ^ (n >> 63);
}
inline int64 WireFormatLite::ZigZagDecode64(uint64 n) {
return (n >> 1) ^ -static_cast<int64>(n & 1);
}
} // namespace internal
} // namespace protobuf
} // namespace google
#endif // GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_H__

View File

@ -0,0 +1,776 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// http://code.google.com/p/protobuf/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Author: kenton@google.com (Kenton Varda)
// wink@google.com (Wink Saville) (refactored from wire_format.h)
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
#ifndef GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_INL_H__
#define GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_INL_H__
#include <string>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/message_lite.h>
#include <google/protobuf/repeated_field.h>
#include <google/protobuf/wire_format_lite.h>
#include <google/protobuf/io/coded_stream.h>
namespace google {
namespace protobuf {
namespace internal {
// Implementation details of ReadPrimitive.
template <>
inline bool WireFormatLite::ReadPrimitive<int32, WireFormatLite::TYPE_INT32>(
io::CodedInputStream* input,
int32* value) {
uint32 temp;
if (!input->ReadVarint32(&temp)) return false;
*value = static_cast<int32>(temp);
return true;
}
template <>
inline bool WireFormatLite::ReadPrimitive<int64, WireFormatLite::TYPE_INT64>(
io::CodedInputStream* input,
int64* value) {
uint64 temp;
if (!input->ReadVarint64(&temp)) return false;
*value = static_cast<int64>(temp);
return true;
}
template <>
inline bool WireFormatLite::ReadPrimitive<uint32, WireFormatLite::TYPE_UINT32>(
io::CodedInputStream* input,
uint32* value) {
return input->ReadVarint32(value);
}
template <>
inline bool WireFormatLite::ReadPrimitive<uint64, WireFormatLite::TYPE_UINT64>(
io::CodedInputStream* input,
uint64* value) {
return input->ReadVarint64(value);
}
template <>
inline bool WireFormatLite::ReadPrimitive<int32, WireFormatLite::TYPE_SINT32>(
io::CodedInputStream* input,
int32* value) {
uint32 temp;
if (!input->ReadVarint32(&temp)) return false;
*value = ZigZagDecode32(temp);
return true;
}
template <>
inline bool WireFormatLite::ReadPrimitive<int64, WireFormatLite::TYPE_SINT64>(
io::CodedInputStream* input,
int64* value) {
uint64 temp;
if (!input->ReadVarint64(&temp)) return false;
*value = ZigZagDecode64(temp);
return true;
}
template <>
inline bool WireFormatLite::ReadPrimitive<uint32, WireFormatLite::TYPE_FIXED32>(
io::CodedInputStream* input,
uint32* value) {
return input->ReadLittleEndian32(value);
}
template <>
inline bool WireFormatLite::ReadPrimitive<uint64, WireFormatLite::TYPE_FIXED64>(
io::CodedInputStream* input,
uint64* value) {
return input->ReadLittleEndian64(value);
}
template <>
inline bool WireFormatLite::ReadPrimitive<int32, WireFormatLite::TYPE_SFIXED32>(
io::CodedInputStream* input,
int32* value) {
uint32 temp;
if (!input->ReadLittleEndian32(&temp)) return false;
*value = static_cast<int32>(temp);
return true;
}
template <>
inline bool WireFormatLite::ReadPrimitive<int64, WireFormatLite::TYPE_SFIXED64>(
io::CodedInputStream* input,
int64* value) {
uint64 temp;
if (!input->ReadLittleEndian64(&temp)) return false;
*value = static_cast<int64>(temp);
return true;
}
template <>
inline bool WireFormatLite::ReadPrimitive<float, WireFormatLite::TYPE_FLOAT>(
io::CodedInputStream* input,
float* value) {
uint32 temp;
if (!input->ReadLittleEndian32(&temp)) return false;
*value = DecodeFloat(temp);
return true;
}
template <>
inline bool WireFormatLite::ReadPrimitive<double, WireFormatLite::TYPE_DOUBLE>(
io::CodedInputStream* input,
double* value) {
uint64 temp;
if (!input->ReadLittleEndian64(&temp)) return false;
*value = DecodeDouble(temp);
return true;
}
template <>
inline bool WireFormatLite::ReadPrimitive<bool, WireFormatLite::TYPE_BOOL>(
io::CodedInputStream* input,
bool* value) {
uint32 temp;
if (!input->ReadVarint32(&temp)) return false;
*value = temp != 0;
return true;
}
template <>
inline bool WireFormatLite::ReadPrimitive<int, WireFormatLite::TYPE_ENUM>(
io::CodedInputStream* input,
int* value) {
uint32 temp;
if (!input->ReadVarint32(&temp)) return false;
*value = static_cast<int>(temp);
return true;
}
template <>
inline const uint8* WireFormatLite::ReadPrimitiveFromArray<
uint32, WireFormatLite::TYPE_FIXED32>(
const uint8* buffer,
uint32* value) {
return io::CodedInputStream::ReadLittleEndian32FromArray(buffer, value);
}
template <>
inline const uint8* WireFormatLite::ReadPrimitiveFromArray<
uint64, WireFormatLite::TYPE_FIXED64>(
const uint8* buffer,
uint64* value) {
return io::CodedInputStream::ReadLittleEndian64FromArray(buffer, value);
}
template <>
inline const uint8* WireFormatLite::ReadPrimitiveFromArray<
int32, WireFormatLite::TYPE_SFIXED32>(
const uint8* buffer,
int32* value) {
uint32 temp;
buffer = io::CodedInputStream::ReadLittleEndian32FromArray(buffer, &temp);
*value = static_cast<int32>(temp);
return buffer;
}
template <>
inline const uint8* WireFormatLite::ReadPrimitiveFromArray<
int64, WireFormatLite::TYPE_SFIXED64>(
const uint8* buffer,
int64* value) {
uint64 temp;
buffer = io::CodedInputStream::ReadLittleEndian64FromArray(buffer, &temp);
*value = static_cast<int64>(temp);
return buffer;
}
template <>
inline const uint8* WireFormatLite::ReadPrimitiveFromArray<
float, WireFormatLite::TYPE_FLOAT>(
const uint8* buffer,
float* value) {
uint32 temp;
buffer = io::CodedInputStream::ReadLittleEndian32FromArray(buffer, &temp);
*value = DecodeFloat(temp);
return buffer;
}
template <>
inline const uint8* WireFormatLite::ReadPrimitiveFromArray<
double, WireFormatLite::TYPE_DOUBLE>(
const uint8* buffer,
double* value) {
uint64 temp;
buffer = io::CodedInputStream::ReadLittleEndian64FromArray(buffer, &temp);
*value = DecodeDouble(temp);
return buffer;
}
template <typename CType, enum WireFormatLite::FieldType DeclaredType>
inline bool WireFormatLite::ReadRepeatedPrimitive(int, // tag_size, unused.
uint32 tag,
io::CodedInputStream* input,
RepeatedField<CType>* values) {
CType value;
if (!ReadPrimitive<CType, DeclaredType>(input, &value)) return false;
values->Add(value);
int elements_already_reserved = values->Capacity() - values->size();
while (elements_already_reserved > 0 && input->ExpectTag(tag)) {
if (!ReadPrimitive<CType, DeclaredType>(input, &value)) return false;
values->AddAlreadyReserved(value);
elements_already_reserved--;
}
return true;
}
template <typename CType, enum WireFormatLite::FieldType DeclaredType>
inline bool WireFormatLite::ReadRepeatedFixedSizePrimitive(
int tag_size,
uint32 tag,
io::CodedInputStream* input,
RepeatedField<CType>* values) {
GOOGLE_DCHECK_EQ(UInt32Size(tag), tag_size);
CType value;
if (!ReadPrimitive<CType, DeclaredType>(input, &value))
return false;
values->Add(value);
// For fixed size values, repeated values can be read more quickly by
// reading directly from a raw array.
//
// We can get a tight loop by only reading as many elements as can be
// added to the RepeatedField without having to do any resizing. Additionally,
// we only try to read as many elements as are available from the current
// buffer space. Doing so avoids having to perform boundary checks when
// reading the value: the maximum number of elements that can be read is
// known outside of the loop.
const void* void_pointer;
int size;
input->GetDirectBufferPointerInline(&void_pointer, &size);
if (size > 0) {
const uint8* buffer = reinterpret_cast<const uint8*>(void_pointer);
// The number of bytes each type occupies on the wire.
const int per_value_size = tag_size + sizeof(value);
int elements_available = min(values->Capacity() - values->size(),
size / per_value_size);
int num_read = 0;
while (num_read < elements_available &&
(buffer = io::CodedInputStream::ExpectTagFromArray(
buffer, tag)) != NULL) {
buffer = ReadPrimitiveFromArray<CType, DeclaredType>(buffer, &value);
values->AddAlreadyReserved(value);
++num_read;
}
const int read_bytes = num_read * per_value_size;
if (read_bytes > 0) {
input->Skip(read_bytes);
}
}
return true;
}
// Specializations of ReadRepeatedPrimitive for the fixed size types, which use
// the optimized code path.
#define READ_REPEATED_FIXED_SIZE_PRIMITIVE(CPPTYPE, DECLARED_TYPE) \
template <> \
inline bool WireFormatLite::ReadRepeatedPrimitive< \
CPPTYPE, WireFormatLite::DECLARED_TYPE>( \
int tag_size, \
uint32 tag, \
io::CodedInputStream* input, \
RepeatedField<CPPTYPE>* values) { \
return ReadRepeatedFixedSizePrimitive< \
CPPTYPE, WireFormatLite::DECLARED_TYPE>( \
tag_size, tag, input, values); \
}
READ_REPEATED_FIXED_SIZE_PRIMITIVE(uint32, TYPE_FIXED32)
READ_REPEATED_FIXED_SIZE_PRIMITIVE(uint64, TYPE_FIXED64)
READ_REPEATED_FIXED_SIZE_PRIMITIVE(int32, TYPE_SFIXED32)
READ_REPEATED_FIXED_SIZE_PRIMITIVE(int64, TYPE_SFIXED64)
READ_REPEATED_FIXED_SIZE_PRIMITIVE(float, TYPE_FLOAT)
READ_REPEATED_FIXED_SIZE_PRIMITIVE(double, TYPE_DOUBLE)
#undef READ_REPEATED_FIXED_SIZE_PRIMITIVE
template <typename CType, enum WireFormatLite::FieldType DeclaredType>
bool WireFormatLite::ReadRepeatedPrimitiveNoInline(
int tag_size,
uint32 tag,
io::CodedInputStream* input,
RepeatedField<CType>* value) {
return ReadRepeatedPrimitive<CType, DeclaredType>(
tag_size, tag, input, value);
}
template <typename CType, enum WireFormatLite::FieldType DeclaredType>
inline bool WireFormatLite::ReadPackedPrimitive(io::CodedInputStream* input,
RepeatedField<CType>* values) {
uint32 length;
if (!input->ReadVarint32(&length)) return false;
io::CodedInputStream::Limit limit = input->PushLimit(length);
while (input->BytesUntilLimit() > 0) {
CType value;
if (!ReadPrimitive<CType, DeclaredType>(input, &value)) return false;
values->Add(value);
}
input->PopLimit(limit);
return true;
}
template <typename CType, enum WireFormatLite::FieldType DeclaredType>
bool WireFormatLite::ReadPackedPrimitiveNoInline(io::CodedInputStream* input,
RepeatedField<CType>* values) {
return ReadPackedPrimitive<CType, DeclaredType>(input, values);
}
inline bool WireFormatLite::ReadGroup(int field_number,
io::CodedInputStream* input,
MessageLite* value) {
if (!input->IncrementRecursionDepth()) return false;
if (!value->MergePartialFromCodedStream(input)) return false;
input->DecrementRecursionDepth();
// Make sure the last thing read was an end tag for this group.
if (!input->LastTagWas(MakeTag(field_number, WIRETYPE_END_GROUP))) {
return false;
}
return true;
}
inline bool WireFormatLite::ReadMessage(io::CodedInputStream* input,
MessageLite* value) {
uint32 length;
if (!input->ReadVarint32(&length)) return false;
if (!input->IncrementRecursionDepth()) return false;
io::CodedInputStream::Limit limit = input->PushLimit(length);
if (!value->MergePartialFromCodedStream(input)) return false;
// Make sure that parsing stopped when the limit was hit, not at an endgroup
// tag.
if (!input->ConsumedEntireMessage()) return false;
input->PopLimit(limit);
input->DecrementRecursionDepth();
return true;
}
// We name the template parameter something long and extremely unlikely to occur
// elsewhere because a *qualified* member access expression designed to avoid
// virtual dispatch, C++03 [basic.lookup.classref] 3.4.5/4 requires that the
// name of the qualifying class to be looked up both in the context of the full
// expression (finding the template parameter) and in the context of the object
// whose member we are accessing. This could potentially find a nested type
// within that object. The standard goes on to require these names to refer to
// the same entity, which this collision would violate. The lack of a safe way
// to avoid this collision appears to be a defect in the standard, but until it
// is corrected, we choose the name to avoid accidental collisions.
template<typename MessageType_WorkAroundCppLookupDefect>
inline bool WireFormatLite::ReadGroupNoVirtual(
int field_number, io::CodedInputStream* input,
MessageType_WorkAroundCppLookupDefect* value) {
if (!input->IncrementRecursionDepth()) return false;
if (!value->
MessageType_WorkAroundCppLookupDefect::MergePartialFromCodedStream(input))
return false;
input->DecrementRecursionDepth();
// Make sure the last thing read was an end tag for this group.
if (!input->LastTagWas(MakeTag(field_number, WIRETYPE_END_GROUP))) {
return false;
}
return true;
}
template<typename MessageType_WorkAroundCppLookupDefect>
inline bool WireFormatLite::ReadMessageNoVirtual(
io::CodedInputStream* input, MessageType_WorkAroundCppLookupDefect* value) {
uint32 length;
if (!input->ReadVarint32(&length)) return false;
if (!input->IncrementRecursionDepth()) return false;
io::CodedInputStream::Limit limit = input->PushLimit(length);
if (!value->
MessageType_WorkAroundCppLookupDefect::MergePartialFromCodedStream(input))
return false;
// Make sure that parsing stopped when the limit was hit, not at an endgroup
// tag.
if (!input->ConsumedEntireMessage()) return false;
input->PopLimit(limit);
input->DecrementRecursionDepth();
return true;
}
// ===================================================================
inline void WireFormatLite::WriteTag(int field_number, WireType type,
io::CodedOutputStream* output) {
output->WriteTag(MakeTag(field_number, type));
}
inline void WireFormatLite::WriteInt32NoTag(int32 value,
io::CodedOutputStream* output) {
output->WriteVarint32SignExtended(value);
}
inline void WireFormatLite::WriteInt64NoTag(int64 value,
io::CodedOutputStream* output) {
output->WriteVarint64(static_cast<uint64>(value));
}
inline void WireFormatLite::WriteUInt32NoTag(uint32 value,
io::CodedOutputStream* output) {
output->WriteVarint32(value);
}
inline void WireFormatLite::WriteUInt64NoTag(uint64 value,
io::CodedOutputStream* output) {
output->WriteVarint64(value);
}
inline void WireFormatLite::WriteSInt32NoTag(int32 value,
io::CodedOutputStream* output) {
output->WriteVarint32(ZigZagEncode32(value));
}
inline void WireFormatLite::WriteSInt64NoTag(int64 value,
io::CodedOutputStream* output) {
output->WriteVarint64(ZigZagEncode64(value));
}
inline void WireFormatLite::WriteFixed32NoTag(uint32 value,
io::CodedOutputStream* output) {
output->WriteLittleEndian32(value);
}
inline void WireFormatLite::WriteFixed64NoTag(uint64 value,
io::CodedOutputStream* output) {
output->WriteLittleEndian64(value);
}
inline void WireFormatLite::WriteSFixed32NoTag(int32 value,
io::CodedOutputStream* output) {
output->WriteLittleEndian32(static_cast<uint32>(value));
}
inline void WireFormatLite::WriteSFixed64NoTag(int64 value,
io::CodedOutputStream* output) {
output->WriteLittleEndian64(static_cast<uint64>(value));
}
inline void WireFormatLite::WriteFloatNoTag(float value,
io::CodedOutputStream* output) {
output->WriteLittleEndian32(EncodeFloat(value));
}
inline void WireFormatLite::WriteDoubleNoTag(double value,
io::CodedOutputStream* output) {
output->WriteLittleEndian64(EncodeDouble(value));
}
inline void WireFormatLite::WriteBoolNoTag(bool value,
io::CodedOutputStream* output) {
output->WriteVarint32(value ? 1 : 0);
}
inline void WireFormatLite::WriteEnumNoTag(int value,
io::CodedOutputStream* output) {
output->WriteVarint32SignExtended(value);
}
// See comment on ReadGroupNoVirtual to understand the need for this template
// parameter name.
template<typename MessageType_WorkAroundCppLookupDefect>
inline void WireFormatLite::WriteGroupNoVirtual(
int field_number, const MessageType_WorkAroundCppLookupDefect& value,
io::CodedOutputStream* output) {
WriteTag(field_number, WIRETYPE_START_GROUP, output);
value.MessageType_WorkAroundCppLookupDefect::SerializeWithCachedSizes(output);
WriteTag(field_number, WIRETYPE_END_GROUP, output);
}
template<typename MessageType_WorkAroundCppLookupDefect>
inline void WireFormatLite::WriteMessageNoVirtual(
int field_number, const MessageType_WorkAroundCppLookupDefect& value,
io::CodedOutputStream* output) {
WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output);
output->WriteVarint32(
value.MessageType_WorkAroundCppLookupDefect::GetCachedSize());
value.MessageType_WorkAroundCppLookupDefect::SerializeWithCachedSizes(output);
}
// ===================================================================
inline uint8* WireFormatLite::WriteTagToArray(int field_number,
WireType type,
uint8* target) {
return io::CodedOutputStream::WriteTagToArray(MakeTag(field_number, type),
target);
}
inline uint8* WireFormatLite::WriteInt32NoTagToArray(int32 value,
uint8* target) {
return io::CodedOutputStream::WriteVarint32SignExtendedToArray(value, target);
}
inline uint8* WireFormatLite::WriteInt64NoTagToArray(int64 value,
uint8* target) {
return io::CodedOutputStream::WriteVarint64ToArray(
static_cast<uint64>(value), target);
}
inline uint8* WireFormatLite::WriteUInt32NoTagToArray(uint32 value,
uint8* target) {
return io::CodedOutputStream::WriteVarint32ToArray(value, target);
}
inline uint8* WireFormatLite::WriteUInt64NoTagToArray(uint64 value,
uint8* target) {
return io::CodedOutputStream::WriteVarint64ToArray(value, target);
}
inline uint8* WireFormatLite::WriteSInt32NoTagToArray(int32 value,
uint8* target) {
return io::CodedOutputStream::WriteVarint32ToArray(ZigZagEncode32(value),
target);
}
inline uint8* WireFormatLite::WriteSInt64NoTagToArray(int64 value,
uint8* target) {
return io::CodedOutputStream::WriteVarint64ToArray(ZigZagEncode64(value),
target);
}
inline uint8* WireFormatLite::WriteFixed32NoTagToArray(uint32 value,
uint8* target) {
return io::CodedOutputStream::WriteLittleEndian32ToArray(value, target);
}
inline uint8* WireFormatLite::WriteFixed64NoTagToArray(uint64 value,
uint8* target) {
return io::CodedOutputStream::WriteLittleEndian64ToArray(value, target);
}
inline uint8* WireFormatLite::WriteSFixed32NoTagToArray(int32 value,
uint8* target) {
return io::CodedOutputStream::WriteLittleEndian32ToArray(
static_cast<uint32>(value), target);
}
inline uint8* WireFormatLite::WriteSFixed64NoTagToArray(int64 value,
uint8* target) {
return io::CodedOutputStream::WriteLittleEndian64ToArray(
static_cast<uint64>(value), target);
}
inline uint8* WireFormatLite::WriteFloatNoTagToArray(float value,
uint8* target) {
return io::CodedOutputStream::WriteLittleEndian32ToArray(EncodeFloat(value),
target);
}
inline uint8* WireFormatLite::WriteDoubleNoTagToArray(double value,
uint8* target) {
return io::CodedOutputStream::WriteLittleEndian64ToArray(EncodeDouble(value),
target);
}
inline uint8* WireFormatLite::WriteBoolNoTagToArray(bool value,
uint8* target) {
return io::CodedOutputStream::WriteVarint32ToArray(value ? 1 : 0, target);
}
inline uint8* WireFormatLite::WriteEnumNoTagToArray(int value,
uint8* target) {
return io::CodedOutputStream::WriteVarint32SignExtendedToArray(value, target);
}
inline uint8* WireFormatLite::WriteInt32ToArray(int field_number,
int32 value,
uint8* target) {
target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
return WriteInt32NoTagToArray(value, target);
}
inline uint8* WireFormatLite::WriteInt64ToArray(int field_number,
int64 value,
uint8* target) {
target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
return WriteInt64NoTagToArray(value, target);
}
inline uint8* WireFormatLite::WriteUInt32ToArray(int field_number,
uint32 value,
uint8* target) {
target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
return WriteUInt32NoTagToArray(value, target);
}
inline uint8* WireFormatLite::WriteUInt64ToArray(int field_number,
uint64 value,
uint8* target) {
target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
return WriteUInt64NoTagToArray(value, target);
}
inline uint8* WireFormatLite::WriteSInt32ToArray(int field_number,
int32 value,
uint8* target) {
target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
return WriteSInt32NoTagToArray(value, target);
}
inline uint8* WireFormatLite::WriteSInt64ToArray(int field_number,
int64 value,
uint8* target) {
target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
return WriteSInt64NoTagToArray(value, target);
}
inline uint8* WireFormatLite::WriteFixed32ToArray(int field_number,
uint32 value,
uint8* target) {
target = WriteTagToArray(field_number, WIRETYPE_FIXED32, target);
return WriteFixed32NoTagToArray(value, target);
}
inline uint8* WireFormatLite::WriteFixed64ToArray(int field_number,
uint64 value,
uint8* target) {
target = WriteTagToArray(field_number, WIRETYPE_FIXED64, target);
return WriteFixed64NoTagToArray(value, target);
}
inline uint8* WireFormatLite::WriteSFixed32ToArray(int field_number,
int32 value,
uint8* target) {
target = WriteTagToArray(field_number, WIRETYPE_FIXED32, target);
return WriteSFixed32NoTagToArray(value, target);
}
inline uint8* WireFormatLite::WriteSFixed64ToArray(int field_number,
int64 value,
uint8* target) {
target = WriteTagToArray(field_number, WIRETYPE_FIXED64, target);
return WriteSFixed64NoTagToArray(value, target);
}
inline uint8* WireFormatLite::WriteFloatToArray(int field_number,
float value,
uint8* target) {
target = WriteTagToArray(field_number, WIRETYPE_FIXED32, target);
return WriteFloatNoTagToArray(value, target);
}
inline uint8* WireFormatLite::WriteDoubleToArray(int field_number,
double value,
uint8* target) {
target = WriteTagToArray(field_number, WIRETYPE_FIXED64, target);
return WriteDoubleNoTagToArray(value, target);
}
inline uint8* WireFormatLite::WriteBoolToArray(int field_number,
bool value,
uint8* target) {
target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
return WriteBoolNoTagToArray(value, target);
}
inline uint8* WireFormatLite::WriteEnumToArray(int field_number,
int value,
uint8* target) {
target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
return WriteEnumNoTagToArray(value, target);
}
inline uint8* WireFormatLite::WriteStringToArray(int field_number,
const string& value,
uint8* target) {
// String is for UTF-8 text only
// WARNING: In wire_format.cc, both strings and bytes are handled by
// WriteString() to avoid code duplication. If the implementations become
// different, you will need to update that usage.
target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target);
target = io::CodedOutputStream::WriteVarint32ToArray(value.size(), target);
return io::CodedOutputStream::WriteStringToArray(value, target);
}
inline uint8* WireFormatLite::WriteBytesToArray(int field_number,
const string& value,
uint8* target) {
target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target);
target = io::CodedOutputStream::WriteVarint32ToArray(value.size(), target);
return io::CodedOutputStream::WriteStringToArray(value, target);
}
inline uint8* WireFormatLite::WriteGroupToArray(int field_number,
const MessageLite& value,
uint8* target) {
target = WriteTagToArray(field_number, WIRETYPE_START_GROUP, target);
target = value.SerializeWithCachedSizesToArray(target);
return WriteTagToArray(field_number, WIRETYPE_END_GROUP, target);
}
inline uint8* WireFormatLite::WriteMessageToArray(int field_number,
const MessageLite& value,
uint8* target) {
target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target);
target = io::CodedOutputStream::WriteVarint32ToArray(
value.GetCachedSize(), target);
return value.SerializeWithCachedSizesToArray(target);
}
// See comment on ReadGroupNoVirtual to understand the need for this template
// parameter name.
template<typename MessageType_WorkAroundCppLookupDefect>
inline uint8* WireFormatLite::WriteGroupNoVirtualToArray(
int field_number, const MessageType_WorkAroundCppLookupDefect& value,
uint8* target) {
target = WriteTagToArray(field_number, WIRETYPE_START_GROUP, target);
target = value.MessageType_WorkAroundCppLookupDefect
::SerializeWithCachedSizesToArray(target);
return WriteTagToArray(field_number, WIRETYPE_END_GROUP, target);
}
template<typename MessageType_WorkAroundCppLookupDefect>
inline uint8* WireFormatLite::WriteMessageNoVirtualToArray(
int field_number, const MessageType_WorkAroundCppLookupDefect& value,
uint8* target) {
target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target);
target = io::CodedOutputStream::WriteVarint32ToArray(
value.MessageType_WorkAroundCppLookupDefect::GetCachedSize(), target);
return value.MessageType_WorkAroundCppLookupDefect
::SerializeWithCachedSizesToArray(target);
}
// ===================================================================
inline int WireFormatLite::Int32Size(int32 value) {
return io::CodedOutputStream::VarintSize32SignExtended(value);
}
inline int WireFormatLite::Int64Size(int64 value) {
return io::CodedOutputStream::VarintSize64(static_cast<uint64>(value));
}
inline int WireFormatLite::UInt32Size(uint32 value) {
return io::CodedOutputStream::VarintSize32(value);
}
inline int WireFormatLite::UInt64Size(uint64 value) {
return io::CodedOutputStream::VarintSize64(value);
}
inline int WireFormatLite::SInt32Size(int32 value) {
return io::CodedOutputStream::VarintSize32(ZigZagEncode32(value));
}
inline int WireFormatLite::SInt64Size(int64 value) {
return io::CodedOutputStream::VarintSize64(ZigZagEncode64(value));
}
inline int WireFormatLite::EnumSize(int value) {
return io::CodedOutputStream::VarintSize32SignExtended(value);
}
inline int WireFormatLite::StringSize(const string& value) {
return io::CodedOutputStream::VarintSize32(value.size()) +
value.size();
}
inline int WireFormatLite::BytesSize(const string& value) {
return io::CodedOutputStream::VarintSize32(value.size()) +
value.size();
}
inline int WireFormatLite::GroupSize(const MessageLite& value) {
return value.ByteSize();
}
inline int WireFormatLite::MessageSize(const MessageLite& value) {
return LengthDelimitedSize(value.ByteSize());
}
// See comment on ReadGroupNoVirtual to understand the need for this template
// parameter name.
template<typename MessageType_WorkAroundCppLookupDefect>
inline int WireFormatLite::GroupSizeNoVirtual(
const MessageType_WorkAroundCppLookupDefect& value) {
return value.MessageType_WorkAroundCppLookupDefect::ByteSize();
}
template<typename MessageType_WorkAroundCppLookupDefect>
inline int WireFormatLite::MessageSizeNoVirtual(
const MessageType_WorkAroundCppLookupDefect& value) {
return LengthDelimitedSize(
value.MessageType_WorkAroundCppLookupDefect::ByteSize());
}
inline int WireFormatLite::LengthDelimitedSize(int length) {
return io::CodedOutputStream::VarintSize32(length) + length;
}
} // namespace internal
} // namespace protobuf
} // namespace google
#endif // GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_INL_H__

View File

@ -0,0 +1,166 @@
/****************************************************************************
Copyright (c) 2013 cocos2d-x.org
http://www.cocos2d-x.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "ConnectWaitLayer.h"
#include "Runtime.h"
#include "FileServer.h"
#include "ConfigParser.h"
#include "VisibleRect.h"
#include "ResData.h"
using namespace cocos2d;
ConnectWaitLayer::ConnectWaitLayer()
{
int designWidth = 1280;
int designHeight = 800;
_imagebg = new Image();
if (ConfigParser::getInstance()->isLanscape())
{
_imagebg->initWithImageData(__landscapePngData, sizeof(__landscapePngData));
Director::getInstance()->getOpenGLView()->setDesignResolutionSize(designWidth, designHeight, ResolutionPolicy::EXACT_FIT);
} else
{
_imagebg->initWithImageData(__portraitPngData, sizeof(__portraitPngData));
Director::getInstance()->getOpenGLView()->setDesignResolutionSize(designHeight, designWidth, ResolutionPolicy::FIXED_HEIGHT);
}
Texture2D* texturebg = Director::getInstance()->getTextureCache()->addImage(_imagebg, "play_background");
auto background = Sprite::createWithTexture(texturebg);
background->setAnchorPoint(Vec2(0.5, 0.5));
background->setPosition(VisibleRect::center());
addChild(background, 9000);
// variable of below is"play" button position.
int portraitX = 400;
int portraitY = 500;
int lanscaptX = 902;
int lanscaptY = 400;
_imageplay = new Image();
_imageplay->initWithImageData(__playEnablePngData, sizeof(__playEnablePngData));
Texture2D* textureplay = Director::getInstance()->getTextureCache()->addImage(_imageplay, "play_enable");
auto playSprite = Sprite::createWithTexture(textureplay);
addChild(playSprite, 9999);
_imageShine = new Image();
_imageShine->initWithImageData(__shinePngData, sizeof(__shinePngData));
Texture2D* textureShine = Director::getInstance()->getTextureCache()->addImage(_imageShine, "shine");
auto shineSprite = Sprite::createWithTexture(textureShine);
shineSprite->setOpacity(0);
Vector<FiniteTimeAction*> arrayOfActions;
arrayOfActions.pushBack(DelayTime::create(0.4f));
arrayOfActions.pushBack(FadeTo::create(0.8f, 200));
arrayOfActions.pushBack(FadeTo::create(0.8f, 255));
arrayOfActions.pushBack(FadeTo::create(0.8f, 200));
arrayOfActions.pushBack(FadeTo::create(0.8f, 0));
arrayOfActions.pushBack(DelayTime::create(0.4f));
shineSprite->runAction(RepeatForever::create(Sequence::create(arrayOfActions)));
addChild(shineSprite, 9998);
std::string strip = getIPAddress();
if (strip.empty())
{
strip = "0.0.0.0";
}
char szIPAddress[64] = {0};
sprintf(szIPAddress, "IP: %s", strip.c_str());
auto IPlabel = Label::createWithSystemFont(szIPAddress, "", 72);
IPlabel->setAnchorPoint(Vec2(0, 0));
int spaceSizex = 72;
int spaceSizey = 200;
IPlabel->setPosition(Point(VisibleRect::leftTop().x + spaceSizex, VisibleRect::top().y - spaceSizey));
addChild(IPlabel, 9001);
std::string transferTip = "waiting for file transfer ...";
if (CC_PLATFORM_WIN32 == CC_TARGET_PLATFORM || CC_PLATFORM_MAC == CC_TARGET_PLATFORM)
{
transferTip = "waiting for debugger to connect ...";
}
char szVersion[256] = {0};
sprintf(szVersion, "runtimeVersion:%s \nengineVersion:%s", getRuntimeVersion(), cocos2dVersion());
Label* verLable = Label::createWithSystemFont(szVersion, "", 24);
verLable->setAnchorPoint(Vec2(0, 0));
int width = verLable->getBoundingBox().size.width;
verLable->setPosition(Point(VisibleRect::right().x - width, VisibleRect::rightBottom().y));
verLable->setAlignment(TextHAlignment::LEFT);
addChild(verLable, 9002);
_labelUploadFile = Label::createWithSystemFont(transferTip, "", 36);
_labelUploadFile->setAnchorPoint(Vec2(0, 0));
_labelUploadFile->setPosition(Point(VisibleRect::leftTop().x + spaceSizex, IPlabel->getPositionY()- spaceSizex));
_labelUploadFile->setAlignment(TextHAlignment::LEFT);
addChild(_labelUploadFile, 9003);
if (ConfigParser::getInstance()->isLanscape())
{
playSprite->setPosition(lanscaptX, lanscaptY);
shineSprite->setPosition(lanscaptX, lanscaptY);
}
else
{
playSprite->setPosition(portraitX, portraitY);
shineSprite->setPosition(portraitX, portraitY);
}
auto listener = EventListenerTouchOneByOne::create();
listener->onTouchBegan = [](Touch* touch, Event *event)->bool{
auto target = static_cast<Sprite*>(event->getCurrentTarget());
Vec2 point = target->convertToNodeSpace(Director::getInstance()->convertToGL(touch->getLocationInView()));
auto rect = Rect(0, 0, target->getContentSize().width, target->getContentSize().height);
if (!rect.containsPoint(point)) return false;
target->stopAllActions();
target->runAction(Sequence::createWithTwoActions(ScaleBy::create(0.05f, 0.9f), ScaleTo::create(0.125f, 1)));
return true;
};
listener->onTouchEnded = [](Touch* touch, Event *event){
auto target = static_cast<Sprite*>(event->getCurrentTarget());
Vec2 point = target->convertToNodeSpace(Director::getInstance()->convertToGL(touch->getLocationInView()));
auto rect = Rect(0, 0, target->getContentSize().width, target->getContentSize().height);
if (!rect.containsPoint(point)) return;
RuntimeEngine::getInstance()->setupRuntime();
RuntimeEngine::getInstance()->startScript("");
};
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, playSprite);
this->scheduleUpdate();
}
ConnectWaitLayer::~ConnectWaitLayer()
{
CC_SAFE_DELETE(_imagebg);
CC_SAFE_DELETE(_imageplay);
CC_SAFE_DELETE(_imageShine);
}
// clean up: ignore stdin, stdout and stderr
void ConnectWaitLayer::update(float fDelta)
{
std::string transferTip = FileServer::getShareInstance()->getTransingFileName();
if (transferTip.empty()){
return;
}
_labelUploadFile->setString(transferTip);
}

View File

@ -0,0 +1,46 @@
/****************************************************************************
Copyright (c) 2013 cocos2d-x.org
http://www.cocos2d-x.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#ifndef _CONNECT_WAIT_LAYER__H_
#define _CONNECT_WAIT_LAYER__H_
#include "cocos2d.h"
class ConnectWaitLayer: public cocos2d::Layer
{
public:
ConnectWaitLayer();
~ConnectWaitLayer();
void update(float fDelta);
private:
cocos2d::Image* _imagebg;
cocos2d::Image* _imageplay;
cocos2d::Image* _imageShine;
cocos2d::Label* _labelUploadFile;
};
#endif // _CONNECT_WAIT_LAYER__H_

View File

@ -0,0 +1,284 @@
/****************************************************************************
Copyright (c) 2013 cocos2d-x.org
http://www.cocos2d-x.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "Runtime.h"
#include "ConfigParser.h"
#include "ConsoleCommand.h"
#include "json/document.h"
#include "json/filestream.h"
#include "json/stringbuffer.h"
#include "RuntimeProtocol.h"
#include "cocos2d.h"
using namespace cocos2d;
ConsoleCommand* ConsoleCommand::s_sharedConsoleCommand = nullptr;
ConsoleCommand* ConsoleCommand::getShareInstance()
{
if (s_sharedConsoleCommand == nullptr)
{
s_sharedConsoleCommand = new ConsoleCommand();
}
return s_sharedConsoleCommand;
}
void ConsoleCommand::purge()
{
if (s_sharedConsoleCommand != nullptr)
{
delete s_sharedConsoleCommand;
}
}
void ConsoleCommand::init()
{
cocos2d::Console *_console = Director::getInstance()->getConsole();
static struct Console::Command commands[] =
{
{"sendrequest","send command to runtime.Args[json format]",std::bind(&ConsoleCommand::onSendCommand, this, std::placeholders::_1, std::placeholders::_2)},
};
for (int i = 0;i< sizeof(commands) / sizeof(Console::Command);i++)
{
_console->addCommand(commands[i]);
}
// set bind address
_console->setBindAddress(ConfigParser::getInstance()->getBindAddress());
_console->listenOnTCP(ConfigParser::getInstance()->getConsolePort()); // 6010,6050
_fileserver = FileServer::getShareInstance();
_fileserver->listenOnTCP(ConfigParser::getInstance()->getUploadPort()); // 6020,6060
_fileserver->readResFileFinfo();
}
void ConsoleCommand::onSendCommand(int fd, const std::string &args)
{
Director::getInstance()->getScheduler()->performFunctionInCocosThread([=](){
rapidjson::Document dArgParse;
dArgParse.Parse<0>(args.c_str());
if (dArgParse.HasMember("cmd"))
{
string strcmd = dArgParse["cmd"].GetString();
rapidjson::Document dReplyParse;
dReplyParse.SetObject();
dReplyParse.AddMember("cmd",strcmd.c_str(),dReplyParse.GetAllocator());
if (dArgParse.HasMember("seq"))
{
dReplyParse.AddMember("seq",dArgParse["seq"],dReplyParse.GetAllocator());
}
if(strcmp(strcmd.c_str(), "start-logic") == 0)
{
auto runtime = RuntimeEngine::getInstance()->getRuntime();
if (!runtime)
{
RuntimeEngine::getInstance()->setupRuntime();
runtime = RuntimeEngine::getInstance()->getRuntime();
}
if (runtime) runtime->onStartDebuger(dArgParse, dReplyParse);
} else if (strcmp(strcmd.c_str(),"clearcompile")==0)
{
auto runtime = RuntimeEngine::getInstance()->getRuntime();
if (!runtime)
{
RuntimeEngine::getInstance()->setupRuntime();
runtime = RuntimeEngine::getInstance()->getRuntime();
}
if (runtime) runtime->onClearCompile(dArgParse, dReplyParse);
} else if(strcmp(strcmd.c_str(),"precompile")==0)
{
auto runtime = RuntimeEngine::getInstance()->getRuntime();
if (!runtime)
{
RuntimeEngine::getInstance()->setupRuntime();
runtime = RuntimeEngine::getInstance()->getRuntime();
}
if (runtime) runtime->onPrecompile(dArgParse, dReplyParse);
} else if(strcmp(strcmd.c_str(), "reload") == 0)
{
auto runtime = RuntimeEngine::getInstance()->getRuntime();
if (!runtime)
{
RuntimeEngine::getInstance()->setupRuntime();
runtime = RuntimeEngine::getInstance()->getRuntime();
}
if (runtime) runtime->onReload(dArgParse, dReplyParse);
} else if(strcmp(strcmd.c_str(), "getversion") == 0)
{
rapidjson::Value bodyvalue(rapidjson::kObjectType);
bodyvalue.AddMember("version", getRuntimeVersion(), dReplyParse.GetAllocator());
dReplyParse.AddMember("body", bodyvalue, dReplyParse.GetAllocator());
dReplyParse.AddMember("code", 0, dReplyParse.GetAllocator());
} else if(strcmp(strcmd.c_str(), "getfileinfo") == 0)
{
rapidjson::Value bodyvalue(rapidjson::kObjectType);
rapidjson::Document* filecfgjson = _fileserver->getFileCfgJson();
for (auto it = filecfgjson->MemberonBegin(); it != filecfgjson->MemberonEnd(); ++it)
{
bodyvalue.AddMember(it->name.GetString(), it->value.GetString(), dReplyParse.GetAllocator());
}
dReplyParse.AddMember("body", bodyvalue, dReplyParse.GetAllocator());
dReplyParse.AddMember("code", 0, dReplyParse.GetAllocator());
} else if (strcmp(strcmd.c_str(), "getEntryfile") == 0)
{
rapidjson::Value bodyvalue(rapidjson::kObjectType);
rapidjson::Value entryFileValue(rapidjson::kStringType);
entryFileValue.SetString(ConfigParser::getInstance()->getEntryFile().c_str(), dReplyParse.GetAllocator());
bodyvalue.AddMember("entryfile", entryFileValue, dReplyParse.GetAllocator());
dReplyParse.AddMember("body", bodyvalue,dReplyParse.GetAllocator());
dReplyParse.AddMember("code", 0, dReplyParse.GetAllocator());
} else if(strcmp(strcmd.c_str(), "getIP") == 0)
{
rapidjson::Value bodyvalue(rapidjson::kObjectType);
rapidjson::Value IPValue(rapidjson::kStringType);
IPValue.SetString(getIPAddress().c_str(), dReplyParse.GetAllocator());
bodyvalue.AddMember("IP", IPValue,dReplyParse.GetAllocator());
dReplyParse.AddMember("body", bodyvalue,dReplyParse.GetAllocator());
dReplyParse.AddMember("code", 0, dReplyParse.GetAllocator());
} else if(strcmp(strcmd.c_str(), "remove") == 0)
{
if (dArgParse.HasMember("files"))
{
rapidjson::Value bodyvalue(rapidjson::kObjectType);
const rapidjson::Value& objectfiles = dArgParse["files"];
const char* filename = NULL;
for (rapidjson::SizeType i = 0; i < objectfiles.Size(); i++)
{
filename = objectfiles[i].GetString();
// remove js compiled script
auto runtime = RuntimeEngine::getInstance()->getRuntime();
if (runtime) runtime->onRemove(filename);
// remove file from disk
string filepath(_fileserver->getWritePath() + "/" + filename);
if (FileUtils::getInstance()->isFileExist(filepath))
{
if(remove(filepath.c_str()) != 0)
{
// remove failed
bodyvalue.AddMember(filename, 2, dReplyParse.GetAllocator());
}
} else
{
// file not exist
bodyvalue.AddMember(filename, 1, dReplyParse.GetAllocator());
}
// file remove success, remove it from record
if (! FileUtils::getInstance()->isFileExist(filepath))
_fileserver->removeResFileInfo(filename);
}
dReplyParse.AddMember("body", bodyvalue, dReplyParse.GetAllocator());
}
dReplyParse.AddMember("code",0,dReplyParse.GetAllocator());
} else if(strcmp(strcmd.c_str(), "shutdownapp") == 0)
{
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
extern void shutDownApp();
shutDownApp();
#else
exit(0);
#endif
} else if(strcmp(strcmd.c_str(), "getplatform") == 0)
{
string platform="UNKNOW";
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
platform = "WIN32";
#elif (CC_TARGET_PLATFORM == CC_PLATFORM_MAC)
platform = "MAC";
#elif (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
platform = "IOS";
#elif (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
platform = "ANDROID";
#endif
rapidjson::Value bodyvalue(rapidjson::kObjectType);
rapidjson::Value platformValue(rapidjson::kStringType);
platformValue.SetString(platform.c_str(), dReplyParse.GetAllocator());
bodyvalue.AddMember("platform", platformValue, dReplyParse.GetAllocator());
dReplyParse.AddMember("body", bodyvalue, dReplyParse.GetAllocator());
dReplyParse.AddMember("code", 0, dReplyParse.GetAllocator());
} else if(strcmp(strcmd.c_str(), "usewritablepath") == 0)
{
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS || CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
// only iOS and Android need to open using write path by Code IDE
FileServer::getShareInstance()->setIsUsingWritePath(true);
std::vector<std::string> searchPathArray = FileUtils::getInstance()->getSearchPaths();
searchPathArray.insert(searchPathArray.begin(), FileServer::getShareInstance()->getWritePath());
FileUtils::getInstance()->setSearchPaths(searchPathArray);
#endif
dReplyParse.AddMember("code", 0, dReplyParse.GetAllocator());
}
else if (strcmp(strcmd.c_str(), "workdir") == 0)
{
if (dArgParse.HasMember("path"))
{
const rapidjson::Value& objectPath = dArgParse["path"];
FileUtils::getInstance()->setDefaultResourceRootPath(objectPath.GetString());
rapidjson::Value bodyvalue(rapidjson::kObjectType);
bodyvalue.AddMember("path", objectPath.GetString(), dReplyParse.GetAllocator());
dReplyParse.AddMember("body", bodyvalue, dReplyParse.GetAllocator());
}
dReplyParse.AddMember("code", 0, dReplyParse.GetAllocator());
}
else if (strcmp(strcmd.c_str(), "writablePath") == 0)
{
if (dArgParse.HasMember("path"))
{
const rapidjson::Value& objectPath = dArgParse["path"];
FileUtils::getInstance()->setWritablePath(objectPath.GetString());
rapidjson::Value bodyvalue(rapidjson::kObjectType);
bodyvalue.AddMember("path", objectPath.GetString(), dReplyParse.GetAllocator());
dReplyParse.AddMember("body", bodyvalue, dReplyParse.GetAllocator());
}
dReplyParse.AddMember("code", 0, dReplyParse.GetAllocator());
}
rapidjson::StringBuffer buffer;
rapidjson::Writer< rapidjson::StringBuffer > writer(buffer);
dReplyParse.Accept(writer);
string msgContent = buffer.GetString();
char msgLength[64] = {0x1, 0};
sprintf(msgLength + 1, "%ld:", msgContent.size());
string msg(msgLength + msgContent);
sendBuf(fd, msg.c_str(), msg.size());
}
});
}
ConsoleCommand::~ConsoleCommand()
{
Director::getInstance()->getConsole()->stop();
}

View File

@ -0,0 +1,46 @@
/****************************************************************************
Copyright (c) 2013 cocos2d-x.org
http://www.cocos2d-x.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#ifndef _CONSOLE_COMMAND__H_
#define _CONSOLE_COMMAND__H_
#include "FileServer.h"
class ConsoleCommand
{
static ConsoleCommand *s_sharedConsoleCommand;
public:
static ConsoleCommand* getShareInstance();
static void purge();
void init();
void onSendCommand(int fd, const std::string &args);
private:
~ConsoleCommand();
FileServer* _fileserver;
};
#endif // _CONSOLE_COMMAND__H_

View File

@ -0,0 +1,564 @@
/****************************************************************************
Copyright (c) 2013 cocos2d-x.org
http://www.cocos2d-x.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "FileServer.h"
#include "Runtime.h"
#include "zlib.h"
#include "ConfigParser.h"
// header files for directory operation
#ifdef _WIN32
#include <direct.h>
#else
#include <sys/stat.h>
#endif
USING_NS_CC;
//1M size
#define MAXPROTOLENGTH 1048576
#define PROTO_START "RuntimeSend:"
FileServer* FileServer::s_sharedFileServer = nullptr;
FileServer* FileServer::getShareInstance()
{
if (s_sharedFileServer == nullptr)
{
s_sharedFileServer = new FileServer;
}
return s_sharedFileServer;
}
void FileServer::purge()
{
CC_SAFE_DELETE(s_sharedFileServer);
}
void FileServer::readResFileFinfo()
{
std::string filecfg = _writePath + "/fileinfo_debug.json";
FILE * pFile = fopen (filecfg.c_str() , "r");
if(pFile)
{
rapidjson::FileStream inputStream(pFile);
_filecfgjson.ParseStream<0>(inputStream);
fclose(pFile);
}
if(! _filecfgjson.IsObject()){
_filecfgjson.SetObject();
}
//save file info to disk every five second
Director::getInstance()->getScheduler()->schedule([&](float){
rapidjson::StringBuffer buffer;
rapidjson::Writer< rapidjson::StringBuffer > writer(buffer);
_filecfgjson.Accept(writer);
const char* str = buffer.GetString();
std::string filecfg = _writePath + "/fileinfo_debug.json";
FILE * pFile = fopen(filecfg.c_str(), "w");
if (!pFile) return ;
fwrite(str, sizeof(char), strlen(str), pFile);
fclose(pFile);
},this, 5.0f, false, "fileinfo");
}
void FileServer::addResFileInfo(const char* filename, uint64_t u64)
{
if(_filecfgjson.HasMember(filename)){
_filecfgjson.RemoveMember(filename);
}
char filetime[512]= {0};
sprintf(filetime, "%llu", u64);
rapidjson::Value filetimeValue(rapidjson::kStringType);
filetimeValue.SetString(filetime, _filecfgjson.GetAllocator());
rapidjson::Value filenameValue(rapidjson::kStringType);
filenameValue.SetString(filename,_filecfgjson.GetAllocator());
_filecfgjson.AddMember(filenameValue.GetString(), filetimeValue, _filecfgjson.GetAllocator());
}
void FileServer::removeResFileInfo(const char *filename)
{
if (_filecfgjson.HasMember(filename)) {
_filecfgjson.RemoveMember(filename);
}
}
std::string FileServer::getTransingFileName()
{
_fileNameMutex.lock();
std::string filename = _strFileName;
_fileNameMutex.unlock();
return filename;
}
void FileServer::setTransingFileName(const std::string &filename)
{
_fileNameMutex.lock();
_strFileName = filename;
_fileNameMutex.unlock();
}
bool FileServer::listenOnTCP(int port)
{
int listenfd, n;
const int on = 1;
struct addrinfo hints, *res, *ressave;
char serv[30];
snprintf(serv, sizeof(serv)-1, "%d", port );
serv[sizeof(serv)-1]=0;
bzero(&hints, sizeof(struct addrinfo));
hints.ai_flags = AI_PASSIVE;
hints.ai_family = AF_INET; // AF_UNSPEC: Do we need IPv6 ?
hints.ai_socktype = SOCK_STREAM;
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
WSADATA wsaData;
n = WSAStartup(MAKEWORD(2, 2),&wsaData);
#endif
if ( (n = getaddrinfo(NULL, serv, &hints, &res)) != 0) {
fprintf(stderr,"net_listen error for %s: %s", serv, gai_strerror(n));
return false;
}
ressave = res;
do {
listenfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
if (listenfd < 0)
continue; /* error, try next one */
setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, (const char*)&on, sizeof(on));
//setsockopt(listenfd, IPPROTO_TCP, TCP_NODELAY, (const char*)&on, sizeof(on));
auto address = ConfigParser::getInstance()->getBindAddress();
// bind address
if (address.length() > 0)
{
if (res->ai_family == AF_INET)
{
struct sockaddr_in *sin = (struct sockaddr_in*) res->ai_addr;
inet_pton(res->ai_family, address.c_str(), (void*)&sin->sin_addr);
}
else if (res->ai_family == AF_INET6)
{
struct sockaddr_in6 *sin = (struct sockaddr_in6*) res->ai_addr;
inet_pton(res->ai_family, address.c_str(), (void*)&sin->sin6_addr);
}
}
if (::bind(listenfd, res->ai_addr, res->ai_addrlen) == 0)
break; /* success */
/* bind error, close and try next one */
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
closesocket(listenfd);
#else
close(listenfd);
#endif
} while ((res = res->ai_next) != NULL);
if (res == NULL)
{
perror("net_listen:");
freeaddrinfo(ressave);
return false;
}
listen(listenfd, 1);
if (res->ai_family == AF_INET)
{
char buf[INET_ADDRSTRLEN] = "";
struct sockaddr_in *sin = (struct sockaddr_in*) res->ai_addr;
if( inet_ntop(res->ai_family, &sin->sin_addr, buf, sizeof(buf)) != NULL )
cocos2d::log("Console: listening on %s : %d", buf, ntohs(sin->sin_port));
else
perror("inet_ntop");
} else if (res->ai_family == AF_INET6)
{
char buf[INET6_ADDRSTRLEN] = "";
struct sockaddr_in6 *sin = (struct sockaddr_in6*) res->ai_addr;
if( inet_ntop(res->ai_family, &sin->sin6_addr, buf, sizeof(buf)) != NULL )
cocos2d::log("Console: listening on %s : %d", buf, ntohs(sin->sin6_port));
else
perror("inet_ntop");
}
freeaddrinfo(ressave);
_listenfd = listenfd;
_receiveThread = std::thread(std::bind( &FileServer::loopReceiveFile, this));
_writeThread = std::thread(std::bind(&FileServer::loopWriteFile, this));
_responseThread = std::thread(std::bind(&FileServer::loopResponse, this));
return true;
}
void FileServer::stop()
{
_receiveEndThread = true;
_writeEndThread = true;
_responseEndThread = true;
if(_receiveRunning)
{
_receiveThread.join();
}
if (_writeRunning)
{
_writeThread.join();
}
if (_responseRunning)
{
_responseThread.join();
}
}
FileServer::FileServer() :
_listenfd(-1),
_receiveRunning(false),
_receiveEndThread(false),
_writeRunning(false),
_writeEndThread(false),
_responseRunning(false),
_responseEndThread(false)
{
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS || CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
// need to be opened by Code IDE
_isUsingWritePath = false;
#else
_isUsingWritePath = true;
#endif
_writePath = FileUtils::getInstance()->getWritablePath();
#if (CC_TARGET_PLATFORM == CC_PLATFORM_MAC)
std::string getCurAppName(void);
_writePath += getCurAppName();
_writePath += "/";
#endif
_writePath += "debugruntime/";
_writePath = replaceAll(_writePath, "\\", "/");
if (_writePath.at(_writePath.length() - 1) != '/'){
_writePath.append("/");
}
}
FileServer::~FileServer()
{
stop();
}
void FileServer::loopReceiveFile()
{
struct sockaddr client;
socklen_t client_len;
/* new client */
client_len = sizeof(client);
int fd = accept(_listenfd, (struct sockaddr *)&client, &client_len );
char *protoBuf = new char[MAXPROTOLENGTH];
while(!_receiveEndThread) {
// recv start flag
char startflag[13] = {0};
recvBuf(fd, startflag, sizeof(startflag) - 1);
if (strcmp(startflag, PROTO_START) != 0)
{
continue;
}
// recv proto num
union
{
char char_type[3];
unsigned short uint16_type;
}protonum;
recvBuf(fd, protonum.char_type, sizeof(protonum.char_type) - 1);
//recv protobuf length
union
{
char char_type[3];
unsigned short uint16_type;
}protolength;
recvBuf(fd, protolength.char_type, sizeof(protolength.char_type) - 1);
//recv variable length
memset(protoBuf, 0, MAXPROTOLENGTH);
recvBuf(fd, protoBuf, protolength.uint16_type);
RecvBufStruct recvDataBuf;
recvDataBuf.fd = fd;
recvDataBuf.fileProto.ParseFromString(protoBuf);
if (1 == recvDataBuf.fileProto.package_seq())
{
_recvErrorFile = "";
} else
{
// recv error
if (_recvErrorFile == recvDataBuf.fileProto.file_name())
{
continue;
}
}
unsigned long contentSize = recvDataBuf.fileProto.content_size();
if (contentSize == 0)
{
recvDataBuf.contentBuf="";
_recvBufListMutex.lock();
_recvBufList.push_back(recvDataBuf);
_recvBufListMutex.unlock();
}else if(contentSize > 0)
{
//recv body data
Bytef *contentbuf = new Bytef[contentSize+1];
memset(contentbuf, 0, contentSize+1);
unsigned long recvTotalLen = contentSize;
while (recvTotalLen != 0){
unsigned long recvLen = MAXPROTOLENGTH;
if(recvTotalLen < MAXPROTOLENGTH)
recvLen = recvTotalLen;
memset(protoBuf, 0, MAXPROTOLENGTH);
unsigned long result = recv(fd, protoBuf, recvLen,0);
if (result <= 0)
{
usleep(1);
continue;
}
memcpy(contentbuf + contentSize - recvTotalLen, protoBuf, result);
recvTotalLen -= result;
}
if (recvDataBuf.fileProto.compress_type() == runtime::FileSendProtos_CompressType::FileSendProtos_CompressType_ZIP){
unsigned long uncompressSize = recvDataBuf.fileProto.uncompress_size();
Bytef *buff = new Bytef[uncompressSize * sizeof(Bytef)];
memset(buff, 0, uncompressSize * sizeof(Bytef));
int err = ::uncompress(buff, &uncompressSize,contentbuf, contentSize * sizeof(Bytef));
if (err != Z_OK){
CC_SAFE_DELETE_ARRAY(buff);
CC_SAFE_DELETE_ARRAY(contentbuf);
addResponse(recvDataBuf.fd, recvDataBuf.fileProto.file_name(), runtime::FileSendComplete::RESULTTYPE::FileSendComplete_RESULTTYPE_UNCOMPRESS_ERROR, err);
continue;
}
CC_SAFE_DELETE_ARRAY(contentbuf);
contentbuf = buff;
contentSize = uncompressSize;
}
recvDataBuf.contentBuf.assign((const char*)contentbuf, contentSize);
CC_SAFE_DELETE_ARRAY(contentbuf);
_recvBufListMutex.lock();
_recvBufList.push_back(recvDataBuf);
_recvBufListMutex.unlock();
}
}
_receiveRunning = false;
CC_SAFE_DELETE_ARRAY(protoBuf);
}
void FileServer::loopWriteFile()
{
_writeRunning = true;
while(!_writeEndThread)
{
_recvBufListMutex.lock();
size_t recvSize = _recvBufList.size();
_recvBufListMutex.unlock();
if(0 == recvSize)
{
usleep(500);
continue;
}
_recvBufListMutex.lock();
RecvBufStruct recvDataBuf = _recvBufList.front();
_recvBufList.pop_front();
_recvBufListMutex.unlock();
std::string filename = recvDataBuf.fileProto.file_name();
std::string fullfilename = _writePath;
fullfilename += filename;
_fileNameMutex.lock();
_strFileName = filename;
_fileNameMutex.unlock();
//cocos2d::log("WriteFile:: fullfilename = %s",filename.c_str());
createDir(fullfilename.substr(0, fullfilename.find_last_of("/")).c_str());
FILE *fp= nullptr;
if (1 == recvDataBuf.fileProto.package_seq())
{
_writeErrorFile ="";
fp = fopen(fullfilename.c_str(), "wb");
} else
{
if (_writeErrorFile == filename)
{
continue;
}
fp=fopen(fullfilename.c_str(), "ab");
}
if (nullptr == fp)
{
addResponse(recvDataBuf.fd, filename, runtime::FileSendComplete::RESULTTYPE::FileSendComplete_RESULTTYPE_FOPEN_ERROR, errno);
continue;
}
if (fp)
{
if (recvDataBuf.contentBuf.size() > 0 && 0 == fwrite(recvDataBuf.contentBuf.c_str(), sizeof(char), recvDataBuf.contentBuf.size(), fp))
{
addResponse(recvDataBuf.fd, filename, runtime::FileSendComplete::RESULTTYPE::FileSendComplete_RESULTTYPE_FWRITE_ERROR, errno);
fclose(fp);
continue;
}
fclose(fp);
}
if (1 == recvDataBuf.fileProto.package_seq())
{
//record new file modify
addResFileInfo(filename.c_str(), recvDataBuf.fileProto.modified_time());
addResponse(recvDataBuf.fd, filename, runtime::FileSendComplete::RESULTTYPE::FileSendComplete_RESULTTYPE_SUCCESS, 0);
}
}
_writeRunning = false;
}
void FileServer::addResponse(int fd, std::string filename, int errortype, int errornum)
{
switch (errortype)
{
case runtime::FileSendComplete::RESULTTYPE::FileSendComplete_RESULTTYPE_UNCOMPRESS_ERROR:
case runtime::FileSendComplete::RESULTTYPE::FileSendComplete_RESULTTYPE_RECV_ERROR:
_recvErrorFile = filename;
break;
case runtime::FileSendComplete::RESULTTYPE::FileSendComplete_RESULTTYPE_FOPEN_ERROR:
case runtime::FileSendComplete::RESULTTYPE::FileSendComplete_RESULTTYPE_FWRITE_ERROR:
_writeErrorFile = filename;
break;
default:
break;
}
ResponseStruct responseBuf;
responseBuf.fd = fd;
responseBuf.fileResponseProto.set_file_name(filename.c_str());
responseBuf.fileResponseProto.set_result((::runtime::FileSendComplete_RESULTTYPE)errortype);
responseBuf.fileResponseProto.set_error_num(errornum);
// push Response struct
_responseBufListMutex.lock();
_responseBufList.push_back(responseBuf);
_responseBufListMutex.unlock();
}
void FileServer::loopResponse()
{
_responseRunning = true;
while(!_responseEndThread) {
_responseBufListMutex.lock();
size_t responseSize = _responseBufList.size();
_responseBufListMutex.unlock();
if(0 == responseSize)
{
usleep(500);
/* error */
continue;
}
_responseBufListMutex.lock();
ResponseStruct responseBuf = _responseBufList.front();
_responseBufList.pop_front();
_responseBufListMutex.unlock();
//send response
std::string responseString;
runtime::FileSendComplete fileSendProtoComplete;
fileSendProtoComplete.set_file_name(responseBuf.fileResponseProto.file_name());
fileSendProtoComplete.set_result(responseBuf.fileResponseProto.result());
fileSendProtoComplete.set_error_num(responseBuf.fileResponseProto.error_num());
fileSendProtoComplete.SerializeToString(&responseString);
char dataBuf[1024] = {0};
struct ResponseHeaderStruct
{
char startFlag[12];
unsigned short protoNum;
unsigned short protoBufLen;
};
ResponseHeaderStruct responseHeader;
strcpy(responseHeader.startFlag, PROTO_START);
responseHeader.protoNum = PROTONUM::FILESENDCOMPLETE;
responseHeader.protoBufLen = (unsigned short) responseString.size();
memcpy(dataBuf, &responseHeader, sizeof(responseHeader));
memcpy(dataBuf + sizeof(responseHeader), responseString.c_str(), responseString.size());
sendBuf(responseBuf.fd, dataBuf, sizeof(responseHeader) + responseString.size());
cocos2d::log("responseFile:%s,result:%d", fileSendProtoComplete.file_name().c_str(), fileSendProtoComplete.result());
}
_responseRunning = false;
}
bool createDir(const char *sPathName)
{
char DirName[256]={0};
strcpy(DirName, sPathName);
size_t i, len = strlen(DirName);
if(DirName[len - 1] != '/')
{
strcat(DirName, "/");
}
len = strlen(DirName);
for(i = 1; i < len; i++)
{
if(DirName[i] == '/')
{
DirName[i] = 0;
#ifdef _WIN32
if(_access(DirName, 0) != 0)
{
if(_mkdir(DirName/*, 0755*/) == -1)
#else
if (access(DirName, 0) != 0)
{
if(mkdir(DirName, 0755) == -1)
#endif
{
perror("mkdir error");
return false;
}
}
DirName[i] = '/';
}
}
return true;
}

View File

@ -0,0 +1,136 @@
/****************************************************************************
Copyright (c) 2013 cocos2d-x.org
http://www.cocos2d-x.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#ifndef _FILE_SERVER__H_
#define _FILE_SERVER__H_
#include "cocos2d.h"
#include "json/document.h"
#include "json/filestream.h"
#include "json/stringbuffer.h"
#include "json/writer.h"
#include "Protos.pb.h"
#include <string>
// header files for socket
#ifdef _WIN32
#include <io.h>
#include <WS2tcpip.h>
#define bzero(a, b) memset(a, 0, b);
#else
#include <netdb.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/socket.h>
#endif
#ifdef _WIN32
#define usleep(t) Sleep(t)
#else
#include <unistd.h>
#endif
class FileServer
{
static FileServer *s_sharedFileServer;
public:
static FileServer* getShareInstance();
static void purge();
bool listenOnTCP(int port);
void stop();
void readResFileFinfo();
void addResFileInfo(const char* filename,uint64_t u64);
void removeResFileInfo(const char *filename);
rapidjson::Document* getFileCfgJson() { return &_filecfgjson; }
bool getIsUsingWritePath() { return _isUsingWritePath; }
void setIsUsingWritePath(bool use) { _isUsingWritePath = use; }
std::string getWritePath() { return _writePath; }
std::string getTransingFileName();
void setTransingFileName(const std::string& filename);
protected:
FileServer();
~FileServer();
private:
void loopReceiveFile();
void loopWriteFile();
void loopResponse();
void addResponse(int fd, std::string filename,int errortype,int errornum);
enum PROTONUM
{
FILEPROTO = 1,
FILESENDCOMPLETE = 2,
DIRPROTO = 3,
DIRSENDCOMPLETE = 4
};
struct RecvBufStruct
{
runtime::FileSendProtos fileProto;
std::string contentBuf;
int fd;
};
struct ResponseStruct
{
runtime::FileSendComplete fileResponseProto;
int fd;
};
// file descriptor: socket, console, etc.
int _listenfd;
std::thread _responseThread;
std::thread _receiveThread;
std::thread _writeThread;
bool _receiveRunning;
bool _receiveEndThread;
bool _writeRunning;
bool _writeEndThread;
bool _responseRunning;
bool _responseEndThread;
std::list<RecvBufStruct> _recvBufList;
std::list<ResponseStruct> _responseBufList;
std::mutex _recvBufListMutex;
std::mutex _responseBufListMutex;
rapidjson::Document _filecfgjson;
std::string _strFileName;
std::mutex _fileNameMutex;
std::string _recvErrorFile;
std::string _writeErrorFile;
bool _isUsingWritePath;
std::string _writePath;
};
bool createDir(const char *sPathName);
#endif // _FILE_SERVER__H_

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,838 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// source: Protos.proto
#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION
#include "Protos.pb.h"
#include <algorithm>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/once.h>
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/wire_format_lite_inl.h>
// @@protoc_insertion_point(includes)
namespace runtime {
void protobuf_ShutdownFile_Protos_2eproto() {
delete FileSendProtos::default_instance_;
delete FileSendComplete::default_instance_;
}
#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
void protobuf_AddDesc_Protos_2eproto_impl() {
GOOGLE_PROTOBUF_VERIFY_VERSION;
#else
void protobuf_AddDesc_Protos_2eproto() {
static bool already_here = false;
if (already_here) return;
already_here = true;
GOOGLE_PROTOBUF_VERIFY_VERSION;
#endif
FileSendProtos::default_instance_ = new FileSendProtos();
FileSendComplete::default_instance_ = new FileSendComplete();
FileSendProtos::default_instance_->InitAsDefaultInstance();
FileSendComplete::default_instance_->InitAsDefaultInstance();
::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_Protos_2eproto);
}
#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AddDesc_Protos_2eproto_once_);
void protobuf_AddDesc_Protos_2eproto() {
::google::protobuf::::google::protobuf::GoogleOnceInit(&protobuf_AddDesc_Protos_2eproto_once_,
&protobuf_AddDesc_Protos_2eproto_impl);
}
#else
// Force AddDescriptors() to be called at static initialization time.
struct StaticDescriptorInitializer_Protos_2eproto {
StaticDescriptorInitializer_Protos_2eproto() {
protobuf_AddDesc_Protos_2eproto();
}
} static_descriptor_initializer_Protos_2eproto_;
#endif
// ===================================================================
bool FileSendProtos_CompressType_IsValid(int value) {
switch(value) {
case 0:
case 1:
return true;
default:
return false;
}
}
#ifndef _MSC_VER
const FileSendProtos_CompressType FileSendProtos::NO_COMPRESS;
const FileSendProtos_CompressType FileSendProtos::ZIP;
const FileSendProtos_CompressType FileSendProtos::CompressType_MIN;
const FileSendProtos_CompressType FileSendProtos::CompressType_MAX;
const int FileSendProtos::CompressType_ARRAYSIZE;
#endif // _MSC_VER
bool FileSendProtos_VerifyMode_IsValid(int value) {
switch(value) {
case 0:
case 1:
case 2:
return true;
default:
return false;
}
}
#ifndef _MSC_VER
const FileSendProtos_VerifyMode FileSendProtos::NO_VERIFY;
const FileSendProtos_VerifyMode FileSendProtos::CRC;
const FileSendProtos_VerifyMode FileSendProtos::MD5;
const FileSendProtos_VerifyMode FileSendProtos::VerifyMode_MIN;
const FileSendProtos_VerifyMode FileSendProtos::VerifyMode_MAX;
const int FileSendProtos::VerifyMode_ARRAYSIZE;
#endif // _MSC_VER
#ifndef _MSC_VER
const int FileSendProtos::kFileNameFieldNumber;
const int FileSendProtos::kPackageSeqFieldNumber;
const int FileSendProtos::kPackageSumFieldNumber;
const int FileSendProtos::kContentSizeFieldNumber;
const int FileSendProtos::kCompressTypeFieldNumber;
const int FileSendProtos::kModifiedTimeFieldNumber;
const int FileSendProtos::kVerifyModeFieldNumber;
const int FileSendProtos::kVerifySignFieldNumber;
const int FileSendProtos::kUncompressSizeFieldNumber;
#endif // !_MSC_VER
FileSendProtos::FileSendProtos()
: ::google::protobuf::MessageLite() {
SharedCtor();
}
void FileSendProtos::InitAsDefaultInstance() {
}
FileSendProtos::FileSendProtos(const FileSendProtos& from)
: ::google::protobuf::MessageLite() {
SharedCtor();
MergeFrom(from);
}
void FileSendProtos::SharedCtor() {
_cached_size_ = 0;
file_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
package_seq_ = 0;
package_sum_ = 0;
content_size_ = GOOGLE_ULONGLONG(0);
compress_type_ = 0;
modified_time_ = GOOGLE_ULONGLONG(0);
verify_mode_ = 0;
verify_sign_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
uncompress_size_ = GOOGLE_ULONGLONG(0);
::memset(_has_bits_, 0, sizeof(_has_bits_));
}
FileSendProtos::~FileSendProtos() {
SharedDtor();
}
void FileSendProtos::SharedDtor() {
if (file_name_ != &::google::protobuf::internal::kEmptyString) {
delete file_name_;
}
if (verify_sign_ != &::google::protobuf::internal::kEmptyString) {
delete verify_sign_;
}
#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
if (this != &default_instance()) {
#else
if (this != default_instance_) {
#endif
}
}
void FileSendProtos::SetCachedSize(int size) const {
GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
_cached_size_ = size;
GOOGLE_SAFE_CONCURRENT_WRITES_END();
}
const FileSendProtos& FileSendProtos::default_instance() {
#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
protobuf_AddDesc_Protos_2eproto();
#else
if (default_instance_ == NULL) protobuf_AddDesc_Protos_2eproto();
#endif
return *default_instance_;
}
FileSendProtos* FileSendProtos::default_instance_ = NULL;
FileSendProtos* FileSendProtos::New() const {
return new FileSendProtos;
}
void FileSendProtos::Clear() {
if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
if (has_file_name()) {
if (file_name_ != &::google::protobuf::internal::kEmptyString) {
file_name_->clear();
}
}
package_seq_ = 0;
package_sum_ = 0;
content_size_ = GOOGLE_ULONGLONG(0);
compress_type_ = 0;
modified_time_ = GOOGLE_ULONGLONG(0);
verify_mode_ = 0;
if (has_verify_sign()) {
if (verify_sign_ != &::google::protobuf::internal::kEmptyString) {
verify_sign_->clear();
}
}
}
if (_has_bits_[8 / 32] & (0xffu << (8 % 32))) {
uncompress_size_ = GOOGLE_ULONGLONG(0);
}
::memset(_has_bits_, 0, sizeof(_has_bits_));
}
bool FileSendProtos::MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) {
#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
::google::protobuf::uint32 tag;
while ((tag = input->ReadTag()) != 0) {
switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
// required string file_name = 1;
case 1: {
if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
DO_(::google::protobuf::internal::WireFormatLite::ReadString(
input, this->mutable_file_name()));
} else {
goto handle_uninterpreted;
}
if (input->ExpectTag(16)) goto parse_package_seq;
break;
}
// required int32 package_seq = 2;
case 2: {
if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
parse_package_seq:
DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
input, &package_seq_)));
set_has_package_seq();
} else {
goto handle_uninterpreted;
}
if (input->ExpectTag(24)) goto parse_package_sum;
break;
}
// required int32 package_sum = 3;
case 3: {
if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
parse_package_sum:
DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
input, &package_sum_)));
set_has_package_sum();
} else {
goto handle_uninterpreted;
}
if (input->ExpectTag(32)) goto parse_content_size;
break;
}
// required uint64 content_size = 4;
case 4: {
if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
parse_content_size:
DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>(
input, &content_size_)));
set_has_content_size();
} else {
goto handle_uninterpreted;
}
if (input->ExpectTag(40)) goto parse_compress_type;
break;
}
// required .runtime.FileSendProtos.CompressType compress_type = 5;
case 5: {
if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
parse_compress_type:
int value;
DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
input, &value)));
if (::runtime::FileSendProtos_CompressType_IsValid(value)) {
set_compress_type(static_cast< ::runtime::FileSendProtos_CompressType >(value));
}
} else {
goto handle_uninterpreted;
}
if (input->ExpectTag(48)) goto parse_modified_time;
break;
}
// optional uint64 modified_time = 6;
case 6: {
if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
parse_modified_time:
DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>(
input, &modified_time_)));
set_has_modified_time();
} else {
goto handle_uninterpreted;
}
if (input->ExpectTag(56)) goto parse_verify_mode;
break;
}
// optional .runtime.FileSendProtos.VerifyMode verify_mode = 7;
case 7: {
if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
parse_verify_mode:
int value;
DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
input, &value)));
if (::runtime::FileSendProtos_VerifyMode_IsValid(value)) {
set_verify_mode(static_cast< ::runtime::FileSendProtos_VerifyMode >(value));
}
} else {
goto handle_uninterpreted;
}
if (input->ExpectTag(66)) goto parse_verify_sign;
break;
}
// optional string verify_sign = 8;
case 8: {
if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
parse_verify_sign:
DO_(::google::protobuf::internal::WireFormatLite::ReadString(
input, this->mutable_verify_sign()));
} else {
goto handle_uninterpreted;
}
if (input->ExpectTag(72)) goto parse_uncompress_size;
break;
}
// optional uint64 uncompress_size = 9;
case 9: {
if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
parse_uncompress_size:
DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>(
input, &uncompress_size_)));
set_has_uncompress_size();
} else {
goto handle_uninterpreted;
}
if (input->ExpectAtEnd()) return true;
break;
}
default: {
handle_uninterpreted:
if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
return true;
}
DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag));
break;
}
}
}
return true;
#undef DO_
}
void FileSendProtos::SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const {
// required string file_name = 1;
if (has_file_name()) {
::google::protobuf::internal::WireFormatLite::WriteString(
1, this->file_name(), output);
}
// required int32 package_seq = 2;
if (has_package_seq()) {
::google::protobuf::internal::WireFormatLite::WriteInt32(2, this->package_seq(), output);
}
// required int32 package_sum = 3;
if (has_package_sum()) {
::google::protobuf::internal::WireFormatLite::WriteInt32(3, this->package_sum(), output);
}
// required uint64 content_size = 4;
if (has_content_size()) {
::google::protobuf::internal::WireFormatLite::WriteUInt64(4, this->content_size(), output);
}
// required .runtime.FileSendProtos.CompressType compress_type = 5;
if (has_compress_type()) {
::google::protobuf::internal::WireFormatLite::WriteEnum(
5, this->compress_type(), output);
}
// optional uint64 modified_time = 6;
if (has_modified_time()) {
::google::protobuf::internal::WireFormatLite::WriteUInt64(6, this->modified_time(), output);
}
// optional .runtime.FileSendProtos.VerifyMode verify_mode = 7;
if (has_verify_mode()) {
::google::protobuf::internal::WireFormatLite::WriteEnum(
7, this->verify_mode(), output);
}
// optional string verify_sign = 8;
if (has_verify_sign()) {
::google::protobuf::internal::WireFormatLite::WriteString(
8, this->verify_sign(), output);
}
// optional uint64 uncompress_size = 9;
if (has_uncompress_size()) {
::google::protobuf::internal::WireFormatLite::WriteUInt64(9, this->uncompress_size(), output);
}
}
int FileSendProtos::ByteSize() const {
int total_size = 0;
if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
// required string file_name = 1;
if (has_file_name()) {
total_size += 1 +
::google::protobuf::internal::WireFormatLite::StringSize(
this->file_name());
}
// required int32 package_seq = 2;
if (has_package_seq()) {
total_size += 1 +
::google::protobuf::internal::WireFormatLite::Int32Size(
this->package_seq());
}
// required int32 package_sum = 3;
if (has_package_sum()) {
total_size += 1 +
::google::protobuf::internal::WireFormatLite::Int32Size(
this->package_sum());
}
// required uint64 content_size = 4;
if (has_content_size()) {
total_size += 1 +
::google::protobuf::internal::WireFormatLite::UInt64Size(
this->content_size());
}
// required .runtime.FileSendProtos.CompressType compress_type = 5;
if (has_compress_type()) {
total_size += 1 +
::google::protobuf::internal::WireFormatLite::EnumSize(this->compress_type());
}
// optional uint64 modified_time = 6;
if (has_modified_time()) {
total_size += 1 +
::google::protobuf::internal::WireFormatLite::UInt64Size(
this->modified_time());
}
// optional .runtime.FileSendProtos.VerifyMode verify_mode = 7;
if (has_verify_mode()) {
total_size += 1 +
::google::protobuf::internal::WireFormatLite::EnumSize(this->verify_mode());
}
// optional string verify_sign = 8;
if (has_verify_sign()) {
total_size += 1 +
::google::protobuf::internal::WireFormatLite::StringSize(
this->verify_sign());
}
}
if (_has_bits_[8 / 32] & (0xffu << (8 % 32))) {
// optional uint64 uncompress_size = 9;
if (has_uncompress_size()) {
total_size += 1 +
::google::protobuf::internal::WireFormatLite::UInt64Size(
this->uncompress_size());
}
}
GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
_cached_size_ = total_size;
GOOGLE_SAFE_CONCURRENT_WRITES_END();
return total_size;
}
void FileSendProtos::CheckTypeAndMergeFrom(
const ::google::protobuf::MessageLite& from) {
MergeFrom(*::google::protobuf::down_cast<const FileSendProtos*>(&from));
}
void FileSendProtos::MergeFrom(const FileSendProtos& from) {
GOOGLE_CHECK_NE(&from, this);
if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
if (from.has_file_name()) {
set_file_name(from.file_name());
}
if (from.has_package_seq()) {
set_package_seq(from.package_seq());
}
if (from.has_package_sum()) {
set_package_sum(from.package_sum());
}
if (from.has_content_size()) {
set_content_size(from.content_size());
}
if (from.has_compress_type()) {
set_compress_type(from.compress_type());
}
if (from.has_modified_time()) {
set_modified_time(from.modified_time());
}
if (from.has_verify_mode()) {
set_verify_mode(from.verify_mode());
}
if (from.has_verify_sign()) {
set_verify_sign(from.verify_sign());
}
}
if (from._has_bits_[8 / 32] & (0xffu << (8 % 32))) {
if (from.has_uncompress_size()) {
set_uncompress_size(from.uncompress_size());
}
}
}
void FileSendProtos::CopyFrom(const FileSendProtos& from) {
if (&from == this) return;
Clear();
MergeFrom(from);
}
bool FileSendProtos::IsInitialized() const {
if ((_has_bits_[0] & 0x0000001f) != 0x0000001f) return false;
return true;
}
void FileSendProtos::Swap(FileSendProtos* other) {
if (other != this) {
std::swap(file_name_, other->file_name_);
std::swap(package_seq_, other->package_seq_);
std::swap(package_sum_, other->package_sum_);
std::swap(content_size_, other->content_size_);
std::swap(compress_type_, other->compress_type_);
std::swap(modified_time_, other->modified_time_);
std::swap(verify_mode_, other->verify_mode_);
std::swap(verify_sign_, other->verify_sign_);
std::swap(uncompress_size_, other->uncompress_size_);
std::swap(_has_bits_[0], other->_has_bits_[0]);
std::swap(_cached_size_, other->_cached_size_);
}
}
::std::string FileSendProtos::GetTypeName() const {
return "runtime.FileSendProtos";
}
// ===================================================================
bool FileSendComplete_RESULTTYPE_IsValid(int value) {
switch(value) {
case 0:
case 1:
case 2:
case 3:
case 4:
return true;
default:
return false;
}
}
#ifndef _MSC_VER
const FileSendComplete_RESULTTYPE FileSendComplete::SUCCESS;
const FileSendComplete_RESULTTYPE FileSendComplete::RECV_ERROR;
const FileSendComplete_RESULTTYPE FileSendComplete::UNCOMPRESS_ERROR;
const FileSendComplete_RESULTTYPE FileSendComplete::FOPEN_ERROR;
const FileSendComplete_RESULTTYPE FileSendComplete::FWRITE_ERROR;
const FileSendComplete_RESULTTYPE FileSendComplete::RESULTTYPE_MIN;
const FileSendComplete_RESULTTYPE FileSendComplete::RESULTTYPE_MAX;
const int FileSendComplete::RESULTTYPE_ARRAYSIZE;
#endif // _MSC_VER
#ifndef _MSC_VER
const int FileSendComplete::kFileNameFieldNumber;
const int FileSendComplete::kResultFieldNumber;
const int FileSendComplete::kErrorNumFieldNumber;
#endif // !_MSC_VER
FileSendComplete::FileSendComplete()
: ::google::protobuf::MessageLite() {
SharedCtor();
}
void FileSendComplete::InitAsDefaultInstance() {
}
FileSendComplete::FileSendComplete(const FileSendComplete& from)
: ::google::protobuf::MessageLite() {
SharedCtor();
MergeFrom(from);
}
void FileSendComplete::SharedCtor() {
_cached_size_ = 0;
file_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
result_ = 0;
error_num_ = 0;
::memset(_has_bits_, 0, sizeof(_has_bits_));
}
FileSendComplete::~FileSendComplete() {
SharedDtor();
}
void FileSendComplete::SharedDtor() {
if (file_name_ != &::google::protobuf::internal::kEmptyString) {
delete file_name_;
}
#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
if (this != &default_instance()) {
#else
if (this != default_instance_) {
#endif
}
}
void FileSendComplete::SetCachedSize(int size) const {
GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
_cached_size_ = size;
GOOGLE_SAFE_CONCURRENT_WRITES_END();
}
const FileSendComplete& FileSendComplete::default_instance() {
#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
protobuf_AddDesc_Protos_2eproto();
#else
if (default_instance_ == NULL) protobuf_AddDesc_Protos_2eproto();
#endif
return *default_instance_;
}
FileSendComplete* FileSendComplete::default_instance_ = NULL;
FileSendComplete* FileSendComplete::New() const {
return new FileSendComplete;
}
void FileSendComplete::Clear() {
if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
if (has_file_name()) {
if (file_name_ != &::google::protobuf::internal::kEmptyString) {
file_name_->clear();
}
}
result_ = 0;
error_num_ = 0;
}
::memset(_has_bits_, 0, sizeof(_has_bits_));
}
bool FileSendComplete::MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input) {
#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
::google::protobuf::uint32 tag;
while ((tag = input->ReadTag()) != 0) {
switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
// required string file_name = 1;
case 1: {
if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
DO_(::google::protobuf::internal::WireFormatLite::ReadString(
input, this->mutable_file_name()));
} else {
goto handle_uninterpreted;
}
if (input->ExpectTag(16)) goto parse_result;
break;
}
// required .runtime.FileSendComplete.RESULTTYPE result = 2;
case 2: {
if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
parse_result:
int value;
DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
input, &value)));
if (::runtime::FileSendComplete_RESULTTYPE_IsValid(value)) {
set_result(static_cast< ::runtime::FileSendComplete_RESULTTYPE >(value));
}
} else {
goto handle_uninterpreted;
}
if (input->ExpectTag(24)) goto parse_error_num;
break;
}
// required int32 error_num = 3;
case 3: {
if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
parse_error_num:
DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
input, &error_num_)));
set_has_error_num();
} else {
goto handle_uninterpreted;
}
if (input->ExpectAtEnd()) return true;
break;
}
default: {
handle_uninterpreted:
if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
return true;
}
DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag));
break;
}
}
}
return true;
#undef DO_
}
void FileSendComplete::SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const {
// required string file_name = 1;
if (has_file_name()) {
::google::protobuf::internal::WireFormatLite::WriteString(
1, this->file_name(), output);
}
// required .runtime.FileSendComplete.RESULTTYPE result = 2;
if (has_result()) {
::google::protobuf::internal::WireFormatLite::WriteEnum(
2, this->result(), output);
}
// required int32 error_num = 3;
if (has_error_num()) {
::google::protobuf::internal::WireFormatLite::WriteInt32(3, this->error_num(), output);
}
}
int FileSendComplete::ByteSize() const {
int total_size = 0;
if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
// required string file_name = 1;
if (has_file_name()) {
total_size += 1 +
::google::protobuf::internal::WireFormatLite::StringSize(
this->file_name());
}
// required .runtime.FileSendComplete.RESULTTYPE result = 2;
if (has_result()) {
total_size += 1 +
::google::protobuf::internal::WireFormatLite::EnumSize(this->result());
}
// required int32 error_num = 3;
if (has_error_num()) {
total_size += 1 +
::google::protobuf::internal::WireFormatLite::Int32Size(
this->error_num());
}
}
GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
_cached_size_ = total_size;
GOOGLE_SAFE_CONCURRENT_WRITES_END();
return total_size;
}
void FileSendComplete::CheckTypeAndMergeFrom(
const ::google::protobuf::MessageLite& from) {
MergeFrom(*::google::protobuf::down_cast<const FileSendComplete*>(&from));
}
void FileSendComplete::MergeFrom(const FileSendComplete& from) {
GOOGLE_CHECK_NE(&from, this);
if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
if (from.has_file_name()) {
set_file_name(from.file_name());
}
if (from.has_result()) {
set_result(from.result());
}
if (from.has_error_num()) {
set_error_num(from.error_num());
}
}
}
void FileSendComplete::CopyFrom(const FileSendComplete& from) {
if (&from == this) return;
Clear();
MergeFrom(from);
}
bool FileSendComplete::IsInitialized() const {
if ((_has_bits_[0] & 0x00000007) != 0x00000007) return false;
return true;
}
void FileSendComplete::Swap(FileSendComplete* other) {
if (other != this) {
std::swap(file_name_, other->file_name_);
std::swap(result_, other->result_);
std::swap(error_num_, other->error_num_);
std::swap(_has_bits_[0], other->_has_bits_[0]);
std::swap(_cached_size_, other->_cached_size_);
}
}
::std::string FileSendComplete::GetTypeName() const {
return "runtime.FileSendComplete";
}
// @@protoc_insertion_point(namespace_scope)
} // namespace runtime
// @@protoc_insertion_point(global_scope)

View File

@ -0,0 +1,822 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// source: Protos.proto
#ifndef PROTOBUF_Protos_2eproto__INCLUDED
#define PROTOBUF_Protos_2eproto__INCLUDED
#include <string>
#include <google/protobuf/stubs/common.h>
#if GOOGLE_PROTOBUF_VERSION < 2005000
#error This file was generated by a newer version of protoc which is
#error incompatible with your Protocol Buffer headers. Please update
#error your headers.
#endif
#if 2005000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION
#error This file was generated by an older version of protoc which is
#error incompatible with your Protocol Buffer headers. Please
#error regenerate this file with a newer version of protoc.
#endif
#include <google/protobuf/generated_message_util.h>
#include <google/protobuf/message_lite.h>
#include <google/protobuf/repeated_field.h>
#include <google/protobuf/extension_set.h>
// @@protoc_insertion_point(includes)
namespace runtime {
// Internal implementation detail -- do not call these.
void protobuf_AddDesc_Protos_2eproto();
void protobuf_AssignDesc_Protos_2eproto();
void protobuf_ShutdownFile_Protos_2eproto();
class FileSendProtos;
class FileSendComplete;
enum FileSendProtos_CompressType {
FileSendProtos_CompressType_NO_COMPRESS = 0,
FileSendProtos_CompressType_ZIP = 1
};
bool FileSendProtos_CompressType_IsValid(int value);
const FileSendProtos_CompressType FileSendProtos_CompressType_CompressType_MIN = FileSendProtos_CompressType_NO_COMPRESS;
const FileSendProtos_CompressType FileSendProtos_CompressType_CompressType_MAX = FileSendProtos_CompressType_ZIP;
const int FileSendProtos_CompressType_CompressType_ARRAYSIZE = FileSendProtos_CompressType_CompressType_MAX + 1;
enum FileSendProtos_VerifyMode {
FileSendProtos_VerifyMode_NO_VERIFY = 0,
FileSendProtos_VerifyMode_CRC = 1,
FileSendProtos_VerifyMode_MD5 = 2
};
bool FileSendProtos_VerifyMode_IsValid(int value);
const FileSendProtos_VerifyMode FileSendProtos_VerifyMode_VerifyMode_MIN = FileSendProtos_VerifyMode_NO_VERIFY;
const FileSendProtos_VerifyMode FileSendProtos_VerifyMode_VerifyMode_MAX = FileSendProtos_VerifyMode_MD5;
const int FileSendProtos_VerifyMode_VerifyMode_ARRAYSIZE = FileSendProtos_VerifyMode_VerifyMode_MAX + 1;
enum FileSendComplete_RESULTTYPE {
FileSendComplete_RESULTTYPE_SUCCESS = 0,
FileSendComplete_RESULTTYPE_RECV_ERROR = 1,
FileSendComplete_RESULTTYPE_UNCOMPRESS_ERROR = 2,
FileSendComplete_RESULTTYPE_FOPEN_ERROR = 3,
FileSendComplete_RESULTTYPE_FWRITE_ERROR = 4
};
bool FileSendComplete_RESULTTYPE_IsValid(int value);
const FileSendComplete_RESULTTYPE FileSendComplete_RESULTTYPE_RESULTTYPE_MIN = FileSendComplete_RESULTTYPE_SUCCESS;
const FileSendComplete_RESULTTYPE FileSendComplete_RESULTTYPE_RESULTTYPE_MAX = FileSendComplete_RESULTTYPE_FWRITE_ERROR;
const int FileSendComplete_RESULTTYPE_RESULTTYPE_ARRAYSIZE = FileSendComplete_RESULTTYPE_RESULTTYPE_MAX + 1;
// ===================================================================
class FileSendProtos : public ::google::protobuf::MessageLite {
public:
FileSendProtos();
virtual ~FileSendProtos();
FileSendProtos(const FileSendProtos& from);
inline FileSendProtos& operator=(const FileSendProtos& from) {
CopyFrom(from);
return *this;
}
static const FileSendProtos& default_instance();
#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
// Returns the internal default instance pointer. This function can
// return NULL thus should not be used by the user. This is intended
// for Protobuf internal code. Please use default_instance() declared
// above instead.
static inline const FileSendProtos* internal_default_instance() {
return default_instance_;
}
#endif
void Swap(FileSendProtos* other);
// implements Message ----------------------------------------------
FileSendProtos* New() const;
void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
void CopyFrom(const FileSendProtos& from);
void MergeFrom(const FileSendProtos& from);
void Clear();
bool IsInitialized() const;
int ByteSize() const;
bool MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input);
void SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const;
int GetCachedSize() const { return _cached_size_; }
private:
void SharedCtor();
void SharedDtor();
void SetCachedSize(int size) const;
public:
::std::string GetTypeName() const;
// nested types ----------------------------------------------------
typedef FileSendProtos_CompressType CompressType;
static const CompressType NO_COMPRESS = FileSendProtos_CompressType_NO_COMPRESS;
static const CompressType ZIP = FileSendProtos_CompressType_ZIP;
static inline bool CompressType_IsValid(int value) {
return FileSendProtos_CompressType_IsValid(value);
}
static const CompressType CompressType_MIN =
FileSendProtos_CompressType_CompressType_MIN;
static const CompressType CompressType_MAX =
FileSendProtos_CompressType_CompressType_MAX;
static const int CompressType_ARRAYSIZE =
FileSendProtos_CompressType_CompressType_ARRAYSIZE;
typedef FileSendProtos_VerifyMode VerifyMode;
static const VerifyMode NO_VERIFY = FileSendProtos_VerifyMode_NO_VERIFY;
static const VerifyMode CRC = FileSendProtos_VerifyMode_CRC;
static const VerifyMode MD5 = FileSendProtos_VerifyMode_MD5;
static inline bool VerifyMode_IsValid(int value) {
return FileSendProtos_VerifyMode_IsValid(value);
}
static const VerifyMode VerifyMode_MIN =
FileSendProtos_VerifyMode_VerifyMode_MIN;
static const VerifyMode VerifyMode_MAX =
FileSendProtos_VerifyMode_VerifyMode_MAX;
static const int VerifyMode_ARRAYSIZE =
FileSendProtos_VerifyMode_VerifyMode_ARRAYSIZE;
// accessors -------------------------------------------------------
// required string file_name = 1;
inline bool has_file_name() const;
inline void clear_file_name();
static const int kFileNameFieldNumber = 1;
inline const ::std::string& file_name() const;
inline void set_file_name(const ::std::string& value);
inline void set_file_name(const char* value);
inline void set_file_name(const char* value, size_t size);
inline ::std::string* mutable_file_name();
inline ::std::string* release_file_name();
inline void set_allocated_file_name(::std::string* file_name);
// required int32 package_seq = 2;
inline bool has_package_seq() const;
inline void clear_package_seq();
static const int kPackageSeqFieldNumber = 2;
inline ::google::protobuf::int32 package_seq() const;
inline void set_package_seq(::google::protobuf::int32 value);
// required int32 package_sum = 3;
inline bool has_package_sum() const;
inline void clear_package_sum();
static const int kPackageSumFieldNumber = 3;
inline ::google::protobuf::int32 package_sum() const;
inline void set_package_sum(::google::protobuf::int32 value);
// required uint64 content_size = 4;
inline bool has_content_size() const;
inline void clear_content_size();
static const int kContentSizeFieldNumber = 4;
inline ::google::protobuf::uint64 content_size() const;
inline void set_content_size(::google::protobuf::uint64 value);
// required .runtime.FileSendProtos.CompressType compress_type = 5;
inline bool has_compress_type() const;
inline void clear_compress_type();
static const int kCompressTypeFieldNumber = 5;
inline ::runtime::FileSendProtos_CompressType compress_type() const;
inline void set_compress_type(::runtime::FileSendProtos_CompressType value);
// optional uint64 modified_time = 6;
inline bool has_modified_time() const;
inline void clear_modified_time();
static const int kModifiedTimeFieldNumber = 6;
inline ::google::protobuf::uint64 modified_time() const;
inline void set_modified_time(::google::protobuf::uint64 value);
// optional .runtime.FileSendProtos.VerifyMode verify_mode = 7;
inline bool has_verify_mode() const;
inline void clear_verify_mode();
static const int kVerifyModeFieldNumber = 7;
inline ::runtime::FileSendProtos_VerifyMode verify_mode() const;
inline void set_verify_mode(::runtime::FileSendProtos_VerifyMode value);
// optional string verify_sign = 8;
inline bool has_verify_sign() const;
inline void clear_verify_sign();
static const int kVerifySignFieldNumber = 8;
inline const ::std::string& verify_sign() const;
inline void set_verify_sign(const ::std::string& value);
inline void set_verify_sign(const char* value);
inline void set_verify_sign(const char* value, size_t size);
inline ::std::string* mutable_verify_sign();
inline ::std::string* release_verify_sign();
inline void set_allocated_verify_sign(::std::string* verify_sign);
// optional uint64 uncompress_size = 9;
inline bool has_uncompress_size() const;
inline void clear_uncompress_size();
static const int kUncompressSizeFieldNumber = 9;
inline ::google::protobuf::uint64 uncompress_size() const;
inline void set_uncompress_size(::google::protobuf::uint64 value);
// @@protoc_insertion_point(class_scope:runtime.FileSendProtos)
private:
inline void set_has_file_name();
inline void clear_has_file_name();
inline void set_has_package_seq();
inline void clear_has_package_seq();
inline void set_has_package_sum();
inline void clear_has_package_sum();
inline void set_has_content_size();
inline void clear_has_content_size();
inline void set_has_compress_type();
inline void clear_has_compress_type();
inline void set_has_modified_time();
inline void clear_has_modified_time();
inline void set_has_verify_mode();
inline void clear_has_verify_mode();
inline void set_has_verify_sign();
inline void clear_has_verify_sign();
inline void set_has_uncompress_size();
inline void clear_has_uncompress_size();
::std::string* file_name_;
::google::protobuf::int32 package_seq_;
::google::protobuf::int32 package_sum_;
::google::protobuf::uint64 content_size_;
::google::protobuf::uint64 modified_time_;
int compress_type_;
int verify_mode_;
::std::string* verify_sign_;
::google::protobuf::uint64 uncompress_size_;
mutable int _cached_size_;
::google::protobuf::uint32 _has_bits_[(9 + 31) / 32];
#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
friend void protobuf_AddDesc_Protos_2eproto_impl();
#else
friend void protobuf_AddDesc_Protos_2eproto();
#endif
friend void protobuf_AssignDesc_Protos_2eproto();
friend void protobuf_ShutdownFile_Protos_2eproto();
void InitAsDefaultInstance();
static FileSendProtos* default_instance_;
};
// -------------------------------------------------------------------
class FileSendComplete : public ::google::protobuf::MessageLite {
public:
FileSendComplete();
virtual ~FileSendComplete();
FileSendComplete(const FileSendComplete& from);
inline FileSendComplete& operator=(const FileSendComplete& from) {
CopyFrom(from);
return *this;
}
static const FileSendComplete& default_instance();
#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
// Returns the internal default instance pointer. This function can
// return NULL thus should not be used by the user. This is intended
// for Protobuf internal code. Please use default_instance() declared
// above instead.
static inline const FileSendComplete* internal_default_instance() {
return default_instance_;
}
#endif
void Swap(FileSendComplete* other);
// implements Message ----------------------------------------------
FileSendComplete* New() const;
void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);
void CopyFrom(const FileSendComplete& from);
void MergeFrom(const FileSendComplete& from);
void Clear();
bool IsInitialized() const;
int ByteSize() const;
bool MergePartialFromCodedStream(
::google::protobuf::io::CodedInputStream* input);
void SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const;
int GetCachedSize() const { return _cached_size_; }
private:
void SharedCtor();
void SharedDtor();
void SetCachedSize(int size) const;
public:
::std::string GetTypeName() const;
// nested types ----------------------------------------------------
typedef FileSendComplete_RESULTTYPE RESULTTYPE;
static const RESULTTYPE SUCCESS = FileSendComplete_RESULTTYPE_SUCCESS;
static const RESULTTYPE RECV_ERROR = FileSendComplete_RESULTTYPE_RECV_ERROR;
static const RESULTTYPE UNCOMPRESS_ERROR = FileSendComplete_RESULTTYPE_UNCOMPRESS_ERROR;
static const RESULTTYPE FOPEN_ERROR = FileSendComplete_RESULTTYPE_FOPEN_ERROR;
static const RESULTTYPE FWRITE_ERROR = FileSendComplete_RESULTTYPE_FWRITE_ERROR;
static inline bool RESULTTYPE_IsValid(int value) {
return FileSendComplete_RESULTTYPE_IsValid(value);
}
static const RESULTTYPE RESULTTYPE_MIN =
FileSendComplete_RESULTTYPE_RESULTTYPE_MIN;
static const RESULTTYPE RESULTTYPE_MAX =
FileSendComplete_RESULTTYPE_RESULTTYPE_MAX;
static const int RESULTTYPE_ARRAYSIZE =
FileSendComplete_RESULTTYPE_RESULTTYPE_ARRAYSIZE;
// accessors -------------------------------------------------------
// required string file_name = 1;
inline bool has_file_name() const;
inline void clear_file_name();
static const int kFileNameFieldNumber = 1;
inline const ::std::string& file_name() const;
inline void set_file_name(const ::std::string& value);
inline void set_file_name(const char* value);
inline void set_file_name(const char* value, size_t size);
inline ::std::string* mutable_file_name();
inline ::std::string* release_file_name();
inline void set_allocated_file_name(::std::string* file_name);
// required .runtime.FileSendComplete.RESULTTYPE result = 2;
inline bool has_result() const;
inline void clear_result();
static const int kResultFieldNumber = 2;
inline ::runtime::FileSendComplete_RESULTTYPE result() const;
inline void set_result(::runtime::FileSendComplete_RESULTTYPE value);
// required int32 error_num = 3;
inline bool has_error_num() const;
inline void clear_error_num();
static const int kErrorNumFieldNumber = 3;
inline ::google::protobuf::int32 error_num() const;
inline void set_error_num(::google::protobuf::int32 value);
// @@protoc_insertion_point(class_scope:runtime.FileSendComplete)
private:
inline void set_has_file_name();
inline void clear_has_file_name();
inline void set_has_result();
inline void clear_has_result();
inline void set_has_error_num();
inline void clear_has_error_num();
::std::string* file_name_;
int result_;
::google::protobuf::int32 error_num_;
mutable int _cached_size_;
::google::protobuf::uint32 _has_bits_[(3 + 31) / 32];
#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
friend void protobuf_AddDesc_Protos_2eproto_impl();
#else
friend void protobuf_AddDesc_Protos_2eproto();
#endif
friend void protobuf_AssignDesc_Protos_2eproto();
friend void protobuf_ShutdownFile_Protos_2eproto();
void InitAsDefaultInstance();
static FileSendComplete* default_instance_;
};
// ===================================================================
// ===================================================================
// FileSendProtos
// required string file_name = 1;
inline bool FileSendProtos::has_file_name() const {
return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void FileSendProtos::set_has_file_name() {
_has_bits_[0] |= 0x00000001u;
}
inline void FileSendProtos::clear_has_file_name() {
_has_bits_[0] &= ~0x00000001u;
}
inline void FileSendProtos::clear_file_name() {
if (file_name_ != &::google::protobuf::internal::kEmptyString) {
file_name_->clear();
}
clear_has_file_name();
}
inline const ::std::string& FileSendProtos::file_name() const {
return *file_name_;
}
inline void FileSendProtos::set_file_name(const ::std::string& value) {
set_has_file_name();
if (file_name_ == &::google::protobuf::internal::kEmptyString) {
file_name_ = new ::std::string;
}
file_name_->assign(value);
}
inline void FileSendProtos::set_file_name(const char* value) {
set_has_file_name();
if (file_name_ == &::google::protobuf::internal::kEmptyString) {
file_name_ = new ::std::string;
}
file_name_->assign(value);
}
inline void FileSendProtos::set_file_name(const char* value, size_t size) {
set_has_file_name();
if (file_name_ == &::google::protobuf::internal::kEmptyString) {
file_name_ = new ::std::string;
}
file_name_->assign(reinterpret_cast<const char*>(value), size);
}
inline ::std::string* FileSendProtos::mutable_file_name() {
set_has_file_name();
if (file_name_ == &::google::protobuf::internal::kEmptyString) {
file_name_ = new ::std::string;
}
return file_name_;
}
inline ::std::string* FileSendProtos::release_file_name() {
clear_has_file_name();
if (file_name_ == &::google::protobuf::internal::kEmptyString) {
return NULL;
} else {
::std::string* temp = file_name_;
file_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
return temp;
}
}
inline void FileSendProtos::set_allocated_file_name(::std::string* file_name) {
if (file_name_ != &::google::protobuf::internal::kEmptyString) {
delete file_name_;
}
if (file_name) {
set_has_file_name();
file_name_ = file_name;
} else {
clear_has_file_name();
file_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
}
}
// required int32 package_seq = 2;
inline bool FileSendProtos::has_package_seq() const {
return (_has_bits_[0] & 0x00000002u) != 0;
}
inline void FileSendProtos::set_has_package_seq() {
_has_bits_[0] |= 0x00000002u;
}
inline void FileSendProtos::clear_has_package_seq() {
_has_bits_[0] &= ~0x00000002u;
}
inline void FileSendProtos::clear_package_seq() {
package_seq_ = 0;
clear_has_package_seq();
}
inline ::google::protobuf::int32 FileSendProtos::package_seq() const {
return package_seq_;
}
inline void FileSendProtos::set_package_seq(::google::protobuf::int32 value) {
set_has_package_seq();
package_seq_ = value;
}
// required int32 package_sum = 3;
inline bool FileSendProtos::has_package_sum() const {
return (_has_bits_[0] & 0x00000004u) != 0;
}
inline void FileSendProtos::set_has_package_sum() {
_has_bits_[0] |= 0x00000004u;
}
inline void FileSendProtos::clear_has_package_sum() {
_has_bits_[0] &= ~0x00000004u;
}
inline void FileSendProtos::clear_package_sum() {
package_sum_ = 0;
clear_has_package_sum();
}
inline ::google::protobuf::int32 FileSendProtos::package_sum() const {
return package_sum_;
}
inline void FileSendProtos::set_package_sum(::google::protobuf::int32 value) {
set_has_package_sum();
package_sum_ = value;
}
// required uint64 content_size = 4;
inline bool FileSendProtos::has_content_size() const {
return (_has_bits_[0] & 0x00000008u) != 0;
}
inline void FileSendProtos::set_has_content_size() {
_has_bits_[0] |= 0x00000008u;
}
inline void FileSendProtos::clear_has_content_size() {
_has_bits_[0] &= ~0x00000008u;
}
inline void FileSendProtos::clear_content_size() {
content_size_ = GOOGLE_ULONGLONG(0);
clear_has_content_size();
}
inline ::google::protobuf::uint64 FileSendProtos::content_size() const {
return content_size_;
}
inline void FileSendProtos::set_content_size(::google::protobuf::uint64 value) {
set_has_content_size();
content_size_ = value;
}
// required .runtime.FileSendProtos.CompressType compress_type = 5;
inline bool FileSendProtos::has_compress_type() const {
return (_has_bits_[0] & 0x00000010u) != 0;
}
inline void FileSendProtos::set_has_compress_type() {
_has_bits_[0] |= 0x00000010u;
}
inline void FileSendProtos::clear_has_compress_type() {
_has_bits_[0] &= ~0x00000010u;
}
inline void FileSendProtos::clear_compress_type() {
compress_type_ = 0;
clear_has_compress_type();
}
inline ::runtime::FileSendProtos_CompressType FileSendProtos::compress_type() const {
return static_cast< ::runtime::FileSendProtos_CompressType >(compress_type_);
}
inline void FileSendProtos::set_compress_type(::runtime::FileSendProtos_CompressType value) {
assert(::runtime::FileSendProtos_CompressType_IsValid(value));
set_has_compress_type();
compress_type_ = value;
}
// optional uint64 modified_time = 6;
inline bool FileSendProtos::has_modified_time() const {
return (_has_bits_[0] & 0x00000020u) != 0;
}
inline void FileSendProtos::set_has_modified_time() {
_has_bits_[0] |= 0x00000020u;
}
inline void FileSendProtos::clear_has_modified_time() {
_has_bits_[0] &= ~0x00000020u;
}
inline void FileSendProtos::clear_modified_time() {
modified_time_ = GOOGLE_ULONGLONG(0);
clear_has_modified_time();
}
inline ::google::protobuf::uint64 FileSendProtos::modified_time() const {
return modified_time_;
}
inline void FileSendProtos::set_modified_time(::google::protobuf::uint64 value) {
set_has_modified_time();
modified_time_ = value;
}
// optional .runtime.FileSendProtos.VerifyMode verify_mode = 7;
inline bool FileSendProtos::has_verify_mode() const {
return (_has_bits_[0] & 0x00000040u) != 0;
}
inline void FileSendProtos::set_has_verify_mode() {
_has_bits_[0] |= 0x00000040u;
}
inline void FileSendProtos::clear_has_verify_mode() {
_has_bits_[0] &= ~0x00000040u;
}
inline void FileSendProtos::clear_verify_mode() {
verify_mode_ = 0;
clear_has_verify_mode();
}
inline ::runtime::FileSendProtos_VerifyMode FileSendProtos::verify_mode() const {
return static_cast< ::runtime::FileSendProtos_VerifyMode >(verify_mode_);
}
inline void FileSendProtos::set_verify_mode(::runtime::FileSendProtos_VerifyMode value) {
assert(::runtime::FileSendProtos_VerifyMode_IsValid(value));
set_has_verify_mode();
verify_mode_ = value;
}
// optional string verify_sign = 8;
inline bool FileSendProtos::has_verify_sign() const {
return (_has_bits_[0] & 0x00000080u) != 0;
}
inline void FileSendProtos::set_has_verify_sign() {
_has_bits_[0] |= 0x00000080u;
}
inline void FileSendProtos::clear_has_verify_sign() {
_has_bits_[0] &= ~0x00000080u;
}
inline void FileSendProtos::clear_verify_sign() {
if (verify_sign_ != &::google::protobuf::internal::kEmptyString) {
verify_sign_->clear();
}
clear_has_verify_sign();
}
inline const ::std::string& FileSendProtos::verify_sign() const {
return *verify_sign_;
}
inline void FileSendProtos::set_verify_sign(const ::std::string& value) {
set_has_verify_sign();
if (verify_sign_ == &::google::protobuf::internal::kEmptyString) {
verify_sign_ = new ::std::string;
}
verify_sign_->assign(value);
}
inline void FileSendProtos::set_verify_sign(const char* value) {
set_has_verify_sign();
if (verify_sign_ == &::google::protobuf::internal::kEmptyString) {
verify_sign_ = new ::std::string;
}
verify_sign_->assign(value);
}
inline void FileSendProtos::set_verify_sign(const char* value, size_t size) {
set_has_verify_sign();
if (verify_sign_ == &::google::protobuf::internal::kEmptyString) {
verify_sign_ = new ::std::string;
}
verify_sign_->assign(reinterpret_cast<const char*>(value), size);
}
inline ::std::string* FileSendProtos::mutable_verify_sign() {
set_has_verify_sign();
if (verify_sign_ == &::google::protobuf::internal::kEmptyString) {
verify_sign_ = new ::std::string;
}
return verify_sign_;
}
inline ::std::string* FileSendProtos::release_verify_sign() {
clear_has_verify_sign();
if (verify_sign_ == &::google::protobuf::internal::kEmptyString) {
return NULL;
} else {
::std::string* temp = verify_sign_;
verify_sign_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
return temp;
}
}
inline void FileSendProtos::set_allocated_verify_sign(::std::string* verify_sign) {
if (verify_sign_ != &::google::protobuf::internal::kEmptyString) {
delete verify_sign_;
}
if (verify_sign) {
set_has_verify_sign();
verify_sign_ = verify_sign;
} else {
clear_has_verify_sign();
verify_sign_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
}
}
// optional uint64 uncompress_size = 9;
inline bool FileSendProtos::has_uncompress_size() const {
return (_has_bits_[0] & 0x00000100u) != 0;
}
inline void FileSendProtos::set_has_uncompress_size() {
_has_bits_[0] |= 0x00000100u;
}
inline void FileSendProtos::clear_has_uncompress_size() {
_has_bits_[0] &= ~0x00000100u;
}
inline void FileSendProtos::clear_uncompress_size() {
uncompress_size_ = GOOGLE_ULONGLONG(0);
clear_has_uncompress_size();
}
inline ::google::protobuf::uint64 FileSendProtos::uncompress_size() const {
return uncompress_size_;
}
inline void FileSendProtos::set_uncompress_size(::google::protobuf::uint64 value) {
set_has_uncompress_size();
uncompress_size_ = value;
}
// -------------------------------------------------------------------
// FileSendComplete
// required string file_name = 1;
inline bool FileSendComplete::has_file_name() const {
return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void FileSendComplete::set_has_file_name() {
_has_bits_[0] |= 0x00000001u;
}
inline void FileSendComplete::clear_has_file_name() {
_has_bits_[0] &= ~0x00000001u;
}
inline void FileSendComplete::clear_file_name() {
if (file_name_ != &::google::protobuf::internal::kEmptyString) {
file_name_->clear();
}
clear_has_file_name();
}
inline const ::std::string& FileSendComplete::file_name() const {
return *file_name_;
}
inline void FileSendComplete::set_file_name(const ::std::string& value) {
set_has_file_name();
if (file_name_ == &::google::protobuf::internal::kEmptyString) {
file_name_ = new ::std::string;
}
file_name_->assign(value);
}
inline void FileSendComplete::set_file_name(const char* value) {
set_has_file_name();
if (file_name_ == &::google::protobuf::internal::kEmptyString) {
file_name_ = new ::std::string;
}
file_name_->assign(value);
}
inline void FileSendComplete::set_file_name(const char* value, size_t size) {
set_has_file_name();
if (file_name_ == &::google::protobuf::internal::kEmptyString) {
file_name_ = new ::std::string;
}
file_name_->assign(reinterpret_cast<const char*>(value), size);
}
inline ::std::string* FileSendComplete::mutable_file_name() {
set_has_file_name();
if (file_name_ == &::google::protobuf::internal::kEmptyString) {
file_name_ = new ::std::string;
}
return file_name_;
}
inline ::std::string* FileSendComplete::release_file_name() {
clear_has_file_name();
if (file_name_ == &::google::protobuf::internal::kEmptyString) {
return NULL;
} else {
::std::string* temp = file_name_;
file_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
return temp;
}
}
inline void FileSendComplete::set_allocated_file_name(::std::string* file_name) {
if (file_name_ != &::google::protobuf::internal::kEmptyString) {
delete file_name_;
}
if (file_name) {
set_has_file_name();
file_name_ = file_name;
} else {
clear_has_file_name();
file_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
}
}
// required .runtime.FileSendComplete.RESULTTYPE result = 2;
inline bool FileSendComplete::has_result() const {
return (_has_bits_[0] & 0x00000002u) != 0;
}
inline void FileSendComplete::set_has_result() {
_has_bits_[0] |= 0x00000002u;
}
inline void FileSendComplete::clear_has_result() {
_has_bits_[0] &= ~0x00000002u;
}
inline void FileSendComplete::clear_result() {
result_ = 0;
clear_has_result();
}
inline ::runtime::FileSendComplete_RESULTTYPE FileSendComplete::result() const {
return static_cast< ::runtime::FileSendComplete_RESULTTYPE >(result_);
}
inline void FileSendComplete::set_result(::runtime::FileSendComplete_RESULTTYPE value) {
assert(::runtime::FileSendComplete_RESULTTYPE_IsValid(value));
set_has_result();
result_ = value;
}
// required int32 error_num = 3;
inline bool FileSendComplete::has_error_num() const {
return (_has_bits_[0] & 0x00000004u) != 0;
}
inline void FileSendComplete::set_has_error_num() {
_has_bits_[0] |= 0x00000004u;
}
inline void FileSendComplete::clear_has_error_num() {
_has_bits_[0] &= ~0x00000004u;
}
inline void FileSendComplete::clear_error_num() {
error_num_ = 0;
clear_has_error_num();
}
inline ::google::protobuf::int32 FileSendComplete::error_num() const {
return error_num_;
}
inline void FileSendComplete::set_error_num(::google::protobuf::int32 value) {
set_has_error_num();
error_num_ = value;
}
// @@protoc_insertion_point(namespace_scope)
} // namespace runtime
// @@protoc_insertion_point(global_scope)
#endif // PROTOBUF_Protos_2eproto__INCLUDED

View File

@ -0,0 +1,9 @@
#ifndef _RESDATA__H_
#define _RESDATA__H_
extern const unsigned char __shinePngData[11776];
extern const unsigned char __portraitPngData[122214];
extern const unsigned char __playEnablePngData[20254];
extern const unsigned char __landscapePngData[115832];
#endif // _RESDATA__H_

View File

@ -0,0 +1,385 @@
/****************************************************************************
Copyright (c) 2013 cocos2d-x.org
http://www.cocos2d-x.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "Runtime.h"
#include "FileServer.h"
#include "ConnectWaitLayer.h"
#include "ConsoleCommand.h"
#include "cocos2d.h"
#include "ConfigParser.h"
#include "RuntimeCCSImpl.h" // TODO: move to ide-support
#if ((CC_TARGET_PLATFORM == CC_PLATFORM_WIN32) || (CC_TARGET_PLATFORM == CC_PLATFORM_MAC))
#include "DeviceEx.h"
#include "network/CCHTTPRequest.h"
#include "xxhash/xxhash.h"
#endif
std::string g_projectPath;
void recvBuf(int fd, char *pbuf, unsigned long bufsize)
{
unsigned long leftLength = bufsize;
while (leftLength != 0)
{
size_t recvlen = recv(fd, pbuf + bufsize - leftLength, leftLength ,0);
if (recvlen <= 0)
{
usleep(1);
continue;
}
leftLength -= recvlen;
}
}
void sendBuf(int fd, const char *pbuf, unsigned long bufsize)
{
unsigned long leftLength = bufsize;
while (leftLength != 0)
{
size_t sendlen = send(fd, pbuf + bufsize - leftLength, leftLength ,0);
if (sendlen <= 0)
{
usleep(1);
continue;
}
leftLength -= sendlen;
}
}
std::string& replaceAll(std::string& str, const std::string& old_value, const std::string& new_value)
{
size_t start = 0;
while(true)
{
size_t pos = 0;
if((pos = str.find(old_value, start)) != std::string::npos) {
str.replace(pos, old_value.length(), new_value);
start = pos + new_value.length();
}
else break;
}
return str;
}
const char* getRuntimeVersion()
{
return "2.0";
}
//////////////////////// Loader ////////////////////
void resetDesignResolution()
{
cocos2d::Size size = ConfigParser::getInstance()->getInitViewSize();
if (!ConfigParser::getInstance()->isLanscape())
{
std::swap(size.width, size.height);
}
Director::getInstance()->getOpenGLView()->setDesignResolutionSize(size.width, size.height, ResolutionPolicy::EXACT_FIT);
}
//
// RuntimeEngine
//
RuntimeEngine::RuntimeEngine()
: _runtime(nullptr)
, _eventTrackingEnable(false)
, _launchEvent("empty")
{
}
RuntimeEngine* RuntimeEngine::getInstance()
{
static RuntimeEngine *instance = nullptr;
if (!instance)
{
instance = new RuntimeEngine();
instance->addRuntime(RuntimeCCSImpl::create(), kRuntimeEngineCCS);
}
return instance;
}
void RuntimeEngine::setupRuntime()
{
//
// 1. get project type fron config.json
// 2. init Lua / Js runtime
//
updateConfigParser();
auto entryFile = ConfigParser::getInstance()->getEntryFile();
#if (CC_TARGET_PLATFORM != CC_PLATFORM_WIN32) && (CC_TARGET_PLATFORM != CC_PLATFORM_MAC)
ConfigParser::getInstance()->readConfig();
entryFile = ConfigParser::getInstance()->getEntryFile();
#endif
// Lua
if ((entryFile.rfind(".lua") != std::string::npos) ||
(entryFile.rfind(".luac") != std::string::npos))
{
_launchEvent = "lua";
_runtime = _runtimes[kRuntimeEngineLua];
}
// Js
else if ((entryFile.rfind(".js") != std::string::npos) ||
(entryFile.rfind(".jsc") != std::string::npos))
{
_launchEvent = "js";
_runtime = _runtimes[kRuntimeEngineJs];
}
// csb
else if ((entryFile.rfind(".csb") != std::string::npos))
{
_launchEvent = "ccs";
_runtime = _runtimes[kRuntimeEngineCCS];
}
// csd
else if ((entryFile.rfind(".csd") != std::string::npos))
{
_launchEvent = "ccs";
_runtime = _runtimes[kRuntimeEngineCCS];
}
}
void RuntimeEngine::setProjectConfig(const ProjectConfig &config)
{
_project = config;
setProjectPath(_project.getProjectDir());
}
const ProjectConfig &RuntimeEngine::getProjectConfig()
{
return _project;
}
void RuntimeEngine::setProjectPath(const std::string &workPath)
{
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32 || CC_TARGET_PLATFORM == CC_PLATFORM_MAC)
vector<std::string> searchPathArray = FileUtils::getInstance()->getSearchPaths();
if (workPath.empty())
{
extern std::string getCurAppPath();
std::string appPath = getCurAppPath();
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
appPath.append("/../../");
#elif (CC_TARGET_PLATFORM == CC_PLATFORM_MAC)
appPath.append("/../../../");
#endif
appPath = replaceAll(appPath, "\\", "/");
g_projectPath = appPath;
}
else
{
g_projectPath = workPath;
}
// add project's root directory to search path
searchPathArray.insert(searchPathArray.begin(), g_projectPath);
// add writable path to search path
searchPathArray.insert(searchPathArray.begin(), FileServer::getShareInstance()->getWritePath());
FileUtils::getInstance()->setSearchPaths(searchPathArray);
#endif
}
void RuntimeEngine::startScript(const std::string &args)
{
resetDesignResolution();
if (_runtime)
{
_runtime->startScript(args);
}
trackLaunchEvent();
}
void RuntimeEngine::start()
{
#if (CC_TARGET_PLATFORM != CC_PLATFORM_WIN32) && (CC_TARGET_PLATFORM != CC_PLATFORM_MAC)
_project.setDebuggerType(kCCRuntimeDebuggerCodeIDE);
#endif
// set search path
string path = FileUtils::getInstance()->fullPathForFilename(_project.getScriptFileRealPath().c_str());
size_t pos;
while ((pos = path.find_first_of("\\")) != std::string::npos)
{
path.replace(pos, 1, "/");
}
size_t p = path.find_last_of("/");
string workdir;
if (p != path.npos)
{
workdir = path.substr(0, p);
FileUtils::getInstance()->addSearchPath(workdir);
}
// update search pathes
FileUtils::getInstance()->addSearchPath(_project.getProjectDir());
auto &customizedPathes = _project.getSearchPath();
for (auto &path : customizedPathes)
{
FileUtils::getInstance()->addSearchPath(path);
}
//
if (_project.getDebuggerType() == kCCRuntimeDebuggerNone)
{
setupRuntime();
startScript(_project.getScriptFileRealPath());
}
else
{
startNetwork();
}
}
void RuntimeEngine::end()
{
if (_runtime)
{
_runtime->end();
}
// delete all runtimes
for (auto it = _runtimes.begin(); it != _runtimes.end(); it++)
{
CC_SAFE_DELETE(it->second);
}
ConsoleCommand::purge();
FileServer::getShareInstance()->stop();
ConfigParser::purge();
// FileServer::purge();
}
void RuntimeEngine::setEventTrackingEnable(bool enable)
{
_eventTrackingEnable = enable;
}
void RuntimeEngine::addRuntime(RuntimeProtocol *runtime, int type)
{
if (_runtimes.find(type) == _runtimes.end())
{
_runtimes.insert(std::make_pair(type, runtime));
}
else
{
CCLOG("RuntimeEngine already has Runtime type %d.", type);
}
}
RuntimeProtocol* RuntimeEngine::getRuntime()
{
return _runtime;
}
//
// private
//
void RuntimeEngine::showUI()
{
auto scene = Scene::create();
auto connectLayer = new ConnectWaitLayer();
connectLayer->autorelease();
auto director = Director::getInstance();
scene->addChild(connectLayer);
director->runWithScene(scene);
}
bool RuntimeEngine::startNetwork()
{
ConsoleCommand::getShareInstance()->init();
showUI();
return true;
}
void RuntimeEngine::updateConfigParser()
{
// set entry file
auto parser = ConfigParser::getInstance();
string entryFile(_project.getScriptFileRealPath());
if (entryFile.find(_project.getProjectDir()) != string::npos)
{
entryFile.erase(0, _project.getProjectDir().length());
}
std::replace(entryFile.begin(), entryFile.end(), '\\', '/');
parser->setEntryFile(entryFile);
parser->setBindAddress(_project.getBindAddress());
}
//
// NOTE: track event on windows / mac platform
//
void RuntimeEngine::trackEvent(const std::string &eventName)
{
if (!_eventTrackingEnable)
{
return ;
}
#if ((CC_TARGET_PLATFORM == CC_PLATFORM_WIN32) || (CC_TARGET_PLATFORM == CC_PLATFORM_MAC))
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
const char *platform = "win";
#elif (CC_TARGET_PLATFORM == CC_PLATFORM_MAC)
const char *platform = "mac";
#else
const char *platform = "UNKNOWN";
#endif
char cidBuf[64] = {0};
auto guid = player::DeviceEx::getInstance()->getUserGUID();
snprintf(cidBuf, sizeof(cidBuf), "%x", XXH32(guid.c_str(), (int)guid.length(), 0));
auto request = extra::HTTPRequest::createWithUrl(NULL,
"http://www.google-analytics.com/collect",
kCCHTTPRequestMethodPOST);
request->addPOSTValue("v", "1");
request->addPOSTValue("tid", "UA-58200293-1");
request->addPOSTValue("cid", cidBuf);
request->addPOSTValue("t", "event");
request->addPOSTValue("an", "simulator");
request->addPOSTValue("av", cocos2dVersion());
request->addPOSTValue("ec", platform);
request->addPOSTValue("ea", eventName.c_str());
request->start();
#endif // ((CC_TARGET_PLATFORM == CC_PLATFORM_WIN32) || (CC_TARGET_PLATFORM == CC_PLATFORM_MAC))
}
void RuntimeEngine::trackLaunchEvent()
{
trackEvent(_launchEvent);
}

View File

@ -0,0 +1,92 @@
/****************************************************************************
Copyright (c) 2013 cocos2d-x.org
http://www.cocos2d-x.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#ifndef _RUNTIME__H_
#define _RUNTIME__H_
#include <string>
#include <functional>
#include <unordered_map>
void recvBuf(int fd, char *pbuf, unsigned long bufsize);
void sendBuf(int fd, const char *pbuf, unsigned long bufsize);
std::string& replaceAll(std::string& str, const std::string& old_value, const std::string& new_value);
std::string getIPAddress();
const char* getRuntimeVersion();
//
void resetDesignResolution();
const char* getRuntimeVersion();
//
// RuntimeEngine
//
#include "ProjectConfig/ProjectConfig.h"
#define kRuntimeEngineLua 1
#define kRuntimeEngineJs 2
#define kRuntimeEngineCCS 4
class RuntimeProtocol;
class RuntimeEngine
{
public:
static RuntimeEngine* getInstance();
//
void setupRuntime();
void setProjectConfig(const ProjectConfig &config);
void setProjectPath(const std::string &path);
const ProjectConfig &getProjectConfig();
void startScript(const std::string &args);
void start();
void end();
void setEventTrackingEnable(bool enable);
void addRuntime(RuntimeProtocol *runtime, int type);
RuntimeProtocol *getRuntime();
private:
RuntimeEngine();
bool startNetwork();
void showUI();
void updateConfigParser();
//
void trackEvent(const std::string &eventName);
void trackLaunchEvent();
RuntimeProtocol *_runtime; // weak ref
ProjectConfig _project;
bool _eventTrackingEnable; // false default
std::string _launchEvent;
std::unordered_map<int,RuntimeProtocol*> _runtimes;
};
#endif // _RUNTIME__H_

View File

@ -0,0 +1,103 @@
#include "RuntimeCCSImpl.h"
#include "ConfigParser.h"
#include "cocostudio/CocoStudio.h"
#include "ui/UIHelper.h"
////////////////////////////////////////
RuntimeCCSImpl *RuntimeCCSImpl::create()
{
auto instance = new RuntimeCCSImpl();
return instance;
}
void RuntimeCCSImpl::onStartDebuger(const rapidjson::Document& dArgParse, rapidjson::Document& dReplyParse)
{
}
void RuntimeCCSImpl::onReload(const rapidjson::Document &dArgParse, rapidjson::Document &dReplyParse)
{
}
void RuntimeCCSImpl::startScript(const std::string& file)
{
std::string filename(file);
if (filename.empty())
{
filename = ConfigParser::getInstance()->getEntryFile();
}
if (filename.rfind(".csd") != std::string::npos)
{
loadCSDProject(filename);
}
else if (filename.rfind(".csb") != std::string::npos)
{
loadCSBProject(filename);
}
}
void RuntimeCCSImpl::loadCSDProject(const std::string& file)
{
CCLOG("------------------------------------------------");
CCLOG("LOAD Cocos Studio FILE (.csd): %s", file.c_str());
CCLOG("------------------------------------------------");
auto node = CSLoader::getInstance()->createNodeWithFlatBuffersForSimulator(file.c_str());
auto action = cocostudio::timeline::ActionTimelineCache::getInstance()->createActionWithFlatBuffersForSimulator(file.c_str());
if (action)
{
node->runAction(action);
action->gotoFrameAndPlay(0);
}
if (node)
{
Size frameSize = Director::getInstance()->getVisibleSize();
node->setContentSize(frameSize);
ui::Helper::doLayout(node);
if (Director::getInstance()->getRunningScene())
{
auto scene = Scene::create();
scene->addChild(node);
Director::getInstance()->replaceScene(scene);
}
else
{
auto scene = Scene::create();
scene->addChild(node);
Director::getInstance()->runWithScene(scene);
}
}
}
void RuntimeCCSImpl::loadCSBProject(const std::string& file)
{
CCLOG("\n------------------------------------------------\n");
CCLOG("[WARNING]: using **SUITABLE** Cocos Studio generate csb file!!");
CCLOG("LOAD Cocos Studio FILE (.csb): %s", file.c_str());
CCLOG("\n------------------------------------------------\n");
auto node = CSLoader::getInstance()->createNode(file);
if (node)
{
Size frameSize = Director::getInstance()->getVisibleSize();
node->setContentSize(frameSize);
ui::Helper::doLayout(node);
if (Director::getInstance()->getRunningScene())
{
auto scene = Scene::create();
scene->addChild(node);
Director::getInstance()->replaceScene(scene);
}
else
{
auto scene = Scene::create();
scene->addChild(node);
Director::getInstance()->runWithScene(scene);
}
}
}

View File

@ -0,0 +1,21 @@
#ifndef __Simulator__RuntimeCCSImpl__
#define __Simulator__RuntimeCCSImpl__
#include "RuntimeProtocol.h"
class RuntimeCCSImpl : public RuntimeProtocol
{
public:
static RuntimeCCSImpl *create();
void onStartDebuger(const rapidjson::Document& dArgParse, rapidjson::Document& dReplyParse);
void onReload(const rapidjson::Document& dArgParse, rapidjson::Document& dReplyParse);
void startScript(const std::string& file);
private:
void loadCSDProject(const std::string& file);
void loadCSBProject(const std::string& file);
};
#endif /* defined(__Simulator__RuntimeCCSImpl__) */

View File

@ -0,0 +1,51 @@
//
// RuntimeProtocol.cpp
// Simulator
//
//
#include "RuntimeProtocol.h"
#include "cocos2d.h"
void RuntimeProtocol::end()
{
}
void RuntimeProtocol::setProjectPath(const std::string& path)
{
_projectPath = path;
}
std::string RuntimeProtocol::getProjectPath() const
{
return _projectPath;
}
void RuntimeProtocol::startScript(const std::string& script)
{
CCLOG("%s: NOT SUPPRT", __FUNCTION__);
}
void RuntimeProtocol::onStartDebuger(const rapidjson::Document& dArgParse, rapidjson::Document& dReplyParse)
{
CCLOG("%s: NOT SUPPRT", __FUNCTION__);
}
void RuntimeProtocol::onClearCompile(const rapidjson::Document& dArgParse, rapidjson::Document& dReplyParse)
{
CCLOG("%s: NOT SUPPRT", __FUNCTION__);
}
void RuntimeProtocol::onPrecompile(const rapidjson::Document& dArgParse, rapidjson::Document& dReplyParse)
{
CCLOG("%s: NOT SUPPRT", __FUNCTION__);
}
void RuntimeProtocol::onReload(const rapidjson::Document& dArgParse, rapidjson::Document& dReplyParse)
{
CCLOG("%s: NOT SUPPRT", __FUNCTION__);
}
void RuntimeProtocol::onRemove(const std::string &filename)
{
}

View File

@ -0,0 +1,32 @@
//
// RuntimeProtocol.h
// Simulator
//
//
#ifndef __Simulator__RuntimeProtocol__
#define __Simulator__RuntimeProtocol__
#include <string>
#include "json/document.h"
class RuntimeProtocol
{
public:
virtual void end();
void setProjectPath(const std::string& path);
std::string getProjectPath() const;
virtual void startScript(const std::string& file);
virtual void onStartDebuger(const rapidjson::Document& dArgParse, rapidjson::Document& dReplyParse);
virtual void onClearCompile(const rapidjson::Document& dArgParse, rapidjson::Document& dReplyParse);
virtual void onPrecompile(const rapidjson::Document& dArgParse, rapidjson::Document& dReplyParse);
virtual void onReload(const rapidjson::Document& dArgParse, rapidjson::Document& dReplyParse);
virtual void onRemove(const std::string &filename);
protected:
std::string _projectPath;
};
#endif /* defined(__Simulator__RuntimeBase__) */

View File

@ -0,0 +1,739 @@
#include "ResData.h"
const unsigned char __shinePngData[11776] = {
0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, 0x00, 0x00, 0x00, 0x0D, 0x49, 0x48, 0x44, 0x52,
0x00, 0x00, 0x01, 0xC4, 0x00, 0x00, 0x02, 0x20, 0x04, 0x03, 0x00, 0x00, 0x00, 0xE9, 0x4C, 0x04,
0x25, 0x00, 0x00, 0x00, 0x1E, 0x50, 0x4C, 0x54, 0x45, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x24, 0x7C, 0x9B, 0x95, 0x00, 0x00, 0x00, 0x0A, 0x74,
0x52, 0x4E, 0x53, 0x00, 0x01, 0x05, 0x09, 0x0E, 0x13, 0x19, 0x24, 0x2B, 0x1E, 0x3A, 0xC3, 0xFD,
0x9D, 0x00, 0x00, 0x2D, 0x87, 0x49, 0x44, 0x41, 0x54, 0x78, 0xDA, 0xDC, 0x9A, 0x4B, 0xB2, 0xD4,
0x30, 0x0C, 0x45, 0x3B, 0xAC, 0x00, 0x04, 0x0B, 0xC0, 0x36, 0x0B, 0xA0, 0x9C, 0x66, 0x0E, 0x24,
0x30, 0x87, 0xA2, 0xD9, 0x01, 0xEC, 0x7F, 0x09, 0x58, 0x96, 0xAD, 0x2B, 0xC7, 0xFC, 0x26, 0x14,
0x4A, 0x94, 0xA6, 0xAA, 0xD3, 0x2F, 0x50, 0x1C, 0x8E, 0x7E, 0xE6, 0xBD, 0xDB, 0xBF, 0x8C, 0xE5,
0x99, 0x8D, 0xA7, 0xB7, 0xAB, 0x45, 0x27, 0xBB, 0x2A, 0x26, 0xA0, 0xE6, 0xB8, 0x5D, 0x20, 0x24,
0x3F, 0x2F, 0x4C, 0x39, 0x01, 0x5E, 0x2D, 0x63, 0x01, 0x78, 0x55, 0x95, 0xCF, 0x4A, 0x5C, 0x1A,
0xD2, 0x2A, 0xBC, 0x66, 0xBA, 0x0A, 0xE1, 0x95, 0x45, 0x0A, 0xE1, 0x95, 0x45, 0x0A, 0xE1, 0x95,
0x45, 0xFE, 0x82, 0x90, 0x9E, 0x05, 0xBC, 0x4E, 0xCE, 0xF8, 0x6C, 0x8E, 0x19, 0x2A, 0x9C, 0x99,
0x11, 0x12, 0x21, 0x50, 0x24, 0x96, 0x8B, 0xCA, 0xC5, 0x6F, 0x44, 0xEA, 0x59, 0x19, 0x67, 0x3E,
0x06, 0x52, 0x56, 0x26, 0xD4, 0xFB, 0x70, 0x4A, 0xC6, 0x59, 0xA2, 0xA0, 0x04, 0x32, 0x80, 0x5D,
0x2A, 0x7F, 0x7C, 0x3E, 0xC6, 0x03, 0x1B, 0xA3, 0x90, 0xBD, 0x15, 0xAB, 0xA1, 0x0B, 0x3E, 0xE1,
0xEC, 0x98, 0x25, 0x42, 0x56, 0x18, 0x53, 0x95, 0xF0, 0xAF, 0x70, 0x2A, 0xC6, 0x11, 0x4E, 0x40,
0x04, 0xC1, 0x02, 0x52, 0xFF, 0x88, 0xCE, 0x57, 0x8E, 0x56, 0x62, 0x47, 0x22, 0x6D, 0x39, 0x14,
0x62, 0x09, 0x8A, 0xA1, 0xDB, 0x05, 0x28, 0x9D, 0x46, 0xA3, 0x45, 0x0C, 0x3A, 0x20, 0x84, 0x34,
0xC4, 0x10, 0xA9, 0x44, 0xA8, 0xA0, 0xF2, 0xB1, 0x54, 0xE7, 0xA9, 0xCA, 0xF1, 0xE8, 0x10, 0xA3,
0xA1, 0xD8, 0x1B, 0x23, 0x46, 0xF3, 0x44, 0xB9, 0xE8, 0x1C, 0xA9, 0xBA, 0x4C, 0x0E, 0xA9, 0xB9,
0x6A, 0x80, 0xC1, 0x46, 0x8C, 0x66, 0x6C, 0x84, 0x93, 0x94, 0x23, 0x10, 0xD1, 0x63, 0x38, 0xA8,
0x31, 0x69, 0x40, 0xA5, 0xE8, 0x6E, 0xFB, 0xCF, 0x09, 0x52, 0x15, 0x39, 0x0A, 0x48, 0x56, 0x18,
0xA2, 0xF0, 0x50, 0x23, 0x64, 0xD8, 0xAE, 0x32, 0xC8, 0x73, 0x74, 0x92, 0xAE, 0x7A, 0x28, 0xC4,
0x40, 0x50, 0xD8, 0xEC, 0x85, 0xFA, 0x1A, 0x5C, 0x46, 0xB3, 0xE8, 0x04, 0xEF, 0x8C, 0xC8, 0x53,
0x4C, 0x04, 0x51, 0xC8, 0x50, 0x82, 0xA6, 0xA8, 0x35, 0x84, 0x5E, 0x25, 0x06, 0xF7, 0x5D, 0x55,
0x11, 0x09, 0xA0, 0x4D, 0x21, 0x09, 0x1F, 0x82, 0x75, 0x76, 0xC8, 0x08, 0x48, 0x72, 0xAE, 0x11,
0x0E, 0xB4, 0x77, 0x44, 0xC9, 0xC5, 0x9F, 0x87, 0x80, 0x57, 0xC9, 0x92, 0xA5, 0xE4, 0xBE, 0x1C,
0x9F, 0xD9, 0x00, 0x61, 0x75, 0xF6, 0xEB, 0x20, 0x59, 0x08, 0x7A, 0x76, 0x07, 0xD7, 0xA9, 0x0A,
0x83, 0xD4, 0x09, 0x43, 0x08, 0xBF, 0x07, 0xAC, 0x5F, 0xAE, 0x4F, 0x9D, 0x61, 0x57, 0x5D, 0x8E,
0xC7, 0x28, 0xC2, 0xA8, 0xF8, 0x43, 0xF4, 0xF1, 0x41, 0x3C, 0x23, 0x1D, 0x6B, 0x6C, 0x88, 0x18,
0xF8, 0x62, 0xE7, 0x8F, 0xD1, 0x0B, 0xF2, 0x04, 0xBB, 0xEA, 0x71, 0x22, 0xB6, 0x61, 0x01, 0x89,
0x39, 0xD9, 0xD7, 0x01, 0xB2, 0x4D, 0x8F, 0xC0, 0x97, 0xDB, 0x54, 0x3D, 0xEC, 0x36, 0x71, 0xCC,
0xD2, 0x42, 0xF5, 0xDB, 0x54, 0xAD, 0x73, 0xD3, 0xFB, 0xE9, 0x78, 0x5C, 0x6D, 0xA8, 0x96, 0xD7,
0xC8, 0x91, 0xE3, 0xDA, 0x82, 0xDF, 0xB3, 0x4B, 0x68, 0x6C, 0x1E, 0xB9, 0x18, 0xDD, 0x76, 0x9C,
0xC5, 0x4C, 0xC4, 0xF2, 0x6B, 0xA8, 0x43, 0xC9, 0xCB, 0xB4, 0xAE, 0x49, 0x82, 0xDF, 0xE5, 0xA3,
0x46, 0xD6, 0xCE, 0x19, 0xEE, 0x77, 0x8F, 0x1B, 0xD7, 0x37, 0x8A, 0x14, 0x4C, 0x9A, 0x2A, 0xA0,
0x48, 0xCC, 0x39, 0xAF, 0xA9, 0xB8, 0x54, 0x93, 0x60, 0xE4, 0xDF, 0xED, 0x75, 0x38, 0x8E, 0xEB,
0xDB, 0x40, 0x98, 0x63, 0x8A, 0x15, 0xCB, 0x84, 0xDC, 0x4F, 0xC3, 0x23, 0x7A, 0x3E, 0x39, 0x0E,
0x79, 0x4A, 0x25, 0xC6, 0x22, 0x2C, 0x02, 0x11, 0x2A, 0x53, 0x4C, 0xC2, 0x23, 0x33, 0xCA, 0x99,
0xC3, 0xA3, 0xC6, 0x71, 0x73, 0x43, 0xAF, 0xE1, 0x4C, 0x64, 0x42, 0x90, 0x21, 0xF8, 0xE3, 0x7C,
0x58, 0xE6, 0x82, 0xDF, 0x6A, 0xB4, 0x2B, 0xF8, 0xC1, 0x61, 0xE1, 0x58, 0xCB, 0x6B, 0x8A, 0x2C,
0x90, 0x10, 0xC9, 0x94, 0xE4, 0x76, 0x8F, 0x5B, 0xEC, 0x7E, 0xCA, 0xED, 0x94, 0xD4, 0x61, 0xCA,
0x86, 0x70, 0x8E, 0xA3, 0x48, 0x2E, 0x47, 0xF2, 0xD8, 0x71, 0xEC, 0x86, 0x2A, 0x12, 0xE1, 0x30,
0xA5, 0x21, 0x47, 0xE7, 0x6C, 0xCD, 0x92, 0xCE, 0x6D, 0x25, 0x2F, 0x13, 0xC7, 0xA5, 0x46, 0x20,
0x06, 0x62, 0x89, 0x28, 0xC4, 0x3C, 0x0B, 0x9C, 0x45, 0x5A, 0x8F, 0xE4, 0x74, 0x55, 0x35, 0x79,
0x3A, 0x6E, 0x6E, 0x63, 0x8A, 0xDE, 0x25, 0xF4, 0x5E, 0x5B, 0x6B, 0xF7, 0x48, 0xEC, 0x51, 0x0E,
0x2A, 0xDE, 0x34, 0x0E, 0x07, 0x61, 0x34, 0xD3, 0x71, 0x5A, 0x6C, 0xDB, 0xB6, 0xD6, 0x0B, 0x98,
0x93, 0x47, 0x5E, 0x6E, 0x5D, 0xAE, 0xAA, 0xA6, 0x14, 0xC9, 0x0E, 0x8C, 0x94, 0x0D, 0x20, 0x93,
0xED, 0x72, 0xED, 0x7C, 0x33, 0x79, 0xEC, 0x90, 0x2E, 0x53, 0x75, 0x19, 0x0E, 0xC2, 0x2A, 0x71,
0x20, 0x5C, 0xF7, 0xAD, 0x90, 0xED, 0x1C, 0x77, 0x86, 0xDD, 0x4A, 0xD8, 0x09, 0x12, 0x21, 0xB2,
0xFE, 0x41, 0xCE, 0x4E, 0x55, 0xC6, 0x22, 0x24, 0xDA, 0x56, 0x53, 0x99, 0x76, 0x1B, 0xDB, 0x7E,
0x17, 0x93, 0x60, 0x4C, 0x9E, 0x3B, 0x8E, 0xC9, 0xD3, 0x5E, 0x8A, 0x89, 0x0B, 0x51, 0x09, 0xD7,
0x42, 0xB4, 0x1F, 0xE3, 0xCE, 0x22, 0x95, 0x30, 0x23, 0x51, 0x29, 0xFA, 0x9B, 0xFF, 0x68, 0xA8,
0xE6, 0x10, 0x95, 0x54, 0xE2, 0xA6, 0x02, 0x27, 0xCA, 0x15, 0xD9, 0x9A, 0xB2, 0x9E, 0x3B, 0xA8,
0xA6, 0xAA, 0xA7, 0x55, 0x75, 0xCC, 0xD3, 0x26, 0x31, 0x65, 0x38, 0x84, 0xC2, 0x29, 0xB6, 0xBB,
0x76, 0xD5, 0xA4, 0x84, 0xE4, 0xEE, 0x9B, 0x1C, 0x40, 0x24, 0xA2, 0x3E, 0x13, 0xD7, 0xF4, 0x37,
0x84, 0xE5, 0x4B, 0xA8, 0x48, 0x1C, 0x1F, 0xDD, 0x0D, 0x0E, 0xE4, 0x69, 0x84, 0xC4, 0xD4, 0x18,
0xC7, 0x32, 0xFC, 0xC0, 0x71, 0x60, 0x5C, 0xB5, 0x20, 0x41, 0x18, 0x9D, 0xCD, 0x7F, 0xD3, 0x6D,
0x30, 0xF7, 0xB3, 0xF6, 0x52, 0x25, 0xFC, 0x52, 0x62, 0x2F, 0xD7, 0x88, 0xB9, 0xC1, 0x63, 0x6A,
0x87, 0x0E, 0xDE, 0x01, 0x5D, 0x69, 0x34, 0x79, 0x0A, 0x89, 0xE8, 0xA6, 0x46, 0xE0, 0xE3, 0xF1,
0xA1, 0x5E, 0x8F, 0x07, 0xD3, 0x82, 0x51, 0x7B, 0x0E, 0x13, 0x36, 0x48, 0x57, 0xA9, 0xBA, 0x20,
0x4F, 0x55, 0xE2, 0x9A, 0xBA, 0x44, 0xEE, 0xA6, 0x6B, 0x05, 0xFC, 0x52, 0xE0, 0x34, 0x3E, 0x30,
0xA5, 0x29, 0xC8, 0x9E, 0xAA, 0x1D, 0xD2, 0x57, 0xAA, 0x0E, 0x69, 0x0A, 0x89, 0x20, 0xDC, 0x5F,
0x3F, 0xDF, 0xF7, 0xC7, 0x17, 0xF0, 0x01, 0x12, 0x23, 0xB2, 0x9F, 0x1E, 0x5D, 0xAE, 0xAA, 0x66,
0x64, 0xC4, 0x16, 0x87, 0x89, 0xF8, 0xEE, 0xF6, 0xCA, 0x1A, 0xFC, 0x52, 0x2E, 0x81, 0xDC, 0x95,
0x71, 0x6D, 0x8C, 0xDA, 0x55, 0x3D, 0x0D, 0x0E, 0x94, 0x62, 0x24, 0x95, 0x28, 0x8C, 0x7D, 0xE4,
0xBF, 0xBF, 0xDD, 0xDE, 0x80, 0x70, 0x60, 0x85, 0xC8, 0xB1, 0xAB, 0x52, 0x5B, 0x55, 0x5D, 0x68,
0x54, 0x44, 0x1C, 0x86, 0x33, 0xD2, 0x94, 0xE3, 0xC3, 0x56, 0x9E, 0x9A, 0x19, 0x45, 0x64, 0xEB,
0xAD, 0x5B, 0x67, 0x3C, 0x6A, 0xF4, 0x50, 0x8D, 0xF3, 0xFF, 0x68, 0xA4, 0x35, 0xB7, 0xCD, 0xB4,
0x0F, 0x8B, 0xF2, 0xD8, 0x13, 0xCE, 0xD4, 0xAF, 0x8F, 0x6F, 0xF2, 0x82, 0xC8, 0xEE, 0x51, 0xF7,
0xD5, 0x4E, 0x18, 0x79, 0x55, 0xF5, 0xF1, 0xB3, 0x2A, 0x73, 0x9E, 0xAE, 0x69, 0x48, 0xD3, 0x52,
0x78, 0xFC, 0xD7, 0x7B, 0x5E, 0xD8, 0x4C, 0xC0, 0x24, 0x7B, 0x14, 0xC8, 0x3E, 0x1C, 0xB1, 0xAA,
0xBA, 0xD0, 0xB8, 0x4C, 0xCD, 0x26, 0xA5, 0x3E, 0xF4, 0x3B, 0xE1, 0xE3, 0x25, 0x3F, 0xF9, 0xE2,
0xF1, 0x0D, 0xF1, 0xD5, 0xA8, 0x6C, 0x1E, 0xEF, 0x9A, 0xAA, 0x66, 0xFE, 0x93, 0x83, 0xA6, 0x6A,
0xF3, 0x94, 0x4C, 0x25, 0x6A, 0x96, 0xF2, 0xC4, 0x7F, 0x5D, 0x1F, 0x7D, 0x53, 0xE4, 0x7D, 0xAF,
0x31, 0x9A, 0xD4, 0x5D, 0xE7, 0xAE, 0xC3, 0x11, 0xF3, 0x9F, 0xFE, 0xBB, 0xC6, 0x65, 0x3E, 0x64,
0xA4, 0x5C, 0x09, 0x9B, 0xC4, 0x3A, 0x2C, 0xDE, 0xCA, 0xB3, 0x1F, 0xBF, 0x4B, 0x7C, 0x13, 0xCA,
0x62, 0x15, 0x1E, 0x51, 0x8E, 0xD8, 0x71, 0xC8, 0xC5, 0x1A, 0x07, 0x44, 0x1A, 0x66, 0xE2, 0x7D,
0x15, 0x40, 0x19, 0x87, 0x9F, 0xE4, 0xE1, 0x27, 0x2C, 0x11, 0xC1, 0x90, 0xF0, 0x38, 0x6B, 0x24,
0xAE, 0xC6, 0xFF, 0xAF, 0x51, 0x09, 0xB1, 0xBB, 0x65, 0x7B, 0xBE, 0x90, 0x21, 0xFF, 0xB9, 0x3D,
0xFD, 0x02, 0x7C, 0xEC, 0xD2, 0x26, 0xEB, 0xD0, 0x55, 0xA3, 0x84, 0x8B, 0x6D, 0xFC, 0x07, 0x33,
0xE7, 0xCE, 0xEB, 0x34, 0x10, 0x44, 0xE1, 0x0D, 0x8F, 0x1E, 0x21, 0xA0, 0xC6, 0x44, 0x3C, 0x4A,
0x84, 0x23, 0x01, 0x1D, 0x12, 0x41, 0x40, 0x47, 0x61, 0x10, 0x74, 0x20, 0xE0, 0x82, 0x3B, 0x10,
0x02, 0x3B, 0x25, 0x2F, 0x79, 0xE9, 0xA0, 0x20, 0x26, 0xFF, 0x96, 0xAC, 0x67, 0xBD, 0x67, 0xD6,
0x63, 0xB3, 0x91, 0xF1, 0x62, 0xE6, 0x07, 0x5C, 0xDD, 0x93, 0x6F, 0x1E, 0x67, 0x76, 0x37, 0xE1,
0x73, 0x3F, 0xF1, 0x9B, 0x0D, 0x04, 0x3E, 0x7C, 0xF9, 0x5C, 0xD9, 0xB8, 0x78, 0xE4, 0x85, 0xE9,
0x3B, 0x2E, 0x55, 0xD1, 0x55, 0xAF, 0xA1, 0xE5, 0xCC, 0x8F, 0x51, 0xEE, 0xFB, 0xF0, 0x35, 0xC8,
0xD3, 0x47, 0x0F, 0x95, 0x09, 0x2A, 0xC7, 0xED, 0x76, 0xEB, 0x25, 0xAB, 0xA7, 0x71, 0xD5, 0xA6,
0xAA, 0xBB, 0xAB, 0x9A, 0x13, 0xA3, 0xDC, 0xA3, 0x00, 0x71, 0xE5, 0x41, 0xDC, 0xB3, 0x72, 0xFF,
0xDB, 0xB1, 0x27, 0xBB, 0x5D, 0xBE, 0x0F, 0x2E, 0x12, 0xA9, 0x4A, 0x18, 0xE1, 0x71, 0x4E, 0xCF,
0x8F, 0x91, 0x2F, 0xC3, 0x83, 0x10, 0x5F, 0xEE, 0x1B, 0xE8, 0x79, 0xD5, 0xC6, 0x99, 0x5D, 0x13,
0x8E, 0xE5, 0x23, 0x33, 0x25, 0xA1, 0x11, 0x56, 0xD5, 0xC6, 0x5C, 0x18, 0x01, 0x11, 0xA5, 0x48,
0x1A, 0x79, 0x25, 0x52, 0x96, 0x36, 0xC3, 0xF0, 0x96, 0x72, 0x71, 0xC9, 0x28, 0x24, 0x95, 0xE0,
0xC8, 0x1D, 0x80, 0x2D, 0xC6, 0x6B, 0xFF, 0x45, 0x35, 0x4A, 0x88, 0xCB, 0x74, 0x09, 0x85, 0x99,
0x53, 0x78, 0xF4, 0x80, 0x7D, 0x2E, 0x4F, 0xAC, 0xC4, 0x7C, 0x47, 0xE9, 0x4A, 0x18, 0x49, 0x23,
0x75, 0x55, 0x60, 0x4C, 0x66, 0xC6, 0xB8, 0x90, 0x97, 0x8A, 0xE9, 0x12, 0x6B, 0x62, 0x66, 0x0B,
0xD1, 0xC8, 0x78, 0xA6, 0x10, 0xC7, 0xF3, 0x1D, 0x40, 0x7A, 0x1C, 0xD7, 0x0C, 0x63, 0x7A, 0xE1,
0x7F, 0x68, 0xAA, 0x50, 0xC8, 0xFA, 0x29, 0x20, 0x32, 0x85, 0x47, 0xCF, 0x15, 0x8B, 0xB3, 0x3B,
0x17, 0x47, 0xA4, 0xB1, 0xE5, 0xE8, 0xBB, 0xF1, 0xF9, 0xAB, 0x91, 0x5F, 0x0D, 0xBB, 0x3C, 0x25,
0x88, 0x74, 0x1A, 0x65, 0x14, 0x52, 0x9E, 0xE6, 0x2F, 0x14, 0x8F, 0xFB, 0x9B, 0xDA, 0x89, 0xCC,
0x99, 0xC6, 0x8C, 0x38, 0xAE, 0x98, 0x8D, 0x4B, 0x80, 0x71, 0x06, 0x89, 0x5C, 0x21, 0x51, 0xE4,
0x10, 0xD7, 0x0D, 0x16, 0xEB, 0xBB, 0xB7, 0x3F, 0x15, 0x8F, 0x63, 0xAF, 0x76, 0x1B, 0xA7, 0x32,
0xC7, 0x78, 0x44, 0x35, 0x9A, 0x18, 0x68, 0xAA, 0x2A, 0x7E, 0x48, 0x88, 0x58, 0x15, 0x89, 0x22,
0x20, 0xDA, 0xD5, 0x62, 0x5F, 0x7C, 0xFE, 0x87, 0x7F, 0xB6, 0x28, 0x48, 0x23, 0xEA, 0x91, 0x34,
0xFE, 0x5F, 0x18, 0x9D, 0x3E, 0xAC, 0x8A, 0x4B, 0x0E, 0x11, 0x95, 0xB8, 0xDD, 0x0B, 0xB9, 0xAA,
0xBC, 0xB8, 0x59, 0x18, 0x91, 0x1B, 0x70, 0x34, 0xA9, 0x8A, 0x95, 0x23, 0xA5, 0x98, 0x19, 0xE3,
0xA2, 0x3F, 0x4F, 0x01, 0x11, 0xBD, 0xC6, 0xC8, 0xB8, 0xA5, 0x3A, 0xA9, 0x5A, 0x6C, 0xF6, 0x2A,
0x6B, 0xC7, 0xD1, 0x61, 0xA4, 0xE1, 0x68, 0x1F, 0x91, 0xCD, 0x80, 0x31, 0x00, 0x91, 0x26, 0x46,
0xA7, 0x12, 0xF3, 0x66, 0x46, 0x3C, 0x55, 0x7E, 0x9C, 0x30, 0x02, 0xEB, 0x16, 0x24, 0x52, 0xD5,
0xB3, 0xAA, 0xCB, 0xD9, 0x30, 0x4A, 0x89, 0x56, 0x23, 0xF2, 0x94, 0x41, 0xDC, 0x1A, 0x0D, 0xF5,
0x0F, 0xA5, 0x64, 0xAA, 0x32, 0x8E, 0x98, 0x1C, 0x19, 0x26, 0xC7, 0x0C, 0x18, 0x03, 0x8F, 0x89,
0xD2, 0x6B, 0x6E, 0x62, 0xB0, 0x76, 0xDA, 0x68, 0xD8, 0xBC, 0x53, 0x4A, 0xA4, 0xAA, 0x51, 0x28,
0x35, 0xAE, 0xB3, 0xFF, 0x04, 0xE3, 0x60, 0x9E, 0x76, 0x21, 0xE6, 0x8D, 0xC2, 0xE2, 0xBD, 0xEA,
0xC6, 0xC9, 0x82, 0x34, 0x52, 0xAE, 0x52, 0x39, 0x52, 0x53, 0x75, 0x18, 0x97, 0xB3, 0x61, 0x94,
0x10, 0x21, 0x71, 0xB5, 0x6A, 0x14, 0x12, 0x44, 0x97, 0xA6, 0x45, 0xF1, 0x41, 0x89, 0xB8, 0xDE,
0x68, 0xDC, 0x58, 0x8E, 0xB9, 0xDF, 0x55, 0x57, 0xE9, 0x9C, 0x18, 0xE5, 0xE3, 0x4C, 0x0A, 0x76,
0x8B, 0xF1, 0xD0, 0x83, 0x58, 0xD7, 0x9B, 0xA2, 0x90, 0x9F, 0xFC, 0xB1, 0xBA, 0x2C, 0x48, 0xE5,
0x26, 0x8C, 0xF1, 0x42, 0xF0, 0xF5, 0x7F, 0x24, 0x88, 0xD8, 0xA3, 0x00, 0x11, 0xED, 0xD4, 0x15,
0xA2, 0xD1, 0x81, 0xC1, 0xC8, 0x0C, 0x40, 0xC5, 0x38, 0xB2, 0x8E, 0xD3, 0xD3, 0x54, 0xE9, 0x14,
0x27, 0x90, 0xA9, 0xB1, 0x20, 0x9E, 0x96, 0x27, 0x1A, 0x19, 0x6F, 0xA7, 0xA4, 0xB0, 0x78, 0xA0,
0x64, 0xDC, 0xAD, 0xAA, 0x8A, 0x38, 0xC2, 0xC9, 0x39, 0xAB, 0x2A, 0xAA, 0xF1, 0x9F, 0xBE, 0xFE,
0x5F, 0xF4, 0x4E, 0x0C, 0x52, 0x28, 0x21, 0xD6, 0x46, 0x63, 0xF5, 0x5D, 0xC9, 0x38, 0xF6, 0xAB,
0x6A, 0x40, 0xD6, 0xD4, 0x72, 0x50, 0x8D, 0x6B, 0xBF, 0x1A, 0x29, 0x02, 0xFB, 0x46, 0x74, 0x88,
0xC8, 0x53, 0x0E, 0x31, 0x77, 0x10, 0xCB, 0xB7, 0xAA, 0x27, 0xCE, 0x69, 0x5D, 0x10, 0x47, 0x93,
0xA9, 0x3B, 0x5E, 0x8E, 0x12, 0xE3, 0x05, 0xBA, 0x8A, 0x8E, 0x8E, 0x11, 0x12, 0xD1, 0x4F, 0xBB,
0xE6, 0xCD, 0x83, 0x58, 0x37, 0x02, 0xCB, 0xEA, 0xB3, 0xEA, 0x8B, 0xC7, 0x5A, 0xD3, 0xEC, 0xA8,
0x69, 0x38, 0x5A, 0x8F, 0x73, 0x47, 0xB8, 0x71, 0xDC, 0xA9, 0xC6, 0xC7, 0x28, 0x9B, 0x0D, 0xB7,
0xE0, 0x46, 0xE1, 0x1A, 0x10, 0xA9, 0x9B, 0x9A, 0x3C, 0xD5, 0x5F, 0x55, 0x5F, 0x1C, 0x2F, 0xB5,
0xA6, 0x7A, 0x6C, 0xBB, 0x2A, 0x96, 0xE3, 0xDB, 0xC0, 0x68, 0x0F, 0xE3, 0x92, 0xC0, 0xDC, 0x88,
0x05, 0x51, 0x2C, 0x19, 0x7E, 0x25, 0x16, 0xB5, 0x11, 0x58, 0xEA, 0x6F, 0xAA, 0x37, 0x2E, 0x6B,
0x5D, 0x16, 0x6E, 0xED, 0xC8, 0x7D, 0x8C, 0x69, 0x17, 0x23, 0x32, 0x55, 0x62, 0x8C, 0xD7, 0x6C,
0xF8, 0x92, 0x71, 0xDB, 0x1D, 0x68, 0x00, 0x22, 0x55, 0xA2, 0xD6, 0xBA, 0xFF, 0x7F, 0x5A, 0xFC,
0xD2, 0x15, 0x89, 0x2C, 0x5C, 0xC7, 0x71, 0xD5, 0x28, 0x30, 0x06, 0xC6, 0x7F, 0xD4, 0x4A, 0x5C,
0x3A, 0x8A, 0x77, 0x32, 0x52, 0x68, 0x21, 0x52, 0x96, 0x9A, 0xA0, 0xC1, 0x28, 0x7D, 0x9C, 0xC9,
0x54, 0x94, 0xA3, 0xDB, 0x38, 0x66, 0xAB, 0x46, 0x09, 0x91, 0x5B, 0x9B, 0xB5, 0x73, 0x36, 0x8F,
0x38, 0xC4, 0xB2, 0x34, 0x12, 0x1F, 0x0C, 0xFC, 0xB9, 0x7B, 0xDA, 0x8A, 0x24, 0xAF, 0x1A, 0xA8,
0xC6, 0x40, 0x53, 0x8D, 0x64, 0x4F, 0xB1, 0x64, 0xC8, 0x4A, 0x24, 0x81, 0x4D, 0xBC, 0x51, 0x6A,
0xB0, 0xE3, 0x50, 0xA6, 0xD6, 0xCE, 0xAA, 0x1A, 0x8C, 0x4D, 0x39, 0xA6, 0xB3, 0x60, 0xEC, 0x40,
0xEC, 0x9A, 0xB7, 0x3B, 0x46, 0xA1, 0x07, 0x51, 0x93, 0xC6, 0x8F, 0x4A, 0x0D, 0x76, 0x9C, 0xB6,
0xE7, 0x98, 0x6A, 0x74, 0x1A, 0x7B, 0xAA, 0xF1, 0x42, 0xA0, 0x1A, 0x63, 0x41, 0xC4, 0x50, 0x74,
0x47, 0x36, 0x0E, 0x22, 0x14, 0xEA, 0x2F, 0x83, 0x7F, 0xF1, 0x17, 0x65, 0x2A, 0xAA, 0x91, 0xAE,
0x56, 0xEF, 0xF4, 0x54, 0x63, 0xEC, 0xA7, 0xB8, 0x72, 0xC7, 0xB0, 0x10, 0x31, 0x14, 0xD7, 0x59,
0x0B, 0x71, 0xDB, 0x42, 0xAC, 0x34, 0x05, 0x66, 0xBF, 0xF0, 0x38, 0xC0, 0xE8, 0x34, 0x5A, 0x8C,
0xB7, 0x7B, 0x31, 0x26, 0x12, 0x63, 0xFC, 0xB1, 0xBF, 0xA4, 0x3C, 0xA5, 0x89, 0x41, 0x0A, 0x5D,
0x25, 0x52, 0x54, 0xE7, 0xD5, 0x60, 0x3C, 0xA6, 0x8E, 0x43, 0xC3, 0x11, 0x8B, 0xE3, 0x0C, 0xD5,
0x28, 0xF2, 0x94, 0x20, 0xF2, 0xA1, 0xE8, 0x9C, 0x0D, 0x2A, 0xD1, 0x06, 0x1A, 0xAA, 0x8C, 0x13,
0x84, 0x11, 0xB3, 0xD1, 0x62, 0x94, 0xD5, 0x48, 0xCF, 0xC6, 0xE3, 0x62, 0x94, 0x13, 0x03, 0x43,
0x91, 0xDB, 0x53, 0x40, 0x94, 0x69, 0x2A, 0xE3, 0x46, 0xAB, 0xD1, 0x60, 0xDC, 0x6E, 0x81, 0x11,
0xD5, 0x28, 0x6E, 0xFF, 0xA1, 0x31, 0x2A, 0x44, 0xDE, 0x6C, 0xE8, 0xCC, 0x66, 0x00, 0xE2, 0xB7,
0x3F, 0xE7, 0xD4, 0x31, 0xF3, 0x49, 0x90, 0x01, 0x70, 0x18, 0x45, 0x35, 0xE2, 0x2D, 0x4E, 0x12,
0xB3, 0xE3, 0x88, 0x5E, 0x83, 0xB1, 0xBF, 0x62, 0x43, 0x31, 0x07, 0xC4, 0x40, 0x9A, 0x62, 0x70,
0x40, 0x23, 0x30, 0x8A, 0x6A, 0xC4, 0xF7, 0xFF, 0xA3, 0x61, 0x14, 0x13, 0x03, 0x79, 0x0A, 0x88,
0xFB, 0x20, 0x88, 0x65, 0x11, 0x4E, 0x53, 0x0C, 0x0E, 0x5D, 0x56, 0x7B, 0x85, 0xA2, 0xA9, 0xAE,
0x43, 0x18, 0x63, 0xE7, 0xA9, 0x74, 0xE0, 0x47, 0x80, 0xD8, 0x2A, 0xAC, 0xF0, 0x8F, 0x84, 0x07,
0x47, 0x8D, 0xA6, 0x2A, 0xAB, 0x51, 0x7E, 0x89, 0x23, 0x0A, 0x44, 0x4C, 0x8C, 0xD3, 0x72, 0x8D,
0xA2, 0xA1, 0x68, 0x2B, 0xB1, 0xB2, 0x33, 0xF1, 0xA9, 0x0A, 0xC7, 0x6B, 0xCF, 0xAA, 0x1E, 0x56,
0x8D, 0xD0, 0xF8, 0xAF, 0x9D, 0x4D, 0x9E, 0x5B, 0x88, 0x21, 0x5F, 0xE3, 0x6F, 0x1C, 0xA4, 0x91,
0xAA, 0x31, 0x30, 0x1B, 0xE5, 0x70, 0x8C, 0x73, 0xA5, 0x28, 0xEF, 0x6A, 0x00, 0x71, 0x57, 0x33,
0x5F, 0x23, 0x86, 0xFE, 0xE0, 0xFC, 0xD7, 0x85, 0xC0, 0x28, 0x4E, 0x71, 0xE2, 0x62, 0xE4, 0x10,
0x69, 0xEE, 0xBB, 0x37, 0x1A, 0xD8, 0x85, 0x69, 0x62, 0x30, 0x88, 0x3F, 0xD4, 0x41, 0x71, 0x02,
0x4D, 0x55, 0x60, 0x94, 0x37, 0x1C, 0x3C, 0x22, 0x41, 0x4C, 0x64, 0xB3, 0xC9, 0x30, 0xF6, 0xA9,
0x14, 0x49, 0x21, 0x3F, 0xB4, 0x09, 0xCF, 0xFF, 0x40, 0x35, 0x12, 0x46, 0xFA, 0xDD, 0x4A, 0x74,
0xD5, 0xC8, 0x79, 0x8A, 0x6E, 0xD3, 0x42, 0xEC, 0xB4, 0xD3, 0x5B, 0xEA, 0xC0, 0x38, 0x4E, 0xC5,
0x18, 0xAC, 0x46, 0xFA, 0x9E, 0x4A, 0x9C, 0x67, 0xE3, 0xFE, 0xC4, 0x20, 0x8C, 0x29, 0x9C, 0x4D,
0xD7, 0x9E, 0x56, 0x62, 0x24, 0x06, 0x31, 0x9A, 0x38, 0xB4, 0x1A, 0x79, 0xC4, 0xCA, 0x53, 0x40,
0x5C, 0xAF, 0x90, 0xA7, 0x80, 0x18, 0xEA, 0x35, 0xD2, 0xC6, 0x61, 0x36, 0x06, 0xAA, 0x31, 0x89,
0xF4, 0x23, 0x0E, 0xC3, 0xF6, 0x94, 0x14, 0x76, 0x9C, 0x4D, 0xD9, 0xD7, 0x6B, 0xC2, 0x36, 0xAE,
0x1A, 0xC6, 0x88, 0x47, 0x9C, 0xA4, 0x71, 0xFA, 0xC9, 0xE1, 0xDB, 0xD3, 0x04, 0x67, 0x36, 0x70,
0x36, 0xA4, 0x10, 0xC7, 0x6E, 0xF2, 0xF4, 0x34, 0xE0, 0xC6, 0x87, 0x31, 0xA6, 0x14, 0x96, 0x62,
0x9C, 0x54, 0x5D, 0x88, 0x03, 0x62, 0x71, 0xE1, 0xC6, 0x2B, 0xD1, 0xD9, 0xEF, 0x08, 0x18, 0x71,
0xC4, 0x81, 0xF1, 0x11, 0x37, 0x4F, 0x6F, 0x77, 0x76, 0x8C, 0x82, 0x0F, 0x8C, 0xC9, 0x30, 0xAE,
0x1C, 0x46, 0x67, 0xE3, 0xA6, 0x4E, 0xD5, 0x21, 0x7B, 0x9A, 0xAE, 0xBA, 0xCE, 0xA6, 0xB9, 0x6C,
0x1B, 0x1C, 0x18, 0xE1, 0xA5, 0x2A, 0x80, 0xD1, 0x2D, 0x55, 0x7E, 0x4C, 0x96, 0xA7, 0xF2, 0x4B,
0x27, 0x2B, 0xEE, 0x6C, 0x72, 0x78, 0x37, 0x32, 0xA7, 0x63, 0x30, 0x56, 0xD5, 0x41, 0x18, 0x29,
0x51, 0x11, 0x71, 0x9F, 0x12, 0xC1, 0xD9, 0xE4, 0x04, 0xB1, 0xC0, 0xC0, 0x18, 0x81, 0xB1, 0x94,
0x18, 0x9D, 0x46, 0x87, 0x31, 0x21, 0x8C, 0x10, 0x79, 0x6A, 0xCA, 0x3C, 0x95, 0x4F, 0x88, 0x79,
0xB3, 0x71, 0xEE, 0xF4, 0x93, 0x52, 0xE3, 0x30, 0x6A, 0x59, 0x8D, 0xEC, 0x85, 0xA3, 0x6B, 0x38,
0x34, 0x1A, 0x11, 0x13, 0xE6, 0xA9, 0x29, 0x04, 0xB9, 0x0B, 0x8B, 0x4A, 0xAC, 0x00, 0x71, 0x92,
0x6A, 0x04, 0x46, 0x68, 0x34, 0x31, 0x95, 0x01, 0x18, 0x3E, 0x78, 0x73, 0x73, 0x1F, 0x5B, 0x14,
0x8D, 0x7D, 0x5C, 0x7D, 0x4F, 0xD4, 0x54, 0x2D, 0xC5, 0xD4, 0x2A, 0x34, 0x0B, 0x87, 0xCF, 0x71,
0x32, 0x89, 0xB2, 0xD9, 0x64, 0x1D, 0x7B, 0x5A, 0xBA, 0xD3, 0x8C, 0x11, 0x71, 0xE5, 0x50, 0x8C,
0xB0, 0x38, 0xC0, 0x38, 0x55, 0x9E, 0x72, 0x88, 0x69, 0xF7, 0xCC, 0xC6, 0x40, 0xAC, 0x46, 0x42,
0x84, 0x53, 0xAD, 0xAA, 0x70, 0x35, 0x1A, 0x8B, 0xD5, 0xE1, 0x38, 0x65, 0x9E, 0xE2, 0xDD, 0x22,
0x9A, 0x0D, 0xEE, 0x31, 0x4A, 0x40, 0x1C, 0x83, 0x31, 0xD8, 0x54, 0xF1, 0x16, 0x37, 0x11, 0x56,
0x75, 0x1A, 0x7F, 0xCA, 0xEC, 0x69, 0xEA, 0x5D, 0x29, 0xC2, 0xD9, 0x00, 0xE2, 0x48, 0x8C, 0x7A,
0xB8, 0x1A, 0x31, 0x38, 0x92, 0x64, 0xBA, 0xF9, 0xBF, 0x18, 0xBE, 0xFA, 0x76, 0xCE, 0x06, 0x95,
0x18, 0x82, 0x38, 0x7E, 0x6F, 0x94, 0x97, 0x71, 0x89, 0x6F, 0x55, 0x4F, 0x4D, 0xF4, 0x8B, 0x36,
0x21, 0x67, 0x33, 0x1E, 0x22, 0xD6, 0x7F, 0xD9, 0x54, 0xE9, 0x88, 0x43, 0xBA, 0x71, 0x3F, 0xA6,
0xF9, 0xE6, 0x10, 0x45, 0x9F, 0xB3, 0xC1, 0x8E, 0x01, 0x88, 0x63, 0xE2, 0x5E, 0x2F, 0xC6, 0x3B,
0x19, 0xFB, 0x4A, 0x15, 0xAA, 0x51, 0xB8, 0xF1, 0x09, 0x7E, 0x04, 0x0D, 0xCE, 0x86, 0x35, 0x1B,
0xF4, 0x53, 0x5D, 0x02, 0xE2, 0xC8, 0x38, 0xD1, 0xDF, 0x54, 0xD7, 0xA2, 0x1A, 0xCD, 0x7F, 0x33,
0xCD, 0x52, 0xB5, 0x90, 0xE6, 0xED, 0x9A, 0x3C, 0xB3, 0xB1, 0x79, 0x5A, 0x00, 0xE2, 0xE8, 0x78,
0x2C, 0x9B, 0xAA, 0x09, 0x89, 0x71, 0xB2, 0x63, 0x1C, 0xD1, 0x6C, 0xE4, 0x99, 0x0D, 0x9C, 0x0D,
0xDC, 0xE9, 0xF8, 0x38, 0xD9, 0xDB, 0x54, 0x33, 0xBE, 0x54, 0x59, 0x85, 0xF2, 0x27, 0xD5, 0x26,
0x18, 0x19, 0x14, 0xD8, 0x14, 0xE1, 0x6C, 0x60, 0x4F, 0xCF, 0xFF, 0xAD, 0x23, 0xFE, 0x4D, 0xDC,
0xD9, 0xEB, 0x36, 0x11, 0x05, 0x51, 0x78, 0x11, 0x24, 0x28, 0x9D, 0x71, 0xE3, 0x16, 0x27, 0x05,
0x29, 0x51, 0x48, 0x01, 0x35, 0x58, 0x49, 0x0D, 0x76, 0x78, 0x03, 0x7E, 0x4A, 0x24, 0xC4, 0xDA,
0x1D, 0x12, 0x88, 0x85, 0x07, 0x40, 0xF0, 0xB8, 0x44, 0x77, 0xCD, 0x7C, 0x3B, 0x1C, 0x7B, 0x75,
0xB3, 0x93, 0xBB, 0xCC, 0x0B, 0x58, 0x57, 0x67, 0x7E, 0xCE, 0x9C, 0x9D, 0x19, 0xBF, 0xB3, 0x68,
0x14, 0x18, 0xCF, 0x13, 0x8C, 0xB6, 0x6E, 0x24, 0xAE, 0x1A, 0xF7, 0xD3, 0xB9, 0xCC, 0xD9, 0xC0,
0x6C, 0x52, 0xC5, 0x00, 0xC4, 0x80, 0x1D, 0x91, 0x54, 0x15, 0x46, 0xEA, 0x06, 0x30, 0x62, 0x51,
0x3F, 0xD5, 0x61, 0xFE, 0x25, 0xCC, 0x26, 0x91, 0x37, 0x66, 0xC1, 0x42, 0x30, 0xAE, 0xF7, 0xC2,
0x08, 0x53, 0xCD, 0x38, 0x37, 0x16, 0x0C, 0xC5, 0xF3, 0xE7, 0xB4, 0x51, 0x08, 0x6F, 0x34, 0xFB,
0x21, 0x7B, 0xD4, 0x03, 0xA3, 0x67, 0xAA, 0x78, 0x2A, 0x4F, 0x8C, 0xE7, 0x53, 0x34, 0xF0, 0xC5,
0x3F, 0xCC, 0xA6, 0x11, 0xC5, 0x26, 0x44, 0xC6, 0xF7, 0x46, 0x23, 0x30, 0x6A, 0x52, 0x0D, 0x3C,
0x71, 0xAF, 0xB6, 0x78, 0xD5, 0xE9, 0x14, 0x91, 0xDD, 0x82, 0xF6, 0xB4, 0x37, 0x1A, 0x75, 0x31,
0x0E, 0x8B, 0x76, 0x19, 0x52, 0x14, 0xBD, 0x66, 0x23, 0xDF, 0x84, 0x83, 0xE5, 0x3F, 0x27, 0x1A,
0xE7, 0x9C, 0x1B, 0x15, 0x4F, 0x8D, 0xF9, 0x29, 0xEB, 0x0A, 0x80, 0x28, 0x02, 0x78, 0xA8, 0xFC,
0xEB, 0xD7, 0x7F, 0xB7, 0xA7, 0xAA, 0x30, 0xC6, 0x9F, 0x48, 0xB2, 0x91, 0x76, 0x1F, 0xE1, 0x0D,
0xEE, 0x16, 0xAD, 0x1B, 0x7D, 0x30, 0x76, 0x58, 0xDC, 0x5C, 0xE6, 0x8D, 0x62, 0x14, 0x7C, 0x8A,
0x2C, 0xF5, 0x7C, 0x47, 0xBB, 0x2F, 0x65, 0x3F, 0x54, 0x37, 0xFA, 0x60, 0xA4, 0x36, 0xEA, 0xB5,
0xD1, 0xE8, 0xA5, 0x10, 0xE6, 0x16, 0x61, 0xE0, 0x30, 0x1B, 0xBE, 0x27, 0xC6, 0xED, 0x74, 0x1F,
0x8C, 0xF2, 0xBD, 0x71, 0x2A, 0xD3, 0x7F, 0x81, 0x50, 0x44, 0x3E, 0x4D, 0x20, 0xA6, 0xF9, 0x5A,
0xC7, 0x6C, 0xA8, 0x18, 0x61, 0xBB, 0x6B, 0x44, 0x55, 0x60, 0x74, 0xAD, 0xB1, 0xD4, 0x8D, 0x49,
0x84, 0xDA, 0xA8, 0x7C, 0x7A, 0xE5, 0x14, 0x0D, 0xAD, 0x18, 0xF1, 0xB6, 0xB1, 0x11, 0x18, 0x77,
0x7E, 0xA8, 0xC2, 0x53, 0x07, 0x3F, 0x11, 0xD1, 0xE6, 0xCC, 0xCF, 0x2D, 0x7A, 0xCD, 0x46, 0x56,
0xA3, 0xA2, 0xFD, 0x86, 0x46, 0x23, 0xFB, 0x8D, 0x68, 0x71, 0xBE, 0xFA, 0x07, 0x54, 0x1B, 0xB7,
0x74, 0x82, 0x9F, 0xBE, 0xC1, 0x4F, 0xA5, 0x51, 0x0C, 0xD9, 0xEF, 0x84, 0x62, 0x0F, 0x8C, 0x27,
0x5D, 0xF5, 0x1F, 0x8B, 0xFB, 0x29, 0xCA, 0x9B, 0x2B, 0x8A, 0x8D, 0xF4, 0x18, 0x51, 0x9B, 0x99,
0xA7, 0x7A, 0x18, 0x17, 0xBB, 0x64, 0xE3, 0xC1, 0xC5, 0x5F, 0xFA, 0xA8, 0x2E, 0x8A, 0xA2, 0x81,
0x4B, 0x8F, 0x11, 0x26, 0xAA, 0xFD, 0xB3, 0x38, 0xF4, 0x54, 0xD7, 0xC6, 0x77, 0xAA, 0xC9, 0x40,
0x3F, 0xD5, 0x8A, 0x41, 0x51, 0x0C, 0xD0, 0xD3, 0x8C, 0x69, 0x23, 0x81, 0x71, 0xC5, 0x46, 0x15,
0x09, 0x67, 0x68, 0x4A, 0xF5, 0xBA, 0x14, 0xF9, 0x14, 0xF9, 0xD4, 0x3A, 0xC5, 0x46, 0xE9, 0x69,
0x3C, 0xE1, 0x18, 0x8C, 0xBF, 0xBA, 0x30, 0x2E, 0x57, 0xAE, 0x6E, 0xA8, 0xA7, 0x0E, 0x06, 0x91,
0x27, 0x22, 0x9F, 0x5A, 0x3E, 0x25, 0xD9, 0xDC, 0x7A, 0xC2, 0xD1, 0xA4, 0xAA, 0x22, 0xCE, 0xD4,
0x25, 0x9C, 0x10, 0x88, 0x7C, 0xAB, 0x69, 0xA7, 0x4F, 0xD9, 0x34, 0xB5, 0x64, 0x53, 0x20, 0xE1,
0x74, 0x61, 0x6C, 0x37, 0xAA, 0x10, 0x71, 0x10, 0xAA, 0x08, 0xC6, 0x50, 0xBF, 0x4F, 0xDD, 0xF7,
0x20, 0xD6, 0xF4, 0xC2, 0x85, 0x12, 0x0E, 0x30, 0xDA, 0x5E, 0xBC, 0x7A, 0x2A, 0xC1, 0x38, 0x8C,
0xBC, 0xD1, 0x64, 0x9C, 0x77, 0x87, 0xF9, 0xAD, 0x28, 0x7E, 0xAB, 0x6E, 0xDF, 0x2E, 0x89, 0x46,
0xDB, 0xE1, 0x94, 0xB6, 0x11, 0x12, 0x07, 0xBF, 0x09, 0x5C, 0x08, 0xF3, 0xCD, 0x30, 0x45, 0x91,
0x36, 0xEA, 0x56, 0xED, 0x70, 0xEB, 0xA9, 0x4D, 0xBB, 0xC3, 0xC1, 0xB6, 0xB1, 0xEB, 0x37, 0x44,
0x8A, 0x0B, 0xCC, 0xF5, 0x9D, 0xF9, 0xD1, 0x4C, 0x5F, 0x14, 0x1F, 0x56, 0x05, 0x6C, 0xFD, 0x1D,
0xD9, 0x98, 0x35, 0x55, 0xA7, 0xFE, 0x3B, 0x4F, 0x25, 0x18, 0xF3, 0x41, 0x54, 0x3F, 0x85, 0xBC,
0xB9, 0x4E, 0xF1, 0x6B, 0x55, 0xC2, 0x4E, 0x5D, 0xF9, 0x07, 0x46, 0x3C, 0xF5, 0xC4, 0xA6, 0x8D,
0xC8, 0xA9, 0x03, 0xE8, 0xA9, 0x5F, 0x36, 0xF5, 0x4D, 0xC6, 0xA6, 0x48, 0x51, 0x44, 0xC3, 0xE1,
0x8D, 0xDB, 0xE5, 0x3F, 0x3B, 0x36, 0x02, 0xC3, 0x19, 0x18, 0x8C, 0xFB, 0x2F, 0x30, 0xD0, 0x64,
0xBC, 0x2F, 0xC0, 0xC0, 0x45, 0xC3, 0x81, 0x8C, 0xFF, 0x64, 0x4D, 0xC5, 0x31, 0x1C, 0x19, 0x6F,
0x98, 0x0C, 0x9A, 0x5C, 0xD4, 0x65, 0xD3, 0xA4, 0xBC, 0x59, 0xC9, 0xF8, 0x52, 0x95, 0xB1, 0xFB,
0x1D, 0x18, 0x5F, 0x02, 0x63, 0xBB, 0x6C, 0xDC, 0xBE, 0xD1, 0xCE, 0xA9, 0xDB, 0x39, 0x95, 0xC9,
0x80, 0xC9, 0x45, 0x27, 0xDA, 0xC8, 0xB4, 0x54, 0xDF, 0x5C, 0x66, 0xBC, 0x34, 0x02, 0xE3, 0xE3,
0xF7, 0xC0, 0x68, 0x8A, 0x2A, 0xE3, 0x0D, 0x32, 0x2C, 0x36, 0x60, 0xD6, 0x9D, 0xB3, 0x44, 0xD4,
0xFD, 0x4D, 0xEB, 0xA7, 0x3F, 0xAA, 0x52, 0x76, 0x09, 0x8C, 0x93, 0x67, 0x0E, 0x46, 0x29, 0x8D,
0x5C, 0xE1, 0x1E, 0x32, 0x4B, 0x84, 0x68, 0x43, 0x51, 0xA4, 0xC9, 0x28, 0x40, 0xDE, 0x50, 0x1B,
0x0D, 0xC6, 0x4F, 0xD5, 0x61, 0x47, 0x19, 0xEF, 0x9C, 0x8C, 0x35, 0x9E, 0x6A, 0x93, 0xFF, 0x37,
0x5F, 0x19, 0xD6, 0x95, 0x8C, 0xAB, 0x4E, 0xC9, 0x68, 0x4A, 0x90, 0x37, 0xFC, 0x69, 0x8B, 0xE2,
0xBA, 0xF9, 0x58, 0xDD, 0x4B, 0x28, 0x6E, 0x89, 0xAA, 0x0A, 0x1C, 0xE8, 0x1B, 0xD9, 0x6E, 0x4A,
0x33, 0xAC, 0x2B, 0x19, 0xBC, 0xB0, 0x9C, 0x9F, 0xD2, 0x35, 0x26, 0x18, 0x3F, 0x54, 0x77, 0xBA,
0x57, 0x2A, 0x16, 0xBE, 0x34, 0xA6, 0x60, 0x94, 0xC6, 0x3F, 0xFF, 0xA2, 0x0D, 0xE3, 0x52, 0x3A,
0xB8, 0xB8, 0x96, 0xAD, 0x7D, 0xB5, 0x38, 0x89, 0x6B, 0x2B, 0xEF, 0x6B, 0xDA, 0x46, 0x0E, 0x38,
0xB8, 0x60, 0x6C, 0xB9, 0xF8, 0x64, 0xD8, 0x59, 0xA2, 0xE4, 0xA8, 0xF2, 0x25, 0xA3, 0xB4, 0x9F,
0x42, 0xE2, 0x9A, 0xEB, 0x1F, 0x79, 0x04, 0x51, 0x75, 0x07, 0x1C, 0x68, 0xA8, 0x40, 0x31, 0xEF,
0x85, 0x5A, 0x14, 0xCF, 0xF9, 0xBC, 0xCF, 0xA0, 0x4D, 0x81, 0x26, 0x43, 0x49, 0x5C, 0x3A, 0xB6,
0x72, 0xF0, 0x97, 0xC5, 0x69, 0xBB, 0xE1, 0x97, 0x1B, 0xF2, 0xDC, 0x94, 0xA2, 0xA8, 0xCA, 0xDB,
0x8A, 0xE5, 0xA8, 0xEF, 0x45, 0xFD, 0x14, 0x7D, 0x23, 0xC5, 0xFB, 0xDD, 0x9A, 0x45, 0x5C, 0x3C,
0x95, 0x8F, 0x54, 0x36, 0xD9, 0x78, 0x13, 0x10, 0x8F, 0xF5, 0x68, 0x0F, 0xE7, 0x5E, 0x52, 0xC9,
0xC0, 0x4F, 0x4B, 0xD9, 0x9A, 0x95, 0x88, 0xB7, 0x1B, 0x4A, 0xE3, 0x72, 0x85, 0xA7, 0x12, 0x8C,
0xAD, 0x65, 0xBD, 0x50, 0x8B, 0xA2, 0x26, 0x9B, 0xF4, 0xC2, 0x62, 0xF9, 0x14, 0x4F, 0x65, 0xD6,
0xFC, 0xA2, 0x85, 0x11, 0x0D, 0x67, 0x4B, 0xC5, 0xCF, 0x6E, 0x12, 0x8C, 0x0F, 0x04, 0x44, 0xBD,
0xC0, 0xE0, 0x3E, 0xEF, 0x17, 0xF3, 0x53, 0x3C, 0x95, 0x73, 0x32, 0xB3, 0xBA, 0x36, 0x0D, 0x87,
0x37, 0x12, 0x8C, 0xC7, 0xA4, 0xD4, 0x0C, 0x10, 0xB9, 0xF7, 0x42, 0x51, 0x54, 0xE5, 0x0D, 0x3F,
0x2D, 0x68, 0x1C, 0x05, 0x3A, 0xF8, 0x7B, 0x32, 0x46, 0x3F, 0x6F, 0x24, 0x03, 0xC5, 0xBC, 0x17,
0x6A, 0x51, 0x44, 0x04, 0x87, 0x82, 0x97, 0xF5, 0x53, 0x3C, 0xF5, 0x61, 0x62, 0xE5, 0xA9, 0x35,
0xB6, 0xD2, 0x48, 0xF5, 0xCF, 0x0F, 0x46, 0x5E, 0x07, 0x77, 0xD3, 0x19, 0x62, 0x44, 0x9B, 0xEC,
0x91, 0xB7, 0xB8, 0xA7, 0x56, 0xC9, 0xDE, 0xD6, 0x1B, 0x72, 0xAA, 0x13, 0x54, 0xD3, 0x0B, 0x6D,
0x02, 0x27, 0x1B, 0xC4, 0x6B, 0xA3, 0x28, 0x5A, 0xB6, 0x41, 0xB4, 0x59, 0xAF, 0xE9, 0xA3, 0x4A,
0x1A, 0x02, 0xDF, 0x45, 0x5D, 0xBB, 0x76, 0x83, 0xCA, 0x28, 0x28, 0xE6, 0x81, 0x08, 0x03, 0xEF,
0x19, 0x04, 0xAF, 0xCA, 0xDB, 0xA9, 0xF5, 0xDC, 0xB3, 0x76, 0x12, 0xC7, 0xDA, 0x0D, 0x8B, 0x46,
0xC6, 0xC5, 0x12, 0x8C, 0xD9, 0x20, 0x6A, 0x51, 0xA4, 0xC9, 0xD8, 0xA4, 0x92, 0x51, 0xA8, 0xDF,
0x57, 0x9E, 0xFA, 0x79, 0xEB, 0xB3, 0xA6, 0x53, 0x59, 0xEF, 0xEF, 0x15, 0x1C, 0xC9, 0x37, 0x02,
0xA2, 0x26, 0x1B, 0x8A, 0xA2, 0x8A, 0x36, 0xD9, 0x5F, 0x86, 0xE3, 0xF3, 0x1B, 0x49, 0xFE, 0x4A,
0xF9, 0xA6, 0xEE, 0xF0, 0xD4, 0x25, 0xC1, 0x68, 0x0B, 0x71, 0x3C, 0xB1, 0x17, 0x44, 0xDA, 0x28,
0x2D, 0x8A, 0x88, 0x36, 0x6B, 0xF4, 0xD3, 0xC2, 0xF6, 0xD4, 0xBE, 0x5D, 0xFE, 0x4A, 0x30, 0x9A,
0x12, 0x67, 0x67, 0xC6, 0x69, 0xA8, 0x28, 0x8C, 0xBD, 0x20, 0xE2, 0xA7, 0x28, 0xC4, 0x7A, 0x81,
0xA1, 0x49, 0xBC, 0x6A, 0x0C, 0x3B, 0xB2, 0x88, 0xBF, 0x48, 0xC2, 0xB8, 0xEF, 0xA8, 0x08, 0x46,
0x4E, 0xC5, 0xE6, 0x81, 0xE8, 0x65, 0x7E, 0x2B, 0x8A, 0xAC, 0xB8, 0x19, 0xE9, 0x28, 0x6E, 0x77,
0xAC, 0x99, 0x99, 0xD5, 0xE4, 0x54, 0xF3, 0x54, 0x82, 0x91, 0x94, 0x9A, 0x95, 0x6C, 0x44, 0xD1,
0x58, 0xC9, 0xB8, 0x14, 0xD4, 0xA6, 0xB0, 0xBD, 0xB2, 0xCC, 0xD3, 0x8A, 0xC6, 0x76, 0x12, 0x2F,
0x39, 0x2A, 0xC1, 0x68, 0x30, 0xE6, 0xF8, 0x29, 0xDF, 0xBE, 0x29, 0x8A, 0x2A, 0x82, 0xFF, 0xA8,
0x46, 0xB6, 0xBB, 0x35, 0x04, 0xC7, 0xE4, 0x0D, 0xB7, 0xD8, 0x00, 0x8A, 0x59, 0x7E, 0xCA, 0x38,
0x3F, 0x17, 0x6D, 0x64, 0x10, 0x7C, 0x5C, 0x4B, 0xD7, 0xD4, 0xF6, 0x07, 0xE3, 0xB1, 0xE4, 0x1B,
0x7D, 0xA2, 0xDE, 0xD1, 0xF0, 0x45, 0x11, 0x0A, 0xCE, 0xF8, 0xE9, 0x98, 0xF6, 0x7A, 0xFB, 0xB1,
0x11, 0x4F, 0x75, 0xC1, 0xC8, 0x10, 0x55, 0x06, 0xB3, 0x99, 0x03, 0xA2, 0x2B, 0x8A, 0xE4, 0xD3,
0xA4, 0x36, 0x8C, 0x6D, 0xA7, 0xB5, 0x27, 0x38, 0x04, 0x23, 0x6B, 0x54, 0x19, 0x4F, 0x94, 0xCB,
0x4B, 0xDC, 0xEA, 0xE3, 0xB6, 0x14, 0x8B, 0xED, 0xA3, 0xDA, 0x11, 0xC1, 0x68, 0xAA, 0x38, 0xC1,
0x88, 0xA3, 0xE6, 0xB6, 0x51, 0x9C, 0x79, 0xE3, 0x56, 0x1F, 0xA2, 0x8D, 0xD1, 0xAA, 0x31, 0xED,
0xA0, 0x21, 0x18, 0xAF, 0x70, 0x54, 0x04, 0x63, 0x2D, 0x8C, 0xFA, 0x44, 0xFD, 0x2B, 0xBE, 0x4E,
0xA7, 0x68, 0xF9, 0xB4, 0x0E, 0xEC, 0x64, 0xC4, 0x3E, 0xE4, 0x00, 0xA3, 0x9F, 0x33, 0xF6, 0x2C,
0x35, 0xD7, 0x4F, 0xB5, 0x28, 0x26, 0x14, 0x6D, 0x29, 0xBA, 0xFA, 0x0F, 0xF6, 0x7B, 0x47, 0x30,
0xA6, 0x7C, 0x03, 0x83, 0xCB, 0x79, 0xE2, 0x5C, 0x66, 0x88, 0xF5, 0x4B, 0x06, 0x25, 0x63, 0x5C,
0xBB, 0x34, 0x4F, 0x25, 0x18, 0x9F, 0x68, 0x30, 0x66, 0xC8, 0x52, 0x32, 0xD5, 0xE7, 0x44, 0x70,
0xBA, 0x8C, 0xD1, 0x6D, 0x96, 0xE6, 0x37, 0xF6, 0x06, 0x23, 0x29, 0xB5, 0x27, 0x14, 0x99, 0x96,
0xE2, 0xB3, 0xE9, 0xE2, 0x85, 0x6C, 0x9B, 0xD2, 0x65, 0x8C, 0x6B, 0x87, 0xBB, 0x83, 0x11, 0x14,
0xA7, 0x39, 0x4F, 0x9C, 0xCB, 0x02, 0x98, 0xBD, 0x90, 0x7C, 0x3A, 0x36, 0x7B, 0x63, 0xC4, 0xC1,
0x05, 0xE3, 0x72, 0x99, 0x82, 0x51, 0xF2, 0x8D, 0x3E, 0x51, 0x92, 0x8D, 0x4E, 0x30, 0x30, 0x9C,
0x19, 0x13, 0xA6, 0xE2, 0xFD, 0xF1, 0xEE, 0x60, 0x3C, 0xB1, 0x27, 0xCE, 0x79, 0x62, 0xCF, 0x87,
0x0C, 0x94, 0x37, 0x16, 0x6B, 0x5C, 0x93, 0x31, 0x3E, 0x7B, 0xE3, 0x46, 0xA5, 0x0B, 0xC6, 0x85,
0xD7, 0x6F, 0xA6, 0x74, 0x8C, 0xFA, 0x44, 0xFD, 0x53, 0xCC, 0x33, 0xFC, 0x94, 0x45, 0xC5, 0xCD,
0x26, 0xE5, 0xD3, 0xF1, 0xD9, 0x1B, 0x29, 0xB5, 0xF1, 0xC1, 0xE8, 0x9B, 0x8D, 0x7D, 0x85, 0x51,
0xFD, 0x14, 0x7E, 0x8A, 0xF2, 0xE6, 0xF3, 0xE9, 0xB7, 0xEA, 0xFF, 0xD8, 0x1F, 0xE6, 0xCE, 0x5E,
0xB9, 0x89, 0x20, 0x08, 0xC2, 0x5B, 0x70, 0x50, 0x10, 0x42, 0xA4, 0x98, 0x80, 0x9F, 0x14, 0x25,
0xE4, 0x86, 0xDC, 0x81, 0xA5, 0x32, 0x99, 0xA8, 0x02, 0x97, 0xF5, 0x04, 0x27, 0x87, 0x44, 0xA7,
0x90, 0x08, 0x9B, 0xB7, 0x85, 0xDB, 0x5B, 0xEF, 0x77, 0xA3, 0x5E, 0xED, 0x91, 0xED, 0xEC, 0x1B,
0x74, 0xF5, 0xED, 0x74, 0xCF, 0xCF, 0xCE, 0xAD, 0x8E, 0x03, 0x97, 0x71, 0x3E, 0xBC, 0x61, 0x0B,
0x8D, 0xF5, 0x68, 0xA3, 0x7F, 0x1D, 0x42, 0x14, 0x89, 0xA7, 0x3F, 0x43, 0x9B, 0xF3, 0xFC, 0x78,
0x38, 0x93, 0x50, 0x19, 0xD5, 0x58, 0xFA, 0xE9, 0x10, 0xF1, 0x54, 0x16, 0x82, 0x47, 0x84, 0x2D,
0xAE, 0x22, 0x21, 0x75, 0xA6, 0x8C, 0x84, 0x9B, 0x14, 0x6F, 0xA8, 0x33, 0x2E, 0xED, 0xE8, 0x85,
0x45, 0x7D, 0x93, 0xD1, 0xF7, 0x6D, 0xAE, 0x22, 0x43, 0x1C, 0x83, 0x29, 0x8A, 0xF3, 0xA5, 0xF2,
0xBA, 0xB8, 0x0E, 0x31, 0xBD, 0x71, 0x23, 0x9E, 0x32, 0x43, 0x4C, 0x3C, 0x6D, 0x70, 0x15, 0x71,
0xA9, 0x71, 0x24, 0xCE, 0xD4, 0xA8, 0x2E, 0x62, 0xBC, 0xA9, 0x09, 0x63, 0x51, 0xF7, 0x53, 0x71,
0x51, 0x93, 0x8C, 0xA1, 0xD1, 0x55, 0x64, 0xA2, 0x0A, 0x65, 0xDC, 0xCC, 0x59, 0xFC, 0x58, 0x61,
0xD1, 0x92, 0x58, 0xCC, 0xF7, 0x6F, 0x4C, 0x3C, 0x6D, 0x62, 0x50, 0x09, 0xA9, 0xBD, 0xB9, 0x8C,
0x57, 0x74, 0x52, 0x97, 0x59, 0xD4, 0x78, 0x5A, 0x48, 0x32, 0x7A, 0x16, 0x83, 0xB6, 0x39, 0x2F,
0xF3, 0x65, 0xA4, 0x0C, 0x37, 0x61, 0xAC, 0x84, 0x54, 0x89, 0xA7, 0xA5, 0x31, 0xE9, 0xFD, 0x7E,
0xFA, 0xF9, 0xD7, 0xB1, 0x95, 0x41, 0xA5, 0xDF, 0xC8, 0x65, 0x8C, 0xC9, 0x06, 0x16, 0xEE, 0x7C,
0x52, 0xAC, 0x24, 0x92, 0x47, 0xB1, 0xD2, 0x86, 0xD5, 0xFC, 0x6D, 0x0C, 0x2A, 0x89, 0x7F, 0xC4,
0x68, 0xFC, 0x4D, 0x41, 0x18, 0x97, 0x57, 0x2E, 0x22, 0x19, 0xE2, 0x4F, 0xA9, 0xF4, 0xB7, 0x39,
0x07, 0xA3, 0x1A, 0x69, 0xC8, 0x08, 0x23, 0x7E, 0x0E, 0xA2, 0xB2, 0x28, 0x92, 0x41, 0x3C, 0x6D,
0x50, 0xB6, 0xD1, 0x3F, 0xA9, 0x15, 0xE2, 0x8D, 0x86, 0x54, 0x85, 0xA8, 0x2B, 0x17, 0x19, 0xE7,
0x37, 0xF1, 0x74, 0x08, 0x0D, 0xCF, 0xA7, 0x38, 0x66, 0x6C, 0xCB, 0xFE, 0x92, 0x31, 0x0A, 0x44,
0xF2, 0xFD, 0x79, 0xE9, 0xAD, 0xFC, 0x66, 0xB8, 0x41, 0x05, 0x55, 0x26, 0xC6, 0x11, 0x7F, 0x4A,
0xE2, 0x55, 0x16, 0x97, 0x4A, 0x6F, 0xDB, 0xEF, 0x89, 0xC4, 0x88, 0xB0, 0x41, 0x05, 0x55, 0x1A,
0xE3, 0x83, 0x69, 0xA5, 0xE6, 0x71, 0x7F, 0x1A, 0x70, 0x02, 0x51, 0x4B, 0x1A, 0xD6, 0xDA, 0x7C,
0xDB, 0xE6, 0x1F, 0x2C, 0xB0, 0x87, 0xB8, 0xD9, 0xE9, 0x8E, 0x24, 0x1B, 0xB4, 0x19, 0xB3, 0x6A,
0xBC, 0x29, 0x40, 0xAC, 0x94, 0xDE, 0x52, 0xFD, 0x74, 0xF7, 0x96, 0x21, 0xE2, 0xB6, 0xC2, 0x8F,
0x11, 0x9F, 0x35, 0x6F, 0x22, 0xC2, 0xAA, 0xF6, 0xEB, 0xFF, 0x5C, 0xD2, 0xAC, 0x7B, 0x9E, 0x5C,
0xDC, 0x75, 0x74, 0xDC, 0xDA, 0x79, 0x70, 0x8C, 0xB8, 0x84, 0x54, 0x54, 0xA3, 0x9C, 0x14, 0x9F,
0xEB, 0xD6, 0x50, 0x7A, 0xDB, 0x85, 0xAF, 0xE9, 0x6F, 0x8A, 0xFC, 0xCC, 0xA5, 0xE1, 0xB9, 0x96,
0x90, 0x0A, 0x8D, 0x35, 0x16, 0xB5, 0x35, 0x8C, 0x64, 0xEC, 0xC2, 0x87, 0x14, 0x4F, 0xDB, 0x0B,
0x7F, 0x9C, 0x35, 0xD2, 0x90, 0x4A, 0x2D, 0xB5, 0xC2, 0xA2, 0xB4, 0x86, 0xB1, 0x36, 0x97, 0xA1,
0x23, 0x9E, 0xC6, 0x16, 0x7F, 0x93, 0x83, 0x6A, 0xA4, 0xCC, 0x3F, 0x85, 0xD4, 0xCF, 0x57, 0xB1,
0x96, 0x4A, 0x52, 0x2C, 0x10, 0xF5, 0x2A, 0xE6, 0x39, 0x94, 0x0C, 0x31, 0xEC, 0xE7, 0xFF, 0x3A,
0x09, 0x6D, 0xCF, 0xCB, 0x18, 0x52, 0x89, 0x37, 0x34, 0x36, 0xD0, 0x7E, 0x85, 0xA8, 0x57, 0x91,
0x61, 0xA2, 0x08, 0xF1, 0x43, 0xEF, 0x26, 0xDA, 0x84, 0x2E, 0x19, 0x71, 0x20, 0x32, 0xB5, 0x59,
0x6E, 0x6B, 0x94, 0xAF, 0xE2, 0x88, 0xF1, 0x0A, 0x88, 0x1D, 0x08, 0x9B, 0x65, 0xFC, 0xE4, 0x1A,
0x23, 0xC6, 0xFB, 0x1C, 0x52, 0xB3, 0x30, 0xAE, 0xC5, 0xC1, 0xA1, 0xFC, 0xB0, 0x58, 0xBA, 0x8A,
0x37, 0xBB, 0x38, 0x0B, 0xDA, 0x0F, 0x3E, 0xA2, 0x4D, 0x08, 0x87, 0xCC, 0x22, 0x46, 0x9C, 0x5C,
0xE3, 0xB5, 0x42, 0xD4, 0x84, 0xDF, 0x66, 0xC3, 0x91, 0xC5, 0xF0, 0x6E, 0x8C, 0x36, 0xED, 0xD3,
0x8C, 0x78, 0x6E, 0xE7, 0x16, 0xCE, 0x18, 0x71, 0x84, 0xB1, 0x08, 0xF1, 0x8D, 0xBD, 0x8A, 0x64,
0x19, 0x7F, 0x46, 0x88, 0x5D, 0x44, 0xD8, 0xAC, 0xBE, 0xA8, 0x15, 0x2A, 0x12, 0x7F, 0xD2, 0xA9,
0x65, 0x16, 0x67, 0x53, 0xC4, 0xEB, 0xF9, 0x3B, 0xBE, 0xCB, 0x69, 0x6A, 0xF9, 0xC8, 0x6F, 0x24,
0x1A, 0x1D, 0x84, 0x51, 0xAB, 0x70, 0x62, 0xC4, 0x15, 0x22, 0xAF, 0x32, 0xE4, 0x7D, 0xD4, 0x25,
0xEB, 0xE7, 0x9B, 0x16, 0x35, 0x34, 0x9D, 0x22, 0xF1, 0x5F, 0xC7, 0x74, 0x4A, 0xAA, 0x37, 0x72,
0x17, 0xB5, 0xBC, 0x08, 0xC4, 0xEE, 0xE8, 0x25, 0xDA, 0x8C, 0xE9, 0x54, 0xC4, 0x68, 0xDA, 0x53,
0x52, 0x4A, 0x55, 0x88, 0x92, 0x2B, 0xB2, 0x84, 0xE1, 0x72, 0xBA, 0xE4, 0x3E, 0xBC, 0x4D, 0x12,
0xC6, 0x21, 0x6B, 0xFF, 0x8F, 0xE4, 0xC3, 0xC9, 0xFB, 0x15, 0xA2, 0xF5, 0x36, 0xFA, 0xF4, 0x3B,
0x41, 0x7C, 0xE7, 0x25, 0xDA, 0x44, 0x61, 0x34, 0x2E, 0x15, 0x61, 0xAC, 0xB2, 0x98, 0x11, 0x8E,
0x07, 0xC9, 0x80, 0xC5, 0xAE, 0x79, 0x09, 0x15, 0x61, 0x3C, 0x49, 0xA7, 0x3E, 0x23, 0x8C, 0xB5,
0x70, 0x43, 0xD9, 0x86, 0xA2, 0x86, 0x81, 0x18, 0x1E, 0x3C, 0x64, 0x52, 0xF9, 0xCE, 0xF4, 0x77,
0xB0, 0xB8, 0x11, 0x7B, 0x53, 0x65, 0x51, 0x9E, 0x7E, 0x67, 0x88, 0xEF, 0x5D, 0xD8, 0xB7, 0x99,
0x30, 0xDE, 0x4D, 0xC2, 0x48, 0x1B, 0x55, 0xED, 0x0D, 0x10, 0x69, 0x2C, 0xAE, 0x19, 0x7B, 0x3B,
0x85, 0xD8, 0xA5, 0xDE, 0x69, 0xFB, 0x33, 0x09, 0xE3, 0x9D, 0x0A, 0x63, 0xD9, 0xDE, 0xE8, 0x6E,
0xA2, 0x98, 0x0E, 0x23, 0x19, 0x19, 0x62, 0x78, 0x70, 0x61, 0xDF, 0x72, 0xC6, 0xD8, 0x67, 0x61,
0xFC, 0x92, 0x84, 0x91, 0xBC, 0xBF, 0x0C, 0xF1, 0x64, 0xEE, 0xED, 0x4A, 0x21, 0xAE, 0x1C, 0x24,
0x8B, 0x79, 0xA5, 0x81, 0xED, 0x6B, 0x90, 0xF7, 0x57, 0x58, 0x64, 0x87, 0x16, 0x0B, 0xA5, 0xD3,
0x0C, 0xC3, 0x23, 0xC4, 0xCE, 0x41, 0xB2, 0x18, 0xCF, 0xB3, 0xB4, 0x77, 0xEB, 0x8C, 0x30, 0x56,
0x59, 0x24, 0x93, 0x62, 0x8C, 0x18, 0x88, 0xE1, 0xC1, 0x83, 0x7D, 0x1B, 0x27, 0xFD, 0x33, 0x8B,
0x56, 0x18, 0x3F, 0x56, 0x3F, 0x54, 0x34, 0x83, 0x21, 0x86, 0x4D, 0x2A, 0xF4, 0x67, 0x88, 0x2B,
0x1F, 0x01, 0x35, 0x2E, 0xA6, 0xC8, 0x4F, 0x36, 0xB6, 0x19, 0x21, 0xA5, 0x8D, 0x1A, 0x8B, 0x24,
0x8B, 0x34, 0x87, 0x61, 0xB1, 0xF3, 0x11, 0x50, 0x47, 0xED, 0x27, 0x63, 0xDC, 0x8C, 0x87, 0x52,
0x6A, 0xC1, 0xDE, 0xE0, 0xDF, 0x08, 0xA8, 0x66, 0x2B, 0xF8, 0x3D, 0x2C, 0x86, 0x5B, 0x17, 0x01,
0x35, 0x6A, 0xFF, 0xE1, 0x71, 0x88, 0x6A, 0x5B, 0x2D, 0x50, 0x29, 0x8B, 0x0C, 0x68, 0x12, 0x50,
0x67, 0x10, 0x57, 0x2E, 0x02, 0x6A, 0x08, 0xD7, 0xB0, 0x48, 0x11, 0x2E, 0x6B, 0xFF, 0x59, 0x16,
0x91, 0xC5, 0x0B, 0xFB, 0xBC, 0x7D, 0x06, 0xF1, 0xA9, 0x07, 0x87, 0x3A, 0x6D, 0x50, 0x39, 0x50,
0x4A, 0xC5, 0xDE, 0x10, 0x6E, 0x8A, 0x2C, 0xCA, 0x3E, 0xBB, 0x02, 0xC4, 0xF0, 0x3D, 0xB8, 0x38,
0x2F, 0x4C, 0xC3, 0x9F, 0xBB, 0x88, 0x49, 0x2D, 0xB3, 0x68, 0x1D, 0x2A, 0x01, 0x75, 0x0E, 0xF1,
0x55, 0x70, 0x71, 0xFE, 0xD9, 0x9B, 0x34, 0x97, 0x4A, 0xDE, 0x6F, 0xAA, 0x37, 0x02, 0x11, 0xFF,
0x36, 0x6B, 0x2C, 0x6E, 0x67, 0x2C, 0x7A, 0x3B, 0xCF, 0x27, 0xED, 0xD7, 0xB1, 0x0D, 0xEC, 0x8D,
0x42, 0x84, 0xC5, 0x24, 0xFC, 0x04, 0x54, 0x87, 0x10, 0xBB, 0x24, 0x8C, 0xD8, 0x1B, 0xDE, 0x32,
0x28, 0x8B, 0x2A, 0x8B, 0x6B, 0x1B, 0x50, 0x3D, 0x42, 0x7C, 0x92, 0x58, 0x94, 0xBC, 0xDF, 0x9A,
0x54, 0x65, 0x51, 0x65, 0x71, 0xEF, 0x94, 0xC5, 0x20, 0xF6, 0xC6, 0x3C, 0x0F, 0x13, 0x88, 0x65,
0x59, 0x8C, 0x0E, 0x75, 0xEF, 0x94, 0x45, 0xEC, 0x4D, 0xB1, 0x06, 0xB7, 0xC8, 0xE2, 0xC5, 0x49,
0x40, 0xED, 0x7D, 0x98, 0xB6, 0x53, 0x7B, 0xD3, 0x57, 0xEC, 0x4D, 0x95, 0x45, 0x95, 0x45, 0x97,
0x10, 0xAF, 0x27, 0xD5, 0x48, 0x10, 0xC5, 0xA4, 0x56, 0x58, 0x5C, 0x9F, 0xC8, 0xE2, 0xDE, 0x2B,
0x8B, 0x9F, 0x0A, 0xD5, 0x9B, 0x45, 0x16, 0xC9, 0x16, 0x91, 0xC5, 0x51, 0x33, 0x7C, 0xB2, 0xB8,
0x2A, 0x55, 0x6F, 0x96, 0x59, 0x64, 0xBA, 0xCF, 0xEE, 0xEC, 0x3B, 0x38, 0x84, 0x18, 0x1D, 0xDC,
0x39, 0x93, 0xAA, 0xA2, 0x11, 0x0F, 0xCA, 0x3F, 0xCF, 0x33, 0xF6, 0x71, 0x7C, 0xF1, 0x57, 0x70,
0x77, 0x46, 0x07, 0x97, 0x0B, 0x54, 0x4B, 0x26, 0x95, 0x2A, 0x2A, 0x2D, 0x9B, 0x13, 0x16, 0x1D,
0x42, 0x8C, 0x83, 0x70, 0x6A, 0x52, 0x61, 0x51, 0x21, 0x52, 0x45, 0x85, 0xC5, 0x29, 0xA0, 0xFA,
0x64, 0x71, 0x5C, 0xD7, 0x34, 0x30, 0xD2, 0x20, 0x26, 0xB5, 0xC2, 0x22, 0xE6, 0x66, 0xBB, 0x99,
0x20, 0xFA, 0x64, 0xF1, 0x69, 0x44, 0xB8, 0x68, 0x52, 0x95, 0x45, 0xD2, 0xC5, 0x49, 0x16, 0x7F,
0x4F, 0x8B, 0xC1, 0xDB, 0x77, 0x14, 0xCB, 0x53, 0x1B, 0x6A, 0x52, 0x97, 0x59, 0xCC, 0xB3, 0xC4,
0xE6, 0x49, 0xE6, 0xE0, 0x10, 0xE2, 0xA2, 0x49, 0x55, 0x88, 0xF8, 0x37, 0x63, 0x6E, 0xDC, 0xB2,
0xF8, 0x7F, 0x26, 0x55, 0x58, 0x24, 0x21, 0xB6, 0x16, 0xD5, 0x41, 0xEB, 0xFB, 0x2F, 0x75, 0x67,
0xAF, 0x1B, 0x45, 0x10, 0x04, 0x61, 0x16, 0xE3, 0x03, 0x32, 0x84, 0x84, 0x80, 0xD0, 0x22, 0x00,
0x52, 0x83, 0x84, 0x09, 0xD1, 0x61, 0x61, 0x52, 0x38, 0x10, 0xC4, 0x88, 0xBF, 0x90, 0x84, 0x5B,
0x9E, 0x60, 0x97, 0x07, 0x00, 0xE3, 0xB7, 0xC5, 0xCB, 0xCC, 0xFA, 0xBB, 0xBE, 0xDA, 0xD9, 0xDD,
0xEC, 0x8A, 0x8D, 0x1C, 0xBA, 0x55, 0xD3, 0xD3, 0xD5, 0xD5, 0xD5, 0x73, 0xFA, 0xFD, 0x19, 0x25,
0xA9, 0x21, 0x44, 0x45, 0x71, 0x09, 0x8A, 0x67, 0xBE, 0x28, 0x7E, 0x99, 0x4F, 0x52, 0x15, 0xC5,
0xDE, 0xC8, 0xF0, 0x36, 0xA3, 0x58, 0x9F, 0x5B, 0xC1, 0xFD, 0xBE, 0x77, 0x33, 0x49, 0xAA, 0xA2,
0x48, 0x8C, 0x5D, 0x59, 0x4C, 0xE4, 0xA6, 0x76, 0x0C, 0xF1, 0x68, 0x36, 0x49, 0x55, 0x14, 0x99,
0x4A, 0xF5, 0x28, 0x7A, 0xCC, 0x31, 0x64, 0x8A, 0x1A, 0x46, 0x8C, 0x63, 0xEE, 0x22, 0x45, 0x31,
0xCD, 0x6C, 0x92, 0x72, 0x93, 0x50, 0x74, 0x0C, 0xF1, 0x0E, 0x23, 0xC6, 0xB0, 0xE0, 0xAF, 0x24,
0x55, 0x51, 0xD4, 0x46, 0xC3, 0x63, 0xE0, 0x56, 0x68, 0x35, 0x36, 0x57, 0x19, 0xC4, 0xE6, 0x5F,
0xCC, 0x45, 0x1A, 0x8D, 0x44, 0x51, 0x2D, 0x43, 0xBC, 0xBA, 0x4D, 0x52, 0x9F, 0x0B, 0x49, 0x9D,
0x44, 0x11, 0x8A, 0x6A, 0xE1, 0x43, 0x91, 0x59, 0x38, 0x24, 0x15, 0xEF, 0x8D, 0x92, 0x54, 0x45,
0x51, 0x1A, 0x8D, 0x2E, 0x17, 0x2D, 0x43, 0x5C, 0x6C, 0x91, 0xD4, 0x55, 0x49, 0x49, 0x2D, 0xA3,
0x48, 0x2F, 0xD5, 0x6D, 0x81, 0xF9, 0x7D, 0xFB, 0x58, 0xFD, 0x04, 0x45, 0xE8, 0x4D, 0x44, 0x11,
0x1A, 0x8E, 0x8A, 0x9A, 0x16, 0xA5, 0x2C, 0x43, 0xBC, 0x92, 0x50, 0x14, 0x1F, 0x9C, 0x92, 0x54,
0x45, 0x91, 0xBD, 0xCC, 0xBC, 0x03, 0xEE, 0x60, 0xB2, 0x2D, 0x3A, 0x1A, 0x20, 0xA9, 0xC7, 0x42,
0x6F, 0xC6, 0x51, 0xCC, 0x1E, 0xC6, 0x84, 0xA2, 0x65, 0x88, 0x97, 0x5B, 0x48, 0x6A, 0xDF, 0x6A,
0xE8, 0xB8, 0x7F, 0x3C, 0x17, 0x3F, 0x79, 0xA3, 0x58, 0xE5, 0x5C, 0x44, 0x83, 0xE3, 0xA0, 0x52,
0xFB, 0x0B, 0x28, 0x3E, 0xDF, 0x46, 0xD1, 0xC3, 0x4E, 0x24, 0x21, 0x0A, 0x49, 0x95, 0xAD, 0xE9,
0xD9, 0x28, 0x9A, 0x38, 0xA6, 0x86, 0xDA, 0xFE, 0x48, 0x52, 0xF5, 0xBA, 0x99, 0x46, 0x31, 0xDF,
0xA8, 0x16, 0x2E, 0x5B, 0xF9, 0x6A, 0xB5, 0xF9, 0x2B, 0x49, 0x1D, 0xBD, 0x51, 0x99, 0x2E, 0x7A,
0x18, 0x89, 0x35, 0xC4, 0x39, 0x24, 0xF5, 0x86, 0xA2, 0x48, 0x8C, 0xA0, 0x58, 0xB7, 0xCD, 0x25,
0xC3, 0xEF, 0x0F, 0x24, 0x15, 0x67, 0xB1, 0xD0, 0x9B, 0x02, 0x8A, 0xAC, 0xD9, 0x24, 0x14, 0x3D,
0x43, 0xFC, 0x52, 0x26, 0xA9, 0xD3, 0x28, 0x22, 0xC0, 0xA5, 0x1D, 0x69, 0x0F, 0x0F, 0xAA, 0x84,
0x58, 0x22, 0xA9, 0x3A, 0xB9, 0xA9, 0x86, 0x51, 0x64, 0xBA, 0x68, 0x62, 0xB3, 0x15, 0xF1, 0xA6,
0x84, 0xA2, 0xAE, 0xDC, 0x54, 0xE5, 0x5C, 0xCC, 0xCD, 0x94, 0xC3, 0x6A, 0xC6, 0x60, 0x88, 0x28,
0xA9, 0x4A, 0x52, 0x35, 0x44, 0x45, 0x11, 0x19, 0xB5, 0xDB, 0xE3, 0xF7, 0xFB, 0x4E, 0xA6, 0x49,
0x2A, 0x21, 0xFE, 0xFB, 0x46, 0x72, 0xD1, 0xC3, 0xF2, 0x2E, 0x21, 0xCE, 0x23, 0xA9, 0x84, 0x78,
0xB3, 0x5C, 0x17, 0x4D, 0x5C, 0xFD, 0xAA, 0x32, 0xAA, 0x92, 0xFA, 0x7C, 0x1E, 0x8A, 0x5A, 0x17,
0x1D, 0x36, 0xC1, 0x06, 0x43, 0x2C, 0x2B, 0xA9, 0x34, 0xC5, 0xDB, 0x28, 0x1E, 0x82, 0xE2, 0x66,
0x5D, 0x6C, 0x0D, 0xBD, 0x45, 0xA0, 0x38, 0xEA, 0x49, 0xBD, 0xA1, 0x28, 0xD2, 0x2F, 0xC2, 0x51,
0x3D, 0x43, 0x7C, 0x40, 0x2E, 0x8E, 0x78, 0x52, 0x15, 0x45, 0x3A, 0x0D, 0xC6, 0x8B, 0x26, 0x4B,
0x44, 0x1A, 0xA2, 0xAC, 0xDC, 0x88, 0x27, 0xB5, 0x84, 0xE2, 0x73, 0x45, 0xD1, 0x70, 0x12, 0x9E,
0x50, 0x0C, 0x7A, 0xF8, 0x4A, 0x16, 0xA7, 0x26, 0x50, 0xA4, 0x5F, 0xF4, 0x0D, 0xB1, 0xA9, 0x69,
0x35, 0xD8, 0x28, 0x8E, 0xB5, 0x1F, 0x14, 0xB1, 0x16, 0x89, 0x76, 0xE3, 0xB0, 0x3E, 0x5C, 0x40,
0x91, 0x47, 0x61, 0x40, 0x91, 0x56, 0x23, 0x86, 0xA8, 0x28, 0xBE, 0xE9, 0x51, 0xB4, 0xD8, 0x90,
0x1E, 0x9E, 0xDB, 0x34, 0x23, 0xE3, 0xFE, 0x32, 0x8A, 0x78, 0x8A, 0x41, 0xD1, 0x72, 0x86, 0x7A,
0x07, 0x14, 0x0B, 0x4A, 0xEA, 0x14, 0x8A, 0xE8, 0xA8, 0x26, 0x9B, 0xA7, 0x32, 0x9A, 0x12, 0x14,
0x45, 0x0F, 0x1F, 0xCF, 0xC5, 0xCD, 0xF9, 0xA2, 0xC9, 0xBA, 0x9B, 0xA2, 0x18, 0x4C, 0x1B, 0xC4,
0xA8, 0xEF, 0xC1, 0x6D, 0x85, 0x28, 0xCE, 0xF0, 0xDA, 0x63, 0x45, 0x5A, 0x43, 0x64, 0xC3, 0x2F,
0xA1, 0xB8, 0x0A, 0xAD, 0x86, 0x86, 0xB8, 0xB1, 0xA6, 0x11, 0x2D, 0x70, 0xAE, 0x73, 0x9B, 0x07,
0x6D, 0x8E, 0x51, 0x4D, 0x1B, 0xA3, 0x28, 0xDE, 0x63, 0xC9, 0xF6, 0xE2, 0xC1, 0x50, 0x8B, 0x97,
0x43, 0x46, 0x4A, 0xBF, 0x58, 0x6F, 0xE6, 0xA1, 0x78, 0xCC, 0x96, 0x86, 0xAB, 0x56, 0x9C, 0x50,
0x84, 0xC1, 0xCD, 0x46, 0x11, 0x83, 0x3F, 0x53, 0xE2, 0xDA, 0x52, 0x48, 0x4D, 0x28, 0xE2, 0x2E,
0x12, 0x67, 0x71, 0xFE, 0x82, 0x39, 0x7C, 0x18, 0x45, 0x57, 0x95, 0x11, 0x14, 0xE3, 0xCB, 0x85,
0xFA, 0xA2, 0xAF, 0xA2, 0xF8, 0x18, 0xF7, 0x54, 0x42, 0xD1, 0x53, 0x65, 0x3C, 0x02, 0x45, 0x1A,
0xC6, 0x99, 0x28, 0x22, 0xDE, 0x64, 0x14, 0x2D, 0x5E, 0x47, 0xD1, 0x10, 0x43, 0x2E, 0x16, 0xDE,
0x68, 0x10, 0x14, 0x91, 0xE0, 0x68, 0xFB, 0x7F, 0x9C, 0xA3, 0x68, 0x29, 0xC1, 0x0D, 0xA1, 0xA8,
0x53, 0x0D, 0x45, 0xF1, 0xDE, 0x10, 0x8A, 0x16, 0xCF, 0xF8, 0x0C, 0x2A, 0x70, 0xBA, 0xC4, 0xA8,
0x28, 0xDE, 0xD8, 0x0A, 0xF1, 0x50, 0xE5, 0x70, 0x57, 0xF1, 0xE6, 0x44, 0xAE, 0x1B, 0xF1, 0x87,
0xE7, 0x10, 0xB5, 0xED, 0x57, 0x39, 0xDC, 0xB2, 0x27, 0x7E, 0x97, 0x43, 0x3C, 0x4D, 0x3D, 0xB1,
0xAE, 0xA2, 0x12, 0xA2, 0x4A, 0x70, 0x69, 0x4F, 0x03, 0x39, 0xBC, 0xB1, 0x6C, 0x18, 0xFF, 0x85,
0xD8, 0x6C, 0xA3, 0xB8, 0x54, 0x14, 0x4B, 0x0D, 0x63, 0x5A, 0x62, 0xC8, 0x55, 0xC3, 0xB2, 0x61,
0xEC, 0x26, 0x53, 0xFD, 0xDB, 0x8C, 0xBF, 0x75, 0x57, 0x83, 0x77, 0x99, 0xE7, 0x34, 0x8C, 0x8D,
0x65, 0x37, 0xF5, 0x07, 0x14, 0x7F, 0x87, 0xF7, 0x52, 0x98, 0x4D, 0x11, 0xE2, 0x54, 0xC3, 0x58,
0x5B, 0xB6, 0x1A, 0x5D, 0x88, 0xE3, 0x06, 0xAA, 0xFC, 0x49, 0x88, 0xD2, 0x6A, 0x9C, 0x87, 0x68,
0xD9, 0x6A, 0xD4, 0x01, 0x45, 0x11, 0x6F, 0x80, 0x91, 0x10, 0xF3, 0x46, 0xD1, 0x7F, 0xD3, 0x6A,
0xD4, 0x83, 0x28, 0x2E, 0xA5, 0xED, 0x57, 0x14, 0x69, 0x35, 0x28, 0x1A, 0x96, 0x86, 0x86, 0x16,
0x14, 0x11, 0x6F, 0x28, 0xFD, 0xF3, 0x50, 0x7C, 0xEB, 0x3C, 0x0A, 0xAF, 0xDA, 0x76, 0x5A, 0xBC,
0x51, 0x92, 0xCA, 0xDC, 0x26, 0x93, 0xD4, 0x6C, 0x0E, 0x77, 0x1C, 0xA2, 0x5E, 0x1E, 0x46, 0x71,
0x29, 0x28, 0x96, 0x49, 0x2A, 0xF4, 0xC6, 0x93, 0xA4, 0xEE, 0x81, 0x22, 0xE2, 0xCD, 0x34, 0x8A,
0x71, 0x4E, 0x0C, 0x49, 0xAD, 0x0D, 0x67, 0x53, 0xE9, 0xDD, 0x3D, 0x8C, 0xC5, 0x48, 0x70, 0xF4,
0xC4, 0xCA, 0xC3, 0xCB, 0x24, 0xD5, 0x90, 0xC1, 0xDD, 0xEA, 0x51, 0xE4, 0x69, 0x46, 0xDE, 0x4A,
0x03, 0x45, 0x09, 0x51, 0xE8, 0x4D, 0x26, 0xA9, 0x86, 0x7A, 0xF8, 0xF5, 0x14, 0x21, 0x07, 0x95,
0x66, 0x8A, 0x07, 0x36, 0x09, 0x51, 0xE8, 0x0D, 0x27, 0xD5, 0x56, 0x2C, 0xBE, 0xDA, 0x6A, 0x5D,
0x3C, 0x06, 0xC5, 0xF2, 0x41, 0x45, 0x0F, 0xE7, 0xA0, 0x9E, 0x5A, 0xD2, 0x9B, 0x6B, 0x39, 0x17,
0x9B, 0x0D, 0xE7, 0x0D, 0xB9, 0x58, 0x42, 0xB1, 0xAC, 0xA4, 0x1A, 0xCA, 0x8C, 0x77, 0x40, 0xF1,
0xF7, 0x92, 0xBA, 0x58, 0x40, 0xB1, 0x1A, 0xD0, 0xC3, 0x8F, 0x03, 0x49, 0x35, 0x94, 0x19, 0x8F,
0xFA, 0x1B, 0xF5, 0xC7, 0xEB, 0x1B, 0x7B, 0x08, 0xA9, 0xE4, 0xA2, 0x34, 0x8C, 0xE8, 0xE1, 0xDD,
0x07, 0xBD, 0x49, 0x28, 0x1A, 0x0A, 0x54, 0x27, 0x19, 0xC5, 0x8F, 0xE7, 0xFF, 0xD8, 0xFE, 0x19,
0x75, 0x11, 0x14, 0xA5, 0x61, 0x14, 0x25, 0xD5, 0x5C, 0xA0, 0x4A, 0x1D, 0xF1, 0xF7, 0x67, 0xDD,
0xDF, 0x0F, 0x83, 0x1C, 0x5E, 0x42, 0x51, 0xF5, 0x70, 0xEE, 0x1B, 0xCB, 0xDA, 0xDF, 0xB5, 0x8B,
0x3F, 0x5F, 0xA5, 0xBF, 0xDF, 0xFF, 0x0E, 0x72, 0xF8, 0x38, 0x8A, 0xBC, 0x3E, 0xD5, 0x6B, 0x70,
0xAE, 0xEA, 0x4D, 0xDD, 0xB6, 0x1F, 0xB2, 0x80, 0x5D, 0x9D, 0x15, 0x50, 0xD4, 0x56, 0x03, 0x22,
0x8E, 0x7A, 0x93, 0x51, 0xB4, 0x93, 0x36, 0xAA, 0xF6, 0xD7, 0xC5, 0xED, 0x70, 0x85, 0xA1, 0x86,
0x0A, 0xA9, 0x84, 0xA8, 0xF4, 0x86, 0x29, 0xAA, 0xA3, 0xB4, 0x51, 0x6D, 0xB4, 0x3E, 0x77, 0xF1,
0x32, 0x16, 0x50, 0xE4, 0xC9, 0x9B, 0x48, 0x6F, 0xEC, 0xFB, 0xFE, 0xFE, 0x7B, 0x19, 0xC7, 0xC4,
0x8A, 0xA2, 0xD0, 0x9B, 0x58, 0x18, 0x8D, 0xFB, 0xFE, 0xFE, 0xFB, 0xBA, 0x39, 0x26, 0x1E, 0x47,
0xF1, 0x40, 0xFB, 0x7E, 0x73, 0xF3, 0x74, 0xEA, 0x1C, 0x71, 0xC1, 0xCD, 0x46, 0x31, 0x16, 0x46,
0xE3, 0xB1, 0x46, 0xFA, 0x16, 0x8C, 0x89, 0xA7, 0x73, 0xF1, 0x66, 0x42, 0x31, 0xD3, 0x1B, 0xFF,
0xB1, 0x46, 0xFA, 0x9E, 0x76, 0x21, 0x4E, 0xA2, 0x38, 0xD9, 0xF7, 0x37, 0x96, 0x9A, 0x7F, 0x4E,
0x45, 0xB1, 0x6C, 0x28, 0x8A, 0x54, 0x0D, 0x1D, 0x6B, 0xFC, 0x53, 0xA8, 0x3C, 0x3B, 0xC6, 0x3E,
0x15, 0x51, 0xE0, 0xCA, 0x28, 0x2A, 0xBD, 0xD1, 0xC2, 0xE8, 0x5B, 0x35, 0x16, 0x67, 0x61, 0xDF,
0x66, 0x02, 0xC5, 0x83, 0x52, 0x61, 0xB4, 0x5D, 0x7F, 0x3B, 0xFF, 0x9E, 0xE0, 0x2D, 0x1A, 0x47,
0x51, 0x0B, 0xE3, 0xF3, 0x50, 0x18, 0x7D, 0xAB, 0xC6, 0x67, 0x55, 0xC3, 0x41, 0x11, 0xEF, 0xB4,
0x14, 0xC6, 0xA5, 0x74, 0x8C, 0xAE, 0x55, 0x63, 0x2F, 0x4B, 0xC5, 0x1F, 0x91, 0xA7, 0xA4, 0xD3,
0x18, 0xBC, 0x6E, 0x28, 0x8C, 0x39, 0x19, 0x1B, 0xD7, 0xAA, 0xB1, 0xC8, 0x53, 0x62, 0xD4, 0x70,
0x45, 0x51, 0x0A, 0xE3, 0xA0, 0xCD, 0xBF, 0x36, 0xD4, 0x19, 0x53, 0x2A, 0xAE, 0xC3, 0x94, 0xB8,
0xD0, 0x2F, 0x0E, 0x15, 0xC6, 0xC7, 0x48, 0xA9, 0xA6, 0xBD, 0x46, 0x9F, 0x8A, 0xD8, 0xFC, 0x50,
0xA7, 0x4A, 0x28, 0x6A, 0x61, 0xE4, 0x4A, 0xB5, 0x5D, 0x9A, 0xDE, 0xC3, 0x3D, 0x15, 0xE6, 0x8B,
0x28, 0x70, 0x84, 0xA8, 0x7D, 0x7F, 0x9C, 0x14, 0x9B, 0x2E, 0x6A, 0x2E, 0x70, 0x4F, 0xC5, 0x73,
0x8A, 0x8E, 0x1A, 0x51, 0x3C, 0x00, 0xC5, 0x7C, 0xA5, 0x3A, 0x2B, 0x54, 0x29, 0x15, 0x71, 0x4F,
0xAD, 0x32, 0x8A, 0x87, 0x82, 0xA2, 0x5C, 0xA9, 0x2A, 0xC2, 0xFD, 0xB0, 0x25, 0xE2, 0xA7, 0x03,
0x1E, 0xB8, 0x47, 0x39, 0x15, 0x35, 0x44, 0xEE, 0x1B, 0xED, 0x35, 0x3C, 0x47, 0x37, 0xE7, 0xB2,
0x0D, 0x6B, 0xA8, 0xD0, 0xF0, 0x39, 0x28, 0x72, 0x50, 0x33, 0x4B, 0x5D, 0xBB, 0x5E, 0xA9, 0x77,
0x19, 0x12, 0x4F, 0xA3, 0x98, 0x0B, 0x23, 0x28, 0xE2, 0xF3, 0x37, 0xBE, 0x52, 0x5F, 0x30, 0x41,
0x0D, 0x02, 0x5C, 0x01, 0x45, 0xED, 0x35, 0xEC, 0xAF, 0xD4, 0x6A, 0x1D, 0x50, 0x0C, 0x43, 0xE2,
0x78, 0xA3, 0x6A, 0x61, 0x44, 0xBE, 0xB1, 0xD6, 0x36, 0xF6, 0xD7, 0x58, 0xE0, 0x28, 0xFD, 0x62,
0x67, 0x90, 0xC2, 0x88, 0x08, 0x07, 0x4B, 0xFD, 0xE1, 0x39, 0x0D, 0xBF, 0x8F, 0x05, 0xAE, 0xD8,
0x68, 0x10, 0x22, 0x85, 0x51, 0xE5, 0x1B, 0x5B, 0xB3, 0xDF, 0xE7, 0xB0, 0x4B, 0xBC, 0x4A, 0x20,
0x6A, 0xBB, 0x38, 0xC6, 0xE0, 0x18, 0xF8, 0x5B, 0x36, 0xFE, 0x7B, 0xFD, 0x03, 0xF0, 0x90, 0x9B,
0x65, 0x19, 0xC5, 0xFC, 0x6D, 0xA2, 0xE8, 0xDF, 0xF8, 0x5F, 0x4F, 0x4F, 0xFA, 0xE4, 0xE9, 0x22,
0x6B, 0x61, 0x82, 0x62, 0x28, 0x8C, 0xFC, 0x1E, 0x83, 0xF8, 0x19, 0xFD, 0x5E, 0x69, 0x38, 0xE1,
0x61, 0xA6, 0x44, 0x6E, 0x30, 0x32, 0x46, 0x14, 0xB5, 0x30, 0x1E, 0x6E, 0x5F, 0xA9, 0x9E, 0x5A,
0x6A, 0x55, 0xAF, 0x63, 0x59, 0x9C, 0x83, 0x22, 0x0C, 0x2E, 0x5E, 0xA9, 0x9E, 0xEE, 0x9B, 0xFD,
0x46, 0xCA, 0x22, 0x28, 0xF6, 0x11, 0x6A, 0x88, 0xC3, 0x2C, 0xD5, 0xD3, 0x79, 0x7B, 0xBF, 0xC9,
0x4F, 0x6C, 0x48, 0xCF, 0x2F, 0xE4, 0x46, 0xAF, 0x54, 0x65, 0xA9, 0xA7, 0x86, 0x8F, 0x50, 0xFD,
0x91, 0x0B, 0x55, 0xCE, 0xA9, 0x86, 0xC8, 0x49, 0x8D, 0x5A, 0xAA, 0xA5, 0x67, 0xF3, 0x0A, 0xEB,
0x44, 0xC1, 0x8D, 0x7A, 0x6F, 0x0A, 0xC5, 0x03, 0x58, 0x2A, 0x4F, 0x89, 0x75, 0x07, 0xD5, 0xEE,
0xBE, 0xB9, 0xCD, 0x0E, 0xEA, 0x1B, 0x76, 0x6D, 0x58, 0x99, 0x1A, 0x47, 0x91, 0x17, 0x53, 0x7C,
0xF9, 0x4D, 0xF5, 0xAE, 0x5F, 0xB5, 0xC1, 0xE3, 0x87, 0x72, 0x13, 0x74, 0x0D, 0xB9, 0x52, 0x21,
0xE2, 0xF8, 0x36, 0x0C, 0xF9, 0xCD, 0xE5, 0x56, 0x2E, 0x54, 0xF5, 0xF7, 0x6B, 0x88, 0xB0, 0x54,
0x8A, 0xFF, 0xDB, 0x7E, 0xB3, 0xC8, 0xEC, 0x2D, 0xB1, 0xEB, 0x6D, 0x1B, 0x2E, 0xD4, 0xE3, 0xA9,
0x83, 0x5A, 0x15, 0xDA, 0x29, 0x5E, 0xD7, 0x76, 0xEB, 0xA7, 0x4E, 0xDA, 0xB5, 0x32, 0x54, 0x36,
0xA6, 0x2E, 0x50, 0xE4, 0x64, 0x6B, 0x32, 0x2E, 0x49, 0xC6, 0x0E, 0x45, 0xB3, 0x37, 0x53, 0x2E,
0xD7, 0x38, 0x8A, 0x59, 0x5E, 0xA4, 0x2C, 0xC6, 0x10, 0xF5, 0x4A, 0x8D, 0xDA, 0x06, 0x8B, 0x8C,
0x46, 0xFA, 0xCD, 0x82, 0x54, 0xE4, 0x42, 0x0D, 0x7D, 0x86, 0x86, 0xA8, 0x72, 0xF1, 0xE6, 0xAC,
0xD8, 0xCE, 0x97, 0x7A, 0xD4, 0x06, 0x86, 0x4A, 0x43, 0xAC, 0x28, 0x6A, 0x88, 0x58, 0x53, 0xFA,
0x96, 0xD1, 0xB0, 0xD9, 0xA8, 0xEA, 0x36, 0xD0, 0xB7, 0x15, 0xE7, 0x14, 0x72, 0xA3, 0x21, 0xEA,
0xEF, 0xDB, 0x45, 0x7E, 0xE3, 0xF4, 0x0C, 0xD5, 0xE2, 0xDF, 0x7D, 0xCA, 0x4A, 0x98, 0xB6, 0x52,
0x84, 0xA8, 0x57, 0xEA, 0x16, 0x11, 0x0F, 0x3B, 0x29, 0x36, 0xC5, 0xFF, 0x28, 0xA5, 0x62, 0xF0,
0xA3, 0x2C, 0x41, 0x51, 0xCB, 0x22, 0x21, 0xEA, 0xAF, 0xDC, 0x30, 0x65, 0x34, 0x4A, 0xC6, 0xAA,
0x4E, 0xA9, 0xC8, 0x6D, 0x13, 0x18, 0xEA, 0x01, 0x28, 0x6A, 0x88, 0x5C, 0xA9, 0x3D, 0x85, 0xE3,
0xA4, 0x1A, 0x8D, 0xFC, 0xF7, 0xF3, 0xFA, 0x82, 0x2A, 0xE1, 0x87, 0x82, 0x62, 0xE1, 0xBE, 0xA1,
0x2D, 0x8E, 0x0F, 0x18, 0xAD, 0x4D, 0xEC, 0xC5, 0x47, 0xA4, 0x62, 0xE2, 0x36, 0xD8, 0x8A, 0xE6,
0x86, 0x88, 0x44, 0xB5, 0xEA, 0x8B, 0xBF, 0x53, 0x32, 0x56, 0x35, 0xA9, 0x18, 0x9A, 0x45, 0xBA,
0xC5, 0x10, 0xA2, 0x5E, 0xA9, 0x9C, 0x54, 0x4D, 0x46, 0x0B, 0x26, 0xBE, 0x68, 0x63, 0x55, 0x0C,
0x4B, 0xB6, 0x5A, 0x16, 0x35, 0x19, 0xE3, 0x2F, 0xF9, 0xF4, 0x9D, 0xBF, 0x53, 0x32, 0x76, 0xE7,
0x54, 0x52, 0x71, 0xB9, 0x94, 0xB2, 0x58, 0x0C, 0x11, 0x87, 0xD1, 0xA3, 0x98, 0x8C, 0x2E, 0x95,
0xB1, 0x3B, 0xA7, 0x0D, 0xA9, 0x48, 0xCD, 0xE0, 0x42, 0x1D, 0x0B, 0x51, 0xF9, 0x4D, 0x4C, 0x46,
0x07, 0xBF, 0xDF, 0xF5, 0xEE, 0x9C, 0x92, 0x8A, 0x38, 0x51, 0xE5, 0x42, 0x95, 0x10, 0x95, 0xDF,
0x3C, 0xB6, 0xAC, 0x8C, 0x27, 0x6D, 0xDB, 0x88, 0x84, 0x4A, 0x2A, 0x6A, 0x88, 0x7A, 0xA5, 0xC6,
0x64, 0xEC, 0x2D, 0x8D, 0x36, 0xB6, 0x86, 0xCB, 0x5D, 0x84, 0x4D, 0x07, 0x22, 0xA9, 0x08, 0xB7,
0x91, 0x0B, 0xB5, 0x74, 0xA5, 0x92, 0x8C, 0x4A, 0x53, 0xBF, 0x5D, 0xDA, 0xED, 0x77, 0x7B, 0xEB,
0x77, 0x26, 0xC4, 0x32, 0x0D, 0x8A, 0x12, 0x22, 0xFC, 0xA6, 0x9C, 0x8C, 0xCD, 0xEE, 0x05, 0xE3,
0xFC, 0xA3, 0x7D, 0x85, 0x54, 0x14, 0x14, 0xCB, 0xF7, 0x8D, 0x26, 0xA3, 0xC9, 0x40, 0x7C, 0xAF,
0xCD, 0xB7, 0xCD, 0xF6, 0x90, 0x9F, 0x36, 0xE3, 0xE6, 0xBC, 0x10, 0x19, 0xA4, 0x5E, 0xD0, 0x54,
0x8F, 0xF5, 0xF0, 0x07, 0x2D, 0xD4, 0x46, 0xAA, 0xA2, 0xDE, 0x36, 0xA3, 0x57, 0x6A, 0x4C, 0x46,
0x97, 0xA7, 0x61, 0xAA, 0x3A, 0x81, 0x78, 0x2A, 0x55, 0x11, 0x14, 0x25, 0x44, 0x4D, 0xC6, 0xED,
0xDF, 0xB8, 0x63, 0x40, 0xB5, 0x7B, 0x77, 0xCA, 0x7E, 0xBF, 0x07, 0x2E, 0x22, 0x31, 0xB7, 0xCD,
0x54, 0x88, 0xF0, 0x1B, 0x4D, 0xC6, 0xB3, 0xF5, 0xCE, 0x5F, 0x83, 0xCF, 0x3F, 0x4F, 0xD0, 0x9B,
0x89, 0xB1, 0x6A, 0x70, 0x50, 0x25, 0x15, 0x09, 0x71, 0x2C, 0x19, 0x51, 0x53, 0x9B, 0x9D, 0x94,
0x0D, 0x8A, 0x62, 0xB8, 0x4F, 0xA9, 0x8A, 0x72, 0x4E, 0x25, 0xC4, 0xF9, 0xC9, 0x58, 0xD7, 0xBB,
0x28, 0x1B, 0x14, 0x45, 0xBA, 0x0C, 0x74, 0xF0, 0xE0, 0x63, 0x38, 0x98, 0x0C, 0x51, 0x93, 0x71,
0x15, 0x04, 0x9C, 0xDD, 0xFE, 0x34, 0xC3, 0x97, 0x8B, 0x8A, 0xA1, 0xA9, 0x78, 0xC8, 0x39, 0x25,
0x15, 0x67, 0x24, 0x23, 0xBA, 0xBF, 0x83, 0x28, 0xFE, 0x97, 0xB8, 0x33, 0xD7, 0x95, 0x1A, 0x88,
0x82, 0x28, 0x6B, 0x40, 0x46, 0xC0, 0x22, 0x32, 0x20, 0x60, 0xC9, 0x10, 0x02, 0x41, 0xCA, 0x4E,
0xCE, 0x1E, 0xB3, 0x88, 0x89, 0x01, 0xE1, 0xF9, 0x01, 0x66, 0x52, 0x90, 0xB0, 0x79, 0x7F, 0x8B,
0xDC, 0xD5, 0x9E, 0xE3, 0xA6, 0x34, 0xB8, 0x69, 0xEC, 0x7E, 0x7C, 0x00, 0xA8, 0x54, 0xDB, 0xBD,
0xD7, 0x36, 0xA3, 0x1F, 0xEC, 0xD3, 0x73, 0x45, 0x48, 0x64, 0x40, 0xCD, 0x86, 0x98, 0x9A, 0x31,
0x3E, 0x66, 0x94, 0x19, 0x0F, 0x79, 0xC0, 0xB9, 0xBB, 0x43, 0x48, 0xD8, 0xA8, 0xF7, 0x09, 0x9B,
0x4B, 0x13, 0x10, 0xF7, 0x9B, 0x31, 0x19, 0x70, 0x6A, 0xEF, 0xC5, 0x84, 0x8D, 0x56, 0xC5, 0x64,
0xB4, 0x11, 0xC6, 0x29, 0x2B, 0xFA, 0x7C, 0x93, 0xBE, 0x9C, 0x42, 0x6D, 0x1C, 0xEA, 0xE3, 0xE2,
0xF3, 0x81, 0x44, 0x56, 0x45, 0x7E, 0xEB, 0xCD, 0xAC, 0x38, 0x01, 0xD1, 0xCC, 0xF8, 0x3C, 0x35,
0x63, 0xFD, 0x4C, 0x25, 0x6C, 0xB6, 0xF4, 0x3E, 0xEF, 0x12, 0xF3, 0xD4, 0x2D, 0x1F, 0x62, 0x6A,
0x46, 0xD1, 0xC8, 0xE3, 0xE2, 0xC3, 0xBA, 0xE0, 0x9C, 0xA4, 0xF6, 0xDB, 0x70, 0x23, 0x26, 0x4F,
0xB9, 0x83, 0x9B, 0x15, 0xF7, 0x94, 0xFF, 0x5E, 0x33, 0x8A, 0xC6, 0xCA, 0x4A, 0x65, 0xB2, 0x49,
0xE6, 0xD3, 0x50, 0x19, 0x1A, 0x6D, 0x98, 0xDE, 0x32, 0x20, 0xBA, 0x19, 0x05, 0x91, 0x27, 0xE2,
0x87, 0xD6, 0xFE, 0xC7, 0x21, 0x51, 0x79, 0x2A, 0x84, 0x13, 0x56, 0x9C, 0x32, 0x63, 0x7A, 0x14,
0x3F, 0xE4, 0xF6, 0xBF, 0x9A, 0x90, 0xC8, 0x8B, 0x6F, 0x41, 0xA8, 0xEC, 0x8A, 0xB9, 0x10, 0xA1,
0x51, 0x8F, 0x36, 0x2C, 0x53, 0xEB, 0xCE, 0xA9, 0xAC, 0x51, 0x90, 0xF8, 0x82, 0x27, 0xA7, 0x19,
0x3A, 0x05, 0x22, 0x66, 0xE4, 0xBD, 0x06, 0x1B, 0x70, 0x0E, 0xE7, 0x2A, 0x7E, 0x8A, 0x9F, 0x97,
0x08, 0xA5, 0xC8, 0x36, 0x2C, 0x12, 0x27, 0x8A, 0xDF, 0xCD, 0x48, 0xA6, 0xF2, 0x1E, 0x55, 0xCC,
0xD4, 0xEE, 0x6B, 0x53, 0xF9, 0x93, 0x4D, 0x7E, 0x71, 0x91, 0xFF, 0x15, 0x8D, 0x09, 0xDC, 0x46,
0x1B, 0xD3, 0xA9, 0x41, 0xC4, 0x8C, 0xBC, 0x0D, 0x27, 0xA9, 0xA2, 0xD4, 0x9A, 0x3F, 0x8E, 0x4E,
0x63, 0x34, 0x0C, 0x6F, 0x71, 0x04, 0x27, 0x4F, 0xB1, 0x22, 0x24, 0xE6, 0x99, 0x51, 0x5F, 0x33,
0x4A, 0xA8, 0xC9, 0x28, 0xBE, 0xA9, 0x7C, 0xA5, 0x7A, 0x1A, 0xD7, 0x7D, 0x85, 0x4D, 0xF2, 0x09,
0x11, 0x2F, 0x14, 0x99, 0x15, 0xF3, 0xCC, 0xA8, 0xF6, 0x7F, 0x4E, 0xA6, 0xD6, 0x7F, 0xEC, 0xCF,
0x8E, 0xC1, 0xBA, 0xAF, 0xDE, 0x17, 0xC6, 0xAC, 0xD1, 0x06, 0x88, 0x6E, 0xC6, 0x5B, 0xF6, 0xD5,
0x46, 0xCD, 0x75, 0xC3, 0x77, 0x8C, 0x56, 0x1F, 0xB9, 0x53, 0xFB, 0x3C, 0x39, 0x35, 0x2B, 0x66,
0x9A, 0x51, 0x34, 0x72, 0xDE, 0x10, 0x8D, 0x75, 0x4F, 0x38, 0xC7, 0xB5, 0x63, 0x10, 0x36, 0xEF,
0xED, 0xA4, 0x31, 0x59, 0x19, 0x40, 0x74, 0x33, 0x3E, 0x90, 0x52, 0x95, 0xA9, 0x91, 0xC6, 0x6D,
0xDD, 0xC0, 0xB9, 0x06, 0x89, 0xC9, 0xA6, 0xF8, 0x40, 0x2C, 0x12, 0x36, 0x06, 0x31, 0xCF, 0x8C,
0xEA, 0x8D, 0x90, 0xA9, 0x49, 0xE0, 0xD4, 0x9B, 0xC5, 0x8F, 0x35, 0x22, 0x91, 0xD7, 0x88, 0xD9,
0x14, 0x3D, 0x4F, 0xD1, 0x69, 0xBE, 0x19, 0x55, 0x1B, 0x64, 0xEA, 0x57, 0xBD, 0x4B, 0xF5, 0xFD,
0x48, 0xAD, 0x3F, 0x57, 0x77, 0x59, 0x43, 0xD8, 0x3C, 0x7C, 0xBE, 0x3B, 0xDA, 0x64, 0xE5, 0xA9,
0x2B, 0x95, 0x6D, 0x63, 0x9C, 0xA9, 0xBB, 0x6A, 0x6C, 0xEA, 0x3C, 0x6A, 0x84, 0xC4, 0x06, 0x12,
0x43, 0xD8, 0x78, 0x29, 0x5E, 0x36, 0x9D, 0x66, 0xE5, 0x8D, 0x67, 0x2A, 0x4A, 0xAD, 0xF1, 0x74,
0x03, 0x12, 0x37, 0x23, 0x12, 0xF5, 0x0B, 0xB6, 0x94, 0x62, 0x6E, 0x9E, 0xBA, 0x52, 0xF7, 0x64,
0xEA, 0xAA, 0xF6, 0xF2, 0x0F, 0x89, 0xEC, 0xC2, 0x90, 0x68, 0x79, 0x9A, 0x0B, 0xD1, 0x33, 0x95,
0x6A, 0xD4, 0x25, 0xAE, 0xA9, 0x74, 0xFA, 0x77, 0x12, 0xF5, 0xAC, 0xC6, 0x4A, 0xF1, 0xF2, 0xA4,
0x4E, 0x51, 0xAA, 0x67, 0x2A, 0xB3, 0xF8, 0x8B, 0x51, 0x35, 0x36, 0x8B, 0xBF, 0x82, 0xEB, 0x24,
0xB6, 0x8C, 0xA7, 0x94, 0x62, 0x2E, 0x89, 0x40, 0xDC, 0x9F, 0xA9, 0x2C, 0xC6, 0xFD, 0x87, 0xA9,
0x9B, 0xA5, 0x37, 0x63, 0x27, 0xB1, 0x1D, 0x16, 0xC5, 0x47, 0x22, 0xD1, 0x4A, 0x31, 0x13, 0x22,
0x4A, 0xC5, 0x8C, 0x16, 0x38, 0xD5, 0xF6, 0x8D, 0xE3, 0xC3, 0x74, 0xDA, 0xD1, 0x18, 0x6C, 0x8A,
0x13, 0x79, 0x3A, 0x65, 0xC6, 0xF4, 0xD9, 0x06, 0x34, 0xAA, 0x37, 0x6A, 0xD1, 0x78, 0x37, 0xED,
0x44, 0xC6, 0xD3, 0x07, 0x69, 0xED, 0x67, 0xE8, 0x14, 0x88, 0xAE, 0x54, 0x49, 0x55, 0xDF, 0x6D,
0xC4, 0xD3, 0x7F, 0x85, 0xB5, 0x91, 0x15, 0x43, 0xDB, 0x7E, 0xD4, 0x29, 0x24, 0xA2, 0x53, 0xAB,
0x8C, 0x3C, 0xA5, 0x5E, 0xF6, 0x4C, 0x1D, 0x2E, 0x71, 0x6D, 0x54, 0xEA, 0x66, 0xBB, 0x59, 0x9A,
0xC6, 0xD7, 0x90, 0xA8, 0xDA, 0x7F, 0x69, 0x08, 0x5D, 0xA7, 0x39, 0x10, 0x3D, 0x53, 0xFF, 0x08,
0x9C, 0x5A, 0xDB, 0xFF, 0x49, 0x48, 0x1C, 0x0D, 0xE0, 0x76, 0x96, 0x72, 0x12, 0xF3, 0xCD, 0x28,
0xA5, 0x42, 0x23, 0x81, 0xB3, 0xAE, 0xE1, 0xC6, 0xA3, 0x1F, 0x21, 0x71, 0x54, 0xFB, 0x90, 0x78,
0x13, 0x12, 0x0B, 0x20, 0x32, 0xE0, 0x58, 0x35, 0x42, 0xE3, 0xC2, 0xDD, 0x78, 0x01, 0x12, 0x99,
0xDD, 0x34, 0xBC, 0x31, 0xD9, 0x4C, 0xF4, 0xFE, 0x74, 0x6D, 0x78, 0x35, 0x26, 0x34, 0x2E, 0x75,
0x8B, 0xA3, 0xF5, 0xF5, 0x71, 0xD4, 0xF8, 0x3E, 0xCC, 0xAB, 0xE0, 0x25, 0x24, 0xA6, 0x34, 0xF2,
0x26, 0x95, 0xBB, 0x71, 0xD9, 0xE3, 0x3F, 0x85, 0x61, 0x5B, 0x54, 0x20, 0xF1, 0xD6, 0xAD, 0xB1,
0x4E, 0x45, 0x62, 0x09, 0xC4, 0x88, 0x90, 0x6A, 0x8C, 0x07, 0x55, 0x68, 0x5C, 0x6C, 0x6F, 0xE4,
0xB0, 0xD8, 0xDF, 0x4E, 0x0F, 0xD6, 0xEA, 0x44, 0x15, 0x86, 0x3F, 0x53, 0x84, 0x44, 0x74, 0x9A,
0xA9, 0x54, 0x32, 0x95, 0x95, 0x6A, 0xE7, 0x46, 0xF6, 0xC6, 0xD9, 0xD7, 0x7F, 0xB2, 0x66, 0xFB,
0x35, 0xEA, 0x74, 0xD5, 0xEE, 0x73, 0xA2, 0xE7, 0x69, 0x81, 0x19, 0x45, 0xA3, 0x16, 0xE3, 0xD4,
0x8D, 0xDA, 0x1B, 0x3F, 0xCD, 0x8C, 0x8D, 0xE1, 0x54, 0x08, 0x83, 0x4C, 0xCD, 0x89, 0xD4, 0xBE,
0x59, 0xB1, 0xC0, 0x8C, 0xD0, 0x68, 0x6E, 0x5C, 0xE4, 0x7D, 0x2A, 0xDE, 0x59, 0x1C, 0xC2, 0xA6,
0xD5, 0xDD, 0xCD, 0x6F, 0x36, 0x62, 0x31, 0x4F, 0xA7, 0x40, 0x74, 0x1A, 0xA9, 0x46, 0x21, 0x4C,
0xBA, 0x71, 0xA9, 0xC4, 0x79, 0xCD, 0x49, 0x0A, 0x27, 0x22, 0x53, 0xAF, 0x7D, 0x48, 0xCC, 0x57,
0xAA, 0x67, 0xEA, 0x70, 0x6D, 0xC4, 0x8D, 0xBA, 0x1B, 0xFF, 0x98, 0x1F, 0xE1, 0x75, 0x6D, 0x18,
0x91, 0xC4, 0xA1, 0x13, 0x59, 0x14, 0x19, 0xDE, 0x0A, 0x21, 0x92, 0xA9, 0x36, 0xE1, 0x98, 0x1B,
0x9B, 0x66, 0x81, 0x51, 0xF5, 0xB8, 0x2A, 0x51, 0x7D, 0x81, 0x13, 0x21, 0xD1, 0x6A, 0xDF, 0x74,
0x9A, 0xA9, 0x54, 0x68, 0xE4, 0x68, 0x9C, 0xB8, 0xB1, 0xE3, 0xFC, 0x3F, 0xFB, 0xE4, 0x96, 0x92,
0xA8, 0xF1, 0xD4, 0x16, 0x45, 0x5B, 0x86, 0xF3, 0x69, 0x64, 0x4E, 0xA5, 0x1A, 0xD5, 0x8D, 0xA9,
0x1B, 0x97, 0x91, 0xEA, 0x9D, 0x2D, 0x24, 0x0A, 0x21, 0x71, 0x1A, 0x48, 0xA4, 0x14, 0x3D, 0x6C,
0xCA, 0x95, 0x8A, 0x54, 0xA3, 0x1B, 0x3F, 0x88, 0xC6, 0x05, 0x4E, 0x55, 0x67, 0x85, 0x30, 0x3E,
0xD9, 0xD7, 0x67, 0x8A, 0x0A, 0x1B, 0x23, 0x91, 0xC6, 0x30, 0x88, 0x99, 0x4A, 0x75, 0x1A, 0xE9,
0xC6, 0x55, 0xBF, 0x37, 0x76, 0xA2, 0x91, 0x01, 0x60, 0x26, 0x23, 0x92, 0xA6, 0x92, 0xA9, 0x93,
0x88, 0x4C, 0xD1, 0x69, 0x01, 0x44, 0x68, 0x4C, 0x06, 0x55, 0xB9, 0x51, 0x34, 0xAE, 0x23, 0xC6,
0xCF, 0xB3, 0xF6, 0x05, 0x24, 0xC6, 0xAC, 0x99, 0x93, 0x44, 0x94, 0xCA, 0xEE, 0x0F, 0x8D, 0xFD,
0x23, 0x63, 0xDC, 0xA8, 0xB3, 0x71, 0x94, 0xEA, 0x8F, 0x39, 0x8D, 0xF8, 0x35, 0xAC, 0x50, 0x38,
0xF1, 0xE5, 0x3E, 0x12, 0xAD, 0x31, 0x0A, 0x68, 0x64, 0xC2, 0xD1, 0x14, 0xC7, 0xA4, 0x2A, 0x1A,
0x35, 0xAA, 0xCE, 0xF8, 0x8A, 0xC3, 0x39, 0x2D, 0x89, 0x51, 0xA7, 0xAB, 0xD8, 0xFA, 0x90, 0x68,
0xE3, 0x69, 0x29, 0x44, 0x0F, 0x1C, 0x66, 0x71, 0xF1, 0x28, 0x1A, 0x29, 0xC7, 0x99, 0xDA, 0xF1,
0x44, 0xFF, 0x37, 0xA5, 0x95, 0xF8, 0x82, 0x73, 0x06, 0x9D, 0x28, 0x12, 0x0B, 0x74, 0x8A, 0x52,
0xA9, 0x46, 0x30, 0x9A, 0x1B, 0x29, 0xC7, 0xB9, 0x22, 0xE7, 0xD8, 0xAF, 0xC1, 0x88, 0x5D, 0x87,
0x4C, 0xC5, 0x21, 0x07, 0x8D, 0x12, 0x12, 0x1D, 0x22, 0x99, 0xEA, 0xB3, 0x38, 0x7B, 0x63, 0x7B,
0xA0, 0x54, 0x8D, 0x13, 0xC0, 0xE9, 0xFF, 0x46, 0x38, 0xEE, 0x7C, 0x21, 0xD4, 0x5C, 0xF3, 0x62,
0x46, 0x12, 0xDD, 0x8C, 0xBC, 0xF6, 0x97, 0xD0, 0x88, 0x54, 0xB1, 0xE3, 0x97, 0xFF, 0xC4, 0x78,
0x74, 0x17, 0xA6, 0xEB, 0xA0, 0xD3, 0x55, 0x28, 0x0C, 0x27, 0x91, 0xF1, 0xD4, 0x20, 0x16, 0xD1,
0x88, 0x1B, 0xA1, 0x91, 0xFE, 0x6F, 0xC7, 0x34, 0x6E, 0x3F, 0xFF, 0x1F, 0xC6, 0x27, 0x01, 0x61,
0xE3, 0x69, 0xAA, 0x38, 0x85, 0x44, 0x0E, 0x1A, 0xE8, 0xB4, 0x04, 0x22, 0x99, 0xCA, 0xA0, 0x0A,
0x8D, 0x3D, 0x48, 0xA5, 0x2A, 0xD5, 0x01, 0xC6, 0x52, 0x84, 0x92, 0x29, 0x08, 0x95, 0x35, 0xBC,
0x82, 0xE2, 0x4E, 0x84, 0xC4, 0x52, 0xA5, 0x3A, 0x8D, 0xAC, 0xC6, 0x21, 0x71, 0x48, 0xD5, 0xC0,
0x23, 0x5A, 0x2D, 0xE4, 0xB0, 0xAF, 0xC4, 0xB5, 0xB6, 0x44, 0x93, 0x29, 0x24, 0x52, 0xFB, 0x90,
0x58, 0x4E, 0xE3, 0xE5, 0x00, 0x12, 0x1A, 0x83, 0x52, 0x03, 0xC6, 0x5E, 0xAA, 0xD8, 0x31, 0x6A,
0xF5, 0xCB, 0xC5, 0x42, 0x1F, 0x8A, 0xC3, 0x66, 0xF0, 0x61, 0xAB, 0xAC, 0x89, 0xCF, 0x69, 0x66,
0x26, 0xD1, 0x95, 0xEA, 0x34, 0x3E, 0x12, 0x8D, 0x92, 0x6A, 0xB0, 0x63, 0x37, 0xF0, 0xF8, 0xED,
0x46, 0x11, 0xC2, 0x57, 0xE2, 0x30, 0x64, 0x4D, 0x97, 0xCA, 0xF4, 0xC5, 0x04, 0x89, 0x40, 0x2C,
0x56, 0xAA, 0xD1, 0xA8, 0xC4, 0x51, 0x39, 0x32, 0xE4, 0x0C, 0x3C, 0x6E, 0xEE, 0x95, 0xB4, 0x45,
0xE0, 0xB0, 0x57, 0x69, 0xB7, 0x56, 0x98, 0x5A, 0xD6, 0xA4, 0x17, 0x1B, 0x0B, 0x9B, 0x39, 0x69,
0x64, 0xE3, 0x88, 0x37, 0x8E, 0x30, 0xAB, 0x0A, 0x63, 0xD3, 0x67, 0xCE, 0xF6, 0xED, 0xBF, 0xFE,
0x73, 0x67, 0x62, 0xE3, 0x6F, 0x06, 0x0E, 0x0F, 0x84, 0x50, 0x51, 0x63, 0x85, 0x51, 0x4E, 0xA2,
0xD3, 0x48, 0xFD, 0x3B, 0x8D, 0xA4, 0xAA, 0x22, 0xA7, 0xEB, 0x22, 0xC8, 0x7F, 0x37, 0xE4, 0x95,
0x46, 0x3E, 0xD4, 0x64, 0x2A, 0x84, 0x6C, 0x89, 0x8F, 0x66, 0x27, 0x11, 0x88, 0xFB, 0x69, 0x64,
0x1A, 0x97, 0x1D, 0xDB, 0x03, 0x19, 0x52, 0x7E, 0xE4, 0x17, 0x20, 0xF3, 0x44, 0xDA, 0xDB, 0x30,
0xFA, 0x70, 0x0D, 0x87, 0x32, 0x22, 0xD7, 0x8C, 0x59, 0x9D, 0x88, 0x52, 0xF9, 0x14, 0xDE, 0x69,
0x8C, 0xCB, 0x31, 0x76, 0xEC, 0xBB, 0x03, 0x90, 0x3F, 0x2F, 0xE6, 0x8B, 0x74, 0xA7, 0xD2, 0x4E,
0xC3, 0x77, 0x4B, 0xE9, 0x3F, 0x07, 0xE1, 0x7C, 0x24, 0x3A, 0x8D, 0x42, 0xE8, 0x34, 0x2A, 0x71,
0xD4, 0x1C, 0x1A, 0xC8, 0x63, 0xE6, 0x04, 0x8C, 0x9B, 0x77, 0xA7, 0x73, 0x28, 0x7C, 0xB3, 0x55,
0xD0, 0x88, 0xC5, 0x83, 0x38, 0x9A, 0x46, 0x23, 0xAA, 0x13, 0xB9, 0x9D, 0x1A, 0x89, 0x06, 0xB1,
0x3C, 0x70, 0xA0, 0x71, 0x6C, 0x47, 0xB9, 0x11, 0xA9, 0x4A, 0xAB, 0x0A, 0x9D, 0x5E, 0xAD, 0xCF,
0x26, 0x9F, 0x67, 0x3E, 0x6E, 0x06, 0x0A, 0xF1, 0xE1, 0x0A, 0x23, 0xD2, 0x17, 0xFA, 0x03, 0x89,
0xA6, 0xD3, 0x22, 0x88, 0x1E, 0x38, 0x1C, 0xAA, 0x74, 0x70, 0xEC, 0xA5, 0x1A, 0xDE, 0x71, 0x80,
0x47, 0x88, 0x14, 0x93, 0x17, 0xFF, 0x06, 0xF0, 0xF6, 0x2F, 0x51, 0xA8, 0xA0, 0x89, 0x3E, 0x6C,
0x93, 0xC1, 0x4D, 0x1C, 0x72, 0x00, 0x9F, 0x89, 0x44, 0x94, 0xEA, 0x34, 0xB2, 0x37, 0x8A, 0x46,
0xEC, 0xB8, 0x92, 0x1F, 0xB5, 0x3D, 0xF6, 0x44, 0x0A, 0xE4, 0xCF, 0xFB, 0x7B, 0xFE, 0x81, 0xDF,
0xD4, 0x9D, 0xE1, 0x8D, 0xD3, 0x40, 0x10, 0x46, 0x5B, 0x00, 0x53, 0x81, 0x49, 0x07, 0xF1, 0x75,
0x10, 0xD2, 0x41, 0x72, 0x1D, 0x18, 0x89, 0x0A, 0x42, 0x2A, 0x08, 0x15, 0x1C, 0xA2, 0x5B, 0x3C,
0x3B, 0xB3, 0x7E, 0x5E, 0x7D, 0xB2, 0x2C, 0x24, 0xAF, 0xB5, 0xCC, 0x59, 0x70, 0x90, 0xFB, 0x71,
0x8F, 0xF7, 0xCD, 0xCC, 0x6E, 0xEE, 0x07, 0x5F, 0xDE, 0xFD, 0x2B, 0x7E, 0xE6, 0x85, 0xFF, 0xF8,
0x8D, 0x43, 0x6F, 0x44, 0x52, 0xEA, 0x35, 0x13, 0xCA, 0xB0, 0xD9, 0x55, 0xE3, 0x80, 0x46, 0xDA,
0x71, 0xC9, 0xF8, 0x28, 0x45, 0x1A, 0xE5, 0xE5, 0x93, 0xF0, 0x5D, 0x7F, 0xDB, 0x4B, 0xFE, 0x13,
0xC4, 0xF9, 0x0A, 0x8C, 0xC3, 0x04, 0xC8, 0x4A, 0x2C, 0x67, 0xCD, 0x54, 0x22, 0xB1, 0x82, 0x46,
0xF6, 0xBF, 0x9F, 0x00, 0x98, 0xAB, 0x7F, 0x1E, 0x21, 0xD2, 0x4D, 0x7A, 0x3D, 0xC7, 0xDB, 0xF0,
0xD5, 0xFF, 0xEF, 0xAE, 0xD3, 0xDB, 0xFD, 0xC7, 0x23, 0xD3, 0xBF, 0x96, 0x0A, 0x71, 0x38, 0x95,
0x4C, 0xD3, 0xF3, 0x79, 0x6F, 0x89, 0x20, 0xAA, 0xC6, 0x60, 0x04, 0x72, 0x5C, 0xB6, 0xA3, 0x31,
0x06, 0xE4, 0xCB, 0x55, 0x6A, 0x31, 0x46, 0xF3, 0x0D, 0xF8, 0xE9, 0x0E, 0x49, 0xA9, 0xC7, 0x94,
0x6B, 0xE2, 0x30, 0x03, 0xF6, 0xD2, 0x89, 0x7B, 0x24, 0x55, 0x35, 0x92, 0x54, 0x4E, 0x00, 0xC9,
0x23, 0x1B, 0x32, 0x65, 0xF0, 0x85, 0x4B, 0xCA, 0x5B, 0xD0, 0xBB, 0xD0, 0x09, 0x71, 0x58, 0x10,
0x22, 0x91, 0xA3, 0x1B, 0x31, 0x45, 0xE2, 0x8E, 0x1A, 0x79, 0x8B, 0x03, 0x48, 0x8F, 0x6A, 0x78,
0xFC, 0xE1, 0x33, 0x27, 0x4F, 0xD6, 0xC4, 0xF8, 0x0A, 0x99, 0xF6, 0x5B, 0xD0, 0xBD, 0xA2, 0x05,
0x99, 0xA4, 0x76, 0xA6, 0x31, 0x87, 0x7E, 0x81, 0xA2, 0x11, 0x07, 0xEE, 0xFA, 0x21, 0x51, 0xC6,
0x69, 0x35, 0x8D, 0x24, 0xD5, 0x6A, 0x0C, 0x8F, 0x1F, 0xC6, 0xC8, 0x91, 0x35, 0x83, 0xBA, 0xCE,
0x5F, 0x3F, 0xA7, 0xDE, 0xB3, 0xC7, 0x19, 0x69, 0x43, 0x0F, 0xA9, 0x13, 0xDE, 0xCB, 0x94, 0x72,
0x38, 0x0D, 0x87, 0x22, 0xB1, 0xB6, 0x46, 0x66, 0xCE, 0x3D, 0x18, 0x3F, 0xFE, 0xE4, 0x8E, 0xF4,
0xB8, 0xDA, 0xD4, 0x71, 0xC6, 0x47, 0x66, 0x0B, 0x3C, 0x06, 0xA9, 0xA7, 0x94, 0x95, 0xAF, 0x27,
0xB7, 0x3A, 0x12, 0xD7, 0x35, 0x9E, 0x5D, 0xE3, 0x10, 0xE7, 0xB8, 0xBC, 0x1E, 0x63, 0xAE, 0x3A,
0x63, 0xC4, 0x15, 0x8F, 0x13, 0x98, 0xC1, 0x39, 0x63, 0x08, 0x34, 0x42, 0x8E, 0x34, 0x6B, 0xEB,
0xC2, 0x6A, 0x5D, 0x62, 0x1D, 0x8D, 0x43, 0x30, 0x5A, 0x56, 0x99, 0x39, 0x71, 0x94, 0xB3, 0x8E,
0x0C, 0x46, 0x43, 0x78, 0xAC, 0x95, 0x59, 0x76, 0x3E, 0x08, 0xC7, 0xEC, 0xF0, 0x1A, 0x4B, 0x9F,
0x46, 0xAC, 0x20, 0x11, 0x44, 0xDE, 0xFC, 0x97, 0xCD, 0xC1, 0x9D, 0x03, 0x8F, 0x9C, 0x02, 0x8C,
0xD2, 0x54, 0x3E, 0x15, 0xCF, 0x04, 0x3E, 0xDD, 0xA0, 0xEF, 0x0A, 0x66, 0x29, 0x8D, 0xA8, 0xD3,
0xB4, 0xDF, 0x55, 0x22, 0x49, 0x85, 0x91, 0x1B, 0x07, 0x87, 0x1C, 0x3C, 0xFA, 0x19, 0x20, 0x86,
0xCE, 0x02, 0xF2, 0x99, 0x78, 0x8C, 0xCA, 0xD1, 0xCC, 0xAD, 0x05, 0x74, 0xEE, 0x42, 0x42, 0x5A,
0x12, 0xCE, 0x80, 0x67, 0x39, 0x9C, 0x22, 0x71, 0x5F, 0x8D, 0x1D, 0x59, 0x3D, 0x9F, 0x79, 0x5B,
0x35, 0x1F, 0xC8, 0x59, 0x1E, 0xDE, 0x91, 0x94, 0xF1, 0x18, 0xE9, 0x54, 0x46, 0x68, 0xD8, 0x26,
0x10, 0x85, 0xBE, 0x2C, 0xC4, 0xE1, 0x85, 0xA5, 0xCF, 0x0D, 0x43, 0x24, 0x56, 0xD0, 0xC8, 0xAD,
0xCA, 0xDB, 0x91, 0xAC, 0x46, 0x43, 0x0A, 0xA4, 0x19, 0x9B, 0x98, 0x42, 0x1E, 0x74, 0x00, 0xFA,
0x28, 0x65, 0x96, 0x5A, 0x0D, 0x8C, 0x9A, 0x7A, 0x12, 0x55, 0xA3, 0x6E, 0x0E, 0x63, 0x24, 0xAB,
0x34, 0x24, 0x90, 0x94, 0xC3, 0x29, 0x20, 0x83, 0x06, 0x87, 0x6C, 0xC4, 0x13, 0x84, 0x9D, 0x48,
0xAC, 0xA0, 0x91, 0x76, 0x0C, 0xC6, 0xCB, 0x5B, 0x91, 0xD5, 0x77, 0x1A, 0x12, 0x48, 0x29, 0x7A,
0x90, 0x36, 0x8C, 0x94, 0xDE, 0x5C, 0x22, 0x37, 0xA8, 0x33, 0x80, 0x7A, 0x3A, 0xAD, 0xA1, 0xD1,
0x2C, 0x32, 0x55, 0x19, 0x39, 0x78, 0xB4, 0xB1, 0x98, 0x21, 0x39, 0xD3, 0x29, 0x9F, 0x01, 0x12,
0x52, 0x71, 0x38, 0x44, 0x23, 0x32, 0x6B, 0x98, 0xA6, 0x48, 0xAC, 0xA0, 0xB1, 0x5B, 0x4E, 0xD5,
0x53, 0xD9, 0x8F, 0xB7, 0x60, 0x9C, 0x8C, 0x10, 0x56, 0x1F, 0xAF, 0x8E, 0xA9, 0x78, 0x7E, 0xB1,
0xF0, 0x90, 0x06, 0xA1, 0xEC, 0x7C, 0x24, 0x56, 0xE8, 0x44, 0x34, 0x52, 0xA6, 0x91, 0x91, 0xC3,
0x49, 0x0E, 0x46, 0x87, 0x9C, 0x1E, 0x20, 0xD2, 0x6F, 0x1F, 0xB9, 0xD2, 0x1F, 0xA9, 0x31, 0x67,
0x14, 0x87, 0x10, 0xD2, 0x88, 0x7D, 0x05, 0x89, 0xA2, 0x51, 0x27, 0xCE, 0x39, 0x34, 0x8A, 0xC7,
0xF1, 0xDD, 0x20, 0x47, 0x67, 0x20, 0xB3, 0xE9, 0x23, 0x98, 0xE3, 0x93, 0xD4, 0xBB, 0x63, 0x6E,
0xC3, 0x99, 0x90, 0x9F, 0xD1, 0xE8, 0x34, 0x45, 0x62, 0x05, 0x8D, 0x2C, 0x0E, 0xDA, 0x11, 0x8F,
0x2C, 0x0F, 0x9F, 0xAC, 0x13, 0xE7, 0x18, 0x6C, 0xE9, 0x01, 0x15, 0x83, 0x36, 0x66, 0x20, 0xBC,
0x42, 0x48, 0x23, 0xB2, 0x12, 0xEB, 0x48, 0x44, 0xA3, 0xFE, 0x30, 0x8E, 0xCD, 0x81, 0xC7, 0x2B,
0x8C, 0x49, 0xE4, 0xFD, 0x7B, 0x5E, 0x93, 0x5A, 0xEF, 0x00, 0x7A, 0x48, 0x21, 0xCC, 0x31, 0x5D,
0x38, 0xAC, 0x22, 0x11, 0x8D, 0xEA, 0x91, 0x91, 0x23, 0x1E, 0x81, 0x0C, 0x82, 0xD1, 0x31, 0x85,
0x6F, 0xBC, 0xC7, 0xED, 0x97, 0x41, 0x53, 0x12, 0xE2, 0x90, 0x69, 0x8A, 0xC4, 0x5D, 0x4B, 0x10,
0x61, 0x34, 0x42, 0x3C, 0x3A, 0x61, 0xDC, 0xAE, 0xA2, 0x27, 0x1D, 0x73, 0x42, 0x5A, 0x3E, 0xFE,
0x8A, 0xF3, 0x31, 0x67, 0x20, 0xD4, 0x51, 0xF3, 0xB5, 0x96, 0x44, 0x34, 0xEA, 0x76, 0x24, 0xAB,
0xDA, 0x8F, 0x33, 0x23, 0x94, 0x3C, 0x2E, 0xD6, 0x13, 0xAA, 0x21, 0x85, 0x70, 0x58, 0xC6, 0xB4,
0xAF, 0x42, 0x48, 0x29, 0x22, 0x8C, 0x83, 0xF4, 0x23, 0xD7, 0x64, 0x28, 0xCB, 0x1A, 0x47, 0xBF,
0xF9, 0x72, 0x9E, 0xB9, 0xCD, 0x1B, 0x5F, 0x53, 0x6A, 0x80, 0x1A, 0xD3, 0x8A, 0x8C, 0x3A, 0x56,
0x99, 0xAB, 0xDF, 0x12, 0x23, 0x90, 0x54, 0x52, 0x37, 0xFF, 0x5A, 0xD4, 0xD5, 0x15, 0xE2, 0x90,
0x51, 0x73, 0xCC, 0xAC, 0x21, 0xAA, 0xDA, 0x8E, 0x72, 0xB1, 0x1A, 0xF0, 0x78, 0x8B, 0x43, 0xAB,
0x96, 0x00, 0xD2, 0x86, 0x5C, 0x2E, 0x58, 0x17, 0xEC, 0xFC, 0x5A, 0x12, 0xD1, 0xA8, 0xED, 0xA8,
0x1E, 0x2F, 0x34, 0x24, 0x26, 0x37, 0x00, 0x6F, 0x0C, 0x9A, 0xE1, 0x92, 0x09, 0xD3, 0xCE, 0x87,
0xB1, 0xB2, 0x44, 0x34, 0x6A, 0x3B, 0xE2, 0x11, 0x46, 0x20, 0x6F, 0x06, 0x09, 0xA5, 0xF2, 0x01,
0x48, 0x1B, 0x92, 0x52, 0x8E, 0xA6, 0xD5, 0x09, 0xD1, 0xA8, 0xED, 0x88, 0x47, 0xC2, 0x0A, 0xA3,
0x01, 0x18, 0x89, 0xE2, 0xDD, 0xA6, 0x32, 0x3A, 0x00, 0x8D, 0x90, 0x94, 0xA2, 0x90, 0x46, 0xAC,
0x19, 0x53, 0x18, 0xB5, 0x1D, 0xF1, 0x28, 0x22, 0x09, 0xAC, 0xD7, 0x92, 0xEE, 0xEE, 0xAF, 0x40,
0xE8, 0x21, 0xE5, 0x8D, 0x0C, 0x2C, 0xF6, 0xC7, 0x48, 0x24, 0xAA, 0x54, 0x67, 0x90, 0xEA, 0x11,
0x91, 0xB8, 0x0C, 0x9D, 0x51, 0xDF, 0xEC, 0x43, 0x15, 0x8A, 0xC3, 0xE3, 0x62, 0x8A, 0x46, 0x3D,
0xAC, 0x8A, 0x47, 0x15, 0x09, 0x27, 0x1F, 0x65, 0xBD, 0xA1, 0x90, 0x33, 0xCD, 0x31, 0xD3, 0x74,
0x9B, 0xB1, 0x9C, 0xAB, 0x85, 0x48, 0x20, 0xA5, 0x14, 0x10, 0x85, 0x4A, 0xB8, 0x21, 0xF1, 0xA8,
0xA8, 0x2A, 0xA3, 0x69, 0xB9, 0x40, 0xB9, 0x01, 0x28, 0x21, 0xE5, 0x64, 0x7A, 0x14, 0x21, 0x1A,
0x75, 0x75, 0x68, 0x58, 0x31, 0xF9, 0x6D, 0x05, 0x92, 0xC3, 0x8C, 0xFD, 0x4B, 0x08, 0xA1, 0xBC,
0x1D, 0x75, 0x48, 0x4C, 0x61, 0x54, 0x8F, 0xCA, 0x88, 0xC9, 0x37, 0xAB, 0x15, 0x7F, 0x0C, 0x99,
0xB5, 0x90, 0x1E, 0x4E, 0x48, 0x54, 0xD5, 0xA3, 0x42, 0x5E, 0xDC, 0xE4, 0x94, 0x43, 0x93, 0x55,
0xD8, 0xF4, 0xBF, 0x70, 0xD1, 0xD2, 0x86, 0xE2, 0xF0, 0x90, 0x98, 0x2A, 0xA3, 0x7A, 0xA4, 0x21,
0x13, 0x23, 0xE5, 0xAA, 0x92, 0x34, 0xCA, 0xE1, 0x45, 0xA1, 0x38, 0x3C, 0x94, 0x90, 0xA8, 0x6E,
0x7B, 0xE4, 0x38, 0x97, 0x31, 0x01, 0x8A, 0xB7, 0x97, 0xE3, 0x65, 0x00, 0x9D, 0x10, 0x87, 0x10,
0x6E, 0xC5, 0xF4, 0x18, 0xC6, 0xE4, 0x91, 0x1A, 0x02, 0x92, 0x02, 0xB5, 0x28, 0x08, 0x99, 0x33,
0xCC, 0xD2, 0x03, 0x09, 0x35, 0xAA, 0xBA, 0x1F, 0x4B, 0x91, 0xA7, 0xA9, 0x06, 0x54, 0x66, 0x67,
0x17, 0x82, 0x4B, 0xA1, 0x50, 0x1C, 0x1E, 0x16, 0xD3, 0x6D, 0x46, 0x08, 0x05, 0x52, 0x8A, 0x70,
0xB2, 0x28, 0xDC, 0x20, 0x0A, 0x71, 0x78, 0x18, 0xE1, 0xB6, 0xC7, 0xDE, 0x4A, 0x21, 0x95, 0x52,
0x01, 0xB9, 0x38, 0xC1, 0x78, 0xB8, 0x43, 0x6D, 0x47, 0x2D, 0x08, 0xA9, 0x89, 0xB0, 0xA0, 0x54,
0x3E, 0x0C, 0x92, 0x51, 0xAB, 0xCF, 0x3B, 0x34, 0xE2, 0xFE, 0x8C, 0x1D, 0x93, 0xB5, 0xDC, 0x92,
0x50, 0x2A, 0x1E, 0x80, 0x5C, 0x0F, 0x9B, 0x20, 0x5C, 0x67, 0xC4, 0x24, 0x75, 0x8E, 0x82, 0xEE,
0x14, 0xC5, 0xD7, 0x10, 0x51, 0x9B, 0x34, 0x2D, 0x10, 0x3A, 0xA3, 0x54, 0xCF, 0x64, 0x95, 0xC8,
0x52, 0xE0, 0x69, 0x75, 0x5F, 0xFB, 0x56, 0x08, 0x95, 0x51, 0x45, 0x6E, 0x97, 0x46, 0x54, 0x00,
0x8F, 0x1F, 0x35, 0xCA, 0xA8, 0x22, 0x2D, 0x6C, 0xCB, 0x9C, 0x9E, 0xEC, 0xA1, 0xF4, 0xEF, 0x49,
0x69, 0x5B, 0x84, 0x30, 0xAA, 0xC8, 0xCE, 0x18, 0x05, 0xA8, 0x7C, 0xA4, 0x09, 0x1D, 0xB0, 0x29,
0x42, 0x18, 0x65, 0x7D, 0xE0, 0x71, 0xAB, 0xD8, 0x14, 0xD6, 0xC6, 0xCD, 0x11, 0xC2, 0xA8, 0x90,
0x56, 0xFF, 0x42, 0x98, 0x15, 0xB6, 0x32, 0x69, 0x84, 0x71, 0x65, 0xEE, 0x6C, 0x43, 0xB2, 0xEB,
0x27, 0xC0, 0x26, 0x09, 0xE5, 0x2C, 0x27, 0x26, 0x37, 0x29, 0xFB, 0xDC, 0x84, 0xAD, 0x12, 0x16,
0x8C, 0x6A, 0x32, 0x63, 0x76, 0xEB, 0xFE, 0xE2, 0xB8, 0xD6, 0x30, 0x61, 0x11, 0x56, 0xAD, 0x80,
0x08, 0x9F, 0x74, 0x5E, 0x86, 0x83, 0xAF, 0xBD, 0x41, 0xB3, 0xCD, 0x88, 0xCB, 0xA8, 0x7E, 0xAE,
0x98, 0x2E, 0x71, 0x65, 0x6A, 0x5D, 0xA1, 0x86, 0xB5, 0xFB, 0xDC, 0xCF, 0x4F, 0xD1, 0x98, 0x52,
0xF9, 0xB5, 0x6E, 0xF1, 0x34, 0x4A, 0xB8, 0x2E, 0x52, 0xBF, 0x6B, 0x95, 0xDC, 0x7C, 0x48, 0x55,
0x64, 0x7C, 0xE3, 0x5D, 0xE2, 0xB3, 0x2A, 0x28, 0x45, 0x77, 0xFE, 0xDA, 0xCF, 0x7D, 0xB3, 0x21,
0x9D, 0x4B, 0x08, 0x02, 0x35, 0x68, 0xF4, 0xC9, 0xA2, 0xED, 0xF5, 0xE6, 0x15, 0xAE, 0xA5, 0xD5,
0x31, 0xFA, 0xB5, 0x30, 0xF6, 0xF1, 0x52, 0xFF, 0xBF, 0x00, 0x06, 0xA4, 0x52, 0xD8, 0x43, 0x1A,
0xF9, 0x24, 0xF0, 0x9B, 0x1E, 0xA4, 0xDB, 0x90, 0x4C, 0x1D, 0x22, 0xC9, 0x27, 0x5D, 0xEB, 0x9B,
0xE2, 0xEF, 0x48, 0xF1, 0x24, 0xA6, 0x07, 0x87, 0x4A, 0x31, 0x4A, 0x7A, 0x9B, 0x4E, 0x70, 0xA8,
0x54, 0xF5, 0xE4, 0xFB, 0x72, 0x28, 0x34, 0xD6, 0x48, 0xF0, 0xE5, 0xB0, 0x8D, 0x3F, 0x54, 0x6F,
0x0E, 0xD3, 0xE8, 0xC3, 0x00, 0xC3, 0x31, 0xF2, 0x06, 0x15, 0x00, 0x00, 0x30, 0x6F, 0xE5, 0x21,
0x41, 0x39, 0x13, 0x54, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4E, 0x44, 0xAE, 0x42, 0x60, 0x82
};