1 // Copyright 2017 The Draco Authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 //
15 #include "draco/metadata/metadata_decoder.h"
16
17 #include <string>
18
19 #include "draco/core/varint_decoding.h"
20
21 namespace draco {
22
MetadataDecoder()23 MetadataDecoder::MetadataDecoder() : buffer_(nullptr) {}
24
DecodeMetadata(DecoderBuffer * in_buffer,Metadata * metadata)25 bool MetadataDecoder::DecodeMetadata(DecoderBuffer *in_buffer,
26 Metadata *metadata) {
27 if (!metadata)
28 return false;
29 buffer_ = in_buffer;
30 return DecodeMetadata(metadata);
31 }
32
DecodeGeometryMetadata(DecoderBuffer * in_buffer,GeometryMetadata * metadata)33 bool MetadataDecoder::DecodeGeometryMetadata(DecoderBuffer *in_buffer,
34 GeometryMetadata *metadata) {
35 if (!metadata)
36 return false;
37 buffer_ = in_buffer;
38 uint32_t num_att_metadata = 0;
39 DecodeVarint(&num_att_metadata, buffer_);
40 // Decode attribute metadata.
41 for (uint32_t i = 0; i < num_att_metadata; ++i) {
42 uint32_t att_unique_id;
43 DecodeVarint(&att_unique_id, buffer_);
44 std::unique_ptr<AttributeMetadata> att_metadata =
45 std::unique_ptr<AttributeMetadata>(new AttributeMetadata());
46 att_metadata->set_att_unique_id(att_unique_id);
47 if (!DecodeMetadata(static_cast<Metadata *>(att_metadata.get())))
48 return false;
49 metadata->AddAttributeMetadata(std::move(att_metadata));
50 }
51 return DecodeMetadata(static_cast<Metadata *>(metadata));
52 }
53
DecodeMetadata(Metadata * metadata)54 bool MetadataDecoder::DecodeMetadata(Metadata *metadata) {
55 uint32_t num_entries = 0;
56 DecodeVarint(&num_entries, buffer_);
57 for (uint32_t i = 0; i < num_entries; ++i) {
58 if (!DecodeEntry(metadata))
59 return false;
60 }
61 uint32_t num_sub_metadata = 0;
62 DecodeVarint(&num_sub_metadata, buffer_);
63 for (uint32_t i = 0; i < num_sub_metadata; ++i) {
64 std::string sub_metadata_name;
65 if (!DecodeName(&sub_metadata_name))
66 return false;
67 std::unique_ptr<Metadata> sub_metadata =
68 std::unique_ptr<Metadata>(new Metadata());
69 if (!DecodeMetadata(sub_metadata.get()))
70 return false;
71 metadata->AddSubMetadata(sub_metadata_name, std::move(sub_metadata));
72 }
73 return true;
74 }
75
DecodeEntry(Metadata * metadata)76 bool MetadataDecoder::DecodeEntry(Metadata *metadata) {
77 std::string entry_name;
78 if (!DecodeName(&entry_name))
79 return false;
80 uint32_t data_size = 0;
81 if (!DecodeVarint(&data_size, buffer_))
82 return false;
83 if (data_size == 0)
84 return false;
85 std::vector<uint8_t> entry_value(data_size);
86 if (!buffer_->Decode(&entry_value[0], data_size))
87 return false;
88 metadata->AddEntryBinary(entry_name, entry_value);
89 return true;
90 }
91
DecodeName(std::string * name)92 bool MetadataDecoder::DecodeName(std::string *name) {
93 uint8_t name_len = 0;
94 if (!buffer_->Decode(&name_len))
95 return false;
96 name->resize(name_len);
97 if (name_len == 0)
98 return true;
99 if (!buffer_->Decode(&name->at(0), name_len))
100 return false;
101 return true;
102 }
103 } // namespace draco
104