huangcm
2024-12-18 9d29be7f7249789d6ffd0440067187a9f040c2cd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#include "dynamic_depth/item.h"
 
#include "android-base/logging.h"
#include "dynamic_depth/const.h"
 
using ::dynamic_depth::xmpmeta::xml::Deserializer;
using ::dynamic_depth::xmpmeta::xml::Serializer;
 
namespace dynamic_depth {
namespace {
 
constexpr char kNamespaceHref[] = "http://ns.google.com/photos/dd/1.0/item/";
 
constexpr char kMime[] = "Mime";
constexpr char kLength[] = "Length";
constexpr char kPadding[] = "Padding";
constexpr char kDataUri[] = "DataURI";
 
}  // namespace
 
// Private constructor.
Item::Item(const ItemParams& params) : params_(params) {}
 
// Private instantiator.
 
std::unique_ptr<Item> Item::FromDataInternal(const ItemParams& params,
                                             bool check_filepath) {
  if (check_filepath && params.length != params.payload_to_serialize.size()) {
    LOG(ERROR) << "Length does not match payload's size";
    return nullptr;
  }
 
  if (params.mime.empty()) {
    LOG(ERROR) << "Mime is empty";
    return nullptr;
  }
 
  if (params.length < 0) {
    LOG(ERROR) << "Item length must be non-negative";
    return nullptr;
  }
 
  if (params.padding > 0 &&
      static_cast<int>(params.length - params.padding) <= 0) {
    LOG(ERROR) << "Item length must be larger than padding; found padding="
               << params.padding << ", length=" << params.length;
    return nullptr;
  }
 
  // TODO(miraleung): Check for only supported mime types?
 
  return std::unique_ptr<Item>(new Item(params));  // NOLINT
}
 
void Item::GetNamespaces(std::unordered_map<string, string>* ns_name_href_map) {
  if (ns_name_href_map == nullptr) {
    LOG(ERROR) << "Namespace list or own namespace is null";
    return;
  }
 
  ns_name_href_map->emplace(DynamicDepthConst::Item(), kNamespaceHref);
}
 
std::unique_ptr<Item> Item::FromData(const ItemParams& params) {
  return FromDataInternal(params, true);
}
 
std::unique_ptr<Item> Item::FromDeserializer(
    const Deserializer& parent_deserializer) {
  std::unique_ptr<Deserializer> deserializer =
      parent_deserializer.CreateDeserializer(
          DynamicDepthConst::Namespace(DynamicDepthConst::Item()),
          DynamicDepthConst::Item());
  if (deserializer == nullptr) {
    return nullptr;
  }
 
  string mime;
  int length;
  int padding = 0;
  string data_uri;
 
  if (!deserializer->ParseString(DynamicDepthConst::Item(), kMime, &mime) ||
      !deserializer->ParseInt(DynamicDepthConst::Item(), kLength, &length)) {
    return nullptr;
  }
 
  deserializer->ParseInt(DynamicDepthConst::Item(), kPadding, &padding);
  deserializer->ParseString(DynamicDepthConst::Item(), kDataUri, &data_uri);
 
  ItemParams params(mime, length);
  if (!data_uri.empty()) {
    params.data_uri = data_uri;
  }
  if (padding > 0) {
    params.padding = padding;
  }
 
  return Item::FromDataInternal(params, false);
}
 
// Getters.
const string& Item::GetMime() const { return params_.mime; }
unsigned int Item::GetLength() const { return params_.length; }
const string& Item::GetDataUri() const { return params_.data_uri; }
unsigned int Item::GetPadding() const { return params_.padding; }
const string& Item::GetPayloadToSerialize() const {
  return params_.payload_to_serialize;
}
 
bool Item::Serialize(Serializer* serializer) const {
  if (serializer == nullptr) {
    LOG(ERROR) << "Serializer is null";
    return false;
  }
 
  // No error-checking for the mime or length here, since it's assumed to be
  // taken care of in the instantiator.
  bool success = serializer->WriteProperty(DynamicDepthConst::Item(), kMime,
                                           params_.mime) &&
                 serializer->WriteProperty(DynamicDepthConst::Item(), kLength,
                                           std::to_string(params_.length));
  if (!params_.data_uri.empty()) {
    success &= serializer->WriteProperty(DynamicDepthConst::Item(), kDataUri,
                                         params_.data_uri);
  }
 
  if (params_.padding > 0) {
    success &= serializer->WriteProperty(DynamicDepthConst::Item(), kPadding,
                                         std::to_string(params_.padding));
  }
 
  return success;
}
 
}  // namespace dynamic_depth