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