Commit e9a122eb authored by Feng Xiao's avatar Feng Xiao

Merge pull request #501 from xfxyjwf/down

Down-integrate from internal code base.
parents b36395b2 818c5eee
......@@ -19,7 +19,7 @@ m4/lt~obsolete.m4
autom4te.cache
# downloaded files
gtest
gmock
# in-tree configure-generated files
Makefile
......@@ -47,6 +47,8 @@ any_test.pb.*
map*unittest.pb.*
unittest*.pb.*
cpp_test*.pb.*
src/google/protobuf/util/**/*.pb.cc
src/google/protobuf/util/**/*.pb.h
*.pyc
*.egg-info
......
......@@ -8,28 +8,29 @@ AUTOMAKE_OPTIONS = foreign
# the right time.
SUBDIRS = . src
# Always include gtest in distributions.
# Always include gmock in distributions.
DIST_SUBDIRS = $(subdirs) src conformance
# Build gtest before we build protobuf tests. We don't add gtest to SUBDIRS
# because then "make check" would also build and run all of gtest's own tests,
# Build gmock before we build protobuf tests. We don't add gmock to SUBDIRS
# because then "make check" would also build and run all of gmock's own tests,
# which takes a lot of time and is generally not useful to us. Also, we don't
# want "make install" to recurse into gtest since we don't want to overwrite
# the installed version of gtest if there is one.
# want "make install" to recurse into gmock since we don't want to overwrite
# the installed version of gmock if there is one.
check-local:
@echo "Making lib/libgtest.a lib/libgtest_main.a in gtest"
@cd gtest && $(MAKE) $(AM_MAKEFLAGS) lib/libgtest.la lib/libgtest_main.la
@echo "Making lib/libgmock.a lib/libgmock_main.a in gmock"
@cd gmock && $(MAKE) $(AM_MAKEFLAGS) lib/libgmock.la lib/libgmock_main.la
@cd gmock/gtest && $(MAKE) $(AM_MAKEFLAGS) lib/libgtest.la lib/libgtest_main.la
# We would like to clean gtest when "make clean" is invoked. But we have to
# We would like to clean gmock when "make clean" is invoked. But we have to
# be careful because clean-local is also invoked during "make distclean", but
# "make distclean" already recurses into gtest because it's listed among the
# DIST_SUBDIRS. distclean will delete gtest/Makefile, so if we then try to
# "make distclean" already recurses into gmock because it's listed among the
# DIST_SUBDIRS. distclean will delete gmock/Makefile, so if we then try to
# cd to the directory again and "make clean" it will fail. So, check that the
# Makefile exists before recursing.
clean-local:
@if test -e gtest/Makefile; then \
echo "Making clean in gtest"; \
cd gtest && $(MAKE) $(AM_MAKEFLAGS) clean; \
@if test -e gmock/Makefile; then \
echo "Making clean in gmock"; \
cd gmock && $(MAKE) $(AM_MAKEFLAGS) clean; \
fi; \
if test -e conformance/Makefile; then \
echo "Making clean in conformance"; \
......
......@@ -15,12 +15,12 @@ first:
$ ./autogen.sh
This will download gtest source (which is used for C++ Protocol Buffer
This will download gmock source (which is used for C++ Protocol Buffer
unit-tests) to the current directory and run automake, autoconf, etc.
to generate the configure script and various template makefiles.
You can skip this step if you are using a release package (which already
contains gtest and the configure script).
contains gmock and the configure script).
To build and install the C++ Protocol Buffer runtime and the Protocol
Buffer compiler (protoc) execute the following:
......
......@@ -12,9 +12,9 @@ environment:
- BUILD_DLL: ON
install:
- ps: Start-FileDownload https://googletest.googlecode.com/files/gtest-1.7.0.zip
- 7z x gtest-1.7.0.zip
- rename gtest-1.7.0 gtest
- ps: Start-FileDownload https://googlemock.googlecode.com/files/gmock-1.7.0.zip
- 7z x gmock-1.7.0.zip
- rename gmock-1.7.0 gmock
before_build:
- if %platform%==Win32 set generator=Visual Studio 12
......@@ -30,4 +30,5 @@ build_script:
- cd %configuration%
- tests.exe
skip_commits:
message: /.*\[skip appveyor\].*/
......@@ -15,27 +15,18 @@ __EOF__
exit 1
fi
# Check that gtest is present. Usually it is already there since the
# Check that gmock is present. Usually it is already there since the
# directory is set up as an SVN external.
if test ! -e gtest; then
echo "Google Test not present. Fetching gtest-1.7.0 from the web..."
curl -O https://googletest.googlecode.com/files/gtest-1.7.0.zip
unzip -q gtest-1.7.0.zip
rm gtest-1.7.0.zip
mv gtest-1.7.0 gtest
if test ! -e gmock; then
echo "Google Mock not present. Fetching gmock-1.7.0 from the web..."
curl -O https://googlemock.googlecode.com/files/gmock-1.7.0.zip
unzip -q gmock-1.7.0.zip
rm gmock-1.7.0.zip
mv gmock-1.7.0 gmock
fi
set -ex
# Temporary hack: Must change C runtime library to "multi-threaded DLL",
# otherwise it will be set to "multi-threaded static" when MSVC upgrades
# the project file to MSVC 2005/2008. vladl of Google Test says gtest will
# probably change their default to match, then this will be unnecessary.
# One of these mappings converts the debug configuration and the other
# converts the release configuration. I don't know which is which.
sed -i -e 's/RuntimeLibrary="5"/RuntimeLibrary="3"/g;
s/RuntimeLibrary="4"/RuntimeLibrary="2"/g;' gtest/msvc/*.vcproj
# TODO(kenton): Remove the ",no-obsolete" part and fix the resulting warnings.
autoreconf -f -i -Wall,no-obsolete
......
......@@ -5,17 +5,17 @@ on your computer before proceeding.
Compiling and Installing
========================
1. Check whether a gtest directory exists in the upper level directory. If you
checkout the code from github via "git clone", this gtest directory won't
1. Check whether a gmock directory exists in the upper level directory. If you
checkout the code from github via "git clone", this gmock directory won't
exist and you won't be able to build protobuf unit-tests. Consider using one
of the release tar balls instead:
https://github.com/google/protobuf/releases
These release tar balls are more stable versions of protobuf and already
have the gtest directory included.
have the gmock directory included.
You can also download gtest by yourself and put it in the right place.
You can also download gmock by yourself and put it in the right place.
If you absolutely don't want to build and run protobuf unit-tests, skip
this step and use protobuf at your own risk.
......@@ -29,7 +29,7 @@ Compiling and Installing
$ cd build
$ cmake -G "Visual Studio 9 2008" ..
If you don't have gtest, skip the build of tests by turning off the
If you don't have gmock, skip the build of tests by turning off the
BUILD_TESTING option:
$ cmake -G "Visutal Studio 9 2008" -DBUILD_TESTING=OFF ..
......
......@@ -11,6 +11,7 @@ mkdir include\google\protobuf\compiler\python
mkdir include\google\protobuf\compiler\ruby
mkdir include\google\protobuf\io
mkdir include\google\protobuf\stubs
mkdir include\google\protobuf\util
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\any.h include\google\protobuf\any.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\any.pb.h include\google\protobuf\any.pb.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\api.pb.h include\google\protobuf\api.pb.h
......@@ -88,6 +89,7 @@ copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\common.h include
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\fastmem.h include\google\protobuf\stubs\fastmem.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\hash.h include\google\protobuf\stubs\hash.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\once.h include\google\protobuf\stubs\once.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\pbconfig.h include\google\protobuf\stubs\pbconfig.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\platform_macros.h include\google\protobuf\stubs\platform_macros.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\shared_ptr.h include\google\protobuf\stubs\shared_ptr.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\singleton.h include\google\protobuf\stubs\singleton.h
......@@ -98,6 +100,11 @@ copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\text_format.h include\
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\timestamp.pb.h include\google\protobuf\timestamp.pb.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\type.pb.h include\google\protobuf\type.pb.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\unknown_field_set.h include\google\protobuf\unknown_field_set.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\util\field_comparator.h include\google\protobuf\util\field_comparator.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\util\json_util.h include\google\protobuf\util\json_util.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\util\message_differencer.h include\google\protobuf\util\message_differencer.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\util\type_resolver.h include\google\protobuf\util\type_resolver.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\util\type_resolver_util.h include\google\protobuf\util\type_resolver_util.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\wire_format.h include\google\protobuf\wire_format.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\wire_format_lite.h include\google\protobuf\wire_format_lite.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\wire_format_lite_inl.h include\google\protobuf\wire_format_lite_inl.h
......
......@@ -10,9 +10,15 @@ set(libprotobuf_lite_files
${protobuf_source_dir}/src/google/protobuf/repeated_field.cc
${protobuf_source_dir}/src/google/protobuf/stubs/atomicops_internals_x86_gcc.cc
${protobuf_source_dir}/src/google/protobuf/stubs/atomicops_internals_x86_msvc.cc
${protobuf_source_dir}/src/google/protobuf/stubs/bytestream.cc
${protobuf_source_dir}/src/google/protobuf/stubs/common.cc
${protobuf_source_dir}/src/google/protobuf/stubs/once.cc
${protobuf_source_dir}/src/google/protobuf/stubs/status.cc
${protobuf_source_dir}/src/google/protobuf/stubs/statusor.cc
${protobuf_source_dir}/src/google/protobuf/stubs/stringpiece.cc
${protobuf_source_dir}/src/google/protobuf/stubs/stringprintf.cc
${protobuf_source_dir}/src/google/protobuf/stubs/strutil.cc
${protobuf_source_dir}/src/google/protobuf/stubs/time.cc
${protobuf_source_dir}/src/google/protobuf/wire_format_lite.cc
)
......
......@@ -24,13 +24,30 @@ set(libprotobuf_files
${protobuf_source_dir}/src/google/protobuf/service.cc
${protobuf_source_dir}/src/google/protobuf/source_context.pb.cc
${protobuf_source_dir}/src/google/protobuf/struct.pb.cc
${protobuf_source_dir}/src/google/protobuf/stubs/mathlimits.cc
${protobuf_source_dir}/src/google/protobuf/stubs/structurally_valid.cc
${protobuf_source_dir}/src/google/protobuf/stubs/strutil.cc
${protobuf_source_dir}/src/google/protobuf/stubs/substitute.cc
${protobuf_source_dir}/src/google/protobuf/text_format.cc
${protobuf_source_dir}/src/google/protobuf/timestamp.pb.cc
${protobuf_source_dir}/src/google/protobuf/type.pb.cc
${protobuf_source_dir}/src/google/protobuf/unknown_field_set.cc
${protobuf_source_dir}/src/google/protobuf/util/field_comparator.cc
${protobuf_source_dir}/src/google/protobuf/util/internal/datapiece.cc
${protobuf_source_dir}/src/google/protobuf/util/internal/default_value_objectwriter.cc
${protobuf_source_dir}/src/google/protobuf/util/internal/error_listener.cc
${protobuf_source_dir}/src/google/protobuf/util/internal/field_mask_utility.cc
${protobuf_source_dir}/src/google/protobuf/util/internal/json_escaping.cc
${protobuf_source_dir}/src/google/protobuf/util/internal/json_objectwriter.cc
${protobuf_source_dir}/src/google/protobuf/util/internal/json_stream_parser.cc
${protobuf_source_dir}/src/google/protobuf/util/internal/object_writer.cc
${protobuf_source_dir}/src/google/protobuf/util/internal/protostream_objectsource.cc
${protobuf_source_dir}/src/google/protobuf/util/internal/protostream_objectwriter.cc
${protobuf_source_dir}/src/google/protobuf/util/internal/type_info.cc
${protobuf_source_dir}/src/google/protobuf/util/internal/type_info_test_helper.cc
${protobuf_source_dir}/src/google/protobuf/util/internal/utility.cc
${protobuf_source_dir}/src/google/protobuf/util/json_util.cc
${protobuf_source_dir}/src/google/protobuf/util/message_differencer.cc
${protobuf_source_dir}/src/google/protobuf/util/type_resolver_util.cc
${protobuf_source_dir}/src/google/protobuf/wire_format.cc
${protobuf_source_dir}/src/google/protobuf/wrappers.pb.cc
)
......
if (NOT EXISTS "${PROJECT_SOURCE_DIR}/../gmock/CMakeLists.txt")
message(FATAL_ERROR "Cannot find gmock directory.")
endif()
include_directories(
${protobuf_source_dir}/gtest/include
${protobuf_source_dir}/gtest)
${protobuf_source_dir}/gmock
${protobuf_source_dir}/gmock/gtest
${protobuf_source_dir}/gmock/gtest/include
${protobuf_source_dir}/gmock/include
)
add_library(gtest STATIC ${protobuf_source_dir}/gtest/src/gtest-all.cc)
add_library(gtest_main STATIC ${protobuf_source_dir}/gtest/src/gtest_main.cc)
target_link_libraries(gtest_main gtest)
add_library(gmock STATIC
${protobuf_source_dir}/gmock/src/gmock-all.cc
${protobuf_source_dir}/gmock/gtest/src/gtest-all.cc
)
add_library(gmock_main STATIC ${protobuf_source_dir}/gmock/src/gmock_main.cc)
target_link_libraries(gmock_main gmock)
set(lite_test_protos
google/protobuf/map_lite_unittest.proto
......@@ -39,6 +49,15 @@ set(tests_protos
google/protobuf/unittest_preserve_unknown_enum2.proto
google/protobuf/unittest_proto3_arena.proto
google/protobuf/unittest_well_known_types.proto
google/protobuf/util/internal/testdata/anys.proto
google/protobuf/util/internal/testdata/books.proto
google/protobuf/util/internal/testdata/default_value.proto
google/protobuf/util/internal/testdata/default_value_test.proto
google/protobuf/util/internal/testdata/field_mask.proto
google/protobuf/util/internal/testdata/maps.proto
google/protobuf/util/internal/testdata/struct.proto
google/protobuf/util/internal/testdata/timestamp_duration.proto
google/protobuf/util/json_format_proto3.proto
)
macro(compile_proto_file filename)
......@@ -46,10 +65,10 @@ macro(compile_proto_file filename)
get_filename_component(basename ${filename} NAME_WE)
add_custom_command(
OUTPUT ${protobuf_source_dir}/src/${dirname}/${basename}.pb.cc
DEPENDS protoc ${protobuf_source_dir}/src/${dirname}/${basename}.proto
COMMAND protoc ${protobuf_source_dir}/src/${dirname}/${basename}.proto
--proto_path=${protobuf_source_dir}/src
--cpp_out=${protobuf_source_dir}/src
DEPENDS protoc
)
endmacro(compile_proto_file)
......@@ -113,21 +132,35 @@ set(tests_files
${protobuf_source_dir}/src/google/protobuf/reflection_ops_unittest.cc
${protobuf_source_dir}/src/google/protobuf/repeated_field_reflection_unittest.cc
${protobuf_source_dir}/src/google/protobuf/repeated_field_unittest.cc
${protobuf_source_dir}/src/google/protobuf/stubs/bytestream_unittest.cc
${protobuf_source_dir}/src/google/protobuf/stubs/common_unittest.cc
${protobuf_source_dir}/src/google/protobuf/stubs/once_unittest.cc
${protobuf_source_dir}/src/google/protobuf/stubs/status_test.cc
${protobuf_source_dir}/src/google/protobuf/stubs/statusor_test.cc
${protobuf_source_dir}/src/google/protobuf/stubs/stringpiece_unittest.cc
${protobuf_source_dir}/src/google/protobuf/stubs/stringprintf_unittest.cc
${protobuf_source_dir}/src/google/protobuf/stubs/structurally_valid_unittest.cc
${protobuf_source_dir}/src/google/protobuf/stubs/strutil_unittest.cc
${protobuf_source_dir}/src/google/protobuf/stubs/template_util_unittest.cc
${protobuf_source_dir}/src/google/protobuf/stubs/time_test.cc
${protobuf_source_dir}/src/google/protobuf/stubs/type_traits_unittest.cc
${protobuf_source_dir}/src/google/protobuf/text_format_unittest.cc
${protobuf_source_dir}/src/google/protobuf/unknown_field_set_unittest.cc
${protobuf_source_dir}/src/google/protobuf/util/field_comparator_test.cc
${protobuf_source_dir}/src/google/protobuf/util/internal/default_value_objectwriter_test.cc
${protobuf_source_dir}/src/google/protobuf/util/internal/json_objectwriter_test.cc
${protobuf_source_dir}/src/google/protobuf/util/internal/json_stream_parser_test.cc
${protobuf_source_dir}/src/google/protobuf/util/internal/protostream_objectsource_test.cc
${protobuf_source_dir}/src/google/protobuf/util/internal/protostream_objectwriter_test.cc
${protobuf_source_dir}/src/google/protobuf/util/internal/type_info_test_helper.cc
${protobuf_source_dir}/src/google/protobuf/util/json_util_test.cc
${protobuf_source_dir}/src/google/protobuf/util/type_resolver_util_test.cc
${protobuf_source_dir}/src/google/protobuf/well_known_types_unittest.cc
${protobuf_source_dir}/src/google/protobuf/wire_format_unittest.cc
)
add_executable(tests ${tests_files} ${common_test_files} ${tests_proto_files} ${lite_test_proto_files})
target_link_libraries(tests libprotoc libprotobuf gtest_main)
target_link_libraries(tests libprotoc libprotobuf gmock_main)
set(test_plugin_files
${protobuf_source_dir}/src/google/protobuf/compiler/mock_code_generator.cc
......@@ -137,7 +170,7 @@ set(test_plugin_files
)
add_executable(test_plugin ${test_plugin_files})
target_link_libraries(test_plugin libprotoc libprotobuf gtest)
target_link_libraries(test_plugin libprotoc libprotobuf gmock)
set(lite_test_files
${protobuf_source_dir}/src/google/protobuf/arena_test_util.cc
......
......@@ -163,12 +163,12 @@ case "$target_os" in
;;
esac
# HACK: Make gtest's configure script pick up our copy of CFLAGS and CXXFLAGS,
# since the flags added by ACX_CHECK_SUNCC must be used when compiling gtest
# HACK: Make gmock's configure script pick up our copy of CFLAGS and CXXFLAGS,
# since the flags added by ACX_CHECK_SUNCC must be used when compiling gmock
# too.
export CFLAGS
export CXXFLAGS
AC_CONFIG_SUBDIRS([gtest])
AC_CONFIG_SUBDIRS([gmock])
AC_CONFIG_FILES([Makefile src/Makefile conformance/Makefile protobuf.pc protobuf-lite.pc])
AC_OUTPUT
This diff is collapsed.
......@@ -621,7 +621,7 @@ GenerateSingularFieldHasBits(const FieldDescriptor* field,
// has_$name$() methods.
vars["has_array_index"] = SimpleItoa(field->index() / 32);
vars["has_mask"] = StrCat(strings::Hex(1u << (field->index() % 32),
strings::Hex::ZERO_PAD_8));
strings::ZERO_PAD_8));
printer->Print(vars,
"$inline$"
"bool $classname$::has_$name$() const {\n"
......@@ -3364,7 +3364,7 @@ static string ConditionalToCheckBitmasks(const vector<uint32>& masks) {
vector<string> parts;
for (int i = 0; i < masks.size(); i++) {
if (masks[i] == 0) continue;
string m = StrCat("0x", strings::Hex(masks[i], strings::Hex::ZERO_PAD_8));
string m = StrCat("0x", strings::Hex(masks[i], strings::ZERO_PAD_8));
// Each xor evaluates to 0 if the expected bits are present.
parts.push_back(StrCat("((_has_bits_[", i, "] & ", m, ") ^ ", m, ")"));
}
......@@ -3659,7 +3659,7 @@ GenerateIsInitialized(io::Printer* printer) {
printer->Print(
"if ((_has_bits_[$i$] & 0x$mask$) != 0x$mask$) return false;\n",
"i", SimpleItoa(i),
"mask", StrCat(strings::Hex(mask, strings::Hex::ZERO_PAD_8)));
"mask", StrCat(strings::Hex(mask, strings::ZERO_PAD_8)));
}
}
}
......
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// 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.
#include <google/protobuf/stubs/bytestream.h>
#include <string.h>
#include <algorithm>
namespace google {
namespace protobuf {
namespace strings {
void ByteSource::CopyTo(ByteSink* sink, size_t n) {
while (n > 0) {
StringPiece fragment = Peek();
if (fragment.empty()) {
GOOGLE_LOG(DFATAL) << "ByteSource::CopyTo() overran input.";
break;
}
std::size_t fragment_size = std::min<std::size_t>(n, fragment.size());
sink->Append(fragment.data(), fragment_size);
Skip(fragment_size);
n -= fragment_size;
}
}
void ByteSink::Flush() {}
void UncheckedArrayByteSink::Append(const char* data, size_t n) {
if (data != dest_) {
// Catch cases where the pointer returned by GetAppendBuffer() was modified.
GOOGLE_DCHECK(!(dest_ <= data && data < (dest_ + n)))
<< "Append() data[] overlaps with dest_[]";
memcpy(dest_, data, n);
}
dest_ += n;
}
CheckedArrayByteSink::CheckedArrayByteSink(char* outbuf, size_t capacity)
: outbuf_(outbuf), capacity_(capacity), size_(0), overflowed_(false) {
}
void CheckedArrayByteSink::Append(const char* bytes, size_t n) {
size_t available = capacity_ - size_;
if (n > available) {
n = available;
overflowed_ = true;
}
if (n > 0 && bytes != (outbuf_ + size_)) {
// Catch cases where the pointer returned by GetAppendBuffer() was modified.
GOOGLE_DCHECK(!(outbuf_ <= bytes && bytes < (outbuf_ + capacity_)))
<< "Append() bytes[] overlaps with outbuf_[]";
memcpy(outbuf_ + size_, bytes, n);
}
size_ += n;
}
GrowingArrayByteSink::GrowingArrayByteSink(size_t estimated_size)
: capacity_(estimated_size),
buf_(new char[estimated_size]),
size_(0) {
}
GrowingArrayByteSink::~GrowingArrayByteSink() {
delete[] buf_; // Just in case the user didn't call GetBuffer.
}
void GrowingArrayByteSink::Append(const char* bytes, size_t n) {
size_t available = capacity_ - size_;
if (bytes != (buf_ + size_)) {
// Catch cases where the pointer returned by GetAppendBuffer() was modified.
// We need to test for this before calling Expand() which may reallocate.
GOOGLE_DCHECK(!(buf_ <= bytes && bytes < (buf_ + capacity_)))
<< "Append() bytes[] overlaps with buf_[]";
}
if (n > available) {
Expand(n - available);
}
if (n > 0 && bytes != (buf_ + size_)) {
memcpy(buf_ + size_, bytes, n);
}
size_ += n;
}
char* GrowingArrayByteSink::GetBuffer(size_t* nbytes) {
ShrinkToFit();
char* b = buf_;
*nbytes = size_;
buf_ = NULL;
size_ = capacity_ = 0;
return b;
}
void GrowingArrayByteSink::Expand(size_t amount) { // Expand by at least 50%.
size_t new_capacity = std::max(capacity_ + amount, (3 * capacity_) / 2);
char* bigger = new char[new_capacity];
memcpy(bigger, buf_, size_);
delete[] buf_;
buf_ = bigger;
capacity_ = new_capacity;
}
void GrowingArrayByteSink::ShrinkToFit() {
// Shrink only if the buffer is large and size_ is less than 3/4
// of capacity_.
if (capacity_ > 256 && size_ < (3 * capacity_) / 4) {
char* just_enough = new char[size_];
memcpy(just_enough, buf_, size_);
delete[] buf_;
buf_ = just_enough;
capacity_ = size_;
}
}
void StringByteSink::Append(const char* data, size_t n) {
dest_->append(data, n);
}
size_t ArrayByteSource::Available() const {
return input_.size();
}
StringPiece ArrayByteSource::Peek() {
return input_;
}
void ArrayByteSource::Skip(size_t n) {
GOOGLE_DCHECK_LE(n, input_.size());
input_.remove_prefix(n);
}
LimitByteSource::LimitByteSource(ByteSource *source, size_t limit)
: source_(source),
limit_(limit) {
}
size_t LimitByteSource::Available() const {
size_t available = source_->Available();
if (available > limit_) {
available = limit_;
}
return available;
}
StringPiece LimitByteSource::Peek() {
StringPiece piece(source_->Peek());
if (piece.size() > limit_) {
piece.set(piece.data(), limit_);
}
return piece;
}
void LimitByteSource::Skip(size_t n) {
GOOGLE_DCHECK_LE(n, limit_);
source_->Skip(n);
limit_ -= n;
}
void LimitByteSource::CopyTo(ByteSink *sink, size_t n) {
GOOGLE_DCHECK_LE(n, limit_);
source_->CopyTo(sink, n);
limit_ -= n;
}
} // namespace strings
} // namespace protobuf
} // namespace google
This diff is collapsed.
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// 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.
#include <google/protobuf/stubs/bytestream.h>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <google/protobuf/testing/googletest.h>
#include <gtest/gtest.h>
namespace google {
namespace protobuf {
namespace strings {
namespace {
// We use this class instead of ArrayByteSource to simulate a ByteSource that
// contains multiple fragments. ArrayByteSource returns the entire array in
// one fragment.
class MockByteSource : public ByteSource {
public:
MockByteSource(StringPiece data, int block_size)
: data_(data), block_size_(block_size) {}
size_t Available() const { return data_.size(); }
StringPiece Peek() {
return data_.substr(0, block_size_);
}
void Skip(size_t n) { data_.remove_prefix(n); }
private:
StringPiece data_;
int block_size_;
};
TEST(ByteSourceTest, CopyTo) {
StringPiece data("Hello world!");
MockByteSource source(data, 3);
string str;
StringByteSink sink(&str);
source.CopyTo(&sink, data.size());
EXPECT_EQ(data, str);
}
TEST(ByteSourceTest, CopySubstringTo) {
StringPiece data("Hello world!");
MockByteSource source(data, 3);
source.Skip(1);
string str;
StringByteSink sink(&str);
source.CopyTo(&sink, data.size() - 2);
EXPECT_EQ(data.substr(1, data.size() - 2), str);
EXPECT_EQ("!", source.Peek());
}
TEST(ByteSourceTest, LimitByteSource) {
StringPiece data("Hello world!");
MockByteSource source(data, 3);
LimitByteSource limit_source(&source, 6);
EXPECT_EQ(6, limit_source.Available());
limit_source.Skip(1);
EXPECT_EQ(5, limit_source.Available());
{
string str;
StringByteSink sink(&str);
limit_source.CopyTo(&sink, limit_source.Available());
EXPECT_EQ("ello ", str);
EXPECT_EQ(0, limit_source.Available());
EXPECT_EQ(6, source.Available());
}
{
string str;
StringByteSink sink(&str);
source.CopyTo(&sink, source.Available());
EXPECT_EQ("world!", str);
EXPECT_EQ(0, source.Available());
}
}
TEST(ByteSourceTest, CopyToStringByteSink) {
StringPiece data("Hello world!");
MockByteSource source(data, 3);
string str;
StringByteSink sink(&str);
source.CopyTo(&sink, data.size());
EXPECT_EQ(data, str);
}
// Verify that ByteSink is subclassable and Flush() overridable.
class FlushingByteSink : public StringByteSink {
public:
explicit FlushingByteSink(string* dest) : StringByteSink(dest) {}
virtual void Flush() { Append("z", 1); }
private:
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FlushingByteSink);
};
// Write and Flush via the ByteSink superclass interface.
void WriteAndFlush(ByteSink* s) {
s->Append("abc", 3);
s->Flush();
}
TEST(ByteSinkTest, Flush) {
string str;
FlushingByteSink f_sink(&str);
WriteAndFlush(&f_sink);
EXPECT_STREQ("abcz", str.c_str());
}
} // namespace
} // namespace strings
} // namespace protobuf
} // namespace google
......@@ -111,12 +111,22 @@ inline To down_cast(From& f) {
return *static_cast<ToAsPointer>(&f);
}
template<typename To, typename From>
inline To bit_cast(const From& from) {
GOOGLE_COMPILE_ASSERT(sizeof(From) == sizeof(To),
bit_cast_with_different_sizes);
To dest;
memcpy(&dest, &from, sizeof(dest));
return dest;
}
} // namespace internal
// We made these internal so that they would show up as such in the docs,
// but we don't want to stick "internal::" in front of them everywhere.
using internal::implicit_cast;
using internal::down_cast;
using internal::bit_cast;
} // namespace protobuf
} // namespace google
......
......@@ -32,6 +32,9 @@
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/once.h>
#include <google/protobuf/stubs/status.h>
#include <google/protobuf/stubs/stringpiece.h>
#include <google/protobuf/stubs/strutil.h>
#include <stdio.h>
#include <errno.h>
#include <vector>
......@@ -146,6 +149,27 @@ LogMessage& LogMessage::operator<<(const char* value) {
return *this;
}
LogMessage& LogMessage::operator<<(const StringPiece& value) {
message_ += value.ToString();
return *this;
}
LogMessage& LogMessage::operator<<(long long value) {
message_ += SimpleItoa(value);
return *this;
}
LogMessage& LogMessage::operator<<(unsigned long long value) {
message_ += SimpleItoa(value);
return *this;
}
LogMessage& LogMessage::operator<<(
const ::google::protobuf::util::Status& status) {
message_ += status.ToString();
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().
......@@ -165,7 +189,7 @@ LogMessage& LogMessage::operator<<(const char* value) {
DECLARE_STREAM_OPERATOR(char , "%c" )
DECLARE_STREAM_OPERATOR(int , "%d" )
DECLARE_STREAM_OPERATOR(uint , "%u" )
DECLARE_STREAM_OPERATOR(unsigned int , "%u" )
DECLARE_STREAM_OPERATOR(long , "%ld")
DECLARE_STREAM_OPERATOR(unsigned long, "%lu")
DECLARE_STREAM_OPERATOR(double , "%g" )
......
This diff is collapsed.
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// 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.
// All Rights Reserved.
//
// Author: Maxim Lifantsev
//
#include <google/protobuf/stubs/mathlimits.h>
#include <google/protobuf/stubs/common.h>
namespace google {
namespace protobuf {
// MSVC++ 2005 and older compilers think the header declaration was a
// definition, and erroneously flag these as a duplicate definition.
#if defined(COMPILER_MSVC) || __cpluscplus < 201103L
#define DEF_COMMON_LIMITS(Type)
#define DEF_UNSIGNED_INT_LIMITS(Type)
#define DEF_SIGNED_INT_LIMITS(Type)
#define DEF_PRECISION_LIMITS(Type)
#else
#define DEF_COMMON_LIMITS(Type) \
const bool MathLimits<Type>::kIsSigned; \
const bool MathLimits<Type>::kIsInteger; \
const int MathLimits<Type>::kMin10Exp; \
const int MathLimits<Type>::kMax10Exp;
#define DEF_UNSIGNED_INT_LIMITS(Type) \
DEF_COMMON_LIMITS(Type) \
const Type MathLimits<Type>::kPosMin; \
const Type MathLimits<Type>::kPosMax; \
const Type MathLimits<Type>::kMin; \
const Type MathLimits<Type>::kMax; \
const Type MathLimits<Type>::kEpsilon; \
const Type MathLimits<Type>::kStdError;
#define DEF_SIGNED_INT_LIMITS(Type) \
DEF_UNSIGNED_INT_LIMITS(Type) \
const Type MathLimits<Type>::kNegMin; \
const Type MathLimits<Type>::kNegMax;
#define DEF_PRECISION_LIMITS(Type) \
const int MathLimits<Type>::kPrecisionDigits;
#endif // not COMPILER_MSVC
// http://en.wikipedia.org/wiki/Quadruple_precision_floating-point_format#Double-double_arithmetic
// With some compilers (gcc 4.6.x) on some platforms (powerpc64),
// "long double" is implemented as a pair of double: "double double" format.
// This causes a problem with epsilon (eps).
// eps is the smallest positive number such that 1.0 + eps > 1.0
//
// Normal format: 1.0 + e = 1.0...01 // N-1 zeros for N fraction bits
// D-D format: 1.0 + e = 1.000...0001 // epsilon can be very small
//
// In the normal format, 1.0 + e has to fit in one stretch of bits.
// The maximum rounding error is half of eps.
//
// In the double-double format, 1.0 + e splits across two doubles:
// 1.0 in the high double, e in the low double, and they do not have to
// be contiguous. The maximum rounding error on a value close to 1.0 is
// much larger than eps.
//
// Some code checks for errors by comparing a computed value to a golden
// value +/- some multiple of the maximum rounding error. The maximum
// rounding error is not available so we use eps as an approximation
// instead. That fails when long double is in the double-double format.
// Therefore, we define kStdError as a multiple of
// max(DBL_EPSILON * DBL_EPSILON, kEpsilon) rather than a multiple of kEpsilon.
#define DEF_FP_LIMITS(Type, PREFIX) \
DEF_COMMON_LIMITS(Type) \
const Type MathLimits<Type>::kPosMin = PREFIX##_MIN; \
const Type MathLimits<Type>::kPosMax = PREFIX##_MAX; \
const Type MathLimits<Type>::kMin = -MathLimits<Type>::kPosMax; \
const Type MathLimits<Type>::kMax = MathLimits<Type>::kPosMax; \
const Type MathLimits<Type>::kNegMin = -MathLimits<Type>::kPosMin; \
const Type MathLimits<Type>::kNegMax = -MathLimits<Type>::kPosMax; \
const Type MathLimits<Type>::kEpsilon = PREFIX##_EPSILON; \
/* 32 is 5 bits of mantissa error; should be adequate for common errors */ \
const Type MathLimits<Type>::kStdError = \
32 * (DBL_EPSILON * DBL_EPSILON > MathLimits<Type>::kEpsilon \
? DBL_EPSILON * DBL_EPSILON : MathLimits<Type>::kEpsilon); \
DEF_PRECISION_LIMITS(Type) \
const Type MathLimits<Type>::kNaN = HUGE_VAL - HUGE_VAL; \
const Type MathLimits<Type>::kPosInf = HUGE_VAL; \
const Type MathLimits<Type>::kNegInf = -HUGE_VAL;
// The following are *not* casts!
DEF_SIGNED_INT_LIMITS(int8)
DEF_SIGNED_INT_LIMITS(int16) // NOLINT(readability/casting)
DEF_SIGNED_INT_LIMITS(int32) // NOLINT(readability/casting)
DEF_SIGNED_INT_LIMITS(int64) // NOLINT(readability/casting)
DEF_UNSIGNED_INT_LIMITS(uint8)
DEF_UNSIGNED_INT_LIMITS(uint16) // NOLINT(readability/casting)
DEF_UNSIGNED_INT_LIMITS(uint32) // NOLINT(readability/casting)
DEF_UNSIGNED_INT_LIMITS(uint64) // NOLINT(readability/casting)
DEF_SIGNED_INT_LIMITS(long int)
DEF_UNSIGNED_INT_LIMITS(unsigned long int)
DEF_FP_LIMITS(float, FLT)
DEF_FP_LIMITS(double, DBL)
DEF_FP_LIMITS(long double, LDBL);
#undef DEF_COMMON_LIMITS
#undef DEF_SIGNED_INT_LIMITS
#undef DEF_UNSIGNED_INT_LIMITS
#undef DEF_FP_LIMITS
#undef DEF_PRECISION_LIMITS
} // namespace protobuf
} // namespace google
This diff is collapsed.
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// 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_STUBS_MATHUTIL_H_
#define GOOGLE_PROTOBUF_STUBS_MATHUTIL_H_
#include <float.h>
#include <math.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/mathlimits.h>
namespace google {
namespace protobuf {
namespace internal {
template<typename T>
bool IsNan(T value) {
return false;
}
template<>
inline bool IsNan(float value) { return isnan(value); }
template<>
inline bool IsNan(double value) { return isnan(value); }
template<typename T>
bool AlmostEquals(T a, T b) {
return a == b;
}
template<>
inline bool AlmostEquals(float a, float b) {
return fabs(a - b) < 32 * FLT_EPSILON;
}
template<>
inline bool AlmostEquals(double a, double b) {
return fabs(a - b) < 32 * DBL_EPSILON;
}
} // namespace internal
class MathUtil {
public:
template<typename T>
static T Sign(T value) {
if (value == T(0) || ::google::protobuf::internal::IsNan<T>(value)) {
return value;
}
return value > T(0) ? value : -value;
}
template<typename T>
static bool AlmostEquals(T a, T b) {
return ::google::protobuf::internal::AlmostEquals(a, b);
}
// Largest of two values.
// Works correctly for special floating point values.
// Note: 0.0 and -0.0 are not differentiated by Max (Max(0.0, -0.0) is -0.0),
// which should be OK because, although they (can) have different
// bit representation, they are observably the same when examined
// with arithmetic and (in)equality operators.
template<typename T>
static T Max(const T x, const T y) {
return MathLimits<T>::IsNaN(x) || x > y ? x : y;
}
// Absolute value of x
// Works correctly for unsigned types and
// for special floating point values.
// Note: 0.0 and -0.0 are not differentiated by Abs (Abs(0.0) is -0.0),
// which should be OK: see the comment for Max above.
template<typename T>
static T Abs(const T x) {
return x > T(0) ? x : -x;
}
// Absolute value of the difference between two numbers.
// Works correctly for signed types and special floating point values.
template<typename T>
static typename MathLimits<T>::UnsignedType AbsDiff(const T x, const T y) {
// Carries out arithmetic as unsigned to avoid overflow.
typedef typename MathLimits<T>::UnsignedType R;
return x > y ? R(x) - R(y) : R(y) - R(x);
}
// If two (usually floating point) numbers are within a certain
// fraction of their magnitude or within a certain absolute margin of error.
// This is the same as the following but faster:
// WithinFraction(x, y, fraction) || WithinMargin(x, y, margin)
// E.g. WithinFraction(0.0, 1e-10, 1e-5) is false but
// WithinFractionOrMargin(0.0, 1e-10, 1e-5, 1e-5) is true.
template<typename T>
static bool WithinFractionOrMargin(const T x, const T y,
const T fraction, const T margin);
};
template<typename T>
bool MathUtil::WithinFractionOrMargin(const T x, const T y,
const T fraction, const T margin) {
// Not just "0 <= fraction" to fool the compiler for unsigned types.
GOOGLE_DCHECK((T(0) < fraction || T(0) == fraction) &&
fraction < T(1) &&
margin >= T(0));
// Template specialization will convert the if() condition to a constant,
// which will cause the compiler to generate code for either the "if" part
// or the "then" part. In this way we avoid a compiler warning
// about a potential integer overflow in crosstool v12 (gcc 4.3.1).
if (MathLimits<T>::kIsInteger) {
return x == y;
} else {
// IsFinite checks are to make kPosInf and kNegInf not within fraction
if (!MathLimits<T>::IsFinite(x) && !MathLimits<T>::IsFinite(y)) {
return false;
}
T relative_margin = static_cast<T>(fraction * Max(Abs(x), Abs(y)));
return AbsDiff(x, y) <= Max(margin, relative_margin);
}
}
} // namespace protobuf
} // namespace google
#endif // GOOGLE_PROTOBUF_STUBS_MATHUTIL_H_
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// 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.
#include <google/protobuf/stubs/status.h>
#include <ostream>
#include <stdint.h>
#include <stdio.h>
#include <string>
#include <utility>
namespace google {
namespace protobuf {
namespace util {
namespace error {
inline string CodeEnumToString(error::Code code) {
switch (code) {
case OK:
return "OK";
case CANCELLED:
return "CANCELLED";
case UNKNOWN:
return "UNKNOWN";
case INVALID_ARGUMENT:
return "INVALID_ARGUMENT";
case DEADLINE_EXCEEDED:
return "DEADLINE_EXCEEDED";
case NOT_FOUND:
return "NOT_FOUND";
case ALREADY_EXISTS:
return "ALREADY_EXISTS";
case PERMISSION_DENIED:
return "PERMISSION_DENIED";
case UNAUTHENTICATED:
return "UNAUTHENTICATED";
case RESOURCE_EXHAUSTED:
return "RESOURCE_EXHAUSTED";
case FAILED_PRECONDITION:
return "FAILED_PRECONDITION";
case ABORTED:
return "ABORTED";
case OUT_OF_RANGE:
return "OUT_OF_RANGE";
case UNIMPLEMENTED:
return "UNIMPLEMENTED";
case INTERNAL:
return "INTERNAL";
case UNAVAILABLE:
return "UNAVAILABLE";
case DATA_LOSS:
return "DATA_LOSS";
}
// No default clause, clang will abort if a code is missing from
// above switch.
return "UNKNOWN";
}
} // namespace error.
const Status Status::OK = Status();
const Status Status::CANCELLED = Status(error::CANCELLED, "");
const Status Status::UNKNOWN = Status(error::UNKNOWN, "");
Status::Status() : error_code_(error::OK) {
}
Status::Status(error::Code error_code, StringPiece error_message)
: error_code_(error_code) {
if (error_code != error::OK) {
error_message_ = error_message.ToString();
}
}
Status::Status(const Status& other)
: error_code_(other.error_code_), error_message_(other.error_message_) {
}
Status& Status::operator=(const Status& other) {
error_code_ = other.error_code_;
error_message_ = other.error_message_;
return *this;
}
bool Status::operator==(const Status& x) const {
return error_code_ == x.error_code_ &&
error_message_ == x.error_message_;
}
string Status::ToString() const {
if (error_code_ == error::OK) {
return "OK";
} else {
if (error_message_.empty()) {
return error::CodeEnumToString(error_code_);
} else {
return error::CodeEnumToString(error_code_) + ":" +
error_message_;
}
}
}
ostream& operator<<(ostream& os, const Status& x) {
os << x.ToString();
return os;
}
} // namespace util
} // namespace protobuf
} // namespace google
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// 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_STUBS_STATUS_H_
#define GOOGLE_PROTOBUF_STUBS_STATUS_H_
#include <iosfwd>
#include <string>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/stringpiece.h>
namespace google {
namespace protobuf {
namespace util {
namespace error {
// These values must match error codes defined in google/rpc/code.proto.
enum Code {
OK = 0,
CANCELLED = 1,
UNKNOWN = 2,
INVALID_ARGUMENT = 3,
DEADLINE_EXCEEDED = 4,
NOT_FOUND = 5,
ALREADY_EXISTS = 6,
PERMISSION_DENIED = 7,
UNAUTHENTICATED = 16,
RESOURCE_EXHAUSTED = 8,
FAILED_PRECONDITION = 9,
ABORTED = 10,
OUT_OF_RANGE = 11,
UNIMPLEMENTED = 12,
INTERNAL = 13,
UNAVAILABLE = 14,
DATA_LOSS = 15,
};
} // namespace error
class LIBPROTOBUF_EXPORT Status {
public:
// Creates a "successful" status.
Status();
// Create a status in the canonical error space with the specified
// code, and error message. If "code == 0", error_message is
// ignored and a Status object identical to Status::OK is
// constructed.
Status(error::Code error_code, StringPiece error_message);
Status(const Status&);
Status& operator=(const Status& x);
~Status() {}
// Some pre-defined Status objects
static const Status OK; // Identical to 0-arg constructor
static const Status CANCELLED;
static const Status UNKNOWN;
// Accessor
bool ok() const {
return error_code_ == error::OK;
}
int error_code() const {
return error_code_;
}
StringPiece error_message() const {
return error_message_;
}
bool operator==(const Status& x) const;
bool operator!=(const Status& x) const {
return !operator==(x);
}
// Return a combination of the error code name and message.
string ToString() const;
private:
error::Code error_code_;
string error_message_;
};
// Prints a human-readable representation of 'x' to 'os'.
LIBPROTOBUF_EXPORT ostream& operator<<(ostream& os, const Status& x);
#define EXPECT_OK(value) EXPECT_TRUE((value).ok())
} // namespace util
} // namespace protobuf
} // namespace google
#endif // GOOGLE_PROTOBUF_STUBS_STATUS_H_
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// 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: util/task/contrib/status_macros/status_macros.h
#ifndef GOOGLE_PROTOBUF_STUBS_STATUS_MACROS_H_
#define GOOGLE_PROTOBUF_STUBS_STATUS_MACROS_H_
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/status.h>
#include <google/protobuf/stubs/statusor.h>
namespace google {
namespace protobuf {
namespace util {
// Run a command that returns a util::Status. If the called code returns an
// error status, return that status up out of this method too.
//
// Example:
// RETURN_IF_ERROR(DoThings(4));
#define RETURN_IF_ERROR(expr) \
do { \
/* Using _status below to avoid capture problems if expr is "status". */ \
const ::google::protobuf::util::Status _status = (expr); \
if (GOOGLE_PREDICT_FALSE(!_status.ok())) return _status; \
} while (0)
// Internal helper for concatenating macro values.
#define STATUS_MACROS_CONCAT_NAME_INNER(x, y) x##y
#define STATUS_MACROS_CONCAT_NAME(x, y) STATUS_MACROS_CONCAT_NAME_INNER(x, y)
template<typename T>
Status DoAssignOrReturn(T& lhs, StatusOr<T> result) {
if (result.ok()) {
lhs = result.ValueOrDie();
}
return result.status();
}
#define ASSIGN_OR_RETURN_IMPL(status, lhs, rexpr) \
Status status = DoAssignOrReturn(lhs, (rexpr)); \
if (GOOGLE_PREDICT_FALSE(!status.ok())) return status;
// Executes an expression that returns a util::StatusOr, extracting its value
// into the variable defined by lhs (or returning on error).
//
// Example: Assigning to an existing value
// ValueType value;
// ASSIGN_OR_RETURN(value, MaybeGetValue(arg));
//
// WARNING: ASSIGN_OR_RETURN expands into multiple statements; it cannot be used
// in a single statement (e.g. as the body of an if statement without {})!
#define ASSIGN_OR_RETURN(lhs, rexpr) \
ASSIGN_OR_RETURN_IMPL( \
STATUS_MACROS_CONCAT_NAME(_status_or_value, __COUNTER__), lhs, rexpr);
} // namespace util
} // namespace protobuf
} // namespace google
#endif // GOOGLE_PROTOBUF_STUBS_STATUS_H_
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// 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.
#include <google/protobuf/stubs/status.h>
#include <stdio.h>
#include <google/protobuf/testing/googletest.h>
#include <gtest/gtest.h>
namespace google {
namespace protobuf {
namespace {
TEST(Status, Empty) {
util::Status status;
EXPECT_EQ(util::error::OK, util::Status::OK.error_code());
EXPECT_EQ("OK", util::Status::OK.ToString());
}
TEST(Status, GenericCodes) {
EXPECT_EQ(util::error::OK, util::Status::OK.error_code());
EXPECT_EQ(util::error::CANCELLED, util::Status::CANCELLED.error_code());
EXPECT_EQ(util::error::UNKNOWN, util::Status::UNKNOWN.error_code());
}
TEST(Status, ConstructorZero) {
util::Status status(util::error::OK, "msg");
EXPECT_TRUE(status.ok());
EXPECT_EQ("OK", status.ToString());
}
TEST(Status, CheckOK) {
util::Status status;
GOOGLE_CHECK_OK(status);
GOOGLE_CHECK_OK(status) << "Failed";
GOOGLE_DCHECK_OK(status) << "Failed";
}
TEST(Status, ErrorMessage) {
util::Status status(util::error::INVALID_ARGUMENT, "");
EXPECT_FALSE(status.ok());
EXPECT_EQ("", status.error_message().ToString());
EXPECT_EQ("INVALID_ARGUMENT", status.ToString());
status = util::Status(util::error::INVALID_ARGUMENT, "msg");
EXPECT_FALSE(status.ok());
EXPECT_EQ("msg", status.error_message().ToString());
EXPECT_EQ("INVALID_ARGUMENT:msg", status.ToString());
status = util::Status(util::error::OK, "msg");
EXPECT_TRUE(status.ok());
EXPECT_EQ("", status.error_message().ToString());
EXPECT_EQ("OK", status.ToString());
}
TEST(Status, Copy) {
util::Status a(util::error::UNKNOWN, "message");
util::Status b(a);
ASSERT_EQ(a.ToString(), b.ToString());
}
TEST(Status, Assign) {
util::Status a(util::error::UNKNOWN, "message");
util::Status b;
b = a;
ASSERT_EQ(a.ToString(), b.ToString());
}
TEST(Status, AssignEmpty) {
util::Status a(util::error::UNKNOWN, "message");
util::Status b;
a = b;
ASSERT_EQ(string("OK"), a.ToString());
ASSERT_TRUE(b.ok());
ASSERT_TRUE(a.ok());
}
TEST(Status, EqualsOK) {
ASSERT_EQ(util::Status::OK, util::Status());
}
TEST(Status, EqualsSame) {
const util::Status a = util::Status(util::error::CANCELLED, "message");
const util::Status b = util::Status(util::error::CANCELLED, "message");
ASSERT_EQ(a, b);
}
TEST(Status, EqualsCopy) {
const util::Status a = util::Status(util::error::CANCELLED, "message");
const util::Status b = a;
ASSERT_EQ(a, b);
}
TEST(Status, EqualsDifferentCode) {
const util::Status a = util::Status(util::error::CANCELLED, "message");
const util::Status b = util::Status(util::error::UNKNOWN, "message");
ASSERT_NE(a, b);
}
TEST(Status, EqualsDifferentMessage) {
const util::Status a = util::Status(util::error::CANCELLED, "message");
const util::Status b = util::Status(util::error::CANCELLED, "another");
ASSERT_NE(a, b);
}
} // namespace
} // namespace protobuf
} // namespace google
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// 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.
#include <google/protobuf/stubs/statusor.h>
namespace google {
namespace protobuf {
namespace util {
namespace internal {
void StatusOrHelper::Crash(const Status& status) {
GOOGLE_LOG(FATAL) << "Attempting to fetch value instead of handling error "
<< status.ToString();
}
} // namespace internal
} // namespace util
} // namespace protobuf
} // namespace google
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// 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.
// StatusOr<T> is the union of a Status object and a T
// object. StatusOr models the concept of an object that is either a
// usable value, or an error Status explaining why such a value is
// not present. To this end, StatusOr<T> does not allow its Status
// value to be Status::OK. Further, StatusOr<T*> does not allow the
// contained pointer to be NULL.
//
// The primary use-case for StatusOr<T> is as the return value of a
// function which may fail.
//
// Example client usage for a StatusOr<T>, where T is not a pointer:
//
// StatusOr<float> result = DoBigCalculationThatCouldFail();
// if (result.ok()) {
// float answer = result.ValueOrDie();
// printf("Big calculation yielded: %f", answer);
// } else {
// LOG(ERROR) << result.status();
// }
//
// Example client usage for a StatusOr<T*>:
//
// StatusOr<Foo*> result = FooFactory::MakeNewFoo(arg);
// if (result.ok()) {
// std::unique_ptr<Foo> foo(result.ValueOrDie());
// foo->DoSomethingCool();
// } else {
// LOG(ERROR) << result.status();
// }
//
// Example client usage for a StatusOr<std::unique_ptr<T>>:
//
// StatusOr<std::unique_ptr<Foo>> result = FooFactory::MakeNewFoo(arg);
// if (result.ok()) {
// std::unique_ptr<Foo> foo = result.ConsumeValueOrDie();
// foo->DoSomethingCool();
// } else {
// LOG(ERROR) << result.status();
// }
//
// Example factory implementation returning StatusOr<T*>:
//
// StatusOr<Foo*> FooFactory::MakeNewFoo(int arg) {
// if (arg <= 0) {
// return ::util::Status(::util::error::INVALID_ARGUMENT,
// "Arg must be positive");
// } else {
// return new Foo(arg);
// }
// }
//
#ifndef GOOGLE_PROTOBUF_STUBS_STATUSOR_H_
#define GOOGLE_PROTOBUF_STUBS_STATUSOR_H_
#include <new>
#include <string>
#include <utility>
#include <google/protobuf/stubs/status.h>
namespace google {
namespace protobuf {
namespace util {
template<typename T>
class StatusOr {
template<typename U> friend class StatusOr;
public:
// Construct a new StatusOr with Status::UNKNOWN status
StatusOr();
// Construct a new StatusOr with the given non-ok status. After calling
// this constructor, calls to ValueOrDie() will CHECK-fail.
//
// NOTE: Not explicit - we want to use StatusOr<T> as a return
// value, so it is convenient and sensible to be able to do 'return
// Status()' when the return type is StatusOr<T>.
//
// REQUIRES: status != Status::OK. This requirement is DCHECKed.
// In optimized builds, passing Status::OK here will have the effect
// of passing PosixErrorSpace::EINVAL as a fallback.
StatusOr(const Status& status); // NOLINT
// Construct a new StatusOr with the given value. If T is a plain pointer,
// value must not be NULL. After calling this constructor, calls to
// ValueOrDie() will succeed, and calls to status() will return OK.
//
// NOTE: Not explicit - we want to use StatusOr<T> as a return type
// so it is convenient and sensible to be able to do 'return T()'
// when when the return type is StatusOr<T>.
//
// REQUIRES: if T is a plain pointer, value != NULL. This requirement is
// DCHECKed. In optimized builds, passing a NULL pointer here will have
// the effect of passing PosixErrorSpace::EINVAL as a fallback.
StatusOr(const T& value); // NOLINT
// Copy constructor.
StatusOr(const StatusOr& other);
// Conversion copy constructor, T must be copy constructible from U
template<typename U>
StatusOr(const StatusOr<U>& other);
// Assignment operator.
StatusOr& operator=(const StatusOr& other);
// Conversion assignment operator, T must be assignable from U
template<typename U>
StatusOr& operator=(const StatusOr<U>& other);
// Returns a reference to our status. If this contains a T, then
// returns Status::OK.
const Status& status() const;
// Returns this->status().ok()
bool ok() const;
// Returns a reference to our current value, or CHECK-fails if !this->ok().
// If you need to initialize a T object from the stored value,
// ConsumeValueOrDie() may be more efficient.
const T& ValueOrDie() const;
private:
Status status_;
T value_;
};
////////////////////////////////////////////////////////////////////////////////
// Implementation details for StatusOr<T>
namespace internal {
class LIBPROTOBUF_EXPORT StatusOrHelper {
public:
// Move type-agnostic error handling to the .cc.
static void Crash(const util::Status& status);
// Customized behavior for StatusOr<T> vs. StatusOr<T*>
template<typename T>
struct Specialize;
};
template<typename T>
struct StatusOrHelper::Specialize {
// For non-pointer T, a reference can never be NULL.
static inline bool IsValueNull(const T& t) { return false; }
};
template<typename T>
struct StatusOrHelper::Specialize<T*> {
static inline bool IsValueNull(const T* t) { return t == NULL; }
};
} // namespace internal
template<typename T>
inline StatusOr<T>::StatusOr()
: status_(util::Status::UNKNOWN) {
}
template<typename T>
inline StatusOr<T>::StatusOr(const Status& status) {
if (status.ok()) {
status_ = Status(error::INTERNAL, "Status::OK is not a valid argument.");
} else {
status_ = status;
}
}
template<typename T>
inline StatusOr<T>::StatusOr(const T& value) {
if (internal::StatusOrHelper::Specialize<T>::IsValueNull(value)) {
status_ = Status(error::INTERNAL, "NULL is not a vaild argument.");
} else {
status_ = Status::OK;
value_ = value;
}
}
template<typename T>
inline StatusOr<T>::StatusOr(const StatusOr<T>& other)
: status_(other.status_), value_(other.value_) {
}
template<typename T>
inline StatusOr<T>& StatusOr<T>::operator=(const StatusOr<T>& other) {
status_ = other.status_;
value_ = other.value_;
return *this;
}
template<typename T>
template<typename U>
inline StatusOr<T>::StatusOr(const StatusOr<U>& other)
: status_(other.status_), value_(other.value_) {
}
template<typename T>
template<typename U>
inline StatusOr<T>& StatusOr<T>::operator=(const StatusOr<U>& other) {
status_ = other.status_;
value_ = other.value_;
return *this;
}
template<typename T>
inline const Status& StatusOr<T>::status() const {
return status_;
}
template<typename T>
inline bool StatusOr<T>::ok() const {
return status().ok();
}
template<typename T>
inline const T& StatusOr<T>::ValueOrDie() const {
if (!status_.ok()) {
internal::StatusOrHelper::Crash(status_);
}
return value_;
}
} // namespace util
} // namespace protobuf
} // namespace google
#endif // GOOGLE_PROTOBUF_STUBS_STATUSOR_H_
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// 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.
#include <google/protobuf/stubs/statusor.h>
#include <errno.h>
#include <memory>
#include <google/protobuf/testing/googletest.h>
#include <gtest/gtest.h>
namespace google {
namespace protobuf {
namespace util {
namespace {
class Base1 {
public:
virtual ~Base1() {}
int pad;
};
class Base2 {
public:
virtual ~Base2() {}
int yetotherpad;
};
class Derived : public Base1, public Base2 {
public:
virtual ~Derived() {}
int evenmorepad;
};
class CopyNoAssign {
public:
explicit CopyNoAssign(int value) : foo(value) {}
CopyNoAssign(const CopyNoAssign& other) : foo(other.foo) {}
int foo;
private:
const CopyNoAssign& operator=(const CopyNoAssign&);
};
TEST(StatusOr, TestDefaultCtor) {
StatusOr<int> thing;
EXPECT_FALSE(thing.ok());
EXPECT_EQ(Status::UNKNOWN, thing.status());
}
TEST(StatusOr, TestStatusCtor) {
StatusOr<int> thing(Status::CANCELLED);
EXPECT_FALSE(thing.ok());
EXPECT_EQ(Status::CANCELLED, thing.status());
}
TEST(StatusOr, TestValueCtor) {
const int kI = 4;
StatusOr<int> thing(kI);
EXPECT_TRUE(thing.ok());
EXPECT_EQ(kI, thing.ValueOrDie());
}
TEST(StatusOr, TestCopyCtorStatusOk) {
const int kI = 4;
StatusOr<int> original(kI);
StatusOr<int> copy(original);
EXPECT_EQ(original.status(), copy.status());
EXPECT_EQ(original.ValueOrDie(), copy.ValueOrDie());
}
TEST(StatusOr, TestCopyCtorStatusNotOk) {
StatusOr<int> original(Status::CANCELLED);
StatusOr<int> copy(original);
EXPECT_EQ(original.status(), copy.status());
}
TEST(StatusOr, TestCopyCtorStatusOKConverting) {
const int kI = 4;
StatusOr<int> original(kI);
StatusOr<double> copy(original);
EXPECT_EQ(original.status(), copy.status());
EXPECT_EQ(original.ValueOrDie(), copy.ValueOrDie());
}
TEST(StatusOr, TestCopyCtorStatusNotOkConverting) {
StatusOr<int> original(Status::CANCELLED);
StatusOr<double> copy(original);
EXPECT_EQ(original.status(), copy.status());
}
TEST(StatusOr, TestAssignmentStatusOk) {
const int kI = 4;
StatusOr<int> source(kI);
StatusOr<int> target;
target = source;
EXPECT_EQ(source.status(), target.status());
EXPECT_EQ(source.ValueOrDie(), target.ValueOrDie());
}
TEST(StatusOr, TestAssignmentStatusNotOk) {
StatusOr<int> source(Status::CANCELLED);
StatusOr<int> target;
target = source;
EXPECT_EQ(source.status(), target.status());
}
TEST(StatusOr, TestAssignmentStatusOKConverting) {
const int kI = 4;
StatusOr<int> source(kI);
StatusOr<double> target;
target = source;
EXPECT_EQ(source.status(), target.status());
EXPECT_DOUBLE_EQ(source.ValueOrDie(), target.ValueOrDie());
}
TEST(StatusOr, TestAssignmentStatusNotOkConverting) {
StatusOr<int> source(Status::CANCELLED);
StatusOr<double> target;
target = source;
EXPECT_EQ(source.status(), target.status());
}
TEST(StatusOr, TestStatus) {
StatusOr<int> good(4);
EXPECT_TRUE(good.ok());
StatusOr<int> bad(Status::CANCELLED);
EXPECT_FALSE(bad.ok());
EXPECT_EQ(Status::CANCELLED, bad.status());
}
TEST(StatusOr, TestValue) {
const int kI = 4;
StatusOr<int> thing(kI);
EXPECT_EQ(kI, thing.ValueOrDie());
}
TEST(StatusOr, TestValueConst) {
const int kI = 4;
const StatusOr<int> thing(kI);
EXPECT_EQ(kI, thing.ValueOrDie());
}
TEST(StatusOr, TestPointerDefaultCtor) {
StatusOr<int*> thing;
EXPECT_FALSE(thing.ok());
EXPECT_EQ(Status::UNKNOWN, thing.status());
}
TEST(StatusOr, TestPointerStatusCtor) {
StatusOr<int*> thing(Status::CANCELLED);
EXPECT_FALSE(thing.ok());
EXPECT_EQ(Status::CANCELLED, thing.status());
}
TEST(StatusOr, TestPointerValueCtor) {
const int kI = 4;
StatusOr<const int*> thing(&kI);
EXPECT_TRUE(thing.ok());
EXPECT_EQ(&kI, thing.ValueOrDie());
}
TEST(StatusOr, TestPointerCopyCtorStatusOk) {
const int kI = 0;
StatusOr<const int*> original(&kI);
StatusOr<const int*> copy(original);
EXPECT_EQ(original.status(), copy.status());
EXPECT_EQ(original.ValueOrDie(), copy.ValueOrDie());
}
TEST(StatusOr, TestPointerCopyCtorStatusNotOk) {
StatusOr<int*> original(Status::CANCELLED);
StatusOr<int*> copy(original);
EXPECT_EQ(original.status(), copy.status());
}
TEST(StatusOr, TestPointerCopyCtorStatusOKConverting) {
Derived derived;
StatusOr<Derived*> original(&derived);
StatusOr<Base2*> copy(original);
EXPECT_EQ(original.status(), copy.status());
EXPECT_EQ(static_cast<const Base2*>(original.ValueOrDie()),
copy.ValueOrDie());
}
TEST(StatusOr, TestPointerCopyCtorStatusNotOkConverting) {
StatusOr<Derived*> original(Status::CANCELLED);
StatusOr<Base2*> copy(original);
EXPECT_EQ(original.status(), copy.status());
}
TEST(StatusOr, TestPointerAssignmentStatusOk) {
const int kI = 0;
StatusOr<const int*> source(&kI);
StatusOr<const int*> target;
target = source;
EXPECT_EQ(source.status(), target.status());
EXPECT_EQ(source.ValueOrDie(), target.ValueOrDie());
}
TEST(StatusOr, TestPointerAssignmentStatusNotOk) {
StatusOr<int*> source(Status::CANCELLED);
StatusOr<int*> target;
target = source;
EXPECT_EQ(source.status(), target.status());
}
TEST(StatusOr, TestPointerAssignmentStatusOKConverting) {
Derived derived;
StatusOr<Derived*> source(&derived);
StatusOr<Base2*> target;
target = source;
EXPECT_EQ(source.status(), target.status());
EXPECT_EQ(static_cast<const Base2*>(source.ValueOrDie()),
target.ValueOrDie());
}
TEST(StatusOr, TestPointerAssignmentStatusNotOkConverting) {
StatusOr<Derived*> source(Status::CANCELLED);
StatusOr<Base2*> target;
target = source;
EXPECT_EQ(source.status(), target.status());
}
TEST(StatusOr, TestPointerStatus) {
const int kI = 0;
StatusOr<const int*> good(&kI);
EXPECT_TRUE(good.ok());
StatusOr<const int*> bad(Status::CANCELLED);
EXPECT_EQ(Status::CANCELLED, bad.status());
}
TEST(StatusOr, TestPointerValue) {
const int kI = 0;
StatusOr<const int*> thing(&kI);
EXPECT_EQ(&kI, thing.ValueOrDie());
}
TEST(StatusOr, TestPointerValueConst) {
const int kI = 0;
const StatusOr<const int*> thing(&kI);
EXPECT_EQ(&kI, thing.ValueOrDie());
}
} // namespace
} // namespace util
} // namespace protobuf
} // namespace google
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// 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.
#include <google/protobuf/stubs/stringpiece.h>
#include <string.h>
#include <algorithm>
#include <climits>
#include <string>
#include <ostream>
namespace google {
namespace protobuf {
std::ostream& operator<<(std::ostream& o, StringPiece piece) {
o.write(piece.data(), piece.size());
return o;
}
// Out-of-line error path.
void StringPiece::LogFatalSizeTooBig(size_t size, const char* details) {
GOOGLE_LOG(FATAL) << "size too big: " << size << " details: " << details;
}
StringPiece::StringPiece(StringPiece x, stringpiece_ssize_type pos)
: ptr_(x.ptr_ + pos), length_(x.length_ - pos) {
GOOGLE_DCHECK_LE(0, pos);
GOOGLE_DCHECK_LE(pos, x.length_);
}
StringPiece::StringPiece(StringPiece x,
stringpiece_ssize_type pos,
stringpiece_ssize_type len)
: ptr_(x.ptr_ + pos), length_(std::min(len, x.length_ - pos)) {
GOOGLE_DCHECK_LE(0, pos);
GOOGLE_DCHECK_LE(pos, x.length_);
GOOGLE_DCHECK_GE(len, 0);
}
void StringPiece::CopyToString(string* target) const {
target->assign(ptr_, length_);
}
void StringPiece::AppendToString(string* target) const {
target->append(ptr_, length_);
}
bool StringPiece::Consume(StringPiece x) {
if (starts_with(x)) {
ptr_ += x.length_;
length_ -= x.length_;
return true;
}
return false;
}
bool StringPiece::ConsumeFromEnd(StringPiece x) {
if (ends_with(x)) {
length_ -= x.length_;
return true;
}
return false;
}
stringpiece_ssize_type StringPiece::copy(char* buf,
size_type n,
size_type pos) const {
stringpiece_ssize_type ret = std::min(length_ - pos, n);
memcpy(buf, ptr_ + pos, ret);
return ret;
}
bool StringPiece::contains(StringPiece s) const {
return find(s, 0) != npos;
}
stringpiece_ssize_type StringPiece::find(StringPiece s, size_type pos) const {
if (length_ <= 0 || pos > static_cast<size_type>(length_)) {
if (length_ == 0 && pos == 0 && s.length_ == 0) return 0;
return npos;
}
const char *result = std::search(ptr_ + pos, ptr_ + length_,
s.ptr_, s.ptr_ + s.length_);
return result == ptr_ + length_ ? npos : result - ptr_;
}
stringpiece_ssize_type StringPiece::find(char c, size_type pos) const {
if (length_ <= 0 || pos >= static_cast<size_type>(length_)) {
return npos;
}
const char* result = static_cast<const char*>(
memchr(ptr_ + pos, c, length_ - pos));
return result != NULL ? result - ptr_ : npos;
}
stringpiece_ssize_type StringPiece::rfind(StringPiece s, size_type pos) const {
if (length_ < s.length_) return npos;
const size_t ulen = length_;
if (s.length_ == 0) return std::min(ulen, pos);
const char* last = ptr_ + std::min(ulen - s.length_, pos) + s.length_;
const char* result = std::find_end(ptr_, last, s.ptr_, s.ptr_ + s.length_);
return result != last ? result - ptr_ : npos;
}
// Search range is [0..pos] inclusive. If pos == npos, search everything.
stringpiece_ssize_type StringPiece::rfind(char c, size_type pos) const {
// Note: memrchr() is not available on Windows.
if (length_ <= 0) return npos;
for (stringpiece_ssize_type i =
std::min(pos, static_cast<size_type>(length_ - 1));
i >= 0; --i) {
if (ptr_[i] == c) {
return i;
}
}
return npos;
}
// For each character in characters_wanted, sets the index corresponding
// to the ASCII code of that character to 1 in table. This is used by
// the find_.*_of methods below to tell whether or not a character is in
// the lookup table in constant time.
// The argument `table' must be an array that is large enough to hold all
// the possible values of an unsigned char. Thus it should be be declared
// as follows:
// bool table[UCHAR_MAX + 1]
static inline void BuildLookupTable(StringPiece characters_wanted,
bool* table) {
const stringpiece_ssize_type length = characters_wanted.length();
const char* const data = characters_wanted.data();
for (stringpiece_ssize_type i = 0; i < length; ++i) {
table[static_cast<unsigned char>(data[i])] = true;
}
}
stringpiece_ssize_type StringPiece::find_first_of(StringPiece s,
size_type pos) const {
if (length_ <= 0 || s.length_ <= 0) {
return npos;
}
// Avoid the cost of BuildLookupTable() for a single-character search.
if (s.length_ == 1) return find_first_of(s.ptr_[0], pos);
bool lookup[UCHAR_MAX + 1] = { false };
BuildLookupTable(s, lookup);
for (stringpiece_ssize_type i = pos; i < length_; ++i) {
if (lookup[static_cast<unsigned char>(ptr_[i])]) {
return i;
}
}
return npos;
}
stringpiece_ssize_type StringPiece::find_first_not_of(StringPiece s,
size_type pos) const {
if (length_ <= 0) return npos;
if (s.length_ <= 0) return 0;
// Avoid the cost of BuildLookupTable() for a single-character search.
if (s.length_ == 1) return find_first_not_of(s.ptr_[0], pos);
bool lookup[UCHAR_MAX + 1] = { false };
BuildLookupTable(s, lookup);
for (stringpiece_ssize_type i = pos; i < length_; ++i) {
if (!lookup[static_cast<unsigned char>(ptr_[i])]) {
return i;
}
}
return npos;
}
stringpiece_ssize_type StringPiece::find_first_not_of(char c,
size_type pos) const {
if (length_ <= 0) return npos;
for (; pos < static_cast<size_type>(length_); ++pos) {
if (ptr_[pos] != c) {
return pos;
}
}
return npos;
}
stringpiece_ssize_type StringPiece::find_last_of(StringPiece s,
size_type pos) const {
if (length_ <= 0 || s.length_ <= 0) return npos;
// Avoid the cost of BuildLookupTable() for a single-character search.
if (s.length_ == 1) return find_last_of(s.ptr_[0], pos);
bool lookup[UCHAR_MAX + 1] = { false };
BuildLookupTable(s, lookup);
for (stringpiece_ssize_type i =
std::min(pos, static_cast<size_type>(length_ - 1)); i >= 0; --i) {
if (lookup[static_cast<unsigned char>(ptr_[i])]) {
return i;
}
}
return npos;
}
stringpiece_ssize_type StringPiece::find_last_not_of(StringPiece s,
size_type pos) const {
if (length_ <= 0) return npos;
stringpiece_ssize_type i = std::min(pos, static_cast<size_type>(length_ - 1));
if (s.length_ <= 0) return i;
// Avoid the cost of BuildLookupTable() for a single-character search.
if (s.length_ == 1) return find_last_not_of(s.ptr_[0], pos);
bool lookup[UCHAR_MAX + 1] = { false };
BuildLookupTable(s, lookup);
for (; i >= 0; --i) {
if (!lookup[static_cast<unsigned char>(ptr_[i])]) {
return i;
}
}
return npos;
}
stringpiece_ssize_type StringPiece::find_last_not_of(char c,
size_type pos) const {
if (length_ <= 0) return npos;
for (stringpiece_ssize_type i =
std::min(pos, static_cast<size_type>(length_ - 1)); i >= 0; --i) {
if (ptr_[i] != c) {
return i;
}
}
return npos;
}
StringPiece StringPiece::substr(size_type pos, size_type n) const {
if (pos > length_) pos = length_;
if (n > length_ - pos) n = length_ - pos;
return StringPiece(ptr_ + pos, n);
}
const StringPiece::size_type StringPiece::npos = size_type(-1);
} // namespace protobuf
} // namespace google
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// 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_STUBS_TIME_H_
#define GOOGLE_PROTOBUF_STUBS_TIME_H_
#include <google/protobuf/stubs/common.h>
namespace google {
namespace protobuf {
namespace internal {
struct DateTime {
int year;
int month;
int day;
int hour;
int minute;
int second;
};
// Converts a timestamp (seconds elapsed since 1970-01-01T00:00:00, could be
// negative to represent time before 1970-01-01) to DateTime. Returns false
// if the timestamp is not in the range between 0001-01-01T00:00:00 and
// 9999-12-31T23:59:59.
bool LIBPROTOBUF_EXPORT SecondsToDateTime(int64 seconds, DateTime* time);
// Converts DateTime to a timestamp (seconds since 1970-01-01T00:00:00).
// Returns false if the DateTime is not valid or is not in the valid range.
bool LIBPROTOBUF_EXPORT DateTimeToSeconds(const DateTime& time, int64* seconds);
void LIBPROTOBUF_EXPORT GetCurrentTime(int64* seconds, int32* nanos);
// Formats a time string in RFC3339 fromat.
//
// For example, "2015-05-20T13:29:35.120Z". For nanos, 0, 3, 6 or 9 fractional
// digits will be used depending on how many are required to represent the exact
// value.
//
// Note that "nanos" must in the range of [0, 999999999].
string LIBPROTOBUF_EXPORT FormatTime(int64 seconds, int32 nanos);
// Parses a time string. This method accepts RFC3339 date/time string with UTC
// offset. For example, "2015-05-20T13:29:35.120-08:00".
bool LIBPROTOBUF_EXPORT ParseTime(const string& vaule, int64* seconds, int32* nanos);
} // namespace internal
} // namespace protobuf
} // namespace google
#endif // GOOGLE_PROTOBUF_STUBS_TIME_H_
This diff is collapsed.
......@@ -1880,7 +1880,7 @@ void TextFormat::Printer::PrintUnknownFields(
generator.Print(field_number);
generator.Print(": 0x");
generator.Print(
StrCat(strings::Hex(field.fixed32(), strings::Hex::ZERO_PAD_8)));
StrCat(strings::Hex(field.fixed32(), strings::ZERO_PAD_8)));
if (single_line_mode_) {
generator.Print(" ");
} else {
......@@ -1892,7 +1892,7 @@ void TextFormat::Printer::PrintUnknownFields(
generator.Print(field_number);
generator.Print(": 0x");
generator.Print(
StrCat(strings::Hex(field.fixed64(), strings::Hex::ZERO_PAD_16)));
StrCat(strings::Hex(field.fixed64(), strings::ZERO_PAD_16)));
if (single_line_mode_) {
generator.Print(" ");
} else {
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// 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.
#include <google/protobuf/util/internal/error_listener.h>
namespace google {
namespace protobuf {
namespace util {
namespace converter {
} // namespace converter
} // namespace util
} // namespace protobuf
} // namespace google
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment