1*993b0882SAndroid Build Coastguard Worker /*
2*993b0882SAndroid Build Coastguard Worker * Copyright (C) 2018 The Android Open Source Project
3*993b0882SAndroid Build Coastguard Worker *
4*993b0882SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*993b0882SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*993b0882SAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*993b0882SAndroid Build Coastguard Worker *
8*993b0882SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*993b0882SAndroid Build Coastguard Worker *
10*993b0882SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*993b0882SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*993b0882SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*993b0882SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*993b0882SAndroid Build Coastguard Worker * limitations under the License.
15*993b0882SAndroid Build Coastguard Worker */
16*993b0882SAndroid Build Coastguard Worker
17*993b0882SAndroid Build Coastguard Worker #include "utils/flatbuffers/mutable.h"
18*993b0882SAndroid Build Coastguard Worker
19*993b0882SAndroid Build Coastguard Worker #include <vector>
20*993b0882SAndroid Build Coastguard Worker
21*993b0882SAndroid Build Coastguard Worker #include "utils/flatbuffers/reflection.h"
22*993b0882SAndroid Build Coastguard Worker #include "utils/strings/numbers.h"
23*993b0882SAndroid Build Coastguard Worker #include "utils/variant.h"
24*993b0882SAndroid Build Coastguard Worker #include "flatbuffers/reflection_generated.h"
25*993b0882SAndroid Build Coastguard Worker
26*993b0882SAndroid Build Coastguard Worker namespace libtextclassifier3 {
27*993b0882SAndroid Build Coastguard Worker namespace {
28*993b0882SAndroid Build Coastguard Worker
Parse(const std::string & str_value,float * value)29*993b0882SAndroid Build Coastguard Worker bool Parse(const std::string& str_value, float* value) {
30*993b0882SAndroid Build Coastguard Worker double double_value;
31*993b0882SAndroid Build Coastguard Worker if (!ParseDouble(str_value.data(), &double_value)) {
32*993b0882SAndroid Build Coastguard Worker return false;
33*993b0882SAndroid Build Coastguard Worker }
34*993b0882SAndroid Build Coastguard Worker *value = static_cast<float>(double_value);
35*993b0882SAndroid Build Coastguard Worker return true;
36*993b0882SAndroid Build Coastguard Worker }
37*993b0882SAndroid Build Coastguard Worker
Parse(const std::string & str_value,double * value)38*993b0882SAndroid Build Coastguard Worker bool Parse(const std::string& str_value, double* value) {
39*993b0882SAndroid Build Coastguard Worker return ParseDouble(str_value.data(), value);
40*993b0882SAndroid Build Coastguard Worker }
41*993b0882SAndroid Build Coastguard Worker
Parse(const std::string & str_value,int64 * value)42*993b0882SAndroid Build Coastguard Worker bool Parse(const std::string& str_value, int64* value) {
43*993b0882SAndroid Build Coastguard Worker return ParseInt64(str_value.data(), value);
44*993b0882SAndroid Build Coastguard Worker }
45*993b0882SAndroid Build Coastguard Worker
Parse(const std::string & str_value,int32 * value)46*993b0882SAndroid Build Coastguard Worker bool Parse(const std::string& str_value, int32* value) {
47*993b0882SAndroid Build Coastguard Worker return ParseInt32(str_value.data(), value);
48*993b0882SAndroid Build Coastguard Worker }
49*993b0882SAndroid Build Coastguard Worker
Parse(const std::string & str_value,std::string * value)50*993b0882SAndroid Build Coastguard Worker bool Parse(const std::string& str_value, std::string* value) {
51*993b0882SAndroid Build Coastguard Worker *value = str_value;
52*993b0882SAndroid Build Coastguard Worker return true;
53*993b0882SAndroid Build Coastguard Worker }
54*993b0882SAndroid Build Coastguard Worker
55*993b0882SAndroid Build Coastguard Worker template <typename T>
ParseAndSetField(const reflection::Field * field,const std::string & str_value,MutableFlatbuffer * buffer)56*993b0882SAndroid Build Coastguard Worker bool ParseAndSetField(const reflection::Field* field,
57*993b0882SAndroid Build Coastguard Worker const std::string& str_value, MutableFlatbuffer* buffer) {
58*993b0882SAndroid Build Coastguard Worker T value;
59*993b0882SAndroid Build Coastguard Worker if (!Parse(str_value, &value)) {
60*993b0882SAndroid Build Coastguard Worker TC3_LOG(ERROR) << "Could not parse '" << str_value << "'";
61*993b0882SAndroid Build Coastguard Worker return false;
62*993b0882SAndroid Build Coastguard Worker }
63*993b0882SAndroid Build Coastguard Worker if (field->type()->base_type() == reflection::Vector) {
64*993b0882SAndroid Build Coastguard Worker buffer->Repeated(field)->Add(value);
65*993b0882SAndroid Build Coastguard Worker return true;
66*993b0882SAndroid Build Coastguard Worker } else {
67*993b0882SAndroid Build Coastguard Worker return buffer->Set<T>(field, value);
68*993b0882SAndroid Build Coastguard Worker }
69*993b0882SAndroid Build Coastguard Worker }
70*993b0882SAndroid Build Coastguard Worker
71*993b0882SAndroid Build Coastguard Worker } // namespace
72*993b0882SAndroid Build Coastguard Worker
MutableFlatbufferBuilder(const reflection::Schema * schema,StringPiece root_type)73*993b0882SAndroid Build Coastguard Worker MutableFlatbufferBuilder::MutableFlatbufferBuilder(
74*993b0882SAndroid Build Coastguard Worker const reflection::Schema* schema, StringPiece root_type)
75*993b0882SAndroid Build Coastguard Worker : schema_(schema), root_type_(TypeForName(schema, root_type)) {}
76*993b0882SAndroid Build Coastguard Worker
NewRoot() const77*993b0882SAndroid Build Coastguard Worker std::unique_ptr<MutableFlatbuffer> MutableFlatbufferBuilder::NewRoot() const {
78*993b0882SAndroid Build Coastguard Worker return NewTable(root_type_);
79*993b0882SAndroid Build Coastguard Worker }
80*993b0882SAndroid Build Coastguard Worker
NewTable(StringPiece table_name) const81*993b0882SAndroid Build Coastguard Worker std::unique_ptr<MutableFlatbuffer> MutableFlatbufferBuilder::NewTable(
82*993b0882SAndroid Build Coastguard Worker StringPiece table_name) const {
83*993b0882SAndroid Build Coastguard Worker return NewTable(TypeForName(schema_, table_name));
84*993b0882SAndroid Build Coastguard Worker }
85*993b0882SAndroid Build Coastguard Worker
NewTable(const int type_id) const86*993b0882SAndroid Build Coastguard Worker std::unique_ptr<MutableFlatbuffer> MutableFlatbufferBuilder::NewTable(
87*993b0882SAndroid Build Coastguard Worker const int type_id) const {
88*993b0882SAndroid Build Coastguard Worker if (type_id < 0 || type_id >= schema_->objects()->size()) {
89*993b0882SAndroid Build Coastguard Worker TC3_LOG(ERROR) << "Invalid type id: " << type_id;
90*993b0882SAndroid Build Coastguard Worker return nullptr;
91*993b0882SAndroid Build Coastguard Worker }
92*993b0882SAndroid Build Coastguard Worker return NewTable(schema_->objects()->Get(type_id));
93*993b0882SAndroid Build Coastguard Worker }
94*993b0882SAndroid Build Coastguard Worker
NewTable(const reflection::Object * type) const95*993b0882SAndroid Build Coastguard Worker std::unique_ptr<MutableFlatbuffer> MutableFlatbufferBuilder::NewTable(
96*993b0882SAndroid Build Coastguard Worker const reflection::Object* type) const {
97*993b0882SAndroid Build Coastguard Worker if (type == nullptr) {
98*993b0882SAndroid Build Coastguard Worker return nullptr;
99*993b0882SAndroid Build Coastguard Worker }
100*993b0882SAndroid Build Coastguard Worker return std::make_unique<MutableFlatbuffer>(schema_, type);
101*993b0882SAndroid Build Coastguard Worker }
102*993b0882SAndroid Build Coastguard Worker
GetFieldOrNull(const StringPiece field_name) const103*993b0882SAndroid Build Coastguard Worker const reflection::Field* MutableFlatbuffer::GetFieldOrNull(
104*993b0882SAndroid Build Coastguard Worker const StringPiece field_name) const {
105*993b0882SAndroid Build Coastguard Worker return libtextclassifier3::GetFieldOrNull(type_, field_name);
106*993b0882SAndroid Build Coastguard Worker }
107*993b0882SAndroid Build Coastguard Worker
GetFieldOrNull(const FlatbufferField * field) const108*993b0882SAndroid Build Coastguard Worker const reflection::Field* MutableFlatbuffer::GetFieldOrNull(
109*993b0882SAndroid Build Coastguard Worker const FlatbufferField* field) const {
110*993b0882SAndroid Build Coastguard Worker return libtextclassifier3::GetFieldOrNull(type_, field);
111*993b0882SAndroid Build Coastguard Worker }
112*993b0882SAndroid Build Coastguard Worker
GetFieldWithParent(const FlatbufferFieldPath * field_path,MutableFlatbuffer ** parent,reflection::Field const ** field)113*993b0882SAndroid Build Coastguard Worker bool MutableFlatbuffer::GetFieldWithParent(
114*993b0882SAndroid Build Coastguard Worker const FlatbufferFieldPath* field_path, MutableFlatbuffer** parent,
115*993b0882SAndroid Build Coastguard Worker reflection::Field const** field) {
116*993b0882SAndroid Build Coastguard Worker const auto* path = field_path->field();
117*993b0882SAndroid Build Coastguard Worker if (path == nullptr || path->size() == 0) {
118*993b0882SAndroid Build Coastguard Worker return false;
119*993b0882SAndroid Build Coastguard Worker }
120*993b0882SAndroid Build Coastguard Worker
121*993b0882SAndroid Build Coastguard Worker for (int i = 0; i < path->size(); i++) {
122*993b0882SAndroid Build Coastguard Worker *parent = (i == 0 ? this : (*parent)->Mutable(*field));
123*993b0882SAndroid Build Coastguard Worker if (*parent == nullptr) {
124*993b0882SAndroid Build Coastguard Worker return false;
125*993b0882SAndroid Build Coastguard Worker }
126*993b0882SAndroid Build Coastguard Worker *field = (*parent)->GetFieldOrNull(path->Get(i));
127*993b0882SAndroid Build Coastguard Worker if (*field == nullptr) {
128*993b0882SAndroid Build Coastguard Worker return false;
129*993b0882SAndroid Build Coastguard Worker }
130*993b0882SAndroid Build Coastguard Worker }
131*993b0882SAndroid Build Coastguard Worker
132*993b0882SAndroid Build Coastguard Worker return true;
133*993b0882SAndroid Build Coastguard Worker }
134*993b0882SAndroid Build Coastguard Worker
GetFieldOrNull(const int field_offset) const135*993b0882SAndroid Build Coastguard Worker const reflection::Field* MutableFlatbuffer::GetFieldOrNull(
136*993b0882SAndroid Build Coastguard Worker const int field_offset) const {
137*993b0882SAndroid Build Coastguard Worker return libtextclassifier3::GetFieldOrNull(type_, field_offset);
138*993b0882SAndroid Build Coastguard Worker }
139*993b0882SAndroid Build Coastguard Worker
SetFromEnumValueName(const reflection::Field * field,StringPiece value_name)140*993b0882SAndroid Build Coastguard Worker bool MutableFlatbuffer::SetFromEnumValueName(const reflection::Field* field,
141*993b0882SAndroid Build Coastguard Worker StringPiece value_name) {
142*993b0882SAndroid Build Coastguard Worker if (!IsEnum(field->type())) {
143*993b0882SAndroid Build Coastguard Worker return false;
144*993b0882SAndroid Build Coastguard Worker }
145*993b0882SAndroid Build Coastguard Worker Variant variant_value = ParseEnumValue(schema_, field->type(), value_name);
146*993b0882SAndroid Build Coastguard Worker if (!variant_value.HasValue()) {
147*993b0882SAndroid Build Coastguard Worker return false;
148*993b0882SAndroid Build Coastguard Worker }
149*993b0882SAndroid Build Coastguard Worker fields_[field] = variant_value;
150*993b0882SAndroid Build Coastguard Worker return true;
151*993b0882SAndroid Build Coastguard Worker }
152*993b0882SAndroid Build Coastguard Worker
SetFromEnumValueName(StringPiece field_name,StringPiece value_name)153*993b0882SAndroid Build Coastguard Worker bool MutableFlatbuffer::SetFromEnumValueName(StringPiece field_name,
154*993b0882SAndroid Build Coastguard Worker StringPiece value_name) {
155*993b0882SAndroid Build Coastguard Worker if (const reflection::Field* field = GetFieldOrNull(field_name)) {
156*993b0882SAndroid Build Coastguard Worker return SetFromEnumValueName(field, value_name);
157*993b0882SAndroid Build Coastguard Worker }
158*993b0882SAndroid Build Coastguard Worker return false;
159*993b0882SAndroid Build Coastguard Worker }
160*993b0882SAndroid Build Coastguard Worker
SetFromEnumValueName(const FlatbufferFieldPath * path,StringPiece value_name)161*993b0882SAndroid Build Coastguard Worker bool MutableFlatbuffer::SetFromEnumValueName(const FlatbufferFieldPath* path,
162*993b0882SAndroid Build Coastguard Worker StringPiece value_name) {
163*993b0882SAndroid Build Coastguard Worker MutableFlatbuffer* parent;
164*993b0882SAndroid Build Coastguard Worker const reflection::Field* field;
165*993b0882SAndroid Build Coastguard Worker if (!GetFieldWithParent(path, &parent, &field)) {
166*993b0882SAndroid Build Coastguard Worker return false;
167*993b0882SAndroid Build Coastguard Worker }
168*993b0882SAndroid Build Coastguard Worker return parent->SetFromEnumValueName(field, value_name);
169*993b0882SAndroid Build Coastguard Worker }
170*993b0882SAndroid Build Coastguard Worker
ParseAndSet(const reflection::Field * field,const std::string & value)171*993b0882SAndroid Build Coastguard Worker bool MutableFlatbuffer::ParseAndSet(const reflection::Field* field,
172*993b0882SAndroid Build Coastguard Worker const std::string& value) {
173*993b0882SAndroid Build Coastguard Worker // Try parsing as an enum value.
174*993b0882SAndroid Build Coastguard Worker if (IsEnum(field->type()) && SetFromEnumValueName(field, value)) {
175*993b0882SAndroid Build Coastguard Worker return true;
176*993b0882SAndroid Build Coastguard Worker }
177*993b0882SAndroid Build Coastguard Worker switch (field->type()->base_type() == reflection::Vector
178*993b0882SAndroid Build Coastguard Worker ? field->type()->element()
179*993b0882SAndroid Build Coastguard Worker : field->type()->base_type()) {
180*993b0882SAndroid Build Coastguard Worker case reflection::String:
181*993b0882SAndroid Build Coastguard Worker return ParseAndSetField<std::string>(field, value, this);
182*993b0882SAndroid Build Coastguard Worker case reflection::Int:
183*993b0882SAndroid Build Coastguard Worker return ParseAndSetField<int32>(field, value, this);
184*993b0882SAndroid Build Coastguard Worker case reflection::Long:
185*993b0882SAndroid Build Coastguard Worker return ParseAndSetField<int64>(field, value, this);
186*993b0882SAndroid Build Coastguard Worker case reflection::Float:
187*993b0882SAndroid Build Coastguard Worker return ParseAndSetField<float>(field, value, this);
188*993b0882SAndroid Build Coastguard Worker case reflection::Double:
189*993b0882SAndroid Build Coastguard Worker return ParseAndSetField<double>(field, value, this);
190*993b0882SAndroid Build Coastguard Worker default:
191*993b0882SAndroid Build Coastguard Worker TC3_LOG(ERROR) << "Unhandled field type: " << field->type()->base_type();
192*993b0882SAndroid Build Coastguard Worker return false;
193*993b0882SAndroid Build Coastguard Worker }
194*993b0882SAndroid Build Coastguard Worker }
195*993b0882SAndroid Build Coastguard Worker
ParseAndSet(const FlatbufferFieldPath * path,const std::string & value)196*993b0882SAndroid Build Coastguard Worker bool MutableFlatbuffer::ParseAndSet(const FlatbufferFieldPath* path,
197*993b0882SAndroid Build Coastguard Worker const std::string& value) {
198*993b0882SAndroid Build Coastguard Worker MutableFlatbuffer* parent;
199*993b0882SAndroid Build Coastguard Worker const reflection::Field* field;
200*993b0882SAndroid Build Coastguard Worker if (!GetFieldWithParent(path, &parent, &field)) {
201*993b0882SAndroid Build Coastguard Worker return false;
202*993b0882SAndroid Build Coastguard Worker }
203*993b0882SAndroid Build Coastguard Worker return parent->ParseAndSet(field, value);
204*993b0882SAndroid Build Coastguard Worker }
205*993b0882SAndroid Build Coastguard Worker
Add(StringPiece field_name)206*993b0882SAndroid Build Coastguard Worker MutableFlatbuffer* MutableFlatbuffer::Add(StringPiece field_name) {
207*993b0882SAndroid Build Coastguard Worker const reflection::Field* field = GetFieldOrNull(field_name);
208*993b0882SAndroid Build Coastguard Worker if (field == nullptr) {
209*993b0882SAndroid Build Coastguard Worker return nullptr;
210*993b0882SAndroid Build Coastguard Worker }
211*993b0882SAndroid Build Coastguard Worker
212*993b0882SAndroid Build Coastguard Worker if (field->type()->base_type() != reflection::BaseType::Vector) {
213*993b0882SAndroid Build Coastguard Worker return nullptr;
214*993b0882SAndroid Build Coastguard Worker }
215*993b0882SAndroid Build Coastguard Worker
216*993b0882SAndroid Build Coastguard Worker return Add(field);
217*993b0882SAndroid Build Coastguard Worker }
218*993b0882SAndroid Build Coastguard Worker
Add(const reflection::Field * field)219*993b0882SAndroid Build Coastguard Worker MutableFlatbuffer* MutableFlatbuffer::Add(const reflection::Field* field) {
220*993b0882SAndroid Build Coastguard Worker if (field == nullptr) {
221*993b0882SAndroid Build Coastguard Worker return nullptr;
222*993b0882SAndroid Build Coastguard Worker }
223*993b0882SAndroid Build Coastguard Worker return Repeated(field)->Add();
224*993b0882SAndroid Build Coastguard Worker }
225*993b0882SAndroid Build Coastguard Worker
Mutable(const StringPiece field_name)226*993b0882SAndroid Build Coastguard Worker MutableFlatbuffer* MutableFlatbuffer::Mutable(const StringPiece field_name) {
227*993b0882SAndroid Build Coastguard Worker if (const reflection::Field* field = GetFieldOrNull(field_name)) {
228*993b0882SAndroid Build Coastguard Worker return Mutable(field);
229*993b0882SAndroid Build Coastguard Worker }
230*993b0882SAndroid Build Coastguard Worker TC3_LOG(ERROR) << "Unknown field: " << field_name.ToString();
231*993b0882SAndroid Build Coastguard Worker return nullptr;
232*993b0882SAndroid Build Coastguard Worker }
233*993b0882SAndroid Build Coastguard Worker
Mutable(const reflection::Field * field)234*993b0882SAndroid Build Coastguard Worker MutableFlatbuffer* MutableFlatbuffer::Mutable(const reflection::Field* field) {
235*993b0882SAndroid Build Coastguard Worker if (field->type()->base_type() != reflection::Obj) {
236*993b0882SAndroid Build Coastguard Worker return nullptr;
237*993b0882SAndroid Build Coastguard Worker }
238*993b0882SAndroid Build Coastguard Worker const auto entry = children_.find(field);
239*993b0882SAndroid Build Coastguard Worker if (entry != children_.end()) {
240*993b0882SAndroid Build Coastguard Worker return entry->second.get();
241*993b0882SAndroid Build Coastguard Worker }
242*993b0882SAndroid Build Coastguard Worker const auto it = children_.insert(
243*993b0882SAndroid Build Coastguard Worker /*hint=*/entry,
244*993b0882SAndroid Build Coastguard Worker std::make_pair(
245*993b0882SAndroid Build Coastguard Worker field,
246*993b0882SAndroid Build Coastguard Worker std::unique_ptr<MutableFlatbuffer>(new MutableFlatbuffer(
247*993b0882SAndroid Build Coastguard Worker schema_, schema_->objects()->Get(field->type()->index())))));
248*993b0882SAndroid Build Coastguard Worker return it->second.get();
249*993b0882SAndroid Build Coastguard Worker }
250*993b0882SAndroid Build Coastguard Worker
Mutable(const FlatbufferFieldPath * path)251*993b0882SAndroid Build Coastguard Worker MutableFlatbuffer* MutableFlatbuffer::Mutable(const FlatbufferFieldPath* path) {
252*993b0882SAndroid Build Coastguard Worker const auto* field_path = path->field();
253*993b0882SAndroid Build Coastguard Worker if (field_path == nullptr || field_path->size() == 0) {
254*993b0882SAndroid Build Coastguard Worker return this;
255*993b0882SAndroid Build Coastguard Worker }
256*993b0882SAndroid Build Coastguard Worker MutableFlatbuffer* object = this;
257*993b0882SAndroid Build Coastguard Worker for (int i = 0; i < field_path->size(); i++) {
258*993b0882SAndroid Build Coastguard Worker const reflection::Field* field = object->GetFieldOrNull(field_path->Get(i));
259*993b0882SAndroid Build Coastguard Worker if (field == nullptr) {
260*993b0882SAndroid Build Coastguard Worker return nullptr;
261*993b0882SAndroid Build Coastguard Worker }
262*993b0882SAndroid Build Coastguard Worker object = object->Mutable(field);
263*993b0882SAndroid Build Coastguard Worker if (object == nullptr) {
264*993b0882SAndroid Build Coastguard Worker return nullptr;
265*993b0882SAndroid Build Coastguard Worker }
266*993b0882SAndroid Build Coastguard Worker }
267*993b0882SAndroid Build Coastguard Worker return object;
268*993b0882SAndroid Build Coastguard Worker }
269*993b0882SAndroid Build Coastguard Worker
Repeated(StringPiece field_name)270*993b0882SAndroid Build Coastguard Worker RepeatedField* MutableFlatbuffer::Repeated(StringPiece field_name) {
271*993b0882SAndroid Build Coastguard Worker if (const reflection::Field* field = GetFieldOrNull(field_name)) {
272*993b0882SAndroid Build Coastguard Worker return Repeated(field);
273*993b0882SAndroid Build Coastguard Worker }
274*993b0882SAndroid Build Coastguard Worker TC3_LOG(ERROR) << "Unknown field: " << field_name.ToString();
275*993b0882SAndroid Build Coastguard Worker return nullptr;
276*993b0882SAndroid Build Coastguard Worker }
277*993b0882SAndroid Build Coastguard Worker
Repeated(const reflection::Field * field)278*993b0882SAndroid Build Coastguard Worker RepeatedField* MutableFlatbuffer::Repeated(const reflection::Field* field) {
279*993b0882SAndroid Build Coastguard Worker if (field->type()->base_type() != reflection::Vector) {
280*993b0882SAndroid Build Coastguard Worker TC3_LOG(ERROR) << "Field is not of type Vector.";
281*993b0882SAndroid Build Coastguard Worker return nullptr;
282*993b0882SAndroid Build Coastguard Worker }
283*993b0882SAndroid Build Coastguard Worker
284*993b0882SAndroid Build Coastguard Worker // If the repeated field was already set, return its instance.
285*993b0882SAndroid Build Coastguard Worker const auto entry = repeated_fields_.find(field);
286*993b0882SAndroid Build Coastguard Worker if (entry != repeated_fields_.end()) {
287*993b0882SAndroid Build Coastguard Worker return entry->second.get();
288*993b0882SAndroid Build Coastguard Worker }
289*993b0882SAndroid Build Coastguard Worker
290*993b0882SAndroid Build Coastguard Worker // Otherwise, create a new instance and store it.
291*993b0882SAndroid Build Coastguard Worker std::unique_ptr<RepeatedField> repeated_field(
292*993b0882SAndroid Build Coastguard Worker new RepeatedField(schema_, field));
293*993b0882SAndroid Build Coastguard Worker const auto it = repeated_fields_.insert(
294*993b0882SAndroid Build Coastguard Worker /*hint=*/entry, std::make_pair(field, std::move(repeated_field)));
295*993b0882SAndroid Build Coastguard Worker return it->second.get();
296*993b0882SAndroid Build Coastguard Worker }
297*993b0882SAndroid Build Coastguard Worker
Repeated(const FlatbufferFieldPath * path)298*993b0882SAndroid Build Coastguard Worker RepeatedField* MutableFlatbuffer::Repeated(const FlatbufferFieldPath* path) {
299*993b0882SAndroid Build Coastguard Worker MutableFlatbuffer* parent;
300*993b0882SAndroid Build Coastguard Worker const reflection::Field* field;
301*993b0882SAndroid Build Coastguard Worker if (!GetFieldWithParent(path, &parent, &field)) {
302*993b0882SAndroid Build Coastguard Worker return nullptr;
303*993b0882SAndroid Build Coastguard Worker }
304*993b0882SAndroid Build Coastguard Worker return parent->Repeated(field);
305*993b0882SAndroid Build Coastguard Worker }
306*993b0882SAndroid Build Coastguard Worker
Serialize(flatbuffers::FlatBufferBuilder * builder) const307*993b0882SAndroid Build Coastguard Worker flatbuffers::uoffset_t MutableFlatbuffer::Serialize(
308*993b0882SAndroid Build Coastguard Worker flatbuffers::FlatBufferBuilder* builder) const {
309*993b0882SAndroid Build Coastguard Worker // Build all children before we can start with this table.
310*993b0882SAndroid Build Coastguard Worker std::vector<
311*993b0882SAndroid Build Coastguard Worker std::pair</* field vtable offset */ int,
312*993b0882SAndroid Build Coastguard Worker /* field data offset in buffer */ flatbuffers::uoffset_t>>
313*993b0882SAndroid Build Coastguard Worker offsets;
314*993b0882SAndroid Build Coastguard Worker offsets.reserve(children_.size() + repeated_fields_.size());
315*993b0882SAndroid Build Coastguard Worker for (const auto& it : children_) {
316*993b0882SAndroid Build Coastguard Worker offsets.push_back({it.first->offset(), it.second->Serialize(builder)});
317*993b0882SAndroid Build Coastguard Worker }
318*993b0882SAndroid Build Coastguard Worker
319*993b0882SAndroid Build Coastguard Worker // Create strings.
320*993b0882SAndroid Build Coastguard Worker for (const auto& it : fields_) {
321*993b0882SAndroid Build Coastguard Worker if (it.second.Has<std::string>()) {
322*993b0882SAndroid Build Coastguard Worker offsets.push_back(
323*993b0882SAndroid Build Coastguard Worker {it.first->offset(),
324*993b0882SAndroid Build Coastguard Worker builder->CreateString(it.second.ConstRefValue<std::string>()).o});
325*993b0882SAndroid Build Coastguard Worker }
326*993b0882SAndroid Build Coastguard Worker }
327*993b0882SAndroid Build Coastguard Worker
328*993b0882SAndroid Build Coastguard Worker // Build the repeated fields.
329*993b0882SAndroid Build Coastguard Worker for (const auto& it : repeated_fields_) {
330*993b0882SAndroid Build Coastguard Worker offsets.push_back({it.first->offset(), it.second->Serialize(builder)});
331*993b0882SAndroid Build Coastguard Worker }
332*993b0882SAndroid Build Coastguard Worker
333*993b0882SAndroid Build Coastguard Worker // Build the table now.
334*993b0882SAndroid Build Coastguard Worker const flatbuffers::uoffset_t table_start = builder->StartTable();
335*993b0882SAndroid Build Coastguard Worker
336*993b0882SAndroid Build Coastguard Worker // Add scalar fields.
337*993b0882SAndroid Build Coastguard Worker for (const auto& it : fields_) {
338*993b0882SAndroid Build Coastguard Worker switch (it.second.GetType()) {
339*993b0882SAndroid Build Coastguard Worker case Variant::TYPE_BOOL_VALUE:
340*993b0882SAndroid Build Coastguard Worker builder->AddElement<uint8_t>(
341*993b0882SAndroid Build Coastguard Worker it.first->offset(), static_cast<uint8_t>(it.second.Value<bool>()),
342*993b0882SAndroid Build Coastguard Worker static_cast<uint8_t>(it.first->default_integer()));
343*993b0882SAndroid Build Coastguard Worker continue;
344*993b0882SAndroid Build Coastguard Worker case Variant::TYPE_INT8_VALUE:
345*993b0882SAndroid Build Coastguard Worker builder->AddElement<int8_t>(
346*993b0882SAndroid Build Coastguard Worker it.first->offset(), static_cast<int8_t>(it.second.Value<int8>()),
347*993b0882SAndroid Build Coastguard Worker static_cast<int8_t>(it.first->default_integer()));
348*993b0882SAndroid Build Coastguard Worker continue;
349*993b0882SAndroid Build Coastguard Worker case Variant::TYPE_UINT8_VALUE:
350*993b0882SAndroid Build Coastguard Worker builder->AddElement<uint8_t>(
351*993b0882SAndroid Build Coastguard Worker it.first->offset(), static_cast<uint8_t>(it.second.Value<uint8>()),
352*993b0882SAndroid Build Coastguard Worker static_cast<uint8_t>(it.first->default_integer()));
353*993b0882SAndroid Build Coastguard Worker continue;
354*993b0882SAndroid Build Coastguard Worker case Variant::TYPE_INT_VALUE:
355*993b0882SAndroid Build Coastguard Worker builder->AddElement<int32>(
356*993b0882SAndroid Build Coastguard Worker it.first->offset(), it.second.Value<int>(),
357*993b0882SAndroid Build Coastguard Worker static_cast<int32>(it.first->default_integer()));
358*993b0882SAndroid Build Coastguard Worker continue;
359*993b0882SAndroid Build Coastguard Worker case Variant::TYPE_UINT_VALUE:
360*993b0882SAndroid Build Coastguard Worker builder->AddElement<uint32>(
361*993b0882SAndroid Build Coastguard Worker it.first->offset(), it.second.Value<uint>(),
362*993b0882SAndroid Build Coastguard Worker static_cast<uint32>(it.first->default_integer()));
363*993b0882SAndroid Build Coastguard Worker continue;
364*993b0882SAndroid Build Coastguard Worker case Variant::TYPE_INT64_VALUE:
365*993b0882SAndroid Build Coastguard Worker builder->AddElement<int64>(it.first->offset(), it.second.Value<int64>(),
366*993b0882SAndroid Build Coastguard Worker it.first->default_integer());
367*993b0882SAndroid Build Coastguard Worker continue;
368*993b0882SAndroid Build Coastguard Worker case Variant::TYPE_UINT64_VALUE:
369*993b0882SAndroid Build Coastguard Worker builder->AddElement<uint64>(it.first->offset(),
370*993b0882SAndroid Build Coastguard Worker it.second.Value<uint64>(),
371*993b0882SAndroid Build Coastguard Worker it.first->default_integer());
372*993b0882SAndroid Build Coastguard Worker continue;
373*993b0882SAndroid Build Coastguard Worker case Variant::TYPE_FLOAT_VALUE:
374*993b0882SAndroid Build Coastguard Worker builder->AddElement<float>(
375*993b0882SAndroid Build Coastguard Worker it.first->offset(), it.second.Value<float>(),
376*993b0882SAndroid Build Coastguard Worker static_cast<float>(it.first->default_real()));
377*993b0882SAndroid Build Coastguard Worker continue;
378*993b0882SAndroid Build Coastguard Worker case Variant::TYPE_DOUBLE_VALUE:
379*993b0882SAndroid Build Coastguard Worker builder->AddElement<double>(it.first->offset(),
380*993b0882SAndroid Build Coastguard Worker it.second.Value<double>(),
381*993b0882SAndroid Build Coastguard Worker it.first->default_real());
382*993b0882SAndroid Build Coastguard Worker continue;
383*993b0882SAndroid Build Coastguard Worker default:
384*993b0882SAndroid Build Coastguard Worker continue;
385*993b0882SAndroid Build Coastguard Worker }
386*993b0882SAndroid Build Coastguard Worker }
387*993b0882SAndroid Build Coastguard Worker
388*993b0882SAndroid Build Coastguard Worker // Add strings, subtables and repeated fields.
389*993b0882SAndroid Build Coastguard Worker for (const auto& it : offsets) {
390*993b0882SAndroid Build Coastguard Worker builder->AddOffset(it.first, flatbuffers::Offset<void>(it.second));
391*993b0882SAndroid Build Coastguard Worker }
392*993b0882SAndroid Build Coastguard Worker
393*993b0882SAndroid Build Coastguard Worker return builder->EndTable(table_start);
394*993b0882SAndroid Build Coastguard Worker }
395*993b0882SAndroid Build Coastguard Worker
Serialize() const396*993b0882SAndroid Build Coastguard Worker std::string MutableFlatbuffer::Serialize() const {
397*993b0882SAndroid Build Coastguard Worker flatbuffers::FlatBufferBuilder builder;
398*993b0882SAndroid Build Coastguard Worker builder.Finish(flatbuffers::Offset<void>(Serialize(&builder)));
399*993b0882SAndroid Build Coastguard Worker return std::string(reinterpret_cast<const char*>(builder.GetBufferPointer()),
400*993b0882SAndroid Build Coastguard Worker builder.GetSize());
401*993b0882SAndroid Build Coastguard Worker }
402*993b0882SAndroid Build Coastguard Worker
MergeFrom(const flatbuffers::Table * from)403*993b0882SAndroid Build Coastguard Worker bool MutableFlatbuffer::MergeFrom(const flatbuffers::Table* from) {
404*993b0882SAndroid Build Coastguard Worker // No fields to set.
405*993b0882SAndroid Build Coastguard Worker if (type_->fields() == nullptr) {
406*993b0882SAndroid Build Coastguard Worker return true;
407*993b0882SAndroid Build Coastguard Worker }
408*993b0882SAndroid Build Coastguard Worker
409*993b0882SAndroid Build Coastguard Worker for (const reflection::Field* field : *type_->fields()) {
410*993b0882SAndroid Build Coastguard Worker // Skip fields that are not explicitly set.
411*993b0882SAndroid Build Coastguard Worker if (!from->CheckField(field->offset())) {
412*993b0882SAndroid Build Coastguard Worker continue;
413*993b0882SAndroid Build Coastguard Worker }
414*993b0882SAndroid Build Coastguard Worker const reflection::BaseType type = field->type()->base_type();
415*993b0882SAndroid Build Coastguard Worker switch (type) {
416*993b0882SAndroid Build Coastguard Worker case reflection::Bool:
417*993b0882SAndroid Build Coastguard Worker Set<bool>(field, from->GetField<uint8_t>(field->offset(),
418*993b0882SAndroid Build Coastguard Worker field->default_integer()));
419*993b0882SAndroid Build Coastguard Worker break;
420*993b0882SAndroid Build Coastguard Worker case reflection::Byte:
421*993b0882SAndroid Build Coastguard Worker Set<int8_t>(field, from->GetField<int8_t>(field->offset(),
422*993b0882SAndroid Build Coastguard Worker field->default_integer()));
423*993b0882SAndroid Build Coastguard Worker break;
424*993b0882SAndroid Build Coastguard Worker case reflection::UByte:
425*993b0882SAndroid Build Coastguard Worker Set<uint8_t>(field, from->GetField<uint8_t>(field->offset(),
426*993b0882SAndroid Build Coastguard Worker field->default_integer()));
427*993b0882SAndroid Build Coastguard Worker break;
428*993b0882SAndroid Build Coastguard Worker case reflection::Int:
429*993b0882SAndroid Build Coastguard Worker Set<int32>(field, from->GetField<int32>(field->offset(),
430*993b0882SAndroid Build Coastguard Worker field->default_integer()));
431*993b0882SAndroid Build Coastguard Worker break;
432*993b0882SAndroid Build Coastguard Worker case reflection::UInt:
433*993b0882SAndroid Build Coastguard Worker Set<uint32>(field, from->GetField<uint32>(field->offset(),
434*993b0882SAndroid Build Coastguard Worker field->default_integer()));
435*993b0882SAndroid Build Coastguard Worker break;
436*993b0882SAndroid Build Coastguard Worker case reflection::Long:
437*993b0882SAndroid Build Coastguard Worker Set<int64>(field, from->GetField<int64>(field->offset(),
438*993b0882SAndroid Build Coastguard Worker field->default_integer()));
439*993b0882SAndroid Build Coastguard Worker break;
440*993b0882SAndroid Build Coastguard Worker case reflection::ULong:
441*993b0882SAndroid Build Coastguard Worker Set<uint64>(field, from->GetField<uint64>(field->offset(),
442*993b0882SAndroid Build Coastguard Worker field->default_integer()));
443*993b0882SAndroid Build Coastguard Worker break;
444*993b0882SAndroid Build Coastguard Worker case reflection::Float:
445*993b0882SAndroid Build Coastguard Worker Set<float>(field, from->GetField<float>(field->offset(),
446*993b0882SAndroid Build Coastguard Worker field->default_real()));
447*993b0882SAndroid Build Coastguard Worker break;
448*993b0882SAndroid Build Coastguard Worker case reflection::Double:
449*993b0882SAndroid Build Coastguard Worker Set<double>(field, from->GetField<double>(field->offset(),
450*993b0882SAndroid Build Coastguard Worker field->default_real()));
451*993b0882SAndroid Build Coastguard Worker break;
452*993b0882SAndroid Build Coastguard Worker case reflection::String:
453*993b0882SAndroid Build Coastguard Worker Set<std::string>(
454*993b0882SAndroid Build Coastguard Worker field, from->GetPointer<const flatbuffers::String*>(field->offset())
455*993b0882SAndroid Build Coastguard Worker ->str());
456*993b0882SAndroid Build Coastguard Worker break;
457*993b0882SAndroid Build Coastguard Worker case reflection::Obj:
458*993b0882SAndroid Build Coastguard Worker if (MutableFlatbuffer* nested_field = Mutable(field);
459*993b0882SAndroid Build Coastguard Worker nested_field == nullptr ||
460*993b0882SAndroid Build Coastguard Worker !nested_field->MergeFrom(
461*993b0882SAndroid Build Coastguard Worker from->GetPointer<const flatbuffers::Table* const>(
462*993b0882SAndroid Build Coastguard Worker field->offset()))) {
463*993b0882SAndroid Build Coastguard Worker return false;
464*993b0882SAndroid Build Coastguard Worker }
465*993b0882SAndroid Build Coastguard Worker break;
466*993b0882SAndroid Build Coastguard Worker case reflection::Vector: {
467*993b0882SAndroid Build Coastguard Worker if (RepeatedField* repeated_field = Repeated(field);
468*993b0882SAndroid Build Coastguard Worker repeated_field == nullptr || !repeated_field->Extend(from)) {
469*993b0882SAndroid Build Coastguard Worker return false;
470*993b0882SAndroid Build Coastguard Worker }
471*993b0882SAndroid Build Coastguard Worker break;
472*993b0882SAndroid Build Coastguard Worker }
473*993b0882SAndroid Build Coastguard Worker default:
474*993b0882SAndroid Build Coastguard Worker TC3_LOG(ERROR) << "Unsupported type: " << type
475*993b0882SAndroid Build Coastguard Worker << " for field: " << field->name()->str();
476*993b0882SAndroid Build Coastguard Worker return false;
477*993b0882SAndroid Build Coastguard Worker }
478*993b0882SAndroid Build Coastguard Worker }
479*993b0882SAndroid Build Coastguard Worker return true;
480*993b0882SAndroid Build Coastguard Worker }
481*993b0882SAndroid Build Coastguard Worker
MergeFromSerializedFlatbuffer(StringPiece from)482*993b0882SAndroid Build Coastguard Worker bool MutableFlatbuffer::MergeFromSerializedFlatbuffer(StringPiece from) {
483*993b0882SAndroid Build Coastguard Worker return MergeFrom(flatbuffers::GetAnyRoot(
484*993b0882SAndroid Build Coastguard Worker reinterpret_cast<const unsigned char*>(from.data())));
485*993b0882SAndroid Build Coastguard Worker }
486*993b0882SAndroid Build Coastguard Worker
AsFlatMap(const std::string & key_separator,const std::string & key_prefix,std::map<std::string,Variant> * result) const487*993b0882SAndroid Build Coastguard Worker void MutableFlatbuffer::AsFlatMap(
488*993b0882SAndroid Build Coastguard Worker const std::string& key_separator, const std::string& key_prefix,
489*993b0882SAndroid Build Coastguard Worker std::map<std::string, Variant>* result) const {
490*993b0882SAndroid Build Coastguard Worker // Add direct fields.
491*993b0882SAndroid Build Coastguard Worker for (const auto& it : fields_) {
492*993b0882SAndroid Build Coastguard Worker (*result)[key_prefix + it.first->name()->str()] = it.second;
493*993b0882SAndroid Build Coastguard Worker }
494*993b0882SAndroid Build Coastguard Worker
495*993b0882SAndroid Build Coastguard Worker // Add nested messages.
496*993b0882SAndroid Build Coastguard Worker for (const auto& it : children_) {
497*993b0882SAndroid Build Coastguard Worker it.second->AsFlatMap(key_separator,
498*993b0882SAndroid Build Coastguard Worker key_prefix + it.first->name()->str() + key_separator,
499*993b0882SAndroid Build Coastguard Worker result);
500*993b0882SAndroid Build Coastguard Worker }
501*993b0882SAndroid Build Coastguard Worker }
502*993b0882SAndroid Build Coastguard Worker
ToTextProto() const503*993b0882SAndroid Build Coastguard Worker std::string RepeatedField::ToTextProto() const {
504*993b0882SAndroid Build Coastguard Worker std::string result = " [";
505*993b0882SAndroid Build Coastguard Worker std::string current_field_separator;
506*993b0882SAndroid Build Coastguard Worker for (int index = 0; index < Size(); index++) {
507*993b0882SAndroid Build Coastguard Worker if (is_primitive_) {
508*993b0882SAndroid Build Coastguard Worker result.append(current_field_separator + items_.at(index).ToString());
509*993b0882SAndroid Build Coastguard Worker } else {
510*993b0882SAndroid Build Coastguard Worker result.append(current_field_separator + "{" +
511*993b0882SAndroid Build Coastguard Worker Get<MutableFlatbuffer*>(index)->ToTextProto() + "}");
512*993b0882SAndroid Build Coastguard Worker }
513*993b0882SAndroid Build Coastguard Worker current_field_separator = ", ";
514*993b0882SAndroid Build Coastguard Worker }
515*993b0882SAndroid Build Coastguard Worker result.append("] ");
516*993b0882SAndroid Build Coastguard Worker return result;
517*993b0882SAndroid Build Coastguard Worker }
518*993b0882SAndroid Build Coastguard Worker
ToTextProto() const519*993b0882SAndroid Build Coastguard Worker std::string MutableFlatbuffer::ToTextProto() const {
520*993b0882SAndroid Build Coastguard Worker std::string result;
521*993b0882SAndroid Build Coastguard Worker std::string current_field_separator;
522*993b0882SAndroid Build Coastguard Worker // Add direct fields.
523*993b0882SAndroid Build Coastguard Worker for (const auto& field_value_pair : fields_) {
524*993b0882SAndroid Build Coastguard Worker const std::string field_name = field_value_pair.first->name()->str();
525*993b0882SAndroid Build Coastguard Worker const Variant& value = field_value_pair.second;
526*993b0882SAndroid Build Coastguard Worker std::string quotes;
527*993b0882SAndroid Build Coastguard Worker if (value.GetType() == Variant::TYPE_STRING_VALUE) {
528*993b0882SAndroid Build Coastguard Worker quotes = "'";
529*993b0882SAndroid Build Coastguard Worker }
530*993b0882SAndroid Build Coastguard Worker result.append(current_field_separator + field_name + ": " + quotes +
531*993b0882SAndroid Build Coastguard Worker value.ToString() + quotes);
532*993b0882SAndroid Build Coastguard Worker current_field_separator = ", ";
533*993b0882SAndroid Build Coastguard Worker }
534*993b0882SAndroid Build Coastguard Worker
535*993b0882SAndroid Build Coastguard Worker // Add repeated message
536*993b0882SAndroid Build Coastguard Worker for (const auto& repeated_fb_pair : repeated_fields_) {
537*993b0882SAndroid Build Coastguard Worker result.append(current_field_separator +
538*993b0882SAndroid Build Coastguard Worker repeated_fb_pair.first->name()->c_str() + ": " +
539*993b0882SAndroid Build Coastguard Worker repeated_fb_pair.second->ToTextProto());
540*993b0882SAndroid Build Coastguard Worker current_field_separator = ", ";
541*993b0882SAndroid Build Coastguard Worker }
542*993b0882SAndroid Build Coastguard Worker
543*993b0882SAndroid Build Coastguard Worker // Add nested messages.
544*993b0882SAndroid Build Coastguard Worker for (const auto& field_flatbuffer_pair : children_) {
545*993b0882SAndroid Build Coastguard Worker const std::string field_name = field_flatbuffer_pair.first->name()->str();
546*993b0882SAndroid Build Coastguard Worker result.append(current_field_separator + field_name + " {" +
547*993b0882SAndroid Build Coastguard Worker field_flatbuffer_pair.second->ToTextProto() + "}");
548*993b0882SAndroid Build Coastguard Worker current_field_separator = ", ";
549*993b0882SAndroid Build Coastguard Worker }
550*993b0882SAndroid Build Coastguard Worker
551*993b0882SAndroid Build Coastguard Worker return result;
552*993b0882SAndroid Build Coastguard Worker }
553*993b0882SAndroid Build Coastguard Worker
554*993b0882SAndroid Build Coastguard Worker //
555*993b0882SAndroid Build Coastguard Worker // Repeated field methods.
556*993b0882SAndroid Build Coastguard Worker //
557*993b0882SAndroid Build Coastguard Worker
Add()558*993b0882SAndroid Build Coastguard Worker MutableFlatbuffer* RepeatedField::Add() {
559*993b0882SAndroid Build Coastguard Worker if (is_primitive_) {
560*993b0882SAndroid Build Coastguard Worker TC3_LOG(ERROR) << "Trying to add sub-message on a primitive-typed field.";
561*993b0882SAndroid Build Coastguard Worker return nullptr;
562*993b0882SAndroid Build Coastguard Worker }
563*993b0882SAndroid Build Coastguard Worker
564*993b0882SAndroid Build Coastguard Worker object_items_.emplace_back(new MutableFlatbuffer(
565*993b0882SAndroid Build Coastguard Worker schema_, schema_->objects()->Get(field_->type()->index())));
566*993b0882SAndroid Build Coastguard Worker return object_items_.back().get();
567*993b0882SAndroid Build Coastguard Worker }
568*993b0882SAndroid Build Coastguard Worker
569*993b0882SAndroid Build Coastguard Worker namespace {
570*993b0882SAndroid Build Coastguard Worker
571*993b0882SAndroid Build Coastguard Worker template <typename T>
TypedSerialize(const std::vector<Variant> & values,flatbuffers::FlatBufferBuilder * builder)572*993b0882SAndroid Build Coastguard Worker flatbuffers::uoffset_t TypedSerialize(const std::vector<Variant>& values,
573*993b0882SAndroid Build Coastguard Worker flatbuffers::FlatBufferBuilder* builder) {
574*993b0882SAndroid Build Coastguard Worker std::vector<T> typed_values;
575*993b0882SAndroid Build Coastguard Worker typed_values.reserve(values.size());
576*993b0882SAndroid Build Coastguard Worker for (const Variant& item : values) {
577*993b0882SAndroid Build Coastguard Worker typed_values.push_back(item.Value<T>());
578*993b0882SAndroid Build Coastguard Worker }
579*993b0882SAndroid Build Coastguard Worker return builder->CreateVector(typed_values).o;
580*993b0882SAndroid Build Coastguard Worker }
581*993b0882SAndroid Build Coastguard Worker
582*993b0882SAndroid Build Coastguard Worker } // namespace
583*993b0882SAndroid Build Coastguard Worker
Extend(const flatbuffers::Table * from)584*993b0882SAndroid Build Coastguard Worker bool RepeatedField::Extend(const flatbuffers::Table* from) {
585*993b0882SAndroid Build Coastguard Worker switch (field_->type()->element()) {
586*993b0882SAndroid Build Coastguard Worker case reflection::Int:
587*993b0882SAndroid Build Coastguard Worker AppendFromVector<int32>(from);
588*993b0882SAndroid Build Coastguard Worker return true;
589*993b0882SAndroid Build Coastguard Worker case reflection::UInt:
590*993b0882SAndroid Build Coastguard Worker AppendFromVector<uint>(from);
591*993b0882SAndroid Build Coastguard Worker return true;
592*993b0882SAndroid Build Coastguard Worker case reflection::Long:
593*993b0882SAndroid Build Coastguard Worker AppendFromVector<int64>(from);
594*993b0882SAndroid Build Coastguard Worker return true;
595*993b0882SAndroid Build Coastguard Worker case reflection::ULong:
596*993b0882SAndroid Build Coastguard Worker AppendFromVector<uint64>(from);
597*993b0882SAndroid Build Coastguard Worker return true;
598*993b0882SAndroid Build Coastguard Worker case reflection::Byte:
599*993b0882SAndroid Build Coastguard Worker AppendFromVector<int8_t>(from);
600*993b0882SAndroid Build Coastguard Worker return true;
601*993b0882SAndroid Build Coastguard Worker case reflection::UByte:
602*993b0882SAndroid Build Coastguard Worker AppendFromVector<uint8_t>(from);
603*993b0882SAndroid Build Coastguard Worker return true;
604*993b0882SAndroid Build Coastguard Worker case reflection::String:
605*993b0882SAndroid Build Coastguard Worker AppendFromVector<std::string>(from);
606*993b0882SAndroid Build Coastguard Worker return true;
607*993b0882SAndroid Build Coastguard Worker case reflection::Obj:
608*993b0882SAndroid Build Coastguard Worker AppendFromVector<MutableFlatbuffer>(from);
609*993b0882SAndroid Build Coastguard Worker return true;
610*993b0882SAndroid Build Coastguard Worker case reflection::Double:
611*993b0882SAndroid Build Coastguard Worker AppendFromVector<double>(from);
612*993b0882SAndroid Build Coastguard Worker return true;
613*993b0882SAndroid Build Coastguard Worker case reflection::Float:
614*993b0882SAndroid Build Coastguard Worker AppendFromVector<float>(from);
615*993b0882SAndroid Build Coastguard Worker return true;
616*993b0882SAndroid Build Coastguard Worker default:
617*993b0882SAndroid Build Coastguard Worker TC3_LOG(ERROR) << "Repeated unsupported type: "
618*993b0882SAndroid Build Coastguard Worker << field_->type()->element()
619*993b0882SAndroid Build Coastguard Worker << " for field: " << field_->name()->str();
620*993b0882SAndroid Build Coastguard Worker return false;
621*993b0882SAndroid Build Coastguard Worker }
622*993b0882SAndroid Build Coastguard Worker }
623*993b0882SAndroid Build Coastguard Worker
Serialize(flatbuffers::FlatBufferBuilder * builder) const624*993b0882SAndroid Build Coastguard Worker flatbuffers::uoffset_t RepeatedField::Serialize(
625*993b0882SAndroid Build Coastguard Worker flatbuffers::FlatBufferBuilder* builder) const {
626*993b0882SAndroid Build Coastguard Worker switch (field_->type()->element()) {
627*993b0882SAndroid Build Coastguard Worker case reflection::String:
628*993b0882SAndroid Build Coastguard Worker return SerializeString(builder);
629*993b0882SAndroid Build Coastguard Worker break;
630*993b0882SAndroid Build Coastguard Worker case reflection::Obj:
631*993b0882SAndroid Build Coastguard Worker return SerializeObject(builder);
632*993b0882SAndroid Build Coastguard Worker break;
633*993b0882SAndroid Build Coastguard Worker case reflection::Bool:
634*993b0882SAndroid Build Coastguard Worker return TypedSerialize<bool>(items_, builder);
635*993b0882SAndroid Build Coastguard Worker break;
636*993b0882SAndroid Build Coastguard Worker case reflection::Byte:
637*993b0882SAndroid Build Coastguard Worker return TypedSerialize<int8_t>(items_, builder);
638*993b0882SAndroid Build Coastguard Worker break;
639*993b0882SAndroid Build Coastguard Worker case reflection::UByte:
640*993b0882SAndroid Build Coastguard Worker return TypedSerialize<uint8_t>(items_, builder);
641*993b0882SAndroid Build Coastguard Worker break;
642*993b0882SAndroid Build Coastguard Worker case reflection::Int:
643*993b0882SAndroid Build Coastguard Worker return TypedSerialize<int>(items_, builder);
644*993b0882SAndroid Build Coastguard Worker break;
645*993b0882SAndroid Build Coastguard Worker case reflection::UInt:
646*993b0882SAndroid Build Coastguard Worker return TypedSerialize<uint>(items_, builder);
647*993b0882SAndroid Build Coastguard Worker break;
648*993b0882SAndroid Build Coastguard Worker case reflection::Long:
649*993b0882SAndroid Build Coastguard Worker return TypedSerialize<int64>(items_, builder);
650*993b0882SAndroid Build Coastguard Worker break;
651*993b0882SAndroid Build Coastguard Worker case reflection::ULong:
652*993b0882SAndroid Build Coastguard Worker return TypedSerialize<uint64>(items_, builder);
653*993b0882SAndroid Build Coastguard Worker break;
654*993b0882SAndroid Build Coastguard Worker case reflection::Float:
655*993b0882SAndroid Build Coastguard Worker return TypedSerialize<float>(items_, builder);
656*993b0882SAndroid Build Coastguard Worker break;
657*993b0882SAndroid Build Coastguard Worker case reflection::Double:
658*993b0882SAndroid Build Coastguard Worker return TypedSerialize<double>(items_, builder);
659*993b0882SAndroid Build Coastguard Worker break;
660*993b0882SAndroid Build Coastguard Worker default:
661*993b0882SAndroid Build Coastguard Worker TC3_LOG(FATAL) << "Unsupported type: " << field_->type()->element();
662*993b0882SAndroid Build Coastguard Worker break;
663*993b0882SAndroid Build Coastguard Worker }
664*993b0882SAndroid Build Coastguard Worker TC3_LOG(FATAL) << "Invalid state.";
665*993b0882SAndroid Build Coastguard Worker return 0;
666*993b0882SAndroid Build Coastguard Worker }
667*993b0882SAndroid Build Coastguard Worker
SerializeString(flatbuffers::FlatBufferBuilder * builder) const668*993b0882SAndroid Build Coastguard Worker flatbuffers::uoffset_t RepeatedField::SerializeString(
669*993b0882SAndroid Build Coastguard Worker flatbuffers::FlatBufferBuilder* builder) const {
670*993b0882SAndroid Build Coastguard Worker std::vector<flatbuffers::Offset<flatbuffers::String>> offsets(items_.size());
671*993b0882SAndroid Build Coastguard Worker for (int i = 0; i < items_.size(); i++) {
672*993b0882SAndroid Build Coastguard Worker offsets[i] = builder->CreateString(items_[i].ConstRefValue<std::string>());
673*993b0882SAndroid Build Coastguard Worker }
674*993b0882SAndroid Build Coastguard Worker return builder->CreateVector(offsets).o;
675*993b0882SAndroid Build Coastguard Worker }
676*993b0882SAndroid Build Coastguard Worker
SerializeObject(flatbuffers::FlatBufferBuilder * builder) const677*993b0882SAndroid Build Coastguard Worker flatbuffers::uoffset_t RepeatedField::SerializeObject(
678*993b0882SAndroid Build Coastguard Worker flatbuffers::FlatBufferBuilder* builder) const {
679*993b0882SAndroid Build Coastguard Worker std::vector<flatbuffers::Offset<void>> offsets(object_items_.size());
680*993b0882SAndroid Build Coastguard Worker for (int i = 0; i < object_items_.size(); i++) {
681*993b0882SAndroid Build Coastguard Worker offsets[i] = object_items_[i]->Serialize(builder);
682*993b0882SAndroid Build Coastguard Worker }
683*993b0882SAndroid Build Coastguard Worker return builder->CreateVector(offsets).o;
684*993b0882SAndroid Build Coastguard Worker }
685*993b0882SAndroid Build Coastguard Worker
686*993b0882SAndroid Build Coastguard Worker } // namespace libtextclassifier3
687