提交 4dd7b167 编写于 作者: R Ruilong Liu 提交者: GitHub

Merge branch 'develop' into develop

...@@ -9,7 +9,6 @@ option(LOG_PROFILE "log profile" ON) ...@@ -9,7 +9,6 @@ option(LOG_PROFILE "log profile" ON)
option(CPU "armv7 with neon" ON) option(CPU "armv7 with neon" ON)
option(MALI_GPU "mali gpu" OFF) option(MALI_GPU "mali gpu" OFF)
option(FPGA "fpga" OFF) option(FPGA "fpga" OFF)
option(QUANTI "quantification" OFF)
file(GLOB_RECURSE PADDLE_MOBILE_CC src/*.cc src/*.cpp src/*.c src/*.mm) file(GLOB_RECURSE PADDLE_MOBILE_CC src/*.cc src/*.cpp src/*.c src/*.mm)
file(GLOB_RECURSE PADDLE_MOBILE_H src/*.h) file(GLOB_RECURSE PADDLE_MOBILE_H src/*.h)
...@@ -163,7 +162,4 @@ if(DEBUGING) ...@@ -163,7 +162,4 @@ if(DEBUGING)
endif() endif()
endif() endif()
if (QUANTI)
add_subdirectory(tools/quantification)
endif ()
# Quantification 模型量化、反量化
## 背景故事
部分网络如AlexNet训练出的模型体积较大,不适宜在移动设备上使用。
## 解决模型过大办法
1. 选用适合移动端的模型结构如:mobilenet、googlenet、 yolo、squeezenet 等;
2. 使用我们提供的量化工具,可以在几乎不影响精度的情况下将float32模型减小至原模型的 1/4;
- - - - -
## 量化工具介绍
### 模型转化工具目录:
- [量化工具目录](https://github.com/PaddlePaddle/paddle-mobile/tree/develop/tools/quantification)
- [模型转化工具](https://github.com/PaddlePaddle/paddle-mobile/blob/develop/tools/quantification/convert.cpp)
#### 使用说明
- [工具使用](https://github.com/PaddlePaddle/paddle-mobile/blob/develop/tools/quantification/README.md)
## 如何读取量化后的模型
load方法中添加了 quantification 参数,默认为false。 如果需要load量化后的模型,按需传参即可。
[我是源代码](https://github.com/PaddlePaddle/paddle-mobile/blob/55302b33ea3bd68c9797d8f65e527544792b8095/src/io/paddle_mobile.h)
```c++
bool Load(const std::string &dirname, bool optimize = false,
bool quantification = false, int batch_size = 1);
```
- - - - -
set(dir ${CMAKE_CURRENT_SOURCE_DIR}) cmake_minimum_required(VERSION 3.6)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${dir}/build") project(quali)
add_definitions(-DENABLE_EXCEPTION)
ADD_EXECUTABLE(convert convert.cpp) set(CMAKE_CXX_STANDARD 11)
target_link_libraries(convert paddle-mobile) file(GLOB_RECURSE QULIFICATON_CC src/*.cc src/*.cpp src/*.c src/*.mm)
\ No newline at end of file file(GLOB_RECURSE QULIFICATON_H src/*.h)
include_directories(. src/)
#add_library(paddle-mobile SHARED ${QULIFICATON_CC} ${QULIFICATON_H} convert.cpp)
add_executable(quantify convert.cpp ${QULIFICATON_CC} ${QULIFICATON_H})
\ No newline at end of file
# 模型量化脚本
#### 量化脚本使用指南
1. 在PaddleMobile项目目录下(如 ~/PaddleProject/paddle-mobile)
2. cd到 tools/quantification/ 目录
3. cmake编译
``` sh
cmake .
make
```
4. 运行量化脚本
```sh
./quantify (0:seperated. 1:combined ) (输入路径) (输出路径)
# quantify googlenet seperated from /Users/xiebaiyuan/PaddleProject/quali/models/googlenet to ./googlenet_min
./quantify 0 /Users/xiebaiyuan/PaddleProject/quali/models/googlenet ./googlenet_min
```
*注:*
*量化工具中*
*1.seperated模型model文件默认命名为 "__model__";*
*2.combined模型的model文件默认命名为 "model",参数文件默认命名为"params";*
##### 整体如下:
以googlenet非combined为例:
```sh
cd tools/quantification/
cmake .
make
./quantify 0 /Users/xiebaiyuan/PaddleProject/quali/models/googlenet ./googlenet_min
```
#include "io/paddle_mobile.h" #include "src/enforce.h"
#include "src/var_desc.h"
#include "src/program_desc.h"
#include <cstdlib> #include <cstdlib>
using std::string; #include <string>
#include <cmath>
#include <iostream>
#include <utility>
#include <vector>
#include "src/framework.pb-c.h"
#include "src/protobuf-c.h"
#include <fstream>
#include <iostream>
static const std::string g_googlenet_combine = "../models/googlenet_combine";
static const std::string g_googlenet = "../models/googlenet";
using paddle_mobile::Executor;
using paddle_mobile::framework::Program;
char *Get_binary_data(std::string filename) { const size_t kSize64 = sizeof(uint64_t);
const size_t kSize32 = sizeof(uint32_t);
char *Get_binary_data(const std::string &filename) {
FILE *file = fopen(filename.c_str(), "rb"); FILE *file = fopen(filename.c_str(), "rb");
PADDLE_MOBILE_ENFORCE(file != nullptr, "can't open file: %s ", PADDLE_MOBILE_ENFORCE(file != nullptr, "can't open file: %s ",
filename.c_str()); filename.c_str());
fseek(file, 0, SEEK_END); fseek(file, 0, SEEK_END);
int64_t size = ftell(file); int64_t size = ftell(file);
PADDLE_MOBILE_ENFORCE(size > 0, "size is too small"); PADDLE_MOBILE_ENFORCE(size > 0, "size is too small");
rewind(file); rewind(file);
char *data = new char[size]; auto *data = new char[size];
size_t bytes_read = fread(data, 1, size, file); size_t bytes_read = fread(data, 1, static_cast<size_t>(size), file);
PADDLE_MOBILE_ENFORCE(bytes_read == size, PADDLE_MOBILE_ENFORCE(bytes_read == size,
"read binary file bytes do not match with fseek"); "read binary file bytes do not match with fseek");
DLOG << "Get_binary_data end";
fclose(file); fclose(file);
return data; return data;
}
static size_t ReadBuffer(const char *file_name, uint8_t **out) {
FILE *fp;
fp = fopen(file_name, "rb");
PADDLE_MOBILE_ENFORCE(fp != nullptr, " %s open failed !", file_name);
fseek(fp, 0, SEEK_END);
auto size = static_cast<size_t>(ftell(fp));
rewind(fp);
*out = reinterpret_cast<uint8_t *>(malloc(size));
size_t cur_len = 0;
size_t nread;
while ((nread = fread(*out + cur_len, 1, size - cur_len, fp)) != 0) {
cur_len += nread;
} }
fclose(fp);
return cur_len;
}
void LoadWithDump(const paddle_mobile::framework::VarDesc var_desc, std::shared_ptr<ProgramDesc> loadParams(const std::string &model_path) {
paddle_mobile::framework::LoDTensor *tensor, char **data, FILE *out_file) { PaddleMobile__Framework__Proto__ProgramDesc *c_program;
uint8_t *buf = nullptr;
size_t read_size = ReadBuffer(model_path.c_str(), &buf);
PADDLE_MOBILE_ENFORCE(buf != nullptr, "read from __model__ is null");
c_program = paddle_mobile__framework__proto__program_desc__unpack(
nullptr, read_size, buf);
PADDLE_MOBILE_ENFORCE(c_program != nullptr, "program is null");
auto originProgramDesc = std::make_shared<ProgramDesc>(c_program);
return originProgramDesc;
}
void LoadWithDump(const paddle_mobile::framework::VarDesc &var_desc, char *dataP, FILE *out_file) {
// 1. version // 1. version
uint32_t version = *reinterpret_cast<uint32_t *>(*data); uint32_t version = *reinterpret_cast<uint32_t *>(dataP);
// write version // write version
fwrite(&version, sizeof(uint32_t), 1, out_file ); fwrite(&version, kSize32, 1, out_file);
(*data) += sizeof(uint32_t);
dataP += kSize32;
// 2 Lod information // 2 Lod information
uint64_t *lod_level_ptr = new uint64_t(); auto *lod_level_ptr = new uint64_t();
memcpy(lod_level_ptr, (*data), sizeof(uint64_t)); memcpy(lod_level_ptr, dataP, kSize64);
uint64_t lod_level = 0; uint64_t lod_level = 0;
// write lod Information // write lod Information
fwrite(&lod_level, sizeof(uint64_t), 1, out_file); fwrite(&lod_level, kSize64, 1, out_file);
delete lod_level_ptr; delete lod_level_ptr;
(*data) += sizeof(uint64_t);
auto &lod = *tensor->mutable_lod(); dataP += kSize64;
lod.resize(lod_level);
for (uint64_t i = 0; i < lod_level; ++i) { for (uint64_t i = 0; i < lod_level; ++i) {
uint64_t size = *reinterpret_cast<uint64_t *>(*data); uint64_t size = *reinterpret_cast<uint64_t *>(dataP);
// write lod size // write lod size
fwrite(&size, sizeof(uint64_t), 1, out_file); fwrite(&size, kSize64, 1, out_file);
(*data) += sizeof(uint64_t); (dataP) += kSize64;
std::vector<size_t> tmp(size / sizeof(size_t)); std::vector<size_t> tmp(size / sizeof(size_t));
for (int k = 0; k < tmp.size(); ++k) { for (unsigned long &k : tmp) {
tmp[k] = *reinterpret_cast<size_t *>(*data); k = *reinterpret_cast<size_t *>(dataP);
(*data) += sizeof(size_t); (dataP) += sizeof(size_t);
} }
// write lod size vector // write lod size vector
fwrite(&tmp, sizeof(size_t), tmp.size(), out_file ); fwrite(&tmp, sizeof(size_t), tmp.size(), out_file);
lod[i] = tmp;
} }
// 3. tensor version // 3. tensor version
uint32_t tensor_version = *reinterpret_cast<uint32_t *>(*data); uint32_t tensor_version = *reinterpret_cast<uint32_t *>(dataP);
// write tensor version // write tensor version
fwrite(&tensor_version, sizeof(uint32_t), 1, out_file); fwrite(&tensor_version, kSize32, 1, out_file);
(*data) += sizeof(uint32_t); (dataP) += kSize32;
// 4. tensor desc // 4. tensor desc
int32_t size = *reinterpret_cast<int32_t *>(*data); int32_t size = *reinterpret_cast<int32_t *>(dataP);
// write tensor desc // write tensor desc
fwrite(&size, sizeof(int32_t), 1, out_file); fwrite(&size, sizeof(int32_t), 1, out_file);
(*data) += sizeof(int32_t); (dataP) += sizeof(int32_t);
std::unique_ptr<char[]> buf(new char[size]); std::unique_ptr<char[]> buf(new char[size]);
for (int m = 0; m < size; ++m) { for (int m = 0; m < size; ++m) {
buf.get()[m] = (*data)[m]; buf.get()[m] = (dataP)[m];
} }
fwrite(buf.get(), sizeof(char), size, out_file);
(*data) += (sizeof(char) * size); fwrite(buf.get(), sizeof(char), static_cast<size_t>(size), out_file);
(dataP) += (sizeof(char) * size);
const paddle_mobile::framework::TensorDesc &desc = var_desc.Tensor_desc(); const paddle_mobile::framework::TensorDesc &desc = var_desc.Tensor_desc();
int memory_size = 1; int memory_size = 1;
for (auto l : desc.Dims()) { for (auto l : desc.Dims()) {
memory_size *= l; memory_size *= l;
} }
tensor->Resize(paddle_mobile::framework::make_ddim(desc.Dims()));
void *memory = tensor; void *memory = nullptr;
int type_size = 0; int type_size = 0;
switch (desc.DataType()) { switch (desc.DataType()) {
case paddle_mobile::framework::VARTYPE_TYPE_FP16: case paddle_mobile::framework::VARTYPE_TYPE_FP16:
...@@ -93,7 +137,6 @@ using paddle_mobile::framework::Program; ...@@ -93,7 +137,6 @@ using paddle_mobile::framework::Program;
break; break;
case paddle_mobile::framework::VARTYPE_TYPE_FP32: case paddle_mobile::framework::VARTYPE_TYPE_FP32:
type_size = 4; type_size = 4;
memory = tensor->mutable_data<float>();
break; break;
case paddle_mobile::framework::VARTYPE_TYPE_FP64: case paddle_mobile::framework::VARTYPE_TYPE_FP64:
type_size = 8; type_size = 8;
...@@ -110,91 +153,121 @@ using paddle_mobile::framework::Program; ...@@ -110,91 +153,121 @@ using paddle_mobile::framework::Program;
default: default:
break; break;
} }
for (int n = 0; n < memory_size * type_size; ++n) { size_t tensorSize = sizeof(char) * memory_size * type_size;
static_cast<char *>(memory)[n] = (*data)[n];
memory = new char[tensorSize];
for (int n = 0; n < tensorSize; ++n) {
static_cast<char *>(memory)[n] = (dataP)[n];
} }
(*data) += (sizeof(char) * memory_size * type_size); dataP += tensorSize;
// for float 32 // for float 32
float min_value = std::numeric_limits<float>::max(); float min_value = std::numeric_limits<float>::max();
float max_value = std::numeric_limits<float>::min(); float max_value = std::numeric_limits<float>::min();
for (int k = 0; k < memory_size; ++k) { for (int k = 0; k < memory_size; ++k) {
min_value = std::min(min_value, static_cast<float *> (memory)[k]); min_value = std::min(min_value, static_cast<float *> (memory)[k]);
max_value = std::max(max_value, static_cast<float *> (memory)[k]); max_value = std::max(max_value, static_cast<float *> (memory)[k]);
} }
fwrite(&min_value, sizeof(float), 1, out_file); fwrite(&min_value, sizeof(float), 1, out_file);
fwrite(&max_value, sizeof(float), 1, out_file); fwrite(&max_value, sizeof(float), 1, out_file);
for (int g = 0; g < memory_size; ++g) { for (int g = 0; g < memory_size; ++g) {
float value = static_cast<float *> (memory)[g]; float value = static_cast<float *> (memory)[g];
uint8_t factor = (uint8_t) round((value - min_value) / (max_value - min_value) * 255); auto factor = (uint8_t) round((value - min_value) / (max_value - min_value) * 255);
fwrite(&factor, sizeof(uint8_t), 1, out_file); fwrite(&factor, sizeof(uint8_t), 1, out_file);
} }
}
void
quantificate_combined(const std::string &model_path, const std::string &param_path, const std::string &param_min_path) {
} auto program = loadParams(model_path);
char *origin_data = Get_binary_data(param_path);
void quantificate_combined(std::string model_path, std::string param_path, std::string param_min_path){
paddle_mobile::Loader<paddle_mobile::CPU,paddle_mobile::Precision::FP32 > loader;
bool optimize = true;
auto program = loader.Load(model_path, param_path, optimize);
char *origin_data = Get_binary_data(program.para_path);
char *data = origin_data; char *data = origin_data;
FILE *out_file = fopen(param_min_path.c_str(), "wb"); FILE *out_file = fopen(param_min_path.c_str(), "wb");
for (const auto &block : program.originProgram->Blocks()) { for (const auto &block : program->Blocks()) {
for (const auto &var_desc : block->Vars()) { for (const auto &var_desc : block->Vars()) {
auto var = program.scope->Var(var_desc->Name()); if (var_desc->Persistable()) {
if(var_desc ->Persistable()) {
auto tensor = var->template GetMutable<paddle_mobile::framework::LoDTensor>();
if (var_desc->Name() == "feed" || var_desc->Name() == "fetch") { if (var_desc->Name() == "feed" || var_desc->Name() == "fetch") {
continue; continue;
} }
LoadWithDump(*var_desc, tensor, &data,out_file); LoadWithDump(*var_desc, data, out_file);
} }
} }
} }
fclose(out_file); fclose(out_file);
delete origin_data; delete origin_data;
} }
void quantificate_seperated(std::string model_dir, std::string param_min_path) {
paddle_mobile::Loader<paddle_mobile::CPU,paddle_mobile::Precision::FP32 > loader; void quantificate_seperated(const std::string model_dir, const std::string param_min_path) {
bool optimize = true;
auto program = loader.Load(model_dir, optimize); auto program = loadParams(model_dir + "/__model__");
std::string shell_command = "mkdir "+param_min_path;
std::string shell_command = "mkdir " + param_min_path;
system(shell_command.c_str()); system(shell_command.c_str());
for (const auto &block : program.originProgram->Blocks()) {
for (const auto &block : program->Blocks()) {
for (const auto &var_desc : block->Vars()) { for (const auto &var_desc : block->Vars()) {
auto var = program.scope->Var(var_desc->Name()); if (var_desc->Persistable()) {
if(var_desc ->Persistable()) {
auto tensor = var->template GetMutable<paddle_mobile::framework::LoDTensor>();
if (var_desc->Name() == "feed" || var_desc->Name() == "fetch") { if (var_desc->Name() == "feed" || var_desc->Name() == "fetch") {
continue; continue;
} }
std::string file_name = param_min_path +"/"+ var_desc->Name(); std::string file_name = param_min_path + "/" + var_desc->Name();
FILE *out_file = fopen(file_name.c_str(), "wb"); FILE *out_file = fopen(file_name.c_str(), "wb");
char *origin_data = char *origin_data = Get_binary_data(model_dir + "/" + var_desc->Name());
Get_binary_data(program.model_path + "/" + var_desc->Name());
char *data = origin_data; char *data = origin_data;
LoadWithDump(*var_desc, tensor, &data,out_file); LoadWithDump(*var_desc, data, out_file);
delete origin_data; delete origin_data;
fclose(out_file); fclose(out_file);
} }
} }
} }
}
int main(int argc, char **argv) {
const std::string kNoteEg = "( eg: ./quantify 1 your_combined_model_path output_path or ./quantify 0 your_seperated_model_path output_path)";
PADDLE_MOBILE_ENFORCE(argc > 1, "wee need params.%s ", kNoteEg.c_str());
std::string action_type = argv[1];
PADDLE_MOBILE_ENFORCE(argc > 1 && (action_type) == "1" || action_type == "0",
"only 1 or 2 supported, current is %s %s ",
action_type.c_str(),
kNoteEg.c_str());
PADDLE_MOBILE_ENFORCE(argc > 2, "we need your model path. %s ", kNoteEg.c_str());
std::string base_path = argv[2];
PADDLE_MOBILE_ENFORCE(argc > 3, "we need your output path. %s ", kNoteEg.c_str());
std::string output_path = argv[3];
if (action_type == "0") {
// for seperated
const std::string &seperated_min_dir = output_path;
quantificate_seperated(base_path, seperated_min_dir);
return 0;
} }
int main() {
std::string filename = "params_min"; if (action_type == "1") {
std::string model_path = g_googlenet_combine + "/model"; // for combined
std::string param_path = g_googlenet_combine + "/params"; const std::string &combined_min_dir = output_path;
std::string dirname = "param_min_dir"; std::string model_path = base_path + "/model";
std::string model_dir = g_googlenet; std::string param_path = base_path + "/params";
// quantificate_combined(model_path, param_path,filename); quantificate_combined(model_path, param_path, combined_min_dir);
quantificate_seperated(model_dir, dirname);
return 0; return 0;
} }
return -1;
}
......
/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. */
//
// Created by 谢柏渊 on 2018/7/25.
//
#include "src/block_desc_local.h"
#include <algorithm>
#include <memory>
#include <vector>
#include "src/framework.pb-c.h"
std::vector<std::shared_ptr<paddle_mobile::framework::VarDesc>>
BlockDesc::Vars() const {
return vars_;
}
BlockDesc::BlockDesc(PaddleMobile__Framework__Proto__BlockDesc *desc)
: index_(desc->idx), parent_index_(desc->idx) {
for (int i = 0; i < desc->n_vars; ++i) {
PaddleMobile__Framework__Proto__VarDesc *var_desc = desc->vars[i];
vars_.emplace_back(std::shared_ptr<paddle_mobile::framework::VarDesc>(
new paddle_mobile::framework::VarDesc(var_desc)));
}
std::sort(vars_.begin(), vars_.end(),
[](std::shared_ptr<paddle_mobile::framework::VarDesc> left,
std::shared_ptr<paddle_mobile::framework::VarDesc> right) {
return left->Name() < right->Name();
});
// for (int j = 0; j < desc->n_ops; ++j) {
// PaddleMobile__Framework__Proto__OpDesc *op_desc = desc->ops[j];
// ops_.emplace_back(new OpDesc(op_desc));
// }
}
/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. */
//
// Created by 谢柏渊 on 2018/7/25.
//
#ifndef TOOLS_QUANTIFICATION_SRC_BLOCK_DESC_LOCAL_H_
#define TOOLS_QUANTIFICATION_SRC_BLOCK_DESC_LOCAL_H_
#include <vector>
#include "src/var_desc.h"
class BlockDesc {
public:
friend class Node;
friend class ProgramOptimize;
BlockDesc() {}
explicit BlockDesc(PaddleMobile__Framework__Proto__BlockDesc *desc);
const int &ID() const { return index_; }
const bool &MultiThread() const { return multi_thread_; }
const int &Parent() const { return parent_index_; }
bool operator==(const BlockDesc &in_block) const {
return this->ID() == in_block.ID() && this->Parent() == in_block.Parent();
}
bool operator<(const BlockDesc &in_block) const {
return this->ID() < in_block.ID() && this->Parent() < in_block.Parent();
}
std::vector<std::shared_ptr<paddle_mobile::framework::VarDesc>> Vars() const;
private:
int index_;
bool multi_thread_;
int parent_index_;
std::vector<std::shared_ptr<paddle_mobile::framework::VarDesc>> vars_;
};
#endif // TOOLS_QUANTIFICATION_SRC_BLOCK_DESC_LOCAL_H_
/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. */
#pragma once
#ifdef ENABLE_EXCEPTION
#include <stdio.h>
#include <exception>
#include <string>
#endif
namespace paddle_mobile {
#ifdef ENABLE_EXCEPTION
struct PaddleMobileException : public std::exception {
const std::string exception_prefix = "paddle mobile C++ Exception: \n";
std::string message;
PaddleMobileException(const char *header, const char *detail,
const char *file, const int line) {
char buffer[1500];
snprintf(buffer, sizeof(buffer),
"%s| %s \n| [in file] : %s\n| [on line] : %d\n| [detail] : %s\n",
exception_prefix.c_str(), header, file, line, detail);
message = std::string(buffer);
}
const char *what() const noexcept { return message.c_str(); }
};
#define PADDLE_MOBILE_THROW_EXCEPTION(...) \
{ \
char buffer[1000]; \
snprintf(buffer, sizeof(buffer), __VA_ARGS__); \
std::string detail(buffer); \
throw paddle_mobile::PaddleMobileException("Custom Exception", buffer, \
__FILE__, __LINE__); \
}
#define PADDLE_MOBILE_ENFORCE(stat, ...) \
{ \
if (stat) { \
} else { \
char buffer[1000]; \
snprintf(buffer, sizeof(buffer), __VA_ARGS__); \
std::string detail(buffer); \
throw paddle_mobile::PaddleMobileException("paddle-mobile enforce", \
buffer, __FILE__, __LINE__); \
} \
}
#else
#define PADDLE_MOBILE_THROW_EXCEPTION(...)
#define PADDLE_MOBILE_ENFORCE(stat, ...)
#endif
} // namespace paddle_mobile
/* Generated by the protocol buffer compiler. DO NOT EDIT! */
/* Generated from: framework.proto */
/* Do not generate deprecated warnings for self */
#ifndef PROTOBUF_C__NO_DEPRECATED
#define PROTOBUF_C__NO_DEPRECATED
#endif
#include "framework.pb-c.h"
void paddle_mobile__framework__proto__op_desc__attr__init(
PaddleMobile__Framework__Proto__OpDesc__Attr *message) {
static const PaddleMobile__Framework__Proto__OpDesc__Attr init_value =
PADDLE_MOBILE__FRAMEWORK__PROTO__OP_DESC__ATTR__INIT;
*message = init_value;
}
void paddle_mobile__framework__proto__op_desc__var__init(
PaddleMobile__Framework__Proto__OpDesc__Var *message) {
static const PaddleMobile__Framework__Proto__OpDesc__Var init_value =
PADDLE_MOBILE__FRAMEWORK__PROTO__OP_DESC__VAR__INIT;
*message = init_value;
}
void paddle_mobile__framework__proto__op_desc__init(
PaddleMobile__Framework__Proto__OpDesc *message) {
static const PaddleMobile__Framework__Proto__OpDesc init_value =
PADDLE_MOBILE__FRAMEWORK__PROTO__OP_DESC__INIT;
*message = init_value;
}
size_t paddle_mobile__framework__proto__op_desc__get_packed_size(
const PaddleMobile__Framework__Proto__OpDesc *message) {
assert(message->base.descriptor ==
&paddle_mobile__framework__proto__op_desc__descriptor);
return protobuf_c_message_get_packed_size(
(const ProtobufCMessage *)(message));
}
PaddleMobile__Framework__Proto__OpDesc *
paddle_mobile__framework__proto__op_desc__unpack(ProtobufCAllocator *allocator,
size_t len,
const uint8_t *data) {
return (PaddleMobile__Framework__Proto__OpDesc *)protobuf_c_message_unpack(
&paddle_mobile__framework__proto__op_desc__descriptor, allocator, len,
data);
}
void paddle_mobile__framework__proto__op_desc__free_unpacked(
PaddleMobile__Framework__Proto__OpDesc *message,
ProtobufCAllocator *allocator) {
if (!message) return;
assert(message->base.descriptor ==
&paddle_mobile__framework__proto__op_desc__descriptor);
protobuf_c_message_free_unpacked((ProtobufCMessage *)message, allocator);
}
void paddle_mobile__framework__proto__op_proto__var__init(
PaddleMobile__Framework__Proto__OpProto__Var *message) {
static const PaddleMobile__Framework__Proto__OpProto__Var init_value =
PADDLE_MOBILE__FRAMEWORK__PROTO__OP_PROTO__VAR__INIT;
*message = init_value;
}
void paddle_mobile__framework__proto__op_proto__attr__init(
PaddleMobile__Framework__Proto__OpProto__Attr *message) {
static const PaddleMobile__Framework__Proto__OpProto__Attr init_value =
PADDLE_MOBILE__FRAMEWORK__PROTO__OP_PROTO__ATTR__INIT;
*message = init_value;
}
void paddle_mobile__framework__proto__op_proto__init(
PaddleMobile__Framework__Proto__OpProto *message) {
static const PaddleMobile__Framework__Proto__OpProto init_value =
PADDLE_MOBILE__FRAMEWORK__PROTO__OP_PROTO__INIT;
*message = init_value;
}
size_t paddle_mobile__framework__proto__op_proto__get_packed_size(
const PaddleMobile__Framework__Proto__OpProto *message) {
assert(message->base.descriptor ==
&paddle_mobile__framework__proto__op_proto__descriptor);
return protobuf_c_message_get_packed_size(
(const ProtobufCMessage *)(message));
}
PaddleMobile__Framework__Proto__OpProto *
paddle_mobile__framework__proto__op_proto__unpack(ProtobufCAllocator *allocator,
size_t len,
const uint8_t *data) {
return (PaddleMobile__Framework__Proto__OpProto *)protobuf_c_message_unpack(
&paddle_mobile__framework__proto__op_proto__descriptor, allocator, len,
data);
}
void paddle_mobile__framework__proto__op_proto__free_unpacked(
PaddleMobile__Framework__Proto__OpProto *message,
ProtobufCAllocator *allocator) {
if (!message) return;
assert(message->base.descriptor ==
&paddle_mobile__framework__proto__op_proto__descriptor);
protobuf_c_message_free_unpacked((ProtobufCMessage *)message, allocator);
}
void paddle_mobile__framework__proto__var_type__tensor_desc__init(
PaddleMobile__Framework__Proto__VarType__TensorDesc *message) {
static const PaddleMobile__Framework__Proto__VarType__TensorDesc init_value =
PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__TENSOR_DESC__INIT;
*message = init_value;
}
void paddle_mobile__framework__proto__var_type__lo_dtensor_desc__init(
PaddleMobile__Framework__Proto__VarType__LoDTensorDesc *message) {
static const PaddleMobile__Framework__Proto__VarType__LoDTensorDesc
init_value =
PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__LO_DTENSOR_DESC__INIT;
*message = init_value;
}
void paddle_mobile__framework__proto__var_type__lo_dtensor_array_desc__init(
PaddleMobile__Framework__Proto__VarType__LoDTensorArrayDesc *message) {
static const PaddleMobile__Framework__Proto__VarType__LoDTensorArrayDesc
init_value =
PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__LO_DTENSOR_ARRAY_DESC__INIT;
*message = init_value;
}
void paddle_mobile__framework__proto__var_type__reader_desc__init(
PaddleMobile__Framework__Proto__VarType__ReaderDesc *message) {
static const PaddleMobile__Framework__Proto__VarType__ReaderDesc init_value =
PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__READER_DESC__INIT;
*message = init_value;
}
void paddle_mobile__framework__proto__var_type__channel_desc__init(
PaddleMobile__Framework__Proto__VarType__ChannelDesc *message) {
static const PaddleMobile__Framework__Proto__VarType__ChannelDesc init_value =
PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__CHANNEL_DESC__INIT;
*message = init_value;
}
void paddle_mobile__framework__proto__var_type__tuple__init(
PaddleMobile__Framework__Proto__VarType__Tuple *message) {
static const PaddleMobile__Framework__Proto__VarType__Tuple init_value =
PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__TUPLE__INIT;
*message = init_value;
}
void paddle_mobile__framework__proto__var_type__init(
PaddleMobile__Framework__Proto__VarType *message) {
static const PaddleMobile__Framework__Proto__VarType init_value =
PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__INIT;
*message = init_value;
}
size_t paddle_mobile__framework__proto__var_type__get_packed_size(
const PaddleMobile__Framework__Proto__VarType *message) {
assert(message->base.descriptor ==
&paddle_mobile__framework__proto__var_type__descriptor);
return protobuf_c_message_get_packed_size(
(const ProtobufCMessage *)(message));
}
PaddleMobile__Framework__Proto__VarType *
paddle_mobile__framework__proto__var_type__unpack(ProtobufCAllocator *allocator,
size_t len,
const uint8_t *data) {
return (PaddleMobile__Framework__Proto__VarType *)protobuf_c_message_unpack(
&paddle_mobile__framework__proto__var_type__descriptor, allocator, len,
data);
}
void paddle_mobile__framework__proto__var_type__free_unpacked(
PaddleMobile__Framework__Proto__VarType *message,
ProtobufCAllocator *allocator) {
if (!message) return;
assert(message->base.descriptor ==
&paddle_mobile__framework__proto__var_type__descriptor);
protobuf_c_message_free_unpacked((ProtobufCMessage *)message, allocator);
}
void paddle_mobile__framework__proto__var_desc__init(
PaddleMobile__Framework__Proto__VarDesc *message) {
static const PaddleMobile__Framework__Proto__VarDesc init_value =
PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_DESC__INIT;
*message = init_value;
}
size_t paddle_mobile__framework__proto__var_desc__get_packed_size(
const PaddleMobile__Framework__Proto__VarDesc *message) {
assert(message->base.descriptor ==
&paddle_mobile__framework__proto__var_desc__descriptor);
return protobuf_c_message_get_packed_size(
(const ProtobufCMessage *)(message));
}
PaddleMobile__Framework__Proto__VarDesc *
paddle_mobile__framework__proto__var_desc__unpack(ProtobufCAllocator *allocator,
size_t len,
const uint8_t *data) {
return (PaddleMobile__Framework__Proto__VarDesc *)protobuf_c_message_unpack(
&paddle_mobile__framework__proto__var_desc__descriptor, allocator, len,
data);
}
void paddle_mobile__framework__proto__var_desc__free_unpacked(
PaddleMobile__Framework__Proto__VarDesc *message,
ProtobufCAllocator *allocator) {
if (!message) return;
assert(message->base.descriptor ==
&paddle_mobile__framework__proto__var_desc__descriptor);
protobuf_c_message_free_unpacked((ProtobufCMessage *)message, allocator);
}
void paddle_mobile__framework__proto__block_desc__init(
PaddleMobile__Framework__Proto__BlockDesc *message) {
static const PaddleMobile__Framework__Proto__BlockDesc init_value =
PADDLE_MOBILE__FRAMEWORK__PROTO__BLOCK_DESC__INIT;
*message = init_value;
}
size_t paddle_mobile__framework__proto__block_desc__get_packed_size(
const PaddleMobile__Framework__Proto__BlockDesc *message) {
assert(message->base.descriptor ==
&paddle_mobile__framework__proto__block_desc__descriptor);
return protobuf_c_message_get_packed_size(
(const ProtobufCMessage *)(message));
}
PaddleMobile__Framework__Proto__BlockDesc *
paddle_mobile__framework__proto__block_desc__unpack(
ProtobufCAllocator *allocator, size_t len, const uint8_t *data) {
return (PaddleMobile__Framework__Proto__BlockDesc *)protobuf_c_message_unpack(
&paddle_mobile__framework__proto__block_desc__descriptor, allocator, len,
data);
}
void paddle_mobile__framework__proto__block_desc__free_unpacked(
PaddleMobile__Framework__Proto__BlockDesc *message,
ProtobufCAllocator *allocator) {
if (!message) return;
assert(message->base.descriptor ==
&paddle_mobile__framework__proto__block_desc__descriptor);
protobuf_c_message_free_unpacked((ProtobufCMessage *)message, allocator);
}
void paddle_mobile__framework__proto__program_desc__init(
PaddleMobile__Framework__Proto__ProgramDesc *message) {
static const PaddleMobile__Framework__Proto__ProgramDesc init_value =
PADDLE_MOBILE__FRAMEWORK__PROTO__PROGRAM_DESC__INIT;
*message = init_value;
}
size_t paddle_mobile__framework__proto__program_desc__get_packed_size(
const PaddleMobile__Framework__Proto__ProgramDesc *message) {
assert(message->base.descriptor ==
&paddle_mobile__framework__proto__program_desc__descriptor);
return protobuf_c_message_get_packed_size(
(const ProtobufCMessage *)(message));
}
PaddleMobile__Framework__Proto__ProgramDesc *
paddle_mobile__framework__proto__program_desc__unpack(
ProtobufCAllocator *allocator, size_t len, const uint8_t *data) {
return (PaddleMobile__Framework__Proto__ProgramDesc *)
protobuf_c_message_unpack(
&paddle_mobile__framework__proto__program_desc__descriptor, allocator,
len, data);
}
void paddle_mobile__framework__proto__program_desc__free_unpacked(
PaddleMobile__Framework__Proto__ProgramDesc *message,
ProtobufCAllocator *allocator) {
if (!message) return;
assert(message->base.descriptor ==
&paddle_mobile__framework__proto__program_desc__descriptor);
protobuf_c_message_free_unpacked((ProtobufCMessage *)message, allocator);
}
static const ProtobufCFieldDescriptor
paddle_mobile__framework__proto__op_desc__attr__field_descriptors[12] = {
{
"name", 1, PROTOBUF_C_LABEL_REQUIRED, PROTOBUF_C_TYPE_STRING,
0, /* quantifier_offset */
offsetof(PaddleMobile__Framework__Proto__OpDesc__Attr, name), NULL,
NULL, 0, /* flags */
0, NULL, NULL /* reserved1,reserved2, etc */
},
{
"type", 2, PROTOBUF_C_LABEL_REQUIRED, PROTOBUF_C_TYPE_ENUM,
0, /* quantifier_offset */
offsetof(PaddleMobile__Framework__Proto__OpDesc__Attr, type),
&paddle_mobile__framework__proto__attr_type__descriptor, NULL,
0, /* flags */
0, NULL, NULL /* reserved1,reserved2, etc */
},
{
"i", 3, PROTOBUF_C_LABEL_OPTIONAL, PROTOBUF_C_TYPE_INT32,
offsetof(PaddleMobile__Framework__Proto__OpDesc__Attr, has_i),
offsetof(PaddleMobile__Framework__Proto__OpDesc__Attr, i), NULL,
NULL, 0, /* flags */
0, NULL, NULL /* reserved1,reserved2, etc */
},
{
"f", 4, PROTOBUF_C_LABEL_OPTIONAL, PROTOBUF_C_TYPE_FLOAT,
offsetof(PaddleMobile__Framework__Proto__OpDesc__Attr, has_f),
offsetof(PaddleMobile__Framework__Proto__OpDesc__Attr, f), NULL,
NULL, 0, /* flags */
0, NULL, NULL /* reserved1,reserved2, etc */
},
{
"s", 5, PROTOBUF_C_LABEL_OPTIONAL, PROTOBUF_C_TYPE_STRING,
0, /* quantifier_offset */
offsetof(PaddleMobile__Framework__Proto__OpDesc__Attr, s), NULL,
NULL, 0, /* flags */
0, NULL, NULL /* reserved1,reserved2, etc */
},
{
"ints", 6, PROTOBUF_C_LABEL_REPEATED, PROTOBUF_C_TYPE_INT32,
offsetof(PaddleMobile__Framework__Proto__OpDesc__Attr, n_ints),
offsetof(PaddleMobile__Framework__Proto__OpDesc__Attr, ints), NULL,
NULL, 0, /* flags */
0, NULL, NULL /* reserved1,reserved2, etc */
},
{
"floats", 7, PROTOBUF_C_LABEL_REPEATED, PROTOBUF_C_TYPE_FLOAT,
offsetof(PaddleMobile__Framework__Proto__OpDesc__Attr, n_floats),
offsetof(PaddleMobile__Framework__Proto__OpDesc__Attr, floats),
NULL, NULL, 0, /* flags */
0, NULL, NULL /* reserved1,reserved2, etc */
},
{
"strings", 8, PROTOBUF_C_LABEL_REPEATED, PROTOBUF_C_TYPE_STRING,
offsetof(PaddleMobile__Framework__Proto__OpDesc__Attr, n_strings),
offsetof(PaddleMobile__Framework__Proto__OpDesc__Attr, strings),
NULL, NULL, 0, /* flags */
0, NULL, NULL /* reserved1,reserved2, etc */
},
{
"b", 10, PROTOBUF_C_LABEL_OPTIONAL, PROTOBUF_C_TYPE_BOOL,
offsetof(PaddleMobile__Framework__Proto__OpDesc__Attr, has_b),
offsetof(PaddleMobile__Framework__Proto__OpDesc__Attr, b), NULL,
NULL, 0, /* flags */
0, NULL, NULL /* reserved1,reserved2, etc */
},
{
"bools", 11, PROTOBUF_C_LABEL_REPEATED, PROTOBUF_C_TYPE_BOOL,
offsetof(PaddleMobile__Framework__Proto__OpDesc__Attr, n_bools),
offsetof(PaddleMobile__Framework__Proto__OpDesc__Attr, bools), NULL,
NULL, 0, /* flags */
0, NULL, NULL /* reserved1,reserved2, etc */
},
{
"block_idx", 12, PROTOBUF_C_LABEL_OPTIONAL, PROTOBUF_C_TYPE_INT32,
offsetof(PaddleMobile__Framework__Proto__OpDesc__Attr,
has_block_idx),
offsetof(PaddleMobile__Framework__Proto__OpDesc__Attr, block_idx),
NULL, NULL, 0, /* flags */
0, NULL, NULL /* reserved1,reserved2, etc */
},
{
"l", 13, PROTOBUF_C_LABEL_OPTIONAL, PROTOBUF_C_TYPE_INT64,
offsetof(PaddleMobile__Framework__Proto__OpDesc__Attr, has_l),
offsetof(PaddleMobile__Framework__Proto__OpDesc__Attr, l), NULL,
NULL, 0, /* flags */
0, NULL, NULL /* reserved1,reserved2, etc */
},
};
static const unsigned
paddle_mobile__framework__proto__op_desc__attr__field_indices_by_name[] = {
8, /* field[8] = b */
10, /* field[10] = block_idx */
9, /* field[9] = bools */
3, /* field[3] = f */
6, /* field[6] = floats */
2, /* field[2] = i */
5, /* field[5] = ints */
11, /* field[11] = l */
0, /* field[0] = name */
4, /* field[4] = s */
7, /* field[7] = strings */
1, /* field[1] = type */
};
static const ProtobufCIntRange
paddle_mobile__framework__proto__op_desc__attr__number_ranges[2 + 1] = {
{1, 0}, {10, 8}, {0, 12}};
const ProtobufCMessageDescriptor
paddle_mobile__framework__proto__op_desc__attr__descriptor = {
PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC,
"paddle_mobile.framework.proto.OpDesc.Attr",
"Attr",
"PaddleMobile__Framework__Proto__OpDesc__Attr",
"paddle_mobile.framework.proto",
sizeof(PaddleMobile__Framework__Proto__OpDesc__Attr),
12,
paddle_mobile__framework__proto__op_desc__attr__field_descriptors,
paddle_mobile__framework__proto__op_desc__attr__field_indices_by_name,
2,
paddle_mobile__framework__proto__op_desc__attr__number_ranges,
(ProtobufCMessageInit)
paddle_mobile__framework__proto__op_desc__attr__init,
NULL,
NULL,
NULL /* reserved[123] */
};
static const ProtobufCFieldDescriptor
paddle_mobile__framework__proto__op_desc__var__field_descriptors[2] = {
{
"parameter", 1, PROTOBUF_C_LABEL_REQUIRED, PROTOBUF_C_TYPE_STRING,
0, /* quantifier_offset */
offsetof(PaddleMobile__Framework__Proto__OpDesc__Var, parameter),
NULL, NULL, 0, /* flags */
0, NULL, NULL /* reserved1,reserved2, etc */
},
{
"arguments", 2, PROTOBUF_C_LABEL_REPEATED, PROTOBUF_C_TYPE_STRING,
offsetof(PaddleMobile__Framework__Proto__OpDesc__Var, n_arguments),
offsetof(PaddleMobile__Framework__Proto__OpDesc__Var, arguments),
NULL, NULL, 0, /* flags */
0, NULL, NULL /* reserved1,reserved2, etc */
},
};
static const unsigned
paddle_mobile__framework__proto__op_desc__var__field_indices_by_name[] = {
1, /* field[1] = arguments */
0, /* field[0] = parameter */
};
static const ProtobufCIntRange
paddle_mobile__framework__proto__op_desc__var__number_ranges[1 + 1] = {
{1, 0}, {0, 2}};
const ProtobufCMessageDescriptor
paddle_mobile__framework__proto__op_desc__var__descriptor = {
PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC,
"paddle_mobile.framework.proto.OpDesc.Var",
"Var",
"PaddleMobile__Framework__Proto__OpDesc__Var",
"paddle_mobile.framework.proto",
sizeof(PaddleMobile__Framework__Proto__OpDesc__Var),
2,
paddle_mobile__framework__proto__op_desc__var__field_descriptors,
paddle_mobile__framework__proto__op_desc__var__field_indices_by_name,
1,
paddle_mobile__framework__proto__op_desc__var__number_ranges,
(ProtobufCMessageInit)
paddle_mobile__framework__proto__op_desc__var__init,
NULL,
NULL,
NULL /* reserved[123] */
};
static const protobuf_c_boolean
paddle_mobile__framework__proto__op_desc__is_target__default_value = 0;
static const ProtobufCFieldDescriptor
paddle_mobile__framework__proto__op_desc__field_descriptors[5] = {
{
"inputs", 1, PROTOBUF_C_LABEL_REPEATED, PROTOBUF_C_TYPE_MESSAGE,
offsetof(PaddleMobile__Framework__Proto__OpDesc, n_inputs),
offsetof(PaddleMobile__Framework__Proto__OpDesc, inputs),
&paddle_mobile__framework__proto__op_desc__var__descriptor, NULL,
0, /* flags */
0, NULL, NULL /* reserved1,reserved2, etc */
},
{
"outputs", 2, PROTOBUF_C_LABEL_REPEATED, PROTOBUF_C_TYPE_MESSAGE,
offsetof(PaddleMobile__Framework__Proto__OpDesc, n_outputs),
offsetof(PaddleMobile__Framework__Proto__OpDesc, outputs),
&paddle_mobile__framework__proto__op_desc__var__descriptor, NULL,
0, /* flags */
0, NULL, NULL /* reserved1,reserved2, etc */
},
{
"type", 3, PROTOBUF_C_LABEL_REQUIRED, PROTOBUF_C_TYPE_STRING,
0, /* quantifier_offset */
offsetof(PaddleMobile__Framework__Proto__OpDesc, type), NULL, NULL,
0, /* flags */
0, NULL, NULL /* reserved1,reserved2, etc */
},
{
"attrs", 4, PROTOBUF_C_LABEL_REPEATED, PROTOBUF_C_TYPE_MESSAGE,
offsetof(PaddleMobile__Framework__Proto__OpDesc, n_attrs),
offsetof(PaddleMobile__Framework__Proto__OpDesc, attrs),
&paddle_mobile__framework__proto__op_desc__attr__descriptor, NULL,
0, /* flags */
0, NULL, NULL /* reserved1,reserved2, etc */
},
{
"is_target", 5, PROTOBUF_C_LABEL_OPTIONAL, PROTOBUF_C_TYPE_BOOL,
offsetof(PaddleMobile__Framework__Proto__OpDesc, has_is_target),
offsetof(PaddleMobile__Framework__Proto__OpDesc, is_target), NULL,
&paddle_mobile__framework__proto__op_desc__is_target__default_value,
0, /* flags */
0, NULL, NULL /* reserved1,reserved2, etc */
},
};
static const unsigned
paddle_mobile__framework__proto__op_desc__field_indices_by_name[] = {
3, /* field[3] = attrs */
0, /* field[0] = inputs */
4, /* field[4] = is_target */
1, /* field[1] = outputs */
2, /* field[2] = type */
};
static const ProtobufCIntRange
paddle_mobile__framework__proto__op_desc__number_ranges[1 + 1] = {{1, 0},
{0, 5}};
const ProtobufCMessageDescriptor
paddle_mobile__framework__proto__op_desc__descriptor = {
PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC,
"paddle_mobile.framework.proto.OpDesc",
"OpDesc",
"PaddleMobile__Framework__Proto__OpDesc",
"paddle_mobile.framework.proto",
sizeof(PaddleMobile__Framework__Proto__OpDesc),
5,
paddle_mobile__framework__proto__op_desc__field_descriptors,
paddle_mobile__framework__proto__op_desc__field_indices_by_name,
1,
paddle_mobile__framework__proto__op_desc__number_ranges,
(ProtobufCMessageInit)paddle_mobile__framework__proto__op_desc__init,
NULL,
NULL,
NULL /* reserved[123] */
};
static const protobuf_c_boolean
paddle_mobile__framework__proto__op_proto__var__duplicable__default_value =
0;
static const protobuf_c_boolean
paddle_mobile__framework__proto__op_proto__var__intermediate__default_value =
0;
static const protobuf_c_boolean
paddle_mobile__framework__proto__op_proto__var__dispensable__default_value =
0;
static const ProtobufCFieldDescriptor
paddle_mobile__framework__proto__op_proto__var__field_descriptors[5] = {
{
"name", 1, PROTOBUF_C_LABEL_REQUIRED, PROTOBUF_C_TYPE_STRING,
0, /* quantifier_offset */
offsetof(PaddleMobile__Framework__Proto__OpProto__Var, name), NULL,
NULL, 0, /* flags */
0, NULL, NULL /* reserved1,reserved2, etc */
},
{
"comment", 2, PROTOBUF_C_LABEL_REQUIRED, PROTOBUF_C_TYPE_STRING,
0, /* quantifier_offset */
offsetof(PaddleMobile__Framework__Proto__OpProto__Var, comment),
NULL, NULL, 0, /* flags */
0, NULL, NULL /* reserved1,reserved2, etc */
},
{
"duplicable", 3, PROTOBUF_C_LABEL_OPTIONAL, PROTOBUF_C_TYPE_BOOL,
offsetof(PaddleMobile__Framework__Proto__OpProto__Var,
has_duplicable),
offsetof(PaddleMobile__Framework__Proto__OpProto__Var, duplicable),
NULL,
&paddle_mobile__framework__proto__op_proto__var__duplicable__default_value,
0, /* flags */
0, NULL, NULL /* reserved1,reserved2, etc */
},
{
"intermediate", 4, PROTOBUF_C_LABEL_OPTIONAL, PROTOBUF_C_TYPE_BOOL,
offsetof(PaddleMobile__Framework__Proto__OpProto__Var,
has_intermediate),
offsetof(PaddleMobile__Framework__Proto__OpProto__Var,
intermediate),
NULL,
&paddle_mobile__framework__proto__op_proto__var__intermediate__default_value,
0, /* flags */
0, NULL, NULL /* reserved1,reserved2, etc */
},
{
"dispensable", 5, PROTOBUF_C_LABEL_OPTIONAL, PROTOBUF_C_TYPE_BOOL,
offsetof(PaddleMobile__Framework__Proto__OpProto__Var,
has_dispensable),
offsetof(PaddleMobile__Framework__Proto__OpProto__Var, dispensable),
NULL,
&paddle_mobile__framework__proto__op_proto__var__dispensable__default_value,
0, /* flags */
0, NULL, NULL /* reserved1,reserved2, etc */
},
};
static const unsigned
paddle_mobile__framework__proto__op_proto__var__field_indices_by_name[] = {
1, /* field[1] = comment */
4, /* field[4] = dispensable */
2, /* field[2] = duplicable */
3, /* field[3] = intermediate */
0, /* field[0] = name */
};
static const ProtobufCIntRange
paddle_mobile__framework__proto__op_proto__var__number_ranges[1 + 1] = {
{1, 0}, {0, 5}};
const ProtobufCMessageDescriptor
paddle_mobile__framework__proto__op_proto__var__descriptor = {
PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC,
"paddle_mobile.framework.proto.OpProto.Var",
"Var",
"PaddleMobile__Framework__Proto__OpProto__Var",
"paddle_mobile.framework.proto",
sizeof(PaddleMobile__Framework__Proto__OpProto__Var),
5,
paddle_mobile__framework__proto__op_proto__var__field_descriptors,
paddle_mobile__framework__proto__op_proto__var__field_indices_by_name,
1,
paddle_mobile__framework__proto__op_proto__var__number_ranges,
(ProtobufCMessageInit)
paddle_mobile__framework__proto__op_proto__var__init,
NULL,
NULL,
NULL /* reserved[123] */
};
static const protobuf_c_boolean
paddle_mobile__framework__proto__op_proto__attr__generated__default_value =
0;
static const ProtobufCFieldDescriptor
paddle_mobile__framework__proto__op_proto__attr__field_descriptors[4] = {
{
"name", 1, PROTOBUF_C_LABEL_REQUIRED, PROTOBUF_C_TYPE_STRING,
0, /* quantifier_offset */
offsetof(PaddleMobile__Framework__Proto__OpProto__Attr, name), NULL,
NULL, 0, /* flags */
0, NULL, NULL /* reserved1,reserved2, etc */
},
{
"type", 2, PROTOBUF_C_LABEL_REQUIRED, PROTOBUF_C_TYPE_ENUM,
0, /* quantifier_offset */
offsetof(PaddleMobile__Framework__Proto__OpProto__Attr, type),
&paddle_mobile__framework__proto__attr_type__descriptor, NULL,
0, /* flags */
0, NULL, NULL /* reserved1,reserved2, etc */
},
{
"comment", 3, PROTOBUF_C_LABEL_REQUIRED, PROTOBUF_C_TYPE_STRING,
0, /* quantifier_offset */
offsetof(PaddleMobile__Framework__Proto__OpProto__Attr, comment),
NULL, NULL, 0, /* flags */
0, NULL, NULL /* reserved1,reserved2, etc */
},
{
"generated", 4, PROTOBUF_C_LABEL_OPTIONAL, PROTOBUF_C_TYPE_BOOL,
offsetof(PaddleMobile__Framework__Proto__OpProto__Attr,
has_generated),
offsetof(PaddleMobile__Framework__Proto__OpProto__Attr, generated),
NULL,
&paddle_mobile__framework__proto__op_proto__attr__generated__default_value,
0, /* flags */
0, NULL, NULL /* reserved1,reserved2, etc */
},
};
static const unsigned
paddle_mobile__framework__proto__op_proto__attr__field_indices_by_name[] = {
2, /* field[2] = comment */
3, /* field[3] = generated */
0, /* field[0] = name */
1, /* field[1] = type */
};
static const ProtobufCIntRange
paddle_mobile__framework__proto__op_proto__attr__number_ranges[1 + 1] = {
{1, 0}, {0, 4}};
const ProtobufCMessageDescriptor
paddle_mobile__framework__proto__op_proto__attr__descriptor = {
PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC,
"paddle_mobile.framework.proto.OpProto.Attr",
"Attr",
"PaddleMobile__Framework__Proto__OpProto__Attr",
"paddle_mobile.framework.proto",
sizeof(PaddleMobile__Framework__Proto__OpProto__Attr),
4,
paddle_mobile__framework__proto__op_proto__attr__field_descriptors,
paddle_mobile__framework__proto__op_proto__attr__field_indices_by_name,
1,
paddle_mobile__framework__proto__op_proto__attr__number_ranges,
(ProtobufCMessageInit)
paddle_mobile__framework__proto__op_proto__attr__init,
NULL,
NULL,
NULL /* reserved[123] */
};
static const ProtobufCFieldDescriptor
paddle_mobile__framework__proto__op_proto__field_descriptors[5] = {
{
"type", 1, PROTOBUF_C_LABEL_REQUIRED, PROTOBUF_C_TYPE_STRING,
0, /* quantifier_offset */
offsetof(PaddleMobile__Framework__Proto__OpProto, type), NULL, NULL,
0, /* flags */
0, NULL, NULL /* reserved1,reserved2, etc */
},
{
"inputs", 2, PROTOBUF_C_LABEL_REPEATED, PROTOBUF_C_TYPE_MESSAGE,
offsetof(PaddleMobile__Framework__Proto__OpProto, n_inputs),
offsetof(PaddleMobile__Framework__Proto__OpProto, inputs),
&paddle_mobile__framework__proto__op_proto__var__descriptor, NULL,
0, /* flags */
0, NULL, NULL /* reserved1,reserved2, etc */
},
{
"outputs", 3, PROTOBUF_C_LABEL_REPEATED, PROTOBUF_C_TYPE_MESSAGE,
offsetof(PaddleMobile__Framework__Proto__OpProto, n_outputs),
offsetof(PaddleMobile__Framework__Proto__OpProto, outputs),
&paddle_mobile__framework__proto__op_proto__var__descriptor, NULL,
0, /* flags */
0, NULL, NULL /* reserved1,reserved2, etc */
},
{
"attrs", 4, PROTOBUF_C_LABEL_REPEATED, PROTOBUF_C_TYPE_MESSAGE,
offsetof(PaddleMobile__Framework__Proto__OpProto, n_attrs),
offsetof(PaddleMobile__Framework__Proto__OpProto, attrs),
&paddle_mobile__framework__proto__op_proto__attr__descriptor, NULL,
0, /* flags */
0, NULL, NULL /* reserved1,reserved2, etc */
},
{
"comment", 5, PROTOBUF_C_LABEL_REQUIRED, PROTOBUF_C_TYPE_STRING,
0, /* quantifier_offset */
offsetof(PaddleMobile__Framework__Proto__OpProto, comment), NULL,
NULL, 0, /* flags */
0, NULL, NULL /* reserved1,reserved2, etc */
},
};
static const unsigned
paddle_mobile__framework__proto__op_proto__field_indices_by_name[] = {
3, /* field[3] = attrs */
4, /* field[4] = comment */
1, /* field[1] = inputs */
2, /* field[2] = outputs */
0, /* field[0] = type */
};
static const ProtobufCIntRange
paddle_mobile__framework__proto__op_proto__number_ranges[1 + 1] = {{1, 0},
{0, 5}};
const ProtobufCMessageDescriptor
paddle_mobile__framework__proto__op_proto__descriptor = {
PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC,
"paddle_mobile.framework.proto.OpProto",
"OpProto",
"PaddleMobile__Framework__Proto__OpProto",
"paddle_mobile.framework.proto",
sizeof(PaddleMobile__Framework__Proto__OpProto),
5,
paddle_mobile__framework__proto__op_proto__field_descriptors,
paddle_mobile__framework__proto__op_proto__field_indices_by_name,
1,
paddle_mobile__framework__proto__op_proto__number_ranges,
(ProtobufCMessageInit)paddle_mobile__framework__proto__op_proto__init,
NULL,
NULL,
NULL /* reserved[123] */
};
static const ProtobufCFieldDescriptor
paddle_mobile__framework__proto__var_type__tensor_desc__field_descriptors
[2] = {
{
"data_type", 1, PROTOBUF_C_LABEL_REQUIRED, PROTOBUF_C_TYPE_ENUM,
0, /* quantifier_offset */
offsetof(PaddleMobile__Framework__Proto__VarType__TensorDesc,
data_type),
&paddle_mobile__framework__proto__var_type__type__descriptor,
NULL, 0, /* flags */
0, NULL, NULL /* reserved1,reserved2, etc */
},
{
"dims", 2, PROTOBUF_C_LABEL_REPEATED, PROTOBUF_C_TYPE_INT64,
offsetof(PaddleMobile__Framework__Proto__VarType__TensorDesc,
n_dims),
offsetof(PaddleMobile__Framework__Proto__VarType__TensorDesc,
dims),
NULL, NULL, 0, /* flags */
0, NULL, NULL /* reserved1,reserved2, etc */
},
};
static const unsigned
paddle_mobile__framework__proto__var_type__tensor_desc__field_indices_by_name
[] = {
0, /* field[0] = data_type */
1, /* field[1] = dims */
};
static const ProtobufCIntRange
paddle_mobile__framework__proto__var_type__tensor_desc__number_ranges[1 +
1] = {
{1, 0}, {0, 2}};
const ProtobufCMessageDescriptor
paddle_mobile__framework__proto__var_type__tensor_desc__descriptor = {
PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC,
"paddle_mobile.framework.proto.VarType.TensorDesc",
"TensorDesc",
"PaddleMobile__Framework__Proto__VarType__TensorDesc",
"paddle_mobile.framework.proto",
sizeof(PaddleMobile__Framework__Proto__VarType__TensorDesc),
2,
paddle_mobile__framework__proto__var_type__tensor_desc__field_descriptors,
paddle_mobile__framework__proto__var_type__tensor_desc__field_indices_by_name,
1,
paddle_mobile__framework__proto__var_type__tensor_desc__number_ranges,
(ProtobufCMessageInit)
paddle_mobile__framework__proto__var_type__tensor_desc__init,
NULL,
NULL,
NULL /* reserved[123] */
};
static const int32_t
paddle_mobile__framework__proto__var_type__lo_dtensor_desc__lod_level__default_value =
0;
static const ProtobufCFieldDescriptor
paddle_mobile__framework__proto__var_type__lo_dtensor_desc__field_descriptors
[2] = {
{
"tensor", 1, PROTOBUF_C_LABEL_REQUIRED, PROTOBUF_C_TYPE_MESSAGE,
0, /* quantifier_offset */
offsetof(PaddleMobile__Framework__Proto__VarType__LoDTensorDesc,
tensor),
&paddle_mobile__framework__proto__var_type__tensor_desc__descriptor,
NULL, 0, /* flags */
0, NULL, NULL /* reserved1,reserved2, etc */
},
{
"lod_level", 2, PROTOBUF_C_LABEL_OPTIONAL,
PROTOBUF_C_TYPE_INT32,
offsetof(PaddleMobile__Framework__Proto__VarType__LoDTensorDesc,
has_lod_level),
offsetof(PaddleMobile__Framework__Proto__VarType__LoDTensorDesc,
lod_level),
NULL,
&paddle_mobile__framework__proto__var_type__lo_dtensor_desc__lod_level__default_value,
0, /* flags */
0, NULL, NULL /* reserved1,reserved2, etc */
},
};
static const unsigned
paddle_mobile__framework__proto__var_type__lo_dtensor_desc__field_indices_by_name
[] = {
1, /* field[1] = lod_level */
0, /* field[0] = tensor */
};
static const ProtobufCIntRange
paddle_mobile__framework__proto__var_type__lo_dtensor_desc__number_ranges
[1 + 1] = {{1, 0}, {0, 2}};
const ProtobufCMessageDescriptor
paddle_mobile__framework__proto__var_type__lo_dtensor_desc__descriptor = {
PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC,
"paddle_mobile.framework.proto.VarType.LoDTensorDesc",
"LoDTensorDesc",
"PaddleMobile__Framework__Proto__VarType__LoDTensorDesc",
"paddle_mobile.framework.proto",
sizeof(PaddleMobile__Framework__Proto__VarType__LoDTensorDesc),
2,
paddle_mobile__framework__proto__var_type__lo_dtensor_desc__field_descriptors,
paddle_mobile__framework__proto__var_type__lo_dtensor_desc__field_indices_by_name,
1,
paddle_mobile__framework__proto__var_type__lo_dtensor_desc__number_ranges,
(ProtobufCMessageInit)
paddle_mobile__framework__proto__var_type__lo_dtensor_desc__init,
NULL,
NULL,
NULL /* reserved[123] */
};
static const int32_t
paddle_mobile__framework__proto__var_type__lo_dtensor_array_desc__lod_level__default_value =
0;
static const ProtobufCFieldDescriptor
paddle_mobile__framework__proto__var_type__lo_dtensor_array_desc__field_descriptors
[2] = {
{
"tensor", 1, PROTOBUF_C_LABEL_REQUIRED, PROTOBUF_C_TYPE_MESSAGE,
0, /* quantifier_offset */
offsetof(
PaddleMobile__Framework__Proto__VarType__LoDTensorArrayDesc,
tensor),
&paddle_mobile__framework__proto__var_type__tensor_desc__descriptor,
NULL, 0, /* flags */
0, NULL, NULL /* reserved1,reserved2, etc */
},
{
"lod_level", 2, PROTOBUF_C_LABEL_OPTIONAL,
PROTOBUF_C_TYPE_INT32,
offsetof(
PaddleMobile__Framework__Proto__VarType__LoDTensorArrayDesc,
has_lod_level),
offsetof(
PaddleMobile__Framework__Proto__VarType__LoDTensorArrayDesc,
lod_level),
NULL,
&paddle_mobile__framework__proto__var_type__lo_dtensor_array_desc__lod_level__default_value,
0, /* flags */
0, NULL, NULL /* reserved1,reserved2, etc */
},
};
static const unsigned
paddle_mobile__framework__proto__var_type__lo_dtensor_array_desc__field_indices_by_name
[] = {
1, /* field[1] = lod_level */
0, /* field[0] = tensor */
};
static const ProtobufCIntRange
paddle_mobile__framework__proto__var_type__lo_dtensor_array_desc__number_ranges
[1 + 1] = {{1, 0}, {0, 2}};
const ProtobufCMessageDescriptor
paddle_mobile__framework__proto__var_type__lo_dtensor_array_desc__descriptor = {
PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC,
"paddle_mobile.framework.proto.VarType.LoDTensorArrayDesc",
"LoDTensorArrayDesc",
"PaddleMobile__Framework__Proto__VarType__LoDTensorArrayDesc",
"paddle_mobile.framework.proto",
sizeof(PaddleMobile__Framework__Proto__VarType__LoDTensorArrayDesc),
2,
paddle_mobile__framework__proto__var_type__lo_dtensor_array_desc__field_descriptors,
paddle_mobile__framework__proto__var_type__lo_dtensor_array_desc__field_indices_by_name,
1,
paddle_mobile__framework__proto__var_type__lo_dtensor_array_desc__number_ranges,
(ProtobufCMessageInit)
paddle_mobile__framework__proto__var_type__lo_dtensor_array_desc__init,
NULL,
NULL,
NULL /* reserved[123] */
};
static const ProtobufCFieldDescriptor
paddle_mobile__framework__proto__var_type__reader_desc__field_descriptors[1] = {
{
"lod_tensor", 1, PROTOBUF_C_LABEL_REPEATED, PROTOBUF_C_TYPE_MESSAGE,
offsetof(PaddleMobile__Framework__Proto__VarType__ReaderDesc,
n_lod_tensor),
offsetof(PaddleMobile__Framework__Proto__VarType__ReaderDesc,
lod_tensor),
&paddle_mobile__framework__proto__var_type__lo_dtensor_desc__descriptor,
NULL, 0, /* flags */
0, NULL, NULL /* reserved1,reserved2, etc */
},
};
static const unsigned
paddle_mobile__framework__proto__var_type__reader_desc__field_indices_by_name
[] = {
0, /* field[0] = lod_tensor */
};
static const ProtobufCIntRange
paddle_mobile__framework__proto__var_type__reader_desc__number_ranges[1 +
1] = {
{1, 0}, {0, 1}};
const ProtobufCMessageDescriptor
paddle_mobile__framework__proto__var_type__reader_desc__descriptor = {
PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC,
"paddle_mobile.framework.proto.VarType.ReaderDesc",
"ReaderDesc",
"PaddleMobile__Framework__Proto__VarType__ReaderDesc",
"paddle_mobile.framework.proto",
sizeof(PaddleMobile__Framework__Proto__VarType__ReaderDesc),
1,
paddle_mobile__framework__proto__var_type__reader_desc__field_descriptors,
paddle_mobile__framework__proto__var_type__reader_desc__field_indices_by_name,
1,
paddle_mobile__framework__proto__var_type__reader_desc__number_ranges,
(ProtobufCMessageInit)
paddle_mobile__framework__proto__var_type__reader_desc__init,
NULL,
NULL,
NULL /* reserved[123] */
};
static const ProtobufCFieldDescriptor
paddle_mobile__framework__proto__var_type__channel_desc__field_descriptors
[2] = {
{
"data_type", 1, PROTOBUF_C_LABEL_REQUIRED, PROTOBUF_C_TYPE_ENUM,
0, /* quantifier_offset */
offsetof(PaddleMobile__Framework__Proto__VarType__ChannelDesc,
data_type),
&paddle_mobile__framework__proto__var_type__type__descriptor,
NULL, 0, /* flags */
0, NULL, NULL /* reserved1,reserved2, etc */
},
{
"capacity", 2, PROTOBUF_C_LABEL_REQUIRED, PROTOBUF_C_TYPE_INT64,
0, /* quantifier_offset */
offsetof(PaddleMobile__Framework__Proto__VarType__ChannelDesc,
capacity),
NULL, NULL, 0, /* flags */
0, NULL, NULL /* reserved1,reserved2, etc */
},
};
static const unsigned
paddle_mobile__framework__proto__var_type__channel_desc__field_indices_by_name
[] = {
1, /* field[1] = capacity */
0, /* field[0] = data_type */
};
static const ProtobufCIntRange
paddle_mobile__framework__proto__var_type__channel_desc__number_ranges[1 +
1] =
{{1, 0}, {0, 2}};
const ProtobufCMessageDescriptor
paddle_mobile__framework__proto__var_type__channel_desc__descriptor = {
PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC,
"paddle_mobile.framework.proto.VarType.ChannelDesc",
"ChannelDesc",
"PaddleMobile__Framework__Proto__VarType__ChannelDesc",
"paddle_mobile.framework.proto",
sizeof(PaddleMobile__Framework__Proto__VarType__ChannelDesc),
2,
paddle_mobile__framework__proto__var_type__channel_desc__field_descriptors,
paddle_mobile__framework__proto__var_type__channel_desc__field_indices_by_name,
1,
paddle_mobile__framework__proto__var_type__channel_desc__number_ranges,
(ProtobufCMessageInit)
paddle_mobile__framework__proto__var_type__channel_desc__init,
NULL,
NULL,
NULL /* reserved[123] */
};
static const ProtobufCFieldDescriptor
paddle_mobile__framework__proto__var_type__tuple__field_descriptors[1] = {
{
"element_type", 1, PROTOBUF_C_LABEL_REPEATED, PROTOBUF_C_TYPE_ENUM,
offsetof(PaddleMobile__Framework__Proto__VarType__Tuple,
n_element_type),
offsetof(PaddleMobile__Framework__Proto__VarType__Tuple,
element_type),
&paddle_mobile__framework__proto__var_type__type__descriptor, NULL,
0, /* flags */
0, NULL, NULL /* reserved1,reserved2, etc */
},
};
static const unsigned
paddle_mobile__framework__proto__var_type__tuple__field_indices_by_name[] =
{
0, /* field[0] = element_type */
};
static const ProtobufCIntRange
paddle_mobile__framework__proto__var_type__tuple__number_ranges[1 + 1] = {
{1, 0}, {0, 1}};
const ProtobufCMessageDescriptor
paddle_mobile__framework__proto__var_type__tuple__descriptor = {
PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC,
"paddle_mobile.framework.proto.VarType.Tuple",
"Tuple",
"PaddleMobile__Framework__Proto__VarType__Tuple",
"paddle_mobile.framework.proto",
sizeof(PaddleMobile__Framework__Proto__VarType__Tuple),
1,
paddle_mobile__framework__proto__var_type__tuple__field_descriptors,
paddle_mobile__framework__proto__var_type__tuple__field_indices_by_name,
1,
paddle_mobile__framework__proto__var_type__tuple__number_ranges,
(ProtobufCMessageInit)
paddle_mobile__framework__proto__var_type__tuple__init,
NULL,
NULL,
NULL /* reserved[123] */
};
static const ProtobufCEnumValue
paddle_mobile__framework__proto__var_type__type__enum_values_by_number[19] =
{
{"BOOL", "PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__TYPE__BOOL",
0},
{"INT16", "PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__TYPE__INT16",
1},
{"INT32", "PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__TYPE__INT32",
2},
{"INT64", "PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__TYPE__INT64",
3},
{"FP16", "PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__TYPE__FP16",
4},
{"FP32", "PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__TYPE__FP32",
5},
{"FP64", "PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__TYPE__FP64",
6},
{"LOD_TENSOR",
"PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__TYPE__LOD_TENSOR", 7},
{"SELECTED_ROWS",
"PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__TYPE__SELECTED_ROWS",
8},
{"FEED_MINIBATCH",
"PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__TYPE__FEED_MINIBATCH",
9},
{"FETCH_LIST",
"PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__TYPE__FETCH_LIST", 10},
{"STEP_SCOPES",
"PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__TYPE__STEP_SCOPES",
11},
{"LOD_RANK_TABLE",
"PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__TYPE__LOD_RANK_TABLE",
12},
{"LOD_TENSOR_ARRAY",
"PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__TYPE__LOD_TENSOR_"
"ARRAY",
13},
{"PLACE_LIST",
"PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__TYPE__PLACE_LIST", 14},
{"READER",
"PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__TYPE__READER", 15},
{"CHANNEL",
"PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__TYPE__CHANNEL", 16},
{"RAW", "PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__TYPE__RAW", 17},
{"TUPLE", "PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__TYPE__TUPLE",
18},
};
static const ProtobufCIntRange
paddle_mobile__framework__proto__var_type__type__value_ranges[] = {{0, 0},
{0, 19}};
static const ProtobufCEnumValueIndex
paddle_mobile__framework__proto__var_type__type__enum_values_by_name[19] = {
{"BOOL", 0},
{"CHANNEL", 16},
{"FEED_MINIBATCH", 9},
{"FETCH_LIST", 10},
{"FP16", 4},
{"FP32", 5},
{"FP64", 6},
{"INT16", 1},
{"INT32", 2},
{"INT64", 3},
{"LOD_RANK_TABLE", 12},
{"LOD_TENSOR", 7},
{"LOD_TENSOR_ARRAY", 13},
{"PLACE_LIST", 14},
{"RAW", 17},
{"READER", 15},
{"SELECTED_ROWS", 8},
{"STEP_SCOPES", 11},
{"TUPLE", 18},
};
const ProtobufCEnumDescriptor
paddle_mobile__framework__proto__var_type__type__descriptor = {
PROTOBUF_C__ENUM_DESCRIPTOR_MAGIC,
"paddle_mobile.framework.proto.VarType.Type",
"Type",
"PaddleMobile__Framework__Proto__VarType__Type",
"paddle_mobile.framework.proto",
19,
paddle_mobile__framework__proto__var_type__type__enum_values_by_number,
19,
paddle_mobile__framework__proto__var_type__type__enum_values_by_name,
1,
paddle_mobile__framework__proto__var_type__type__value_ranges,
NULL,
NULL,
NULL,
NULL /* reserved[1234] */
};
static const ProtobufCFieldDescriptor
paddle_mobile__framework__proto__var_type__field_descriptors[7] = {
{
"type", 1, PROTOBUF_C_LABEL_REQUIRED, PROTOBUF_C_TYPE_ENUM,
0, /* quantifier_offset */
offsetof(PaddleMobile__Framework__Proto__VarType, type),
&paddle_mobile__framework__proto__var_type__type__descriptor, NULL,
0, /* flags */
0, NULL, NULL /* reserved1,reserved2, etc */
},
{
"selected_rows", 2, PROTOBUF_C_LABEL_OPTIONAL,
PROTOBUF_C_TYPE_MESSAGE, 0, /* quantifier_offset */
offsetof(PaddleMobile__Framework__Proto__VarType, selected_rows),
&paddle_mobile__framework__proto__var_type__tensor_desc__descriptor,
NULL, 0, /* flags */
0, NULL, NULL /* reserved1,reserved2, etc */
},
{
"lod_tensor", 3, PROTOBUF_C_LABEL_OPTIONAL, PROTOBUF_C_TYPE_MESSAGE,
0, /* quantifier_offset */
offsetof(PaddleMobile__Framework__Proto__VarType, lod_tensor),
&paddle_mobile__framework__proto__var_type__lo_dtensor_desc__descriptor,
NULL, 0, /* flags */
0, NULL, NULL /* reserved1,reserved2, etc */
},
{
"tensor_array", 4, PROTOBUF_C_LABEL_OPTIONAL,
PROTOBUF_C_TYPE_MESSAGE, 0, /* quantifier_offset */
offsetof(PaddleMobile__Framework__Proto__VarType, tensor_array),
&paddle_mobile__framework__proto__var_type__lo_dtensor_array_desc__descriptor,
NULL, 0, /* flags */
0, NULL, NULL /* reserved1,reserved2, etc */
},
{
"reader", 5, PROTOBUF_C_LABEL_OPTIONAL, PROTOBUF_C_TYPE_MESSAGE,
0, /* quantifier_offset */
offsetof(PaddleMobile__Framework__Proto__VarType, reader),
&paddle_mobile__framework__proto__var_type__reader_desc__descriptor,
NULL, 0, /* flags */
0, NULL, NULL /* reserved1,reserved2, etc */
},
{
"channel", 6, PROTOBUF_C_LABEL_OPTIONAL, PROTOBUF_C_TYPE_MESSAGE,
0, /* quantifier_offset */
offsetof(PaddleMobile__Framework__Proto__VarType, channel),
&paddle_mobile__framework__proto__var_type__channel_desc__descriptor,
NULL, 0, /* flags */
0, NULL, NULL /* reserved1,reserved2, etc */
},
{
"tuple", 7, PROTOBUF_C_LABEL_OPTIONAL, PROTOBUF_C_TYPE_MESSAGE,
0, /* quantifier_offset */
offsetof(PaddleMobile__Framework__Proto__VarType, tuple),
&paddle_mobile__framework__proto__var_type__tuple__descriptor, NULL,
0, /* flags */
0, NULL, NULL /* reserved1,reserved2, etc */
},
};
static const unsigned
paddle_mobile__framework__proto__var_type__field_indices_by_name[] = {
5, /* field[5] = channel */
2, /* field[2] = lod_tensor */
4, /* field[4] = reader */
1, /* field[1] = selected_rows */
3, /* field[3] = tensor_array */
6, /* field[6] = tuple */
0, /* field[0] = type */
};
static const ProtobufCIntRange
paddle_mobile__framework__proto__var_type__number_ranges[1 + 1] = {{1, 0},
{0, 7}};
const ProtobufCMessageDescriptor
paddle_mobile__framework__proto__var_type__descriptor = {
PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC,
"paddle_mobile.framework.proto.VarType",
"VarType",
"PaddleMobile__Framework__Proto__VarType",
"paddle_mobile.framework.proto",
sizeof(PaddleMobile__Framework__Proto__VarType),
7,
paddle_mobile__framework__proto__var_type__field_descriptors,
paddle_mobile__framework__proto__var_type__field_indices_by_name,
1,
paddle_mobile__framework__proto__var_type__number_ranges,
(ProtobufCMessageInit)paddle_mobile__framework__proto__var_type__init,
NULL,
NULL,
NULL /* reserved[123] */
};
static const protobuf_c_boolean
paddle_mobile__framework__proto__var_desc__persistable__default_value = 0;
static const ProtobufCFieldDescriptor
paddle_mobile__framework__proto__var_desc__field_descriptors[3] = {
{
"name", 1, PROTOBUF_C_LABEL_REQUIRED, PROTOBUF_C_TYPE_STRING,
0, /* quantifier_offset */
offsetof(PaddleMobile__Framework__Proto__VarDesc, name), NULL, NULL,
0, /* flags */
0, NULL, NULL /* reserved1,reserved2, etc */
},
{
"type", 2, PROTOBUF_C_LABEL_REQUIRED, PROTOBUF_C_TYPE_MESSAGE,
0, /* quantifier_offset */
offsetof(PaddleMobile__Framework__Proto__VarDesc, type),
&paddle_mobile__framework__proto__var_type__descriptor, NULL,
0, /* flags */
0, NULL, NULL /* reserved1,reserved2, etc */
},
{
"persistable", 3, PROTOBUF_C_LABEL_OPTIONAL, PROTOBUF_C_TYPE_BOOL,
offsetof(PaddleMobile__Framework__Proto__VarDesc, has_persistable),
offsetof(PaddleMobile__Framework__Proto__VarDesc, persistable),
NULL,
&paddle_mobile__framework__proto__var_desc__persistable__default_value,
0, /* flags */
0, NULL, NULL /* reserved1,reserved2, etc */
},
};
static const unsigned
paddle_mobile__framework__proto__var_desc__field_indices_by_name[] = {
0, /* field[0] = name */
2, /* field[2] = persistable */
1, /* field[1] = type */
};
static const ProtobufCIntRange
paddle_mobile__framework__proto__var_desc__number_ranges[1 + 1] = {{1, 0},
{0, 3}};
const ProtobufCMessageDescriptor
paddle_mobile__framework__proto__var_desc__descriptor = {
PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC,
"paddle_mobile.framework.proto.VarDesc",
"VarDesc",
"PaddleMobile__Framework__Proto__VarDesc",
"paddle_mobile.framework.proto",
sizeof(PaddleMobile__Framework__Proto__VarDesc),
3,
paddle_mobile__framework__proto__var_desc__field_descriptors,
paddle_mobile__framework__proto__var_desc__field_indices_by_name,
1,
paddle_mobile__framework__proto__var_desc__number_ranges,
(ProtobufCMessageInit)paddle_mobile__framework__proto__var_desc__init,
NULL,
NULL,
NULL /* reserved[123] */
};
static const int32_t
paddle_mobile__framework__proto__block_desc__forward_block_idx__default_value =
-1;
static const ProtobufCFieldDescriptor
paddle_mobile__framework__proto__block_desc__field_descriptors[5] = {
{
"idx", 1, PROTOBUF_C_LABEL_REQUIRED, PROTOBUF_C_TYPE_INT32,
0, /* quantifier_offset */
offsetof(PaddleMobile__Framework__Proto__BlockDesc, idx), NULL,
NULL, 0, /* flags */
0, NULL, NULL /* reserved1,reserved2, etc */
},
{
"parent_idx", 2, PROTOBUF_C_LABEL_REQUIRED, PROTOBUF_C_TYPE_INT32,
0, /* quantifier_offset */
offsetof(PaddleMobile__Framework__Proto__BlockDesc, parent_idx),
NULL, NULL, 0, /* flags */
0, NULL, NULL /* reserved1,reserved2, etc */
},
{
"vars", 3, PROTOBUF_C_LABEL_REPEATED, PROTOBUF_C_TYPE_MESSAGE,
offsetof(PaddleMobile__Framework__Proto__BlockDesc, n_vars),
offsetof(PaddleMobile__Framework__Proto__BlockDesc, vars),
&paddle_mobile__framework__proto__var_desc__descriptor, NULL,
0, /* flags */
0, NULL, NULL /* reserved1,reserved2, etc */
},
{
"ops", 4, PROTOBUF_C_LABEL_REPEATED, PROTOBUF_C_TYPE_MESSAGE,
offsetof(PaddleMobile__Framework__Proto__BlockDesc, n_ops),
offsetof(PaddleMobile__Framework__Proto__BlockDesc, ops),
&paddle_mobile__framework__proto__op_desc__descriptor, NULL,
0, /* flags */
0, NULL, NULL /* reserved1,reserved2, etc */
},
{
"forward_block_idx", 5, PROTOBUF_C_LABEL_OPTIONAL,
PROTOBUF_C_TYPE_INT32,
offsetof(PaddleMobile__Framework__Proto__BlockDesc,
has_forward_block_idx),
offsetof(PaddleMobile__Framework__Proto__BlockDesc,
forward_block_idx),
NULL,
&paddle_mobile__framework__proto__block_desc__forward_block_idx__default_value,
0, /* flags */
0, NULL, NULL /* reserved1,reserved2, etc */
},
};
static const unsigned
paddle_mobile__framework__proto__block_desc__field_indices_by_name[] = {
4, /* field[4] = forward_block_idx */
0, /* field[0] = idx */
3, /* field[3] = ops */
1, /* field[1] = parent_idx */
2, /* field[2] = vars */
};
static const ProtobufCIntRange
paddle_mobile__framework__proto__block_desc__number_ranges[1 + 1] = {
{1, 0}, {0, 5}};
const ProtobufCMessageDescriptor
paddle_mobile__framework__proto__block_desc__descriptor = {
PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC,
"paddle_mobile.framework.proto.BlockDesc",
"BlockDesc",
"PaddleMobile__Framework__Proto__BlockDesc",
"paddle_mobile.framework.proto",
sizeof(PaddleMobile__Framework__Proto__BlockDesc),
5,
paddle_mobile__framework__proto__block_desc__field_descriptors,
paddle_mobile__framework__proto__block_desc__field_indices_by_name,
1,
paddle_mobile__framework__proto__block_desc__number_ranges,
(ProtobufCMessageInit)paddle_mobile__framework__proto__block_desc__init,
NULL,
NULL,
NULL /* reserved[123] */
};
static const ProtobufCFieldDescriptor
paddle_mobile__framework__proto__program_desc__field_descriptors[1] = {
{
"blocks", 1, PROTOBUF_C_LABEL_REPEATED, PROTOBUF_C_TYPE_MESSAGE,
offsetof(PaddleMobile__Framework__Proto__ProgramDesc, n_blocks),
offsetof(PaddleMobile__Framework__Proto__ProgramDesc, blocks),
&paddle_mobile__framework__proto__block_desc__descriptor, NULL,
0, /* flags */
0, NULL, NULL /* reserved1,reserved2, etc */
},
};
static const unsigned
paddle_mobile__framework__proto__program_desc__field_indices_by_name[] = {
0, /* field[0] = blocks */
};
static const ProtobufCIntRange
paddle_mobile__framework__proto__program_desc__number_ranges[1 + 1] = {
{1, 0}, {0, 1}};
const ProtobufCMessageDescriptor
paddle_mobile__framework__proto__program_desc__descriptor = {
PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC,
"paddle_mobile.framework.proto.ProgramDesc",
"ProgramDesc",
"PaddleMobile__Framework__Proto__ProgramDesc",
"paddle_mobile.framework.proto",
sizeof(PaddleMobile__Framework__Proto__ProgramDesc),
1,
paddle_mobile__framework__proto__program_desc__field_descriptors,
paddle_mobile__framework__proto__program_desc__field_indices_by_name,
1,
paddle_mobile__framework__proto__program_desc__number_ranges,
(ProtobufCMessageInit)
paddle_mobile__framework__proto__program_desc__init,
NULL,
NULL,
NULL /* reserved[123] */
};
static const ProtobufCEnumValue
paddle_mobile__framework__proto__attr_type__enum_values_by_number[10] = {
{"INT", "PADDLE_MOBILE__FRAMEWORK__PROTO__ATTR_TYPE__INT", 0},
{"FLOAT", "PADDLE_MOBILE__FRAMEWORK__PROTO__ATTR_TYPE__FLOAT", 1},
{"STRING", "PADDLE_MOBILE__FRAMEWORK__PROTO__ATTR_TYPE__STRING", 2},
{"INTS", "PADDLE_MOBILE__FRAMEWORK__PROTO__ATTR_TYPE__INTS", 3},
{"FLOATS", "PADDLE_MOBILE__FRAMEWORK__PROTO__ATTR_TYPE__FLOATS", 4},
{"STRINGS", "PADDLE_MOBILE__FRAMEWORK__PROTO__ATTR_TYPE__STRINGS", 5},
{"BOOLEAN", "PADDLE_MOBILE__FRAMEWORK__PROTO__ATTR_TYPE__BOOLEAN", 6},
{"BOOLEANS", "PADDLE_MOBILE__FRAMEWORK__PROTO__ATTR_TYPE__BOOLEANS", 7},
{"BLOCK", "PADDLE_MOBILE__FRAMEWORK__PROTO__ATTR_TYPE__BLOCK", 8},
{"LONG", "PADDLE_MOBILE__FRAMEWORK__PROTO__ATTR_TYPE__LONG", 9},
};
static const ProtobufCIntRange
paddle_mobile__framework__proto__attr_type__value_ranges[] = {{0, 0},
{0, 10}};
static const ProtobufCEnumValueIndex
paddle_mobile__framework__proto__attr_type__enum_values_by_name[10] = {
{"BLOCK", 8}, {"BOOLEAN", 6}, {"BOOLEANS", 7}, {"FLOAT", 1},
{"FLOATS", 4}, {"INT", 0}, {"INTS", 3}, {"LONG", 9},
{"STRING", 2}, {"STRINGS", 5},
};
const ProtobufCEnumDescriptor
paddle_mobile__framework__proto__attr_type__descriptor = {
PROTOBUF_C__ENUM_DESCRIPTOR_MAGIC,
"paddle_mobile.framework.proto.AttrType",
"AttrType",
"PaddleMobile__Framework__Proto__AttrType",
"paddle_mobile.framework.proto",
10,
paddle_mobile__framework__proto__attr_type__enum_values_by_number,
10,
paddle_mobile__framework__proto__attr_type__enum_values_by_name,
1,
paddle_mobile__framework__proto__attr_type__value_ranges,
NULL,
NULL,
NULL,
NULL /* reserved[1234] */
};
/* Generated by the protocol buffer compiler. DO NOT EDIT! */
/* Generated from: framework.proto */
#ifndef PROTOBUF_C_framework_2eproto__INCLUDED
#define PROTOBUF_C_framework_2eproto__INCLUDED
#include "protobuf-c.h"
PROTOBUF_C__BEGIN_DECLS
#if PROTOBUF_C_VERSION_NUMBER < 1000000
# error This file was generated by a newer version of protoc-c which is incompatible with your libprotobuf-c headers. Please update your headers.
#elif 1003000 < PROTOBUF_C_MIN_COMPILER_VERSION
# error This file was generated by an older version of protoc-c which is incompatible with your libprotobuf-c headers. Please regenerate this file with a newer version of protoc-c.
#endif
typedef struct _PaddleMobile__Framework__Proto__OpDesc
PaddleMobile__Framework__Proto__OpDesc;
typedef struct _PaddleMobile__Framework__Proto__OpDesc__Attr
PaddleMobile__Framework__Proto__OpDesc__Attr;
typedef struct _PaddleMobile__Framework__Proto__OpDesc__Var
PaddleMobile__Framework__Proto__OpDesc__Var;
typedef struct _PaddleMobile__Framework__Proto__OpProto
PaddleMobile__Framework__Proto__OpProto;
typedef struct _PaddleMobile__Framework__Proto__OpProto__Var
PaddleMobile__Framework__Proto__OpProto__Var;
typedef struct _PaddleMobile__Framework__Proto__OpProto__Attr
PaddleMobile__Framework__Proto__OpProto__Attr;
typedef struct _PaddleMobile__Framework__Proto__VarType
PaddleMobile__Framework__Proto__VarType;
typedef struct _PaddleMobile__Framework__Proto__VarType__TensorDesc
PaddleMobile__Framework__Proto__VarType__TensorDesc;
typedef struct _PaddleMobile__Framework__Proto__VarType__LoDTensorDesc
PaddleMobile__Framework__Proto__VarType__LoDTensorDesc;
typedef struct _PaddleMobile__Framework__Proto__VarType__LoDTensorArrayDesc
PaddleMobile__Framework__Proto__VarType__LoDTensorArrayDesc;
typedef struct _PaddleMobile__Framework__Proto__VarType__ReaderDesc
PaddleMobile__Framework__Proto__VarType__ReaderDesc;
typedef struct _PaddleMobile__Framework__Proto__VarType__ChannelDesc
PaddleMobile__Framework__Proto__VarType__ChannelDesc;
typedef struct _PaddleMobile__Framework__Proto__VarType__Tuple
PaddleMobile__Framework__Proto__VarType__Tuple;
typedef struct _PaddleMobile__Framework__Proto__VarDesc
PaddleMobile__Framework__Proto__VarDesc;
typedef struct _PaddleMobile__Framework__Proto__BlockDesc
PaddleMobile__Framework__Proto__BlockDesc;
typedef struct _PaddleMobile__Framework__Proto__ProgramDesc
PaddleMobile__Framework__Proto__ProgramDesc;
/* --- enums --- */
typedef enum _PaddleMobile__Framework__Proto__VarType__Type {
/*
* Pod Types
*/
PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__TYPE__BOOL = 0,
PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__TYPE__INT16 = 1,
PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__TYPE__INT32 = 2,
PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__TYPE__INT64 = 3,
PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__TYPE__FP16 = 4,
PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__TYPE__FP32 = 5,
PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__TYPE__FP64 = 6,
/*
* Other types that may need additional descriptions
*/
PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__TYPE__LOD_TENSOR = 7,
PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__TYPE__SELECTED_ROWS = 8,
PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__TYPE__FEED_MINIBATCH = 9,
PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__TYPE__FETCH_LIST = 10,
PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__TYPE__STEP_SCOPES = 11,
PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__TYPE__LOD_RANK_TABLE = 12,
PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__TYPE__LOD_TENSOR_ARRAY = 13,
PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__TYPE__PLACE_LIST = 14,
PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__TYPE__READER = 15,
PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__TYPE__CHANNEL = 16,
/*
* Any runtime decided variable type is raw
* raw variables should manage their own allocations
* in operators like nccl_op
*/
PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__TYPE__RAW = 17,
PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__TYPE__TUPLE =
18 PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE(
PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__TYPE)
} PaddleMobile__Framework__Proto__VarType__Type;
typedef enum _PaddleMobile__Framework__Proto__AttrType {
PADDLE_MOBILE__FRAMEWORK__PROTO__ATTR_TYPE__INT = 0,
PADDLE_MOBILE__FRAMEWORK__PROTO__ATTR_TYPE__FLOAT = 1,
PADDLE_MOBILE__FRAMEWORK__PROTO__ATTR_TYPE__STRING = 2,
PADDLE_MOBILE__FRAMEWORK__PROTO__ATTR_TYPE__INTS = 3,
PADDLE_MOBILE__FRAMEWORK__PROTO__ATTR_TYPE__FLOATS = 4,
PADDLE_MOBILE__FRAMEWORK__PROTO__ATTR_TYPE__STRINGS = 5,
PADDLE_MOBILE__FRAMEWORK__PROTO__ATTR_TYPE__BOOLEAN = 6,
PADDLE_MOBILE__FRAMEWORK__PROTO__ATTR_TYPE__BOOLEANS = 7,
PADDLE_MOBILE__FRAMEWORK__PROTO__ATTR_TYPE__BLOCK = 8,
PADDLE_MOBILE__FRAMEWORK__PROTO__ATTR_TYPE__LONG =
9 PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE(
PADDLE_MOBILE__FRAMEWORK__PROTO__ATTR_TYPE)
} PaddleMobile__Framework__Proto__AttrType;
/* --- messages --- */
struct _PaddleMobile__Framework__Proto__OpDesc__Attr {
ProtobufCMessage base;
char *name;
PaddleMobile__Framework__Proto__AttrType type;
protobuf_c_boolean has_i;
int32_t i;
protobuf_c_boolean has_f;
float f;
char *s;
size_t n_ints;
int32_t *ints;
size_t n_floats;
float *floats;
size_t n_strings;
char **strings;
protobuf_c_boolean has_b;
protobuf_c_boolean b;
size_t n_bools;
protobuf_c_boolean *bools;
protobuf_c_boolean has_block_idx;
int32_t block_idx;
protobuf_c_boolean has_l;
int64_t l;
};
#define PADDLE_MOBILE__FRAMEWORK__PROTO__OP_DESC__ATTR__INIT \
{ \
PROTOBUF_C_MESSAGE_INIT( \
&paddle_mobile__framework__proto__op_desc__attr__descriptor) \
, NULL, PADDLE_MOBILE__FRAMEWORK__PROTO__ATTR_TYPE__INT, 0, 0, 0, 0, NULL, \
0, NULL, 0, NULL, 0, NULL, 0, 0, 0, NULL, 0, 0, 0, 0 \
}
struct _PaddleMobile__Framework__Proto__OpDesc__Var {
ProtobufCMessage base;
char *parameter;
size_t n_arguments;
char **arguments;
};
#define PADDLE_MOBILE__FRAMEWORK__PROTO__OP_DESC__VAR__INIT \
{ \
PROTOBUF_C_MESSAGE_INIT( \
&paddle_mobile__framework__proto__op_desc__var__descriptor) \
, NULL, 0, NULL \
}
/*
* OpDesc describes an instance of a C++ framework::OperatorBase
* derived class type.
*/
struct _PaddleMobile__Framework__Proto__OpDesc {
ProtobufCMessage base;
char *type;
size_t n_inputs;
PaddleMobile__Framework__Proto__OpDesc__Var **inputs;
size_t n_outputs;
PaddleMobile__Framework__Proto__OpDesc__Var **outputs;
size_t n_attrs;
PaddleMobile__Framework__Proto__OpDesc__Attr **attrs;
protobuf_c_boolean has_is_target;
protobuf_c_boolean is_target;
};
#define PADDLE_MOBILE__FRAMEWORK__PROTO__OP_DESC__INIT \
{ \
PROTOBUF_C_MESSAGE_INIT( \
&paddle_mobile__framework__proto__op_desc__descriptor) \
, NULL, 0, NULL, 0, NULL, 0, NULL, 0, 0 \
}
/*
* VarProto describes the C++ type framework::Variable.
*/
struct _PaddleMobile__Framework__Proto__OpProto__Var {
ProtobufCMessage base;
char *name;
char *comment;
protobuf_c_boolean has_duplicable;
protobuf_c_boolean duplicable;
protobuf_c_boolean has_intermediate;
protobuf_c_boolean intermediate;
protobuf_c_boolean has_dispensable;
protobuf_c_boolean dispensable;
};
#define PADDLE_MOBILE__FRAMEWORK__PROTO__OP_PROTO__VAR__INIT \
{ \
PROTOBUF_C_MESSAGE_INIT( \
&paddle_mobile__framework__proto__op_proto__var__descriptor) \
, NULL, NULL, 0, 0, 0, 0, 0, 0 \
}
/*
* AttrProto describes the C++ type Attribute.
*/
struct _PaddleMobile__Framework__Proto__OpProto__Attr {
ProtobufCMessage base;
char *name;
PaddleMobile__Framework__Proto__AttrType type;
char *comment;
/*
* If that attribute is generated, it means the Paddle third
* language binding has responsibility to fill that
* attribute. End-User should not set that attribute.
*/
protobuf_c_boolean has_generated;
protobuf_c_boolean generated;
};
#define PADDLE_MOBILE__FRAMEWORK__PROTO__OP_PROTO__ATTR__INIT \
{ \
PROTOBUF_C_MESSAGE_INIT( \
&paddle_mobile__framework__proto__op_proto__attr__descriptor) \
, NULL, PADDLE_MOBILE__FRAMEWORK__PROTO__ATTR_TYPE__INT, NULL, 0, 0 \
}
/*
* OpProto describes a C++ framework::OperatorBase derived class.
*/
struct _PaddleMobile__Framework__Proto__OpProto {
ProtobufCMessage base;
char *type;
size_t n_inputs;
PaddleMobile__Framework__Proto__OpProto__Var **inputs;
size_t n_outputs;
PaddleMobile__Framework__Proto__OpProto__Var **outputs;
size_t n_attrs;
PaddleMobile__Framework__Proto__OpProto__Attr **attrs;
char *comment;
};
#define PADDLE_MOBILE__FRAMEWORK__PROTO__OP_PROTO__INIT \
{ \
PROTOBUF_C_MESSAGE_INIT( \
&paddle_mobile__framework__proto__op_proto__descriptor) \
, NULL, 0, NULL, 0, NULL, 0, NULL, NULL \
}
struct _PaddleMobile__Framework__Proto__VarType__TensorDesc {
ProtobufCMessage base;
/*
* Should only be PODType. Is enforced in C++
*/
PaddleMobile__Framework__Proto__VarType__Type data_type;
/*
* [UNK, 640, 480] is saved as [-1, 640, 480]
*/
size_t n_dims;
int64_t *dims;
};
#define PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__TENSOR_DESC__INIT \
{ \
PROTOBUF_C_MESSAGE_INIT( \
&paddle_mobile__framework__proto__var_type__tensor_desc__descriptor) \
, PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__TYPE__BOOL, 0, NULL \
}
struct _PaddleMobile__Framework__Proto__VarType__LoDTensorDesc {
ProtobufCMessage base;
PaddleMobile__Framework__Proto__VarType__TensorDesc *tensor;
protobuf_c_boolean has_lod_level;
int32_t lod_level;
};
#define PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__LO_DTENSOR_DESC__INIT \
{ \
PROTOBUF_C_MESSAGE_INIT( \
&paddle_mobile__framework__proto__var_type__lo_dtensor_desc__descriptor) \
, NULL, 0, 0 \
}
struct _PaddleMobile__Framework__Proto__VarType__LoDTensorArrayDesc {
ProtobufCMessage base;
PaddleMobile__Framework__Proto__VarType__TensorDesc *tensor;
protobuf_c_boolean has_lod_level;
int32_t lod_level;
};
#define PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__LO_DTENSOR_ARRAY_DESC__INIT \
{ \
PROTOBUF_C_MESSAGE_INIT( \
&paddle_mobile__framework__proto__var_type__lo_dtensor_array_desc__descriptor) \
, NULL, 0, 0 \
}
struct _PaddleMobile__Framework__Proto__VarType__ReaderDesc {
ProtobufCMessage base;
size_t n_lod_tensor;
PaddleMobile__Framework__Proto__VarType__LoDTensorDesc **lod_tensor;
};
#define PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__READER_DESC__INIT \
{ \
PROTOBUF_C_MESSAGE_INIT( \
&paddle_mobile__framework__proto__var_type__reader_desc__descriptor) \
, 0, NULL \
}
struct _PaddleMobile__Framework__Proto__VarType__ChannelDesc {
ProtobufCMessage base;
PaddleMobile__Framework__Proto__VarType__Type data_type;
int64_t capacity;
};
#define PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__CHANNEL_DESC__INIT \
{ \
PROTOBUF_C_MESSAGE_INIT( \
&paddle_mobile__framework__proto__var_type__channel_desc__descriptor) \
, PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__TYPE__BOOL, 0 \
}
struct _PaddleMobile__Framework__Proto__VarType__Tuple {
ProtobufCMessage base;
size_t n_element_type;
PaddleMobile__Framework__Proto__VarType__Type *element_type;
};
#define PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__TUPLE__INIT \
{ \
PROTOBUF_C_MESSAGE_INIT( \
&paddle_mobile__framework__proto__var_type__tuple__descriptor) \
, 0, NULL \
}
struct _PaddleMobile__Framework__Proto__VarType {
ProtobufCMessage base;
PaddleMobile__Framework__Proto__VarType__Type type;
PaddleMobile__Framework__Proto__VarType__TensorDesc *selected_rows;
PaddleMobile__Framework__Proto__VarType__LoDTensorDesc *lod_tensor;
PaddleMobile__Framework__Proto__VarType__LoDTensorArrayDesc *tensor_array;
PaddleMobile__Framework__Proto__VarType__ReaderDesc *reader;
PaddleMobile__Framework__Proto__VarType__ChannelDesc *channel;
PaddleMobile__Framework__Proto__VarType__Tuple *tuple;
};
#define PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__INIT \
{ \
PROTOBUF_C_MESSAGE_INIT( \
&paddle_mobile__framework__proto__var_type__descriptor) \
, PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__TYPE__BOOL, NULL, NULL, NULL, \
NULL, NULL, NULL \
}
struct _PaddleMobile__Framework__Proto__VarDesc {
ProtobufCMessage base;
char *name;
PaddleMobile__Framework__Proto__VarType *type;
protobuf_c_boolean has_persistable;
protobuf_c_boolean persistable;
};
#define PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_DESC__INIT \
{ \
PROTOBUF_C_MESSAGE_INIT( \
&paddle_mobile__framework__proto__var_desc__descriptor) \
, NULL, NULL, 0, 0 \
}
struct _PaddleMobile__Framework__Proto__BlockDesc {
ProtobufCMessage base;
int32_t idx;
int32_t parent_idx;
size_t n_vars;
PaddleMobile__Framework__Proto__VarDesc **vars;
size_t n_ops;
PaddleMobile__Framework__Proto__OpDesc **ops;
protobuf_c_boolean has_forward_block_idx;
int32_t forward_block_idx;
};
#define PADDLE_MOBILE__FRAMEWORK__PROTO__BLOCK_DESC__INIT \
{ \
PROTOBUF_C_MESSAGE_INIT( \
&paddle_mobile__framework__proto__block_desc__descriptor) \
, 0, 0, 0, NULL, 0, NULL, 0, -1 \
}
/*
* Please refer to
* https://github.com/PaddlePaddle/Paddle/blob/develop/doc/design/program.md
* for more details.
* TODO(panyx0718): A model can have multiple programs. Need a
* way to distinguish them. Maybe ID or name?
*/
struct _PaddleMobile__Framework__Proto__ProgramDesc {
ProtobufCMessage base;
size_t n_blocks;
PaddleMobile__Framework__Proto__BlockDesc **blocks;
};
#define PADDLE_MOBILE__FRAMEWORK__PROTO__PROGRAM_DESC__INIT \
{ \
PROTOBUF_C_MESSAGE_INIT( \
&paddle_mobile__framework__proto__program_desc__descriptor) \
, 0, NULL \
}
/* PaddleMobile__Framework__Proto__OpDesc__Attr methods */
void paddle_mobile__framework__proto__op_desc__attr__init(
PaddleMobile__Framework__Proto__OpDesc__Attr *message);
/* PaddleMobile__Framework__Proto__OpDesc__Var methods */
void paddle_mobile__framework__proto__op_desc__var__init(
PaddleMobile__Framework__Proto__OpDesc__Var *message);
/* PaddleMobile__Framework__Proto__OpDesc methods */
void paddle_mobile__framework__proto__op_desc__init(
PaddleMobile__Framework__Proto__OpDesc *message);
size_t paddle_mobile__framework__proto__op_desc__get_packed_size(
const PaddleMobile__Framework__Proto__OpDesc *message);
PaddleMobile__Framework__Proto__OpDesc *
paddle_mobile__framework__proto__op_desc__unpack(ProtobufCAllocator *allocator,
size_t len,
const uint8_t *data);
void paddle_mobile__framework__proto__op_desc__free_unpacked(
PaddleMobile__Framework__Proto__OpDesc *message,
ProtobufCAllocator *allocator);
/* PaddleMobile__Framework__Proto__OpProto__Var methods */
void paddle_mobile__framework__proto__op_proto__var__init(
PaddleMobile__Framework__Proto__OpProto__Var *message);
/* PaddleMobile__Framework__Proto__OpProto__Attr methods */
void paddle_mobile__framework__proto__op_proto__attr__init(
PaddleMobile__Framework__Proto__OpProto__Attr *message);
/* PaddleMobile__Framework__Proto__OpProto methods */
void paddle_mobile__framework__proto__op_proto__init(
PaddleMobile__Framework__Proto__OpProto *message);
size_t paddle_mobile__framework__proto__op_proto__get_packed_size(
const PaddleMobile__Framework__Proto__OpProto *message);
PaddleMobile__Framework__Proto__OpProto *
paddle_mobile__framework__proto__op_proto__unpack(ProtobufCAllocator *allocator,
size_t len,
const uint8_t *data);
void paddle_mobile__framework__proto__op_proto__free_unpacked(
PaddleMobile__Framework__Proto__OpProto *message,
ProtobufCAllocator *allocator);
/* PaddleMobile__Framework__Proto__VarType__TensorDesc methods */
void paddle_mobile__framework__proto__var_type__tensor_desc__init(
PaddleMobile__Framework__Proto__VarType__TensorDesc *message);
/* PaddleMobile__Framework__Proto__VarType__LoDTensorDesc methods */
void paddle_mobile__framework__proto__var_type__lo_dtensor_desc__init(
PaddleMobile__Framework__Proto__VarType__LoDTensorDesc *message);
/* PaddleMobile__Framework__Proto__VarType__LoDTensorArrayDesc methods */
void paddle_mobile__framework__proto__var_type__lo_dtensor_array_desc__init(
PaddleMobile__Framework__Proto__VarType__LoDTensorArrayDesc *message);
/* PaddleMobile__Framework__Proto__VarType__ReaderDesc methods */
void paddle_mobile__framework__proto__var_type__reader_desc__init(
PaddleMobile__Framework__Proto__VarType__ReaderDesc *message);
/* PaddleMobile__Framework__Proto__VarType__ChannelDesc methods */
void paddle_mobile__framework__proto__var_type__channel_desc__init(
PaddleMobile__Framework__Proto__VarType__ChannelDesc *message);
/* PaddleMobile__Framework__Proto__VarType__Tuple methods */
void paddle_mobile__framework__proto__var_type__tuple__init(
PaddleMobile__Framework__Proto__VarType__Tuple *message);
/* PaddleMobile__Framework__Proto__VarType methods */
void paddle_mobile__framework__proto__var_type__init(
PaddleMobile__Framework__Proto__VarType *message);
size_t paddle_mobile__framework__proto__var_type__get_packed_size(
const PaddleMobile__Framework__Proto__VarType *message);
PaddleMobile__Framework__Proto__VarType *
paddle_mobile__framework__proto__var_type__unpack(ProtobufCAllocator *allocator,
size_t len,
const uint8_t *data);
void paddle_mobile__framework__proto__var_type__free_unpacked(
PaddleMobile__Framework__Proto__VarType *message,
ProtobufCAllocator *allocator);
/* PaddleMobile__Framework__Proto__VarDesc methods */
void paddle_mobile__framework__proto__var_desc__init(
PaddleMobile__Framework__Proto__VarDesc *message);
size_t paddle_mobile__framework__proto__var_desc__get_packed_size(
const PaddleMobile__Framework__Proto__VarDesc *message);
PaddleMobile__Framework__Proto__VarDesc *
paddle_mobile__framework__proto__var_desc__unpack(ProtobufCAllocator *allocator,
size_t len,
const uint8_t *data);
void paddle_mobile__framework__proto__var_desc__free_unpacked(
PaddleMobile__Framework__Proto__VarDesc *message,
ProtobufCAllocator *allocator);
/* PaddleMobile__Framework__Proto__BlockDesc methods */
void paddle_mobile__framework__proto__block_desc__init(
PaddleMobile__Framework__Proto__BlockDesc *message);
size_t paddle_mobile__framework__proto__block_desc__get_packed_size(
const PaddleMobile__Framework__Proto__BlockDesc *message);
PaddleMobile__Framework__Proto__BlockDesc *
paddle_mobile__framework__proto__block_desc__unpack(
ProtobufCAllocator *allocator, size_t len, const uint8_t *data);
void paddle_mobile__framework__proto__block_desc__free_unpacked(
PaddleMobile__Framework__Proto__BlockDesc *message,
ProtobufCAllocator *allocator);
/* PaddleMobile__Framework__Proto__ProgramDesc methods */
void paddle_mobile__framework__proto__program_desc__init(
PaddleMobile__Framework__Proto__ProgramDesc *message);
size_t paddle_mobile__framework__proto__program_desc__get_packed_size(
const PaddleMobile__Framework__Proto__ProgramDesc *message);
PaddleMobile__Framework__Proto__ProgramDesc *
paddle_mobile__framework__proto__program_desc__unpack(
ProtobufCAllocator *allocator, size_t len, const uint8_t *data);
void paddle_mobile__framework__proto__program_desc__free_unpacked(
PaddleMobile__Framework__Proto__ProgramDesc *message,
ProtobufCAllocator *allocator);
/* --- per-message closures --- */
typedef void (*PaddleMobile__Framework__Proto__OpDesc__Attr_Closure)(
const PaddleMobile__Framework__Proto__OpDesc__Attr *message,
void *closure_data);
typedef void (*PaddleMobile__Framework__Proto__OpDesc__Var_Closure)(
const PaddleMobile__Framework__Proto__OpDesc__Var *message,
void *closure_data);
typedef void (*PaddleMobile__Framework__Proto__OpDesc_Closure)(
const PaddleMobile__Framework__Proto__OpDesc *message, void *closure_data);
typedef void (*PaddleMobile__Framework__Proto__OpProto__Var_Closure)(
const PaddleMobile__Framework__Proto__OpProto__Var *message,
void *closure_data);
typedef void (*PaddleMobile__Framework__Proto__OpProto__Attr_Closure)(
const PaddleMobile__Framework__Proto__OpProto__Attr *message,
void *closure_data);
typedef void (*PaddleMobile__Framework__Proto__OpProto_Closure)(
const PaddleMobile__Framework__Proto__OpProto *message, void *closure_data);
typedef void (*PaddleMobile__Framework__Proto__VarType__TensorDesc_Closure)(
const PaddleMobile__Framework__Proto__VarType__TensorDesc *message,
void *closure_data);
typedef void (*PaddleMobile__Framework__Proto__VarType__LoDTensorDesc_Closure)(
const PaddleMobile__Framework__Proto__VarType__LoDTensorDesc *message,
void *closure_data);
typedef void (
*PaddleMobile__Framework__Proto__VarType__LoDTensorArrayDesc_Closure)(
const PaddleMobile__Framework__Proto__VarType__LoDTensorArrayDesc *message,
void *closure_data);
typedef void (*PaddleMobile__Framework__Proto__VarType__ReaderDesc_Closure)(
const PaddleMobile__Framework__Proto__VarType__ReaderDesc *message,
void *closure_data);
typedef void (*PaddleMobile__Framework__Proto__VarType__ChannelDesc_Closure)(
const PaddleMobile__Framework__Proto__VarType__ChannelDesc *message,
void *closure_data);
typedef void (*PaddleMobile__Framework__Proto__VarType__Tuple_Closure)(
const PaddleMobile__Framework__Proto__VarType__Tuple *message,
void *closure_data);
typedef void (*PaddleMobile__Framework__Proto__VarType_Closure)(
const PaddleMobile__Framework__Proto__VarType *message, void *closure_data);
typedef void (*PaddleMobile__Framework__Proto__VarDesc_Closure)(
const PaddleMobile__Framework__Proto__VarDesc *message, void *closure_data);
typedef void (*PaddleMobile__Framework__Proto__BlockDesc_Closure)(
const PaddleMobile__Framework__Proto__BlockDesc *message,
void *closure_data);
typedef void (*PaddleMobile__Framework__Proto__ProgramDesc_Closure)(
const PaddleMobile__Framework__Proto__ProgramDesc *message,
void *closure_data);
/* --- services --- */
/* --- descriptors --- */
extern const ProtobufCEnumDescriptor
paddle_mobile__framework__proto__attr_type__descriptor;
extern const ProtobufCMessageDescriptor
paddle_mobile__framework__proto__op_desc__descriptor;
extern const ProtobufCMessageDescriptor
paddle_mobile__framework__proto__op_desc__attr__descriptor;
extern const ProtobufCMessageDescriptor
paddle_mobile__framework__proto__op_desc__var__descriptor;
extern const ProtobufCMessageDescriptor
paddle_mobile__framework__proto__op_proto__descriptor;
extern const ProtobufCMessageDescriptor
paddle_mobile__framework__proto__op_proto__var__descriptor;
extern const ProtobufCMessageDescriptor
paddle_mobile__framework__proto__op_proto__attr__descriptor;
extern const ProtobufCMessageDescriptor
paddle_mobile__framework__proto__var_type__descriptor;
extern const ProtobufCMessageDescriptor
paddle_mobile__framework__proto__var_type__tensor_desc__descriptor;
extern const ProtobufCMessageDescriptor
paddle_mobile__framework__proto__var_type__lo_dtensor_desc__descriptor;
extern const ProtobufCMessageDescriptor
paddle_mobile__framework__proto__var_type__lo_dtensor_array_desc__descriptor;
extern const ProtobufCMessageDescriptor
paddle_mobile__framework__proto__var_type__reader_desc__descriptor;
extern const ProtobufCMessageDescriptor
paddle_mobile__framework__proto__var_type__channel_desc__descriptor;
extern const ProtobufCMessageDescriptor
paddle_mobile__framework__proto__var_type__tuple__descriptor;
extern const ProtobufCEnumDescriptor
paddle_mobile__framework__proto__var_type__type__descriptor;
extern const ProtobufCMessageDescriptor
paddle_mobile__framework__proto__var_desc__descriptor;
extern const ProtobufCMessageDescriptor
paddle_mobile__framework__proto__block_desc__descriptor;
extern const ProtobufCMessageDescriptor
paddle_mobile__framework__proto__program_desc__descriptor;
PROTOBUF_C__END_DECLS
#endif /* PROTOBUF_C_framework_2eproto__INCLUDED */
/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. */
//
// Created by 谢柏渊 on 2018/7/25.
//
#include "src/program_desc.h"
#include <vector>
ProgramDesc::ProgramDesc(PaddleMobile__Framework__Proto__ProgramDesc *desc) {
for (int i = 0; i < desc->n_blocks; ++i) {
blocks_.emplace_back(std::make_shared<BlockDesc>(desc->blocks[i]));
}
}
const std::vector<std::shared_ptr<BlockDesc>> ProgramDesc::Blocks() {
return blocks_;
}
/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. */
//
// Created by 谢柏渊 on 2018/7/25.
//
#ifndef TOOLS_QUANTIFICATION_SRC_PROGRAM_DESC_H_
#define TOOLS_QUANTIFICATION_SRC_PROGRAM_DESC_H_
#include <memory>
#include <vector>
#include "src/block_desc_local.h"
#include "src/framework.pb-c.h"
class ProgramDesc {
public:
// friend class Node;
//
// friend class ProgramOptimize;
explicit ProgramDesc(PaddleMobile__Framework__Proto__ProgramDesc *desc);
const std::vector<std::shared_ptr<BlockDesc>> Blocks();
private:
std::vector<std::shared_ptr<BlockDesc>> blocks_;
};
#endif // TOOLS_QUANTIFICATION_SRC_PROGRAM_DESC_H_
/*
* Copyright (c) 2008-2015, Dave Benson and the protobuf-c authors.
* 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.
*
* 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.
*/
/*! \file
* Support library for `protoc-c` generated code.
*
* This file implements the public API used by the code generated
* by `protoc-c`.
*
* \authors Dave Benson and the protobuf-c authors
*
* \copyright 2008-2014. Licensed under the terms of the [BSD-2-Clause] license.
*/
/**
* \todo 64-BIT OPTIMIZATION: certain implementations use 32-bit math
* even on 64-bit platforms (uint64_size, uint64_pack, parse_uint64).
*
* \todo Use size_t consistently.
*/
#include <stdlib.h> /* for malloc, free */
#include <string.h> /* for strcmp, strlen, memcpy, memmove, memset */
#include "protobuf-c.h"
#define TRUE 1
#define FALSE 0
#define PROTOBUF_C__ASSERT_NOT_REACHED() assert(0)
/* Workaround for Microsoft compilers. */
#ifdef _MSC_VER
#define inline __inline
#endif
/**
* \defgroup internal Internal functions and macros
*
* These are not exported by the library but are useful to developers working
* on `libprotobuf-c` itself.
*/
/**
* \defgroup macros Utility macros for manipulating structures
*
* Macros and constants used to manipulate the base "classes" generated by
* `protobuf-c`. They also define limits and check correctness.
*
* \ingroup internal
* @{
*/
/** The maximum length of a 64-bit integer in varint encoding. */
#define MAX_UINT64_ENCODED_SIZE 10
#ifndef PROTOBUF_C_UNPACK_ERROR
#define PROTOBUF_C_UNPACK_ERROR(...)
#endif
const char protobuf_c_empty_string[] = "";
/**
* Internal `ProtobufCMessage` manipulation macro.
*
* Base macro for manipulating a `ProtobufCMessage`. Used by STRUCT_MEMBER() and
* STRUCT_MEMBER_PTR().
*/
#define STRUCT_MEMBER_P(struct_p, struct_offset) \
((void *)((uint8_t *)(struct_p) + (struct_offset)))
/**
* Return field in a `ProtobufCMessage` based on offset.
*
* Take a pointer to a `ProtobufCMessage` and find the field at the offset.
* Cast it to the passed type.
*/
#define STRUCT_MEMBER(member_type, struct_p, struct_offset) \
(*(member_type *)STRUCT_MEMBER_P((struct_p), (struct_offset)))
/**
* Return field in a `ProtobufCMessage` based on offset.
*
* Take a pointer to a `ProtobufCMessage` and find the field at the offset. Cast
* it to a pointer to the passed type.
*/
#define STRUCT_MEMBER_PTR(member_type, struct_p, struct_offset) \
((member_type *)STRUCT_MEMBER_P((struct_p), (struct_offset)))
/* Assertions for magic numbers. */
#define ASSERT_IS_ENUM_DESCRIPTOR(desc) \
assert((desc)->magic == PROTOBUF_C__ENUM_DESCRIPTOR_MAGIC)
#define ASSERT_IS_MESSAGE_DESCRIPTOR(desc) \
assert((desc)->magic == PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC)
#define ASSERT_IS_MESSAGE(message) \
ASSERT_IS_MESSAGE_DESCRIPTOR((message)->descriptor)
#define ASSERT_IS_SERVICE_DESCRIPTOR(desc) \
assert((desc)->magic == PROTOBUF_C__SERVICE_DESCRIPTOR_MAGIC)
/**@}*/
/* --- version --- */
const char *protobuf_c_version(void) { return PROTOBUF_C_VERSION; }
uint32_t protobuf_c_version_number(void) { return PROTOBUF_C_VERSION_NUMBER; }
/* --- allocator --- */
static void *system_alloc(void *allocator_data, size_t size) {
return malloc(size);
}
static void system_free(void *allocator_data, void *data) { free(data); }
static inline void *do_alloc(ProtobufCAllocator *allocator, size_t size) {
return allocator->alloc(allocator->allocator_data, size);
}
static inline void do_free(ProtobufCAllocator *allocator, void *data) {
if (data != NULL) allocator->free(allocator->allocator_data, data);
}
/*
* This allocator uses the system's malloc() and free(). It is the default
* allocator used if NULL is passed as the ProtobufCAllocator to an exported
* function.
*/
static ProtobufCAllocator protobuf_c__allocator = {
.alloc = &system_alloc,
.free = &system_free,
.allocator_data = NULL,
};
/* === buffer-simple === */
void protobuf_c_buffer_simple_append(ProtobufCBuffer *buffer, size_t len,
const uint8_t *data) {
ProtobufCBufferSimple *simp = (ProtobufCBufferSimple *)buffer;
size_t new_len = simp->len + len;
if (new_len > simp->alloced) {
ProtobufCAllocator *allocator = simp->allocator;
size_t new_alloced = simp->alloced * 2;
uint8_t *new_data;
if (allocator == NULL) allocator = &protobuf_c__allocator;
while (new_alloced < new_len) new_alloced += new_alloced;
new_data = do_alloc(allocator, new_alloced);
if (!new_data) return;
memcpy(new_data, simp->data, simp->len);
if (simp->must_free_data)
do_free(allocator, simp->data);
else
simp->must_free_data = TRUE;
simp->data = new_data;
simp->alloced = new_alloced;
}
memcpy(simp->data + simp->len, data, len);
simp->len = new_len;
}
/**
* \defgroup packedsz protobuf_c_message_get_packed_size() implementation
*
* Routines mainly used by protobuf_c_message_get_packed_size().
*
* \ingroup internal
* @{
*/
/**
* Return the number of bytes required to store the tag for the field. Includes
* 3 bits for the wire-type, and a single bit that denotes the end-of-tag.
*
* \param number
* Field tag to encode.
* \return
* Number of bytes required.
*/
static inline size_t get_tag_size(uint32_t number) {
if (number < (1UL << 4)) {
return 1;
} else if (number < (1UL << 11)) {
return 2;
} else if (number < (1UL << 18)) {
return 3;
} else if (number < (1UL << 25)) {
return 4;
} else {
return 5;
}
}
/**
* Return the number of bytes required to store a variable-length unsigned
* 32-bit integer in base-128 varint encoding.
*
* \param v
* Value to encode.
* \return
* Number of bytes required.
*/
static inline size_t uint32_size(uint32_t v) {
if (v < (1UL << 7)) {
return 1;
} else if (v < (1UL << 14)) {
return 2;
} else if (v < (1UL << 21)) {
return 3;
} else if (v < (1UL << 28)) {
return 4;
} else {
return 5;
}
}
/**
* Return the number of bytes required to store a variable-length signed 32-bit
* integer in base-128 varint encoding.
*
* \param v
* Value to encode.
* \return
* Number of bytes required.
*/
static inline size_t int32_size(int32_t v) {
if (v < 0) {
return 10;
} else if (v < (1L << 7)) {
return 1;
} else if (v < (1L << 14)) {
return 2;
} else if (v < (1L << 21)) {
return 3;
} else if (v < (1L << 28)) {
return 4;
} else {
return 5;
}
}
/**
* Return the ZigZag-encoded 32-bit unsigned integer form of a 32-bit signed
* integer.
*
* \param v
* Value to encode.
* \return
* ZigZag encoded integer.
*/
static inline uint32_t zigzag32(int32_t v) {
if (v < 0)
return (-(uint32_t)v) * 2 - 1;
else
return (uint32_t)(v)*2;
}
/**
* Return the number of bytes required to store a signed 32-bit integer,
* converted to an unsigned 32-bit integer with ZigZag encoding, using base-128
* varint encoding.
*
* \param v
* Value to encode.
* \return
* Number of bytes required.
*/
static inline size_t sint32_size(int32_t v) { return uint32_size(zigzag32(v)); }
/**
* Return the number of bytes required to store a 64-bit unsigned integer in
* base-128 varint encoding.
*
* \param v
* Value to encode.
* \return
* Number of bytes required.
*/
static inline size_t uint64_size(uint64_t v) {
uint32_t upper_v = (uint32_t)(v >> 32);
if (upper_v == 0) {
return uint32_size((uint32_t)v);
} else if (upper_v < (1UL << 3)) {
return 5;
} else if (upper_v < (1UL << 10)) {
return 6;
} else if (upper_v < (1UL << 17)) {
return 7;
} else if (upper_v < (1UL << 24)) {
return 8;
} else if (upper_v < (1UL << 31)) {
return 9;
} else {
return 10;
}
}
/**
* Return the ZigZag-encoded 64-bit unsigned integer form of a 64-bit signed
* integer.
*
* \param v
* Value to encode.
* \return
* ZigZag encoded integer.
*/
static inline uint64_t zigzag64(int64_t v) {
if (v < 0)
return (-(uint64_t)v) * 2 - 1;
else
return (uint64_t)(v)*2;
}
/**
* Return the number of bytes required to store a signed 64-bit integer,
* converted to an unsigned 64-bit integer with ZigZag encoding, using base-128
* varint encoding.
*
* \param v
* Value to encode.
* \return
* Number of bytes required.
*/
static inline size_t sint64_size(int64_t v) { return uint64_size(zigzag64(v)); }
/**
* Calculate the serialized size of a single required message field, including
* the space needed by the preceding tag.
*
* \param field
* Field descriptor for member.
* \param member
* Field to encode.
* \return
* Number of bytes required.
*/
static size_t required_field_get_packed_size(
const ProtobufCFieldDescriptor *field, const void *member) {
size_t rv = get_tag_size(field->id);
switch (field->type) {
case PROTOBUF_C_TYPE_SINT32:
return rv + sint32_size(*(const int32_t *)member);
case PROTOBUF_C_TYPE_ENUM:
case PROTOBUF_C_TYPE_INT32:
return rv + int32_size(*(const int32_t *)member);
case PROTOBUF_C_TYPE_UINT32:
return rv + uint32_size(*(const uint32_t *)member);
case PROTOBUF_C_TYPE_SINT64:
return rv + sint64_size(*(const int64_t *)member);
case PROTOBUF_C_TYPE_INT64:
case PROTOBUF_C_TYPE_UINT64:
return rv + uint64_size(*(const uint64_t *)member);
case PROTOBUF_C_TYPE_SFIXED32:
case PROTOBUF_C_TYPE_FIXED32:
return rv + 4;
case PROTOBUF_C_TYPE_SFIXED64:
case PROTOBUF_C_TYPE_FIXED64:
return rv + 8;
case PROTOBUF_C_TYPE_BOOL:
return rv + 1;
case PROTOBUF_C_TYPE_FLOAT:
return rv + 4;
case PROTOBUF_C_TYPE_DOUBLE:
return rv + 8;
case PROTOBUF_C_TYPE_STRING: {
const char *str = *(char *const *)member;
size_t len = str ? strlen(str) : 0;
return rv + uint32_size(len) + len;
}
case PROTOBUF_C_TYPE_BYTES: {
size_t len = ((const ProtobufCBinaryData *)member)->len;
return rv + uint32_size(len) + len;
}
case PROTOBUF_C_TYPE_MESSAGE: {
const ProtobufCMessage *msg = *(ProtobufCMessage *const *)member;
size_t subrv = msg ? protobuf_c_message_get_packed_size(msg) : 0;
return rv + uint32_size(subrv) + subrv;
}
}
PROTOBUF_C__ASSERT_NOT_REACHED();
return 0;
}
/**
* Calculate the serialized size of a single oneof message field, including
* the space needed by the preceding tag. Returns 0 if the oneof field isn't
* selected or is not set.
*
* \param field
* Field descriptor for member.
* \param oneof_case
* Enum value that selects the field in the oneof.
* \param member
* Field to encode.
* \return
* Number of bytes required.
*/
static size_t oneof_field_get_packed_size(const ProtobufCFieldDescriptor *field,
uint32_t oneof_case,
const void *member) {
if (oneof_case != field->id) {
return 0;
}
if (field->type == PROTOBUF_C_TYPE_MESSAGE ||
field->type == PROTOBUF_C_TYPE_STRING) {
const void *ptr = *(const void *const *)member;
if (ptr == NULL || ptr == field->default_value) return 0;
}
return required_field_get_packed_size(field, member);
}
/**
* Calculate the serialized size of a single optional message field, including
* the space needed by the preceding tag. Returns 0 if the optional field isn't
* set.
*
* \param field
* Field descriptor for member.
* \param has
* True if the field exists, false if not.
* \param member
* Field to encode.
* \return
* Number of bytes required.
*/
static size_t optional_field_get_packed_size(
const ProtobufCFieldDescriptor *field, const protobuf_c_boolean has,
const void *member) {
if (field->type == PROTOBUF_C_TYPE_MESSAGE ||
field->type == PROTOBUF_C_TYPE_STRING) {
const void *ptr = *(const void *const *)member;
if (ptr == NULL || ptr == field->default_value) return 0;
} else {
if (!has) return 0;
}
return required_field_get_packed_size(field, member);
}
static protobuf_c_boolean field_is_zeroish(
const ProtobufCFieldDescriptor *field, const void *member) {
protobuf_c_boolean ret = FALSE;
switch (field->type) {
case PROTOBUF_C_TYPE_BOOL:
ret = (0 == *(const protobuf_c_boolean *)member);
break;
case PROTOBUF_C_TYPE_ENUM:
case PROTOBUF_C_TYPE_SINT32:
case PROTOBUF_C_TYPE_INT32:
case PROTOBUF_C_TYPE_UINT32:
case PROTOBUF_C_TYPE_SFIXED32:
case PROTOBUF_C_TYPE_FIXED32:
ret = (0 == *(const uint32_t *)member);
break;
case PROTOBUF_C_TYPE_SINT64:
case PROTOBUF_C_TYPE_INT64:
case PROTOBUF_C_TYPE_UINT64:
case PROTOBUF_C_TYPE_SFIXED64:
case PROTOBUF_C_TYPE_FIXED64:
ret = (0 == *(const uint64_t *)member);
break;
case PROTOBUF_C_TYPE_FLOAT:
ret = (0 == *(const float *)member);
break;
case PROTOBUF_C_TYPE_DOUBLE:
ret = (0 == *(const double *)member);
break;
case PROTOBUF_C_TYPE_STRING:
ret = (NULL == *(const char *const *)member) ||
('\0' == **(const char *const *)member);
break;
case PROTOBUF_C_TYPE_BYTES:
case PROTOBUF_C_TYPE_MESSAGE:
ret = (NULL == *(const void *const *)member);
break;
default:
ret = TRUE;
break;
}
return ret;
}
/**
* Calculate the serialized size of a single unlabeled message field, including
* the space needed by the preceding tag. Returns 0 if the field isn't set or
* if it is set to a "zeroish" value (null pointer or 0 for numerical values).
* Unlabeled fields are supported only in proto3.
*
* \param field
* Field descriptor for member.
* \param member
* Field to encode.
* \return
* Number of bytes required.
*/
static size_t unlabeled_field_get_packed_size(
const ProtobufCFieldDescriptor *field, const void *member) {
if (field_is_zeroish(field, member)) return 0;
return required_field_get_packed_size(field, member);
}
/**
* Calculate the serialized size of repeated message fields, which may consist
* of any number of values (including 0). Includes the space needed by the
* preceding tags (as needed).
*
* \param field
* Field descriptor for member.
* \param count
* Number of repeated field members.
* \param member
* Field to encode.
* \return
* Number of bytes required.
*/
static size_t repeated_field_get_packed_size(
const ProtobufCFieldDescriptor *field, size_t count, const void *member) {
size_t header_size;
size_t rv = 0;
unsigned i;
void *array = *(void *const *)member;
if (count == 0) return 0;
header_size = get_tag_size(field->id);
if (0 == (field->flags & PROTOBUF_C_FIELD_FLAG_PACKED)) header_size *= count;
switch (field->type) {
case PROTOBUF_C_TYPE_SINT32:
for (i = 0; i < count; i++) rv += sint32_size(((int32_t *)array)[i]);
break;
case PROTOBUF_C_TYPE_ENUM:
case PROTOBUF_C_TYPE_INT32:
for (i = 0; i < count; i++) rv += int32_size(((int32_t *)array)[i]);
break;
case PROTOBUF_C_TYPE_UINT32:
for (i = 0; i < count; i++) rv += uint32_size(((uint32_t *)array)[i]);
break;
case PROTOBUF_C_TYPE_SINT64:
for (i = 0; i < count; i++) rv += sint64_size(((int64_t *)array)[i]);
break;
case PROTOBUF_C_TYPE_INT64:
case PROTOBUF_C_TYPE_UINT64:
for (i = 0; i < count; i++) rv += uint64_size(((uint64_t *)array)[i]);
break;
case PROTOBUF_C_TYPE_SFIXED32:
case PROTOBUF_C_TYPE_FIXED32:
case PROTOBUF_C_TYPE_FLOAT:
rv += 4 * count;
break;
case PROTOBUF_C_TYPE_SFIXED64:
case PROTOBUF_C_TYPE_FIXED64:
case PROTOBUF_C_TYPE_DOUBLE:
rv += 8 * count;
break;
case PROTOBUF_C_TYPE_BOOL:
rv += count;
break;
case PROTOBUF_C_TYPE_STRING:
for (i = 0; i < count; i++) {
size_t len = strlen(((char **)array)[i]);
rv += uint32_size(len) + len;
}
break;
case PROTOBUF_C_TYPE_BYTES:
for (i = 0; i < count; i++) {
size_t len = ((ProtobufCBinaryData *)array)[i].len;
rv += uint32_size(len) + len;
}
break;
case PROTOBUF_C_TYPE_MESSAGE:
for (i = 0; i < count; i++) {
size_t len =
protobuf_c_message_get_packed_size(((ProtobufCMessage **)array)[i]);
rv += uint32_size(len) + len;
}
break;
}
if (0 != (field->flags & PROTOBUF_C_FIELD_FLAG_PACKED))
header_size += uint32_size(rv);
return header_size + rv;
}
/**
* Calculate the serialized size of an unknown field, i.e. one that is passed
* through mostly uninterpreted. This is required for forward compatibility if
* new fields are added to the message descriptor.
*
* \param field
* Unknown field type.
* \return
* Number of bytes required.
*/
static inline size_t unknown_field_get_packed_size(
const ProtobufCMessageUnknownField *field) {
return get_tag_size(field->tag) + field->len;
}
/**@}*/
/*
* Calculate the serialized size of the message.
*/
size_t protobuf_c_message_get_packed_size(const ProtobufCMessage *message) {
unsigned i;
size_t rv = 0;
ASSERT_IS_MESSAGE(message);
for (i = 0; i < message->descriptor->n_fields; i++) {
const ProtobufCFieldDescriptor *field = message->descriptor->fields + i;
const void *member = ((const char *)message) + field->offset;
const void *qmember = ((const char *)message) + field->quantifier_offset;
if (field->label == PROTOBUF_C_LABEL_REQUIRED) {
rv += required_field_get_packed_size(field, member);
} else if ((field->label == PROTOBUF_C_LABEL_OPTIONAL ||
field->label == PROTOBUF_C_LABEL_NONE) &&
(0 != (field->flags & PROTOBUF_C_FIELD_FLAG_ONEOF))) {
rv += oneof_field_get_packed_size(field, *(const uint32_t *)qmember,
member);
} else if (field->label == PROTOBUF_C_LABEL_OPTIONAL) {
rv += optional_field_get_packed_size(
field, *(protobuf_c_boolean *)qmember, member);
} else if (field->label == PROTOBUF_C_LABEL_NONE) {
rv += unlabeled_field_get_packed_size(field, member);
} else {
rv += repeated_field_get_packed_size(field, *(const size_t *)qmember,
member);
}
}
for (i = 0; i < message->n_unknown_fields; i++)
rv += unknown_field_get_packed_size(&message->unknown_fields[i]);
return rv;
}
/**
* \defgroup pack protobuf_c_message_pack() implementation
*
* Routines mainly used by protobuf_c_message_pack().
*
* \ingroup internal
* @{
*/
/**
* Pack an unsigned 32-bit integer in base-128 varint encoding and return the
* number of bytes written, which must be 5 or less.
*
* \param value
* Value to encode.
* \param[out] out
* Packed value.
* \return
* Number of bytes written to `out`.
*/
static inline size_t uint32_pack(uint32_t value, uint8_t *out) {
unsigned rv = 0;
if (value >= 0x80) {
out[rv++] = value | 0x80;
value >>= 7;
if (value >= 0x80) {
out[rv++] = value | 0x80;
value >>= 7;
if (value >= 0x80) {
out[rv++] = value | 0x80;
value >>= 7;
if (value >= 0x80) {
out[rv++] = value | 0x80;
value >>= 7;
}
}
}
}
/* assert: value<128 */
out[rv++] = value;
return rv;
}
/**
* Pack a 64-bit unsigned integer using base-128 varint encoding and return the
* number of bytes written.
*
* \param value
* Value to encode.
* \param[out] out
* Packed value.
* \return
* Number of bytes written to `out`.
*/
static size_t uint64_pack(uint64_t value, uint8_t *out) {
uint32_t hi = (uint32_t)(value >> 32);
uint32_t lo = (uint32_t)value;
unsigned rv;
if (hi == 0) return uint32_pack((uint32_t)lo, out);
out[0] = (lo) | 0x80;
out[1] = (lo >> 7) | 0x80;
out[2] = (lo >> 14) | 0x80;
out[3] = (lo >> 21) | 0x80;
if (hi < 8) {
out[4] = (hi << 4) | (lo >> 28);
return 5;
} else {
out[4] = ((hi & 7) << 4) | (lo >> 28) | 0x80;
hi >>= 3;
}
rv = 5;
while (hi >= 128) {
out[rv++] = hi | 0x80;
hi >>= 7;
}
out[rv++] = hi;
return rv;
}
/**
* Pack a ProtobufCBinaryData and return the number of bytes written. The output
* includes a length delimiter.
*
* \param bd
* ProtobufCBinaryData to encode.
* \param[out] out
* Packed value.
* \return
* Number of bytes written to `out`.
*/
static inline size_t binary_data_pack(const ProtobufCBinaryData *bd,
uint8_t *out) {
size_t len = bd->len;
size_t rv = uint32_pack(len, out);
memcpy(out + rv, bd->data, len);
return rv + len;
}
/**
* Pack a field tag.
*
* Wire-type will be added in required_field_pack().
*
* \todo Just call uint64_pack on 64-bit platforms.
*
* \param id
* Tag value to encode.
* \param[out] out
* Packed value.
* \return
* Number of bytes written to `out`.
*/
static size_t tag_pack(uint32_t id, uint8_t *out) {
if (id < (1UL << (32 - 3)))
return uint32_pack(id << 3, out);
else
return uint64_pack(((uint64_t)id) << 3, out);
}
/**
* Given a field type, return the in-memory size.
*
* \todo Implement as a table lookup.
*
* \param type
* Field type.
* \return
* Size of the field.
*/
static inline size_t sizeof_elt_in_repeated_array(ProtobufCType type) {
switch (type) {
case PROTOBUF_C_TYPE_SINT32:
case PROTOBUF_C_TYPE_INT32:
case PROTOBUF_C_TYPE_UINT32:
case PROTOBUF_C_TYPE_SFIXED32:
case PROTOBUF_C_TYPE_FIXED32:
case PROTOBUF_C_TYPE_FLOAT:
case PROTOBUF_C_TYPE_ENUM:
return 4;
case PROTOBUF_C_TYPE_SINT64:
case PROTOBUF_C_TYPE_INT64:
case PROTOBUF_C_TYPE_UINT64:
case PROTOBUF_C_TYPE_SFIXED64:
case PROTOBUF_C_TYPE_FIXED64:
case PROTOBUF_C_TYPE_DOUBLE:
return 8;
case PROTOBUF_C_TYPE_BOOL:
return sizeof(protobuf_c_boolean);
case PROTOBUF_C_TYPE_STRING:
case PROTOBUF_C_TYPE_MESSAGE:
return sizeof(void *);
case PROTOBUF_C_TYPE_BYTES:
return sizeof(ProtobufCBinaryData);
}
PROTOBUF_C__ASSERT_NOT_REACHED();
return 0;
}
static inline int int_range_lookup(unsigned n_ranges,
const ProtobufCIntRange *ranges, int value) {
unsigned n;
unsigned start;
if (n_ranges == 0) return -1;
start = 0;
n = n_ranges;
while (n > 1) {
unsigned mid = start + n / 2;
if (value < ranges[mid].start_value) {
n = mid - start;
} else if (value >=
ranges[mid].start_value +
(int)(ranges[mid + 1].orig_index - ranges[mid].orig_index)) {
unsigned new_start = mid + 1;
n = start + n - new_start;
start = new_start;
} else
return (value - ranges[mid].start_value) + ranges[mid].orig_index;
}
if (n > 0) {
unsigned start_orig_index = ranges[start].orig_index;
unsigned range_size = ranges[start + 1].orig_index - start_orig_index;
if (ranges[start].start_value <= value &&
value < (int)(ranges[start].start_value + range_size)) {
return (value - ranges[start].start_value) + start_orig_index;
}
}
return -1;
}
static size_t parse_tag_and_wiretype(size_t len, const uint8_t *data,
uint32_t *tag_out,
ProtobufCWireType *wiretype_out) {
unsigned max_rv = len > 5 ? 5 : len;
uint32_t tag = (data[0] & 0x7f) >> 3;
unsigned shift = 4;
unsigned rv;
*wiretype_out = data[0] & 7;
if ((data[0] & 0x80) == 0) {
*tag_out = tag;
return 1;
}
for (rv = 1; rv < max_rv; rv++) {
if (data[rv] & 0x80) {
tag |= (data[rv] & 0x7f) << shift;
shift += 7;
} else {
tag |= data[rv] << shift;
*tag_out = tag;
return rv + 1;
}
}
return 0; /* error: bad header */
}
/* sizeof(ScannedMember) must be <= (1UL<<BOUND_SIZEOF_SCANNED_MEMBER_LOG2) */
#define BOUND_SIZEOF_SCANNED_MEMBER_LOG2 5
typedef struct _ScannedMember ScannedMember;
/** Field as it's being read. */
struct _ScannedMember {
uint32_t tag; /**< Field tag. */
uint8_t wire_type; /**< Field type. */
uint8_t length_prefix_len; /**< Prefix length. */
const ProtobufCFieldDescriptor *field; /**< Field descriptor. */
size_t len; /**< Field length. */
const uint8_t *data; /**< Pointer to field data. */
};
static inline uint32_t scan_length_prefixed_data(size_t len,
const uint8_t *data,
size_t *prefix_len_out) {
unsigned hdr_max = len < 5 ? len : 5;
unsigned hdr_len;
uint32_t val = 0;
unsigned i;
unsigned shift = 0;
for (i = 0; i < hdr_max; i++) {
val |= (data[i] & 0x7f) << shift;
shift += 7;
if ((data[i] & 0x80) == 0) break;
}
if (i == hdr_max) {
PROTOBUF_C_UNPACK_ERROR("error parsing length for length-prefixed data");
return 0;
}
hdr_len = i + 1;
*prefix_len_out = hdr_len;
if (hdr_len + val > len) {
PROTOBUF_C_UNPACK_ERROR("data too short after length-prefix of %u", val);
return 0;
}
return hdr_len + val;
}
static size_t max_b128_numbers(size_t len, const uint8_t *data) {
size_t rv = 0;
while (len--)
if ((*data++ & 0x80) == 0) ++rv;
return rv;
}
/**@}*/
/**
* Merge earlier message into a latter message.
*
* For numeric types and strings, if the same value appears multiple
* times, the parser accepts the last value it sees. For embedded
* message fields, the parser merges multiple instances of the same
* field. That is, all singular scalar fields in the latter instance
* replace those in the former, singular embedded messages are merged,
* and repeated fields are concatenated.
*
* The earlier message should be freed after calling this function, as
* some of its fields may have been reused and changed to their default
* values during the merge.
*/
static protobuf_c_boolean merge_messages(ProtobufCMessage *earlier_msg,
ProtobufCMessage *latter_msg,
ProtobufCAllocator *allocator) {
unsigned i;
const ProtobufCFieldDescriptor *fields = latter_msg->descriptor->fields;
for (i = 0; i < latter_msg->descriptor->n_fields; i++) {
if (fields[i].label == PROTOBUF_C_LABEL_REPEATED) {
size_t *n_earlier =
STRUCT_MEMBER_PTR(size_t, earlier_msg, fields[i].quantifier_offset);
uint8_t **p_earlier =
STRUCT_MEMBER_PTR(uint8_t *, earlier_msg, fields[i].offset);
size_t *n_latter =
STRUCT_MEMBER_PTR(size_t, latter_msg, fields[i].quantifier_offset);
uint8_t **p_latter =
STRUCT_MEMBER_PTR(uint8_t *, latter_msg, fields[i].offset);
if (*n_earlier > 0) {
if (*n_latter > 0) {
/* Concatenate the repeated field */
size_t el_size = sizeof_elt_in_repeated_array(fields[i].type);
uint8_t *new_field;
new_field = do_alloc(allocator, (*n_earlier + *n_latter) * el_size);
if (!new_field) return FALSE;
memcpy(new_field, *p_earlier, *n_earlier * el_size);
memcpy(new_field + *n_earlier * el_size, *p_latter,
*n_latter * el_size);
do_free(allocator, *p_latter);
do_free(allocator, *p_earlier);
*p_latter = new_field;
*n_latter = *n_earlier + *n_latter;
} else {
/* Zero copy the repeated field from the earlier message */
*n_latter = *n_earlier;
*p_latter = *p_earlier;
}
/* Make sure the field does not get double freed */
*n_earlier = 0;
*p_earlier = 0;
}
} else if (fields[i].label == PROTOBUF_C_LABEL_OPTIONAL ||
fields[i].label == PROTOBUF_C_LABEL_NONE) {
const ProtobufCFieldDescriptor *field;
uint32_t *earlier_case_p =
STRUCT_MEMBER_PTR(uint32_t, earlier_msg, fields[i].quantifier_offset);
uint32_t *latter_case_p =
STRUCT_MEMBER_PTR(uint32_t, latter_msg, fields[i].quantifier_offset);
protobuf_c_boolean need_to_merge = FALSE;
void *earlier_elem;
void *latter_elem;
const void *def_val;
if (fields[i].flags & PROTOBUF_C_FIELD_FLAG_ONEOF) {
if (*latter_case_p == 0) {
/* lookup correct oneof field */
int field_index = int_range_lookup(
latter_msg->descriptor->n_field_ranges,
latter_msg->descriptor->field_ranges, *earlier_case_p);
field = latter_msg->descriptor->fields + field_index;
} else {
/* Oneof is present in the latter message, move on */
continue;
}
} else {
field = &fields[i];
}
earlier_elem = STRUCT_MEMBER_P(earlier_msg, field->offset);
latter_elem = STRUCT_MEMBER_P(latter_msg, field->offset);
def_val = field->default_value;
switch (field->type) {
case PROTOBUF_C_TYPE_MESSAGE: {
ProtobufCMessage *em = *(ProtobufCMessage **)earlier_elem;
ProtobufCMessage *lm = *(ProtobufCMessage **)latter_elem;
if (em != NULL) {
if (lm != NULL) {
if (!merge_messages(em, lm, allocator)) return FALSE;
/* Already merged */
need_to_merge = FALSE;
} else {
/* Zero copy the message */
need_to_merge = TRUE;
}
}
break;
}
case PROTOBUF_C_TYPE_BYTES: {
uint8_t *e_data = ((ProtobufCBinaryData *)earlier_elem)->data;
uint8_t *l_data = ((ProtobufCBinaryData *)latter_elem)->data;
const ProtobufCBinaryData *d_bd = (ProtobufCBinaryData *)def_val;
need_to_merge =
(e_data != NULL && (d_bd == NULL || e_data != d_bd->data)) &&
(l_data == NULL || (d_bd != NULL && l_data == d_bd->data));
break;
}
case PROTOBUF_C_TYPE_STRING: {
char *e_str = *(char **)earlier_elem;
char *l_str = *(char **)latter_elem;
const char *d_str = def_val;
need_to_merge = e_str != d_str && l_str == d_str;
break;
}
default: {
/* Could be has field or case enum, the logic is
* equivalent, since 0 (FALSE) means not set for
* oneof */
need_to_merge = (*earlier_case_p != 0) && (*latter_case_p == 0);
break;
}
}
if (need_to_merge) {
size_t el_size = sizeof_elt_in_repeated_array(field->type);
memcpy(latter_elem, earlier_elem, el_size);
/*
* Reset the element from the old message to 0
* to make sure earlier message deallocation
* doesn't corrupt zero-copied data in the new
* message, earlier message will be freed after
* this function is called anyway
*/
memset(earlier_elem, 0, el_size);
if (field->quantifier_offset != 0) {
/* Set the has field or the case enum,
* if applicable */
*latter_case_p = *earlier_case_p;
*earlier_case_p = 0;
}
}
}
}
return TRUE;
}
/**
* Count packed elements.
*
* Given a raw slab of packed-repeated values, determine the number of
* elements. This function detects certain kinds of errors but not
* others; the remaining error checking is done by
* parse_packed_repeated_member().
*/
static protobuf_c_boolean count_packed_elements(ProtobufCType type, size_t len,
const uint8_t *data,
size_t *count_out) {
switch (type) {
case PROTOBUF_C_TYPE_SFIXED32:
case PROTOBUF_C_TYPE_FIXED32:
case PROTOBUF_C_TYPE_FLOAT:
if (len % 4 != 0) {
PROTOBUF_C_UNPACK_ERROR(
"length must be a multiple of 4 for fixed-length 32-bit types");
return FALSE;
}
*count_out = len / 4;
return TRUE;
case PROTOBUF_C_TYPE_SFIXED64:
case PROTOBUF_C_TYPE_FIXED64:
case PROTOBUF_C_TYPE_DOUBLE:
if (len % 8 != 0) {
PROTOBUF_C_UNPACK_ERROR(
"length must be a multiple of 8 for fixed-length 64-bit types");
return FALSE;
}
*count_out = len / 8;
return TRUE;
case PROTOBUF_C_TYPE_ENUM:
case PROTOBUF_C_TYPE_INT32:
case PROTOBUF_C_TYPE_SINT32:
case PROTOBUF_C_TYPE_UINT32:
case PROTOBUF_C_TYPE_INT64:
case PROTOBUF_C_TYPE_SINT64:
case PROTOBUF_C_TYPE_UINT64:
*count_out = max_b128_numbers(len, data);
return TRUE;
case PROTOBUF_C_TYPE_BOOL:
*count_out = len;
return TRUE;
case PROTOBUF_C_TYPE_STRING:
case PROTOBUF_C_TYPE_BYTES:
case PROTOBUF_C_TYPE_MESSAGE:
default:
PROTOBUF_C_UNPACK_ERROR("bad protobuf-c type %u for packed-repeated",
type);
return FALSE;
}
}
static inline uint32_t parse_uint32(unsigned len, const uint8_t *data) {
uint32_t rv = data[0] & 0x7f;
if (len > 1) {
rv |= ((uint32_t)(data[1] & 0x7f) << 7);
if (len > 2) {
rv |= ((uint32_t)(data[2] & 0x7f) << 14);
if (len > 3) {
rv |= ((uint32_t)(data[3] & 0x7f) << 21);
if (len > 4) rv |= ((uint32_t)(data[4]) << 28);
}
}
}
return rv;
}
static inline uint32_t parse_int32(unsigned len, const uint8_t *data) {
return parse_uint32(len, data);
}
static inline int32_t unzigzag32(uint32_t v) {
if (v & 1)
return -(v >> 1) - 1;
else
return v >> 1;
}
static inline uint32_t parse_fixed_uint32(const uint8_t *data) {
#if !defined(WORDS_BIGENDIAN)
uint32_t t;
memcpy(&t, data, 4);
return t;
#else
return data[0] | ((uint32_t)(data[1]) << 8) | ((uint32_t)(data[2]) << 16) |
((uint32_t)(data[3]) << 24);
#endif
}
static uint64_t parse_uint64(unsigned len, const uint8_t *data) {
unsigned shift, i;
uint64_t rv;
if (len < 5) return parse_uint32(len, data);
rv = ((uint64_t)(data[0] & 0x7f)) | ((uint64_t)(data[1] & 0x7f) << 7) |
((uint64_t)(data[2] & 0x7f) << 14) | ((uint64_t)(data[3] & 0x7f) << 21);
shift = 28;
for (i = 4; i < len; i++) {
rv |= (((uint64_t)(data[i] & 0x7f)) << shift);
shift += 7;
}
return rv;
}
static inline int64_t unzigzag64(uint64_t v) {
if (v & 1)
return -(v >> 1) - 1;
else
return v >> 1;
}
static inline uint64_t parse_fixed_uint64(const uint8_t *data) {
#if !defined(WORDS_BIGENDIAN)
uint64_t t;
memcpy(&t, data, 8);
return t;
#else
return (uint64_t)parse_fixed_uint32(data) |
(((uint64_t)parse_fixed_uint32(data + 4)) << 32);
#endif
}
static protobuf_c_boolean parse_boolean(unsigned len, const uint8_t *data) {
unsigned i;
for (i = 0; i < len; i++)
if (data[i] & 0x7f) return TRUE;
return FALSE;
}
static protobuf_c_boolean parse_required_member(
ScannedMember *scanned_member, void *member, ProtobufCAllocator *allocator,
protobuf_c_boolean maybe_clear) {
unsigned len = scanned_member->len;
const uint8_t *data = scanned_member->data;
ProtobufCWireType wire_type = scanned_member->wire_type;
switch (scanned_member->field->type) {
case PROTOBUF_C_TYPE_ENUM:
case PROTOBUF_C_TYPE_INT32:
if (wire_type != PROTOBUF_C_WIRE_TYPE_VARINT) return FALSE;
*(int32_t *)member = parse_int32(len, data);
return TRUE;
case PROTOBUF_C_TYPE_UINT32:
if (wire_type != PROTOBUF_C_WIRE_TYPE_VARINT) return FALSE;
*(uint32_t *)member = parse_uint32(len, data);
return TRUE;
case PROTOBUF_C_TYPE_SINT32:
if (wire_type != PROTOBUF_C_WIRE_TYPE_VARINT) return FALSE;
*(int32_t *)member = unzigzag32(parse_uint32(len, data));
return TRUE;
case PROTOBUF_C_TYPE_SFIXED32:
case PROTOBUF_C_TYPE_FIXED32:
case PROTOBUF_C_TYPE_FLOAT:
if (wire_type != PROTOBUF_C_WIRE_TYPE_32BIT) return FALSE;
*(uint32_t *)member = parse_fixed_uint32(data);
return TRUE;
case PROTOBUF_C_TYPE_INT64:
case PROTOBUF_C_TYPE_UINT64:
if (wire_type != PROTOBUF_C_WIRE_TYPE_VARINT) return FALSE;
*(uint64_t *)member = parse_uint64(len, data);
return TRUE;
case PROTOBUF_C_TYPE_SINT64:
if (wire_type != PROTOBUF_C_WIRE_TYPE_VARINT) return FALSE;
*(int64_t *)member = unzigzag64(parse_uint64(len, data));
return TRUE;
case PROTOBUF_C_TYPE_SFIXED64:
case PROTOBUF_C_TYPE_FIXED64:
case PROTOBUF_C_TYPE_DOUBLE:
if (wire_type != PROTOBUF_C_WIRE_TYPE_64BIT) return FALSE;
*(uint64_t *)member = parse_fixed_uint64(data);
return TRUE;
case PROTOBUF_C_TYPE_BOOL:
*(protobuf_c_boolean *)member = parse_boolean(len, data);
return TRUE;
case PROTOBUF_C_TYPE_STRING: {
char **pstr = member;
unsigned pref_len = scanned_member->length_prefix_len;
if (wire_type != PROTOBUF_C_WIRE_TYPE_LENGTH_PREFIXED) return FALSE;
if (maybe_clear && *pstr != NULL) {
const char *def = scanned_member->field->default_value;
if (*pstr != NULL && *pstr != def) do_free(allocator, *pstr);
}
*pstr = do_alloc(allocator, len - pref_len + 1);
if (*pstr == NULL) return FALSE;
memcpy(*pstr, data + pref_len, len - pref_len);
(*pstr)[len - pref_len] = 0;
return TRUE;
}
case PROTOBUF_C_TYPE_BYTES: {
ProtobufCBinaryData *bd = member;
const ProtobufCBinaryData *def_bd;
unsigned pref_len = scanned_member->length_prefix_len;
if (wire_type != PROTOBUF_C_WIRE_TYPE_LENGTH_PREFIXED) return FALSE;
def_bd = scanned_member->field->default_value;
if (maybe_clear && bd->data != NULL &&
(def_bd == NULL || bd->data != def_bd->data)) {
do_free(allocator, bd->data);
}
if (len - pref_len > 0) {
bd->data = do_alloc(allocator, len - pref_len);
if (bd->data == NULL) return FALSE;
memcpy(bd->data, data + pref_len, len - pref_len);
} else {
bd->data = NULL;
}
bd->len = len - pref_len;
return TRUE;
}
case PROTOBUF_C_TYPE_MESSAGE: {
ProtobufCMessage **pmessage = member;
ProtobufCMessage *subm;
const ProtobufCMessage *def_mess;
protobuf_c_boolean merge_successful = TRUE;
unsigned pref_len = scanned_member->length_prefix_len;
if (wire_type != PROTOBUF_C_WIRE_TYPE_LENGTH_PREFIXED) return FALSE;
def_mess = scanned_member->field->default_value;
subm =
protobuf_c_message_unpack(scanned_member->field->descriptor,
allocator, len - pref_len, data + pref_len);
if (maybe_clear && *pmessage != NULL && *pmessage != def_mess) {
if (subm != NULL)
merge_successful = merge_messages(*pmessage, subm, allocator);
/* Delete the previous message */
protobuf_c_message_free_unpacked(*pmessage, allocator);
}
*pmessage = subm;
if (subm == NULL || !merge_successful) return FALSE;
return TRUE;
}
}
return FALSE;
}
static protobuf_c_boolean parse_oneof_member(ScannedMember *scanned_member,
void *member,
ProtobufCMessage *message,
ProtobufCAllocator *allocator) {
uint32_t *oneof_case = STRUCT_MEMBER_PTR(
uint32_t, message, scanned_member->field->quantifier_offset);
/* If we have already parsed a member of this oneof, free it. */
if (*oneof_case != 0) {
/* lookup field */
int field_index =
int_range_lookup(message->descriptor->n_field_ranges,
message->descriptor->field_ranges, *oneof_case);
const ProtobufCFieldDescriptor *old_field =
message->descriptor->fields + field_index;
size_t el_size = sizeof_elt_in_repeated_array(old_field->type);
switch (old_field->type) {
case PROTOBUF_C_TYPE_STRING: {
char **pstr = member;
const char *def = old_field->default_value;
if (*pstr != NULL && *pstr != def) do_free(allocator, *pstr);
break;
}
case PROTOBUF_C_TYPE_BYTES: {
ProtobufCBinaryData *bd = member;
const ProtobufCBinaryData *def_bd = old_field->default_value;
if (bd->data != NULL && (def_bd == NULL || bd->data != def_bd->data)) {
do_free(allocator, bd->data);
}
break;
}
case PROTOBUF_C_TYPE_MESSAGE: {
ProtobufCMessage **pmessage = member;
const ProtobufCMessage *def_mess = old_field->default_value;
if (*pmessage != NULL && *pmessage != def_mess)
protobuf_c_message_free_unpacked(*pmessage, allocator);
break;
}
default:
break;
}
memset(member, 0, el_size);
}
if (!parse_required_member(scanned_member, member, allocator, TRUE))
return FALSE;
*oneof_case = scanned_member->tag;
return TRUE;
}
static protobuf_c_boolean parse_optional_member(ScannedMember *scanned_member,
void *member,
ProtobufCMessage *message,
ProtobufCAllocator *allocator) {
if (!parse_required_member(scanned_member, member, allocator, TRUE))
return FALSE;
if (scanned_member->field->quantifier_offset != 0)
STRUCT_MEMBER(protobuf_c_boolean, message,
scanned_member->field->quantifier_offset) = TRUE;
return TRUE;
}
static protobuf_c_boolean parse_repeated_member(ScannedMember *scanned_member,
void *member,
ProtobufCMessage *message,
ProtobufCAllocator *allocator) {
const ProtobufCFieldDescriptor *field = scanned_member->field;
size_t *p_n = STRUCT_MEMBER_PTR(size_t, message, field->quantifier_offset);
size_t siz = sizeof_elt_in_repeated_array(field->type);
char *array = *(char **)member;
if (!parse_required_member(scanned_member, array + siz * (*p_n), allocator,
FALSE)) {
return FALSE;
}
*p_n += 1;
return TRUE;
}
static unsigned scan_varint(unsigned len, const uint8_t *data) {
unsigned i;
if (len > 10) len = 10;
for (i = 0; i < len; i++)
if ((data[i] & 0x80) == 0) break;
if (i == len) return 0;
return i + 1;
}
static protobuf_c_boolean parse_packed_repeated_member(
ScannedMember *scanned_member, void *member, ProtobufCMessage *message) {
const ProtobufCFieldDescriptor *field = scanned_member->field;
size_t *p_n = STRUCT_MEMBER_PTR(size_t, message, field->quantifier_offset);
size_t siz = sizeof_elt_in_repeated_array(field->type);
void *array = *(char **)member + siz * (*p_n);
const uint8_t *at = scanned_member->data + scanned_member->length_prefix_len;
size_t rem = scanned_member->len - scanned_member->length_prefix_len;
size_t count = 0;
unsigned i;
switch (field->type) {
case PROTOBUF_C_TYPE_SFIXED32:
case PROTOBUF_C_TYPE_FIXED32:
case PROTOBUF_C_TYPE_FLOAT:
count = (scanned_member->len - scanned_member->length_prefix_len) / 4;
#if !defined(WORDS_BIGENDIAN)
goto no_unpacking_needed;
#else
for (i = 0; i < count; i++) {
((uint32_t *)array)[i] = parse_fixed_uint32(at);
at += 4;
}
break;
#endif
case PROTOBUF_C_TYPE_SFIXED64:
case PROTOBUF_C_TYPE_FIXED64:
case PROTOBUF_C_TYPE_DOUBLE:
count = (scanned_member->len - scanned_member->length_prefix_len) / 8;
#if !defined(WORDS_BIGENDIAN)
goto no_unpacking_needed;
#else
for (i = 0; i < count; i++) {
((uint64_t *)array)[i] = parse_fixed_uint64(at);
at += 8;
}
break;
#endif
case PROTOBUF_C_TYPE_ENUM:
case PROTOBUF_C_TYPE_INT32:
while (rem > 0) {
unsigned s = scan_varint(rem, at);
if (s == 0) {
PROTOBUF_C_UNPACK_ERROR("bad packed-repeated int32 value");
return FALSE;
}
((int32_t *)array)[count++] = parse_int32(s, at);
at += s;
rem -= s;
}
break;
case PROTOBUF_C_TYPE_SINT32:
while (rem > 0) {
unsigned s = scan_varint(rem, at);
if (s == 0) {
PROTOBUF_C_UNPACK_ERROR("bad packed-repeated sint32 value");
return FALSE;
}
((int32_t *)array)[count++] = unzigzag32(parse_uint32(s, at));
at += s;
rem -= s;
}
break;
case PROTOBUF_C_TYPE_UINT32:
while (rem > 0) {
unsigned s = scan_varint(rem, at);
if (s == 0) {
PROTOBUF_C_UNPACK_ERROR("bad packed-repeated enum or uint32 value");
return FALSE;
}
((uint32_t *)array)[count++] = parse_uint32(s, at);
at += s;
rem -= s;
}
break;
case PROTOBUF_C_TYPE_SINT64:
while (rem > 0) {
unsigned s = scan_varint(rem, at);
if (s == 0) {
PROTOBUF_C_UNPACK_ERROR("bad packed-repeated sint64 value");
return FALSE;
}
((int64_t *)array)[count++] = unzigzag64(parse_uint64(s, at));
at += s;
rem -= s;
}
break;
case PROTOBUF_C_TYPE_INT64:
case PROTOBUF_C_TYPE_UINT64:
while (rem > 0) {
unsigned s = scan_varint(rem, at);
if (s == 0) {
PROTOBUF_C_UNPACK_ERROR("bad packed-repeated int64/uint64 value");
return FALSE;
}
((int64_t *)array)[count++] = parse_uint64(s, at);
at += s;
rem -= s;
}
break;
case PROTOBUF_C_TYPE_BOOL:
count = rem;
for (i = 0; i < count; i++) {
if (at[i] > 1) {
PROTOBUF_C_UNPACK_ERROR("bad packed-repeated boolean value");
return FALSE;
}
((protobuf_c_boolean *)array)[i] = at[i];
}
break;
default:
PROTOBUF_C__ASSERT_NOT_REACHED();
}
*p_n += count;
return TRUE;
#if !defined(WORDS_BIGENDIAN)
no_unpacking_needed:
memcpy(array, at, count * siz);
*p_n += count;
return TRUE;
#endif
}
static protobuf_c_boolean is_packable_type(ProtobufCType type) {
return type != PROTOBUF_C_TYPE_STRING && type != PROTOBUF_C_TYPE_BYTES &&
type != PROTOBUF_C_TYPE_MESSAGE;
}
static protobuf_c_boolean parse_member(ScannedMember *scanned_member,
ProtobufCMessage *message,
ProtobufCAllocator *allocator) {
const ProtobufCFieldDescriptor *field = scanned_member->field;
void *member;
if (field == NULL) {
ProtobufCMessageUnknownField *ufield =
message->unknown_fields + (message->n_unknown_fields++);
ufield->tag = scanned_member->tag;
ufield->wire_type = scanned_member->wire_type;
ufield->len = scanned_member->len;
ufield->data = do_alloc(allocator, scanned_member->len);
if (ufield->data == NULL) return FALSE;
memcpy(ufield->data, scanned_member->data, ufield->len);
return TRUE;
}
member = (char *)message + field->offset;
switch (field->label) {
case PROTOBUF_C_LABEL_REQUIRED:
return parse_required_member(scanned_member, member, allocator, TRUE);
case PROTOBUF_C_LABEL_OPTIONAL:
case PROTOBUF_C_LABEL_NONE:
if (0 != (field->flags & PROTOBUF_C_FIELD_FLAG_ONEOF)) {
return parse_oneof_member(scanned_member, member, message, allocator);
} else {
return parse_optional_member(scanned_member, member, message,
allocator);
}
case PROTOBUF_C_LABEL_REPEATED:
if (scanned_member->wire_type == PROTOBUF_C_WIRE_TYPE_LENGTH_PREFIXED &&
(0 != (field->flags & PROTOBUF_C_FIELD_FLAG_PACKED) ||
is_packable_type(field->type))) {
return parse_packed_repeated_member(scanned_member, member, message);
} else {
return parse_repeated_member(scanned_member, member, message,
allocator);
}
}
PROTOBUF_C__ASSERT_NOT_REACHED();
return 0;
}
/**
* Initialise messages generated by old code.
*
* This function is used if desc->message_init == NULL (which occurs
* for old code, and which would be useful to support allocating
* descriptors dynamically).
*/
static void message_init_generic(const ProtobufCMessageDescriptor *desc,
ProtobufCMessage *message) {
unsigned i;
memset(message, 0, desc->sizeof_message);
message->descriptor = desc;
for (i = 0; i < desc->n_fields; i++) {
if (desc->fields[i].default_value != NULL &&
desc->fields[i].label != PROTOBUF_C_LABEL_REPEATED) {
void *field = STRUCT_MEMBER_P(message, desc->fields[i].offset);
const void *dv = desc->fields[i].default_value;
switch (desc->fields[i].type) {
case PROTOBUF_C_TYPE_INT32:
case PROTOBUF_C_TYPE_SINT32:
case PROTOBUF_C_TYPE_SFIXED32:
case PROTOBUF_C_TYPE_UINT32:
case PROTOBUF_C_TYPE_FIXED32:
case PROTOBUF_C_TYPE_FLOAT:
case PROTOBUF_C_TYPE_ENUM:
memcpy(field, dv, 4);
break;
case PROTOBUF_C_TYPE_INT64:
case PROTOBUF_C_TYPE_SINT64:
case PROTOBUF_C_TYPE_SFIXED64:
case PROTOBUF_C_TYPE_UINT64:
case PROTOBUF_C_TYPE_FIXED64:
case PROTOBUF_C_TYPE_DOUBLE:
memcpy(field, dv, 8);
break;
case PROTOBUF_C_TYPE_BOOL:
memcpy(field, dv, sizeof(protobuf_c_boolean));
break;
case PROTOBUF_C_TYPE_BYTES:
memcpy(field, dv, sizeof(ProtobufCBinaryData));
break;
case PROTOBUF_C_TYPE_STRING:
case PROTOBUF_C_TYPE_MESSAGE:
/*
* The next line essentially implements a cast
* from const, which is totally unavoidable.
*/
*(const void **)field = dv;
break;
}
}
}
}
/**@}*/
/*
* ScannedMember slabs (an unpacking implementation detail). Before doing real
* unpacking, we first scan through the elements to see how many there are (for
* repeated fields), and which field to use (for non-repeated fields given
* twice).
*
* In order to avoid allocations for small messages, we keep a stack-allocated
* slab of ScannedMembers of size FIRST_SCANNED_MEMBER_SLAB_SIZE (16). After we
* fill that up, we allocate each slab twice as large as the previous one.
*/
#define FIRST_SCANNED_MEMBER_SLAB_SIZE_LOG2 4
/*
* The number of slabs, including the stack-allocated ones; choose the number so
* that we would overflow if we needed a slab larger than provided.
*/
#define MAX_SCANNED_MEMBER_SLAB \
(sizeof(unsigned int) * 8 - 1 - BOUND_SIZEOF_SCANNED_MEMBER_LOG2 - \
FIRST_SCANNED_MEMBER_SLAB_SIZE_LOG2)
#define REQUIRED_FIELD_BITMAP_SET(index) \
(required_fields_bitmap[(index) / 8] |= (1UL << ((index) % 8)))
#define REQUIRED_FIELD_BITMAP_IS_SET(index) \
(required_fields_bitmap[(index) / 8] & (1UL << ((index) % 8)))
ProtobufCMessage *protobuf_c_message_unpack(
const ProtobufCMessageDescriptor *desc, ProtobufCAllocator *allocator,
size_t len, const uint8_t *data) {
ProtobufCMessage *rv;
size_t rem = len;
const uint8_t *at = data;
const ProtobufCFieldDescriptor *last_field = desc->fields + 0;
ScannedMember first_member_slab[1UL << FIRST_SCANNED_MEMBER_SLAB_SIZE_LOG2];
/*
* scanned_member_slabs[i] is an array of arrays of ScannedMember.
* The first slab (scanned_member_slabs[0] is just a pointer to
* first_member_slab), above. All subsequent slabs will be allocated
* using the allocator.
*/
ScannedMember *scanned_member_slabs[MAX_SCANNED_MEMBER_SLAB + 1];
unsigned which_slab = 0; /* the slab we are currently populating */
unsigned in_slab_index = 0; /* number of members in the slab */
size_t n_unknown = 0;
unsigned f;
unsigned j;
unsigned i_slab;
unsigned last_field_index = 0;
unsigned required_fields_bitmap_len;
unsigned char required_fields_bitmap_stack[16];
unsigned char *required_fields_bitmap = required_fields_bitmap_stack;
protobuf_c_boolean required_fields_bitmap_alloced = FALSE;
ASSERT_IS_MESSAGE_DESCRIPTOR(desc);
if (allocator == NULL) allocator = &protobuf_c__allocator;
rv = do_alloc(allocator, desc->sizeof_message);
if (!rv) return (NULL);
scanned_member_slabs[0] = first_member_slab;
required_fields_bitmap_len = (desc->n_fields + 7) / 8;
if (required_fields_bitmap_len > sizeof(required_fields_bitmap_stack)) {
required_fields_bitmap = do_alloc(allocator, required_fields_bitmap_len);
if (!required_fields_bitmap) {
do_free(allocator, rv);
return (NULL);
}
required_fields_bitmap_alloced = TRUE;
}
memset(required_fields_bitmap, 0, required_fields_bitmap_len);
/*
* Generated code always defines "message_init". However, we provide a
* fallback for (1) users of old protobuf-c generated-code that do not
* provide the function, and (2) descriptors constructed from some other
* source (most likely, direct construction from the .proto file).
*/
if (desc->message_init != NULL)
protobuf_c_message_init(desc, rv);
else
message_init_generic(desc, rv);
while (rem > 0) {
uint32_t tag;
ProtobufCWireType wire_type;
size_t used = parse_tag_and_wiretype(rem, at, &tag, &wire_type);
const ProtobufCFieldDescriptor *field;
ScannedMember tmp;
if (used == 0) {
PROTOBUF_C_UNPACK_ERROR("error parsing tag/wiretype at offset %u",
(unsigned)(at - data));
goto error_cleanup_during_scan;
}
/*
* \todo Consider optimizing for field[1].id == tag, if field[1]
* exists!
*/
if (last_field == NULL || last_field->id != tag) {
/* lookup field */
int field_index =
int_range_lookup(desc->n_field_ranges, desc->field_ranges, tag);
if (field_index < 0) {
field = NULL;
n_unknown++;
} else {
field = desc->fields + field_index;
last_field = field;
last_field_index = field_index;
}
} else {
field = last_field;
}
if (field != NULL && field->label == PROTOBUF_C_LABEL_REQUIRED)
REQUIRED_FIELD_BITMAP_SET(last_field_index);
at += used;
rem -= used;
tmp.tag = tag;
tmp.wire_type = wire_type;
tmp.field = field;
tmp.data = at;
tmp.length_prefix_len = 0;
switch (wire_type) {
case PROTOBUF_C_WIRE_TYPE_VARINT: {
unsigned max_len = rem < 10 ? rem : 10;
unsigned i;
for (i = 0; i < max_len; i++)
if ((at[i] & 0x80) == 0) break;
if (i == max_len) {
PROTOBUF_C_UNPACK_ERROR("unterminated varint at offset %u",
(unsigned)(at - data));
goto error_cleanup_during_scan;
}
tmp.len = i + 1;
break;
}
case PROTOBUF_C_WIRE_TYPE_64BIT:
if (rem < 8) {
PROTOBUF_C_UNPACK_ERROR("too short after 64bit wiretype at offset %u",
(unsigned)(at - data));
goto error_cleanup_during_scan;
}
tmp.len = 8;
break;
case PROTOBUF_C_WIRE_TYPE_LENGTH_PREFIXED: {
size_t pref_len;
tmp.len = scan_length_prefixed_data(rem, at, &pref_len);
if (tmp.len == 0) {
/* NOTE: scan_length_prefixed_data calls UNPACK_ERROR */
goto error_cleanup_during_scan;
}
tmp.length_prefix_len = pref_len;
break;
}
case PROTOBUF_C_WIRE_TYPE_32BIT:
if (rem < 4) {
PROTOBUF_C_UNPACK_ERROR("too short after 32bit wiretype at offset %u",
(unsigned)(at - data));
goto error_cleanup_during_scan;
}
tmp.len = 4;
break;
default:
PROTOBUF_C_UNPACK_ERROR("unsupported tag %u at offset %u", wire_type,
(unsigned)(at - data));
goto error_cleanup_during_scan;
}
if (in_slab_index ==
(1UL << (which_slab + FIRST_SCANNED_MEMBER_SLAB_SIZE_LOG2))) {
size_t size;
in_slab_index = 0;
if (which_slab == MAX_SCANNED_MEMBER_SLAB) {
PROTOBUF_C_UNPACK_ERROR("too many fields");
goto error_cleanup_during_scan;
}
which_slab++;
size = sizeof(ScannedMember)
<< (which_slab + FIRST_SCANNED_MEMBER_SLAB_SIZE_LOG2);
scanned_member_slabs[which_slab] = do_alloc(allocator, size);
if (scanned_member_slabs[which_slab] == NULL)
goto error_cleanup_during_scan;
}
scanned_member_slabs[which_slab][in_slab_index++] = tmp;
if (field != NULL && field->label == PROTOBUF_C_LABEL_REPEATED) {
size_t *n = STRUCT_MEMBER_PTR(size_t, rv, field->quantifier_offset);
if (wire_type == PROTOBUF_C_WIRE_TYPE_LENGTH_PREFIXED &&
(0 != (field->flags & PROTOBUF_C_FIELD_FLAG_PACKED) ||
is_packable_type(field->type))) {
size_t count;
if (!count_packed_elements(field->type, tmp.len - tmp.length_prefix_len,
tmp.data + tmp.length_prefix_len, &count)) {
PROTOBUF_C_UNPACK_ERROR("counting packed elements");
goto error_cleanup_during_scan;
}
*n += count;
} else {
*n += 1;
}
}
at += tmp.len;
rem -= tmp.len;
}
/* allocate space for repeated fields, also check that all required fields
* have been set */
for (f = 0; f < desc->n_fields; f++) {
const ProtobufCFieldDescriptor *field = desc->fields + f;
if (field->label == PROTOBUF_C_LABEL_REPEATED) {
size_t siz = sizeof_elt_in_repeated_array(field->type);
size_t *n_ptr = STRUCT_MEMBER_PTR(size_t, rv, field->quantifier_offset);
if (*n_ptr != 0) {
unsigned n = *n_ptr;
void *a;
*n_ptr = 0;
assert(rv->descriptor != NULL);
#define CLEAR_REMAINING_N_PTRS() \
for (f++; f < desc->n_fields; f++) { \
field = desc->fields + f; \
if (field->label == PROTOBUF_C_LABEL_REPEATED) \
STRUCT_MEMBER(size_t, rv, field->quantifier_offset) = 0; \
}
a = do_alloc(allocator, siz * n);
if (!a) {
CLEAR_REMAINING_N_PTRS();
goto error_cleanup;
}
STRUCT_MEMBER(void *, rv, field->offset) = a;
}
} else if (field->label == PROTOBUF_C_LABEL_REQUIRED) {
if (field->default_value == NULL && !REQUIRED_FIELD_BITMAP_IS_SET(f)) {
CLEAR_REMAINING_N_PTRS();
PROTOBUF_C_UNPACK_ERROR("message '%s': missing required field '%s'",
desc->name, field->name);
goto error_cleanup;
}
}
}
#undef CLEAR_REMAINING_N_PTRS
/* allocate space for unknown fields */
if (n_unknown) {
rv->unknown_fields =
do_alloc(allocator, n_unknown * sizeof(ProtobufCMessageUnknownField));
if (rv->unknown_fields == NULL) goto error_cleanup;
}
/* do real parsing */
for (i_slab = 0; i_slab <= which_slab; i_slab++) {
unsigned max =
(i_slab == which_slab) ? in_slab_index : (1UL << (i_slab + 4));
ScannedMember *slab = scanned_member_slabs[i_slab];
for (j = 0; j < max; j++) {
if (!parse_member(slab + j, rv, allocator)) {
PROTOBUF_C_UNPACK_ERROR(
"error parsing member %s of %s",
slab->field ? slab->field->name : "*unknown-field*", desc->name);
goto error_cleanup;
}
}
}
/* cleanup */
for (j = 1; j <= which_slab; j++) do_free(allocator, scanned_member_slabs[j]);
if (required_fields_bitmap_alloced)
do_free(allocator, required_fields_bitmap);
return rv;
error_cleanup:
protobuf_c_message_free_unpacked(rv, allocator);
for (j = 1; j <= which_slab; j++) do_free(allocator, scanned_member_slabs[j]);
if (required_fields_bitmap_alloced)
do_free(allocator, required_fields_bitmap);
return NULL;
error_cleanup_during_scan:
do_free(allocator, rv);
for (j = 1; j <= which_slab; j++) do_free(allocator, scanned_member_slabs[j]);
if (required_fields_bitmap_alloced)
do_free(allocator, required_fields_bitmap);
return NULL;
}
void protobuf_c_message_free_unpacked(ProtobufCMessage *message,
ProtobufCAllocator *allocator) {
const ProtobufCMessageDescriptor *desc;
unsigned f;
if (message == NULL) return;
desc = message->descriptor;
ASSERT_IS_MESSAGE(message);
if (allocator == NULL) allocator = &protobuf_c__allocator;
message->descriptor = NULL;
for (f = 0; f < desc->n_fields; f++) {
if (0 != (desc->fields[f].flags & PROTOBUF_C_FIELD_FLAG_ONEOF) &&
desc->fields[f].id !=
STRUCT_MEMBER(uint32_t, message,
desc->fields[f].quantifier_offset)) {
/* This is not the selected oneof, skip it */
continue;
}
if (desc->fields[f].label == PROTOBUF_C_LABEL_REPEATED) {
size_t n =
STRUCT_MEMBER(size_t, message, desc->fields[f].quantifier_offset);
void *arr = STRUCT_MEMBER(void *, message, desc->fields[f].offset);
if (arr != NULL) {
if (desc->fields[f].type == PROTOBUF_C_TYPE_STRING) {
unsigned i;
for (i = 0; i < n; i++) do_free(allocator, ((char **)arr)[i]);
} else if (desc->fields[f].type == PROTOBUF_C_TYPE_BYTES) {
unsigned i;
for (i = 0; i < n; i++)
do_free(allocator, ((ProtobufCBinaryData *)arr)[i].data);
} else if (desc->fields[f].type == PROTOBUF_C_TYPE_MESSAGE) {
unsigned i;
for (i = 0; i < n; i++)
protobuf_c_message_free_unpacked(((ProtobufCMessage **)arr)[i],
allocator);
}
do_free(allocator, arr);
}
} else if (desc->fields[f].type == PROTOBUF_C_TYPE_STRING) {
char *str = STRUCT_MEMBER(char *, message, desc->fields[f].offset);
if (str && str != desc->fields[f].default_value) do_free(allocator, str);
} else if (desc->fields[f].type == PROTOBUF_C_TYPE_BYTES) {
void *data =
STRUCT_MEMBER(ProtobufCBinaryData, message, desc->fields[f].offset)
.data;
const ProtobufCBinaryData *default_bd;
default_bd = desc->fields[f].default_value;
if (data != NULL && (default_bd == NULL || default_bd->data != data)) {
do_free(allocator, data);
}
} else if (desc->fields[f].type == PROTOBUF_C_TYPE_MESSAGE) {
ProtobufCMessage *sm;
sm = STRUCT_MEMBER(ProtobufCMessage *, message, desc->fields[f].offset);
if (sm && sm != desc->fields[f].default_value)
protobuf_c_message_free_unpacked(sm, allocator);
}
}
for (f = 0; f < message->n_unknown_fields; f++)
do_free(allocator, message->unknown_fields[f].data);
if (message->unknown_fields != NULL)
do_free(allocator, message->unknown_fields);
do_free(allocator, message);
}
void protobuf_c_message_init(const ProtobufCMessageDescriptor *descriptor,
void *message) {
descriptor->message_init((ProtobufCMessage *)(message));
}
protobuf_c_boolean protobuf_c_message_check(const ProtobufCMessage *message) {
unsigned i;
if (!message || !message->descriptor ||
message->descriptor->magic != PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC) {
return FALSE;
}
for (i = 0; i < message->descriptor->n_fields; i++) {
const ProtobufCFieldDescriptor *f = message->descriptor->fields + i;
ProtobufCType type = f->type;
ProtobufCLabel label = f->label;
void *field = STRUCT_MEMBER_P(message, f->offset);
if (label == PROTOBUF_C_LABEL_REPEATED) {
size_t *quantity = STRUCT_MEMBER_P(message, f->quantifier_offset);
if (*quantity > 0 && *(void **)field == NULL) {
return FALSE;
}
if (type == PROTOBUF_C_TYPE_MESSAGE) {
ProtobufCMessage **submessage = *(ProtobufCMessage ***)field;
unsigned j;
for (j = 0; j < *quantity; j++) {
if (!protobuf_c_message_check(submessage[j])) return FALSE;
}
} else if (type == PROTOBUF_C_TYPE_STRING) {
char **string = *(char ***)field;
unsigned j;
for (j = 0; j < *quantity; j++) {
if (!string[j]) return FALSE;
}
} else if (type == PROTOBUF_C_TYPE_BYTES) {
ProtobufCBinaryData *bd = *(ProtobufCBinaryData **)field;
unsigned j;
for (j = 0; j < *quantity; j++) {
if (bd[j].len > 0 && bd[j].data == NULL) return FALSE;
}
}
} else { /* PROTOBUF_C_LABEL_REQUIRED or PROTOBUF_C_LABEL_OPTIONAL */
if (type == PROTOBUF_C_TYPE_MESSAGE) {
ProtobufCMessage *submessage = *(ProtobufCMessage **)field;
if (label == PROTOBUF_C_LABEL_REQUIRED || submessage != NULL) {
if (!protobuf_c_message_check(submessage)) return FALSE;
}
} else if (type == PROTOBUF_C_TYPE_STRING) {
char *string = *(char **)field;
if (label == PROTOBUF_C_LABEL_REQUIRED && string == NULL) return FALSE;
} else if (type == PROTOBUF_C_TYPE_BYTES) {
protobuf_c_boolean *has =
STRUCT_MEMBER_P(message, f->quantifier_offset);
ProtobufCBinaryData *bd = field;
if (label == PROTOBUF_C_LABEL_REQUIRED || *has == TRUE) {
if (bd->len > 0 && bd->data == NULL) return FALSE;
}
}
}
}
return TRUE;
}
/* === services === */
typedef void (*GenericHandler)(void *service, const ProtobufCMessage *input,
ProtobufCClosure closure, void *closure_data);
/*
* Copyright (c) 2008-2017, Dave Benson and the protobuf-c authors.
* 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.
*
* 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.
*/
/*! \file
* \mainpage Introduction
*
* This is [protobuf-c], a C implementation of [Protocol Buffers].
*
* This file defines the public API for the `libprotobuf-c` support library.
* This API includes interfaces that can be used directly by client code as well
* as the interfaces used by the code generated by the `protoc-c` compiler.
*
* The `libprotobuf-c` support library performs the actual serialization and
* deserialization of Protocol Buffers messages. It interacts with structures,
* definitions, and metadata generated by the `protoc-c` compiler from .proto
* files.
*
* \authors Dave Benson and the `protobuf-c` authors.
*
* \copyright 2008-2014. Licensed under the terms of the [BSD-2-Clause] license.
*
* [protobuf-c]: https://github.com/protobuf-c/protobuf-c
* [Protocol Buffers]: https://developers.google.com/protocol-buffers/
* [BSD-2-Clause]: http://opensource.org/licenses/BSD-2-Clause
*
* \page gencode Generated Code
*
* For each enum, we generate a C enum. For each message, we generate a C
* structure which can be cast to a `ProtobufCMessage`.
*
* For each enum and message, we generate a descriptor object that allows us to
* implement a kind of reflection on the structures.
*
* First, some naming conventions:
*
* - The name of the type for enums and messages and services is camel case
* (meaning WordsAreCrammedTogether) except that double underscores are used
* to delimit scopes. For example, the following `.proto` file:
*
~~~{.proto}
package foo.bar;
message BazBah {
optional int32 val = 1;
}
~~~
*
* would generate a C type `Foo__Bar__BazBah`.
*
* - Identifiers for functions and globals are all lowercase, with camel case
* words separated by single underscores. For example, one of the function
* prototypes generated by `protoc-c` for the above example:
*
~~~{.c}
Foo__Bar__BazBah *
foo__bar__baz_bah__unpack
(ProtobufCAllocator *allocator,
size_t len,
const uint8_t *data);
~~~
*
* - Identifiers for enum values contain an uppercase prefix which embeds the
* package name and the enum type name.
*
* - A double underscore is used to separate further components of identifier
* names.
*
* For example, in the name of the unpack function above, the package name
* `foo.bar` has become `foo__bar`, the message name BazBah has become
* `baz_bah`, and the method name is `unpack`. These are all joined with double
* underscores to form the C identifier `foo__bar__baz_bah__unpack`.
*
* We also generate descriptor objects for messages and enums. These are
* declared in the `.pb-c.h` files:
*
~~~{.c}
extern const ProtobufCMessageDescriptor foo__bar__baz_bah__descriptor;
~~~
*
* The message structures all begin with `ProtobufCMessageDescriptor *` which is
* sufficient to allow them to be cast to `ProtobufCMessage`.
*
* For each message defined in a `.proto` file, we generate a number of
* functions and macros. Each function name contains a prefix based on the
* package name and message name in order to make it a unique C identifier.
*
* - `INIT`. Statically initializes a message object, initializing its
* descriptor and setting its fields to default values. Uninitialized
* messages cannot be processed by the protobuf-c library.
*
~~~{.c}
#define FOO__BAR__BAZ_BAH__INIT \
{ PROTOBUF_C_MESSAGE_INIT (&foo__bar__baz_bah__descriptor), 0 }
~~~
* - `init()`. Initializes a message object, initializing its descriptor and
* setting its fields to default values. Uninitialized messages cannot be
* processed by the protobuf-c library.
*
~~~{.c}
void foo__bar__baz_bah__init
(Foo__Bar__BazBah *message);
~~~
* - `unpack()`. Unpacks data for a particular message format. Note that the
* `allocator` parameter is usually `NULL` to indicate that the system's
* `malloc()` and `free()` functions should be used for dynamically allocating
* memory.
*
~~~{.c}
Foo__Bar__BazBah *
foo__bar__baz_bah__unpack
(ProtobufCAllocator *allocator,
size_t len,
const uint8_t *data);
~~~
*
* - `free_unpacked()`. Frees a message object obtained with the `unpack()`
* method. Freeing `NULL` is allowed (the same as with `free()`).
*
~~~{.c}
void foo__bar__baz_bah__free_unpacked
(Foo__Bar__BazBah *message,
ProtobufCAllocator *allocator);
~~~
*
* - `get_packed_size()`. Calculates the length in bytes of the serialized
* representation of the message object.
*
~~~{.c}
size_t foo__bar__baz_bah__get_packed_size
(const Foo__Bar__BazBah *message);
~~~
*
* - `pack()`. Pack a message object into a preallocated buffer. Assumes that
* the buffer is large enough. (Use `get_packed_size()` first.)
*
~~~{.c}
size_t foo__bar__baz_bah__pack
(const Foo__Bar__BazBah *message,
uint8_t *out);
~~~
*
* - `pack_to_buffer()`. Packs a message into a "virtual buffer". This is an
* object which defines an "append bytes" callback to consume data as it is
* serialized.
*
~~~{.c}
size_t foo__bar__baz_bah__pack_to_buffer
(const Foo__Bar__BazBah *message,
ProtobufCBuffer *buffer);
~~~
*
* \page pack Packing and unpacking messages
*
* To pack a message, first compute the packed size of the message with
* protobuf_c_message_get_packed_size(), then allocate a buffer of at least
* that size, then call protobuf_c_message_pack().
*
* Alternatively, a message can be serialized without calculating the final size
* first. Use the protobuf_c_message_pack_to_buffer() function and provide a
* ProtobufCBuffer object which implements an "append" method that consumes
* data.
*
* To unpack a message, call the protobuf_c_message_unpack() function. The
* result can be cast to an object of the type that matches the descriptor for
* the message.
*
* The result of unpacking a message should be freed with
* protobuf_c_message_free_unpacked().
*/
#ifndef PROTOBUF_C_H
#define PROTOBUF_C_H
#include <assert.h>
#include <limits.h>
#include <stddef.h>
#include <stdint.h>
#ifdef __cplusplus
#define PROTOBUF_C__BEGIN_DECLS extern "C" {
#define PROTOBUF_C__END_DECLS }
#else
#define PROTOBUF_C__BEGIN_DECLS
#define PROTOBUF_C__END_DECLS
#endif
PROTOBUF_C__BEGIN_DECLS
#if defined(_WIN32) && defined(PROTOBUF_C_USE_SHARED_LIB)
#ifdef PROTOBUF_C_EXPORT
#define PROTOBUF_C__API __declspec(dllexport)
#else
#define PROTOBUF_C__API __declspec(dllimport)
#endif
#else
#define PROTOBUF_C__API
#endif
#if !defined(PROTOBUF_C__NO_DEPRECATED) && \
((__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
#define PROTOBUF_C__DEPRECATED __attribute__((__deprecated__))
#else
#define PROTOBUF_C__DEPRECATED
#endif
#ifndef PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE
#define PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE(enum_name) \
, _##enum_name##_IS_INT_SIZE = INT_MAX
#endif
#define PROTOBUF_C__SERVICE_DESCRIPTOR_MAGIC 0x14159bc3
#define PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC 0x28aaeef9
#define PROTOBUF_C__ENUM_DESCRIPTOR_MAGIC 0x114315af
/* Empty string used for initializers */
extern const char protobuf_c_empty_string[];
/**
* \defgroup api Public API
*
* This is the public API for `libprotobuf-c`. These interfaces are stable and
* subject to Semantic Versioning guarantees.
*
* @{
*/
/**
* Values for the `flags` word in `ProtobufCFieldDescriptor`.
*/
typedef enum {
/** Set if the field is repeated and marked with the `packed` option. */
PROTOBUF_C_FIELD_FLAG_PACKED = (1 << 0),
/** Set if the field is marked with the `deprecated` option. */
PROTOBUF_C_FIELD_FLAG_DEPRECATED = (1 << 1),
/** Set if the field is a member of a oneof (union). */
PROTOBUF_C_FIELD_FLAG_ONEOF = (1 << 2),
} ProtobufCFieldFlag;
/**
* Message field rules.
*
* \see [Defining A Message Type] in the Protocol Buffers documentation.
*
* [Defining A Message Type]:
* https://developers.google.com/protocol-buffers/docs/proto#simple
*/
typedef enum {
/** A well-formed message must have exactly one of this field. */
PROTOBUF_C_LABEL_REQUIRED,
/**
* A well-formed message can have zero or one of this field (but not
* more than one).
*/
PROTOBUF_C_LABEL_OPTIONAL,
/**
* This field can be repeated any number of times (including zero) in a
* well-formed message. The order of the repeated values will be
* preserved.
*/
PROTOBUF_C_LABEL_REPEATED,
/**
* This field has no label. This is valid only in proto3 and is
* equivalent to OPTIONAL but no "has" quantifier will be consulted.
*/
PROTOBUF_C_LABEL_NONE,
} ProtobufCLabel;
/**
* Field value types.
*
* \see [Scalar Value Types] in the Protocol Buffers documentation.
*
* [Scalar Value Types]:
* https://developers.google.com/protocol-buffers/docs/proto#scalar
*/
typedef enum {
PROTOBUF_C_TYPE_INT32, /**< int32 */
PROTOBUF_C_TYPE_SINT32, /**< signed int32 */
PROTOBUF_C_TYPE_SFIXED32, /**< signed int32 (4 bytes) */
PROTOBUF_C_TYPE_INT64, /**< int64 */
PROTOBUF_C_TYPE_SINT64, /**< signed int64 */
PROTOBUF_C_TYPE_SFIXED64, /**< signed int64 (8 bytes) */
PROTOBUF_C_TYPE_UINT32, /**< unsigned int32 */
PROTOBUF_C_TYPE_FIXED32, /**< unsigned int32 (4 bytes) */
PROTOBUF_C_TYPE_UINT64, /**< unsigned int64 */
PROTOBUF_C_TYPE_FIXED64, /**< unsigned int64 (8 bytes) */
PROTOBUF_C_TYPE_FLOAT, /**< float */
PROTOBUF_C_TYPE_DOUBLE, /**< double */
PROTOBUF_C_TYPE_BOOL, /**< boolean */
PROTOBUF_C_TYPE_ENUM, /**< enumerated type */
PROTOBUF_C_TYPE_STRING, /**< UTF-8 or ASCII string */
PROTOBUF_C_TYPE_BYTES, /**< arbitrary byte sequence */
PROTOBUF_C_TYPE_MESSAGE, /**< nested message */
} ProtobufCType;
/**
* Field wire types.
*
* \see [Message Structure] in the Protocol Buffers documentation.
*
* [Message Structure]:
* https://developers.google.com/protocol-buffers/docs/encoding#structure
*/
typedef enum {
PROTOBUF_C_WIRE_TYPE_VARINT = 0,
PROTOBUF_C_WIRE_TYPE_64BIT = 1,
PROTOBUF_C_WIRE_TYPE_LENGTH_PREFIXED = 2,
/* "Start group" and "end group" wire types are unsupported. */
PROTOBUF_C_WIRE_TYPE_32BIT = 5,
} ProtobufCWireType;
struct ProtobufCAllocator;
struct ProtobufCBinaryData;
struct ProtobufCBuffer;
struct ProtobufCBufferSimple;
struct ProtobufCEnumDescriptor;
struct ProtobufCEnumValue;
struct ProtobufCEnumValueIndex;
struct ProtobufCFieldDescriptor;
struct ProtobufCIntRange;
struct ProtobufCMessage;
struct ProtobufCMessageDescriptor;
struct ProtobufCMessageUnknownField;
struct ProtobufCMethodDescriptor;
struct ProtobufCService;
struct ProtobufCServiceDescriptor;
typedef struct ProtobufCAllocator ProtobufCAllocator;
typedef struct ProtobufCBinaryData ProtobufCBinaryData;
typedef struct ProtobufCBuffer ProtobufCBuffer;
typedef struct ProtobufCBufferSimple ProtobufCBufferSimple;
typedef struct ProtobufCEnumDescriptor ProtobufCEnumDescriptor;
typedef struct ProtobufCEnumValue ProtobufCEnumValue;
typedef struct ProtobufCEnumValueIndex ProtobufCEnumValueIndex;
typedef struct ProtobufCFieldDescriptor ProtobufCFieldDescriptor;
typedef struct ProtobufCIntRange ProtobufCIntRange;
typedef struct ProtobufCMessage ProtobufCMessage;
typedef struct ProtobufCMessageDescriptor ProtobufCMessageDescriptor;
typedef struct ProtobufCMessageUnknownField ProtobufCMessageUnknownField;
typedef struct ProtobufCMethodDescriptor ProtobufCMethodDescriptor;
typedef struct ProtobufCService ProtobufCService;
typedef struct ProtobufCServiceDescriptor ProtobufCServiceDescriptor;
/** Boolean type. */
typedef int protobuf_c_boolean;
typedef void (*ProtobufCClosure)(const ProtobufCMessage *, void *closure_data);
typedef void (*ProtobufCMessageInit)(ProtobufCMessage *);
typedef void (*ProtobufCServiceDestroy)(ProtobufCService *);
/**
* Structure for defining a custom memory allocator.
*/
struct ProtobufCAllocator {
/** Function to allocate memory. */
void *(*alloc)(void *allocator_data, size_t size);
/** Function to free memory. */
void (*free)(void *allocator_data, void *pointer);
/** Opaque pointer passed to `alloc` and `free` functions. */
void *allocator_data;
};
/**
* Structure for the protobuf `bytes` scalar type.
*
* The data contained in a `ProtobufCBinaryData` is an arbitrary sequence of
* bytes. It may contain embedded `NUL` characters and is not required to be
* `NUL`-terminated.
*/
struct ProtobufCBinaryData {
size_t len; /**< Number of bytes in the `data` field. */
uint8_t *data; /**< Data bytes. */
};
/**
* Structure for defining a virtual append-only buffer. Used by
* protobuf_c_message_pack_to_buffer() to abstract the consumption of serialized
* bytes.
*
* `ProtobufCBuffer` "subclasses" may be defined on the stack. For example, to
* write to a `FILE` object:
*
~~~{.c}
typedef struct {
ProtobufCBuffer base;
FILE *fp;
} BufferAppendToFile;
static void
my_buffer_file_append(ProtobufCBuffer *buffer,
size_t len,
const uint8_t *data)
{
BufferAppendToFile *file_buf = (BufferAppendToFile *) buffer;
fwrite(data, len, 1, file_buf->fp); // XXX: No error handling!
}
~~~
*
* To use this new type of ProtobufCBuffer, it could be called as follows:
*
~~~{.c}
...
BufferAppendToFile tmp = {0};
tmp.base.append = my_buffer_file_append;
tmp.fp = fp;
protobuf_c_message_pack_to_buffer(&message, &tmp);
...
~~~
*/
struct ProtobufCBuffer {
/** Append function. Consumes the `len` bytes stored at `data`. */
void (*append)(ProtobufCBuffer *buffer, size_t len, const uint8_t *data);
};
/**
* Simple buffer "subclass" of `ProtobufCBuffer`.
*
* A `ProtobufCBufferSimple` object is declared on the stack and uses a
* scratch buffer provided by the user for the initial allocation. It performs
* exponential resizing, using dynamically allocated memory. A
* `ProtobufCBufferSimple` object can be created and used as follows:
*
~~~{.c}
uint8_t pad[128];
ProtobufCBufferSimple simple = PROTOBUF_C_BUFFER_SIMPLE_INIT(pad);
ProtobufCBuffer *buffer = (ProtobufCBuffer *) &simple;
~~~
*
* `buffer` can now be used with `protobuf_c_message_pack_to_buffer()`. Once a
* message has been serialized to a `ProtobufCBufferSimple` object, the
* serialized data bytes can be accessed from the `.data` field.
*
* To free the memory allocated by a `ProtobufCBufferSimple` object, if any,
* call PROTOBUF_C_BUFFER_SIMPLE_CLEAR() on the object, for example:
*
~~~{.c}
PROTOBUF_C_BUFFER_SIMPLE_CLEAR(&simple);
~~~
*
* \see PROTOBUF_C_BUFFER_SIMPLE_INIT
* \see PROTOBUF_C_BUFFER_SIMPLE_CLEAR
*/
struct ProtobufCBufferSimple {
/** "Base class". */
ProtobufCBuffer base;
/** Number of bytes allocated in `data`. */
size_t alloced;
/** Number of bytes currently stored in `data`. */
size_t len;
/** Data bytes. */
uint8_t *data;
/** Whether `data` must be freed. */
protobuf_c_boolean must_free_data;
/** Allocator to use. May be NULL to indicate the system allocator. */
ProtobufCAllocator *allocator;
};
/**
* Describes an enumeration as a whole, with all of its values.
*/
struct ProtobufCEnumDescriptor {
/** Magic value checked to ensure that the API is used correctly. */
uint32_t magic;
/** The qualified name (e.g., "namespace.Type"). */
const char *name;
/** The unqualified name as given in the .proto file (e.g., "Type"). */
const char *short_name;
/** Identifier used in generated C code. */
const char *c_name;
/** The dot-separated namespace. */
const char *package_name;
/** Number elements in `values`. */
unsigned n_values;
/** Array of distinct values, sorted by numeric value. */
const ProtobufCEnumValue *values;
/** Number of elements in `values_by_name`. */
unsigned n_value_names;
/** Array of named values, including aliases, sorted by name. */
const ProtobufCEnumValueIndex *values_by_name;
/** Number of elements in `value_ranges`. */
unsigned n_value_ranges;
/** Value ranges, for faster lookups by numeric value. */
const ProtobufCIntRange *value_ranges;
/** Reserved for future use. */
void *reserved1;
/** Reserved for future use. */
void *reserved2;
/** Reserved for future use. */
void *reserved3;
/** Reserved for future use. */
void *reserved4;
};
/**
* Represents a single value of an enumeration.
*/
struct ProtobufCEnumValue {
/** The string identifying this value in the .proto file. */
const char *name;
/** The string identifying this value in generated C code. */
const char *c_name;
/** The numeric value assigned in the .proto file. */
int value;
};
/**
* Used by `ProtobufCEnumDescriptor` to look up enum values.
*/
struct ProtobufCEnumValueIndex {
/** Name of the enum value. */
const char *name;
/** Index into values[] array. */
unsigned index;
};
/**
* Describes a single field in a message.
*/
struct ProtobufCFieldDescriptor {
/** Name of the field as given in the .proto file. */
const char *name;
/** Tag value of the field as given in the .proto file. */
uint32_t id;
/** Whether the field is `REQUIRED`, `OPTIONAL`, or `REPEATED`. */
ProtobufCLabel label;
/** The type of the field. */
ProtobufCType type;
/**
* The offset in bytes of the message's C structure's quantifier field
* (the `has_MEMBER` field for optional members or the `n_MEMBER` field
* for repeated members or the case enum for oneofs).
*/
unsigned quantifier_offset;
/**
* The offset in bytes into the message's C structure for the member
* itself.
*/
unsigned offset;
/**
* A type-specific descriptor.
*
* If `type` is `PROTOBUF_C_TYPE_ENUM`, then `descriptor` points to the
* corresponding `ProtobufCEnumDescriptor`.
*
* If `type` is `PROTOBUF_C_TYPE_MESSAGE`, then `descriptor` points to
* the corresponding `ProtobufCMessageDescriptor`.
*
* Otherwise this field is NULL.
*/
const void *descriptor; /* for MESSAGE and ENUM types */
/** The default value for this field, if defined. May be NULL. */
const void *default_value;
/**
* A flag word. Zero or more of the bits defined in the
* `ProtobufCFieldFlag` enum may be set.
*/
uint32_t flags;
/** Reserved for future use. */
unsigned reserved_flags;
/** Reserved for future use. */
void *reserved2;
/** Reserved for future use. */
void *reserved3;
};
/**
* Helper structure for optimizing int => index lookups in the case
* where the keys are mostly consecutive values, as they presumably are for
* enums and fields.
*
* The data structures requires that the values in the original array are
* sorted.
*/
struct ProtobufCIntRange {
int start_value;
unsigned orig_index;
/*
* NOTE: the number of values in the range can be inferred by looking
* at the next element's orig_index. A dummy element is added to make
* this simple.
*/
};
/**
* An instance of a message.
*
* `ProtobufCMessage` is a light-weight "base class" for all messages.
*
* In particular, `ProtobufCMessage` doesn't have any allocation policy
* associated with it. That's because it's common to create `ProtobufCMessage`
* objects on the stack. In fact, that's what we recommend for sending messages.
* If the object is allocated from the stack, you can't really have a memory
* leak.
*
* This means that calls to functions like protobuf_c_message_unpack() which
* return a `ProtobufCMessage` must be paired with a call to a free function,
* like protobuf_c_message_free_unpacked().
*/
struct ProtobufCMessage {
/** The descriptor for this message type. */
const ProtobufCMessageDescriptor *descriptor;
/** The number of elements in `unknown_fields`. */
unsigned n_unknown_fields;
/** The fields that weren't recognized by the parser. */
ProtobufCMessageUnknownField *unknown_fields;
};
/**
* Describes a message.
*/
struct ProtobufCMessageDescriptor {
/** Magic value checked to ensure that the API is used correctly. */
uint32_t magic;
/** The qualified name (e.g., "namespace.Type"). */
const char *name;
/** The unqualified name as given in the .proto file (e.g., "Type"). */
const char *short_name;
/** Identifier used in generated C code. */
const char *c_name;
/** The dot-separated namespace. */
const char *package_name;
/**
* Size in bytes of the C structure representing an instance of this
* type of message.
*/
size_t sizeof_message;
/** Number of elements in `fields`. */
unsigned n_fields;
/** Field descriptors, sorted by tag number. */
const ProtobufCFieldDescriptor *fields;
/** Used for looking up fields by name. */
const unsigned *fields_sorted_by_name;
/** Number of elements in `field_ranges`. */
unsigned n_field_ranges;
/** Used for looking up fields by id. */
const ProtobufCIntRange *field_ranges;
/** Message initialisation function. */
ProtobufCMessageInit message_init;
/** Reserved for future use. */
void *reserved1;
/** Reserved for future use. */
void *reserved2;
/** Reserved for future use. */
void *reserved3;
};
/**
* An unknown message field.
*/
struct ProtobufCMessageUnknownField {
/** The tag number. */
uint32_t tag;
/** The wire type of the field. */
ProtobufCWireType wire_type;
/** Number of bytes in `data`. */
size_t len;
/** Field data. */
uint8_t *data;
};
/**
* Method descriptor.
*/
struct ProtobufCMethodDescriptor {
/** Method name. */
const char *name;
/** Input message descriptor. */
const ProtobufCMessageDescriptor *input;
/** Output message descriptor. */
const ProtobufCMessageDescriptor *output;
};
/**
* Service.
*/
struct ProtobufCService {
/** Service descriptor. */
const ProtobufCServiceDescriptor *descriptor;
/** Function to invoke the service. */
void (*invoke)(ProtobufCService *service, unsigned method_index,
const ProtobufCMessage *input, ProtobufCClosure closure,
void *closure_data);
/** Function to destroy the service. */
void (*destroy)(ProtobufCService *service);
};
/**
* Service descriptor.
*/
struct ProtobufCServiceDescriptor {
/** Magic value checked to ensure that the API is used correctly. */
uint32_t magic;
/** Service name. */
const char *name;
/** Short version of service name. */
const char *short_name;
/** C identifier for the service name. */
const char *c_name;
/** Package name. */
const char *package;
/** Number of elements in `methods`. */
unsigned n_methods;
/** Method descriptors, in the order defined in the .proto file. */
const ProtobufCMethodDescriptor *methods;
/** Sort index of methods. */
const unsigned *method_indices_by_name;
};
/**
* Get the version of the protobuf-c library. Note that this is the version of
* the library linked against, not the version of the headers compiled against.
*
* \return A string containing the version number of protobuf-c.
*/
PROTOBUF_C__API
const char *protobuf_c_version(void);
/**
* Get the version of the protobuf-c library. Note that this is the version of
* the library linked against, not the version of the headers compiled against.
*
* \return A 32 bit unsigned integer containing the version number of
* protobuf-c, represented in base-10 as (MAJOR*1E6) + (MINOR*1E3) + PATCH.
*/
PROTOBUF_C__API
uint32_t protobuf_c_version_number(void);
/**
* The version of the protobuf-c headers, represented as a string using the same
* format as protobuf_c_version().
*/
#define PROTOBUF_C_VERSION "1.3.0"
/**
* The version of the protobuf-c headers, represented as an integer using the
* same format as protobuf_c_version_number().
*/
#define PROTOBUF_C_VERSION_NUMBER 1003000
/**
* The minimum protoc-c version which works with the current version of the
* protobuf-c headers.
*/
#define PROTOBUF_C_MIN_COMPILER_VERSION 1000000
/**
* Determine the number of bytes required to store the serialised message.
*
* \param message
* The message object to serialise.
* \return
* Number of bytes.
*/
PROTOBUF_C__API
size_t protobuf_c_message_get_packed_size(const ProtobufCMessage *message);
/**
* Unpack a serialised message into an in-memory representation.
*
* \param descriptor
* The message descriptor.
* \param allocator
* `ProtobufCAllocator` to use for memory allocation. May be NULL to
* specify the default allocator.
* \param len
* Length in bytes of the serialised message.
* \param data
* Pointer to the serialised message.
* \return
* An unpacked message object.
* \retval NULL
* If an error occurred during unpacking.
*/
PROTOBUF_C__API
ProtobufCMessage *protobuf_c_message_unpack(
const ProtobufCMessageDescriptor *descriptor, ProtobufCAllocator *allocator,
size_t len, const uint8_t *data);
/**
* Free an unpacked message object.
*
* This function should be used to deallocate the memory used by a call to
* protobuf_c_message_unpack().
*
* \param message
* The message object to free. May be NULL.
* \param allocator
* `ProtobufCAllocator` to use for memory deallocation. May be NULL to
* specify the default allocator.
*/
PROTOBUF_C__API
void protobuf_c_message_free_unpacked(ProtobufCMessage *message,
ProtobufCAllocator *allocator);
/**
* Check the validity of a message object.
*
* Makes sure all required fields (`PROTOBUF_C_LABEL_REQUIRED`) are present.
* Recursively checks nested messages.
*
* \retval TRUE
* Message is valid.
* \retval FALSE
* Message is invalid.
*/
PROTOBUF_C__API
protobuf_c_boolean protobuf_c_message_check(const ProtobufCMessage *);
/** Message initialiser. */
#define PROTOBUF_C_MESSAGE_INIT(descriptor) \
{ descriptor, 0, NULL }
/**
* Initialise a message object from a message descriptor.
*
* \param descriptor
* Message descriptor.
* \param message
* Allocated block of memory of size `descriptor->sizeof_message`.
*/
PROTOBUF_C__API
void protobuf_c_message_init(const ProtobufCMessageDescriptor *descriptor,
void *message);
/**
* Initialise a `ProtobufCBufferSimple` object.
*/
#define PROTOBUF_C_BUFFER_SIMPLE_INIT(array_of_bytes) \
{ \
{protobuf_c_buffer_simple_append}, sizeof(array_of_bytes), 0, \
(array_of_bytes), 0, NULL \
}
/**
* Clear a `ProtobufCBufferSimple` object, freeing any allocated memory.
*/
#define PROTOBUF_C_BUFFER_SIMPLE_CLEAR(simp_buf) \
do { \
if ((simp_buf)->must_free_data) { \
if ((simp_buf)->allocator != NULL) \
(simp_buf)->allocator->free((simp_buf)->allocator, (simp_buf)->data); \
else \
free((simp_buf)->data); \
} \
} while (0)
/**
* The `append` method for `ProtobufCBufferSimple`.
*
* \param buffer
* The buffer object to append to. Must actually be a
* `ProtobufCBufferSimple` object.
* \param len
* Number of bytes in `data`.
* \param data
* Data to append.
*/
PROTOBUF_C__API
void protobuf_c_buffer_simple_append(ProtobufCBuffer *buffer, size_t len,
const unsigned char *data);
/**@}*/
PROTOBUF_C__END_DECLS
#endif /* PROTOBUF_C_H */
/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. */
#pragma once
#include <vector>
#include "src/framework.pb-c.h"
namespace paddle_mobile {
namespace framework {
enum VarType_Type {
VARTYPE_TYPE_BOOL = 0,
VARTYPE_TYPE_INT16 = 1,
VARTYPE_TYPE_INT32 = 2,
VARTYPE_TYPE_INT64 = 3,
VARTYPE_TYPE_FP16 = 4,
VARTYPE_TYPE_FP32 = 5,
VARTYPE_TYPE_FP64 = 6,
VARTYPE_TYPE_LOD_TENSOR = 7,
VARTYPE_TYPE_SELECTED_ROWS = 8,
VARTYPE_TYPE_FEED_MINIBATCH = 9,
VARTYPE_TYPE_FETCH_LIST = 10,
VARTYPE_TYPE_STEP_SCOPES = 11,
VARTYPE_TYPE_STEP_LOD_RANK_TABLE = 12,
VARTYPE_TYPE_STEP_LOD_TENSOR_ARRAY = 13,
VARTYPE_TYPE_STEP_PLACE_LIST = 14,
VARTYPE_TYPE_READER = 15,
VARTYPE_TYPE_CHANNEL = 16,
VARTYPE_TYPE_RAW = 17,
VARTYPE_TYPE_TUPLE = 18
};
class TensorDesc {
public:
TensorDesc() = default;
TensorDesc(const TensorDesc &desc) {
this->dims_ = desc.dims_;
this->data_type_ = desc.data_type_;
}
explicit TensorDesc(
PaddleMobile__Framework__Proto__VarType__TensorDesc *desc) {
for (int i = 0; i < desc->n_dims; ++i) {
int64_t d = desc->dims[i];
dims_.emplace_back(d);
}
data_type_ = (VarType_Type)desc->data_type;
}
std::vector<int64_t> Dims() const { return dims_; }
VarType_Type DataType() const { return data_type_; }
private:
std::vector<int64_t> dims_;
VarType_Type data_type_;
};
} // namespace framework
} // namespace paddle_mobile
/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. */
#pragma once
#include <string>
#include "src/framework.pb-c.h"
#include "src/tensor_desc.h"
namespace paddle_mobile {
namespace framework {
class VarDesc {
public:
VarDesc(const VarDesc &var_desc) {
this->data_type_ = var_desc.data_type_;
this->name_ = var_desc.name_;
this->persistable_ = var_desc.persistable_;
this->tensor_desc_ = var_desc.tensor_desc_;
this->type_ = var_desc.type_;
}
explicit VarDesc(PaddleMobile__Framework__Proto__VarDesc *desc) {
type_ = (VarType_Type)desc->type->type;
name_ = std::string(desc->name);
persistable_ = static_cast<bool>(desc->persistable);
switch (type_) {
case VARTYPE_TYPE_SELECTED_ROWS:
tensor_desc_ = TensorDesc(desc->type->selected_rows);
break;
case VARTYPE_TYPE_LOD_TENSOR:
tensor_desc_ = TensorDesc(desc->type->lod_tensor->tensor);
break;
case VARTYPE_TYPE_STEP_LOD_TENSOR_ARRAY:
// desc->type->tensor_array->tensor->data_type;
tensor_desc_ = TensorDesc(desc->type->tensor_array->tensor);
break;
default:
break;
}
switch (type_) {
case VARTYPE_TYPE_CHANNEL:
data_type_ = (VarType_Type)desc->type->channel->data_type;
break;
default:
data_type_ = tensor_desc_.DataType();
break;
}
}
std::string Name() const { return name_; }
VarType_Type Type() const { return type_; }
bool Persistable() const { return persistable_; }
const TensorDesc &Tensor_desc() const { return tensor_desc_; }
private:
std::string name_;
bool persistable_;
TensorDesc tensor_desc_;
VarType_Type type_;
VarType_Type data_type_;
};
} // namespace framework
} // namespace paddle_mobile
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册