Setup build system for Linux
This commit is contained in:
parent
81cdd02a61
commit
26ca509cbb
|
@ -4,8 +4,10 @@
|
||||||
*.VC.opendb
|
*.VC.opendb
|
||||||
*.VC.db
|
*.VC.db
|
||||||
|
|
||||||
build
|
|
||||||
bin
|
|
||||||
lib
|
|
||||||
CMakeCache.txt
|
CMakeCache.txt
|
||||||
CMakeFiles
|
CMakeFiles
|
||||||
|
|
||||||
|
bin
|
||||||
|
build
|
||||||
|
include
|
||||||
|
lib
|
||||||
|
|
|
@ -1,21 +1,29 @@
|
||||||
cmake_minimum_required (VERSION 2.6)
|
cmake_minimum_required (VERSION 2.6)
|
||||||
project (CarlaServer)
|
project (CarlaServer)
|
||||||
|
|
||||||
SET(CMAKE_CXX_COMPILER clang++)
|
if (UNIX)
|
||||||
SET(CMAKE_CXX_STANDARD 14)
|
set(CMAKE_CXX_COMPILER clang++)
|
||||||
SET(CMAKE_CXX_STANDARD_REQUIRED 14)
|
find_package(Threads)
|
||||||
|
endif (UNIX)
|
||||||
|
|
||||||
|
set(CMAKE_CXX_STANDARD 14)
|
||||||
|
set(CMAKE_CXX_STANDARD_REQUIRED 14)
|
||||||
|
|
||||||
# Boost configuration
|
# Boost configuration
|
||||||
SET(Boost_USE_STATIC_LIBS ON)
|
set(Boost_USE_STATIC_LIBS ON)
|
||||||
find_package(Boost REQUIRED system date_time regex)
|
find_package(Boost REQUIRED system date_time regex)
|
||||||
include_directories(${Boost_INCLUDE_DIRS})
|
include_directories(${Boost_INCLUDE_DIRS})
|
||||||
|
|
||||||
set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)
|
set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)
|
||||||
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
|
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
|
||||||
|
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
|
||||||
|
|
||||||
|
set(Protobuf_LIBRARY carla_protocol -lprotobuf)
|
||||||
|
|
||||||
include_directories("${PROJECT_SOURCE_DIR}/source")
|
include_directories("${PROJECT_SOURCE_DIR}/source")
|
||||||
include_directories("${PROJECT_SOURCE_DIR}/source/carla/Protocol/carlaProtocol/include")
|
|
||||||
|
|
||||||
|
add_subdirectory(source/carla/protocol)
|
||||||
add_subdirectory(source/carla/server)
|
add_subdirectory(source/carla/server)
|
||||||
add_subdirectory(source/test)
|
add_subdirectory(source/test)
|
||||||
|
|
||||||
|
install(FILES ${PROJECT_SOURCE_DIR}/source/carla/CarlaServer.h DESTINATION ${PROJECT_SOURCE_DIR}/include/carla)
|
||||||
|
|
|
@ -1,21 +1,20 @@
|
||||||
BUILD_FOLDER=build
|
BUILD_FOLDER=build
|
||||||
|
PROTOBUF_SRC_DIR=source/carla/protocol
|
||||||
|
|
||||||
vsproject:
|
default: build
|
||||||
|
cd build && ninja && ninja install
|
||||||
|
|
||||||
|
build: protobuf
|
||||||
|
cmake -H. -B$(BUILD_FOLDER) -G "Ninja"
|
||||||
|
|
||||||
|
vsproject: protobuf
|
||||||
cmake -H. -B$(BUILD_FOLDER) -G "Visual Studio 14 2015 Win64"
|
cmake -H. -B$(BUILD_FOLDER) -G "Visual Studio 14 2015 Win64"
|
||||||
|
|
||||||
stproject:
|
protobuf:
|
||||||
cmake -H. -B$(BUILD_FOLDER) -G "Sublime Text 2 - Ninja"
|
protoc -I=$(PROTOBUF_SRC_DIR) --cpp_out=$(PROTOBUF_SRC_DIR) $(PROTOBUF_SRC_DIR)/carla_protocol.proto
|
||||||
|
|
||||||
cd protobuf-2.6.1
|
|
||||||
./autogen.sh
|
|
||||||
./configure --prefix= ${PROJECT_SOURCE_DIR}/lib
|
|
||||||
make
|
|
||||||
make check
|
|
||||||
sudo make install
|
|
||||||
sudo ldconfig # refresh shared library cache
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -Rf build CMakeFiles
|
rm -Rf build CMakeFiles
|
||||||
|
|
||||||
clean-all: clean
|
clean-all: clean
|
||||||
rm -Rf bin lib
|
rm -Rf bin lib include
|
||||||
|
|
|
@ -3,13 +3,25 @@ CarlaServer
|
||||||
|
|
||||||
Library for socket communications.
|
Library for socket communications.
|
||||||
|
|
||||||
Requires boost libraries installed.
|
|
||||||
|
|
||||||
Building
|
Building
|
||||||
--------
|
--------
|
||||||
|
|
||||||
|
#### Linux
|
||||||
|
|
||||||
|
Install boost, protobuf, and ninja.
|
||||||
|
|
||||||
|
$ sudo apt-get install libprotobuf-dev protobuf-compiler libboost-all-dev ninja-build
|
||||||
|
|
||||||
|
Run make
|
||||||
|
|
||||||
|
$ make
|
||||||
|
|
||||||
|
#### Windows
|
||||||
|
|
||||||
|
Install boost and protobuf.
|
||||||
|
|
||||||
To generate the Visual Studio solution
|
To generate the Visual Studio solution
|
||||||
|
|
||||||
make vsproject
|
$ make vsproject
|
||||||
|
|
||||||
The solution gets generated at `./build/CarlaServer.sln`.
|
The solution gets generated at `./build/CarlaServer.sln`.
|
||||||
|
|
|
@ -0,0 +1,122 @@
|
||||||
|
// CARLA, Copyright (C) 2017 Computer Vision Center (CVC)
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace carla {
|
||||||
|
|
||||||
|
struct Vector2D {
|
||||||
|
float x;
|
||||||
|
float y;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Vector3D {
|
||||||
|
float x;
|
||||||
|
float y;
|
||||||
|
float z;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Color {
|
||||||
|
uint8 B;
|
||||||
|
uint8 G;
|
||||||
|
uint8 R;
|
||||||
|
uint8 A;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Reward_Values {
|
||||||
|
/// Time-stamp of the current frame.
|
||||||
|
int32 timestamp;
|
||||||
|
/// World location of the player.
|
||||||
|
Vector2D player_location;
|
||||||
|
/// Orientation of the player.
|
||||||
|
Vector3D player_orientation;
|
||||||
|
/// Current acceleration of the player.
|
||||||
|
Vector3D player_acceleration;
|
||||||
|
/// Forward speed in km/h.
|
||||||
|
float forward_speed;
|
||||||
|
/// General collision intensity (everything else but pedestrians and cars).
|
||||||
|
float collision_general;
|
||||||
|
/// Collision intensity with pedestrians.
|
||||||
|
float collision_pedestrian;
|
||||||
|
/// Collision intensity with other cars.
|
||||||
|
float collision_car;
|
||||||
|
/// Percentage of the car invading other lanes.
|
||||||
|
float intersect_other_lane;
|
||||||
|
/// Percentage of the car off-road.
|
||||||
|
float intersect_offroad;
|
||||||
|
/// Width and height of the images.
|
||||||
|
int32 image_width, image_height;
|
||||||
|
/// RGB images.
|
||||||
|
std::vector<Color> image_rgb_0;
|
||||||
|
std::vector<Color> image_rgb_1;
|
||||||
|
/// Depth images.
|
||||||
|
std::vector<Color> image_depth_1;
|
||||||
|
std::vector<Color> image_depth_2;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Scene_Values {
|
||||||
|
/// Possible world positions to spawn the player.
|
||||||
|
std::vector<Vector2D> possible_Positions;
|
||||||
|
/// Projection matrices of the cameras (1 in mode mono, 2 in stereo).
|
||||||
|
std::vector<std::array<float, 16u>> projection_Matrices;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class Mode : int8 {
|
||||||
|
MONO = 0,
|
||||||
|
STEREO = 1,
|
||||||
|
|
||||||
|
NUMBER_OF_MODES
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Asynchronous TCP server. Uses three ports, one for sending messages
|
||||||
|
/// (write), one for receiving messages (read), and one for world level
|
||||||
|
/// commands (world).
|
||||||
|
///
|
||||||
|
/// Writing and reading are executed in different threads. Each thread has its
|
||||||
|
/// own queue of messages.
|
||||||
|
class CarlaServer {
|
||||||
|
public:
|
||||||
|
|
||||||
|
explicit CarlaServer(uint32 writePort, uint32 readPort, uint32 worldPort);
|
||||||
|
|
||||||
|
~CarlaServer();
|
||||||
|
|
||||||
|
CarlaServer(const CarlaServer &) = delete;
|
||||||
|
CarlaServer &operator=(const CarlaServer &x) = delete;
|
||||||
|
|
||||||
|
/// Initialize the server.
|
||||||
|
///
|
||||||
|
/// @param LevelCount Number of levels available.
|
||||||
|
void init(uint32 LevelCount);
|
||||||
|
|
||||||
|
/// Try to read if the client has selected an scene and mode. Return false
|
||||||
|
/// if the queue is empty.
|
||||||
|
bool tryReadSceneInit(Mode &mode, int &scene);
|
||||||
|
|
||||||
|
/// Try to read if the client has selected an end & start point. Return
|
||||||
|
/// false if the queue is empty.
|
||||||
|
bool tryReadEpisodeStart(uint32 &startIndex, uint32 &endIndex);
|
||||||
|
|
||||||
|
/// Try to read the response of the client. Return false if the queue
|
||||||
|
/// is empty.
|
||||||
|
bool tryReadControl(float &steer, float &throttle);
|
||||||
|
|
||||||
|
/// Send values of the current player status.
|
||||||
|
void sendReward(const Reward_Values &values);
|
||||||
|
|
||||||
|
/// Send the values of the generated scene.
|
||||||
|
void sendSceneValues(const Scene_Values &values);
|
||||||
|
|
||||||
|
/// Send a signal to the client to notify that the car is ready.
|
||||||
|
void sendEndReset();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
class Pimpl;
|
||||||
|
std::unique_ptr<Pimpl> _pimpl;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace carla
|
|
@ -1,10 +0,0 @@
|
||||||
# add_library(carla_server
|
|
||||||
# carla_protocol.pb.h
|
|
||||||
# carla_protocol.pb.cc
|
|
||||||
# )
|
|
||||||
file(GLOB carla_server_SRC
|
|
||||||
"*.h"
|
|
||||||
"*.cpp"
|
|
||||||
)
|
|
||||||
|
|
||||||
add_library(carla_server ${carla_server_SRC})
|
|
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
|
@ -1,145 +0,0 @@
|
||||||
// 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.
|
|
||||||
|
|
||||||
// Author: kenton@google.com (Kenton Varda)
|
|
||||||
// Based on original Protocol Buffers design by
|
|
||||||
// Sanjay Ghemawat, Jeff Dean, and others.
|
|
||||||
//
|
|
||||||
// Defines the abstract interface implemented by each of the language-specific
|
|
||||||
// code generators.
|
|
||||||
|
|
||||||
#ifndef GOOGLE_PROTOBUF_COMPILER_CODE_GENERATOR_H__
|
|
||||||
#define GOOGLE_PROTOBUF_COMPILER_CODE_GENERATOR_H__
|
|
||||||
|
|
||||||
#include <google/protobuf/stubs/common.h>
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
namespace google {
|
|
||||||
namespace protobuf {
|
|
||||||
|
|
||||||
namespace io { class ZeroCopyOutputStream; }
|
|
||||||
class FileDescriptor;
|
|
||||||
|
|
||||||
namespace compiler {
|
|
||||||
|
|
||||||
// Defined in this file.
|
|
||||||
class CodeGenerator;
|
|
||||||
class GeneratorContext;
|
|
||||||
|
|
||||||
// The abstract interface to a class which generates code implementing a
|
|
||||||
// particular proto file in a particular language. A number of these may
|
|
||||||
// be registered with CommandLineInterface to support various languages.
|
|
||||||
class LIBPROTOC_EXPORT CodeGenerator {
|
|
||||||
public:
|
|
||||||
inline CodeGenerator() {}
|
|
||||||
virtual ~CodeGenerator();
|
|
||||||
|
|
||||||
// Generates code for the given proto file, generating one or more files in
|
|
||||||
// the given output directory.
|
|
||||||
//
|
|
||||||
// A parameter to be passed to the generator can be specified on the
|
|
||||||
// command line. This is intended to be used by Java and similar languages
|
|
||||||
// to specify which specific class from the proto file is to be generated,
|
|
||||||
// though it could have other uses as well. It is empty if no parameter was
|
|
||||||
// given.
|
|
||||||
//
|
|
||||||
// Returns true if successful. Otherwise, sets *error to a description of
|
|
||||||
// the problem (e.g. "invalid parameter") and returns false.
|
|
||||||
virtual bool Generate(const FileDescriptor* file,
|
|
||||||
const string& parameter,
|
|
||||||
GeneratorContext* generator_context,
|
|
||||||
string* error) const = 0;
|
|
||||||
|
|
||||||
private:
|
|
||||||
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CodeGenerator);
|
|
||||||
};
|
|
||||||
|
|
||||||
// CodeGenerators generate one or more files in a given directory. This
|
|
||||||
// abstract interface represents the directory to which the CodeGenerator is
|
|
||||||
// to write and other information about the context in which the Generator
|
|
||||||
// runs.
|
|
||||||
class LIBPROTOC_EXPORT GeneratorContext {
|
|
||||||
public:
|
|
||||||
inline GeneratorContext() {}
|
|
||||||
virtual ~GeneratorContext();
|
|
||||||
|
|
||||||
// Opens the given file, truncating it if it exists, and returns a
|
|
||||||
// ZeroCopyOutputStream that writes to the file. The caller takes ownership
|
|
||||||
// of the returned object. This method never fails (a dummy stream will be
|
|
||||||
// returned instead).
|
|
||||||
//
|
|
||||||
// The filename given should be relative to the root of the source tree.
|
|
||||||
// E.g. the C++ generator, when generating code for "foo/bar.proto", will
|
|
||||||
// generate the files "foo/bar.pb.h" and "foo/bar.pb.cc"; note that
|
|
||||||
// "foo/" is included in these filenames. The filename is not allowed to
|
|
||||||
// contain "." or ".." components.
|
|
||||||
virtual io::ZeroCopyOutputStream* Open(const string& filename) = 0;
|
|
||||||
|
|
||||||
// Similar to Open() but the output will be appended to the file if exists
|
|
||||||
virtual io::ZeroCopyOutputStream* OpenForAppend(const string& filename);
|
|
||||||
|
|
||||||
// Creates a ZeroCopyOutputStream which will insert code into the given file
|
|
||||||
// at the given insertion point. See plugin.proto (plugin.pb.h) for more
|
|
||||||
// information on insertion points. The default implementation
|
|
||||||
// assert-fails -- it exists only for backwards-compatibility.
|
|
||||||
//
|
|
||||||
// WARNING: This feature is currently EXPERIMENTAL and is subject to change.
|
|
||||||
virtual io::ZeroCopyOutputStream* OpenForInsert(
|
|
||||||
const string& filename, const string& insertion_point);
|
|
||||||
|
|
||||||
// Returns a vector of FileDescriptors for all the files being compiled
|
|
||||||
// in this run. Useful for languages, such as Go, that treat files
|
|
||||||
// differently when compiled as a set rather than individually.
|
|
||||||
virtual void ListParsedFiles(vector<const FileDescriptor*>* output);
|
|
||||||
|
|
||||||
private:
|
|
||||||
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(GeneratorContext);
|
|
||||||
};
|
|
||||||
|
|
||||||
// The type GeneratorContext was once called OutputDirectory. This typedef
|
|
||||||
// provides backward compatibility.
|
|
||||||
typedef GeneratorContext OutputDirectory;
|
|
||||||
|
|
||||||
// Several code generators treat the parameter argument as holding a
|
|
||||||
// list of options separated by commas. This helper function parses
|
|
||||||
// a set of comma-delimited name/value pairs: e.g.,
|
|
||||||
// "foo=bar,baz,qux=corge"
|
|
||||||
// parses to the pairs:
|
|
||||||
// ("foo", "bar"), ("baz", ""), ("qux", "corge")
|
|
||||||
extern void ParseGeneratorParameter(const string&,
|
|
||||||
vector<pair<string, string> >*);
|
|
||||||
|
|
||||||
} // namespace compiler
|
|
||||||
} // namespace protobuf
|
|
||||||
|
|
||||||
} // namespace google
|
|
||||||
#endif // GOOGLE_PROTOBUF_COMPILER_CODE_GENERATOR_H__
|
|
|
@ -1,378 +0,0 @@
|
||||||
// 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.
|
|
||||||
|
|
||||||
// Author: kenton@google.com (Kenton Varda)
|
|
||||||
// Based on original Protocol Buffers design by
|
|
||||||
// Sanjay Ghemawat, Jeff Dean, and others.
|
|
||||||
//
|
|
||||||
// Implements the Protocol Compiler front-end such that it may be reused by
|
|
||||||
// custom compilers written to support other languages.
|
|
||||||
|
|
||||||
#ifndef GOOGLE_PROTOBUF_COMPILER_COMMAND_LINE_INTERFACE_H__
|
|
||||||
#define GOOGLE_PROTOBUF_COMPILER_COMMAND_LINE_INTERFACE_H__
|
|
||||||
|
|
||||||
#include <google/protobuf/stubs/common.h>
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
#include <map>
|
|
||||||
#include <set>
|
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
namespace google {
|
|
||||||
namespace protobuf {
|
|
||||||
|
|
||||||
class Descriptor; // descriptor.h
|
|
||||||
class DescriptorPool; // descriptor.h
|
|
||||||
class FileDescriptor; // descriptor.h
|
|
||||||
class FileDescriptorProto; // descriptor.pb.h
|
|
||||||
template<typename T> class RepeatedPtrField; // repeated_field.h
|
|
||||||
|
|
||||||
namespace compiler {
|
|
||||||
|
|
||||||
class CodeGenerator; // code_generator.h
|
|
||||||
class GeneratorContext; // code_generator.h
|
|
||||||
class DiskSourceTree; // importer.h
|
|
||||||
|
|
||||||
// This class implements the command-line interface to the protocol compiler.
|
|
||||||
// It is designed to make it very easy to create a custom protocol compiler
|
|
||||||
// supporting the languages of your choice. For example, if you wanted to
|
|
||||||
// create a custom protocol compiler binary which includes both the regular
|
|
||||||
// C++ support plus support for your own custom output "Foo", you would
|
|
||||||
// write a class "FooGenerator" which implements the CodeGenerator interface,
|
|
||||||
// then write a main() procedure like this:
|
|
||||||
//
|
|
||||||
// int main(int argc, char* argv[]) {
|
|
||||||
// google::protobuf::compiler::CommandLineInterface cli;
|
|
||||||
//
|
|
||||||
// // Support generation of C++ source and headers.
|
|
||||||
// google::protobuf::compiler::cpp::CppGenerator cpp_generator;
|
|
||||||
// cli.RegisterGenerator("--cpp_out", &cpp_generator,
|
|
||||||
// "Generate C++ source and header.");
|
|
||||||
//
|
|
||||||
// // Support generation of Foo code.
|
|
||||||
// FooGenerator foo_generator;
|
|
||||||
// cli.RegisterGenerator("--foo_out", &foo_generator,
|
|
||||||
// "Generate Foo file.");
|
|
||||||
//
|
|
||||||
// return cli.Run(argc, argv);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// The compiler is invoked with syntax like:
|
|
||||||
// protoc --cpp_out=outdir --foo_out=outdir --proto_path=src src/foo.proto
|
|
||||||
//
|
|
||||||
// For a full description of the command-line syntax, invoke it with --help.
|
|
||||||
class LIBPROTOC_EXPORT CommandLineInterface {
|
|
||||||
public:
|
|
||||||
CommandLineInterface();
|
|
||||||
~CommandLineInterface();
|
|
||||||
|
|
||||||
// Register a code generator for a language.
|
|
||||||
//
|
|
||||||
// Parameters:
|
|
||||||
// * flag_name: The command-line flag used to specify an output file of
|
|
||||||
// this type. The name must start with a '-'. If the name is longer
|
|
||||||
// than one letter, it must start with two '-'s.
|
|
||||||
// * generator: The CodeGenerator which will be called to generate files
|
|
||||||
// of this type.
|
|
||||||
// * help_text: Text describing this flag in the --help output.
|
|
||||||
//
|
|
||||||
// Some generators accept extra parameters. You can specify this parameter
|
|
||||||
// on the command-line by placing it before the output directory, separated
|
|
||||||
// by a colon:
|
|
||||||
// protoc --foo_out=enable_bar:outdir
|
|
||||||
// The text before the colon is passed to CodeGenerator::Generate() as the
|
|
||||||
// "parameter".
|
|
||||||
void RegisterGenerator(const string& flag_name,
|
|
||||||
CodeGenerator* generator,
|
|
||||||
const string& help_text);
|
|
||||||
|
|
||||||
// Register a code generator for a language.
|
|
||||||
// Besides flag_name you can specify another option_flag_name that could be
|
|
||||||
// used to pass extra parameters to the registered code generator.
|
|
||||||
// Suppose you have registered a generator by calling:
|
|
||||||
// command_line_interface.RegisterGenerator("--foo_out", "--foo_opt", ...)
|
|
||||||
// Then you could invoke the compiler with a command like:
|
|
||||||
// protoc --foo_out=enable_bar:outdir --foo_opt=enable_baz
|
|
||||||
// This will pass "enable_bar,enable_baz" as the parameter to the generator.
|
|
||||||
void RegisterGenerator(const string& flag_name,
|
|
||||||
const string& option_flag_name,
|
|
||||||
CodeGenerator* generator,
|
|
||||||
const string& help_text);
|
|
||||||
|
|
||||||
// Enables "plugins". In this mode, if a command-line flag ends with "_out"
|
|
||||||
// but does not match any registered generator, the compiler will attempt to
|
|
||||||
// find a "plugin" to implement the generator. Plugins are just executables.
|
|
||||||
// They should live somewhere in the PATH.
|
|
||||||
//
|
|
||||||
// The compiler determines the executable name to search for by concatenating
|
|
||||||
// exe_name_prefix with the unrecognized flag name, removing "_out". So, for
|
|
||||||
// example, if exe_name_prefix is "protoc-" and you pass the flag --foo_out,
|
|
||||||
// the compiler will try to run the program "protoc-foo".
|
|
||||||
//
|
|
||||||
// The plugin program should implement the following usage:
|
|
||||||
// plugin [--out=OUTDIR] [--parameter=PARAMETER] PROTO_FILES < DESCRIPTORS
|
|
||||||
// --out indicates the output directory (as passed to the --foo_out
|
|
||||||
// parameter); if omitted, the current directory should be used. --parameter
|
|
||||||
// gives the generator parameter, if any was provided. The PROTO_FILES list
|
|
||||||
// the .proto files which were given on the compiler command-line; these are
|
|
||||||
// the files for which the plugin is expected to generate output code.
|
|
||||||
// Finally, DESCRIPTORS is an encoded FileDescriptorSet (as defined in
|
|
||||||
// descriptor.proto). This is piped to the plugin's stdin. The set will
|
|
||||||
// include descriptors for all the files listed in PROTO_FILES as well as
|
|
||||||
// all files that they import. The plugin MUST NOT attempt to read the
|
|
||||||
// PROTO_FILES directly -- it must use the FileDescriptorSet.
|
|
||||||
//
|
|
||||||
// The plugin should generate whatever files are necessary, as code generators
|
|
||||||
// normally do. It should write the names of all files it generates to
|
|
||||||
// stdout. The names should be relative to the output directory, NOT absolute
|
|
||||||
// names or relative to the current directory. If any errors occur, error
|
|
||||||
// messages should be written to stderr. If an error is fatal, the plugin
|
|
||||||
// should exit with a non-zero exit code.
|
|
||||||
void AllowPlugins(const string& exe_name_prefix);
|
|
||||||
|
|
||||||
// Run the Protocol Compiler with the given command-line parameters.
|
|
||||||
// Returns the error code which should be returned by main().
|
|
||||||
//
|
|
||||||
// It may not be safe to call Run() in a multi-threaded environment because
|
|
||||||
// it calls strerror(). I'm not sure why you'd want to do this anyway.
|
|
||||||
int Run(int argc, const char* const argv[]);
|
|
||||||
|
|
||||||
// Call SetInputsAreCwdRelative(true) if the input files given on the command
|
|
||||||
// line should be interpreted relative to the proto import path specified
|
|
||||||
// using --proto_path or -I flags. Otherwise, input file names will be
|
|
||||||
// interpreted relative to the current working directory (or as absolute
|
|
||||||
// paths if they start with '/'), though they must still reside inside
|
|
||||||
// a directory given by --proto_path or the compiler will fail. The latter
|
|
||||||
// mode is generally more intuitive and easier to use, especially e.g. when
|
|
||||||
// defining implicit rules in Makefiles.
|
|
||||||
void SetInputsAreProtoPathRelative(bool enable) {
|
|
||||||
inputs_are_proto_path_relative_ = enable;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Provides some text which will be printed when the --version flag is
|
|
||||||
// used. The version of libprotoc will also be printed on the next line
|
|
||||||
// after this text.
|
|
||||||
void SetVersionInfo(const string& text) {
|
|
||||||
version_info_ = text;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
|
||||||
// -----------------------------------------------------------------
|
|
||||||
|
|
||||||
class ErrorPrinter;
|
|
||||||
class GeneratorContextImpl;
|
|
||||||
class MemoryOutputStream;
|
|
||||||
|
|
||||||
// Clear state from previous Run().
|
|
||||||
void Clear();
|
|
||||||
|
|
||||||
// Remaps each file in input_files_ so that it is relative to one of the
|
|
||||||
// directories in proto_path_. Returns false if an error occurred. This
|
|
||||||
// is only used if inputs_are_proto_path_relative_ is false.
|
|
||||||
bool MakeInputsBeProtoPathRelative(
|
|
||||||
DiskSourceTree* source_tree);
|
|
||||||
|
|
||||||
// Return status for ParseArguments() and InterpretArgument().
|
|
||||||
enum ParseArgumentStatus {
|
|
||||||
PARSE_ARGUMENT_DONE_AND_CONTINUE,
|
|
||||||
PARSE_ARGUMENT_DONE_AND_EXIT,
|
|
||||||
PARSE_ARGUMENT_FAIL
|
|
||||||
};
|
|
||||||
|
|
||||||
// Parse all command-line arguments.
|
|
||||||
ParseArgumentStatus ParseArguments(int argc, const char* const argv[]);
|
|
||||||
|
|
||||||
// Parses a command-line argument into a name/value pair. Returns
|
|
||||||
// true if the next argument in the argv should be used as the value,
|
|
||||||
// false otherwise.
|
|
||||||
//
|
|
||||||
// Exmaples:
|
|
||||||
// "-Isrc/protos" ->
|
|
||||||
// name = "-I", value = "src/protos"
|
|
||||||
// "--cpp_out=src/foo.pb2.cc" ->
|
|
||||||
// name = "--cpp_out", value = "src/foo.pb2.cc"
|
|
||||||
// "foo.proto" ->
|
|
||||||
// name = "", value = "foo.proto"
|
|
||||||
bool ParseArgument(const char* arg, string* name, string* value);
|
|
||||||
|
|
||||||
// Interprets arguments parsed with ParseArgument.
|
|
||||||
ParseArgumentStatus InterpretArgument(const string& name,
|
|
||||||
const string& value);
|
|
||||||
|
|
||||||
// Print the --help text to stderr.
|
|
||||||
void PrintHelpText();
|
|
||||||
|
|
||||||
// Generate the given output file from the given input.
|
|
||||||
struct OutputDirective; // see below
|
|
||||||
bool GenerateOutput(const vector<const FileDescriptor*>& parsed_files,
|
|
||||||
const OutputDirective& output_directive,
|
|
||||||
GeneratorContext* generator_context);
|
|
||||||
bool GeneratePluginOutput(const vector<const FileDescriptor*>& parsed_files,
|
|
||||||
const string& plugin_name,
|
|
||||||
const string& parameter,
|
|
||||||
GeneratorContext* generator_context,
|
|
||||||
string* error);
|
|
||||||
|
|
||||||
// Implements --encode and --decode.
|
|
||||||
bool EncodeOrDecode(const DescriptorPool* pool);
|
|
||||||
|
|
||||||
// Implements the --descriptor_set_out option.
|
|
||||||
bool WriteDescriptorSet(const vector<const FileDescriptor*> parsed_files);
|
|
||||||
|
|
||||||
// Get all transitive dependencies of the given file (including the file
|
|
||||||
// itself), adding them to the given list of FileDescriptorProtos. The
|
|
||||||
// protos will be ordered such that every file is listed before any file that
|
|
||||||
// depends on it, so that you can call DescriptorPool::BuildFile() on them
|
|
||||||
// in order. Any files in *already_seen will not be added, and each file
|
|
||||||
// added will be inserted into *already_seen. If include_source_code_info is
|
|
||||||
// true then include the source code information in the FileDescriptorProtos.
|
|
||||||
static void GetTransitiveDependencies(
|
|
||||||
const FileDescriptor* file,
|
|
||||||
bool include_source_code_info,
|
|
||||||
set<const FileDescriptor*>* already_seen,
|
|
||||||
RepeatedPtrField<FileDescriptorProto>* output);
|
|
||||||
|
|
||||||
// Implements the --print_free_field_numbers. This function prints free field
|
|
||||||
// numbers into stdout for the message and it's nested message types in
|
|
||||||
// post-order, i.e. nested types first. Printed range are left-right
|
|
||||||
// inclusive, i.e. [a, b].
|
|
||||||
//
|
|
||||||
// Groups:
|
|
||||||
// For historical reasons, groups are considered to share the same
|
|
||||||
// field number space with the parent message, thus it will not print free
|
|
||||||
// field numbers for groups. The field numbers used in the groups are
|
|
||||||
// excluded in the free field numbers of the parent message.
|
|
||||||
//
|
|
||||||
// Extension Ranges:
|
|
||||||
// Extension ranges are considered ocuppied field numbers and they will not be
|
|
||||||
// listed as free numbers in the output.
|
|
||||||
void PrintFreeFieldNumbers(const Descriptor* descriptor);
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------
|
|
||||||
|
|
||||||
// The name of the executable as invoked (i.e. argv[0]).
|
|
||||||
string executable_name_;
|
|
||||||
|
|
||||||
// Version info set with SetVersionInfo().
|
|
||||||
string version_info_;
|
|
||||||
|
|
||||||
// Registered generators.
|
|
||||||
struct GeneratorInfo {
|
|
||||||
string flag_name;
|
|
||||||
string option_flag_name;
|
|
||||||
CodeGenerator* generator;
|
|
||||||
string help_text;
|
|
||||||
};
|
|
||||||
typedef map<string, GeneratorInfo> GeneratorMap;
|
|
||||||
GeneratorMap generators_by_flag_name_;
|
|
||||||
GeneratorMap generators_by_option_name_;
|
|
||||||
// A map from generator names to the parameters specified using the option
|
|
||||||
// flag. For example, if the user invokes the compiler with:
|
|
||||||
// protoc --foo_out=outputdir --foo_opt=enable_bar ...
|
|
||||||
// Then there will be an entry ("--foo_out", "enable_bar") in this map.
|
|
||||||
map<string, string> generator_parameters_;
|
|
||||||
|
|
||||||
// See AllowPlugins(). If this is empty, plugins aren't allowed.
|
|
||||||
string plugin_prefix_;
|
|
||||||
|
|
||||||
// Maps specific plugin names to files. When executing a plugin, this map
|
|
||||||
// is searched first to find the plugin executable. If not found here, the
|
|
||||||
// PATH (or other OS-specific search strategy) is searched.
|
|
||||||
map<string, string> plugins_;
|
|
||||||
|
|
||||||
// Stuff parsed from command line.
|
|
||||||
enum Mode {
|
|
||||||
MODE_COMPILE, // Normal mode: parse .proto files and compile them.
|
|
||||||
MODE_ENCODE, // --encode: read text from stdin, write binary to stdout.
|
|
||||||
MODE_DECODE, // --decode: read binary from stdin, write text to stdout.
|
|
||||||
MODE_PRINT, // Print mode: print info of the given .proto files and exit.
|
|
||||||
};
|
|
||||||
|
|
||||||
Mode mode_;
|
|
||||||
|
|
||||||
enum PrintMode {
|
|
||||||
PRINT_NONE, // Not in MODE_PRINT
|
|
||||||
PRINT_FREE_FIELDS, // --print_free_fields
|
|
||||||
};
|
|
||||||
|
|
||||||
PrintMode print_mode_;
|
|
||||||
|
|
||||||
enum ErrorFormat {
|
|
||||||
ERROR_FORMAT_GCC, // GCC error output format (default).
|
|
||||||
ERROR_FORMAT_MSVS // Visual Studio output (--error_format=msvs).
|
|
||||||
};
|
|
||||||
|
|
||||||
ErrorFormat error_format_;
|
|
||||||
|
|
||||||
vector<pair<string, string> > proto_path_; // Search path for proto files.
|
|
||||||
vector<string> input_files_; // Names of the input proto files.
|
|
||||||
|
|
||||||
// output_directives_ lists all the files we are supposed to output and what
|
|
||||||
// generator to use for each.
|
|
||||||
struct OutputDirective {
|
|
||||||
string name; // E.g. "--foo_out"
|
|
||||||
CodeGenerator* generator; // NULL for plugins
|
|
||||||
string parameter;
|
|
||||||
string output_location;
|
|
||||||
};
|
|
||||||
vector<OutputDirective> output_directives_;
|
|
||||||
|
|
||||||
// When using --encode or --decode, this names the type we are encoding or
|
|
||||||
// decoding. (Empty string indicates --decode_raw.)
|
|
||||||
string codec_type_;
|
|
||||||
|
|
||||||
// If --descriptor_set_out was given, this is the filename to which the
|
|
||||||
// FileDescriptorSet should be written. Otherwise, empty.
|
|
||||||
string descriptor_set_name_;
|
|
||||||
|
|
||||||
// True if --include_imports was given, meaning that we should
|
|
||||||
// write all transitive dependencies to the DescriptorSet. Otherwise, only
|
|
||||||
// the .proto files listed on the command-line are added.
|
|
||||||
bool imports_in_descriptor_set_;
|
|
||||||
|
|
||||||
// True if --include_source_info was given, meaning that we should not strip
|
|
||||||
// SourceCodeInfo from the DescriptorSet.
|
|
||||||
bool source_info_in_descriptor_set_;
|
|
||||||
|
|
||||||
// Was the --disallow_services flag used?
|
|
||||||
bool disallow_services_;
|
|
||||||
|
|
||||||
// See SetInputsAreProtoPathRelative().
|
|
||||||
bool inputs_are_proto_path_relative_;
|
|
||||||
|
|
||||||
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CommandLineInterface);
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace compiler
|
|
||||||
} // namespace protobuf
|
|
||||||
|
|
||||||
} // namespace google
|
|
||||||
#endif // GOOGLE_PROTOBUF_COMPILER_COMMAND_LINE_INTERFACE_H__
|
|
|
@ -1,72 +0,0 @@
|
||||||
// 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.
|
|
||||||
|
|
||||||
// Author: kenton@google.com (Kenton Varda)
|
|
||||||
// Based on original Protocol Buffers design by
|
|
||||||
// Sanjay Ghemawat, Jeff Dean, and others.
|
|
||||||
//
|
|
||||||
// Generates C++ code for a given .proto file.
|
|
||||||
|
|
||||||
#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_GENERATOR_H__
|
|
||||||
#define GOOGLE_PROTOBUF_COMPILER_CPP_GENERATOR_H__
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <google/protobuf/compiler/code_generator.h>
|
|
||||||
|
|
||||||
namespace google {
|
|
||||||
namespace protobuf {
|
|
||||||
namespace compiler {
|
|
||||||
namespace cpp {
|
|
||||||
|
|
||||||
// CodeGenerator implementation which generates a C++ source file and
|
|
||||||
// header. If you create your own protocol compiler binary and you want
|
|
||||||
// it to support C++ output, you can do so by registering an instance of this
|
|
||||||
// CodeGenerator with the CommandLineInterface in your main() function.
|
|
||||||
class LIBPROTOC_EXPORT CppGenerator : public CodeGenerator {
|
|
||||||
public:
|
|
||||||
CppGenerator();
|
|
||||||
~CppGenerator();
|
|
||||||
|
|
||||||
// implements CodeGenerator ----------------------------------------
|
|
||||||
bool Generate(const FileDescriptor* file,
|
|
||||||
const string& parameter,
|
|
||||||
GeneratorContext* generator_context,
|
|
||||||
string* error) const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CppGenerator);
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace cpp
|
|
||||||
} // namespace compiler
|
|
||||||
} // namespace protobuf
|
|
||||||
|
|
||||||
} // namespace google
|
|
||||||
#endif // GOOGLE_PROTOBUF_COMPILER_CPP_GENERATOR_H__
|
|
|
@ -1,317 +0,0 @@
|
||||||
// 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.
|
|
||||||
|
|
||||||
// Author: kenton@google.com (Kenton Varda)
|
|
||||||
// Based on original Protocol Buffers design by
|
|
||||||
// Sanjay Ghemawat, Jeff Dean, and others.
|
|
||||||
//
|
|
||||||
// This file is the public interface to the .proto file parser.
|
|
||||||
|
|
||||||
#ifndef GOOGLE_PROTOBUF_COMPILER_IMPORTER_H__
|
|
||||||
#define GOOGLE_PROTOBUF_COMPILER_IMPORTER_H__
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
#include <set>
|
|
||||||
#include <utility>
|
|
||||||
#include <google/protobuf/descriptor.h>
|
|
||||||
#include <google/protobuf/descriptor_database.h>
|
|
||||||
#include <google/protobuf/compiler/parser.h>
|
|
||||||
|
|
||||||
namespace google {
|
|
||||||
namespace protobuf {
|
|
||||||
|
|
||||||
namespace io { class ZeroCopyInputStream; }
|
|
||||||
|
|
||||||
namespace compiler {
|
|
||||||
|
|
||||||
// Defined in this file.
|
|
||||||
class Importer;
|
|
||||||
class MultiFileErrorCollector;
|
|
||||||
class SourceTree;
|
|
||||||
class DiskSourceTree;
|
|
||||||
|
|
||||||
// TODO(kenton): Move all SourceTree stuff to a separate file?
|
|
||||||
|
|
||||||
// An implementation of DescriptorDatabase which loads files from a SourceTree
|
|
||||||
// and parses them.
|
|
||||||
//
|
|
||||||
// Note: This class is not thread-safe since it maintains a table of source
|
|
||||||
// code locations for error reporting. However, when a DescriptorPool wraps
|
|
||||||
// a DescriptorDatabase, it uses mutex locking to make sure only one method
|
|
||||||
// of the database is called at a time, even if the DescriptorPool is used
|
|
||||||
// from multiple threads. Therefore, there is only a problem if you create
|
|
||||||
// multiple DescriptorPools wrapping the same SourceTreeDescriptorDatabase
|
|
||||||
// and use them from multiple threads.
|
|
||||||
//
|
|
||||||
// Note: This class does not implement FindFileContainingSymbol() or
|
|
||||||
// FindFileContainingExtension(); these will always return false.
|
|
||||||
class LIBPROTOBUF_EXPORT SourceTreeDescriptorDatabase : public DescriptorDatabase {
|
|
||||||
public:
|
|
||||||
SourceTreeDescriptorDatabase(SourceTree* source_tree);
|
|
||||||
~SourceTreeDescriptorDatabase();
|
|
||||||
|
|
||||||
// Instructs the SourceTreeDescriptorDatabase to report any parse errors
|
|
||||||
// to the given MultiFileErrorCollector. This should be called before
|
|
||||||
// parsing. error_collector must remain valid until either this method
|
|
||||||
// is called again or the SourceTreeDescriptorDatabase is destroyed.
|
|
||||||
void RecordErrorsTo(MultiFileErrorCollector* error_collector) {
|
|
||||||
error_collector_ = error_collector;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Gets a DescriptorPool::ErrorCollector which records errors to the
|
|
||||||
// MultiFileErrorCollector specified with RecordErrorsTo(). This collector
|
|
||||||
// has the ability to determine exact line and column numbers of errors
|
|
||||||
// from the information given to it by the DescriptorPool.
|
|
||||||
DescriptorPool::ErrorCollector* GetValidationErrorCollector() {
|
|
||||||
using_validation_error_collector_ = true;
|
|
||||||
return &validation_error_collector_;
|
|
||||||
}
|
|
||||||
|
|
||||||
// implements DescriptorDatabase -----------------------------------
|
|
||||||
bool FindFileByName(const string& filename, FileDescriptorProto* output);
|
|
||||||
bool FindFileContainingSymbol(const string& symbol_name,
|
|
||||||
FileDescriptorProto* output);
|
|
||||||
bool FindFileContainingExtension(const string& containing_type,
|
|
||||||
int field_number,
|
|
||||||
FileDescriptorProto* output);
|
|
||||||
|
|
||||||
private:
|
|
||||||
class SingleFileErrorCollector;
|
|
||||||
|
|
||||||
SourceTree* source_tree_;
|
|
||||||
MultiFileErrorCollector* error_collector_;
|
|
||||||
|
|
||||||
class LIBPROTOBUF_EXPORT ValidationErrorCollector : public DescriptorPool::ErrorCollector {
|
|
||||||
public:
|
|
||||||
ValidationErrorCollector(SourceTreeDescriptorDatabase* owner);
|
|
||||||
~ValidationErrorCollector();
|
|
||||||
|
|
||||||
// implements ErrorCollector ---------------------------------------
|
|
||||||
void AddError(const string& filename,
|
|
||||||
const string& element_name,
|
|
||||||
const Message* descriptor,
|
|
||||||
ErrorLocation location,
|
|
||||||
const string& message);
|
|
||||||
|
|
||||||
private:
|
|
||||||
SourceTreeDescriptorDatabase* owner_;
|
|
||||||
};
|
|
||||||
friend class ValidationErrorCollector;
|
|
||||||
|
|
||||||
bool using_validation_error_collector_;
|
|
||||||
SourceLocationTable source_locations_;
|
|
||||||
ValidationErrorCollector validation_error_collector_;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Simple interface for parsing .proto files. This wraps the process
|
|
||||||
// of opening the file, parsing it with a Parser, recursively parsing all its
|
|
||||||
// imports, and then cross-linking the results to produce a FileDescriptor.
|
|
||||||
//
|
|
||||||
// This is really just a thin wrapper around SourceTreeDescriptorDatabase.
|
|
||||||
// You may find that SourceTreeDescriptorDatabase is more flexible.
|
|
||||||
//
|
|
||||||
// TODO(kenton): I feel like this class is not well-named.
|
|
||||||
class LIBPROTOBUF_EXPORT Importer {
|
|
||||||
public:
|
|
||||||
Importer(SourceTree* source_tree,
|
|
||||||
MultiFileErrorCollector* error_collector);
|
|
||||||
~Importer();
|
|
||||||
|
|
||||||
// Import the given file and build a FileDescriptor representing it. If
|
|
||||||
// the file is already in the DescriptorPool, the existing FileDescriptor
|
|
||||||
// will be returned. The FileDescriptor is property of the DescriptorPool,
|
|
||||||
// and will remain valid until it is destroyed. If any errors occur, they
|
|
||||||
// will be reported using the error collector and Import() will return NULL.
|
|
||||||
//
|
|
||||||
// A particular Importer object will only report errors for a particular
|
|
||||||
// file once. All future attempts to import the same file will return NULL
|
|
||||||
// without reporting any errors. The idea is that you might want to import
|
|
||||||
// a lot of files without seeing the same errors over and over again. If
|
|
||||||
// you want to see errors for the same files repeatedly, you can use a
|
|
||||||
// separate Importer object to import each one (but use the same
|
|
||||||
// DescriptorPool so that they can be cross-linked).
|
|
||||||
const FileDescriptor* Import(const string& filename);
|
|
||||||
|
|
||||||
// The DescriptorPool in which all imported FileDescriptors and their
|
|
||||||
// contents are stored.
|
|
||||||
inline const DescriptorPool* pool() const {
|
|
||||||
return &pool_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AddUnusedImportTrackFile(const string& file_name);
|
|
||||||
void ClearUnusedImportTrackFiles();
|
|
||||||
|
|
||||||
private:
|
|
||||||
SourceTreeDescriptorDatabase database_;
|
|
||||||
DescriptorPool pool_;
|
|
||||||
|
|
||||||
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Importer);
|
|
||||||
};
|
|
||||||
|
|
||||||
// If the importer encounters problems while trying to import the proto files,
|
|
||||||
// it reports them to a MultiFileErrorCollector.
|
|
||||||
class LIBPROTOBUF_EXPORT MultiFileErrorCollector {
|
|
||||||
public:
|
|
||||||
inline MultiFileErrorCollector() {}
|
|
||||||
virtual ~MultiFileErrorCollector();
|
|
||||||
|
|
||||||
// Line and column numbers are zero-based. A line number of -1 indicates
|
|
||||||
// an error with the entire file (e.g. "not found").
|
|
||||||
virtual void AddError(const string& filename, int line, int column,
|
|
||||||
const string& message) = 0;
|
|
||||||
|
|
||||||
private:
|
|
||||||
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MultiFileErrorCollector);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Abstract interface which represents a directory tree containing proto files.
|
|
||||||
// Used by the default implementation of Importer to resolve import statements
|
|
||||||
// Most users will probably want to use the DiskSourceTree implementation,
|
|
||||||
// below.
|
|
||||||
class LIBPROTOBUF_EXPORT SourceTree {
|
|
||||||
public:
|
|
||||||
inline SourceTree() {}
|
|
||||||
virtual ~SourceTree();
|
|
||||||
|
|
||||||
// Open the given file and return a stream that reads it, or NULL if not
|
|
||||||
// found. The caller takes ownership of the returned object. The filename
|
|
||||||
// must be a path relative to the root of the source tree and must not
|
|
||||||
// contain "." or ".." components.
|
|
||||||
virtual io::ZeroCopyInputStream* Open(const string& filename) = 0;
|
|
||||||
|
|
||||||
// If Open() returns NULL, calling this method immediately will return an
|
|
||||||
// description of the error.
|
|
||||||
// Subclasses should implement this method and return a meaningful value for
|
|
||||||
// better error reporting.
|
|
||||||
// TODO(xiaofeng): change this to a pure virtual function.
|
|
||||||
virtual string GetLastErrorMessage();
|
|
||||||
|
|
||||||
private:
|
|
||||||
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(SourceTree);
|
|
||||||
};
|
|
||||||
|
|
||||||
// An implementation of SourceTree which loads files from locations on disk.
|
|
||||||
// Multiple mappings can be set up to map locations in the DiskSourceTree to
|
|
||||||
// locations in the physical filesystem.
|
|
||||||
class LIBPROTOBUF_EXPORT DiskSourceTree : public SourceTree {
|
|
||||||
public:
|
|
||||||
DiskSourceTree();
|
|
||||||
~DiskSourceTree();
|
|
||||||
|
|
||||||
// Map a path on disk to a location in the SourceTree. The path may be
|
|
||||||
// either a file or a directory. If it is a directory, the entire tree
|
|
||||||
// under it will be mapped to the given virtual location. To map a directory
|
|
||||||
// to the root of the source tree, pass an empty string for virtual_path.
|
|
||||||
//
|
|
||||||
// If multiple mapped paths apply when opening a file, they will be searched
|
|
||||||
// in order. For example, if you do:
|
|
||||||
// MapPath("bar", "foo/bar");
|
|
||||||
// MapPath("", "baz");
|
|
||||||
// and then you do:
|
|
||||||
// Open("bar/qux");
|
|
||||||
// the DiskSourceTree will first try to open foo/bar/qux, then baz/bar/qux,
|
|
||||||
// returning the first one that opens successfuly.
|
|
||||||
//
|
|
||||||
// disk_path may be an absolute path or relative to the current directory,
|
|
||||||
// just like a path you'd pass to open().
|
|
||||||
void MapPath(const string& virtual_path, const string& disk_path);
|
|
||||||
|
|
||||||
// Return type for DiskFileToVirtualFile().
|
|
||||||
enum DiskFileToVirtualFileResult {
|
|
||||||
SUCCESS,
|
|
||||||
SHADOWED,
|
|
||||||
CANNOT_OPEN,
|
|
||||||
NO_MAPPING
|
|
||||||
};
|
|
||||||
|
|
||||||
// Given a path to a file on disk, find a virtual path mapping to that
|
|
||||||
// file. The first mapping created with MapPath() whose disk_path contains
|
|
||||||
// the filename is used. However, that virtual path may not actually be
|
|
||||||
// usable to open the given file. Possible return values are:
|
|
||||||
// * SUCCESS: The mapping was found. *virtual_file is filled in so that
|
|
||||||
// calling Open(*virtual_file) will open the file named by disk_file.
|
|
||||||
// * SHADOWED: A mapping was found, but using Open() to open this virtual
|
|
||||||
// path will end up returning some different file. This is because some
|
|
||||||
// other mapping with a higher precedence also matches this virtual path
|
|
||||||
// and maps it to a different file that exists on disk. *virtual_file
|
|
||||||
// is filled in as it would be in the SUCCESS case. *shadowing_disk_file
|
|
||||||
// is filled in with the disk path of the file which would be opened if
|
|
||||||
// you were to call Open(*virtual_file).
|
|
||||||
// * CANNOT_OPEN: The mapping was found and was not shadowed, but the
|
|
||||||
// file specified cannot be opened. When this value is returned,
|
|
||||||
// errno will indicate the reason the file cannot be opened. *virtual_file
|
|
||||||
// will be set to the virtual path as in the SUCCESS case, even though
|
|
||||||
// it is not useful.
|
|
||||||
// * NO_MAPPING: Indicates that no mapping was found which contains this
|
|
||||||
// file.
|
|
||||||
DiskFileToVirtualFileResult
|
|
||||||
DiskFileToVirtualFile(const string& disk_file,
|
|
||||||
string* virtual_file,
|
|
||||||
string* shadowing_disk_file);
|
|
||||||
|
|
||||||
// Given a virtual path, find the path to the file on disk.
|
|
||||||
// Return true and update disk_file with the on-disk path if the file exists.
|
|
||||||
// Return false and leave disk_file untouched if the file doesn't exist.
|
|
||||||
bool VirtualFileToDiskFile(const string& virtual_file, string* disk_file);
|
|
||||||
|
|
||||||
// implements SourceTree -------------------------------------------
|
|
||||||
virtual io::ZeroCopyInputStream* Open(const string& filename);
|
|
||||||
|
|
||||||
virtual string GetLastErrorMessage();
|
|
||||||
|
|
||||||
private:
|
|
||||||
struct Mapping {
|
|
||||||
string virtual_path;
|
|
||||||
string disk_path;
|
|
||||||
|
|
||||||
inline Mapping(const string& virtual_path_param,
|
|
||||||
const string& disk_path_param)
|
|
||||||
: virtual_path(virtual_path_param), disk_path(disk_path_param) {}
|
|
||||||
};
|
|
||||||
vector<Mapping> mappings_;
|
|
||||||
string last_error_message_;
|
|
||||||
|
|
||||||
// Like Open(), but returns the on-disk path in disk_file if disk_file is
|
|
||||||
// non-NULL and the file could be successfully opened.
|
|
||||||
io::ZeroCopyInputStream* OpenVirtualFile(const string& virtual_file,
|
|
||||||
string* disk_file);
|
|
||||||
|
|
||||||
// Like Open() but given the actual on-disk path.
|
|
||||||
io::ZeroCopyInputStream* OpenDiskFile(const string& filename);
|
|
||||||
|
|
||||||
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DiskSourceTree);
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace compiler
|
|
||||||
} // namespace protobuf
|
|
||||||
|
|
||||||
} // namespace google
|
|
||||||
#endif // GOOGLE_PROTOBUF_COMPILER_IMPORTER_H__
|
|
|
@ -1,72 +0,0 @@
|
||||||
// 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.
|
|
||||||
|
|
||||||
// Author: kenton@google.com (Kenton Varda)
|
|
||||||
// Based on original Protocol Buffers design by
|
|
||||||
// Sanjay Ghemawat, Jeff Dean, and others.
|
|
||||||
//
|
|
||||||
// Generates Java code for a given .proto file.
|
|
||||||
|
|
||||||
#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_GENERATOR_H__
|
|
||||||
#define GOOGLE_PROTOBUF_COMPILER_JAVA_GENERATOR_H__
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <google/protobuf/compiler/code_generator.h>
|
|
||||||
|
|
||||||
namespace google {
|
|
||||||
namespace protobuf {
|
|
||||||
namespace compiler {
|
|
||||||
namespace java {
|
|
||||||
|
|
||||||
// CodeGenerator implementation which generates Java code. If you create your
|
|
||||||
// own protocol compiler binary and you want it to support Java output, you
|
|
||||||
// can do so by registering an instance of this CodeGenerator with the
|
|
||||||
// CommandLineInterface in your main() function.
|
|
||||||
class LIBPROTOC_EXPORT JavaGenerator : public CodeGenerator {
|
|
||||||
public:
|
|
||||||
JavaGenerator();
|
|
||||||
~JavaGenerator();
|
|
||||||
|
|
||||||
// implements CodeGenerator ----------------------------------------
|
|
||||||
bool Generate(const FileDescriptor* file,
|
|
||||||
const string& parameter,
|
|
||||||
GeneratorContext* context,
|
|
||||||
string* error) const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(JavaGenerator);
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace java
|
|
||||||
} // namespace compiler
|
|
||||||
} // namespace protobuf
|
|
||||||
|
|
||||||
} // namespace google
|
|
||||||
#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_GENERATOR_H__
|
|
|
@ -1,522 +0,0 @@
|
||||||
// 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.
|
|
||||||
|
|
||||||
// Author: kenton@google.com (Kenton Varda)
|
|
||||||
// Based on original Protocol Buffers design by
|
|
||||||
// Sanjay Ghemawat, Jeff Dean, and others.
|
|
||||||
//
|
|
||||||
// Implements parsing of .proto files to FileDescriptorProtos.
|
|
||||||
|
|
||||||
#ifndef GOOGLE_PROTOBUF_COMPILER_PARSER_H__
|
|
||||||
#define GOOGLE_PROTOBUF_COMPILER_PARSER_H__
|
|
||||||
|
|
||||||
#include <map>
|
|
||||||
#include <string>
|
|
||||||
#include <utility>
|
|
||||||
#include <google/protobuf/descriptor.h>
|
|
||||||
#include <google/protobuf/descriptor.pb.h>
|
|
||||||
#include <google/protobuf/repeated_field.h>
|
|
||||||
#include <google/protobuf/io/tokenizer.h>
|
|
||||||
|
|
||||||
namespace google {
|
|
||||||
namespace protobuf { class Message; }
|
|
||||||
|
|
||||||
namespace protobuf {
|
|
||||||
namespace compiler {
|
|
||||||
|
|
||||||
// Defined in this file.
|
|
||||||
class Parser;
|
|
||||||
class SourceLocationTable;
|
|
||||||
|
|
||||||
// Implements parsing of protocol definitions (such as .proto files).
|
|
||||||
//
|
|
||||||
// Note that most users will be more interested in the Importer class.
|
|
||||||
// Parser is a lower-level class which simply converts a single .proto file
|
|
||||||
// to a FileDescriptorProto. It does not resolve import directives or perform
|
|
||||||
// many other kinds of validation needed to construct a complete
|
|
||||||
// FileDescriptor.
|
|
||||||
class LIBPROTOBUF_EXPORT Parser {
|
|
||||||
public:
|
|
||||||
Parser();
|
|
||||||
~Parser();
|
|
||||||
|
|
||||||
// Parse the entire input and construct a FileDescriptorProto representing
|
|
||||||
// it. Returns true if no errors occurred, false otherwise.
|
|
||||||
bool Parse(io::Tokenizer* input, FileDescriptorProto* file);
|
|
||||||
|
|
||||||
// Optional fetaures:
|
|
||||||
|
|
||||||
// DEPRECATED: New code should use the SourceCodeInfo embedded in the
|
|
||||||
// FileDescriptorProto.
|
|
||||||
//
|
|
||||||
// Requests that locations of certain definitions be recorded to the given
|
|
||||||
// SourceLocationTable while parsing. This can be used to look up exact line
|
|
||||||
// and column numbers for errors reported by DescriptorPool during validation.
|
|
||||||
// Set to NULL (the default) to discard source location information.
|
|
||||||
void RecordSourceLocationsTo(SourceLocationTable* location_table) {
|
|
||||||
source_location_table_ = location_table;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Requests that errors be recorded to the given ErrorCollector while
|
|
||||||
// parsing. Set to NULL (the default) to discard error messages.
|
|
||||||
void RecordErrorsTo(io::ErrorCollector* error_collector) {
|
|
||||||
error_collector_ = error_collector;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns the identifier used in the "syntax = " declaration, if one was
|
|
||||||
// seen during the last call to Parse(), or the empty string otherwise.
|
|
||||||
const string& GetSyntaxIdentifier() { return syntax_identifier_; }
|
|
||||||
|
|
||||||
// If set true, input files will be required to begin with a syntax
|
|
||||||
// identifier. Otherwise, files may omit this. If a syntax identifier
|
|
||||||
// is provided, it must be 'syntax = "proto2";' and must appear at the
|
|
||||||
// top of this file regardless of whether or not it was required.
|
|
||||||
void SetRequireSyntaxIdentifier(bool value) {
|
|
||||||
require_syntax_identifier_ = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Call SetStopAfterSyntaxIdentifier(true) to tell the parser to stop
|
|
||||||
// parsing as soon as it has seen the syntax identifier, or lack thereof.
|
|
||||||
// This is useful for quickly identifying the syntax of the file without
|
|
||||||
// parsing the whole thing. If this is enabled, no error will be recorded
|
|
||||||
// if the syntax identifier is something other than "proto2" (since
|
|
||||||
// presumably the caller intends to deal with that), but other kinds of
|
|
||||||
// errors (e.g. parse errors) will still be reported. When this is enabled,
|
|
||||||
// you may pass a NULL FileDescriptorProto to Parse().
|
|
||||||
void SetStopAfterSyntaxIdentifier(bool value) {
|
|
||||||
stop_after_syntax_identifier_ = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
class LocationRecorder;
|
|
||||||
|
|
||||||
// =================================================================
|
|
||||||
// Error recovery helpers
|
|
||||||
|
|
||||||
// Consume the rest of the current statement. This consumes tokens
|
|
||||||
// until it sees one of:
|
|
||||||
// ';' Consumes the token and returns.
|
|
||||||
// '{' Consumes the brace then calls SkipRestOfBlock().
|
|
||||||
// '}' Returns without consuming.
|
|
||||||
// EOF Returns (can't consume).
|
|
||||||
// The Parser often calls SkipStatement() after encountering a syntax
|
|
||||||
// error. This allows it to go on parsing the following lines, allowing
|
|
||||||
// it to report more than just one error in the file.
|
|
||||||
void SkipStatement();
|
|
||||||
|
|
||||||
// Consume the rest of the current block, including nested blocks,
|
|
||||||
// ending after the closing '}' is encountered and consumed, or at EOF.
|
|
||||||
void SkipRestOfBlock();
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------
|
|
||||||
// Single-token consuming helpers
|
|
||||||
//
|
|
||||||
// These make parsing code more readable.
|
|
||||||
|
|
||||||
// True if the current token is TYPE_END.
|
|
||||||
inline bool AtEnd();
|
|
||||||
|
|
||||||
// True if the next token matches the given text.
|
|
||||||
inline bool LookingAt(const char* text);
|
|
||||||
// True if the next token is of the given type.
|
|
||||||
inline bool LookingAtType(io::Tokenizer::TokenType token_type);
|
|
||||||
|
|
||||||
// If the next token exactly matches the text given, consume it and return
|
|
||||||
// true. Otherwise, return false without logging an error.
|
|
||||||
bool TryConsume(const char* text);
|
|
||||||
|
|
||||||
// These attempt to read some kind of token from the input. If successful,
|
|
||||||
// they return true. Otherwise they return false and add the given error
|
|
||||||
// to the error list.
|
|
||||||
|
|
||||||
// Consume a token with the exact text given.
|
|
||||||
bool Consume(const char* text, const char* error);
|
|
||||||
// Same as above, but automatically generates the error "Expected \"text\".",
|
|
||||||
// where "text" is the expected token text.
|
|
||||||
bool Consume(const char* text);
|
|
||||||
// Consume a token of type IDENTIFIER and store its text in "output".
|
|
||||||
bool ConsumeIdentifier(string* output, const char* error);
|
|
||||||
// Consume an integer and store its value in "output".
|
|
||||||
bool ConsumeInteger(int* output, const char* error);
|
|
||||||
// Consume a signed integer and store its value in "output".
|
|
||||||
bool ConsumeSignedInteger(int* output, const char* error);
|
|
||||||
// Consume a 64-bit integer and store its value in "output". If the value
|
|
||||||
// is greater than max_value, an error will be reported.
|
|
||||||
bool ConsumeInteger64(uint64 max_value, uint64* output, const char* error);
|
|
||||||
// Consume a number and store its value in "output". This will accept
|
|
||||||
// tokens of either INTEGER or FLOAT type.
|
|
||||||
bool ConsumeNumber(double* output, const char* error);
|
|
||||||
// Consume a string literal and store its (unescaped) value in "output".
|
|
||||||
bool ConsumeString(string* output, const char* error);
|
|
||||||
|
|
||||||
// Consume a token representing the end of the statement. Comments between
|
|
||||||
// this token and the next will be harvested for documentation. The given
|
|
||||||
// LocationRecorder should refer to the declaration that was just parsed;
|
|
||||||
// it will be populated with these comments.
|
|
||||||
//
|
|
||||||
// TODO(kenton): The LocationRecorder is const because historically locations
|
|
||||||
// have been passed around by const reference, for no particularly good
|
|
||||||
// reason. We should probably go through and change them all to mutable
|
|
||||||
// pointer to make this more intuitive.
|
|
||||||
bool TryConsumeEndOfDeclaration(const char* text,
|
|
||||||
const LocationRecorder* location);
|
|
||||||
bool ConsumeEndOfDeclaration(const char* text,
|
|
||||||
const LocationRecorder* location);
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------
|
|
||||||
// Error logging helpers
|
|
||||||
|
|
||||||
// Invokes error_collector_->AddError(), if error_collector_ is not NULL.
|
|
||||||
void AddError(int line, int column, const string& error);
|
|
||||||
|
|
||||||
// Invokes error_collector_->AddError() with the line and column number
|
|
||||||
// of the current token.
|
|
||||||
void AddError(const string& error);
|
|
||||||
|
|
||||||
// Records a location in the SourceCodeInfo.location table (see
|
|
||||||
// descriptor.proto). We use RAII to ensure that the start and end locations
|
|
||||||
// are recorded -- the constructor records the start location and the
|
|
||||||
// destructor records the end location. Since the parser is
|
|
||||||
// recursive-descent, this works out beautifully.
|
|
||||||
class LIBPROTOBUF_EXPORT LocationRecorder {
|
|
||||||
public:
|
|
||||||
// Construct the file's "root" location.
|
|
||||||
LocationRecorder(Parser* parser);
|
|
||||||
|
|
||||||
// Construct a location that represents a declaration nested within the
|
|
||||||
// given parent. E.g. a field's location is nested within the location
|
|
||||||
// for a message type. The parent's path will be copied, so you should
|
|
||||||
// call AddPath() only to add the path components leading from the parent
|
|
||||||
// to the child (as opposed to leading from the root to the child).
|
|
||||||
LocationRecorder(const LocationRecorder& parent);
|
|
||||||
|
|
||||||
// Convenience constructors that call AddPath() one or two times.
|
|
||||||
LocationRecorder(const LocationRecorder& parent, int path1);
|
|
||||||
LocationRecorder(const LocationRecorder& parent, int path1, int path2);
|
|
||||||
|
|
||||||
~LocationRecorder();
|
|
||||||
|
|
||||||
// Add a path component. See SourceCodeInfo.Location.path in
|
|
||||||
// descriptor.proto.
|
|
||||||
void AddPath(int path_component);
|
|
||||||
|
|
||||||
// By default the location is considered to start at the current token at
|
|
||||||
// the time the LocationRecorder is created. StartAt() sets the start
|
|
||||||
// location to the given token instead.
|
|
||||||
void StartAt(const io::Tokenizer::Token& token);
|
|
||||||
|
|
||||||
// Start at the same location as some other LocationRecorder.
|
|
||||||
void StartAt(const LocationRecorder& other);
|
|
||||||
|
|
||||||
// By default the location is considered to end at the previous token at
|
|
||||||
// the time the LocationRecorder is destroyed. EndAt() sets the end
|
|
||||||
// location to the given token instead.
|
|
||||||
void EndAt(const io::Tokenizer::Token& token);
|
|
||||||
|
|
||||||
// Records the start point of this location to the SourceLocationTable that
|
|
||||||
// was passed to RecordSourceLocationsTo(), if any. SourceLocationTable
|
|
||||||
// is an older way of keeping track of source locations which is still
|
|
||||||
// used in some places.
|
|
||||||
void RecordLegacyLocation(const Message* descriptor,
|
|
||||||
DescriptorPool::ErrorCollector::ErrorLocation location);
|
|
||||||
|
|
||||||
// Attaches leading and trailing comments to the location. The two strings
|
|
||||||
// will be swapped into place, so after this is called *leading and
|
|
||||||
// *trailing will be empty.
|
|
||||||
//
|
|
||||||
// TODO(kenton): See comment on TryConsumeEndOfDeclaration(), above, for
|
|
||||||
// why this is const.
|
|
||||||
void AttachComments(string* leading, string* trailing) const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
Parser* parser_;
|
|
||||||
SourceCodeInfo::Location* location_;
|
|
||||||
|
|
||||||
void Init(const LocationRecorder& parent);
|
|
||||||
};
|
|
||||||
|
|
||||||
// =================================================================
|
|
||||||
// Parsers for various language constructs
|
|
||||||
|
|
||||||
// Parses the "syntax = \"proto2\";" line at the top of the file. Returns
|
|
||||||
// false if it failed to parse or if the syntax identifier was not
|
|
||||||
// recognized.
|
|
||||||
bool ParseSyntaxIdentifier();
|
|
||||||
|
|
||||||
// These methods parse various individual bits of code. They return
|
|
||||||
// false if they completely fail to parse the construct. In this case,
|
|
||||||
// it is probably necessary to skip the rest of the statement to recover.
|
|
||||||
// However, if these methods return true, it does NOT mean that there
|
|
||||||
// were no errors; only that there were no *syntax* errors. For instance,
|
|
||||||
// if a service method is defined using proper syntax but uses a primitive
|
|
||||||
// type as its input or output, ParseMethodField() still returns true
|
|
||||||
// and only reports the error by calling AddError(). In practice, this
|
|
||||||
// makes logic much simpler for the caller.
|
|
||||||
|
|
||||||
// Parse a top-level message, enum, service, etc.
|
|
||||||
bool ParseTopLevelStatement(FileDescriptorProto* file,
|
|
||||||
const LocationRecorder& root_location);
|
|
||||||
|
|
||||||
// Parse various language high-level language construrcts.
|
|
||||||
bool ParseMessageDefinition(DescriptorProto* message,
|
|
||||||
const LocationRecorder& message_location,
|
|
||||||
const FileDescriptorProto* containing_file);
|
|
||||||
bool ParseEnumDefinition(EnumDescriptorProto* enum_type,
|
|
||||||
const LocationRecorder& enum_location,
|
|
||||||
const FileDescriptorProto* containing_file);
|
|
||||||
bool ParseServiceDefinition(ServiceDescriptorProto* service,
|
|
||||||
const LocationRecorder& service_location,
|
|
||||||
const FileDescriptorProto* containing_file);
|
|
||||||
bool ParsePackage(FileDescriptorProto* file,
|
|
||||||
const LocationRecorder& root_location,
|
|
||||||
const FileDescriptorProto* containing_file);
|
|
||||||
bool ParseImport(RepeatedPtrField<string>* dependency,
|
|
||||||
RepeatedField<int32>* public_dependency,
|
|
||||||
RepeatedField<int32>* weak_dependency,
|
|
||||||
const LocationRecorder& root_location,
|
|
||||||
const FileDescriptorProto* containing_file);
|
|
||||||
bool ParseOption(Message* options,
|
|
||||||
const LocationRecorder& options_location,
|
|
||||||
const FileDescriptorProto* containing_file);
|
|
||||||
|
|
||||||
// These methods parse the contents of a message, enum, or service type and
|
|
||||||
// add them to the given object. They consume the entire block including
|
|
||||||
// the beginning and ending brace.
|
|
||||||
bool ParseMessageBlock(DescriptorProto* message,
|
|
||||||
const LocationRecorder& message_location,
|
|
||||||
const FileDescriptorProto* containing_file);
|
|
||||||
bool ParseEnumBlock(EnumDescriptorProto* enum_type,
|
|
||||||
const LocationRecorder& enum_location,
|
|
||||||
const FileDescriptorProto* containing_file);
|
|
||||||
bool ParseServiceBlock(ServiceDescriptorProto* service,
|
|
||||||
const LocationRecorder& service_location,
|
|
||||||
const FileDescriptorProto* containing_file);
|
|
||||||
|
|
||||||
// Parse one statement within a message, enum, or service block, inclunding
|
|
||||||
// final semicolon.
|
|
||||||
bool ParseMessageStatement(DescriptorProto* message,
|
|
||||||
const LocationRecorder& message_location,
|
|
||||||
const FileDescriptorProto* containing_file);
|
|
||||||
bool ParseEnumStatement(EnumDescriptorProto* message,
|
|
||||||
const LocationRecorder& enum_location,
|
|
||||||
const FileDescriptorProto* containing_file);
|
|
||||||
bool ParseServiceStatement(ServiceDescriptorProto* message,
|
|
||||||
const LocationRecorder& service_location,
|
|
||||||
const FileDescriptorProto* containing_file);
|
|
||||||
|
|
||||||
// Parse a field of a message. If the field is a group, its type will be
|
|
||||||
// added to "messages".
|
|
||||||
//
|
|
||||||
// parent_location and location_field_number_for_nested_type are needed when
|
|
||||||
// parsing groups -- we need to generate a nested message type within the
|
|
||||||
// parent and record its location accordingly. Since the parent could be
|
|
||||||
// either a FileDescriptorProto or a DescriptorProto, we must pass in the
|
|
||||||
// correct field number to use.
|
|
||||||
bool ParseMessageField(FieldDescriptorProto* field,
|
|
||||||
RepeatedPtrField<DescriptorProto>* messages,
|
|
||||||
const LocationRecorder& parent_location,
|
|
||||||
int location_field_number_for_nested_type,
|
|
||||||
const LocationRecorder& field_location,
|
|
||||||
const FileDescriptorProto* containing_file);
|
|
||||||
|
|
||||||
// Like ParseMessageField() but expects the label has already been filled in
|
|
||||||
// by the caller.
|
|
||||||
bool ParseMessageFieldNoLabel(FieldDescriptorProto* field,
|
|
||||||
RepeatedPtrField<DescriptorProto>* messages,
|
|
||||||
const LocationRecorder& parent_location,
|
|
||||||
int location_field_number_for_nested_type,
|
|
||||||
const LocationRecorder& field_location,
|
|
||||||
const FileDescriptorProto* containing_file);
|
|
||||||
|
|
||||||
// Parse an "extensions" declaration.
|
|
||||||
bool ParseExtensions(DescriptorProto* message,
|
|
||||||
const LocationRecorder& extensions_location,
|
|
||||||
const FileDescriptorProto* containing_file);
|
|
||||||
|
|
||||||
// Parse an "extend" declaration. (See also comments for
|
|
||||||
// ParseMessageField().)
|
|
||||||
bool ParseExtend(RepeatedPtrField<FieldDescriptorProto>* extensions,
|
|
||||||
RepeatedPtrField<DescriptorProto>* messages,
|
|
||||||
const LocationRecorder& parent_location,
|
|
||||||
int location_field_number_for_nested_type,
|
|
||||||
const LocationRecorder& extend_location,
|
|
||||||
const FileDescriptorProto* containing_file);
|
|
||||||
|
|
||||||
// Parse a "oneof" declaration. The caller is responsible for setting
|
|
||||||
// oneof_decl->label() since it will have had to parse the label before it
|
|
||||||
// knew it was parsing a oneof.
|
|
||||||
bool ParseOneof(OneofDescriptorProto* oneof_decl,
|
|
||||||
DescriptorProto* containing_type,
|
|
||||||
int oneof_index,
|
|
||||||
const LocationRecorder& oneof_location,
|
|
||||||
const LocationRecorder& containing_type_location,
|
|
||||||
const FileDescriptorProto* containing_file);
|
|
||||||
|
|
||||||
// Parse a single enum value within an enum block.
|
|
||||||
bool ParseEnumConstant(EnumValueDescriptorProto* enum_value,
|
|
||||||
const LocationRecorder& enum_value_location,
|
|
||||||
const FileDescriptorProto* containing_file);
|
|
||||||
|
|
||||||
// Parse enum constant options, i.e. the list in square brackets at the end
|
|
||||||
// of the enum constant value definition.
|
|
||||||
bool ParseEnumConstantOptions(EnumValueDescriptorProto* value,
|
|
||||||
const LocationRecorder& enum_value_location,
|
|
||||||
const FileDescriptorProto* containing_file);
|
|
||||||
|
|
||||||
// Parse a single method within a service definition.
|
|
||||||
bool ParseServiceMethod(MethodDescriptorProto* method,
|
|
||||||
const LocationRecorder& method_location,
|
|
||||||
const FileDescriptorProto* containing_file);
|
|
||||||
|
|
||||||
|
|
||||||
// Parse options of a single method or stream.
|
|
||||||
bool ParseOptions(const LocationRecorder& parent_location,
|
|
||||||
const FileDescriptorProto* containing_file,
|
|
||||||
const int optionsFieldNumber,
|
|
||||||
Message* mutable_options);
|
|
||||||
|
|
||||||
// Parse "required", "optional", or "repeated" and fill in "label"
|
|
||||||
// with the value.
|
|
||||||
bool ParseLabel(FieldDescriptorProto::Label* label,
|
|
||||||
const FileDescriptorProto* containing_file);
|
|
||||||
|
|
||||||
// Parse a type name and fill in "type" (if it is a primitive) or
|
|
||||||
// "type_name" (if it is not) with the type parsed.
|
|
||||||
bool ParseType(FieldDescriptorProto::Type* type,
|
|
||||||
string* type_name);
|
|
||||||
// Parse a user-defined type and fill in "type_name" with the name.
|
|
||||||
// If a primitive type is named, it is treated as an error.
|
|
||||||
bool ParseUserDefinedType(string* type_name);
|
|
||||||
|
|
||||||
// Parses field options, i.e. the stuff in square brackets at the end
|
|
||||||
// of a field definition. Also parses default value.
|
|
||||||
bool ParseFieldOptions(FieldDescriptorProto* field,
|
|
||||||
const LocationRecorder& field_location,
|
|
||||||
const FileDescriptorProto* containing_file);
|
|
||||||
|
|
||||||
// Parse the "default" option. This needs special handling because its
|
|
||||||
// type is the field's type.
|
|
||||||
bool ParseDefaultAssignment(FieldDescriptorProto* field,
|
|
||||||
const LocationRecorder& field_location,
|
|
||||||
const FileDescriptorProto* containing_file);
|
|
||||||
|
|
||||||
enum OptionStyle {
|
|
||||||
OPTION_ASSIGNMENT, // just "name = value"
|
|
||||||
OPTION_STATEMENT // "option name = value;"
|
|
||||||
};
|
|
||||||
|
|
||||||
// Parse a single option name/value pair, e.g. "ctype = CORD". The name
|
|
||||||
// identifies a field of the given Message, and the value of that field
|
|
||||||
// is set to the parsed value.
|
|
||||||
bool ParseOption(Message* options,
|
|
||||||
const LocationRecorder& options_location,
|
|
||||||
const FileDescriptorProto* containing_file,
|
|
||||||
OptionStyle style);
|
|
||||||
|
|
||||||
// Parses a single part of a multipart option name. A multipart name consists
|
|
||||||
// of names separated by dots. Each name is either an identifier or a series
|
|
||||||
// of identifiers separated by dots and enclosed in parentheses. E.g.,
|
|
||||||
// "foo.(bar.baz).qux".
|
|
||||||
bool ParseOptionNamePart(UninterpretedOption* uninterpreted_option,
|
|
||||||
const LocationRecorder& part_location,
|
|
||||||
const FileDescriptorProto* containing_file);
|
|
||||||
|
|
||||||
// Parses a string surrounded by balanced braces. Strips off the outer
|
|
||||||
// braces and stores the enclosed string in *value.
|
|
||||||
// E.g.,
|
|
||||||
// { foo } *value gets 'foo'
|
|
||||||
// { foo { bar: box } } *value gets 'foo { bar: box }'
|
|
||||||
// {} *value gets ''
|
|
||||||
//
|
|
||||||
// REQUIRES: LookingAt("{")
|
|
||||||
// When finished successfully, we are looking at the first token past
|
|
||||||
// the ending brace.
|
|
||||||
bool ParseUninterpretedBlock(string* value);
|
|
||||||
|
|
||||||
// =================================================================
|
|
||||||
|
|
||||||
io::Tokenizer* input_;
|
|
||||||
io::ErrorCollector* error_collector_;
|
|
||||||
SourceCodeInfo* source_code_info_;
|
|
||||||
SourceLocationTable* source_location_table_; // legacy
|
|
||||||
bool had_errors_;
|
|
||||||
bool require_syntax_identifier_;
|
|
||||||
bool stop_after_syntax_identifier_;
|
|
||||||
string syntax_identifier_;
|
|
||||||
|
|
||||||
// Leading doc comments for the next declaration. These are not complete
|
|
||||||
// yet; use ConsumeEndOfDeclaration() to get the complete comments.
|
|
||||||
string upcoming_doc_comments_;
|
|
||||||
|
|
||||||
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Parser);
|
|
||||||
};
|
|
||||||
|
|
||||||
// A table mapping (descriptor, ErrorLocation) pairs -- as reported by
|
|
||||||
// DescriptorPool when validating descriptors -- to line and column numbers
|
|
||||||
// within the original source code.
|
|
||||||
//
|
|
||||||
// This is semi-obsolete: FileDescriptorProto.source_code_info now contains
|
|
||||||
// far more complete information about source locations. However, as of this
|
|
||||||
// writing you still need to use SourceLocationTable when integrating with
|
|
||||||
// DescriptorPool.
|
|
||||||
class LIBPROTOBUF_EXPORT SourceLocationTable {
|
|
||||||
public:
|
|
||||||
SourceLocationTable();
|
|
||||||
~SourceLocationTable();
|
|
||||||
|
|
||||||
// Finds the precise location of the given error and fills in *line and
|
|
||||||
// *column with the line and column numbers. If not found, sets *line to
|
|
||||||
// -1 and *column to 0 (since line = -1 is used to mean "error has no exact
|
|
||||||
// location" in the ErrorCollector interface). Returns true if found, false
|
|
||||||
// otherwise.
|
|
||||||
bool Find(const Message* descriptor,
|
|
||||||
DescriptorPool::ErrorCollector::ErrorLocation location,
|
|
||||||
int* line, int* column) const;
|
|
||||||
|
|
||||||
// Adds a location to the table.
|
|
||||||
void Add(const Message* descriptor,
|
|
||||||
DescriptorPool::ErrorCollector::ErrorLocation location,
|
|
||||||
int line, int column);
|
|
||||||
|
|
||||||
// Clears the contents of the table.
|
|
||||||
void Clear();
|
|
||||||
|
|
||||||
private:
|
|
||||||
typedef map<
|
|
||||||
pair<const Message*, DescriptorPool::ErrorCollector::ErrorLocation>,
|
|
||||||
pair<int, int> > LocationMap;
|
|
||||||
LocationMap location_map_;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace compiler
|
|
||||||
} // namespace protobuf
|
|
||||||
|
|
||||||
} // namespace google
|
|
||||||
#endif // GOOGLE_PROTOBUF_COMPILER_PARSER_H__
|
|
|
@ -1,72 +0,0 @@
|
||||||
// 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.
|
|
||||||
|
|
||||||
// Author: kenton@google.com (Kenton Varda)
|
|
||||||
//
|
|
||||||
// Front-end for protoc code generator plugins written in C++.
|
|
||||||
//
|
|
||||||
// To implement a protoc plugin in C++, simply write an implementation of
|
|
||||||
// CodeGenerator, then create a main() function like:
|
|
||||||
// int main(int argc, char* argv[]) {
|
|
||||||
// MyCodeGenerator generator;
|
|
||||||
// return google::protobuf::compiler::PluginMain(argc, argv, &generator);
|
|
||||||
// }
|
|
||||||
// You must link your plugin against libprotobuf and libprotoc.
|
|
||||||
//
|
|
||||||
// To get protoc to use the plugin, do one of the following:
|
|
||||||
// * Place the plugin binary somewhere in the PATH and give it the name
|
|
||||||
// "protoc-gen-NAME" (replacing "NAME" with the name of your plugin). If you
|
|
||||||
// then invoke protoc with the parameter --NAME_out=OUT_DIR (again, replace
|
|
||||||
// "NAME" with your plugin's name), protoc will invoke your plugin to generate
|
|
||||||
// the output, which will be placed in OUT_DIR.
|
|
||||||
// * Place the plugin binary anywhere, with any name, and pass the --plugin
|
|
||||||
// parameter to protoc to direct it to your plugin like so:
|
|
||||||
// protoc --plugin=protoc-gen-NAME=path/to/mybinary --NAME_out=OUT_DIR
|
|
||||||
// On Windows, make sure to include the .exe suffix:
|
|
||||||
// protoc --plugin=protoc-gen-NAME=path/to/mybinary.exe --NAME_out=OUT_DIR
|
|
||||||
|
|
||||||
#ifndef GOOGLE_PROTOBUF_COMPILER_PLUGIN_H__
|
|
||||||
#define GOOGLE_PROTOBUF_COMPILER_PLUGIN_H__
|
|
||||||
|
|
||||||
#include <google/protobuf/stubs/common.h>
|
|
||||||
namespace google {
|
|
||||||
namespace protobuf {
|
|
||||||
namespace compiler {
|
|
||||||
|
|
||||||
class CodeGenerator; // code_generator.h
|
|
||||||
|
|
||||||
// Implements main() for a protoc plugin exposing the given code generator.
|
|
||||||
LIBPROTOC_EXPORT int PluginMain(int argc, char* argv[], const CodeGenerator* generator);
|
|
||||||
|
|
||||||
} // namespace compiler
|
|
||||||
} // namespace protobuf
|
|
||||||
|
|
||||||
} // namespace google
|
|
||||||
#endif // GOOGLE_PROTOBUF_COMPILER_PLUGIN_H__
|
|
|
@ -1,166 +0,0 @@
|
||||||
// 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.
|
|
||||||
|
|
||||||
// Author: robinson@google.com (Will Robinson)
|
|
||||||
//
|
|
||||||
// Generates Python code for a given .proto file.
|
|
||||||
|
|
||||||
#ifndef GOOGLE_PROTOBUF_COMPILER_PYTHON_GENERATOR_H__
|
|
||||||
#define GOOGLE_PROTOBUF_COMPILER_PYTHON_GENERATOR_H__
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include <google/protobuf/compiler/code_generator.h>
|
|
||||||
#include <google/protobuf/stubs/common.h>
|
|
||||||
|
|
||||||
namespace google {
|
|
||||||
namespace protobuf {
|
|
||||||
|
|
||||||
class Descriptor;
|
|
||||||
class EnumDescriptor;
|
|
||||||
class EnumValueDescriptor;
|
|
||||||
class FieldDescriptor;
|
|
||||||
class ServiceDescriptor;
|
|
||||||
|
|
||||||
namespace io { class Printer; }
|
|
||||||
|
|
||||||
namespace compiler {
|
|
||||||
namespace python {
|
|
||||||
|
|
||||||
// CodeGenerator implementation for generated Python protocol buffer classes.
|
|
||||||
// If you create your own protocol compiler binary and you want it to support
|
|
||||||
// Python output, you can do so by registering an instance of this
|
|
||||||
// CodeGenerator with the CommandLineInterface in your main() function.
|
|
||||||
class LIBPROTOC_EXPORT Generator : public CodeGenerator {
|
|
||||||
public:
|
|
||||||
Generator();
|
|
||||||
virtual ~Generator();
|
|
||||||
|
|
||||||
// CodeGenerator methods.
|
|
||||||
virtual bool Generate(const FileDescriptor* file,
|
|
||||||
const string& parameter,
|
|
||||||
GeneratorContext* generator_context,
|
|
||||||
string* error) const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
void PrintImports() const;
|
|
||||||
void PrintFileDescriptor() const;
|
|
||||||
void PrintTopLevelEnums() const;
|
|
||||||
void PrintAllNestedEnumsInFile() const;
|
|
||||||
void PrintNestedEnums(const Descriptor& descriptor) const;
|
|
||||||
void PrintEnum(const EnumDescriptor& enum_descriptor) const;
|
|
||||||
|
|
||||||
void PrintTopLevelExtensions() const;
|
|
||||||
|
|
||||||
void PrintFieldDescriptor(
|
|
||||||
const FieldDescriptor& field, bool is_extension) const;
|
|
||||||
void PrintFieldDescriptorsInDescriptor(
|
|
||||||
const Descriptor& message_descriptor,
|
|
||||||
bool is_extension,
|
|
||||||
const string& list_variable_name,
|
|
||||||
int (Descriptor::*CountFn)() const,
|
|
||||||
const FieldDescriptor* (Descriptor::*GetterFn)(int) const) const;
|
|
||||||
void PrintFieldsInDescriptor(const Descriptor& message_descriptor) const;
|
|
||||||
void PrintExtensionsInDescriptor(const Descriptor& message_descriptor) const;
|
|
||||||
void PrintMessageDescriptors() const;
|
|
||||||
void PrintDescriptor(const Descriptor& message_descriptor) const;
|
|
||||||
void PrintNestedDescriptors(const Descriptor& containing_descriptor) const;
|
|
||||||
|
|
||||||
void PrintMessages() const;
|
|
||||||
void PrintMessage(const Descriptor& message_descriptor, const string& prefix,
|
|
||||||
vector<string>* to_register) const;
|
|
||||||
void PrintNestedMessages(const Descriptor& containing_descriptor,
|
|
||||||
const string& prefix,
|
|
||||||
vector<string>* to_register) const;
|
|
||||||
|
|
||||||
void FixForeignFieldsInDescriptors() const;
|
|
||||||
void FixForeignFieldsInDescriptor(
|
|
||||||
const Descriptor& descriptor,
|
|
||||||
const Descriptor* containing_descriptor) const;
|
|
||||||
void FixForeignFieldsInField(const Descriptor* containing_type,
|
|
||||||
const FieldDescriptor& field,
|
|
||||||
const string& python_dict_name) const;
|
|
||||||
void AddMessageToFileDescriptor(const Descriptor& descriptor) const;
|
|
||||||
void AddEnumToFileDescriptor(const EnumDescriptor& descriptor) const;
|
|
||||||
void AddExtensionToFileDescriptor(const FieldDescriptor& descriptor) const;
|
|
||||||
string FieldReferencingExpression(const Descriptor* containing_type,
|
|
||||||
const FieldDescriptor& field,
|
|
||||||
const string& python_dict_name) const;
|
|
||||||
template <typename DescriptorT>
|
|
||||||
void FixContainingTypeInDescriptor(
|
|
||||||
const DescriptorT& descriptor,
|
|
||||||
const Descriptor* containing_descriptor) const;
|
|
||||||
|
|
||||||
void FixForeignFieldsInExtensions() const;
|
|
||||||
void FixForeignFieldsInExtension(
|
|
||||||
const FieldDescriptor& extension_field) const;
|
|
||||||
void FixForeignFieldsInNestedExtensions(const Descriptor& descriptor) const;
|
|
||||||
|
|
||||||
void PrintServices() const;
|
|
||||||
void PrintServiceDescriptor(const ServiceDescriptor& descriptor) const;
|
|
||||||
void PrintServiceClass(const ServiceDescriptor& descriptor) const;
|
|
||||||
void PrintServiceStub(const ServiceDescriptor& descriptor) const;
|
|
||||||
|
|
||||||
void PrintEnumValueDescriptor(const EnumValueDescriptor& descriptor) const;
|
|
||||||
string OptionsValue(const string& class_name,
|
|
||||||
const string& serialized_options) const;
|
|
||||||
bool GeneratingDescriptorProto() const;
|
|
||||||
|
|
||||||
template <typename DescriptorT>
|
|
||||||
string ModuleLevelDescriptorName(const DescriptorT& descriptor) const;
|
|
||||||
string ModuleLevelMessageName(const Descriptor& descriptor) const;
|
|
||||||
string ModuleLevelServiceDescriptorName(
|
|
||||||
const ServiceDescriptor& descriptor) const;
|
|
||||||
|
|
||||||
template <typename DescriptorT, typename DescriptorProtoT>
|
|
||||||
void PrintSerializedPbInterval(
|
|
||||||
const DescriptorT& descriptor, DescriptorProtoT& proto) const;
|
|
||||||
|
|
||||||
void FixAllDescriptorOptions() const;
|
|
||||||
void FixOptionsForField(const FieldDescriptor& field) const;
|
|
||||||
void FixOptionsForEnum(const EnumDescriptor& descriptor) const;
|
|
||||||
void FixOptionsForMessage(const Descriptor& descriptor) const;
|
|
||||||
|
|
||||||
// Very coarse-grained lock to ensure that Generate() is reentrant.
|
|
||||||
// Guards file_, printer_ and file_descriptor_serialized_.
|
|
||||||
mutable Mutex mutex_;
|
|
||||||
mutable const FileDescriptor* file_; // Set in Generate(). Under mutex_.
|
|
||||||
mutable string file_descriptor_serialized_;
|
|
||||||
mutable io::Printer* printer_; // Set in Generate(). Under mutex_.
|
|
||||||
|
|
||||||
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Generator);
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace python
|
|
||||||
} // namespace compiler
|
|
||||||
} // namespace protobuf
|
|
||||||
|
|
||||||
} // namespace google
|
|
||||||
#endif // GOOGLE_PROTOBUF_COMPILER_PYTHON_GENERATOR_H__
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,369 +0,0 @@
|
||||||
// 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.
|
|
||||||
|
|
||||||
// Author: kenton@google.com (Kenton Varda)
|
|
||||||
// Based on original Protocol Buffers design by
|
|
||||||
// Sanjay Ghemawat, Jeff Dean, and others.
|
|
||||||
//
|
|
||||||
// Interface for manipulating databases of descriptors.
|
|
||||||
|
|
||||||
#ifndef GOOGLE_PROTOBUF_DESCRIPTOR_DATABASE_H__
|
|
||||||
#define GOOGLE_PROTOBUF_DESCRIPTOR_DATABASE_H__
|
|
||||||
|
|
||||||
#include <map>
|
|
||||||
#include <string>
|
|
||||||
#include <utility>
|
|
||||||
#include <vector>
|
|
||||||
#include <google/protobuf/stubs/common.h>
|
|
||||||
#include <google/protobuf/descriptor.h>
|
|
||||||
|
|
||||||
namespace google {
|
|
||||||
namespace protobuf {
|
|
||||||
|
|
||||||
// Defined in this file.
|
|
||||||
class DescriptorDatabase;
|
|
||||||
class SimpleDescriptorDatabase;
|
|
||||||
class EncodedDescriptorDatabase;
|
|
||||||
class DescriptorPoolDatabase;
|
|
||||||
class MergedDescriptorDatabase;
|
|
||||||
|
|
||||||
// Abstract interface for a database of descriptors.
|
|
||||||
//
|
|
||||||
// This is useful if you want to create a DescriptorPool which loads
|
|
||||||
// descriptors on-demand from some sort of large database. If the database
|
|
||||||
// is large, it may be inefficient to enumerate every .proto file inside it
|
|
||||||
// calling DescriptorPool::BuildFile() for each one. Instead, a DescriptorPool
|
|
||||||
// can be created which wraps a DescriptorDatabase and only builds particular
|
|
||||||
// descriptors when they are needed.
|
|
||||||
class LIBPROTOBUF_EXPORT DescriptorDatabase {
|
|
||||||
public:
|
|
||||||
inline DescriptorDatabase() {}
|
|
||||||
virtual ~DescriptorDatabase();
|
|
||||||
|
|
||||||
// Find a file by file name. Fills in in *output and returns true if found.
|
|
||||||
// Otherwise, returns false, leaving the contents of *output undefined.
|
|
||||||
virtual bool FindFileByName(const string& filename,
|
|
||||||
FileDescriptorProto* output) = 0;
|
|
||||||
|
|
||||||
// Find the file that declares the given fully-qualified symbol name.
|
|
||||||
// If found, fills in *output and returns true, otherwise returns false
|
|
||||||
// and leaves *output undefined.
|
|
||||||
virtual bool FindFileContainingSymbol(const string& symbol_name,
|
|
||||||
FileDescriptorProto* output) = 0;
|
|
||||||
|
|
||||||
// Find the file which defines an extension extending the given message type
|
|
||||||
// with the given field number. If found, fills in *output and returns true,
|
|
||||||
// otherwise returns false and leaves *output undefined. containing_type
|
|
||||||
// must be a fully-qualified type name.
|
|
||||||
virtual bool FindFileContainingExtension(const string& containing_type,
|
|
||||||
int field_number,
|
|
||||||
FileDescriptorProto* output) = 0;
|
|
||||||
|
|
||||||
// Finds the tag numbers used by all known extensions of
|
|
||||||
// extendee_type, and appends them to output in an undefined
|
|
||||||
// order. This method is best-effort: it's not guaranteed that the
|
|
||||||
// database will find all extensions, and it's not guaranteed that
|
|
||||||
// FindFileContainingExtension will return true on all of the found
|
|
||||||
// numbers. Returns true if the search was successful, otherwise
|
|
||||||
// returns false and leaves output unchanged.
|
|
||||||
//
|
|
||||||
// This method has a default implementation that always returns
|
|
||||||
// false.
|
|
||||||
virtual bool FindAllExtensionNumbers(const string& /* extendee_type */,
|
|
||||||
vector<int>* /* output */) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
|
||||||
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DescriptorDatabase);
|
|
||||||
};
|
|
||||||
|
|
||||||
// A DescriptorDatabase into which you can insert files manually.
|
|
||||||
//
|
|
||||||
// FindFileContainingSymbol() is fully-implemented. When you add a file, its
|
|
||||||
// symbols will be indexed for this purpose. Note that the implementation
|
|
||||||
// may return false positives, but only if it isn't possible for the symbol
|
|
||||||
// to be defined in any other file. In particular, if a file defines a symbol
|
|
||||||
// "Foo", then searching for "Foo.[anything]" will match that file. This way,
|
|
||||||
// the database does not need to aggressively index all children of a symbol.
|
|
||||||
//
|
|
||||||
// FindFileContainingExtension() is mostly-implemented. It works if and only
|
|
||||||
// if the original FieldDescriptorProto defining the extension has a
|
|
||||||
// fully-qualified type name in its "extendee" field (i.e. starts with a '.').
|
|
||||||
// If the extendee is a relative name, SimpleDescriptorDatabase will not
|
|
||||||
// attempt to resolve the type, so it will not know what type the extension is
|
|
||||||
// extending. Therefore, calling FindFileContainingExtension() with the
|
|
||||||
// extension's containing type will never actually find that extension. Note
|
|
||||||
// that this is an unlikely problem, as all FileDescriptorProtos created by the
|
|
||||||
// protocol compiler (as well as ones created by calling
|
|
||||||
// FileDescriptor::CopyTo()) will always use fully-qualified names for all
|
|
||||||
// types. You only need to worry if you are constructing FileDescriptorProtos
|
|
||||||
// yourself, or are calling compiler::Parser directly.
|
|
||||||
class LIBPROTOBUF_EXPORT SimpleDescriptorDatabase : public DescriptorDatabase {
|
|
||||||
public:
|
|
||||||
SimpleDescriptorDatabase();
|
|
||||||
~SimpleDescriptorDatabase();
|
|
||||||
|
|
||||||
// Adds the FileDescriptorProto to the database, making a copy. The object
|
|
||||||
// can be deleted after Add() returns. Returns false if the file conflicted
|
|
||||||
// with a file already in the database, in which case an error will have
|
|
||||||
// been written to GOOGLE_LOG(ERROR).
|
|
||||||
bool Add(const FileDescriptorProto& file);
|
|
||||||
|
|
||||||
// Adds the FileDescriptorProto to the database and takes ownership of it.
|
|
||||||
bool AddAndOwn(const FileDescriptorProto* file);
|
|
||||||
|
|
||||||
// implements DescriptorDatabase -----------------------------------
|
|
||||||
bool FindFileByName(const string& filename,
|
|
||||||
FileDescriptorProto* output);
|
|
||||||
bool FindFileContainingSymbol(const string& symbol_name,
|
|
||||||
FileDescriptorProto* output);
|
|
||||||
bool FindFileContainingExtension(const string& containing_type,
|
|
||||||
int field_number,
|
|
||||||
FileDescriptorProto* output);
|
|
||||||
bool FindAllExtensionNumbers(const string& extendee_type,
|
|
||||||
vector<int>* output);
|
|
||||||
|
|
||||||
private:
|
|
||||||
// So that it can use DescriptorIndex.
|
|
||||||
friend class EncodedDescriptorDatabase;
|
|
||||||
|
|
||||||
// An index mapping file names, symbol names, and extension numbers to
|
|
||||||
// some sort of values.
|
|
||||||
template <typename Value>
|
|
||||||
class DescriptorIndex {
|
|
||||||
public:
|
|
||||||
// Helpers to recursively add particular descriptors and all their contents
|
|
||||||
// to the index.
|
|
||||||
bool AddFile(const FileDescriptorProto& file,
|
|
||||||
Value value);
|
|
||||||
bool AddSymbol(const string& name, Value value);
|
|
||||||
bool AddNestedExtensions(const DescriptorProto& message_type,
|
|
||||||
Value value);
|
|
||||||
bool AddExtension(const FieldDescriptorProto& field,
|
|
||||||
Value value);
|
|
||||||
|
|
||||||
Value FindFile(const string& filename);
|
|
||||||
Value FindSymbol(const string& name);
|
|
||||||
Value FindExtension(const string& containing_type, int field_number);
|
|
||||||
bool FindAllExtensionNumbers(const string& containing_type,
|
|
||||||
vector<int>* output);
|
|
||||||
|
|
||||||
private:
|
|
||||||
map<string, Value> by_name_;
|
|
||||||
map<string, Value> by_symbol_;
|
|
||||||
map<pair<string, int>, Value> by_extension_;
|
|
||||||
|
|
||||||
// Invariant: The by_symbol_ map does not contain any symbols which are
|
|
||||||
// prefixes of other symbols in the map. For example, "foo.bar" is a
|
|
||||||
// prefix of "foo.bar.baz" (but is not a prefix of "foo.barbaz").
|
|
||||||
//
|
|
||||||
// This invariant is important because it means that given a symbol name,
|
|
||||||
// we can find a key in the map which is a prefix of the symbol in O(lg n)
|
|
||||||
// time, and we know that there is at most one such key.
|
|
||||||
//
|
|
||||||
// The prefix lookup algorithm works like so:
|
|
||||||
// 1) Find the last key in the map which is less than or equal to the
|
|
||||||
// search key.
|
|
||||||
// 2) If the found key is a prefix of the search key, then return it.
|
|
||||||
// Otherwise, there is no match.
|
|
||||||
//
|
|
||||||
// I am sure this algorithm has been described elsewhere, but since I
|
|
||||||
// wasn't able to find it quickly I will instead prove that it works
|
|
||||||
// myself. The key to the algorithm is that if a match exists, step (1)
|
|
||||||
// will find it. Proof:
|
|
||||||
// 1) Define the "search key" to be the key we are looking for, the "found
|
|
||||||
// key" to be the key found in step (1), and the "match key" to be the
|
|
||||||
// key which actually matches the serach key (i.e. the key we're trying
|
|
||||||
// to find).
|
|
||||||
// 2) The found key must be less than or equal to the search key by
|
|
||||||
// definition.
|
|
||||||
// 3) The match key must also be less than or equal to the search key
|
|
||||||
// (because it is a prefix).
|
|
||||||
// 4) The match key cannot be greater than the found key, because if it
|
|
||||||
// were, then step (1) of the algorithm would have returned the match
|
|
||||||
// key instead (since it finds the *greatest* key which is less than or
|
|
||||||
// equal to the search key).
|
|
||||||
// 5) Therefore, the found key must be between the match key and the search
|
|
||||||
// key, inclusive.
|
|
||||||
// 6) Since the search key must be a sub-symbol of the match key, if it is
|
|
||||||
// not equal to the match key, then search_key[match_key.size()] must
|
|
||||||
// be '.'.
|
|
||||||
// 7) Since '.' sorts before any other character that is valid in a symbol
|
|
||||||
// name, then if the found key is not equal to the match key, then
|
|
||||||
// found_key[match_key.size()] must also be '.', because any other value
|
|
||||||
// would make it sort after the search key.
|
|
||||||
// 8) Therefore, if the found key is not equal to the match key, then the
|
|
||||||
// found key must be a sub-symbol of the match key. However, this would
|
|
||||||
// contradict our map invariant which says that no symbol in the map is
|
|
||||||
// a sub-symbol of any other.
|
|
||||||
// 9) Therefore, the found key must match the match key.
|
|
||||||
//
|
|
||||||
// The above proof assumes the match key exists. In the case that the
|
|
||||||
// match key does not exist, then step (1) will return some other symbol.
|
|
||||||
// That symbol cannot be a super-symbol of the search key since if it were,
|
|
||||||
// then it would be a match, and we're assuming the match key doesn't exist.
|
|
||||||
// Therefore, step 2 will correctly return no match.
|
|
||||||
|
|
||||||
// Find the last entry in the by_symbol_ map whose key is less than or
|
|
||||||
// equal to the given name.
|
|
||||||
typename map<string, Value>::iterator FindLastLessOrEqual(
|
|
||||||
const string& name);
|
|
||||||
|
|
||||||
// True if either the arguments are equal or super_symbol identifies a
|
|
||||||
// parent symbol of sub_symbol (e.g. "foo.bar" is a parent of
|
|
||||||
// "foo.bar.baz", but not a parent of "foo.barbaz").
|
|
||||||
bool IsSubSymbol(const string& sub_symbol, const string& super_symbol);
|
|
||||||
|
|
||||||
// Returns true if and only if all characters in the name are alphanumerics,
|
|
||||||
// underscores, or periods.
|
|
||||||
bool ValidateSymbolName(const string& name);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
DescriptorIndex<const FileDescriptorProto*> index_;
|
|
||||||
vector<const FileDescriptorProto*> files_to_delete_;
|
|
||||||
|
|
||||||
// If file is non-NULL, copy it into *output and return true, otherwise
|
|
||||||
// return false.
|
|
||||||
bool MaybeCopy(const FileDescriptorProto* file,
|
|
||||||
FileDescriptorProto* output);
|
|
||||||
|
|
||||||
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(SimpleDescriptorDatabase);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Very similar to SimpleDescriptorDatabase, but stores all the descriptors
|
|
||||||
// as raw bytes and generally tries to use as little memory as possible.
|
|
||||||
//
|
|
||||||
// The same caveats regarding FindFileContainingExtension() apply as with
|
|
||||||
// SimpleDescriptorDatabase.
|
|
||||||
class LIBPROTOBUF_EXPORT EncodedDescriptorDatabase : public DescriptorDatabase {
|
|
||||||
public:
|
|
||||||
EncodedDescriptorDatabase();
|
|
||||||
~EncodedDescriptorDatabase();
|
|
||||||
|
|
||||||
// Adds the FileDescriptorProto to the database. The descriptor is provided
|
|
||||||
// in encoded form. The database does not make a copy of the bytes, nor
|
|
||||||
// does it take ownership; it's up to the caller to make sure the bytes
|
|
||||||
// remain valid for the life of the database. Returns false and logs an error
|
|
||||||
// if the bytes are not a valid FileDescriptorProto or if the file conflicted
|
|
||||||
// with a file already in the database.
|
|
||||||
bool Add(const void* encoded_file_descriptor, int size);
|
|
||||||
|
|
||||||
// Like Add(), but makes a copy of the data, so that the caller does not
|
|
||||||
// need to keep it around.
|
|
||||||
bool AddCopy(const void* encoded_file_descriptor, int size);
|
|
||||||
|
|
||||||
// Like FindFileContainingSymbol but returns only the name of the file.
|
|
||||||
bool FindNameOfFileContainingSymbol(const string& symbol_name,
|
|
||||||
string* output);
|
|
||||||
|
|
||||||
// implements DescriptorDatabase -----------------------------------
|
|
||||||
bool FindFileByName(const string& filename,
|
|
||||||
FileDescriptorProto* output);
|
|
||||||
bool FindFileContainingSymbol(const string& symbol_name,
|
|
||||||
FileDescriptorProto* output);
|
|
||||||
bool FindFileContainingExtension(const string& containing_type,
|
|
||||||
int field_number,
|
|
||||||
FileDescriptorProto* output);
|
|
||||||
bool FindAllExtensionNumbers(const string& extendee_type,
|
|
||||||
vector<int>* output);
|
|
||||||
|
|
||||||
private:
|
|
||||||
SimpleDescriptorDatabase::DescriptorIndex<pair<const void*, int> > index_;
|
|
||||||
vector<void*> files_to_delete_;
|
|
||||||
|
|
||||||
// If encoded_file.first is non-NULL, parse the data into *output and return
|
|
||||||
// true, otherwise return false.
|
|
||||||
bool MaybeParse(pair<const void*, int> encoded_file,
|
|
||||||
FileDescriptorProto* output);
|
|
||||||
|
|
||||||
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EncodedDescriptorDatabase);
|
|
||||||
};
|
|
||||||
|
|
||||||
// A DescriptorDatabase that fetches files from a given pool.
|
|
||||||
class LIBPROTOBUF_EXPORT DescriptorPoolDatabase : public DescriptorDatabase {
|
|
||||||
public:
|
|
||||||
DescriptorPoolDatabase(const DescriptorPool& pool);
|
|
||||||
~DescriptorPoolDatabase();
|
|
||||||
|
|
||||||
// implements DescriptorDatabase -----------------------------------
|
|
||||||
bool FindFileByName(const string& filename,
|
|
||||||
FileDescriptorProto* output);
|
|
||||||
bool FindFileContainingSymbol(const string& symbol_name,
|
|
||||||
FileDescriptorProto* output);
|
|
||||||
bool FindFileContainingExtension(const string& containing_type,
|
|
||||||
int field_number,
|
|
||||||
FileDescriptorProto* output);
|
|
||||||
bool FindAllExtensionNumbers(const string& extendee_type,
|
|
||||||
vector<int>* output);
|
|
||||||
|
|
||||||
private:
|
|
||||||
const DescriptorPool& pool_;
|
|
||||||
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DescriptorPoolDatabase);
|
|
||||||
};
|
|
||||||
|
|
||||||
// A DescriptorDatabase that wraps two or more others. It first searches the
|
|
||||||
// first database and, if that fails, tries the second, and so on.
|
|
||||||
class LIBPROTOBUF_EXPORT MergedDescriptorDatabase : public DescriptorDatabase {
|
|
||||||
public:
|
|
||||||
// Merge just two databases. The sources remain property of the caller.
|
|
||||||
MergedDescriptorDatabase(DescriptorDatabase* source1,
|
|
||||||
DescriptorDatabase* source2);
|
|
||||||
// Merge more than two databases. The sources remain property of the caller.
|
|
||||||
// The vector may be deleted after the constructor returns but the
|
|
||||||
// DescriptorDatabases need to stick around.
|
|
||||||
MergedDescriptorDatabase(const vector<DescriptorDatabase*>& sources);
|
|
||||||
~MergedDescriptorDatabase();
|
|
||||||
|
|
||||||
// implements DescriptorDatabase -----------------------------------
|
|
||||||
bool FindFileByName(const string& filename,
|
|
||||||
FileDescriptorProto* output);
|
|
||||||
bool FindFileContainingSymbol(const string& symbol_name,
|
|
||||||
FileDescriptorProto* output);
|
|
||||||
bool FindFileContainingExtension(const string& containing_type,
|
|
||||||
int field_number,
|
|
||||||
FileDescriptorProto* output);
|
|
||||||
// Merges the results of calling all databases. Returns true iff any
|
|
||||||
// of the databases returned true.
|
|
||||||
bool FindAllExtensionNumbers(const string& extendee_type,
|
|
||||||
vector<int>* output);
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
|
||||||
vector<DescriptorDatabase*> sources_;
|
|
||||||
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MergedDescriptorDatabase);
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace protobuf
|
|
||||||
|
|
||||||
} // namespace google
|
|
||||||
#endif // GOOGLE_PROTOBUF_DESCRIPTOR_DATABASE_H__
|
|
|
@ -1,148 +0,0 @@
|
||||||
// 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.
|
|
||||||
|
|
||||||
// Author: kenton@google.com (Kenton Varda)
|
|
||||||
// Based on original Protocol Buffers design by
|
|
||||||
// Sanjay Ghemawat, Jeff Dean, and others.
|
|
||||||
//
|
|
||||||
// Defines an implementation of Message which can emulate types which are not
|
|
||||||
// known at compile-time.
|
|
||||||
|
|
||||||
#ifndef GOOGLE_PROTOBUF_DYNAMIC_MESSAGE_H__
|
|
||||||
#define GOOGLE_PROTOBUF_DYNAMIC_MESSAGE_H__
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
#include <google/protobuf/message.h>
|
|
||||||
#include <google/protobuf/stubs/common.h>
|
|
||||||
|
|
||||||
namespace google {
|
|
||||||
namespace protobuf {
|
|
||||||
|
|
||||||
// Defined in other files.
|
|
||||||
class Descriptor; // descriptor.h
|
|
||||||
class DescriptorPool; // descriptor.h
|
|
||||||
|
|
||||||
// Constructs implementations of Message which can emulate types which are not
|
|
||||||
// known at compile-time.
|
|
||||||
//
|
|
||||||
// Sometimes you want to be able to manipulate protocol types that you don't
|
|
||||||
// know about at compile time. It would be nice to be able to construct
|
|
||||||
// a Message object which implements the message type given by any arbitrary
|
|
||||||
// Descriptor. DynamicMessage provides this.
|
|
||||||
//
|
|
||||||
// As it turns out, a DynamicMessage needs to construct extra
|
|
||||||
// information about its type in order to operate. Most of this information
|
|
||||||
// can be shared between all DynamicMessages of the same type. But, caching
|
|
||||||
// this information in some sort of global map would be a bad idea, since
|
|
||||||
// the cached information for a particular descriptor could outlive the
|
|
||||||
// descriptor itself. To avoid this problem, DynamicMessageFactory
|
|
||||||
// encapsulates this "cache". All DynamicMessages of the same type created
|
|
||||||
// from the same factory will share the same support data. Any Descriptors
|
|
||||||
// used with a particular factory must outlive the factory.
|
|
||||||
class LIBPROTOBUF_EXPORT DynamicMessageFactory : public MessageFactory {
|
|
||||||
public:
|
|
||||||
// Construct a DynamicMessageFactory that will search for extensions in
|
|
||||||
// the DescriptorPool in which the extendee is defined.
|
|
||||||
DynamicMessageFactory();
|
|
||||||
|
|
||||||
// Construct a DynamicMessageFactory that will search for extensions in
|
|
||||||
// the given DescriptorPool.
|
|
||||||
//
|
|
||||||
// DEPRECATED: Use CodedInputStream::SetExtensionRegistry() to tell the
|
|
||||||
// parser to look for extensions in an alternate pool. However, note that
|
|
||||||
// this is almost never what you want to do. Almost all users should use
|
|
||||||
// the zero-arg constructor.
|
|
||||||
DynamicMessageFactory(const DescriptorPool* pool);
|
|
||||||
|
|
||||||
~DynamicMessageFactory();
|
|
||||||
|
|
||||||
// Call this to tell the DynamicMessageFactory that if it is given a
|
|
||||||
// Descriptor d for which:
|
|
||||||
// d->file()->pool() == DescriptorPool::generated_pool(),
|
|
||||||
// then it should delegate to MessageFactory::generated_factory() instead
|
|
||||||
// of constructing a dynamic implementation of the message. In theory there
|
|
||||||
// is no down side to doing this, so it may become the default in the future.
|
|
||||||
void SetDelegateToGeneratedFactory(bool enable) {
|
|
||||||
delegate_to_generated_factory_ = enable;
|
|
||||||
}
|
|
||||||
|
|
||||||
// implements MessageFactory ---------------------------------------
|
|
||||||
|
|
||||||
// Given a Descriptor, constructs the default (prototype) Message of that
|
|
||||||
// type. You can then call that message's New() method to construct a
|
|
||||||
// mutable message of that type.
|
|
||||||
//
|
|
||||||
// Calling this method twice with the same Descriptor returns the same
|
|
||||||
// object. The returned object remains property of the factory and will
|
|
||||||
// be destroyed when the factory is destroyed. Also, any objects created
|
|
||||||
// by calling the prototype's New() method share some data with the
|
|
||||||
// prototype, so these must be destroyed before the DynamicMessageFactory
|
|
||||||
// is destroyed.
|
|
||||||
//
|
|
||||||
// The given descriptor must outlive the returned message, and hence must
|
|
||||||
// outlive the DynamicMessageFactory.
|
|
||||||
//
|
|
||||||
// The method is thread-safe.
|
|
||||||
const Message* GetPrototype(const Descriptor* type);
|
|
||||||
|
|
||||||
private:
|
|
||||||
const DescriptorPool* pool_;
|
|
||||||
bool delegate_to_generated_factory_;
|
|
||||||
|
|
||||||
// This struct just contains a hash_map. We can't #include <google/protobuf/stubs/hash.h> from
|
|
||||||
// this header due to hacks needed for hash_map portability in the open source
|
|
||||||
// release. Namely, stubs/hash.h, which defines hash_map portably, is not a
|
|
||||||
// public header (for good reason), but dynamic_message.h is, and public
|
|
||||||
// headers may only #include other public headers.
|
|
||||||
struct PrototypeMap;
|
|
||||||
scoped_ptr<PrototypeMap> prototypes_;
|
|
||||||
mutable Mutex prototypes_mutex_;
|
|
||||||
|
|
||||||
friend class DynamicMessage;
|
|
||||||
const Message* GetPrototypeNoLock(const Descriptor* type);
|
|
||||||
|
|
||||||
// Construct default oneof instance for reflection usage if oneof
|
|
||||||
// is defined.
|
|
||||||
static void ConstructDefaultOneofInstance(const Descriptor* type,
|
|
||||||
const int offsets[],
|
|
||||||
void* default_oneof_instance);
|
|
||||||
// Delete default oneof instance. Called by ~DynamicMessageFactory.
|
|
||||||
static void DeleteDefaultOneofInstance(const Descriptor* type,
|
|
||||||
const int offsets[],
|
|
||||||
void* default_oneof_instance);
|
|
||||||
|
|
||||||
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DynamicMessageFactory);
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace protobuf
|
|
||||||
|
|
||||||
} // namespace google
|
|
||||||
#endif // GOOGLE_PROTOBUF_DYNAMIC_MESSAGE_H__
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,91 +0,0 @@
|
||||||
// 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.
|
|
||||||
|
|
||||||
// Author: jasonh@google.com (Jason Hsueh)
|
|
||||||
//
|
|
||||||
// This header is logically internal, but is made public because it is used
|
|
||||||
// from protocol-compiler-generated code, which may reside in other components.
|
|
||||||
// It provides reflection support for generated enums, and is included in
|
|
||||||
// generated .pb.h files and should have minimal dependencies. The methods are
|
|
||||||
// implemented in generated_message_reflection.cc.
|
|
||||||
|
|
||||||
#ifndef GOOGLE_PROTOBUF_GENERATED_ENUM_REFLECTION_H__
|
|
||||||
#define GOOGLE_PROTOBUF_GENERATED_ENUM_REFLECTION_H__
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include <google/protobuf/stubs/template_util.h>
|
|
||||||
|
|
||||||
namespace google {
|
|
||||||
namespace protobuf {
|
|
||||||
class EnumDescriptor;
|
|
||||||
} // namespace protobuf
|
|
||||||
|
|
||||||
namespace protobuf {
|
|
||||||
|
|
||||||
// This type trait can be used to cause templates to only match proto2 enum
|
|
||||||
// types.
|
|
||||||
template <typename T> struct is_proto_enum : ::google::protobuf::internal::false_type {};
|
|
||||||
|
|
||||||
// Returns the EnumDescriptor for enum type E, which must be a
|
|
||||||
// proto-declared enum type. Code generated by the protocol compiler
|
|
||||||
// will include specializations of this template for each enum type declared.
|
|
||||||
template <typename E>
|
|
||||||
const EnumDescriptor* GetEnumDescriptor();
|
|
||||||
|
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
// Helper for EnumType_Parse functions: try to parse the string 'name' as an
|
|
||||||
// enum name of the given type, returning true and filling in value on success,
|
|
||||||
// or returning false and leaving value unchanged on failure.
|
|
||||||
LIBPROTOBUF_EXPORT bool ParseNamedEnum(const EnumDescriptor* descriptor,
|
|
||||||
const string& name,
|
|
||||||
int* value);
|
|
||||||
|
|
||||||
template<typename EnumType>
|
|
||||||
bool ParseNamedEnum(const EnumDescriptor* descriptor,
|
|
||||||
const string& name,
|
|
||||||
EnumType* value) {
|
|
||||||
int tmp;
|
|
||||||
if (!ParseNamedEnum(descriptor, name, &tmp)) return false;
|
|
||||||
*value = static_cast<EnumType>(tmp);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Just a wrapper around printing the name of a value. The main point of this
|
|
||||||
// function is not to be inlined, so that you can do this without including
|
|
||||||
// descriptor.h.
|
|
||||||
LIBPROTOBUF_EXPORT const string& NameOfEnum(const EnumDescriptor* descriptor, int value);
|
|
||||||
|
|
||||||
} // namespace internal
|
|
||||||
} // namespace protobuf
|
|
||||||
|
|
||||||
} // namespace google
|
|
||||||
#endif // GOOGLE_PROTOBUF_GENERATED_ENUM_REFLECTION_H__
|
|
|
@ -1,504 +0,0 @@
|
||||||
// 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.
|
|
||||||
|
|
||||||
// Author: kenton@google.com (Kenton Varda)
|
|
||||||
// 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_GENERATED_MESSAGE_REFLECTION_H__
|
|
||||||
#define GOOGLE_PROTOBUF_GENERATED_MESSAGE_REFLECTION_H__
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
#include <google/protobuf/stubs/common.h>
|
|
||||||
// TODO(jasonh): Remove this once the compiler change to directly include this
|
|
||||||
// is released to components.
|
|
||||||
#include <google/protobuf/generated_enum_reflection.h>
|
|
||||||
#include <google/protobuf/message.h>
|
|
||||||
#include <google/protobuf/unknown_field_set.h>
|
|
||||||
|
|
||||||
|
|
||||||
namespace google {
|
|
||||||
namespace upb {
|
|
||||||
namespace google_opensource {
|
|
||||||
class GMR_Handlers;
|
|
||||||
} // namespace google_opensource
|
|
||||||
} // namespace upb
|
|
||||||
|
|
||||||
namespace protobuf {
|
|
||||||
class DescriptorPool;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace protobuf {
|
|
||||||
namespace internal {
|
|
||||||
class DefaultEmptyOneof;
|
|
||||||
|
|
||||||
// Defined in this file.
|
|
||||||
class GeneratedMessageReflection;
|
|
||||||
|
|
||||||
// Defined in other files.
|
|
||||||
class ExtensionSet; // extension_set.h
|
|
||||||
|
|
||||||
// THIS CLASS IS NOT INTENDED FOR DIRECT USE. It is intended for use
|
|
||||||
// by generated code. This class is just a big hack that reduces code
|
|
||||||
// size.
|
|
||||||
//
|
|
||||||
// A GeneratedMessageReflection is an implementation of Reflection
|
|
||||||
// which expects all fields to be backed by simple variables located in
|
|
||||||
// memory. The locations are given using a base pointer and a set of
|
|
||||||
// offsets.
|
|
||||||
//
|
|
||||||
// It is required that the user represents fields of each type in a standard
|
|
||||||
// way, so that GeneratedMessageReflection can cast the void* pointer to
|
|
||||||
// the appropriate type. For primitive fields and string fields, each field
|
|
||||||
// should be represented using the obvious C++ primitive type. Enums and
|
|
||||||
// Messages are different:
|
|
||||||
// - Singular Message fields are stored as a pointer to a Message. These
|
|
||||||
// should start out NULL, except for in the default instance where they
|
|
||||||
// should start out pointing to other default instances.
|
|
||||||
// - Enum fields are stored as an int. This int must always contain
|
|
||||||
// a valid value, such that EnumDescriptor::FindValueByNumber() would
|
|
||||||
// not return NULL.
|
|
||||||
// - Repeated fields are stored as RepeatedFields or RepeatedPtrFields
|
|
||||||
// of whatever type the individual field would be. Strings and
|
|
||||||
// Messages use RepeatedPtrFields while everything else uses
|
|
||||||
// RepeatedFields.
|
|
||||||
class LIBPROTOBUF_EXPORT GeneratedMessageReflection : public Reflection {
|
|
||||||
public:
|
|
||||||
// Constructs a GeneratedMessageReflection.
|
|
||||||
// Parameters:
|
|
||||||
// descriptor: The descriptor for the message type being implemented.
|
|
||||||
// default_instance: The default instance of the message. This is only
|
|
||||||
// used to obtain pointers to default instances of embedded
|
|
||||||
// messages, which GetMessage() will return if the particular
|
|
||||||
// sub-message has not been initialized yet. (Thus, all
|
|
||||||
// embedded message fields *must* have non-NULL pointers
|
|
||||||
// in the default instance.)
|
|
||||||
// offsets: An array of ints giving the byte offsets, relative to
|
|
||||||
// the start of the message object, of each field. These can
|
|
||||||
// be computed at compile time using the
|
|
||||||
// GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET() macro, defined
|
|
||||||
// below.
|
|
||||||
// has_bits_offset: Offset in the message of an array of uint32s of size
|
|
||||||
// descriptor->field_count()/32, rounded up. This is a
|
|
||||||
// bitfield where each bit indicates whether or not the
|
|
||||||
// corresponding field of the message has been initialized.
|
|
||||||
// The bit for field index i is obtained by the expression:
|
|
||||||
// has_bits[i / 32] & (1 << (i % 32))
|
|
||||||
// unknown_fields_offset: Offset in the message of the UnknownFieldSet for
|
|
||||||
// the message.
|
|
||||||
// extensions_offset: Offset in the message of the ExtensionSet for the
|
|
||||||
// message, or -1 if the message type has no extension
|
|
||||||
// ranges.
|
|
||||||
// pool: DescriptorPool to search for extension definitions. Only
|
|
||||||
// used by FindKnownExtensionByName() and
|
|
||||||
// FindKnownExtensionByNumber().
|
|
||||||
// factory: MessageFactory to use to construct extension messages.
|
|
||||||
// object_size: The size of a message object of this type, as measured
|
|
||||||
// by sizeof().
|
|
||||||
GeneratedMessageReflection(const Descriptor* descriptor,
|
|
||||||
const Message* default_instance,
|
|
||||||
const int offsets[],
|
|
||||||
int has_bits_offset,
|
|
||||||
int unknown_fields_offset,
|
|
||||||
int extensions_offset,
|
|
||||||
const DescriptorPool* pool,
|
|
||||||
MessageFactory* factory,
|
|
||||||
int object_size);
|
|
||||||
|
|
||||||
// Similar with the construction above. Call this construction if the
|
|
||||||
// message has oneof definition.
|
|
||||||
// Parameters:
|
|
||||||
// offsets: An array of ints giving the byte offsets.
|
|
||||||
// For each oneof field, the offset is relative to the
|
|
||||||
// default_oneof_instance. These can be computed at compile
|
|
||||||
// time using the
|
|
||||||
// PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET() macro.
|
|
||||||
// For each none oneof field, the offset is related to
|
|
||||||
// the start of the message object. These can be computed
|
|
||||||
// at compile time using the
|
|
||||||
// GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET() macro.
|
|
||||||
// Besides offsets for all fields, this array also contains
|
|
||||||
// offsets for oneof unions. The offset of the i-th oneof
|
|
||||||
// union is offsets[descriptor->field_count() + i].
|
|
||||||
// default_oneof_instance: The default instance of the oneofs. It is a
|
|
||||||
// struct holding the default value of all oneof fields
|
|
||||||
// for this message. It is only used to obtain pointers
|
|
||||||
// to default instances of oneof fields, which Get
|
|
||||||
// methods will return if the field is not set.
|
|
||||||
// oneof_case_offset: Offset in the message of an array of uint32s of
|
|
||||||
// size descriptor->oneof_decl_count(). Each uint32
|
|
||||||
// indicates what field is set for each oneof.
|
|
||||||
// other parameters are the same with the construction above.
|
|
||||||
GeneratedMessageReflection(const Descriptor* descriptor,
|
|
||||||
const Message* default_instance,
|
|
||||||
const int offsets[],
|
|
||||||
int has_bits_offset,
|
|
||||||
int unknown_fields_offset,
|
|
||||||
int extensions_offset,
|
|
||||||
const void* default_oneof_instance,
|
|
||||||
int oneof_case_offset,
|
|
||||||
const DescriptorPool* pool,
|
|
||||||
MessageFactory* factory,
|
|
||||||
int object_size);
|
|
||||||
~GeneratedMessageReflection();
|
|
||||||
|
|
||||||
// implements Reflection -------------------------------------------
|
|
||||||
|
|
||||||
const UnknownFieldSet& GetUnknownFields(const Message& message) const;
|
|
||||||
UnknownFieldSet* MutableUnknownFields(Message* message) const;
|
|
||||||
|
|
||||||
int SpaceUsed(const Message& message) const;
|
|
||||||
|
|
||||||
bool HasField(const Message& message, const FieldDescriptor* field) const;
|
|
||||||
int FieldSize(const Message& message, const FieldDescriptor* field) const;
|
|
||||||
void ClearField(Message* message, const FieldDescriptor* field) const;
|
|
||||||
bool HasOneof(const Message& message,
|
|
||||||
const OneofDescriptor* oneof_descriptor) const;
|
|
||||||
void ClearOneof(Message* message, const OneofDescriptor* field) const;
|
|
||||||
void RemoveLast(Message* message, const FieldDescriptor* field) const;
|
|
||||||
Message* ReleaseLast(Message* message, const FieldDescriptor* field) const;
|
|
||||||
void Swap(Message* message1, Message* message2) const;
|
|
||||||
void SwapFields(Message* message1, Message* message2,
|
|
||||||
const vector<const FieldDescriptor*>& fields) const;
|
|
||||||
void SwapElements(Message* message, const FieldDescriptor* field,
|
|
||||||
int index1, int index2) const;
|
|
||||||
void ListFields(const Message& message,
|
|
||||||
vector<const FieldDescriptor*>* output) const;
|
|
||||||
|
|
||||||
int32 GetInt32 (const Message& message,
|
|
||||||
const FieldDescriptor* field) const;
|
|
||||||
int64 GetInt64 (const Message& message,
|
|
||||||
const FieldDescriptor* field) const;
|
|
||||||
uint32 GetUInt32(const Message& message,
|
|
||||||
const FieldDescriptor* field) const;
|
|
||||||
uint64 GetUInt64(const Message& message,
|
|
||||||
const FieldDescriptor* field) const;
|
|
||||||
float GetFloat (const Message& message,
|
|
||||||
const FieldDescriptor* field) const;
|
|
||||||
double GetDouble(const Message& message,
|
|
||||||
const FieldDescriptor* field) const;
|
|
||||||
bool GetBool (const Message& message,
|
|
||||||
const FieldDescriptor* field) const;
|
|
||||||
string GetString(const Message& message,
|
|
||||||
const FieldDescriptor* field) const;
|
|
||||||
const string& GetStringReference(const Message& message,
|
|
||||||
const FieldDescriptor* field,
|
|
||||||
string* scratch) const;
|
|
||||||
const EnumValueDescriptor* GetEnum(const Message& message,
|
|
||||||
const FieldDescriptor* field) const;
|
|
||||||
const Message& GetMessage(const Message& message,
|
|
||||||
const FieldDescriptor* field,
|
|
||||||
MessageFactory* factory = NULL) const;
|
|
||||||
|
|
||||||
const FieldDescriptor* GetOneofFieldDescriptor(
|
|
||||||
const Message& message,
|
|
||||||
const OneofDescriptor* oneof_descriptor) const;
|
|
||||||
|
|
||||||
public:
|
|
||||||
void SetInt32 (Message* message,
|
|
||||||
const FieldDescriptor* field, int32 value) const;
|
|
||||||
void SetInt64 (Message* message,
|
|
||||||
const FieldDescriptor* field, int64 value) const;
|
|
||||||
void SetUInt32(Message* message,
|
|
||||||
const FieldDescriptor* field, uint32 value) const;
|
|
||||||
void SetUInt64(Message* message,
|
|
||||||
const FieldDescriptor* field, uint64 value) const;
|
|
||||||
void SetFloat (Message* message,
|
|
||||||
const FieldDescriptor* field, float value) const;
|
|
||||||
void SetDouble(Message* message,
|
|
||||||
const FieldDescriptor* field, double value) const;
|
|
||||||
void SetBool (Message* message,
|
|
||||||
const FieldDescriptor* field, bool value) const;
|
|
||||||
void SetString(Message* message,
|
|
||||||
const FieldDescriptor* field,
|
|
||||||
const string& value) const;
|
|
||||||
void SetEnum (Message* message, const FieldDescriptor* field,
|
|
||||||
const EnumValueDescriptor* value) const;
|
|
||||||
Message* MutableMessage(Message* message, const FieldDescriptor* field,
|
|
||||||
MessageFactory* factory = NULL) const;
|
|
||||||
void SetAllocatedMessage(Message* message,
|
|
||||||
Message* sub_message,
|
|
||||||
const FieldDescriptor* field) const;
|
|
||||||
Message* ReleaseMessage(Message* message, const FieldDescriptor* field,
|
|
||||||
MessageFactory* factory = NULL) const;
|
|
||||||
|
|
||||||
int32 GetRepeatedInt32 (const Message& message,
|
|
||||||
const FieldDescriptor* field, int index) const;
|
|
||||||
int64 GetRepeatedInt64 (const Message& message,
|
|
||||||
const FieldDescriptor* field, int index) const;
|
|
||||||
uint32 GetRepeatedUInt32(const Message& message,
|
|
||||||
const FieldDescriptor* field, int index) const;
|
|
||||||
uint64 GetRepeatedUInt64(const Message& message,
|
|
||||||
const FieldDescriptor* field, int index) const;
|
|
||||||
float GetRepeatedFloat (const Message& message,
|
|
||||||
const FieldDescriptor* field, int index) const;
|
|
||||||
double GetRepeatedDouble(const Message& message,
|
|
||||||
const FieldDescriptor* field, int index) const;
|
|
||||||
bool GetRepeatedBool (const Message& message,
|
|
||||||
const FieldDescriptor* field, int index) const;
|
|
||||||
string GetRepeatedString(const Message& message,
|
|
||||||
const FieldDescriptor* field, int index) const;
|
|
||||||
const string& GetRepeatedStringReference(const Message& message,
|
|
||||||
const FieldDescriptor* field,
|
|
||||||
int index, string* scratch) const;
|
|
||||||
const EnumValueDescriptor* GetRepeatedEnum(const Message& message,
|
|
||||||
const FieldDescriptor* field,
|
|
||||||
int index) const;
|
|
||||||
const Message& GetRepeatedMessage(const Message& message,
|
|
||||||
const FieldDescriptor* field,
|
|
||||||
int index) const;
|
|
||||||
|
|
||||||
// Set the value of a field.
|
|
||||||
void SetRepeatedInt32 (Message* message,
|
|
||||||
const FieldDescriptor* field, int index, int32 value) const;
|
|
||||||
void SetRepeatedInt64 (Message* message,
|
|
||||||
const FieldDescriptor* field, int index, int64 value) const;
|
|
||||||
void SetRepeatedUInt32(Message* message,
|
|
||||||
const FieldDescriptor* field, int index, uint32 value) const;
|
|
||||||
void SetRepeatedUInt64(Message* message,
|
|
||||||
const FieldDescriptor* field, int index, uint64 value) const;
|
|
||||||
void SetRepeatedFloat (Message* message,
|
|
||||||
const FieldDescriptor* field, int index, float value) const;
|
|
||||||
void SetRepeatedDouble(Message* message,
|
|
||||||
const FieldDescriptor* field, int index, double value) const;
|
|
||||||
void SetRepeatedBool (Message* message,
|
|
||||||
const FieldDescriptor* field, int index, bool value) const;
|
|
||||||
void SetRepeatedString(Message* message,
|
|
||||||
const FieldDescriptor* field, int index,
|
|
||||||
const string& value) const;
|
|
||||||
void SetRepeatedEnum(Message* message, const FieldDescriptor* field,
|
|
||||||
int index, const EnumValueDescriptor* value) const;
|
|
||||||
// Get a mutable pointer to a field with a message type.
|
|
||||||
Message* MutableRepeatedMessage(Message* message,
|
|
||||||
const FieldDescriptor* field,
|
|
||||||
int index) const;
|
|
||||||
|
|
||||||
void AddInt32 (Message* message,
|
|
||||||
const FieldDescriptor* field, int32 value) const;
|
|
||||||
void AddInt64 (Message* message,
|
|
||||||
const FieldDescriptor* field, int64 value) const;
|
|
||||||
void AddUInt32(Message* message,
|
|
||||||
const FieldDescriptor* field, uint32 value) const;
|
|
||||||
void AddUInt64(Message* message,
|
|
||||||
const FieldDescriptor* field, uint64 value) const;
|
|
||||||
void AddFloat (Message* message,
|
|
||||||
const FieldDescriptor* field, float value) const;
|
|
||||||
void AddDouble(Message* message,
|
|
||||||
const FieldDescriptor* field, double value) const;
|
|
||||||
void AddBool (Message* message,
|
|
||||||
const FieldDescriptor* field, bool value) const;
|
|
||||||
void AddString(Message* message,
|
|
||||||
const FieldDescriptor* field, const string& value) const;
|
|
||||||
void AddEnum(Message* message,
|
|
||||||
const FieldDescriptor* field,
|
|
||||||
const EnumValueDescriptor* value) const;
|
|
||||||
Message* AddMessage(Message* message, const FieldDescriptor* field,
|
|
||||||
MessageFactory* factory = NULL) const;
|
|
||||||
|
|
||||||
const FieldDescriptor* FindKnownExtensionByName(const string& name) const;
|
|
||||||
const FieldDescriptor* FindKnownExtensionByNumber(int number) const;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual void* MutableRawRepeatedField(
|
|
||||||
Message* message, const FieldDescriptor* field, FieldDescriptor::CppType,
|
|
||||||
int ctype, const Descriptor* desc) const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
friend class GeneratedMessage;
|
|
||||||
|
|
||||||
// To parse directly into a proto2 generated class, the class GMR_Handlers
|
|
||||||
// needs access to member offsets and hasbits.
|
|
||||||
friend class LIBPROTOBUF_EXPORT upb::google_opensource::GMR_Handlers;
|
|
||||||
|
|
||||||
const Descriptor* descriptor_;
|
|
||||||
const Message* default_instance_;
|
|
||||||
const void* default_oneof_instance_;
|
|
||||||
const int* offsets_;
|
|
||||||
|
|
||||||
int has_bits_offset_;
|
|
||||||
int oneof_case_offset_;
|
|
||||||
int unknown_fields_offset_;
|
|
||||||
int extensions_offset_;
|
|
||||||
int object_size_;
|
|
||||||
|
|
||||||
const DescriptorPool* descriptor_pool_;
|
|
||||||
MessageFactory* message_factory_;
|
|
||||||
|
|
||||||
template <typename Type>
|
|
||||||
inline const Type& GetRaw(const Message& message,
|
|
||||||
const FieldDescriptor* field) const;
|
|
||||||
template <typename Type>
|
|
||||||
inline Type* MutableRaw(Message* message,
|
|
||||||
const FieldDescriptor* field) const;
|
|
||||||
template <typename Type>
|
|
||||||
inline const Type& DefaultRaw(const FieldDescriptor* field) const;
|
|
||||||
template <typename Type>
|
|
||||||
inline const Type& DefaultOneofRaw(const FieldDescriptor* field) const;
|
|
||||||
|
|
||||||
inline const uint32* GetHasBits(const Message& message) const;
|
|
||||||
inline uint32* MutableHasBits(Message* message) const;
|
|
||||||
inline uint32 GetOneofCase(
|
|
||||||
const Message& message,
|
|
||||||
const OneofDescriptor* oneof_descriptor) const;
|
|
||||||
inline uint32* MutableOneofCase(
|
|
||||||
Message* message,
|
|
||||||
const OneofDescriptor* oneof_descriptor) const;
|
|
||||||
inline const ExtensionSet& GetExtensionSet(const Message& message) const;
|
|
||||||
inline ExtensionSet* MutableExtensionSet(Message* message) const;
|
|
||||||
|
|
||||||
inline bool HasBit(const Message& message,
|
|
||||||
const FieldDescriptor* field) const;
|
|
||||||
inline void SetBit(Message* message,
|
|
||||||
const FieldDescriptor* field) const;
|
|
||||||
inline void ClearBit(Message* message,
|
|
||||||
const FieldDescriptor* field) const;
|
|
||||||
inline void SwapBit(Message* message1,
|
|
||||||
Message* message2,
|
|
||||||
const FieldDescriptor* field) const;
|
|
||||||
|
|
||||||
// This function only swaps the field. Should swap corresponding has_bit
|
|
||||||
// before or after using this function.
|
|
||||||
void SwapField(Message* message1,
|
|
||||||
Message* message2,
|
|
||||||
const FieldDescriptor* field) const;
|
|
||||||
|
|
||||||
void SwapOneofField(Message* message1,
|
|
||||||
Message* message2,
|
|
||||||
const OneofDescriptor* oneof_descriptor) const;
|
|
||||||
|
|
||||||
inline bool HasOneofField(const Message& message,
|
|
||||||
const FieldDescriptor* field) const;
|
|
||||||
inline void SetOneofCase(Message* message,
|
|
||||||
const FieldDescriptor* field) const;
|
|
||||||
inline void ClearOneofField(Message* message,
|
|
||||||
const FieldDescriptor* field) const;
|
|
||||||
|
|
||||||
template <typename Type>
|
|
||||||
inline const Type& GetField(const Message& message,
|
|
||||||
const FieldDescriptor* field) const;
|
|
||||||
template <typename Type>
|
|
||||||
inline void SetField(Message* message,
|
|
||||||
const FieldDescriptor* field, const Type& value) const;
|
|
||||||
template <typename Type>
|
|
||||||
inline Type* MutableField(Message* message,
|
|
||||||
const FieldDescriptor* field) const;
|
|
||||||
template <typename Type>
|
|
||||||
inline const Type& GetRepeatedField(const Message& message,
|
|
||||||
const FieldDescriptor* field,
|
|
||||||
int index) const;
|
|
||||||
template <typename Type>
|
|
||||||
inline const Type& GetRepeatedPtrField(const Message& message,
|
|
||||||
const FieldDescriptor* field,
|
|
||||||
int index) const;
|
|
||||||
template <typename Type>
|
|
||||||
inline void SetRepeatedField(Message* message,
|
|
||||||
const FieldDescriptor* field, int index,
|
|
||||||
Type value) const;
|
|
||||||
template <typename Type>
|
|
||||||
inline Type* MutableRepeatedField(Message* message,
|
|
||||||
const FieldDescriptor* field,
|
|
||||||
int index) const;
|
|
||||||
template <typename Type>
|
|
||||||
inline void AddField(Message* message,
|
|
||||||
const FieldDescriptor* field, const Type& value) const;
|
|
||||||
template <typename Type>
|
|
||||||
inline Type* AddField(Message* message,
|
|
||||||
const FieldDescriptor* field) const;
|
|
||||||
|
|
||||||
int GetExtensionNumberOrDie(const Descriptor* type) const;
|
|
||||||
|
|
||||||
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(GeneratedMessageReflection);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Returns the offset of the given field within the given aggregate type.
|
|
||||||
// This is equivalent to the ANSI C offsetof() macro. However, according
|
|
||||||
// to the C++ standard, offsetof() only works on POD types, and GCC
|
|
||||||
// enforces this requirement with a warning. In practice, this rule is
|
|
||||||
// unnecessarily strict; there is probably no compiler or platform on
|
|
||||||
// which the offsets of the direct fields of a class are non-constant.
|
|
||||||
// Fields inherited from superclasses *can* have non-constant offsets,
|
|
||||||
// but that's not what this macro will be used for.
|
|
||||||
//
|
|
||||||
// Note that we calculate relative to the pointer value 16 here since if we
|
|
||||||
// just use zero, GCC complains about dereferencing a NULL pointer. We
|
|
||||||
// choose 16 rather than some other number just in case the compiler would
|
|
||||||
// be confused by an unaligned pointer.
|
|
||||||
#define GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(TYPE, FIELD) \
|
|
||||||
static_cast<int>( \
|
|
||||||
reinterpret_cast<const char*>( \
|
|
||||||
&reinterpret_cast<const TYPE*>(16)->FIELD) - \
|
|
||||||
reinterpret_cast<const char*>(16))
|
|
||||||
|
|
||||||
#define PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET(ONEOF, FIELD) \
|
|
||||||
static_cast<int>( \
|
|
||||||
reinterpret_cast<const char*>(&(ONEOF->FIELD)) \
|
|
||||||
- reinterpret_cast<const char*>(ONEOF))
|
|
||||||
|
|
||||||
// There are some places in proto2 where dynamic_cast would be useful as an
|
|
||||||
// optimization. For example, take Message::MergeFrom(const Message& other).
|
|
||||||
// For a given generated message FooMessage, we generate these two methods:
|
|
||||||
// void MergeFrom(const FooMessage& other);
|
|
||||||
// void MergeFrom(const Message& other);
|
|
||||||
// The former method can be implemented directly in terms of FooMessage's
|
|
||||||
// inline accessors, but the latter method must work with the reflection
|
|
||||||
// interface. However, if the parameter to the latter method is actually of
|
|
||||||
// type FooMessage, then we'd like to be able to just call the other method
|
|
||||||
// as an optimization. So, we use dynamic_cast to check this.
|
|
||||||
//
|
|
||||||
// That said, dynamic_cast requires RTTI, which many people like to disable
|
|
||||||
// for performance and code size reasons. When RTTI is not available, we
|
|
||||||
// still need to produce correct results. So, in this case we have to fall
|
|
||||||
// back to using reflection, which is what we would have done anyway if the
|
|
||||||
// objects were not of the exact same class.
|
|
||||||
//
|
|
||||||
// dynamic_cast_if_available() implements this logic. If RTTI is
|
|
||||||
// enabled, it does a dynamic_cast. If RTTI is disabled, it just returns
|
|
||||||
// NULL.
|
|
||||||
//
|
|
||||||
// If you need to compile without RTTI, simply #define GOOGLE_PROTOBUF_NO_RTTI.
|
|
||||||
// On MSVC, this should be detected automatically.
|
|
||||||
template<typename To, typename From>
|
|
||||||
inline To dynamic_cast_if_available(From from) {
|
|
||||||
#if defined(GOOGLE_PROTOBUF_NO_RTTI) || (defined(_MSC_VER)&&!defined(_CPPRTTI))
|
|
||||||
return NULL;
|
|
||||||
#else
|
|
||||||
return dynamic_cast<To>(from);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace internal
|
|
||||||
} // namespace protobuf
|
|
||||||
|
|
||||||
} // namespace google
|
|
||||||
#endif // GOOGLE_PROTOBUF_GENERATED_MESSAGE_REFLECTION_H__
|
|
|
@ -1,113 +0,0 @@
|
||||||
// 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.
|
|
||||||
|
|
||||||
// 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 <assert.h>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include <google/protobuf/stubs/once.h>
|
|
||||||
|
|
||||||
#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();
|
|
||||||
|
|
||||||
// TODO(jieluo): Change to template. We have tried to use template,
|
|
||||||
// but it causes net/rpc/python:rpcutil_test fail (the empty string will
|
|
||||||
// init twice). It may related to swig. Change to template after we
|
|
||||||
// found the solution.
|
|
||||||
|
|
||||||
// Default empty string object. Don't use the pointer directly. Instead, call
|
|
||||||
// GetEmptyString() to get the reference.
|
|
||||||
LIBPROTOBUF_EXPORT extern const ::std::string* empty_string_;
|
|
||||||
LIBPROTOBUF_EXPORT extern ProtobufOnceType empty_string_once_init_;
|
|
||||||
LIBPROTOBUF_EXPORT void InitEmptyString();
|
|
||||||
|
|
||||||
|
|
||||||
LIBPROTOBUF_EXPORT inline const ::std::string& GetEmptyStringAlreadyInited() {
|
|
||||||
assert(empty_string_ != NULL);
|
|
||||||
return *empty_string_;
|
|
||||||
}
|
|
||||||
LIBPROTOBUF_EXPORT inline const ::std::string& GetEmptyString() {
|
|
||||||
::google::protobuf::GoogleOnceInit(&empty_string_once_init_, &InitEmptyString);
|
|
||||||
return GetEmptyStringAlreadyInited();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Defined in generated_message_reflection.cc -- not actually part of the lite
|
|
||||||
// library.
|
|
||||||
//
|
|
||||||
// TODO(jasonh): The various callers get this declaration from a variety of
|
|
||||||
// places: probably in most cases repeated_field.h. Clean these up so they all
|
|
||||||
// get the declaration from this file.
|
|
||||||
LIBPROTOBUF_EXPORT int StringSpaceUsedExcludingSelf(const string& str);
|
|
||||||
|
|
||||||
|
|
||||||
// True if IsInitialized() is true for all elements of t. Type is expected
|
|
||||||
// to be a RepeatedPtrField<some message type>. It's useful to have this
|
|
||||||
// helper here to keep the protobuf compiler from ever having to emit loops in
|
|
||||||
// IsInitialized() methods. We want the C++ compiler to inline this or not
|
|
||||||
// as it sees fit.
|
|
||||||
template <class Type> bool AllAreInitialized(const Type& t) {
|
|
||||||
for (int i = t.size(); --i >= 0; ) {
|
|
||||||
if (!t.Get(i).IsInitialized()) return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace internal
|
|
||||||
} // namespace protobuf
|
|
||||||
|
|
||||||
} // namespace google
|
|
||||||
#endif // GOOGLE_PROTOBUF_GENERATED_MESSAGE_UTIL_H__
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,209 +0,0 @@
|
||||||
// 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.
|
|
||||||
|
|
||||||
// Author: brianolson@google.com (Brian Olson)
|
|
||||||
//
|
|
||||||
// This file contains the definition for classes GzipInputStream and
|
|
||||||
// GzipOutputStream.
|
|
||||||
//
|
|
||||||
// GzipInputStream decompresses data from an underlying
|
|
||||||
// ZeroCopyInputStream and provides the decompressed data as a
|
|
||||||
// ZeroCopyInputStream.
|
|
||||||
//
|
|
||||||
// GzipOutputStream is an ZeroCopyOutputStream that compresses data to
|
|
||||||
// an underlying ZeroCopyOutputStream.
|
|
||||||
|
|
||||||
#ifndef GOOGLE_PROTOBUF_IO_GZIP_STREAM_H__
|
|
||||||
#define GOOGLE_PROTOBUF_IO_GZIP_STREAM_H__
|
|
||||||
|
|
||||||
#include <zlib.h>
|
|
||||||
|
|
||||||
#include <google/protobuf/stubs/common.h>
|
|
||||||
#include <google/protobuf/io/zero_copy_stream.h>
|
|
||||||
|
|
||||||
namespace google {
|
|
||||||
namespace protobuf {
|
|
||||||
namespace io {
|
|
||||||
|
|
||||||
// A ZeroCopyInputStream that reads compressed data through zlib
|
|
||||||
class LIBPROTOBUF_EXPORT GzipInputStream : public ZeroCopyInputStream {
|
|
||||||
public:
|
|
||||||
// Format key for constructor
|
|
||||||
enum Format {
|
|
||||||
// zlib will autodetect gzip header or deflate stream
|
|
||||||
AUTO = 0,
|
|
||||||
|
|
||||||
// GZIP streams have some extra header data for file attributes.
|
|
||||||
GZIP = 1,
|
|
||||||
|
|
||||||
// Simpler zlib stream format.
|
|
||||||
ZLIB = 2,
|
|
||||||
};
|
|
||||||
|
|
||||||
// buffer_size and format may be -1 for default of 64kB and GZIP format
|
|
||||||
explicit GzipInputStream(
|
|
||||||
ZeroCopyInputStream* sub_stream,
|
|
||||||
Format format = AUTO,
|
|
||||||
int buffer_size = -1);
|
|
||||||
virtual ~GzipInputStream();
|
|
||||||
|
|
||||||
// Return last error message or NULL if no error.
|
|
||||||
inline const char* ZlibErrorMessage() const {
|
|
||||||
return zcontext_.msg;
|
|
||||||
}
|
|
||||||
inline int ZlibErrorCode() const {
|
|
||||||
return zerror_;
|
|
||||||
}
|
|
||||||
|
|
||||||
// implements ZeroCopyInputStream ----------------------------------
|
|
||||||
bool Next(const void** data, int* size);
|
|
||||||
void BackUp(int count);
|
|
||||||
bool Skip(int count);
|
|
||||||
int64 ByteCount() const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
Format format_;
|
|
||||||
|
|
||||||
ZeroCopyInputStream* sub_stream_;
|
|
||||||
|
|
||||||
z_stream zcontext_;
|
|
||||||
int zerror_;
|
|
||||||
|
|
||||||
void* output_buffer_;
|
|
||||||
void* output_position_;
|
|
||||||
size_t output_buffer_length_;
|
|
||||||
|
|
||||||
int Inflate(int flush);
|
|
||||||
void DoNextOutput(const void** data, int* size);
|
|
||||||
|
|
||||||
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(GzipInputStream);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class LIBPROTOBUF_EXPORT GzipOutputStream : public ZeroCopyOutputStream {
|
|
||||||
public:
|
|
||||||
// Format key for constructor
|
|
||||||
enum Format {
|
|
||||||
// GZIP streams have some extra header data for file attributes.
|
|
||||||
GZIP = 1,
|
|
||||||
|
|
||||||
// Simpler zlib stream format.
|
|
||||||
ZLIB = 2,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Options {
|
|
||||||
// Defaults to GZIP.
|
|
||||||
Format format;
|
|
||||||
|
|
||||||
// What size buffer to use internally. Defaults to 64kB.
|
|
||||||
int buffer_size;
|
|
||||||
|
|
||||||
// A number between 0 and 9, where 0 is no compression and 9 is best
|
|
||||||
// compression. Defaults to Z_DEFAULT_COMPRESSION (see zlib.h).
|
|
||||||
int compression_level;
|
|
||||||
|
|
||||||
// Defaults to Z_DEFAULT_STRATEGY. Can also be set to Z_FILTERED,
|
|
||||||
// Z_HUFFMAN_ONLY, or Z_RLE. See the documentation for deflateInit2 in
|
|
||||||
// zlib.h for definitions of these constants.
|
|
||||||
int compression_strategy;
|
|
||||||
|
|
||||||
Options(); // Initializes with default values.
|
|
||||||
};
|
|
||||||
|
|
||||||
// Create a GzipOutputStream with default options.
|
|
||||||
explicit GzipOutputStream(ZeroCopyOutputStream* sub_stream);
|
|
||||||
|
|
||||||
// Create a GzipOutputStream with the given options.
|
|
||||||
GzipOutputStream(
|
|
||||||
ZeroCopyOutputStream* sub_stream,
|
|
||||||
const Options& options);
|
|
||||||
|
|
||||||
virtual ~GzipOutputStream();
|
|
||||||
|
|
||||||
// Return last error message or NULL if no error.
|
|
||||||
inline const char* ZlibErrorMessage() const {
|
|
||||||
return zcontext_.msg;
|
|
||||||
}
|
|
||||||
inline int ZlibErrorCode() const {
|
|
||||||
return zerror_;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Flushes data written so far to zipped data in the underlying stream.
|
|
||||||
// It is the caller's responsibility to flush the underlying stream if
|
|
||||||
// necessary.
|
|
||||||
// Compression may be less efficient stopping and starting around flushes.
|
|
||||||
// Returns true if no error.
|
|
||||||
//
|
|
||||||
// Please ensure that block size is > 6. Here is an excerpt from the zlib
|
|
||||||
// doc that explains why:
|
|
||||||
//
|
|
||||||
// In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that avail_out
|
|
||||||
// is greater than six to avoid repeated flush markers due to
|
|
||||||
// avail_out == 0 on return.
|
|
||||||
bool Flush();
|
|
||||||
|
|
||||||
// Writes out all data and closes the gzip stream.
|
|
||||||
// It is the caller's responsibility to close the underlying stream if
|
|
||||||
// necessary.
|
|
||||||
// Returns true if no error.
|
|
||||||
bool Close();
|
|
||||||
|
|
||||||
// implements ZeroCopyOutputStream ---------------------------------
|
|
||||||
bool Next(void** data, int* size);
|
|
||||||
void BackUp(int count);
|
|
||||||
int64 ByteCount() const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
ZeroCopyOutputStream* sub_stream_;
|
|
||||||
// Result from calling Next() on sub_stream_
|
|
||||||
void* sub_data_;
|
|
||||||
int sub_data_size_;
|
|
||||||
|
|
||||||
z_stream zcontext_;
|
|
||||||
int zerror_;
|
|
||||||
void* input_buffer_;
|
|
||||||
size_t input_buffer_length_;
|
|
||||||
|
|
||||||
// Shared constructor code.
|
|
||||||
void Init(ZeroCopyOutputStream* sub_stream, const Options& options);
|
|
||||||
|
|
||||||
// Do some compression.
|
|
||||||
// Takes zlib flush mode.
|
|
||||||
// Returns zlib error code.
|
|
||||||
int Deflate(int flush);
|
|
||||||
|
|
||||||
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(GzipOutputStream);
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace io
|
|
||||||
} // namespace protobuf
|
|
||||||
|
|
||||||
} // namespace google
|
|
||||||
#endif // GOOGLE_PROTOBUF_IO_GZIP_STREAM_H__
|
|
|
@ -1,136 +0,0 @@
|
||||||
// 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.
|
|
||||||
|
|
||||||
// Author: kenton@google.com (Kenton Varda)
|
|
||||||
// Based on original Protocol Buffers design by
|
|
||||||
// Sanjay Ghemawat, Jeff Dean, and others.
|
|
||||||
//
|
|
||||||
// Utility class for writing text to a ZeroCopyOutputStream.
|
|
||||||
|
|
||||||
#ifndef GOOGLE_PROTOBUF_IO_PRINTER_H__
|
|
||||||
#define GOOGLE_PROTOBUF_IO_PRINTER_H__
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <map>
|
|
||||||
#include <google/protobuf/stubs/common.h>
|
|
||||||
|
|
||||||
namespace google {
|
|
||||||
namespace protobuf {
|
|
||||||
namespace io {
|
|
||||||
|
|
||||||
class ZeroCopyOutputStream; // zero_copy_stream.h
|
|
||||||
|
|
||||||
// This simple utility class assists in code generation. It basically
|
|
||||||
// allows the caller to define a set of variables and then output some
|
|
||||||
// text with variable substitutions. Example usage:
|
|
||||||
//
|
|
||||||
// Printer printer(output, '$');
|
|
||||||
// map<string, string> vars;
|
|
||||||
// vars["name"] = "Bob";
|
|
||||||
// printer.Print(vars, "My name is $name$.");
|
|
||||||
//
|
|
||||||
// The above writes "My name is Bob." to the output stream.
|
|
||||||
//
|
|
||||||
// Printer aggressively enforces correct usage, crashing (with assert failures)
|
|
||||||
// in the case of undefined variables in debug builds. This helps greatly in
|
|
||||||
// debugging code which uses it.
|
|
||||||
class LIBPROTOBUF_EXPORT Printer {
|
|
||||||
public:
|
|
||||||
// Create a printer that writes text to the given output stream. Use the
|
|
||||||
// given character as the delimiter for variables.
|
|
||||||
Printer(ZeroCopyOutputStream* output, char variable_delimiter);
|
|
||||||
~Printer();
|
|
||||||
|
|
||||||
// Print some text after applying variable substitutions. If a particular
|
|
||||||
// variable in the text is not defined, this will crash. Variables to be
|
|
||||||
// substituted are identified by their names surrounded by delimiter
|
|
||||||
// characters (as given to the constructor). The variable bindings are
|
|
||||||
// defined by the given map.
|
|
||||||
void Print(const map<string, string>& variables, const char* text);
|
|
||||||
|
|
||||||
// Like the first Print(), except the substitutions are given as parameters.
|
|
||||||
void Print(const char* text);
|
|
||||||
// Like the first Print(), except the substitutions are given as parameters.
|
|
||||||
void Print(const char* text, const char* variable, const string& value);
|
|
||||||
// Like the first Print(), except the substitutions are given as parameters.
|
|
||||||
void Print(const char* text, const char* variable1, const string& value1,
|
|
||||||
const char* variable2, const string& value2);
|
|
||||||
// Like the first Print(), except the substitutions are given as parameters.
|
|
||||||
void Print(const char* text, const char* variable1, const string& value1,
|
|
||||||
const char* variable2, const string& value2,
|
|
||||||
const char* variable3, const string& value3);
|
|
||||||
// TODO(kenton): Overloaded versions with more variables? Three seems
|
|
||||||
// to be enough.
|
|
||||||
|
|
||||||
// Indent text by two spaces. After calling Indent(), two spaces will be
|
|
||||||
// inserted at the beginning of each line of text. Indent() may be called
|
|
||||||
// multiple times to produce deeper indents.
|
|
||||||
void Indent();
|
|
||||||
|
|
||||||
// Reduces the current indent level by two spaces, or crashes if the indent
|
|
||||||
// level is zero.
|
|
||||||
void Outdent();
|
|
||||||
|
|
||||||
// Write a string to the output buffer.
|
|
||||||
// This method does not look for newlines to add indentation.
|
|
||||||
void PrintRaw(const string& data);
|
|
||||||
|
|
||||||
// Write a zero-delimited string to output buffer.
|
|
||||||
// This method does not look for newlines to add indentation.
|
|
||||||
void PrintRaw(const char* data);
|
|
||||||
|
|
||||||
// Write some bytes to the output buffer.
|
|
||||||
// This method does not look for newlines to add indentation.
|
|
||||||
void WriteRaw(const char* data, int size);
|
|
||||||
|
|
||||||
// True if any write to the underlying stream failed. (We don't just
|
|
||||||
// crash in this case because this is an I/O failure, not a programming
|
|
||||||
// error.)
|
|
||||||
bool failed() const { return failed_; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
const char variable_delimiter_;
|
|
||||||
|
|
||||||
ZeroCopyOutputStream* const output_;
|
|
||||||
char* buffer_;
|
|
||||||
int buffer_size_;
|
|
||||||
|
|
||||||
string indent_;
|
|
||||||
bool at_start_of_line_;
|
|
||||||
bool failed_;
|
|
||||||
|
|
||||||
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Printer);
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace io
|
|
||||||
} // namespace protobuf
|
|
||||||
|
|
||||||
} // namespace google
|
|
||||||
#endif // GOOGLE_PROTOBUF_IO_PRINTER_H__
|
|
|
@ -1,50 +0,0 @@
|
||||||
// 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.
|
|
||||||
|
|
||||||
// A locale-independent version of strtod(), used to parse floating
|
|
||||||
// point default values in .proto files, where the decimal separator
|
|
||||||
// is always a dot.
|
|
||||||
|
|
||||||
#ifndef GOOGLE_PROTOBUF_IO_STRTOD_H__
|
|
||||||
#define GOOGLE_PROTOBUF_IO_STRTOD_H__
|
|
||||||
|
|
||||||
namespace google {
|
|
||||||
namespace protobuf {
|
|
||||||
namespace io {
|
|
||||||
|
|
||||||
// A locale-independent version of the standard strtod(), which always
|
|
||||||
// uses a dot as the decimal separator.
|
|
||||||
double NoLocaleStrtod(const char* str, char** endptr);
|
|
||||||
|
|
||||||
} // namespace io
|
|
||||||
} // namespace protobuf
|
|
||||||
|
|
||||||
} // namespace google
|
|
||||||
#endif // GOOGLE_PROTOBUF_IO_STRTOD_H__
|
|
|
@ -1,402 +0,0 @@
|
||||||
// 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.
|
|
||||||
|
|
||||||
// Author: kenton@google.com (Kenton Varda)
|
|
||||||
// Based on original Protocol Buffers design by
|
|
||||||
// Sanjay Ghemawat, Jeff Dean, and others.
|
|
||||||
//
|
|
||||||
// Class for parsing tokenized text from a ZeroCopyInputStream.
|
|
||||||
|
|
||||||
#ifndef GOOGLE_PROTOBUF_IO_TOKENIZER_H__
|
|
||||||
#define GOOGLE_PROTOBUF_IO_TOKENIZER_H__
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
#include <google/protobuf/stubs/common.h>
|
|
||||||
|
|
||||||
namespace google {
|
|
||||||
namespace protobuf {
|
|
||||||
namespace io {
|
|
||||||
|
|
||||||
class ZeroCopyInputStream; // zero_copy_stream.h
|
|
||||||
|
|
||||||
// Defined in this file.
|
|
||||||
class ErrorCollector;
|
|
||||||
class Tokenizer;
|
|
||||||
|
|
||||||
// Abstract interface for an object which collects the errors that occur
|
|
||||||
// during parsing. A typical implementation might simply print the errors
|
|
||||||
// to stdout.
|
|
||||||
class LIBPROTOBUF_EXPORT ErrorCollector {
|
|
||||||
public:
|
|
||||||
inline ErrorCollector() {}
|
|
||||||
virtual ~ErrorCollector();
|
|
||||||
|
|
||||||
// Indicates that there was an error in the input at the given line and
|
|
||||||
// column numbers. The numbers are zero-based, so you may want to add
|
|
||||||
// 1 to each before printing them.
|
|
||||||
virtual void AddError(int line, int column, const string& message) = 0;
|
|
||||||
|
|
||||||
// Indicates that there was a warning in the input at the given line and
|
|
||||||
// column numbers. The numbers are zero-based, so you may want to add
|
|
||||||
// 1 to each before printing them.
|
|
||||||
virtual void AddWarning(int /* line */, int /* column */,
|
|
||||||
const string& /* message */) { }
|
|
||||||
|
|
||||||
private:
|
|
||||||
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ErrorCollector);
|
|
||||||
};
|
|
||||||
|
|
||||||
// This class converts a stream of raw text into a stream of tokens for
|
|
||||||
// the protocol definition parser to parse. The tokens recognized are
|
|
||||||
// similar to those that make up the C language; see the TokenType enum for
|
|
||||||
// precise descriptions. Whitespace and comments are skipped. By default,
|
|
||||||
// C- and C++-style comments are recognized, but other styles can be used by
|
|
||||||
// calling set_comment_style().
|
|
||||||
class LIBPROTOBUF_EXPORT Tokenizer {
|
|
||||||
public:
|
|
||||||
// Construct a Tokenizer that reads and tokenizes text from the given
|
|
||||||
// input stream and writes errors to the given error_collector.
|
|
||||||
// The caller keeps ownership of input and error_collector.
|
|
||||||
Tokenizer(ZeroCopyInputStream* input, ErrorCollector* error_collector);
|
|
||||||
~Tokenizer();
|
|
||||||
|
|
||||||
enum TokenType {
|
|
||||||
TYPE_START, // Next() has not yet been called.
|
|
||||||
TYPE_END, // End of input reached. "text" is empty.
|
|
||||||
|
|
||||||
TYPE_IDENTIFIER, // A sequence of letters, digits, and underscores, not
|
|
||||||
// starting with a digit. It is an error for a number
|
|
||||||
// to be followed by an identifier with no space in
|
|
||||||
// between.
|
|
||||||
TYPE_INTEGER, // A sequence of digits representing an integer. Normally
|
|
||||||
// the digits are decimal, but a prefix of "0x" indicates
|
|
||||||
// a hex number and a leading zero indicates octal, just
|
|
||||||
// like with C numeric literals. A leading negative sign
|
|
||||||
// is NOT included in the token; it's up to the parser to
|
|
||||||
// interpret the unary minus operator on its own.
|
|
||||||
TYPE_FLOAT, // A floating point literal, with a fractional part and/or
|
|
||||||
// an exponent. Always in decimal. Again, never
|
|
||||||
// negative.
|
|
||||||
TYPE_STRING, // A quoted sequence of escaped characters. Either single
|
|
||||||
// or double quotes can be used, but they must match.
|
|
||||||
// A string literal cannot cross a line break.
|
|
||||||
TYPE_SYMBOL, // Any other printable character, like '!' or '+'.
|
|
||||||
// Symbols are always a single character, so "!+$%" is
|
|
||||||
// four tokens.
|
|
||||||
};
|
|
||||||
|
|
||||||
// Structure representing a token read from the token stream.
|
|
||||||
struct Token {
|
|
||||||
TokenType type;
|
|
||||||
string text; // The exact text of the token as it appeared in
|
|
||||||
// the input. e.g. tokens of TYPE_STRING will still
|
|
||||||
// be escaped and in quotes.
|
|
||||||
|
|
||||||
// "line" and "column" specify the position of the first character of
|
|
||||||
// the token within the input stream. They are zero-based.
|
|
||||||
int line;
|
|
||||||
int column;
|
|
||||||
int end_column;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Get the current token. This is updated when Next() is called. Before
|
|
||||||
// the first call to Next(), current() has type TYPE_START and no contents.
|
|
||||||
const Token& current();
|
|
||||||
|
|
||||||
// Return the previous token -- i.e. what current() returned before the
|
|
||||||
// previous call to Next().
|
|
||||||
const Token& previous();
|
|
||||||
|
|
||||||
// Advance to the next token. Returns false if the end of the input is
|
|
||||||
// reached.
|
|
||||||
bool Next();
|
|
||||||
|
|
||||||
// Like Next(), but also collects comments which appear between the previous
|
|
||||||
// and next tokens.
|
|
||||||
//
|
|
||||||
// Comments which appear to be attached to the previous token are stored
|
|
||||||
// in *prev_tailing_comments. Comments which appear to be attached to the
|
|
||||||
// next token are stored in *next_leading_comments. Comments appearing in
|
|
||||||
// between which do not appear to be attached to either will be added to
|
|
||||||
// detached_comments. Any of these parameters can be NULL to simply discard
|
|
||||||
// the comments.
|
|
||||||
//
|
|
||||||
// A series of line comments appearing on consecutive lines, with no other
|
|
||||||
// tokens appearing on those lines, will be treated as a single comment.
|
|
||||||
//
|
|
||||||
// Only the comment content is returned; comment markers (e.g. //) are
|
|
||||||
// stripped out. For block comments, leading whitespace and an asterisk will
|
|
||||||
// be stripped from the beginning of each line other than the first. Newlines
|
|
||||||
// are included in the output.
|
|
||||||
//
|
|
||||||
// Examples:
|
|
||||||
//
|
|
||||||
// optional int32 foo = 1; // Comment attached to foo.
|
|
||||||
// // Comment attached to bar.
|
|
||||||
// optional int32 bar = 2;
|
|
||||||
//
|
|
||||||
// optional string baz = 3;
|
|
||||||
// // Comment attached to baz.
|
|
||||||
// // Another line attached to baz.
|
|
||||||
//
|
|
||||||
// // Comment attached to qux.
|
|
||||||
// //
|
|
||||||
// // Another line attached to qux.
|
|
||||||
// optional double qux = 4;
|
|
||||||
//
|
|
||||||
// // Detached comment. This is not attached to qux or corge
|
|
||||||
// // because there are blank lines separating it from both.
|
|
||||||
//
|
|
||||||
// optional string corge = 5;
|
|
||||||
// /* Block comment attached
|
|
||||||
// * to corge. Leading asterisks
|
|
||||||
// * will be removed. */
|
|
||||||
// /* Block comment attached to
|
|
||||||
// * grault. */
|
|
||||||
// optional int32 grault = 6;
|
|
||||||
bool NextWithComments(string* prev_trailing_comments,
|
|
||||||
vector<string>* detached_comments,
|
|
||||||
string* next_leading_comments);
|
|
||||||
|
|
||||||
// Parse helpers ---------------------------------------------------
|
|
||||||
|
|
||||||
// Parses a TYPE_FLOAT token. This never fails, so long as the text actually
|
|
||||||
// comes from a TYPE_FLOAT token parsed by Tokenizer. If it doesn't, the
|
|
||||||
// result is undefined (possibly an assert failure).
|
|
||||||
static double ParseFloat(const string& text);
|
|
||||||
|
|
||||||
// Parses a TYPE_STRING token. This never fails, so long as the text actually
|
|
||||||
// comes from a TYPE_STRING token parsed by Tokenizer. If it doesn't, the
|
|
||||||
// result is undefined (possibly an assert failure).
|
|
||||||
static void ParseString(const string& text, string* output);
|
|
||||||
|
|
||||||
// Identical to ParseString, but appends to output.
|
|
||||||
static void ParseStringAppend(const string& text, string* output);
|
|
||||||
|
|
||||||
// Parses a TYPE_INTEGER token. Returns false if the result would be
|
|
||||||
// greater than max_value. Otherwise, returns true and sets *output to the
|
|
||||||
// result. If the text is not from a Token of type TYPE_INTEGER originally
|
|
||||||
// parsed by a Tokenizer, the result is undefined (possibly an assert
|
|
||||||
// failure).
|
|
||||||
static bool ParseInteger(const string& text, uint64 max_value,
|
|
||||||
uint64* output);
|
|
||||||
|
|
||||||
// Options ---------------------------------------------------------
|
|
||||||
|
|
||||||
// Set true to allow floats to be suffixed with the letter 'f'. Tokens
|
|
||||||
// which would otherwise be integers but which have the 'f' suffix will be
|
|
||||||
// forced to be interpreted as floats. For all other purposes, the 'f' is
|
|
||||||
// ignored.
|
|
||||||
void set_allow_f_after_float(bool value) { allow_f_after_float_ = value; }
|
|
||||||
|
|
||||||
// Valid values for set_comment_style().
|
|
||||||
enum CommentStyle {
|
|
||||||
// Line comments begin with "//", block comments are delimited by "/*" and
|
|
||||||
// "*/".
|
|
||||||
CPP_COMMENT_STYLE,
|
|
||||||
// Line comments begin with "#". No way to write block comments.
|
|
||||||
SH_COMMENT_STYLE
|
|
||||||
};
|
|
||||||
|
|
||||||
// Sets the comment style.
|
|
||||||
void set_comment_style(CommentStyle style) { comment_style_ = style; }
|
|
||||||
|
|
||||||
// Whether to require whitespace between a number and a field name.
|
|
||||||
// Default is true. Do not use this; for Google-internal cleanup only.
|
|
||||||
void set_require_space_after_number(bool require) {
|
|
||||||
require_space_after_number_ = require;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Whether to allow string literals to span multiple lines. Default is false.
|
|
||||||
// Do not use this; for Google-internal cleanup only.
|
|
||||||
void set_allow_multiline_strings(bool allow) {
|
|
||||||
allow_multiline_strings_ = allow;
|
|
||||||
}
|
|
||||||
|
|
||||||
// External helper: validate an identifier.
|
|
||||||
static bool IsIdentifier(const string& text);
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------
|
|
||||||
private:
|
|
||||||
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Tokenizer);
|
|
||||||
|
|
||||||
Token current_; // Returned by current().
|
|
||||||
Token previous_; // Returned by previous().
|
|
||||||
|
|
||||||
ZeroCopyInputStream* input_;
|
|
||||||
ErrorCollector* error_collector_;
|
|
||||||
|
|
||||||
char current_char_; // == buffer_[buffer_pos_], updated by NextChar().
|
|
||||||
const char* buffer_; // Current buffer returned from input_.
|
|
||||||
int buffer_size_; // Size of buffer_.
|
|
||||||
int buffer_pos_; // Current position within the buffer.
|
|
||||||
bool read_error_; // Did we previously encounter a read error?
|
|
||||||
|
|
||||||
// Line and column number of current_char_ within the whole input stream.
|
|
||||||
int line_;
|
|
||||||
int column_;
|
|
||||||
|
|
||||||
// String to which text should be appended as we advance through it.
|
|
||||||
// Call RecordTo(&str) to start recording and StopRecording() to stop.
|
|
||||||
// E.g. StartToken() calls RecordTo(¤t_.text). record_start_ is the
|
|
||||||
// position within the current buffer where recording started.
|
|
||||||
string* record_target_;
|
|
||||||
int record_start_;
|
|
||||||
|
|
||||||
// Options.
|
|
||||||
bool allow_f_after_float_;
|
|
||||||
CommentStyle comment_style_;
|
|
||||||
bool require_space_after_number_;
|
|
||||||
bool allow_multiline_strings_;
|
|
||||||
|
|
||||||
// Since we count columns we need to interpret tabs somehow. We'll take
|
|
||||||
// the standard 8-character definition for lack of any way to do better.
|
|
||||||
static const int kTabWidth = 8;
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------
|
|
||||||
// Helper methods.
|
|
||||||
|
|
||||||
// Consume this character and advance to the next one.
|
|
||||||
void NextChar();
|
|
||||||
|
|
||||||
// Read a new buffer from the input.
|
|
||||||
void Refresh();
|
|
||||||
|
|
||||||
inline void RecordTo(string* target);
|
|
||||||
inline void StopRecording();
|
|
||||||
|
|
||||||
// Called when the current character is the first character of a new
|
|
||||||
// token (not including whitespace or comments).
|
|
||||||
inline void StartToken();
|
|
||||||
// Called when the current character is the first character after the
|
|
||||||
// end of the last token. After this returns, current_.text will
|
|
||||||
// contain all text consumed since StartToken() was called.
|
|
||||||
inline void EndToken();
|
|
||||||
|
|
||||||
// Convenience method to add an error at the current line and column.
|
|
||||||
void AddError(const string& message) {
|
|
||||||
error_collector_->AddError(line_, column_, message);
|
|
||||||
}
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------
|
|
||||||
// The following four methods are used to consume tokens of specific
|
|
||||||
// types. They are actually used to consume all characters *after*
|
|
||||||
// the first, since the calling function consumes the first character
|
|
||||||
// in order to decide what kind of token is being read.
|
|
||||||
|
|
||||||
// Read and consume a string, ending when the given delimiter is
|
|
||||||
// consumed.
|
|
||||||
void ConsumeString(char delimiter);
|
|
||||||
|
|
||||||
// Read and consume a number, returning TYPE_FLOAT or TYPE_INTEGER
|
|
||||||
// depending on what was read. This needs to know if the first
|
|
||||||
// character was a zero in order to correctly recognize hex and octal
|
|
||||||
// numbers.
|
|
||||||
// It also needs to know if the first characted was a . to parse floating
|
|
||||||
// point correctly.
|
|
||||||
TokenType ConsumeNumber(bool started_with_zero, bool started_with_dot);
|
|
||||||
|
|
||||||
// Consume the rest of a line.
|
|
||||||
void ConsumeLineComment(string* content);
|
|
||||||
// Consume until "*/".
|
|
||||||
void ConsumeBlockComment(string* content);
|
|
||||||
|
|
||||||
enum NextCommentStatus {
|
|
||||||
// Started a line comment.
|
|
||||||
LINE_COMMENT,
|
|
||||||
|
|
||||||
// Started a block comment.
|
|
||||||
BLOCK_COMMENT,
|
|
||||||
|
|
||||||
// Consumed a slash, then realized it wasn't a comment. current_ has
|
|
||||||
// been filled in with a slash token. The caller should return it.
|
|
||||||
SLASH_NOT_COMMENT,
|
|
||||||
|
|
||||||
// We do not appear to be starting a comment here.
|
|
||||||
NO_COMMENT
|
|
||||||
};
|
|
||||||
|
|
||||||
// If we're at the start of a new comment, consume it and return what kind
|
|
||||||
// of comment it is.
|
|
||||||
NextCommentStatus TryConsumeCommentStart();
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------
|
|
||||||
// These helper methods make the parsing code more readable. The
|
|
||||||
// "character classes" refered to are defined at the top of the .cc file.
|
|
||||||
// Basically it is a C++ class with one method:
|
|
||||||
// static bool InClass(char c);
|
|
||||||
// The method returns true if c is a member of this "class", like "Letter"
|
|
||||||
// or "Digit".
|
|
||||||
|
|
||||||
// Returns true if the current character is of the given character
|
|
||||||
// class, but does not consume anything.
|
|
||||||
template<typename CharacterClass>
|
|
||||||
inline bool LookingAt();
|
|
||||||
|
|
||||||
// If the current character is in the given class, consume it and return
|
|
||||||
// true. Otherwise return false.
|
|
||||||
// e.g. TryConsumeOne<Letter>()
|
|
||||||
template<typename CharacterClass>
|
|
||||||
inline bool TryConsumeOne();
|
|
||||||
|
|
||||||
// Like above, but try to consume the specific character indicated.
|
|
||||||
inline bool TryConsume(char c);
|
|
||||||
|
|
||||||
// Consume zero or more of the given character class.
|
|
||||||
template<typename CharacterClass>
|
|
||||||
inline void ConsumeZeroOrMore();
|
|
||||||
|
|
||||||
// Consume one or more of the given character class or log the given
|
|
||||||
// error message.
|
|
||||||
// e.g. ConsumeOneOrMore<Digit>("Expected digits.");
|
|
||||||
template<typename CharacterClass>
|
|
||||||
inline void ConsumeOneOrMore(const char* error);
|
|
||||||
};
|
|
||||||
|
|
||||||
// inline methods ====================================================
|
|
||||||
inline const Tokenizer::Token& Tokenizer::current() {
|
|
||||||
return current_;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline const Tokenizer::Token& Tokenizer::previous() {
|
|
||||||
return previous_;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void Tokenizer::ParseString(const string& text, string* output) {
|
|
||||||
output->clear();
|
|
||||||
ParseStringAppend(text, output);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace io
|
|
||||||
} // namespace protobuf
|
|
||||||
|
|
||||||
} // namespace google
|
|
||||||
#endif // GOOGLE_PROTOBUF_IO_TOKENIZER_H__
|
|
|
@ -1,248 +0,0 @@
|
||||||
// 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.
|
|
||||||
|
|
||||||
// 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;
|
|
||||||
|
|
||||||
// Write a given chunk of data to the output. Some output streams may
|
|
||||||
// implement this in a way that avoids copying. Check AllowsAliasing() before
|
|
||||||
// calling WriteAliasedRaw(). It will GOOGLE_CHECK fail if WriteAliasedRaw() is
|
|
||||||
// called on a stream that does not allow aliasing.
|
|
||||||
//
|
|
||||||
// NOTE: It is caller's responsibility to ensure that the chunk of memory
|
|
||||||
// remains live until all of the data has been consumed from the stream.
|
|
||||||
virtual bool WriteAliasedRaw(const void* data, int size);
|
|
||||||
virtual bool AllowsAliasing() const { return false; }
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
|
||||||
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ZeroCopyOutputStream);
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace io
|
|
||||||
} // namespace protobuf
|
|
||||||
|
|
||||||
} // namespace google
|
|
||||||
#endif // GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_H__
|
|
|
@ -1,358 +0,0 @@
|
||||||
// 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.
|
|
||||||
|
|
||||||
// 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.
|
|
||||||
int64 prior_bytes_read_; // Bytes read on underlying stream at construction
|
|
||||||
|
|
||||||
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(LimitingInputStream);
|
|
||||||
};
|
|
||||||
|
|
||||||
// ===================================================================
|
|
||||||
|
|
||||||
} // namespace io
|
|
||||||
} // namespace protobuf
|
|
||||||
|
|
||||||
} // namespace google
|
|
||||||
#endif // GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_IMPL_H__
|
|
|
@ -1,354 +0,0 @@
|
||||||
// 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.
|
|
||||||
|
|
||||||
// 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>
|
|
||||||
#include <google/protobuf/stubs/stl_util.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);
|
|
||||||
};
|
|
||||||
|
|
||||||
// ===================================================================
|
|
||||||
|
|
||||||
// Return a pointer to mutable characters underlying the given string. The
|
|
||||||
// return value is valid until the next time the string is resized. We
|
|
||||||
// trust the caller to treat the return value as an array of length s->size().
|
|
||||||
inline char* mutable_string_data(string* s) {
|
|
||||||
#ifdef LANG_CXX11
|
|
||||||
// This should be simpler & faster than string_as_array() because the latter
|
|
||||||
// is guaranteed to return NULL when *s is empty, so it has to check for that.
|
|
||||||
return &(*s)[0];
|
|
||||||
#else
|
|
||||||
return string_as_array(s);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace io
|
|
||||||
} // namespace protobuf
|
|
||||||
|
|
||||||
} // namespace google
|
|
||||||
#endif // GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_IMPL_LITE_H__
|
|
|
@ -1,866 +0,0 @@
|
||||||
// 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.
|
|
||||||
|
|
||||||
// Author: kenton@google.com (Kenton Varda)
|
|
||||||
// Based on original Protocol Buffers design by
|
|
||||||
// Sanjay Ghemawat, Jeff Dean, and others.
|
|
||||||
//
|
|
||||||
// Defines Message, the abstract interface implemented by non-lite
|
|
||||||
// protocol message objects. Although it's possible to implement this
|
|
||||||
// interface manually, most users will use the protocol compiler to
|
|
||||||
// generate implementations.
|
|
||||||
//
|
|
||||||
// Example usage:
|
|
||||||
//
|
|
||||||
// Say you have a message defined as:
|
|
||||||
//
|
|
||||||
// message Foo {
|
|
||||||
// optional string text = 1;
|
|
||||||
// repeated int32 numbers = 2;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// Then, if you used the protocol compiler to generate a class from the above
|
|
||||||
// definition, you could use it like so:
|
|
||||||
//
|
|
||||||
// string data; // Will store a serialized version of the message.
|
|
||||||
//
|
|
||||||
// {
|
|
||||||
// // Create a message and serialize it.
|
|
||||||
// Foo foo;
|
|
||||||
// foo.set_text("Hello World!");
|
|
||||||
// foo.add_numbers(1);
|
|
||||||
// foo.add_numbers(5);
|
|
||||||
// foo.add_numbers(42);
|
|
||||||
//
|
|
||||||
// foo.SerializeToString(&data);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// {
|
|
||||||
// // Parse the serialized message and check that it contains the
|
|
||||||
// // correct data.
|
|
||||||
// Foo foo;
|
|
||||||
// foo.ParseFromString(data);
|
|
||||||
//
|
|
||||||
// assert(foo.text() == "Hello World!");
|
|
||||||
// assert(foo.numbers_size() == 3);
|
|
||||||
// assert(foo.numbers(0) == 1);
|
|
||||||
// assert(foo.numbers(1) == 5);
|
|
||||||
// assert(foo.numbers(2) == 42);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// {
|
|
||||||
// // Same as the last block, but do it dynamically via the Message
|
|
||||||
// // reflection interface.
|
|
||||||
// Message* foo = new Foo;
|
|
||||||
// const Descriptor* descriptor = foo->GetDescriptor();
|
|
||||||
//
|
|
||||||
// // Get the descriptors for the fields we're interested in and verify
|
|
||||||
// // their types.
|
|
||||||
// const FieldDescriptor* text_field = descriptor->FindFieldByName("text");
|
|
||||||
// assert(text_field != NULL);
|
|
||||||
// assert(text_field->type() == FieldDescriptor::TYPE_STRING);
|
|
||||||
// assert(text_field->label() == FieldDescriptor::LABEL_OPTIONAL);
|
|
||||||
// const FieldDescriptor* numbers_field = descriptor->
|
|
||||||
// FindFieldByName("numbers");
|
|
||||||
// assert(numbers_field != NULL);
|
|
||||||
// assert(numbers_field->type() == FieldDescriptor::TYPE_INT32);
|
|
||||||
// assert(numbers_field->label() == FieldDescriptor::LABEL_REPEATED);
|
|
||||||
//
|
|
||||||
// // Parse the message.
|
|
||||||
// foo->ParseFromString(data);
|
|
||||||
//
|
|
||||||
// // Use the reflection interface to examine the contents.
|
|
||||||
// const Reflection* reflection = foo->GetReflection();
|
|
||||||
// assert(reflection->GetString(foo, text_field) == "Hello World!");
|
|
||||||
// assert(reflection->FieldSize(foo, numbers_field) == 3);
|
|
||||||
// assert(reflection->GetRepeatedInt32(foo, numbers_field, 0) == 1);
|
|
||||||
// assert(reflection->GetRepeatedInt32(foo, numbers_field, 1) == 5);
|
|
||||||
// assert(reflection->GetRepeatedInt32(foo, numbers_field, 2) == 42);
|
|
||||||
//
|
|
||||||
// delete foo;
|
|
||||||
// }
|
|
||||||
|
|
||||||
#ifndef GOOGLE_PROTOBUF_MESSAGE_H__
|
|
||||||
#define GOOGLE_PROTOBUF_MESSAGE_H__
|
|
||||||
|
|
||||||
#include <iosfwd>
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include <google/protobuf/message_lite.h>
|
|
||||||
|
|
||||||
#include <google/protobuf/stubs/common.h>
|
|
||||||
#include <google/protobuf/descriptor.h>
|
|
||||||
|
|
||||||
|
|
||||||
#define GOOGLE_PROTOBUF_HAS_ONEOF
|
|
||||||
|
|
||||||
namespace google {
|
|
||||||
namespace protobuf {
|
|
||||||
|
|
||||||
// Defined in this file.
|
|
||||||
class Message;
|
|
||||||
class Reflection;
|
|
||||||
class MessageFactory;
|
|
||||||
|
|
||||||
// Defined in other files.
|
|
||||||
class UnknownFieldSet; // unknown_field_set.h
|
|
||||||
namespace io {
|
|
||||||
class ZeroCopyInputStream; // zero_copy_stream.h
|
|
||||||
class ZeroCopyOutputStream; // zero_copy_stream.h
|
|
||||||
class CodedInputStream; // coded_stream.h
|
|
||||||
class CodedOutputStream; // coded_stream.h
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
class RepeatedField; // repeated_field.h
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
class RepeatedPtrField; // repeated_field.h
|
|
||||||
|
|
||||||
// A container to hold message metadata.
|
|
||||||
struct Metadata {
|
|
||||||
const Descriptor* descriptor;
|
|
||||||
const Reflection* reflection;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Abstract interface for protocol messages.
|
|
||||||
//
|
|
||||||
// See also MessageLite, which contains most every-day operations. Message
|
|
||||||
// adds descriptors and reflection on top of that.
|
|
||||||
//
|
|
||||||
// The methods of this class that are virtual but not pure-virtual have
|
|
||||||
// default implementations based on reflection. Message classes which are
|
|
||||||
// optimized for speed will want to override these with faster implementations,
|
|
||||||
// but classes optimized for code size may be happy with keeping them. See
|
|
||||||
// the optimize_for option in descriptor.proto.
|
|
||||||
class LIBPROTOBUF_EXPORT Message : public MessageLite {
|
|
||||||
public:
|
|
||||||
inline Message() {}
|
|
||||||
virtual ~Message();
|
|
||||||
|
|
||||||
// Basic Operations ------------------------------------------------
|
|
||||||
|
|
||||||
// Construct a new instance of the same type. Ownership is passed to the
|
|
||||||
// caller. (This is also defined in MessageLite, but is defined again here
|
|
||||||
// for return-type covariance.)
|
|
||||||
virtual Message* New() const = 0;
|
|
||||||
|
|
||||||
// Make this message into a copy of the given message. The given message
|
|
||||||
// must have the same descriptor, but need not necessarily be the same class.
|
|
||||||
// By default this is just implemented as "Clear(); MergeFrom(from);".
|
|
||||||
virtual void CopyFrom(const Message& from);
|
|
||||||
|
|
||||||
// Merge the fields from the given message into this message. Singular
|
|
||||||
// fields will be overwritten, if specified in from, except for embedded
|
|
||||||
// messages which will be merged. Repeated fields will be concatenated.
|
|
||||||
// The given message must be of the same type as this message (i.e. the
|
|
||||||
// exact same class).
|
|
||||||
virtual void MergeFrom(const Message& from);
|
|
||||||
|
|
||||||
// Verifies that IsInitialized() returns true. GOOGLE_CHECK-fails otherwise, with
|
|
||||||
// a nice error message.
|
|
||||||
void CheckInitialized() const;
|
|
||||||
|
|
||||||
// Slowly build a list of all required fields that are not set.
|
|
||||||
// This is much, much slower than IsInitialized() as it is implemented
|
|
||||||
// purely via reflection. Generally, you should not call this unless you
|
|
||||||
// have already determined that an error exists by calling IsInitialized().
|
|
||||||
void FindInitializationErrors(vector<string>* errors) const;
|
|
||||||
|
|
||||||
// Like FindInitializationErrors, but joins all the strings, delimited by
|
|
||||||
// commas, and returns them.
|
|
||||||
string InitializationErrorString() const;
|
|
||||||
|
|
||||||
// Clears all unknown fields from this message and all embedded messages.
|
|
||||||
// Normally, if unknown tag numbers are encountered when parsing a message,
|
|
||||||
// the tag and value are stored in the message's UnknownFieldSet and
|
|
||||||
// then written back out when the message is serialized. This allows servers
|
|
||||||
// which simply route messages to other servers to pass through messages
|
|
||||||
// that have new field definitions which they don't yet know about. However,
|
|
||||||
// this behavior can have security implications. To avoid it, call this
|
|
||||||
// method after parsing.
|
|
||||||
//
|
|
||||||
// See Reflection::GetUnknownFields() for more on unknown fields.
|
|
||||||
virtual void DiscardUnknownFields();
|
|
||||||
|
|
||||||
// Computes (an estimate of) the total number of bytes currently used for
|
|
||||||
// storing the message in memory. The default implementation calls the
|
|
||||||
// Reflection object's SpaceUsed() method.
|
|
||||||
virtual int SpaceUsed() const;
|
|
||||||
|
|
||||||
// Debugging & Testing----------------------------------------------
|
|
||||||
|
|
||||||
// Generates a human readable form of this message, useful for debugging
|
|
||||||
// and other purposes.
|
|
||||||
string DebugString() const;
|
|
||||||
// Like DebugString(), but with less whitespace.
|
|
||||||
string ShortDebugString() const;
|
|
||||||
// Like DebugString(), but do not escape UTF-8 byte sequences.
|
|
||||||
string Utf8DebugString() const;
|
|
||||||
// Convenience function useful in GDB. Prints DebugString() to stdout.
|
|
||||||
void PrintDebugString() const;
|
|
||||||
|
|
||||||
// Heavy I/O -------------------------------------------------------
|
|
||||||
// Additional parsing and serialization methods not implemented by
|
|
||||||
// MessageLite because they are not supported by the lite library.
|
|
||||||
|
|
||||||
// Parse a protocol buffer from a file descriptor. If successful, the entire
|
|
||||||
// input will be consumed.
|
|
||||||
bool ParseFromFileDescriptor(int file_descriptor);
|
|
||||||
// Like ParseFromFileDescriptor(), but accepts messages that are missing
|
|
||||||
// required fields.
|
|
||||||
bool ParsePartialFromFileDescriptor(int file_descriptor);
|
|
||||||
// Parse a protocol buffer from a C++ istream. If successful, the entire
|
|
||||||
// input will be consumed.
|
|
||||||
bool ParseFromIstream(istream* input);
|
|
||||||
// Like ParseFromIstream(), but accepts messages that are missing
|
|
||||||
// required fields.
|
|
||||||
bool ParsePartialFromIstream(istream* input);
|
|
||||||
|
|
||||||
// Serialize the message and write it to the given file descriptor. All
|
|
||||||
// required fields must be set.
|
|
||||||
bool SerializeToFileDescriptor(int file_descriptor) const;
|
|
||||||
// Like SerializeToFileDescriptor(), but allows missing required fields.
|
|
||||||
bool SerializePartialToFileDescriptor(int file_descriptor) const;
|
|
||||||
// Serialize the message and write it to the given C++ ostream. All
|
|
||||||
// required fields must be set.
|
|
||||||
bool SerializeToOstream(ostream* output) const;
|
|
||||||
// Like SerializeToOstream(), but allows missing required fields.
|
|
||||||
bool SerializePartialToOstream(ostream* output) const;
|
|
||||||
|
|
||||||
|
|
||||||
// Reflection-based methods ----------------------------------------
|
|
||||||
// These methods are pure-virtual in MessageLite, but Message provides
|
|
||||||
// reflection-based default implementations.
|
|
||||||
|
|
||||||
virtual string GetTypeName() const;
|
|
||||||
virtual void Clear();
|
|
||||||
virtual bool IsInitialized() const;
|
|
||||||
virtual void CheckTypeAndMergeFrom(const MessageLite& other);
|
|
||||||
virtual bool MergePartialFromCodedStream(io::CodedInputStream* input);
|
|
||||||
virtual int ByteSize() const;
|
|
||||||
virtual void SerializeWithCachedSizes(io::CodedOutputStream* output) const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
// This is called only by the default implementation of ByteSize(), to
|
|
||||||
// update the cached size. If you override ByteSize(), you do not need
|
|
||||||
// to override this. If you do not override ByteSize(), you MUST override
|
|
||||||
// this; the default implementation will crash.
|
|
||||||
//
|
|
||||||
// The method is private because subclasses should never call it; only
|
|
||||||
// override it. Yes, C++ lets you do that. Crazy, huh?
|
|
||||||
virtual void SetCachedSize(int size) const;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
// Introspection ---------------------------------------------------
|
|
||||||
|
|
||||||
// Typedef for backwards-compatibility.
|
|
||||||
typedef google::protobuf::Reflection Reflection;
|
|
||||||
|
|
||||||
// Get a Descriptor for this message's type. This describes what
|
|
||||||
// fields the message contains, the types of those fields, etc.
|
|
||||||
const Descriptor* GetDescriptor() const { return GetMetadata().descriptor; }
|
|
||||||
|
|
||||||
// Get the Reflection interface for this Message, which can be used to
|
|
||||||
// read and modify the fields of the Message dynamically (in other words,
|
|
||||||
// without knowing the message type at compile time). This object remains
|
|
||||||
// property of the Message.
|
|
||||||
//
|
|
||||||
// This method remains virtual in case a subclass does not implement
|
|
||||||
// reflection and wants to override the default behavior.
|
|
||||||
virtual const Reflection* GetReflection() const {
|
|
||||||
return GetMetadata().reflection;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
// Get a struct containing the metadata for the Message. Most subclasses only
|
|
||||||
// need to implement this method, rather than the GetDescriptor() and
|
|
||||||
// GetReflection() wrappers.
|
|
||||||
virtual Metadata GetMetadata() const = 0;
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
|
||||||
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Message);
|
|
||||||
};
|
|
||||||
|
|
||||||
// This interface contains methods that can be used to dynamically access
|
|
||||||
// and modify the fields of a protocol message. Their semantics are
|
|
||||||
// similar to the accessors the protocol compiler generates.
|
|
||||||
//
|
|
||||||
// To get the Reflection for a given Message, call Message::GetReflection().
|
|
||||||
//
|
|
||||||
// This interface is separate from Message only for efficiency reasons;
|
|
||||||
// the vast majority of implementations of Message will share the same
|
|
||||||
// implementation of Reflection (GeneratedMessageReflection,
|
|
||||||
// defined in generated_message.h), and all Messages of a particular class
|
|
||||||
// should share the same Reflection object (though you should not rely on
|
|
||||||
// the latter fact).
|
|
||||||
//
|
|
||||||
// There are several ways that these methods can be used incorrectly. For
|
|
||||||
// example, any of the following conditions will lead to undefined
|
|
||||||
// results (probably assertion failures):
|
|
||||||
// - The FieldDescriptor is not a field of this message type.
|
|
||||||
// - The method called is not appropriate for the field's type. For
|
|
||||||
// each field type in FieldDescriptor::TYPE_*, there is only one
|
|
||||||
// Get*() method, one Set*() method, and one Add*() method that is
|
|
||||||
// valid for that type. It should be obvious which (except maybe
|
|
||||||
// for TYPE_BYTES, which are represented using strings in C++).
|
|
||||||
// - A Get*() or Set*() method for singular fields is called on a repeated
|
|
||||||
// field.
|
|
||||||
// - GetRepeated*(), SetRepeated*(), or Add*() is called on a non-repeated
|
|
||||||
// field.
|
|
||||||
// - The Message object passed to any method is not of the right type for
|
|
||||||
// this Reflection object (i.e. message.GetReflection() != reflection).
|
|
||||||
//
|
|
||||||
// You might wonder why there is not any abstract representation for a field
|
|
||||||
// of arbitrary type. E.g., why isn't there just a "GetField()" method that
|
|
||||||
// returns "const Field&", where "Field" is some class with accessors like
|
|
||||||
// "GetInt32Value()". The problem is that someone would have to deal with
|
|
||||||
// allocating these Field objects. For generated message classes, having to
|
|
||||||
// allocate space for an additional object to wrap every field would at least
|
|
||||||
// double the message's memory footprint, probably worse. Allocating the
|
|
||||||
// objects on-demand, on the other hand, would be expensive and prone to
|
|
||||||
// memory leaks. So, instead we ended up with this flat interface.
|
|
||||||
//
|
|
||||||
// TODO(kenton): Create a utility class which callers can use to read and
|
|
||||||
// write fields from a Reflection without paying attention to the type.
|
|
||||||
class LIBPROTOBUF_EXPORT Reflection {
|
|
||||||
public:
|
|
||||||
inline Reflection() {}
|
|
||||||
virtual ~Reflection();
|
|
||||||
|
|
||||||
// Get the UnknownFieldSet for the message. This contains fields which
|
|
||||||
// were seen when the Message was parsed but were not recognized according
|
|
||||||
// to the Message's definition.
|
|
||||||
virtual const UnknownFieldSet& GetUnknownFields(
|
|
||||||
const Message& message) const = 0;
|
|
||||||
// Get a mutable pointer to the UnknownFieldSet for the message. This
|
|
||||||
// contains fields which were seen when the Message was parsed but were not
|
|
||||||
// recognized according to the Message's definition.
|
|
||||||
virtual UnknownFieldSet* MutableUnknownFields(Message* message) const = 0;
|
|
||||||
|
|
||||||
// Estimate the amount of memory used by the message object.
|
|
||||||
virtual int SpaceUsed(const Message& message) const = 0;
|
|
||||||
|
|
||||||
// Check if the given non-repeated field is set.
|
|
||||||
virtual bool HasField(const Message& message,
|
|
||||||
const FieldDescriptor* field) const = 0;
|
|
||||||
|
|
||||||
// Get the number of elements of a repeated field.
|
|
||||||
virtual int FieldSize(const Message& message,
|
|
||||||
const FieldDescriptor* field) const = 0;
|
|
||||||
|
|
||||||
// Clear the value of a field, so that HasField() returns false or
|
|
||||||
// FieldSize() returns zero.
|
|
||||||
virtual void ClearField(Message* message,
|
|
||||||
const FieldDescriptor* field) const = 0;
|
|
||||||
|
|
||||||
// Check if the oneof is set. Returns ture if any field in oneof
|
|
||||||
// is set, false otherwise.
|
|
||||||
// TODO(jieluo) - make it pure virtual after updating all
|
|
||||||
// the subclasses.
|
|
||||||
virtual bool HasOneof(const Message& message,
|
|
||||||
const OneofDescriptor* oneof_descriptor) const {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void ClearOneof(Message* message,
|
|
||||||
const OneofDescriptor* oneof_descriptor) const {}
|
|
||||||
|
|
||||||
// Returns the field descriptor if the oneof is set. NULL otherwise.
|
|
||||||
// TODO(jieluo) - make it pure virtual.
|
|
||||||
virtual const FieldDescriptor* GetOneofFieldDescriptor(
|
|
||||||
const Message& message,
|
|
||||||
const OneofDescriptor* oneof_descriptor) const {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Removes the last element of a repeated field.
|
|
||||||
// We don't provide a way to remove any element other than the last
|
|
||||||
// because it invites inefficient use, such as O(n^2) filtering loops
|
|
||||||
// that should have been O(n). If you want to remove an element other
|
|
||||||
// than the last, the best way to do it is to re-arrange the elements
|
|
||||||
// (using Swap()) so that the one you want removed is at the end, then
|
|
||||||
// call RemoveLast().
|
|
||||||
virtual void RemoveLast(Message* message,
|
|
||||||
const FieldDescriptor* field) const = 0;
|
|
||||||
// Removes the last element of a repeated message field, and returns the
|
|
||||||
// pointer to the caller. Caller takes ownership of the returned pointer.
|
|
||||||
virtual Message* ReleaseLast(Message* message,
|
|
||||||
const FieldDescriptor* field) const = 0;
|
|
||||||
|
|
||||||
// Swap the complete contents of two messages.
|
|
||||||
virtual void Swap(Message* message1, Message* message2) const = 0;
|
|
||||||
|
|
||||||
// Swap fields listed in fields vector of two messages.
|
|
||||||
virtual void SwapFields(Message* message1,
|
|
||||||
Message* message2,
|
|
||||||
const vector<const FieldDescriptor*>& fields)
|
|
||||||
const = 0;
|
|
||||||
|
|
||||||
// Swap two elements of a repeated field.
|
|
||||||
virtual void SwapElements(Message* message,
|
|
||||||
const FieldDescriptor* field,
|
|
||||||
int index1,
|
|
||||||
int index2) const = 0;
|
|
||||||
|
|
||||||
// List all fields of the message which are currently set. This includes
|
|
||||||
// extensions. Singular fields will only be listed if HasField(field) would
|
|
||||||
// return true and repeated fields will only be listed if FieldSize(field)
|
|
||||||
// would return non-zero. Fields (both normal fields and extension fields)
|
|
||||||
// will be listed ordered by field number.
|
|
||||||
virtual void ListFields(const Message& message,
|
|
||||||
vector<const FieldDescriptor*>* output) const = 0;
|
|
||||||
|
|
||||||
// Singular field getters ------------------------------------------
|
|
||||||
// These get the value of a non-repeated field. They return the default
|
|
||||||
// value for fields that aren't set.
|
|
||||||
|
|
||||||
virtual int32 GetInt32 (const Message& message,
|
|
||||||
const FieldDescriptor* field) const = 0;
|
|
||||||
virtual int64 GetInt64 (const Message& message,
|
|
||||||
const FieldDescriptor* field) const = 0;
|
|
||||||
virtual uint32 GetUInt32(const Message& message,
|
|
||||||
const FieldDescriptor* field) const = 0;
|
|
||||||
virtual uint64 GetUInt64(const Message& message,
|
|
||||||
const FieldDescriptor* field) const = 0;
|
|
||||||
virtual float GetFloat (const Message& message,
|
|
||||||
const FieldDescriptor* field) const = 0;
|
|
||||||
virtual double GetDouble(const Message& message,
|
|
||||||
const FieldDescriptor* field) const = 0;
|
|
||||||
virtual bool GetBool (const Message& message,
|
|
||||||
const FieldDescriptor* field) const = 0;
|
|
||||||
virtual string GetString(const Message& message,
|
|
||||||
const FieldDescriptor* field) const = 0;
|
|
||||||
virtual const EnumValueDescriptor* GetEnum(
|
|
||||||
const Message& message, const FieldDescriptor* field) const = 0;
|
|
||||||
// See MutableMessage() for the meaning of the "factory" parameter.
|
|
||||||
virtual const Message& GetMessage(const Message& message,
|
|
||||||
const FieldDescriptor* field,
|
|
||||||
MessageFactory* factory = NULL) const = 0;
|
|
||||||
|
|
||||||
// Get a string value without copying, if possible.
|
|
||||||
//
|
|
||||||
// GetString() necessarily returns a copy of the string. This can be
|
|
||||||
// inefficient when the string is already stored in a string object in the
|
|
||||||
// underlying message. GetStringReference() will return a reference to the
|
|
||||||
// underlying string in this case. Otherwise, it will copy the string into
|
|
||||||
// *scratch and return that.
|
|
||||||
//
|
|
||||||
// Note: It is perfectly reasonable and useful to write code like:
|
|
||||||
// str = reflection->GetStringReference(field, &str);
|
|
||||||
// This line would ensure that only one copy of the string is made
|
|
||||||
// regardless of the field's underlying representation. When initializing
|
|
||||||
// a newly-constructed string, though, it's just as fast and more readable
|
|
||||||
// to use code like:
|
|
||||||
// string str = reflection->GetString(field);
|
|
||||||
virtual const string& GetStringReference(const Message& message,
|
|
||||||
const FieldDescriptor* field,
|
|
||||||
string* scratch) const = 0;
|
|
||||||
|
|
||||||
|
|
||||||
// Singular field mutators -----------------------------------------
|
|
||||||
// These mutate the value of a non-repeated field.
|
|
||||||
|
|
||||||
virtual void SetInt32 (Message* message,
|
|
||||||
const FieldDescriptor* field, int32 value) const = 0;
|
|
||||||
virtual void SetInt64 (Message* message,
|
|
||||||
const FieldDescriptor* field, int64 value) const = 0;
|
|
||||||
virtual void SetUInt32(Message* message,
|
|
||||||
const FieldDescriptor* field, uint32 value) const = 0;
|
|
||||||
virtual void SetUInt64(Message* message,
|
|
||||||
const FieldDescriptor* field, uint64 value) const = 0;
|
|
||||||
virtual void SetFloat (Message* message,
|
|
||||||
const FieldDescriptor* field, float value) const = 0;
|
|
||||||
virtual void SetDouble(Message* message,
|
|
||||||
const FieldDescriptor* field, double value) const = 0;
|
|
||||||
virtual void SetBool (Message* message,
|
|
||||||
const FieldDescriptor* field, bool value) const = 0;
|
|
||||||
virtual void SetString(Message* message,
|
|
||||||
const FieldDescriptor* field,
|
|
||||||
const string& value) const = 0;
|
|
||||||
virtual void SetEnum (Message* message,
|
|
||||||
const FieldDescriptor* field,
|
|
||||||
const EnumValueDescriptor* value) const = 0;
|
|
||||||
// Get a mutable pointer to a field with a message type. If a MessageFactory
|
|
||||||
// is provided, it will be used to construct instances of the sub-message;
|
|
||||||
// otherwise, the default factory is used. If the field is an extension that
|
|
||||||
// does not live in the same pool as the containing message's descriptor (e.g.
|
|
||||||
// it lives in an overlay pool), then a MessageFactory must be provided.
|
|
||||||
// If you have no idea what that meant, then you probably don't need to worry
|
|
||||||
// about it (don't provide a MessageFactory). WARNING: If the
|
|
||||||
// FieldDescriptor is for a compiled-in extension, then
|
|
||||||
// factory->GetPrototype(field->message_type() MUST return an instance of the
|
|
||||||
// compiled-in class for this type, NOT DynamicMessage.
|
|
||||||
virtual Message* MutableMessage(Message* message,
|
|
||||||
const FieldDescriptor* field,
|
|
||||||
MessageFactory* factory = NULL) const = 0;
|
|
||||||
// Replaces the message specified by 'field' with the already-allocated object
|
|
||||||
// sub_message, passing ownership to the message. If the field contained a
|
|
||||||
// message, that message is deleted. If sub_message is NULL, the field is
|
|
||||||
// cleared.
|
|
||||||
virtual void SetAllocatedMessage(Message* message,
|
|
||||||
Message* sub_message,
|
|
||||||
const FieldDescriptor* field) const = 0;
|
|
||||||
// Releases the message specified by 'field' and returns the pointer,
|
|
||||||
// ReleaseMessage() will return the message the message object if it exists.
|
|
||||||
// Otherwise, it may or may not return NULL. In any case, if the return value
|
|
||||||
// is non-NULL, the caller takes ownership of the pointer.
|
|
||||||
// If the field existed (HasField() is true), then the returned pointer will
|
|
||||||
// be the same as the pointer returned by MutableMessage().
|
|
||||||
// This function has the same effect as ClearField().
|
|
||||||
virtual Message* ReleaseMessage(Message* message,
|
|
||||||
const FieldDescriptor* field,
|
|
||||||
MessageFactory* factory = NULL) const = 0;
|
|
||||||
|
|
||||||
|
|
||||||
// Repeated field getters ------------------------------------------
|
|
||||||
// These get the value of one element of a repeated field.
|
|
||||||
|
|
||||||
virtual int32 GetRepeatedInt32 (const Message& message,
|
|
||||||
const FieldDescriptor* field,
|
|
||||||
int index) const = 0;
|
|
||||||
virtual int64 GetRepeatedInt64 (const Message& message,
|
|
||||||
const FieldDescriptor* field,
|
|
||||||
int index) const = 0;
|
|
||||||
virtual uint32 GetRepeatedUInt32(const Message& message,
|
|
||||||
const FieldDescriptor* field,
|
|
||||||
int index) const = 0;
|
|
||||||
virtual uint64 GetRepeatedUInt64(const Message& message,
|
|
||||||
const FieldDescriptor* field,
|
|
||||||
int index) const = 0;
|
|
||||||
virtual float GetRepeatedFloat (const Message& message,
|
|
||||||
const FieldDescriptor* field,
|
|
||||||
int index) const = 0;
|
|
||||||
virtual double GetRepeatedDouble(const Message& message,
|
|
||||||
const FieldDescriptor* field,
|
|
||||||
int index) const = 0;
|
|
||||||
virtual bool GetRepeatedBool (const Message& message,
|
|
||||||
const FieldDescriptor* field,
|
|
||||||
int index) const = 0;
|
|
||||||
virtual string GetRepeatedString(const Message& message,
|
|
||||||
const FieldDescriptor* field,
|
|
||||||
int index) const = 0;
|
|
||||||
virtual const EnumValueDescriptor* GetRepeatedEnum(
|
|
||||||
const Message& message,
|
|
||||||
const FieldDescriptor* field, int index) const = 0;
|
|
||||||
virtual const Message& GetRepeatedMessage(
|
|
||||||
const Message& message,
|
|
||||||
const FieldDescriptor* field, int index) const = 0;
|
|
||||||
|
|
||||||
// See GetStringReference(), above.
|
|
||||||
virtual const string& GetRepeatedStringReference(
|
|
||||||
const Message& message, const FieldDescriptor* field,
|
|
||||||
int index, string* scratch) const = 0;
|
|
||||||
|
|
||||||
|
|
||||||
// Repeated field mutators -----------------------------------------
|
|
||||||
// These mutate the value of one element of a repeated field.
|
|
||||||
|
|
||||||
virtual void SetRepeatedInt32 (Message* message,
|
|
||||||
const FieldDescriptor* field,
|
|
||||||
int index, int32 value) const = 0;
|
|
||||||
virtual void SetRepeatedInt64 (Message* message,
|
|
||||||
const FieldDescriptor* field,
|
|
||||||
int index, int64 value) const = 0;
|
|
||||||
virtual void SetRepeatedUInt32(Message* message,
|
|
||||||
const FieldDescriptor* field,
|
|
||||||
int index, uint32 value) const = 0;
|
|
||||||
virtual void SetRepeatedUInt64(Message* message,
|
|
||||||
const FieldDescriptor* field,
|
|
||||||
int index, uint64 value) const = 0;
|
|
||||||
virtual void SetRepeatedFloat (Message* message,
|
|
||||||
const FieldDescriptor* field,
|
|
||||||
int index, float value) const = 0;
|
|
||||||
virtual void SetRepeatedDouble(Message* message,
|
|
||||||
const FieldDescriptor* field,
|
|
||||||
int index, double value) const = 0;
|
|
||||||
virtual void SetRepeatedBool (Message* message,
|
|
||||||
const FieldDescriptor* field,
|
|
||||||
int index, bool value) const = 0;
|
|
||||||
virtual void SetRepeatedString(Message* message,
|
|
||||||
const FieldDescriptor* field,
|
|
||||||
int index, const string& value) const = 0;
|
|
||||||
virtual void SetRepeatedEnum(Message* message,
|
|
||||||
const FieldDescriptor* field, int index,
|
|
||||||
const EnumValueDescriptor* value) const = 0;
|
|
||||||
// Get a mutable pointer to an element of a repeated field with a message
|
|
||||||
// type.
|
|
||||||
virtual Message* MutableRepeatedMessage(
|
|
||||||
Message* message, const FieldDescriptor* field, int index) const = 0;
|
|
||||||
|
|
||||||
|
|
||||||
// Repeated field adders -------------------------------------------
|
|
||||||
// These add an element to a repeated field.
|
|
||||||
|
|
||||||
virtual void AddInt32 (Message* message,
|
|
||||||
const FieldDescriptor* field, int32 value) const = 0;
|
|
||||||
virtual void AddInt64 (Message* message,
|
|
||||||
const FieldDescriptor* field, int64 value) const = 0;
|
|
||||||
virtual void AddUInt32(Message* message,
|
|
||||||
const FieldDescriptor* field, uint32 value) const = 0;
|
|
||||||
virtual void AddUInt64(Message* message,
|
|
||||||
const FieldDescriptor* field, uint64 value) const = 0;
|
|
||||||
virtual void AddFloat (Message* message,
|
|
||||||
const FieldDescriptor* field, float value) const = 0;
|
|
||||||
virtual void AddDouble(Message* message,
|
|
||||||
const FieldDescriptor* field, double value) const = 0;
|
|
||||||
virtual void AddBool (Message* message,
|
|
||||||
const FieldDescriptor* field, bool value) const = 0;
|
|
||||||
virtual void AddString(Message* message,
|
|
||||||
const FieldDescriptor* field,
|
|
||||||
const string& value) const = 0;
|
|
||||||
virtual void AddEnum (Message* message,
|
|
||||||
const FieldDescriptor* field,
|
|
||||||
const EnumValueDescriptor* value) const = 0;
|
|
||||||
// See MutableMessage() for comments on the "factory" parameter.
|
|
||||||
virtual Message* AddMessage(Message* message,
|
|
||||||
const FieldDescriptor* field,
|
|
||||||
MessageFactory* factory = NULL) const = 0;
|
|
||||||
|
|
||||||
|
|
||||||
// Repeated field accessors -------------------------------------------------
|
|
||||||
// The methods above, e.g. GetRepeatedInt32(msg, fd, index), provide singular
|
|
||||||
// access to the data in a RepeatedField. The methods below provide aggregate
|
|
||||||
// access by exposing the RepeatedField object itself with the Message.
|
|
||||||
// Applying these templates to inappropriate types will lead to an undefined
|
|
||||||
// reference at link time (e.g. GetRepeatedField<***double>), or possibly a
|
|
||||||
// template matching error at compile time (e.g. GetRepeatedPtrField<File>).
|
|
||||||
//
|
|
||||||
// Usage example: my_doubs = refl->GetRepeatedField<double>(msg, fd);
|
|
||||||
|
|
||||||
// for T = Cord and all protobuf scalar types except enums.
|
|
||||||
template<typename T>
|
|
||||||
const RepeatedField<T>& GetRepeatedField(
|
|
||||||
const Message&, const FieldDescriptor*) const;
|
|
||||||
|
|
||||||
// for T = Cord and all protobuf scalar types except enums.
|
|
||||||
template<typename T>
|
|
||||||
RepeatedField<T>* MutableRepeatedField(
|
|
||||||
Message*, const FieldDescriptor*) const;
|
|
||||||
|
|
||||||
// for T = string, google::protobuf::internal::StringPieceField
|
|
||||||
// google::protobuf::Message & descendants.
|
|
||||||
template<typename T>
|
|
||||||
const RepeatedPtrField<T>& GetRepeatedPtrField(
|
|
||||||
const Message&, const FieldDescriptor*) const;
|
|
||||||
|
|
||||||
// for T = string, google::protobuf::internal::StringPieceField
|
|
||||||
// google::protobuf::Message & descendants.
|
|
||||||
template<typename T>
|
|
||||||
RepeatedPtrField<T>* MutableRepeatedPtrField(
|
|
||||||
Message*, const FieldDescriptor*) const;
|
|
||||||
|
|
||||||
// Extensions ----------------------------------------------------------------
|
|
||||||
|
|
||||||
// Try to find an extension of this message type by fully-qualified field
|
|
||||||
// name. Returns NULL if no extension is known for this name or number.
|
|
||||||
virtual const FieldDescriptor* FindKnownExtensionByName(
|
|
||||||
const string& name) const = 0;
|
|
||||||
|
|
||||||
// Try to find an extension of this message type by field number.
|
|
||||||
// Returns NULL if no extension is known for this name or number.
|
|
||||||
virtual const FieldDescriptor* FindKnownExtensionByNumber(
|
|
||||||
int number) const = 0;
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
protected:
|
|
||||||
// Obtain a pointer to a Repeated Field Structure and do some type checking:
|
|
||||||
// on field->cpp_type(),
|
|
||||||
// on field->field_option().ctype() (if ctype >= 0)
|
|
||||||
// of field->message_type() (if message_type != NULL).
|
|
||||||
// We use 1 routine rather than 4 (const vs mutable) x (scalar vs pointer).
|
|
||||||
virtual void* MutableRawRepeatedField(
|
|
||||||
Message* message, const FieldDescriptor* field, FieldDescriptor::CppType,
|
|
||||||
int ctype, const Descriptor* message_type) const = 0;
|
|
||||||
|
|
||||||
private:
|
|
||||||
// Special version for specialized implementations of string. We can't call
|
|
||||||
// MutableRawRepeatedField directly here because we don't have access to
|
|
||||||
// FieldOptions::* which are defined in descriptor.pb.h. Including that
|
|
||||||
// file here is not possible because it would cause a circular include cycle.
|
|
||||||
void* MutableRawRepeatedString(
|
|
||||||
Message* message, const FieldDescriptor* field, bool is_string) const;
|
|
||||||
|
|
||||||
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Reflection);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Abstract interface for a factory for message objects.
|
|
||||||
class LIBPROTOBUF_EXPORT MessageFactory {
|
|
||||||
public:
|
|
||||||
inline MessageFactory() {}
|
|
||||||
virtual ~MessageFactory();
|
|
||||||
|
|
||||||
// Given a Descriptor, gets or constructs the default (prototype) Message
|
|
||||||
// of that type. You can then call that message's New() method to construct
|
|
||||||
// a mutable message of that type.
|
|
||||||
//
|
|
||||||
// Calling this method twice with the same Descriptor returns the same
|
|
||||||
// object. The returned object remains property of the factory. Also, any
|
|
||||||
// objects created by calling the prototype's New() method share some data
|
|
||||||
// with the prototype, so these must be destroyed before the MessageFactory
|
|
||||||
// is destroyed.
|
|
||||||
//
|
|
||||||
// The given descriptor must outlive the returned message, and hence must
|
|
||||||
// outlive the MessageFactory.
|
|
||||||
//
|
|
||||||
// Some implementations do not support all types. GetPrototype() will
|
|
||||||
// return NULL if the descriptor passed in is not supported.
|
|
||||||
//
|
|
||||||
// This method may or may not be thread-safe depending on the implementation.
|
|
||||||
// Each implementation should document its own degree thread-safety.
|
|
||||||
virtual const Message* GetPrototype(const Descriptor* type) = 0;
|
|
||||||
|
|
||||||
// Gets a MessageFactory which supports all generated, compiled-in messages.
|
|
||||||
// In other words, for any compiled-in type FooMessage, the following is true:
|
|
||||||
// MessageFactory::generated_factory()->GetPrototype(
|
|
||||||
// FooMessage::descriptor()) == FooMessage::default_instance()
|
|
||||||
// This factory supports all types which are found in
|
|
||||||
// DescriptorPool::generated_pool(). If given a descriptor from any other
|
|
||||||
// pool, GetPrototype() will return NULL. (You can also check if a
|
|
||||||
// descriptor is for a generated message by checking if
|
|
||||||
// descriptor->file()->pool() == DescriptorPool::generated_pool().)
|
|
||||||
//
|
|
||||||
// This factory is 100% thread-safe; calling GetPrototype() does not modify
|
|
||||||
// any shared data.
|
|
||||||
//
|
|
||||||
// This factory is a singleton. The caller must not delete the object.
|
|
||||||
static MessageFactory* generated_factory();
|
|
||||||
|
|
||||||
// For internal use only: Registers a .proto file at static initialization
|
|
||||||
// time, to be placed in generated_factory. The first time GetPrototype()
|
|
||||||
// is called with a descriptor from this file, |register_messages| will be
|
|
||||||
// called, with the file name as the parameter. It must call
|
|
||||||
// InternalRegisterGeneratedMessage() (below) to register each message type
|
|
||||||
// in the file. This strange mechanism is necessary because descriptors are
|
|
||||||
// built lazily, so we can't register types by their descriptor until we
|
|
||||||
// know that the descriptor exists. |filename| must be a permanent string.
|
|
||||||
static void InternalRegisterGeneratedFile(
|
|
||||||
const char* filename, void (*register_messages)(const string&));
|
|
||||||
|
|
||||||
// For internal use only: Registers a message type. Called only by the
|
|
||||||
// functions which are registered with InternalRegisterGeneratedFile(),
|
|
||||||
// above.
|
|
||||||
static void InternalRegisterGeneratedMessage(const Descriptor* descriptor,
|
|
||||||
const Message* prototype);
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
|
||||||
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageFactory);
|
|
||||||
};
|
|
||||||
|
|
||||||
#define DECLARE_GET_REPEATED_FIELD(TYPE) \
|
|
||||||
template<> \
|
|
||||||
LIBPROTOBUF_EXPORT \
|
|
||||||
const RepeatedField<TYPE>& Reflection::GetRepeatedField<TYPE>( \
|
|
||||||
const Message& message, const FieldDescriptor* field) const; \
|
|
||||||
\
|
|
||||||
template<> \
|
|
||||||
RepeatedField<TYPE>* Reflection::MutableRepeatedField<TYPE>( \
|
|
||||||
Message* message, const FieldDescriptor* field) const;
|
|
||||||
|
|
||||||
DECLARE_GET_REPEATED_FIELD(int32)
|
|
||||||
DECLARE_GET_REPEATED_FIELD(int64)
|
|
||||||
DECLARE_GET_REPEATED_FIELD(uint32)
|
|
||||||
DECLARE_GET_REPEATED_FIELD(uint64)
|
|
||||||
DECLARE_GET_REPEATED_FIELD(float)
|
|
||||||
DECLARE_GET_REPEATED_FIELD(double)
|
|
||||||
DECLARE_GET_REPEATED_FIELD(bool)
|
|
||||||
|
|
||||||
#undef DECLARE_GET_REPEATED_FIELD
|
|
||||||
|
|
||||||
// =============================================================================
|
|
||||||
// Implementation details for {Get,Mutable}RawRepeatedPtrField. We provide
|
|
||||||
// specializations for <string>, <StringPieceField> and <Message> and handle
|
|
||||||
// everything else with the default template which will match any type having
|
|
||||||
// a method with signature "static const google::protobuf::Descriptor* descriptor()".
|
|
||||||
// Such a type presumably is a descendant of google::protobuf::Message.
|
|
||||||
|
|
||||||
template<>
|
|
||||||
inline const RepeatedPtrField<string>& Reflection::GetRepeatedPtrField<string>(
|
|
||||||
const Message& message, const FieldDescriptor* field) const {
|
|
||||||
return *static_cast<RepeatedPtrField<string>* >(
|
|
||||||
MutableRawRepeatedString(const_cast<Message*>(&message), field, true));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<>
|
|
||||||
inline RepeatedPtrField<string>* Reflection::MutableRepeatedPtrField<string>(
|
|
||||||
Message* message, const FieldDescriptor* field) const {
|
|
||||||
return static_cast<RepeatedPtrField<string>* >(
|
|
||||||
MutableRawRepeatedString(message, field, true));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// -----
|
|
||||||
|
|
||||||
template<>
|
|
||||||
inline const RepeatedPtrField<Message>& Reflection::GetRepeatedPtrField(
|
|
||||||
const Message& message, const FieldDescriptor* field) const {
|
|
||||||
return *static_cast<RepeatedPtrField<Message>* >(
|
|
||||||
MutableRawRepeatedField(const_cast<Message*>(&message), field,
|
|
||||||
FieldDescriptor::CPPTYPE_MESSAGE, -1,
|
|
||||||
NULL));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<>
|
|
||||||
inline RepeatedPtrField<Message>* Reflection::MutableRepeatedPtrField(
|
|
||||||
Message* message, const FieldDescriptor* field) const {
|
|
||||||
return static_cast<RepeatedPtrField<Message>* >(
|
|
||||||
MutableRawRepeatedField(message, field,
|
|
||||||
FieldDescriptor::CPPTYPE_MESSAGE, -1,
|
|
||||||
NULL));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename PB>
|
|
||||||
inline const RepeatedPtrField<PB>& Reflection::GetRepeatedPtrField(
|
|
||||||
const Message& message, const FieldDescriptor* field) const {
|
|
||||||
return *static_cast<RepeatedPtrField<PB>* >(
|
|
||||||
MutableRawRepeatedField(const_cast<Message*>(&message), field,
|
|
||||||
FieldDescriptor::CPPTYPE_MESSAGE, -1,
|
|
||||||
PB::default_instance().GetDescriptor()));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename PB>
|
|
||||||
inline RepeatedPtrField<PB>* Reflection::MutableRepeatedPtrField(
|
|
||||||
Message* message, const FieldDescriptor* field) const {
|
|
||||||
return static_cast<RepeatedPtrField<PB>* >(
|
|
||||||
MutableRawRepeatedField(message, field,
|
|
||||||
FieldDescriptor::CPPTYPE_MESSAGE, -1,
|
|
||||||
PB::default_instance().GetDescriptor()));
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace protobuf
|
|
||||||
|
|
||||||
} // namespace google
|
|
||||||
#endif // GOOGLE_PROTOBUF_MESSAGE_H__
|
|
|
@ -1,247 +0,0 @@
|
||||||
// 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.
|
|
||||||
|
|
||||||
// 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(). Clear() will be called
|
|
||||||
// before merging the input.
|
|
||||||
|
|
||||||
// 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__
|
|
|
@ -1,81 +0,0 @@
|
||||||
// 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.
|
|
||||||
|
|
||||||
// Author: kenton@google.com (Kenton Varda)
|
|
||||||
// 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_REFLECTION_OPS_H__
|
|
||||||
#define GOOGLE_PROTOBUF_REFLECTION_OPS_H__
|
|
||||||
|
|
||||||
#include <google/protobuf/stubs/common.h>
|
|
||||||
#include <google/protobuf/message.h>
|
|
||||||
|
|
||||||
namespace google {
|
|
||||||
namespace protobuf {
|
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
// Basic operations that can be performed using reflection.
|
|
||||||
// These can be used as a cheap way to implement the corresponding
|
|
||||||
// methods of the Message interface, though they are likely to be
|
|
||||||
// slower than implementations tailored for the specific message type.
|
|
||||||
//
|
|
||||||
// This class should stay limited to operations needed to implement
|
|
||||||
// the Message interface.
|
|
||||||
//
|
|
||||||
// This class is really a namespace that contains only static methods.
|
|
||||||
class LIBPROTOBUF_EXPORT ReflectionOps {
|
|
||||||
public:
|
|
||||||
static void Copy(const Message& from, Message* to);
|
|
||||||
static void Merge(const Message& from, Message* to);
|
|
||||||
static void Clear(Message* message);
|
|
||||||
static bool IsInitialized(const Message& message);
|
|
||||||
static void DiscardUnknownFields(Message* message);
|
|
||||||
|
|
||||||
// Finds all unset required fields in the message and adds their full
|
|
||||||
// paths (e.g. "foo.bar[5].baz") to *names. "prefix" will be attached to
|
|
||||||
// the front of each name.
|
|
||||||
static void FindInitializationErrors(const Message& message,
|
|
||||||
const string& prefix,
|
|
||||||
vector<string>* errors);
|
|
||||||
|
|
||||||
private:
|
|
||||||
// All methods are static. No need to construct.
|
|
||||||
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ReflectionOps);
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace internal
|
|
||||||
} // namespace protobuf
|
|
||||||
|
|
||||||
} // namespace google
|
|
||||||
#endif // GOOGLE_PROTOBUF_REFLECTION_OPS_H__
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,291 +0,0 @@
|
||||||
// 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.
|
|
||||||
|
|
||||||
// Author: kenton@google.com (Kenton Varda)
|
|
||||||
// Based on original Protocol Buffers design by
|
|
||||||
// Sanjay Ghemawat, Jeff Dean, and others.
|
|
||||||
//
|
|
||||||
// DEPRECATED: This module declares the abstract interfaces underlying proto2
|
|
||||||
// RPC services. These are intented to be independent of any particular RPC
|
|
||||||
// implementation, so that proto2 services can be used on top of a variety
|
|
||||||
// of implementations. Starting with version 2.3.0, RPC implementations should
|
|
||||||
// not try to build on these, but should instead provide code generator plugins
|
|
||||||
// which generate code specific to the particular RPC implementation. This way
|
|
||||||
// the generated code can be more appropriate for the implementation in use
|
|
||||||
// and can avoid unnecessary layers of indirection.
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// When you use the protocol compiler to compile a service definition, it
|
|
||||||
// generates two classes: An abstract interface for the service (with
|
|
||||||
// methods matching the service definition) and a "stub" implementation.
|
|
||||||
// A stub is just a type-safe wrapper around an RpcChannel which emulates a
|
|
||||||
// local implementation of the service.
|
|
||||||
//
|
|
||||||
// For example, the service definition:
|
|
||||||
// service MyService {
|
|
||||||
// rpc Foo(MyRequest) returns(MyResponse);
|
|
||||||
// }
|
|
||||||
// will generate abstract interface "MyService" and class "MyService::Stub".
|
|
||||||
// You could implement a MyService as follows:
|
|
||||||
// class MyServiceImpl : public MyService {
|
|
||||||
// public:
|
|
||||||
// MyServiceImpl() {}
|
|
||||||
// ~MyServiceImpl() {}
|
|
||||||
//
|
|
||||||
// // implements MyService ---------------------------------------
|
|
||||||
//
|
|
||||||
// void Foo(google::protobuf::RpcController* controller,
|
|
||||||
// const MyRequest* request,
|
|
||||||
// MyResponse* response,
|
|
||||||
// Closure* done) {
|
|
||||||
// // ... read request and fill in response ...
|
|
||||||
// done->Run();
|
|
||||||
// }
|
|
||||||
// };
|
|
||||||
// You would then register an instance of MyServiceImpl with your RPC server
|
|
||||||
// implementation. (How to do that depends on the implementation.)
|
|
||||||
//
|
|
||||||
// To call a remote MyServiceImpl, first you need an RpcChannel connected to it.
|
|
||||||
// How to construct a channel depends, again, on your RPC implementation.
|
|
||||||
// Here we use a hypothentical "MyRpcChannel" as an example:
|
|
||||||
// MyRpcChannel channel("rpc:hostname:1234/myservice");
|
|
||||||
// MyRpcController controller;
|
|
||||||
// MyServiceImpl::Stub stub(&channel);
|
|
||||||
// FooRequest request;
|
|
||||||
// FooRespnose response;
|
|
||||||
//
|
|
||||||
// // ... fill in request ...
|
|
||||||
//
|
|
||||||
// stub.Foo(&controller, request, &response, NewCallback(HandleResponse));
|
|
||||||
//
|
|
||||||
// On Thread-Safety:
|
|
||||||
//
|
|
||||||
// Different RPC implementations may make different guarantees about what
|
|
||||||
// threads they may run callbacks on, and what threads the application is
|
|
||||||
// allowed to use to call the RPC system. Portable software should be ready
|
|
||||||
// for callbacks to be called on any thread, but should not try to call the
|
|
||||||
// RPC system from any thread except for the ones on which it received the
|
|
||||||
// callbacks. Realistically, though, simple software will probably want to
|
|
||||||
// use a single-threaded RPC system while high-end software will want to
|
|
||||||
// use multiple threads. RPC implementations should provide multiple
|
|
||||||
// choices.
|
|
||||||
|
|
||||||
#ifndef GOOGLE_PROTOBUF_SERVICE_H__
|
|
||||||
#define GOOGLE_PROTOBUF_SERVICE_H__
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <google/protobuf/stubs/common.h>
|
|
||||||
|
|
||||||
namespace google {
|
|
||||||
namespace protobuf {
|
|
||||||
|
|
||||||
// Defined in this file.
|
|
||||||
class Service;
|
|
||||||
class RpcController;
|
|
||||||
class RpcChannel;
|
|
||||||
|
|
||||||
// Defined in other files.
|
|
||||||
class Descriptor; // descriptor.h
|
|
||||||
class ServiceDescriptor; // descriptor.h
|
|
||||||
class MethodDescriptor; // descriptor.h
|
|
||||||
class Message; // message.h
|
|
||||||
|
|
||||||
// Abstract base interface for protocol-buffer-based RPC services. Services
|
|
||||||
// themselves are abstract interfaces (implemented either by servers or as
|
|
||||||
// stubs), but they subclass this base interface. The methods of this
|
|
||||||
// interface can be used to call the methods of the Service without knowing
|
|
||||||
// its exact type at compile time (analogous to Reflection).
|
|
||||||
class LIBPROTOBUF_EXPORT Service {
|
|
||||||
public:
|
|
||||||
inline Service() {}
|
|
||||||
virtual ~Service();
|
|
||||||
|
|
||||||
// When constructing a stub, you may pass STUB_OWNS_CHANNEL as the second
|
|
||||||
// parameter to the constructor to tell it to delete its RpcChannel when
|
|
||||||
// destroyed.
|
|
||||||
enum ChannelOwnership {
|
|
||||||
STUB_OWNS_CHANNEL,
|
|
||||||
STUB_DOESNT_OWN_CHANNEL
|
|
||||||
};
|
|
||||||
|
|
||||||
// Get the ServiceDescriptor describing this service and its methods.
|
|
||||||
virtual const ServiceDescriptor* GetDescriptor() = 0;
|
|
||||||
|
|
||||||
// Call a method of the service specified by MethodDescriptor. This is
|
|
||||||
// normally implemented as a simple switch() that calls the standard
|
|
||||||
// definitions of the service's methods.
|
|
||||||
//
|
|
||||||
// Preconditions:
|
|
||||||
// * method->service() == GetDescriptor()
|
|
||||||
// * request and response are of the exact same classes as the objects
|
|
||||||
// returned by GetRequestPrototype(method) and
|
|
||||||
// GetResponsePrototype(method).
|
|
||||||
// * After the call has started, the request must not be modified and the
|
|
||||||
// response must not be accessed at all until "done" is called.
|
|
||||||
// * "controller" is of the correct type for the RPC implementation being
|
|
||||||
// used by this Service. For stubs, the "correct type" depends on the
|
|
||||||
// RpcChannel which the stub is using. Server-side Service
|
|
||||||
// implementations are expected to accept whatever type of RpcController
|
|
||||||
// the server-side RPC implementation uses.
|
|
||||||
//
|
|
||||||
// Postconditions:
|
|
||||||
// * "done" will be called when the method is complete. This may be
|
|
||||||
// before CallMethod() returns or it may be at some point in the future.
|
|
||||||
// * If the RPC succeeded, "response" contains the response returned by
|
|
||||||
// the server.
|
|
||||||
// * If the RPC failed, "response"'s contents are undefined. The
|
|
||||||
// RpcController can be queried to determine if an error occurred and
|
|
||||||
// possibly to get more information about the error.
|
|
||||||
virtual void CallMethod(const MethodDescriptor* method,
|
|
||||||
RpcController* controller,
|
|
||||||
const Message* request,
|
|
||||||
Message* response,
|
|
||||||
Closure* done) = 0;
|
|
||||||
|
|
||||||
// CallMethod() requires that the request and response passed in are of a
|
|
||||||
// particular subclass of Message. GetRequestPrototype() and
|
|
||||||
// GetResponsePrototype() get the default instances of these required types.
|
|
||||||
// You can then call Message::New() on these instances to construct mutable
|
|
||||||
// objects which you can then pass to CallMethod().
|
|
||||||
//
|
|
||||||
// Example:
|
|
||||||
// const MethodDescriptor* method =
|
|
||||||
// service->GetDescriptor()->FindMethodByName("Foo");
|
|
||||||
// Message* request = stub->GetRequestPrototype (method)->New();
|
|
||||||
// Message* response = stub->GetResponsePrototype(method)->New();
|
|
||||||
// request->ParseFromString(input);
|
|
||||||
// service->CallMethod(method, *request, response, callback);
|
|
||||||
virtual const Message& GetRequestPrototype(
|
|
||||||
const MethodDescriptor* method) const = 0;
|
|
||||||
virtual const Message& GetResponsePrototype(
|
|
||||||
const MethodDescriptor* method) const = 0;
|
|
||||||
|
|
||||||
private:
|
|
||||||
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Service);
|
|
||||||
};
|
|
||||||
|
|
||||||
// An RpcController mediates a single method call. The primary purpose of
|
|
||||||
// the controller is to provide a way to manipulate settings specific to the
|
|
||||||
// RPC implementation and to find out about RPC-level errors.
|
|
||||||
//
|
|
||||||
// The methods provided by the RpcController interface are intended to be a
|
|
||||||
// "least common denominator" set of features which we expect all
|
|
||||||
// implementations to support. Specific implementations may provide more
|
|
||||||
// advanced features (e.g. deadline propagation).
|
|
||||||
class LIBPROTOBUF_EXPORT RpcController {
|
|
||||||
public:
|
|
||||||
inline RpcController() {}
|
|
||||||
virtual ~RpcController();
|
|
||||||
|
|
||||||
// Client-side methods ---------------------------------------------
|
|
||||||
// These calls may be made from the client side only. Their results
|
|
||||||
// are undefined on the server side (may crash).
|
|
||||||
|
|
||||||
// Resets the RpcController to its initial state so that it may be reused in
|
|
||||||
// a new call. Must not be called while an RPC is in progress.
|
|
||||||
virtual void Reset() = 0;
|
|
||||||
|
|
||||||
// After a call has finished, returns true if the call failed. The possible
|
|
||||||
// reasons for failure depend on the RPC implementation. Failed() must not
|
|
||||||
// be called before a call has finished. If Failed() returns true, the
|
|
||||||
// contents of the response message are undefined.
|
|
||||||
virtual bool Failed() const = 0;
|
|
||||||
|
|
||||||
// If Failed() is true, returns a human-readable description of the error.
|
|
||||||
virtual string ErrorText() const = 0;
|
|
||||||
|
|
||||||
// Advises the RPC system that the caller desires that the RPC call be
|
|
||||||
// canceled. The RPC system may cancel it immediately, may wait awhile and
|
|
||||||
// then cancel it, or may not even cancel the call at all. If the call is
|
|
||||||
// canceled, the "done" callback will still be called and the RpcController
|
|
||||||
// will indicate that the call failed at that time.
|
|
||||||
virtual void StartCancel() = 0;
|
|
||||||
|
|
||||||
// Server-side methods ---------------------------------------------
|
|
||||||
// These calls may be made from the server side only. Their results
|
|
||||||
// are undefined on the client side (may crash).
|
|
||||||
|
|
||||||
// Causes Failed() to return true on the client side. "reason" will be
|
|
||||||
// incorporated into the message returned by ErrorText(). If you find
|
|
||||||
// you need to return machine-readable information about failures, you
|
|
||||||
// should incorporate it into your response protocol buffer and should
|
|
||||||
// NOT call SetFailed().
|
|
||||||
virtual void SetFailed(const string& reason) = 0;
|
|
||||||
|
|
||||||
// If true, indicates that the client canceled the RPC, so the server may
|
|
||||||
// as well give up on replying to it. The server should still call the
|
|
||||||
// final "done" callback.
|
|
||||||
virtual bool IsCanceled() const = 0;
|
|
||||||
|
|
||||||
// Asks that the given callback be called when the RPC is canceled. The
|
|
||||||
// callback will always be called exactly once. If the RPC completes without
|
|
||||||
// being canceled, the callback will be called after completion. If the RPC
|
|
||||||
// has already been canceled when NotifyOnCancel() is called, the callback
|
|
||||||
// will be called immediately.
|
|
||||||
//
|
|
||||||
// NotifyOnCancel() must be called no more than once per request.
|
|
||||||
virtual void NotifyOnCancel(Closure* callback) = 0;
|
|
||||||
|
|
||||||
private:
|
|
||||||
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RpcController);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Abstract interface for an RPC channel. An RpcChannel represents a
|
|
||||||
// communication line to a Service which can be used to call that Service's
|
|
||||||
// methods. The Service may be running on another machine. Normally, you
|
|
||||||
// should not call an RpcChannel directly, but instead construct a stub Service
|
|
||||||
// wrapping it. Example:
|
|
||||||
// RpcChannel* channel = new MyRpcChannel("remotehost.example.com:1234");
|
|
||||||
// MyService* service = new MyService::Stub(channel);
|
|
||||||
// service->MyMethod(request, &response, callback);
|
|
||||||
class LIBPROTOBUF_EXPORT RpcChannel {
|
|
||||||
public:
|
|
||||||
inline RpcChannel() {}
|
|
||||||
virtual ~RpcChannel();
|
|
||||||
|
|
||||||
// Call the given method of the remote service. The signature of this
|
|
||||||
// procedure looks the same as Service::CallMethod(), but the requirements
|
|
||||||
// are less strict in one important way: the request and response objects
|
|
||||||
// need not be of any specific class as long as their descriptors are
|
|
||||||
// method->input_type() and method->output_type().
|
|
||||||
virtual void CallMethod(const MethodDescriptor* method,
|
|
||||||
RpcController* controller,
|
|
||||||
const Message* request,
|
|
||||||
Message* response,
|
|
||||||
Closure* done) = 0;
|
|
||||||
|
|
||||||
private:
|
|
||||||
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RpcChannel);
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace protobuf
|
|
||||||
|
|
||||||
} // namespace google
|
|
||||||
#endif // GOOGLE_PROTOBUF_SERVICE_H__
|
|
|
@ -1,227 +0,0 @@
|
||||||
// Protocol Buffers - Google's data interchange format
|
|
||||||
// Copyright 2012 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.
|
|
||||||
|
|
||||||
// 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(__ILP32__) || defined(GOOGLE_PROTOBUF_OS_NACL) || defined(GOOGLE_PROTOBUF_ARCH_SPARC)
|
|
||||||
// NaCl's intptr_t is not actually 64-bits on 64-bit!
|
|
||||||
// http://code.google.com/p/nativeclient/issues/detail?id=1162
|
|
||||||
// sparcv9's pointer type is 32bits
|
|
||||||
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);
|
|
||||||
|
|
||||||
#if defined(__MINGW32__) && defined(MemoryBarrier)
|
|
||||||
#undef MemoryBarrier
|
|
||||||
#endif
|
|
||||||
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"
|
|
||||||
|
|
||||||
// ThreadSanitizer, http://clang.llvm.org/docs/ThreadSanitizer.html.
|
|
||||||
#if defined(THREAD_SANITIZER)
|
|
||||||
#include <google/protobuf/stubs/atomicops_internals_tsan.h>
|
|
||||||
// MSVC.
|
|
||||||
#elif 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
|
|
||||||
|
|
||||||
// Solaris
|
|
||||||
#elif defined(GOOGLE_PROTOBUF_OS_SOLARIS)
|
|
||||||
#include <google/protobuf/stubs/atomicops_internals_solaris.h>
|
|
||||||
|
|
||||||
// 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) && defined(__linux__)
|
|
||||||
#include <google/protobuf/stubs/atomicops_internals_arm_gcc.h>
|
|
||||||
#elif defined(GOOGLE_PROTOBUF_ARCH_AARCH64)
|
|
||||||
#include <google/protobuf/stubs/atomicops_internals_arm64_gcc.h>
|
|
||||||
#elif defined(GOOGLE_PROTOBUF_ARCH_ARM_QNX)
|
|
||||||
#include <google/protobuf/stubs/atomicops_internals_arm_qnx.h>
|
|
||||||
#elif defined(GOOGLE_PROTOBUF_ARCH_MIPS) || defined(GOOGLE_PROTOBUF_ARCH_MIPS64)
|
|
||||||
#include <google/protobuf/stubs/atomicops_internals_mips_gcc.h>
|
|
||||||
#elif defined(__native_client__)
|
|
||||||
#include <google/protobuf/stubs/atomicops_internals_pnacl.h>
|
|
||||||
#elif (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4))
|
|
||||||
#include <google/protobuf/stubs/atomicops_internals_generic_gcc.h>
|
|
||||||
#elif defined(__clang__)
|
|
||||||
#if __has_extension(c_atomic)
|
|
||||||
#include <google/protobuf/stubs/atomicops_internals_generic_gcc.h>
|
|
||||||
#else
|
|
||||||
GOOGLE_PROTOBUF_ATOMICOPS_ERROR
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
GOOGLE_PROTOBUF_ATOMICOPS_ERROR
|
|
||||||
#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_
|
|
|
@ -1,150 +0,0 @@
|
||||||
// Protocol Buffers - Google's data interchange format
|
|
||||||
// Copyright 2012 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.
|
|
||||||
|
|
||||||
// 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_
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,166 +0,0 @@
|
||||||
// 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.
|
|
||||||
|
|
||||||
// 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
|
|
||||||
|
|
||||||
class GoogleOnceDynamic {
|
|
||||||
public:
|
|
||||||
GoogleOnceDynamic() : state_(GOOGLE_PROTOBUF_ONCE_INIT) { }
|
|
||||||
|
|
||||||
// If this->Init() has not been called before by any thread,
|
|
||||||
// execute (*func_with_arg)(arg) then return.
|
|
||||||
// Otherwise, wait until that prior invocation has finished
|
|
||||||
// executing its function, then return.
|
|
||||||
template<typename T>
|
|
||||||
void Init(void (*func_with_arg)(T*), T* arg) {
|
|
||||||
GoogleOnceInit<T>(&this->state_,
|
|
||||||
func_with_arg,
|
|
||||||
arg);
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
ProtobufOnceType state_;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define GOOGLE_PROTOBUF_DECLARE_ONCE(NAME) \
|
|
||||||
::google::protobuf::ProtobufOnceType NAME = GOOGLE_PROTOBUF_ONCE_INIT
|
|
||||||
|
|
||||||
} // namespace protobuf
|
|
||||||
} // namespace google
|
|
||||||
|
|
||||||
#endif // GOOGLE_PROTOBUF_STUBS_ONCE_H__
|
|
|
@ -1,103 +0,0 @@
|
||||||
// Protocol Buffers - Google's data interchange format
|
|
||||||
// Copyright 2012 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_PLATFORM_MACROS_H_
|
|
||||||
#define GOOGLE_PROTOBUF_PLATFORM_MACROS_H_
|
|
||||||
|
|
||||||
#include <google/protobuf/stubs/common.h>
|
|
||||||
|
|
||||||
#define GOOGLE_PROTOBUF_PLATFORM_ERROR \
|
|
||||||
#error "Host platform was not detected as supported by protobuf"
|
|
||||||
|
|
||||||
// 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(__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(__aarch64__)
|
|
||||||
#define GOOGLE_PROTOBUF_ARCH_AARCH64 1
|
|
||||||
#define GOOGLE_PROTOBUF_ARCH_64_BIT 1
|
|
||||||
#elif defined(__MIPSEL__)
|
|
||||||
#if defined(__LP64__)
|
|
||||||
#define GOOGLE_PROTOBUF_ARCH_MIPS64 1
|
|
||||||
#define GOOGLE_PROTOBUF_ARCH_64_BIT 1
|
|
||||||
#else
|
|
||||||
#define GOOGLE_PROTOBUF_ARCH_MIPS 1
|
|
||||||
#define GOOGLE_PROTOBUF_ARCH_32_BIT 1
|
|
||||||
#endif
|
|
||||||
#elif defined(__pnacl__)
|
|
||||||
#define GOOGLE_PROTOBUF_ARCH_32_BIT 1
|
|
||||||
#elif defined(sparc)
|
|
||||||
#define GOOGLE_PROTOBUF_ARCH_SPARC 1
|
|
||||||
#ifdef SOLARIS_64BIT_ENABLED
|
|
||||||
#define GOOGLE_PROTOBUF_ARCH_64_BIT 1
|
|
||||||
#else
|
|
||||||
#define GOOGLE_PROTOBUF_ARCH_32_BIT 1
|
|
||||||
#endif
|
|
||||||
#elif defined(__GNUC__)
|
|
||||||
# if (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4))
|
|
||||||
// We fallback to the generic Clang/GCC >= 4.7 implementation in atomicops.h
|
|
||||||
# elif defined(__clang__)
|
|
||||||
# if !__has_extension(c_atomic)
|
|
||||||
GOOGLE_PROTOBUF_PLATFORM_ERROR
|
|
||||||
# endif
|
|
||||||
// We fallback to the generic Clang/GCC >= 4.7 implementation in atomicops.h
|
|
||||||
# endif
|
|
||||||
# if __LP64__
|
|
||||||
# define GOOGLE_PROTOBUF_ARCH_64_BIT 1
|
|
||||||
# else
|
|
||||||
# define GOOGLE_PROTOBUF_ARCH_32_BIT 1
|
|
||||||
# endif
|
|
||||||
#else
|
|
||||||
GOOGLE_PROTOBUF_PLATFORM_ERROR
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(__APPLE__)
|
|
||||||
#define GOOGLE_PROTOBUF_OS_APPLE
|
|
||||||
#elif defined(__native_client__)
|
|
||||||
#define GOOGLE_PROTOBUF_OS_NACL
|
|
||||||
#elif defined(sun)
|
|
||||||
#define GOOGLE_PROTOBUF_OS_SOLARIS
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#undef GOOGLE_PROTOBUF_PLATFORM_ERROR
|
|
||||||
|
|
||||||
#endif // GOOGLE_PROTOBUF_PLATFORM_MACROS_H_
|
|
|
@ -1,138 +0,0 @@
|
||||||
// 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_
|
|
|
@ -1,336 +0,0 @@
|
||||||
// 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_
|
|
|
@ -1,473 +0,0 @@
|
||||||
// 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.
|
|
||||||
|
|
||||||
// Author: jschorr@google.com (Joseph Schorr)
|
|
||||||
// Based on original Protocol Buffers design by
|
|
||||||
// Sanjay Ghemawat, Jeff Dean, and others.
|
|
||||||
//
|
|
||||||
// Utilities for printing and parsing protocol messages in a human-readable,
|
|
||||||
// text-based format.
|
|
||||||
|
|
||||||
#ifndef GOOGLE_PROTOBUF_TEXT_FORMAT_H__
|
|
||||||
#define GOOGLE_PROTOBUF_TEXT_FORMAT_H__
|
|
||||||
|
|
||||||
#include <map>
|
|
||||||
#include <memory>
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include <google/protobuf/stubs/common.h>
|
|
||||||
#include <google/protobuf/descriptor.h>
|
|
||||||
#include <google/protobuf/message.h>
|
|
||||||
|
|
||||||
namespace google {
|
|
||||||
namespace protobuf {
|
|
||||||
|
|
||||||
namespace io {
|
|
||||||
class ErrorCollector; // tokenizer.h
|
|
||||||
}
|
|
||||||
|
|
||||||
// This class implements protocol buffer text format. Printing and parsing
|
|
||||||
// protocol messages in text format is useful for debugging and human editing
|
|
||||||
// of messages.
|
|
||||||
//
|
|
||||||
// This class is really a namespace that contains only static methods.
|
|
||||||
class LIBPROTOBUF_EXPORT TextFormat {
|
|
||||||
public:
|
|
||||||
// Outputs a textual representation of the given message to the given
|
|
||||||
// output stream.
|
|
||||||
static bool Print(const Message& message, io::ZeroCopyOutputStream* output);
|
|
||||||
|
|
||||||
// Print the fields in an UnknownFieldSet. They are printed by tag number
|
|
||||||
// only. Embedded messages are heuristically identified by attempting to
|
|
||||||
// parse them.
|
|
||||||
static bool PrintUnknownFields(const UnknownFieldSet& unknown_fields,
|
|
||||||
io::ZeroCopyOutputStream* output);
|
|
||||||
|
|
||||||
// Like Print(), but outputs directly to a string.
|
|
||||||
static bool PrintToString(const Message& message, string* output);
|
|
||||||
|
|
||||||
// Like PrintUnknownFields(), but outputs directly to a string.
|
|
||||||
static bool PrintUnknownFieldsToString(const UnknownFieldSet& unknown_fields,
|
|
||||||
string* output);
|
|
||||||
|
|
||||||
// Outputs a textual representation of the value of the field supplied on
|
|
||||||
// the message supplied. For non-repeated fields, an index of -1 must
|
|
||||||
// be supplied. Note that this method will print the default value for a
|
|
||||||
// field if it is not set.
|
|
||||||
static void PrintFieldValueToString(const Message& message,
|
|
||||||
const FieldDescriptor* field,
|
|
||||||
int index,
|
|
||||||
string* output);
|
|
||||||
|
|
||||||
// The default printer that converts scalar values from fields into
|
|
||||||
// their string representation.
|
|
||||||
// You can derive from this FieldValuePrinter if you want to have
|
|
||||||
// fields to be printed in a different way and register it at the
|
|
||||||
// Printer.
|
|
||||||
class LIBPROTOBUF_EXPORT FieldValuePrinter {
|
|
||||||
public:
|
|
||||||
FieldValuePrinter();
|
|
||||||
virtual ~FieldValuePrinter();
|
|
||||||
virtual string PrintBool(bool val) const;
|
|
||||||
virtual string PrintInt32(int32 val) const;
|
|
||||||
virtual string PrintUInt32(uint32 val) const;
|
|
||||||
virtual string PrintInt64(int64 val) const;
|
|
||||||
virtual string PrintUInt64(uint64 val) const;
|
|
||||||
virtual string PrintFloat(float val) const;
|
|
||||||
virtual string PrintDouble(double val) const;
|
|
||||||
virtual string PrintString(const string& val) const;
|
|
||||||
virtual string PrintBytes(const string& val) const;
|
|
||||||
virtual string PrintEnum(int32 val, const string& name) const;
|
|
||||||
virtual string PrintFieldName(const Message& message,
|
|
||||||
const Reflection* reflection,
|
|
||||||
const FieldDescriptor* field) const;
|
|
||||||
virtual string PrintMessageStart(const Message& message,
|
|
||||||
int field_index,
|
|
||||||
int field_count,
|
|
||||||
bool single_line_mode) const;
|
|
||||||
virtual string PrintMessageEnd(const Message& message,
|
|
||||||
int field_index,
|
|
||||||
int field_count,
|
|
||||||
bool single_line_mode) const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldValuePrinter);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Class for those users which require more fine-grained control over how
|
|
||||||
// a protobuffer message is printed out.
|
|
||||||
class LIBPROTOBUF_EXPORT Printer {
|
|
||||||
public:
|
|
||||||
Printer();
|
|
||||||
~Printer();
|
|
||||||
|
|
||||||
// Like TextFormat::Print
|
|
||||||
bool Print(const Message& message, io::ZeroCopyOutputStream* output) const;
|
|
||||||
// Like TextFormat::PrintUnknownFields
|
|
||||||
bool PrintUnknownFields(const UnknownFieldSet& unknown_fields,
|
|
||||||
io::ZeroCopyOutputStream* output) const;
|
|
||||||
// Like TextFormat::PrintToString
|
|
||||||
bool PrintToString(const Message& message, string* output) const;
|
|
||||||
// Like TextFormat::PrintUnknownFieldsToString
|
|
||||||
bool PrintUnknownFieldsToString(const UnknownFieldSet& unknown_fields,
|
|
||||||
string* output) const;
|
|
||||||
// Like TextFormat::PrintFieldValueToString
|
|
||||||
void PrintFieldValueToString(const Message& message,
|
|
||||||
const FieldDescriptor* field,
|
|
||||||
int index,
|
|
||||||
string* output) const;
|
|
||||||
|
|
||||||
// Adjust the initial indent level of all output. Each indent level is
|
|
||||||
// equal to two spaces.
|
|
||||||
void SetInitialIndentLevel(int indent_level) {
|
|
||||||
initial_indent_level_ = indent_level;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If printing in single line mode, then the entire message will be output
|
|
||||||
// on a single line with no line breaks.
|
|
||||||
void SetSingleLineMode(bool single_line_mode) {
|
|
||||||
single_line_mode_ = single_line_mode;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsInSingleLineMode() {
|
|
||||||
return single_line_mode_;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If use_field_number is true, uses field number instead of field name.
|
|
||||||
void SetUseFieldNumber(bool use_field_number) {
|
|
||||||
use_field_number_ = use_field_number;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set true to print repeated primitives in a format like:
|
|
||||||
// field_name: [1, 2, 3, 4]
|
|
||||||
// instead of printing each value on its own line. Short format applies
|
|
||||||
// only to primitive values -- i.e. everything except strings and
|
|
||||||
// sub-messages/groups.
|
|
||||||
void SetUseShortRepeatedPrimitives(bool use_short_repeated_primitives) {
|
|
||||||
use_short_repeated_primitives_ = use_short_repeated_primitives;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set true to output UTF-8 instead of ASCII. The only difference
|
|
||||||
// is that bytes >= 0x80 in string fields will not be escaped,
|
|
||||||
// because they are assumed to be part of UTF-8 multi-byte
|
|
||||||
// sequences. This will change the default FieldValuePrinter.
|
|
||||||
void SetUseUtf8StringEscaping(bool as_utf8);
|
|
||||||
|
|
||||||
// Set the default FieldValuePrinter that is used for all fields that
|
|
||||||
// don't have a field-specific printer registered.
|
|
||||||
// Takes ownership of the printer.
|
|
||||||
void SetDefaultFieldValuePrinter(const FieldValuePrinter* printer);
|
|
||||||
|
|
||||||
// Sets whether we want to hide unknown fields or not.
|
|
||||||
// Usually unknown fields are printed in a generic way that includes the
|
|
||||||
// tag number of the field instead of field name. However, sometimes it
|
|
||||||
// is useful to be able to print the message without unknown fields (e.g.
|
|
||||||
// for the python protobuf version to maintain consistency between its pure
|
|
||||||
// python and c++ implementations).
|
|
||||||
void SetHideUnknownFields(bool hide) {
|
|
||||||
hide_unknown_fields_ = hide;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If print_message_fields_in_index_order is true, print fields of a proto
|
|
||||||
// message using the order defined in source code instead of the field
|
|
||||||
// number. By default, use the field number order.
|
|
||||||
void SetPrintMessageFieldsInIndexOrder(
|
|
||||||
bool print_message_fields_in_index_order) {
|
|
||||||
print_message_fields_in_index_order_ =
|
|
||||||
print_message_fields_in_index_order;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Register a custom field-specific FieldValuePrinter for fields
|
|
||||||
// with a particular FieldDescriptor.
|
|
||||||
// Returns "true" if the registration succeeded, or "false", if there is
|
|
||||||
// already a printer for that FieldDescriptor.
|
|
||||||
// Takes ownership of the printer on successful registration.
|
|
||||||
bool RegisterFieldValuePrinter(const FieldDescriptor* field,
|
|
||||||
const FieldValuePrinter* printer);
|
|
||||||
|
|
||||||
private:
|
|
||||||
// Forward declaration of an internal class used to print the text
|
|
||||||
// output to the OutputStream (see text_format.cc for implementation).
|
|
||||||
class TextGenerator;
|
|
||||||
|
|
||||||
// Internal Print method, used for writing to the OutputStream via
|
|
||||||
// the TextGenerator class.
|
|
||||||
void Print(const Message& message,
|
|
||||||
TextGenerator& generator) const;
|
|
||||||
|
|
||||||
// Print a single field.
|
|
||||||
void PrintField(const Message& message,
|
|
||||||
const Reflection* reflection,
|
|
||||||
const FieldDescriptor* field,
|
|
||||||
TextGenerator& generator) const;
|
|
||||||
|
|
||||||
// Print a repeated primitive field in short form.
|
|
||||||
void PrintShortRepeatedField(const Message& message,
|
|
||||||
const Reflection* reflection,
|
|
||||||
const FieldDescriptor* field,
|
|
||||||
TextGenerator& generator) const;
|
|
||||||
|
|
||||||
// Print the name of a field -- i.e. everything that comes before the
|
|
||||||
// ':' for a single name/value pair.
|
|
||||||
void PrintFieldName(const Message& message,
|
|
||||||
const Reflection* reflection,
|
|
||||||
const FieldDescriptor* field,
|
|
||||||
TextGenerator& generator) const;
|
|
||||||
|
|
||||||
// Outputs a textual representation of the value of the field supplied on
|
|
||||||
// the message supplied or the default value if not set.
|
|
||||||
void PrintFieldValue(const Message& message,
|
|
||||||
const Reflection* reflection,
|
|
||||||
const FieldDescriptor* field,
|
|
||||||
int index,
|
|
||||||
TextGenerator& generator) const;
|
|
||||||
|
|
||||||
// Print the fields in an UnknownFieldSet. They are printed by tag number
|
|
||||||
// only. Embedded messages are heuristically identified by attempting to
|
|
||||||
// parse them.
|
|
||||||
void PrintUnknownFields(const UnknownFieldSet& unknown_fields,
|
|
||||||
TextGenerator& generator) const;
|
|
||||||
|
|
||||||
int initial_indent_level_;
|
|
||||||
|
|
||||||
bool single_line_mode_;
|
|
||||||
|
|
||||||
bool use_field_number_;
|
|
||||||
|
|
||||||
bool use_short_repeated_primitives_;
|
|
||||||
|
|
||||||
bool hide_unknown_fields_;
|
|
||||||
|
|
||||||
bool print_message_fields_in_index_order_;
|
|
||||||
|
|
||||||
scoped_ptr<const FieldValuePrinter> default_field_value_printer_;
|
|
||||||
typedef map<const FieldDescriptor*,
|
|
||||||
const FieldValuePrinter*> CustomPrinterMap;
|
|
||||||
CustomPrinterMap custom_printers_;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Parses a text-format protocol message from the given input stream to
|
|
||||||
// the given message object. This function parses the format written
|
|
||||||
// by Print().
|
|
||||||
static bool Parse(io::ZeroCopyInputStream* input, Message* output);
|
|
||||||
// Like Parse(), but reads directly from a string.
|
|
||||||
static bool ParseFromString(const string& input, Message* output);
|
|
||||||
|
|
||||||
// Like Parse(), but the data is merged into the given message, as if
|
|
||||||
// using Message::MergeFrom().
|
|
||||||
static bool Merge(io::ZeroCopyInputStream* input, Message* output);
|
|
||||||
// Like Merge(), but reads directly from a string.
|
|
||||||
static bool MergeFromString(const string& input, Message* output);
|
|
||||||
|
|
||||||
// Parse the given text as a single field value and store it into the
|
|
||||||
// given field of the given message. If the field is a repeated field,
|
|
||||||
// the new value will be added to the end
|
|
||||||
static bool ParseFieldValueFromString(const string& input,
|
|
||||||
const FieldDescriptor* field,
|
|
||||||
Message* message);
|
|
||||||
|
|
||||||
// Interface that TextFormat::Parser can use to find extensions.
|
|
||||||
// This class may be extended in the future to find more information
|
|
||||||
// like fields, etc.
|
|
||||||
class LIBPROTOBUF_EXPORT Finder {
|
|
||||||
public:
|
|
||||||
virtual ~Finder();
|
|
||||||
|
|
||||||
// Try to find an extension of *message by fully-qualified field
|
|
||||||
// name. Returns NULL if no extension is known for this name or number.
|
|
||||||
virtual const FieldDescriptor* FindExtension(
|
|
||||||
Message* message,
|
|
||||||
const string& name) const = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
// A location in the parsed text.
|
|
||||||
struct ParseLocation {
|
|
||||||
int line;
|
|
||||||
int column;
|
|
||||||
|
|
||||||
ParseLocation() : line(-1), column(-1) {}
|
|
||||||
ParseLocation(int line_param, int column_param)
|
|
||||||
: line(line_param), column(column_param) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Data structure which is populated with the locations of each field
|
|
||||||
// value parsed from the text.
|
|
||||||
class LIBPROTOBUF_EXPORT ParseInfoTree {
|
|
||||||
public:
|
|
||||||
ParseInfoTree();
|
|
||||||
~ParseInfoTree();
|
|
||||||
|
|
||||||
// Returns the parse location for index-th value of the field in the parsed
|
|
||||||
// text. If none exists, returns a location with line = -1. Index should be
|
|
||||||
// -1 for not-repeated fields.
|
|
||||||
ParseLocation GetLocation(const FieldDescriptor* field, int index) const;
|
|
||||||
|
|
||||||
// Returns the parse info tree for the given field, which must be a message
|
|
||||||
// type. The nested information tree is owned by the root tree and will be
|
|
||||||
// deleted when it is deleted.
|
|
||||||
ParseInfoTree* GetTreeForNested(const FieldDescriptor* field,
|
|
||||||
int index) const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
// Allow the text format parser to record information into the tree.
|
|
||||||
friend class TextFormat;
|
|
||||||
|
|
||||||
// Records the starting location of a single value for a field.
|
|
||||||
void RecordLocation(const FieldDescriptor* field, ParseLocation location);
|
|
||||||
|
|
||||||
// Create and records a nested tree for a nested message field.
|
|
||||||
ParseInfoTree* CreateNested(const FieldDescriptor* field);
|
|
||||||
|
|
||||||
// Defines the map from the index-th field descriptor to its parse location.
|
|
||||||
typedef map<const FieldDescriptor*, vector<ParseLocation> > LocationMap;
|
|
||||||
|
|
||||||
// Defines the map from the index-th field descriptor to the nested parse
|
|
||||||
// info tree.
|
|
||||||
typedef map<const FieldDescriptor*, vector<ParseInfoTree*> > NestedMap;
|
|
||||||
|
|
||||||
LocationMap locations_;
|
|
||||||
NestedMap nested_;
|
|
||||||
|
|
||||||
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ParseInfoTree);
|
|
||||||
};
|
|
||||||
|
|
||||||
// For more control over parsing, use this class.
|
|
||||||
class LIBPROTOBUF_EXPORT Parser {
|
|
||||||
public:
|
|
||||||
Parser();
|
|
||||||
~Parser();
|
|
||||||
|
|
||||||
// Like TextFormat::Parse().
|
|
||||||
bool Parse(io::ZeroCopyInputStream* input, Message* output);
|
|
||||||
// Like TextFormat::ParseFromString().
|
|
||||||
bool ParseFromString(const string& input, Message* output);
|
|
||||||
// Like TextFormat::Merge().
|
|
||||||
bool Merge(io::ZeroCopyInputStream* input, Message* output);
|
|
||||||
// Like TextFormat::MergeFromString().
|
|
||||||
bool MergeFromString(const string& input, Message* output);
|
|
||||||
|
|
||||||
// Set where to report parse errors. If NULL (the default), errors will
|
|
||||||
// be printed to stderr.
|
|
||||||
void RecordErrorsTo(io::ErrorCollector* error_collector) {
|
|
||||||
error_collector_ = error_collector;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set how parser finds extensions. If NULL (the default), the
|
|
||||||
// parser will use the standard Reflection object associated with
|
|
||||||
// the message being parsed.
|
|
||||||
void SetFinder(Finder* finder) {
|
|
||||||
finder_ = finder;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sets where location information about the parse will be written. If NULL
|
|
||||||
// (the default), then no location will be written.
|
|
||||||
void WriteLocationsTo(ParseInfoTree* tree) {
|
|
||||||
parse_info_tree_ = tree;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Normally parsing fails if, after parsing, output->IsInitialized()
|
|
||||||
// returns false. Call AllowPartialMessage(true) to skip this check.
|
|
||||||
void AllowPartialMessage(bool allow) {
|
|
||||||
allow_partial_ = allow;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Allow field names to be matched case-insensitively.
|
|
||||||
// This is not advisable if there are fields that only differ in case, or
|
|
||||||
// if you want to enforce writing in the canonical form.
|
|
||||||
// This is 'false' by default.
|
|
||||||
void AllowCaseInsensitiveField(bool allow) {
|
|
||||||
allow_case_insensitive_field_ = allow;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Like TextFormat::ParseFieldValueFromString
|
|
||||||
bool ParseFieldValueFromString(const string& input,
|
|
||||||
const FieldDescriptor* field,
|
|
||||||
Message* output);
|
|
||||||
|
|
||||||
|
|
||||||
void AllowFieldNumber(bool allow) {
|
|
||||||
allow_field_number_ = allow;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
// Forward declaration of an internal class used to parse text
|
|
||||||
// representations (see text_format.cc for implementation).
|
|
||||||
class ParserImpl;
|
|
||||||
|
|
||||||
// Like TextFormat::Merge(). The provided implementation is used
|
|
||||||
// to do the parsing.
|
|
||||||
bool MergeUsingImpl(io::ZeroCopyInputStream* input,
|
|
||||||
Message* output,
|
|
||||||
ParserImpl* parser_impl);
|
|
||||||
|
|
||||||
io::ErrorCollector* error_collector_;
|
|
||||||
Finder* finder_;
|
|
||||||
ParseInfoTree* parse_info_tree_;
|
|
||||||
bool allow_partial_;
|
|
||||||
bool allow_case_insensitive_field_;
|
|
||||||
bool allow_unknown_field_;
|
|
||||||
bool allow_unknown_enum_;
|
|
||||||
bool allow_field_number_;
|
|
||||||
bool allow_relaxed_whitespace_;
|
|
||||||
bool allow_singular_overwrites_;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
|
||||||
// Hack: ParseInfoTree declares TextFormat as a friend which should extend
|
|
||||||
// the friendship to TextFormat::Parser::ParserImpl, but unfortunately some
|
|
||||||
// old compilers (e.g. GCC 3.4.6) don't implement this correctly. We provide
|
|
||||||
// helpers for ParserImpl to call methods of ParseInfoTree.
|
|
||||||
static inline void RecordLocation(ParseInfoTree* info_tree,
|
|
||||||
const FieldDescriptor* field,
|
|
||||||
ParseLocation location);
|
|
||||||
static inline ParseInfoTree* CreateNested(ParseInfoTree* info_tree,
|
|
||||||
const FieldDescriptor* field);
|
|
||||||
|
|
||||||
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(TextFormat);
|
|
||||||
};
|
|
||||||
|
|
||||||
inline void TextFormat::RecordLocation(ParseInfoTree* info_tree,
|
|
||||||
const FieldDescriptor* field,
|
|
||||||
ParseLocation location) {
|
|
||||||
info_tree->RecordLocation(field, location);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline TextFormat::ParseInfoTree* TextFormat::CreateNested(
|
|
||||||
ParseInfoTree* info_tree, const FieldDescriptor* field) {
|
|
||||||
return info_tree->CreateNested(field);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace protobuf
|
|
||||||
|
|
||||||
} // namespace google
|
|
||||||
#endif // GOOGLE_PROTOBUF_TEXT_FORMAT_H__
|
|
|
@ -1,318 +0,0 @@
|
||||||
// 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.
|
|
||||||
|
|
||||||
// Author: kenton@google.com (Kenton Varda)
|
|
||||||
// Based on original Protocol Buffers design by
|
|
||||||
// Sanjay Ghemawat, Jeff Dean, and others.
|
|
||||||
//
|
|
||||||
// Contains classes used to keep track of unrecognized fields seen while
|
|
||||||
// parsing a protocol message.
|
|
||||||
|
|
||||||
#ifndef GOOGLE_PROTOBUF_UNKNOWN_FIELD_SET_H__
|
|
||||||
#define GOOGLE_PROTOBUF_UNKNOWN_FIELD_SET_H__
|
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
#include <google/protobuf/stubs/common.h>
|
|
||||||
|
|
||||||
namespace google {
|
|
||||||
namespace protobuf {
|
|
||||||
namespace io {
|
|
||||||
class CodedInputStream; // coded_stream.h
|
|
||||||
class CodedOutputStream; // coded_stream.h
|
|
||||||
class ZeroCopyInputStream; // zero_copy_stream.h
|
|
||||||
}
|
|
||||||
namespace internal {
|
|
||||||
class WireFormat; // wire_format.h
|
|
||||||
class MessageSetFieldSkipperUsingCord;
|
|
||||||
// extension_set_heavy.cc
|
|
||||||
}
|
|
||||||
|
|
||||||
class Message; // message.h
|
|
||||||
class UnknownField; // below
|
|
||||||
|
|
||||||
// An UnknownFieldSet contains fields that were encountered while parsing a
|
|
||||||
// message but were not defined by its type. Keeping track of these can be
|
|
||||||
// useful, especially in that they may be written if the message is serialized
|
|
||||||
// again without being cleared in between. This means that software which
|
|
||||||
// simply receives messages and forwards them to other servers does not need
|
|
||||||
// to be updated every time a new field is added to the message definition.
|
|
||||||
//
|
|
||||||
// To get the UnknownFieldSet attached to any message, call
|
|
||||||
// Reflection::GetUnknownFields().
|
|
||||||
//
|
|
||||||
// This class is necessarily tied to the protocol buffer wire format, unlike
|
|
||||||
// the Reflection interface which is independent of any serialization scheme.
|
|
||||||
class LIBPROTOBUF_EXPORT UnknownFieldSet {
|
|
||||||
public:
|
|
||||||
UnknownFieldSet();
|
|
||||||
~UnknownFieldSet();
|
|
||||||
|
|
||||||
// Remove all fields.
|
|
||||||
inline void Clear();
|
|
||||||
|
|
||||||
// Remove all fields and deallocate internal data objects
|
|
||||||
void ClearAndFreeMemory();
|
|
||||||
|
|
||||||
// Is this set empty?
|
|
||||||
inline bool empty() const;
|
|
||||||
|
|
||||||
// Merge the contents of some other UnknownFieldSet with this one.
|
|
||||||
void MergeFrom(const UnknownFieldSet& other);
|
|
||||||
|
|
||||||
// Swaps the contents of some other UnknownFieldSet with this one.
|
|
||||||
inline void Swap(UnknownFieldSet* x);
|
|
||||||
|
|
||||||
// Computes (an estimate of) the total number of bytes currently used for
|
|
||||||
// storing the unknown fields in memory. Does NOT include
|
|
||||||
// sizeof(*this) in the calculation.
|
|
||||||
int SpaceUsedExcludingSelf() const;
|
|
||||||
|
|
||||||
// Version of SpaceUsed() including sizeof(*this).
|
|
||||||
int SpaceUsed() const;
|
|
||||||
|
|
||||||
// Returns the number of fields present in the UnknownFieldSet.
|
|
||||||
inline int field_count() const;
|
|
||||||
// Get a field in the set, where 0 <= index < field_count(). The fields
|
|
||||||
// appear in the order in which they were added.
|
|
||||||
inline const UnknownField& field(int index) const;
|
|
||||||
// Get a mutable pointer to a field in the set, where
|
|
||||||
// 0 <= index < field_count(). The fields appear in the order in which
|
|
||||||
// they were added.
|
|
||||||
inline UnknownField* mutable_field(int index);
|
|
||||||
|
|
||||||
// Adding fields ---------------------------------------------------
|
|
||||||
|
|
||||||
void AddVarint(int number, uint64 value);
|
|
||||||
void AddFixed32(int number, uint32 value);
|
|
||||||
void AddFixed64(int number, uint64 value);
|
|
||||||
void AddLengthDelimited(int number, const string& value);
|
|
||||||
string* AddLengthDelimited(int number);
|
|
||||||
UnknownFieldSet* AddGroup(int number);
|
|
||||||
|
|
||||||
// Adds an unknown field from another set.
|
|
||||||
void AddField(const UnknownField& field);
|
|
||||||
|
|
||||||
// Delete fields with indices in the range [start .. start+num-1].
|
|
||||||
// Caution: implementation moves all fields with indices [start+num .. ].
|
|
||||||
void DeleteSubrange(int start, int num);
|
|
||||||
|
|
||||||
// Delete all fields with a specific field number. The order of left fields
|
|
||||||
// is preserved.
|
|
||||||
// Caution: implementation moves all fields after the first deleted field.
|
|
||||||
void DeleteByNumber(int number);
|
|
||||||
|
|
||||||
// Parsing helpers -------------------------------------------------
|
|
||||||
// These work exactly like the similarly-named methods of Message.
|
|
||||||
|
|
||||||
bool MergeFromCodedStream(io::CodedInputStream* input);
|
|
||||||
bool ParseFromCodedStream(io::CodedInputStream* input);
|
|
||||||
bool ParseFromZeroCopyStream(io::ZeroCopyInputStream* input);
|
|
||||||
bool ParseFromArray(const void* data, int size);
|
|
||||||
inline bool ParseFromString(const string& data) {
|
|
||||||
return ParseFromArray(data.data(), static_cast<int>(data.size()));
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
void ClearFallback();
|
|
||||||
|
|
||||||
vector<UnknownField>* fields_;
|
|
||||||
|
|
||||||
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(UnknownFieldSet);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Represents one field in an UnknownFieldSet.
|
|
||||||
class LIBPROTOBUF_EXPORT UnknownField {
|
|
||||||
public:
|
|
||||||
enum Type {
|
|
||||||
TYPE_VARINT,
|
|
||||||
TYPE_FIXED32,
|
|
||||||
TYPE_FIXED64,
|
|
||||||
TYPE_LENGTH_DELIMITED,
|
|
||||||
TYPE_GROUP
|
|
||||||
};
|
|
||||||
|
|
||||||
// The field's tag number, as seen on the wire.
|
|
||||||
inline int number() const;
|
|
||||||
|
|
||||||
// The field type.
|
|
||||||
inline Type type() const;
|
|
||||||
|
|
||||||
// Accessors -------------------------------------------------------
|
|
||||||
// Each method works only for UnknownFields of the corresponding type.
|
|
||||||
|
|
||||||
inline uint64 varint() const;
|
|
||||||
inline uint32 fixed32() const;
|
|
||||||
inline uint64 fixed64() const;
|
|
||||||
inline const string& length_delimited() const;
|
|
||||||
inline const UnknownFieldSet& group() const;
|
|
||||||
|
|
||||||
inline void set_varint(uint64 value);
|
|
||||||
inline void set_fixed32(uint32 value);
|
|
||||||
inline void set_fixed64(uint64 value);
|
|
||||||
inline void set_length_delimited(const string& value);
|
|
||||||
inline string* mutable_length_delimited();
|
|
||||||
inline UnknownFieldSet* mutable_group();
|
|
||||||
|
|
||||||
// Serialization API.
|
|
||||||
// These methods can take advantage of the underlying implementation and may
|
|
||||||
// archieve a better performance than using getters to retrieve the data and
|
|
||||||
// do the serialization yourself.
|
|
||||||
void SerializeLengthDelimitedNoTag(io::CodedOutputStream* output) const;
|
|
||||||
uint8* SerializeLengthDelimitedNoTagToArray(uint8* target) const;
|
|
||||||
|
|
||||||
inline int GetLengthDelimitedSize() const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
friend class UnknownFieldSet;
|
|
||||||
|
|
||||||
// If this UnknownField contains a pointer, delete it.
|
|
||||||
void Delete();
|
|
||||||
|
|
||||||
// Make a deep copy of any pointers in this UnknownField.
|
|
||||||
void DeepCopy();
|
|
||||||
|
|
||||||
// Set the wire type of this UnknownField. Should only be used when this
|
|
||||||
// UnknownField is being created.
|
|
||||||
inline void SetType(Type type);
|
|
||||||
|
|
||||||
uint32 number_;
|
|
||||||
uint32 type_;
|
|
||||||
union {
|
|
||||||
uint64 varint_;
|
|
||||||
uint32 fixed32_;
|
|
||||||
uint64 fixed64_;
|
|
||||||
mutable union {
|
|
||||||
string* string_value_;
|
|
||||||
} length_delimited_;
|
|
||||||
UnknownFieldSet* group_;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
// ===================================================================
|
|
||||||
// inline implementations
|
|
||||||
|
|
||||||
inline void UnknownFieldSet::Clear() {
|
|
||||||
if (fields_ != NULL) {
|
|
||||||
ClearFallback();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool UnknownFieldSet::empty() const {
|
|
||||||
return fields_ == NULL || fields_->empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void UnknownFieldSet::Swap(UnknownFieldSet* x) {
|
|
||||||
std::swap(fields_, x->fields_);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline int UnknownFieldSet::field_count() const {
|
|
||||||
return (fields_ == NULL) ? 0 : static_cast<int>(fields_->size());
|
|
||||||
}
|
|
||||||
inline const UnknownField& UnknownFieldSet::field(int index) const {
|
|
||||||
return (*fields_)[index];
|
|
||||||
}
|
|
||||||
inline UnknownField* UnknownFieldSet::mutable_field(int index) {
|
|
||||||
return &(*fields_)[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void UnknownFieldSet::AddLengthDelimited(
|
|
||||||
int number, const string& value) {
|
|
||||||
AddLengthDelimited(number)->assign(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline int UnknownField::number() const { return number_; }
|
|
||||||
inline UnknownField::Type UnknownField::type() const {
|
|
||||||
return static_cast<Type>(type_);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline uint64 UnknownField::varint() const {
|
|
||||||
assert(type() == TYPE_VARINT);
|
|
||||||
return varint_;
|
|
||||||
}
|
|
||||||
inline uint32 UnknownField::fixed32() const {
|
|
||||||
assert(type() == TYPE_FIXED32);
|
|
||||||
return fixed32_;
|
|
||||||
}
|
|
||||||
inline uint64 UnknownField::fixed64() const {
|
|
||||||
assert(type() == TYPE_FIXED64);
|
|
||||||
return fixed64_;
|
|
||||||
}
|
|
||||||
inline const string& UnknownField::length_delimited() const {
|
|
||||||
assert(type() == TYPE_LENGTH_DELIMITED);
|
|
||||||
return *length_delimited_.string_value_;
|
|
||||||
}
|
|
||||||
inline const UnknownFieldSet& UnknownField::group() const {
|
|
||||||
assert(type() == TYPE_GROUP);
|
|
||||||
return *group_;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void UnknownField::set_varint(uint64 value) {
|
|
||||||
assert(type() == TYPE_VARINT);
|
|
||||||
varint_ = value;
|
|
||||||
}
|
|
||||||
inline void UnknownField::set_fixed32(uint32 value) {
|
|
||||||
assert(type() == TYPE_FIXED32);
|
|
||||||
fixed32_ = value;
|
|
||||||
}
|
|
||||||
inline void UnknownField::set_fixed64(uint64 value) {
|
|
||||||
assert(type() == TYPE_FIXED64);
|
|
||||||
fixed64_ = value;
|
|
||||||
}
|
|
||||||
inline void UnknownField::set_length_delimited(const string& value) {
|
|
||||||
assert(type() == TYPE_LENGTH_DELIMITED);
|
|
||||||
length_delimited_.string_value_->assign(value);
|
|
||||||
}
|
|
||||||
inline string* UnknownField::mutable_length_delimited() {
|
|
||||||
assert(type() == TYPE_LENGTH_DELIMITED);
|
|
||||||
return length_delimited_.string_value_;
|
|
||||||
}
|
|
||||||
inline UnknownFieldSet* UnknownField::mutable_group() {
|
|
||||||
assert(type() == TYPE_GROUP);
|
|
||||||
return group_;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline int UnknownField::GetLengthDelimitedSize() const {
|
|
||||||
GOOGLE_DCHECK_EQ(TYPE_LENGTH_DELIMITED, type());
|
|
||||||
return static_cast<int>(length_delimited_.string_value_->size());
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void UnknownField::SetType(Type type) {
|
|
||||||
type_ = type;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace protobuf
|
|
||||||
|
|
||||||
} // namespace google
|
|
||||||
#endif // GOOGLE_PROTOBUF_UNKNOWN_FIELD_SET_H__
|
|
|
@ -1,336 +0,0 @@
|
||||||
// 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.
|
|
||||||
|
|
||||||
// Author: kenton@google.com (Kenton Varda)
|
|
||||||
// atenasio@google.com (Chris Atenasio) (ZigZag transform)
|
|
||||||
// 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_H__
|
|
||||||
#define GOOGLE_PROTOBUF_WIRE_FORMAT_H__
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <google/protobuf/stubs/common.h>
|
|
||||||
#include <google/protobuf/descriptor.pb.h>
|
|
||||||
#include <google/protobuf/descriptor.h>
|
|
||||||
#include <google/protobuf/message.h>
|
|
||||||
#include <google/protobuf/wire_format_lite.h>
|
|
||||||
|
|
||||||
// Do UTF-8 validation on string type in Debug build only
|
|
||||||
#ifndef NDEBUG
|
|
||||||
#define GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace google {
|
|
||||||
namespace protobuf {
|
|
||||||
namespace io {
|
|
||||||
class CodedInputStream; // coded_stream.h
|
|
||||||
class CodedOutputStream; // coded_stream.h
|
|
||||||
}
|
|
||||||
class UnknownFieldSet; // unknown_field_set.h
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace protobuf {
|
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
// 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 code for implementing the binary protocol buffer
|
|
||||||
// wire format via reflection. The WireFormatLite class implements the
|
|
||||||
// non-reflection based routines.
|
|
||||||
//
|
|
||||||
// This class is really a namespace that contains only static methods
|
|
||||||
class LIBPROTOBUF_EXPORT WireFormat {
|
|
||||||
public:
|
|
||||||
|
|
||||||
// Given a field return its WireType
|
|
||||||
static inline WireFormatLite::WireType WireTypeForField(
|
|
||||||
const FieldDescriptor* field);
|
|
||||||
|
|
||||||
// Given a FieldDescriptor::Type return its WireType
|
|
||||||
static inline WireFormatLite::WireType WireTypeForFieldType(
|
|
||||||
FieldDescriptor::Type type);
|
|
||||||
|
|
||||||
// Compute the byte size of a tag. For groups, this includes both the start
|
|
||||||
// and end tags.
|
|
||||||
static inline int TagSize(int field_number, FieldDescriptor::Type type);
|
|
||||||
|
|
||||||
// These procedures can be used to implement the methods of Message which
|
|
||||||
// handle parsing and serialization of the protocol buffer wire format
|
|
||||||
// using only the Reflection interface. When you ask the protocol
|
|
||||||
// compiler to optimize for code size rather than speed, it will implement
|
|
||||||
// those methods in terms of these procedures. Of course, these are much
|
|
||||||
// slower than the specialized implementations which the protocol compiler
|
|
||||||
// generates when told to optimize for speed.
|
|
||||||
|
|
||||||
// Read a message in protocol buffer wire format.
|
|
||||||
//
|
|
||||||
// This procedure reads either to the end of the input stream or through
|
|
||||||
// a WIRETYPE_END_GROUP tag ending the message, whichever comes first.
|
|
||||||
// It returns false if the input is invalid.
|
|
||||||
//
|
|
||||||
// Required fields are NOT checked by this method. You must call
|
|
||||||
// IsInitialized() on the resulting message yourself.
|
|
||||||
static bool ParseAndMergePartial(io::CodedInputStream* input,
|
|
||||||
Message* message);
|
|
||||||
|
|
||||||
// Serialize a message in protocol buffer wire format.
|
|
||||||
//
|
|
||||||
// Any embedded messages within the message must have their correct sizes
|
|
||||||
// cached. However, the top-level message need not; its size is passed as
|
|
||||||
// a parameter to this procedure.
|
|
||||||
//
|
|
||||||
// These return false iff the underlying stream returns a write error.
|
|
||||||
static void SerializeWithCachedSizes(
|
|
||||||
const Message& message,
|
|
||||||
int size, io::CodedOutputStream* output);
|
|
||||||
|
|
||||||
// Implements Message::ByteSize() via reflection. WARNING: The result
|
|
||||||
// of this method is *not* cached anywhere. However, all embedded messages
|
|
||||||
// will have their ByteSize() methods called, so their sizes will be cached.
|
|
||||||
// Therefore, calling this method is sufficient to allow you to call
|
|
||||||
// WireFormat::SerializeWithCachedSizes() on the same object.
|
|
||||||
static int ByteSize(const Message& message);
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------
|
|
||||||
// Helpers for dealing with unknown fields
|
|
||||||
|
|
||||||
// Skips a field value of the given WireType. The input should start
|
|
||||||
// positioned immediately after the tag. If unknown_fields is non-NULL,
|
|
||||||
// the contents of the field will be added to it.
|
|
||||||
static bool SkipField(io::CodedInputStream* input, uint32 tag,
|
|
||||||
UnknownFieldSet* unknown_fields);
|
|
||||||
|
|
||||||
// Reads and ignores a message from the input. If unknown_fields is non-NULL,
|
|
||||||
// the contents will be added to it.
|
|
||||||
static bool SkipMessage(io::CodedInputStream* input,
|
|
||||||
UnknownFieldSet* unknown_fields);
|
|
||||||
|
|
||||||
// Write the contents of an UnknownFieldSet to the output.
|
|
||||||
static void SerializeUnknownFields(const UnknownFieldSet& unknown_fields,
|
|
||||||
io::CodedOutputStream* output);
|
|
||||||
// Same as above, except writing directly to the provided buffer.
|
|
||||||
// Requires that the buffer have sufficient capacity for
|
|
||||||
// ComputeUnknownFieldsSize(unknown_fields).
|
|
||||||
//
|
|
||||||
// Returns a pointer past the last written byte.
|
|
||||||
static uint8* SerializeUnknownFieldsToArray(
|
|
||||||
const UnknownFieldSet& unknown_fields,
|
|
||||||
uint8* target);
|
|
||||||
|
|
||||||
// Same thing except for messages that have the message_set_wire_format
|
|
||||||
// option.
|
|
||||||
static void SerializeUnknownMessageSetItems(
|
|
||||||
const UnknownFieldSet& unknown_fields,
|
|
||||||
io::CodedOutputStream* output);
|
|
||||||
// Same as above, except writing directly to the provided buffer.
|
|
||||||
// Requires that the buffer have sufficient capacity for
|
|
||||||
// ComputeUnknownMessageSetItemsSize(unknown_fields).
|
|
||||||
//
|
|
||||||
// Returns a pointer past the last written byte.
|
|
||||||
static uint8* SerializeUnknownMessageSetItemsToArray(
|
|
||||||
const UnknownFieldSet& unknown_fields,
|
|
||||||
uint8* target);
|
|
||||||
|
|
||||||
// Compute the size of the UnknownFieldSet on the wire.
|
|
||||||
static int ComputeUnknownFieldsSize(const UnknownFieldSet& unknown_fields);
|
|
||||||
|
|
||||||
// Same thing except for messages that have the message_set_wire_format
|
|
||||||
// option.
|
|
||||||
static int ComputeUnknownMessageSetItemsSize(
|
|
||||||
const UnknownFieldSet& unknown_fields);
|
|
||||||
|
|
||||||
|
|
||||||
// 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(const FieldDescriptor* field);
|
|
||||||
|
|
||||||
// Parse a single field. The input should start out positioned immediately
|
|
||||||
// after the tag.
|
|
||||||
static bool ParseAndMergeField(
|
|
||||||
uint32 tag,
|
|
||||||
const FieldDescriptor* field, // May be NULL for unknown
|
|
||||||
Message* message,
|
|
||||||
io::CodedInputStream* input);
|
|
||||||
|
|
||||||
// Serialize a single field.
|
|
||||||
static void SerializeFieldWithCachedSizes(
|
|
||||||
const FieldDescriptor* field, // Cannot be NULL
|
|
||||||
const Message& message,
|
|
||||||
io::CodedOutputStream* output);
|
|
||||||
|
|
||||||
// Compute size of a single field. If the field is a message type, this
|
|
||||||
// will call ByteSize() for the embedded message, insuring that it caches
|
|
||||||
// its size.
|
|
||||||
static int FieldByteSize(
|
|
||||||
const FieldDescriptor* field, // Cannot be NULL
|
|
||||||
const Message& message);
|
|
||||||
|
|
||||||
// Parse/serialize a MessageSet::Item group. Used with messages that use
|
|
||||||
// opion message_set_wire_format = true.
|
|
||||||
static bool ParseAndMergeMessageSetItem(
|
|
||||||
io::CodedInputStream* input,
|
|
||||||
Message* message);
|
|
||||||
static void SerializeMessageSetItemWithCachedSizes(
|
|
||||||
const FieldDescriptor* field,
|
|
||||||
const Message& message,
|
|
||||||
io::CodedOutputStream* output);
|
|
||||||
static int MessageSetItemByteSize(
|
|
||||||
const FieldDescriptor* field,
|
|
||||||
const Message& message);
|
|
||||||
|
|
||||||
// Computes the byte size of a field, excluding tags. For packed fields, it
|
|
||||||
// only includes the size of the raw data, and not the size of the total
|
|
||||||
// length, but for other length-delimited types, the size of the length is
|
|
||||||
// included.
|
|
||||||
static int FieldDataOnlyByteSize(
|
|
||||||
const FieldDescriptor* field, // Cannot be NULL
|
|
||||||
const Message& message);
|
|
||||||
|
|
||||||
enum Operation {
|
|
||||||
PARSE,
|
|
||||||
SERIALIZE,
|
|
||||||
};
|
|
||||||
|
|
||||||
// Verifies that a string field is valid UTF8, logging an error if not.
|
|
||||||
// This function will not be called by newly generated protobuf code
|
|
||||||
// but remains present to support existing code.
|
|
||||||
static void VerifyUTF8String(const char* data, int size, Operation op);
|
|
||||||
// The NamedField variant takes a field name in order to produce an
|
|
||||||
// informative error message if verification fails.
|
|
||||||
static void VerifyUTF8StringNamedField(const char* data,
|
|
||||||
int size,
|
|
||||||
Operation op,
|
|
||||||
const char* field_name);
|
|
||||||
|
|
||||||
private:
|
|
||||||
// Verifies that a string field is valid UTF8, logging an error if not.
|
|
||||||
static void VerifyUTF8StringFallback(
|
|
||||||
const char* data,
|
|
||||||
int size,
|
|
||||||
Operation op,
|
|
||||||
const char* field_name);
|
|
||||||
|
|
||||||
// Skip a MessageSet field.
|
|
||||||
static bool SkipMessageSetField(io::CodedInputStream* input,
|
|
||||||
uint32 field_number,
|
|
||||||
UnknownFieldSet* unknown_fields);
|
|
||||||
|
|
||||||
// Parse a MessageSet field.
|
|
||||||
static bool ParseAndMergeMessageSetField(uint32 field_number,
|
|
||||||
const FieldDescriptor* field,
|
|
||||||
Message* message,
|
|
||||||
io::CodedInputStream* input);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(WireFormat);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Subclass of FieldSkipper which saves skipped fields to an UnknownFieldSet.
|
|
||||||
class LIBPROTOBUF_EXPORT UnknownFieldSetFieldSkipper : public FieldSkipper {
|
|
||||||
public:
|
|
||||||
UnknownFieldSetFieldSkipper(UnknownFieldSet* unknown_fields)
|
|
||||||
: unknown_fields_(unknown_fields) {}
|
|
||||||
virtual ~UnknownFieldSetFieldSkipper() {}
|
|
||||||
|
|
||||||
// implements FieldSkipper -----------------------------------------
|
|
||||||
virtual bool SkipField(io::CodedInputStream* input, uint32 tag);
|
|
||||||
virtual bool SkipMessage(io::CodedInputStream* input);
|
|
||||||
virtual void SkipUnknownEnum(int field_number, int value);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
UnknownFieldSet* unknown_fields_;
|
|
||||||
};
|
|
||||||
|
|
||||||
// inline methods ====================================================
|
|
||||||
|
|
||||||
inline WireFormatLite::WireType WireFormat::WireTypeForField(
|
|
||||||
const FieldDescriptor* field) {
|
|
||||||
if (field->options().packed()) {
|
|
||||||
return WireFormatLite::WIRETYPE_LENGTH_DELIMITED;
|
|
||||||
} else {
|
|
||||||
return WireTypeForFieldType(field->type());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline WireFormatLite::WireType WireFormat::WireTypeForFieldType(
|
|
||||||
FieldDescriptor::Type type) {
|
|
||||||
// Some compilers don't like enum -> enum casts, so we implicit_cast to
|
|
||||||
// int first.
|
|
||||||
return WireFormatLite::WireTypeForFieldType(
|
|
||||||
static_cast<WireFormatLite::FieldType>(
|
|
||||||
implicit_cast<int>(type)));
|
|
||||||
}
|
|
||||||
|
|
||||||
inline uint32 WireFormat::MakeTag(const FieldDescriptor* field) {
|
|
||||||
return WireFormatLite::MakeTag(field->number(), WireTypeForField(field));
|
|
||||||
}
|
|
||||||
|
|
||||||
inline int WireFormat::TagSize(int field_number, FieldDescriptor::Type type) {
|
|
||||||
// Some compilers don't like enum -> enum casts, so we implicit_cast to
|
|
||||||
// int first.
|
|
||||||
return WireFormatLite::TagSize(field_number,
|
|
||||||
static_cast<WireFormatLite::FieldType>(
|
|
||||||
implicit_cast<int>(type)));
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void WireFormat::VerifyUTF8String(const char* data, int size,
|
|
||||||
WireFormat::Operation op) {
|
|
||||||
#ifdef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
|
|
||||||
WireFormat::VerifyUTF8StringFallback(data, size, op, NULL);
|
|
||||||
#else
|
|
||||||
// Avoid the compiler warning about unsued variables.
|
|
||||||
(void)data; (void)size; (void)op;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void WireFormat::VerifyUTF8StringNamedField(
|
|
||||||
const char* data, int size, WireFormat::Operation op,
|
|
||||||
const char* field_name) {
|
|
||||||
#ifdef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
|
|
||||||
WireFormat::VerifyUTF8StringFallback(data, size, op, field_name);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace internal
|
|
||||||
} // namespace protobuf
|
|
||||||
|
|
||||||
} // namespace google
|
|
||||||
#endif // GOOGLE_PROTOBUF_WIRE_FORMAT_H__
|
|
|
@ -1,661 +0,0 @@
|
||||||
// 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.
|
|
||||||
|
|
||||||
// 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);
|
|
||||||
|
|
||||||
// Skips a field value with the given tag. The input should start
|
|
||||||
// positioned immediately after the tag. Skipped values are recorded to a
|
|
||||||
// CodedOutputStream.
|
|
||||||
static bool SkipField(io::CodedInputStream* input, uint32 tag,
|
|
||||||
io::CodedOutputStream* output);
|
|
||||||
|
|
||||||
// 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);
|
|
||||||
|
|
||||||
// Reads and ignores a message from the input. Skipped values are recorded
|
|
||||||
// to a CodedOutputStream.
|
|
||||||
static bool SkipMessage(io::CodedInputStream* input,
|
|
||||||
io::CodedOutputStream* output);
|
|
||||||
|
|
||||||
// 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_arg
|
|
||||||
#define output io::CodedOutputStream* output_arg
|
|
||||||
#define field_number int field_number_arg
|
|
||||||
#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 WriteStringMaybeAliased(
|
|
||||||
field_number, const string& value, output);
|
|
||||||
static void WriteBytesMaybeAliased(
|
|
||||||
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;
|
|
||||||
|
|
||||||
// Like ReadRepeatedFixedSizePrimitive but for packed primitive fields.
|
|
||||||
template <typename CType, enum FieldType DeclaredType>
|
|
||||||
static inline bool ReadPackedFixedSizePrimitive(
|
|
||||||
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);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Subclass of FieldSkipper which saves skipped fields to a CodedOutputStream.
|
|
||||||
|
|
||||||
class LIBPROTOBUF_EXPORT CodedOutputStreamFieldSkipper : public FieldSkipper {
|
|
||||||
public:
|
|
||||||
explicit CodedOutputStreamFieldSkipper(io::CodedOutputStream* unknown_fields)
|
|
||||||
: unknown_fields_(unknown_fields) {}
|
|
||||||
virtual ~CodedOutputStreamFieldSkipper() {}
|
|
||||||
|
|
||||||
// implements FieldSkipper -----------------------------------------
|
|
||||||
virtual bool SkipField(io::CodedInputStream* input, uint32 tag);
|
|
||||||
virtual bool SkipMessage(io::CodedInputStream* input);
|
|
||||||
virtual void SkipUnknownEnum(int field_number, int value);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
io::CodedOutputStream* unknown_fields_;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// 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__
|
|
|
@ -1,860 +0,0 @@
|
||||||
// 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.
|
|
||||||
|
|
||||||
// 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__
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
// This is required for min/max on VS2013 only.
|
|
||||||
#include <algorithm>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#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) {
|
|
||||||
uint64 temp;
|
|
||||||
if (!input->ReadVarint64(&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>
|
|
||||||
inline bool WireFormatLite::ReadPackedFixedSizePrimitive(
|
|
||||||
io::CodedInputStream* input, RepeatedField<CType>* values) {
|
|
||||||
uint32 length;
|
|
||||||
if (!input->ReadVarint32(&length)) return false;
|
|
||||||
const uint32 old_entries = values->size();
|
|
||||||
const uint32 new_entries = length / sizeof(CType);
|
|
||||||
const uint32 new_bytes = new_entries * sizeof(CType);
|
|
||||||
if (new_bytes != length) return false;
|
|
||||||
// We would *like* to pre-allocate the buffer to write into (for
|
|
||||||
// speed), but *must* avoid performing a very large allocation due
|
|
||||||
// to a malicious user-supplied "length" above. So we have a fast
|
|
||||||
// path that pre-allocates when the "length" is less than a bound.
|
|
||||||
// We determine the bound by calling BytesUntilTotalBytesLimit() and
|
|
||||||
// BytesUntilLimit(). These return -1 to mean "no limit set".
|
|
||||||
// There are four cases:
|
|
||||||
// TotalBytesLimit Limit
|
|
||||||
// -1 -1 Use slow path.
|
|
||||||
// -1 >= 0 Use fast path if length <= Limit.
|
|
||||||
// >= 0 -1 Use slow path.
|
|
||||||
// >= 0 >= 0 Use fast path if length <= min(both limits).
|
|
||||||
int64 bytes_limit = input->BytesUntilTotalBytesLimit();
|
|
||||||
if (bytes_limit == -1) {
|
|
||||||
bytes_limit = input->BytesUntilLimit();
|
|
||||||
} else {
|
|
||||||
bytes_limit =
|
|
||||||
min(bytes_limit, static_cast<int64>(input->BytesUntilLimit()));
|
|
||||||
}
|
|
||||||
if (bytes_limit >= new_bytes) {
|
|
||||||
// Fast-path that pre-allocates *values to the final size.
|
|
||||||
#if defined(PROTOBUF_LITTLE_ENDIAN)
|
|
||||||
values->Resize(old_entries + new_entries, 0);
|
|
||||||
// values->mutable_data() may change after Resize(), so do this after:
|
|
||||||
void* dest = reinterpret_cast<void*>(values->mutable_data() + old_entries);
|
|
||||||
if (!input->ReadRaw(dest, new_bytes)) {
|
|
||||||
values->Truncate(old_entries);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
values->Reserve(old_entries + new_entries);
|
|
||||||
CType value;
|
|
||||||
for (int i = 0; i < new_entries; ++i) {
|
|
||||||
if (!ReadPrimitive<CType, DeclaredType>(input, &value)) return false;
|
|
||||||
values->AddAlreadyReserved(value);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
} else {
|
|
||||||
// This is the slow-path case where "length" may be too large to
|
|
||||||
// safely allocate. We read as much as we can into *values
|
|
||||||
// without pre-allocating "length" bytes.
|
|
||||||
CType value;
|
|
||||||
for (uint32 i = 0; i < new_entries; ++i) {
|
|
||||||
if (!ReadPrimitive<CType, DeclaredType>(input, &value)) return false;
|
|
||||||
values->Add(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Specializations of ReadPackedPrimitive for the fixed size types, which use
|
|
||||||
// an optimized code path.
|
|
||||||
#define READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(CPPTYPE, DECLARED_TYPE) \
|
|
||||||
template <> \
|
|
||||||
inline bool WireFormatLite::ReadPackedPrimitive< \
|
|
||||||
CPPTYPE, WireFormatLite::DECLARED_TYPE>( \
|
|
||||||
io::CodedInputStream* input, \
|
|
||||||
RepeatedField<CPPTYPE>* values) { \
|
|
||||||
return ReadPackedFixedSizePrimitive< \
|
|
||||||
CPPTYPE, WireFormatLite::DECLARED_TYPE>(input, values); \
|
|
||||||
}
|
|
||||||
|
|
||||||
READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(uint32, TYPE_FIXED32);
|
|
||||||
READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(uint64, TYPE_FIXED64);
|
|
||||||
READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(int32, TYPE_SFIXED32);
|
|
||||||
READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(int64, TYPE_SFIXED64);
|
|
||||||
READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(float, TYPE_FLOAT);
|
|
||||||
READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(double, TYPE_DOUBLE);
|
|
||||||
|
|
||||||
#undef READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE
|
|
||||||
|
|
||||||
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);
|
|
||||||
return io::CodedOutputStream::WriteStringWithSizeToArray(value, target);
|
|
||||||
}
|
|
||||||
inline uint8* WireFormatLite::WriteBytesToArray(int field_number,
|
|
||||||
const string& value,
|
|
||||||
uint8* target) {
|
|
||||||
target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target);
|
|
||||||
return io::CodedOutputStream::WriteStringWithSizeToArray(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__
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,2 @@
|
||||||
|
*.pb.cc
|
||||||
|
*.pb.h
|
|
@ -0,0 +1 @@
|
||||||
|
add_library(carla_protocol carla_protocol.pb.h carla_protocol.pb.cc)
|
|
@ -1,4 +1,4 @@
|
||||||
|
syntax = "proto2";
|
||||||
|
|
||||||
// Client Messages
|
// Client Messages
|
||||||
message EpisodeStart {
|
message EpisodeStart {
|
|
@ -1,11 +1,3 @@
|
||||||
# add_library(carla_server
|
|
||||||
# CarlaServer.h
|
|
||||||
# CarlaServer.cpp
|
|
||||||
# TCPServer.h
|
|
||||||
# TCPServer.cpp
|
|
||||||
# Protocol.h
|
|
||||||
# Protocol.cpp
|
|
||||||
# )
|
|
||||||
file(GLOB carla_server_SRC
|
file(GLOB carla_server_SRC
|
||||||
"*.h"
|
"*.h"
|
||||||
"*.cpp"
|
"*.cpp"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "carla/Protocol/carlaProtocol/carla_protocol.pb.h"
|
#include <carla/protocol/carla_protocol.pb.h>
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
add_executable(test_async_server async_server.cpp)
|
add_executable(test_async_server async_server.cpp)
|
||||||
target_link_libraries(test_async_server carla_server ${Boost_DATE_TIME_LIBRARY} ${Boost_REGEX_LIBRARY} ${Boost_SYSTEM_LIBRARY})
|
target_link_libraries(test_async_server carla_server ${CMAKE_THREAD_LIBS_INIT} ${Boost_DATE_TIME_LIBRARY} ${Boost_REGEX_LIBRARY} ${Boost_SYSTEM_LIBRARY} ${Protobuf_LIBRARY})
|
||||||
|
|
||||||
add_executable(test_sync_server sync_server.cpp)
|
add_executable(test_sync_server sync_server.cpp)
|
||||||
target_link_libraries(test_sync_server carla_server ${Boost_SYSTEM_LIBRARY} ${Boost_DATE_TIME_LIBRARY} ${Boost_REGEX_LIBRARY})
|
target_link_libraries(test_sync_server carla_server ${CMAKE_THREAD_LIBS_INIT} ${Boost_SYSTEM_LIBRARY} ${Boost_DATE_TIME_LIBRARY} ${Boost_REGEX_LIBRARY} ${Protobuf_LIBRARY})
|
||||||
|
|
||||||
add_executable(test_client client.cpp)
|
add_executable(test_client client.cpp)
|
||||||
target_link_libraries(test_client carla_server libprotobuf libprotobuf-lite libprotoc ${Boost_SYSTEM_LIBRARY} ${Boost_DATE_TIME_LIBRARY} ${Boost_REGEX_LIBRARY})
|
target_link_libraries(test_client carla_server ${CMAKE_THREAD_LIBS_INIT} ${Boost_SYSTEM_LIBRARY} ${Boost_DATE_TIME_LIBRARY} ${Boost_REGEX_LIBRARY} ${Protobuf_LIBRARY})
|
||||||
|
|
Loading…
Reference in New Issue