1/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "proto/ProtoHelpers.h"
18
19namespace aapt {
20
21void serializeStringPoolToPb(const StringPool& pool, pb::StringPool* outPbPool) {
22    BigBuffer buffer(1024);
23    StringPool::flattenUtf8(&buffer, pool);
24
25    std::string* data = outPbPool->mutable_data();
26    data->reserve(buffer.size());
27
28    size_t offset = 0;
29    for (const BigBuffer::Block& block : buffer) {
30        data->insert(data->begin() + offset, block.buffer.get(), block.buffer.get() + block.size);
31        offset += block.size;
32    }
33}
34
35void serializeSourceToPb(const Source& source, StringPool* srcPool, pb::Source* outPbSource) {
36    StringPool::Ref ref = srcPool->makeRef(util::utf8ToUtf16(source.path));
37    outPbSource->set_path_idx(static_cast<uint32_t>(ref.getIndex()));
38    if (source.line) {
39        outPbSource->set_line_no(static_cast<uint32_t>(source.line.value()));
40    }
41}
42
43void deserializeSourceFromPb(const pb::Source& pbSource, const android::ResStringPool& srcPool,
44                             Source* outSource) {
45    if (pbSource.has_path_idx()) {
46        outSource->path = util::getString8(srcPool, pbSource.path_idx()).toString();
47    }
48
49    if (pbSource.has_line_no()) {
50        outSource->line = static_cast<size_t>(pbSource.line_no());
51    }
52}
53
54pb::SymbolStatus_Visibility serializeVisibilityToPb(SymbolState state) {
55    switch (state) {
56    case SymbolState::kPrivate: return pb::SymbolStatus_Visibility_Private;
57    case SymbolState::kPublic: return pb::SymbolStatus_Visibility_Public;
58    default: break;
59    }
60    return pb::SymbolStatus_Visibility_Unknown;
61}
62
63SymbolState deserializeVisibilityFromPb(pb::SymbolStatus_Visibility pbVisibility) {
64    switch (pbVisibility) {
65    case pb::SymbolStatus_Visibility_Private: return SymbolState::kPrivate;
66    case pb::SymbolStatus_Visibility_Public: return SymbolState::kPublic;
67    default: break;
68    }
69    return SymbolState::kUndefined;
70}
71
72void serializeConfig(const ConfigDescription& config, pb::ConfigDescription* outPbConfig) {
73    android::ResTable_config flatConfig = config;
74    flatConfig.size = sizeof(flatConfig);
75    flatConfig.swapHtoD();
76    outPbConfig->set_data(&flatConfig, sizeof(flatConfig));
77}
78
79bool deserializeConfigDescriptionFromPb(const pb::ConfigDescription& pbConfig,
80                                        ConfigDescription* outConfig) {
81    if (!pbConfig.has_data()) {
82        return false;
83    }
84
85    const android::ResTable_config* config;
86    if (pbConfig.data().size() > sizeof(*config)) {
87        return false;
88    }
89
90    config = reinterpret_cast<const android::ResTable_config*>(pbConfig.data().data());
91    outConfig->copyFromDtoH(*config);
92    return true;
93}
94
95pb::Reference_Type serializeReferenceTypeToPb(Reference::Type type) {
96    switch (type) {
97    case Reference::Type::kResource:  return pb::Reference_Type_Ref;
98    case Reference::Type::kAttribute: return pb::Reference_Type_Attr;
99    default: break;
100    }
101    return pb::Reference_Type_Ref;
102}
103
104Reference::Type deserializeReferenceTypeFromPb(pb::Reference_Type pbType) {
105    switch (pbType) {
106    case pb::Reference_Type_Ref:  return Reference::Type::kResource;
107    case pb::Reference_Type_Attr: return Reference::Type::kAttribute;
108    default: break;
109    }
110    return Reference::Type::kResource;
111}
112
113pb::Plural_Arity serializePluralEnumToPb(size_t pluralIdx) {
114    switch (pluralIdx) {
115    case Plural::Zero:  return pb::Plural_Arity_Zero;
116    case Plural::One:   return pb::Plural_Arity_One;
117    case Plural::Two:   return pb::Plural_Arity_Two;
118    case Plural::Few:   return pb::Plural_Arity_Few;
119    case Plural::Many:  return pb::Plural_Arity_Many;
120    default: break;
121    }
122    return pb::Plural_Arity_Other;
123}
124
125size_t deserializePluralEnumFromPb(pb::Plural_Arity arity) {
126    switch (arity) {
127    case pb::Plural_Arity_Zero: return Plural::Zero;
128    case pb::Plural_Arity_One:  return Plural::One;
129    case pb::Plural_Arity_Two:  return Plural::Two;
130    case pb::Plural_Arity_Few:  return Plural::Few;
131    case pb::Plural_Arity_Many: return Plural::Many;
132    default: break;
133    }
134    return Plural::Other;
135}
136
137} // namespace aapt
138