1 /*
2 * Copyright (C) 2018 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 "actions/zlib-utils.h"
18
19 #include <memory>
20
21 #include "utils/base/logging.h"
22 #include "utils/intents/zlib-utils.h"
23
24 namespace libtextclassifier3 {
25
26 // Compress rule fields in the model.
CompressActionsModel(ActionsModelT * model)27 bool CompressActionsModel(ActionsModelT* model) {
28 std::unique_ptr<ZlibCompressor> zlib_compressor = ZlibCompressor::Instance();
29 if (!zlib_compressor) {
30 TC3_LOG(ERROR) << "Cannot compress model.";
31 return false;
32 }
33
34 // Compress regex rules.
35 if (model->rules != nullptr) {
36 for (int i = 0; i < model->rules->regex_rule.size(); i++) {
37 RulesModel_::RegexRuleT* rule = model->rules->regex_rule[i].get();
38 rule->compressed_pattern.reset(new CompressedBufferT);
39 zlib_compressor->Compress(rule->pattern, rule->compressed_pattern.get());
40 rule->pattern.clear();
41 }
42 }
43
44 if (model->low_confidence_rules != nullptr) {
45 for (int i = 0; i < model->low_confidence_rules->regex_rule.size(); i++) {
46 RulesModel_::RegexRuleT* rule =
47 model->low_confidence_rules->regex_rule[i].get();
48 if (!rule->pattern.empty()) {
49 rule->compressed_pattern.reset(new CompressedBufferT);
50 zlib_compressor->Compress(rule->pattern,
51 rule->compressed_pattern.get());
52 rule->pattern.clear();
53 }
54 if (!rule->output_pattern.empty()) {
55 rule->compressed_output_pattern.reset(new CompressedBufferT);
56 zlib_compressor->Compress(rule->output_pattern,
57 rule->compressed_output_pattern.get());
58 rule->output_pattern.clear();
59 }
60 }
61 }
62
63 if (!model->lua_actions_script.empty()) {
64 model->compressed_lua_actions_script.reset(new CompressedBufferT);
65 zlib_compressor->Compress(model->lua_actions_script,
66 model->compressed_lua_actions_script.get());
67 }
68
69 if (model->ranking_options != nullptr &&
70 !model->ranking_options->lua_ranking_script.empty()) {
71 model->ranking_options->compressed_lua_ranking_script.reset(
72 new CompressedBufferT);
73 zlib_compressor->Compress(
74 model->ranking_options->lua_ranking_script,
75 model->ranking_options->compressed_lua_ranking_script.get());
76 }
77
78 // Compress intent generator.
79 if (model->android_intent_options != nullptr) {
80 CompressIntentModel(model->android_intent_options.get());
81 }
82
83 return true;
84 }
85
DecompressActionsModel(ActionsModelT * model)86 bool DecompressActionsModel(ActionsModelT* model) {
87 std::unique_ptr<ZlibDecompressor> zlib_decompressor =
88 ZlibDecompressor::Instance();
89 if (!zlib_decompressor) {
90 TC3_LOG(ERROR) << "Cannot initialize decompressor.";
91 return false;
92 }
93
94 // Decompress regex rules.
95 if (model->rules != nullptr) {
96 for (int i = 0; i < model->rules->regex_rule.size(); i++) {
97 RulesModel_::RegexRuleT* rule = model->rules->regex_rule[i].get();
98 if (!zlib_decompressor->MaybeDecompress(rule->compressed_pattern.get(),
99 &rule->pattern)) {
100 TC3_LOG(ERROR) << "Cannot decompress pattern: " << i;
101 return false;
102 }
103 rule->compressed_pattern.reset(nullptr);
104 }
105 }
106
107 // Decompress low confidence rules.
108 if (model->low_confidence_rules != nullptr) {
109 for (int i = 0; i < model->low_confidence_rules->regex_rule.size(); i++) {
110 RulesModel_::RegexRuleT* rule =
111 model->low_confidence_rules->regex_rule[i].get();
112 if (!zlib_decompressor->MaybeDecompress(rule->compressed_pattern.get(),
113 &rule->pattern)) {
114 TC3_LOG(ERROR) << "Cannot decompress pattern: " << i;
115 return false;
116 }
117 if (!zlib_decompressor->MaybeDecompress(
118 rule->compressed_output_pattern.get(), &rule->output_pattern)) {
119 TC3_LOG(ERROR) << "Cannot decompress pattern: " << i;
120 return false;
121 }
122 rule->compressed_pattern.reset(nullptr);
123 rule->compressed_output_pattern.reset(nullptr);
124 }
125 }
126
127 if (!zlib_decompressor->MaybeDecompress(
128 model->compressed_lua_actions_script.get(),
129 &model->lua_actions_script)) {
130 TC3_LOG(ERROR) << "Cannot decompress actions script.";
131 return false;
132 }
133
134 if (model->ranking_options != nullptr &&
135 !zlib_decompressor->MaybeDecompress(
136 model->ranking_options->compressed_lua_ranking_script.get(),
137 &model->ranking_options->lua_ranking_script)) {
138 TC3_LOG(ERROR) << "Cannot decompress actions script.";
139 return false;
140 }
141
142 return true;
143 }
144
CompressSerializedActionsModel(const std::string & model)145 std::string CompressSerializedActionsModel(const std::string& model) {
146 std::unique_ptr<ActionsModelT> unpacked_model =
147 UnPackActionsModel(model.c_str());
148 TC3_CHECK(unpacked_model != nullptr);
149 TC3_CHECK(CompressActionsModel(unpacked_model.get()));
150 flatbuffers::FlatBufferBuilder builder;
151 FinishActionsModelBuffer(builder,
152 ActionsModel::Pack(builder, unpacked_model.get()));
153 return std::string(reinterpret_cast<const char*>(builder.GetBufferPointer()),
154 builder.GetSize());
155 }
156
GetUncompressedString(const flatbuffers::String * uncompressed_buffer,const CompressedBuffer * compressed_buffer,ZlibDecompressor * decompressor,std::string * out)157 bool GetUncompressedString(const flatbuffers::String* uncompressed_buffer,
158 const CompressedBuffer* compressed_buffer,
159 ZlibDecompressor* decompressor, std::string* out) {
160 if (uncompressed_buffer == nullptr && compressed_buffer == nullptr) {
161 out->clear();
162 return true;
163 }
164
165 return decompressor->MaybeDecompressOptionallyCompressedBuffer(
166 uncompressed_buffer, compressed_buffer, out);
167 }
168
169 } // namespace libtextclassifier3
170