summaryrefslogtreecommitdiff
path: root/internal/dynamic_depth/item.cc
blob: a1c2a8f640e9616319bbe0f3d34c981b77be264e (plain)
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
137
138
139
#include "dynamic_depth/item.h"

#include "android-base/logging.h"
#include "dynamic_depth/const.h"

using photos_editing_formats::xml::Deserializer;
using photos_editing_formats::xml::Serializer;

namespace photos_editing_formats {
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 xml::Deserializer& parent_deserializer) {
  std::unique_ptr<Deserializer> deserializer =
      parent_deserializer.CreateDeserializer(
          DynamicDepthConst::Namespace(DynamicDepthConst::Item()),
          DynamicDepthConst::Item());
  if (deserializer == nullptr) {
    LOG(ERROR) << "Deserializer must not be null";
    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(xml::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
}  // namespace photos_editing_formats