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