8
8
#include < string>
9
9
#include < string_view>
10
10
11
+ #include " rapidjson/document.h"
12
+ #include " third_party/skia/include/utils/SkBase64.h"
13
+
11
14
#include " flutter/fml/base32.h"
12
15
#include " flutter/fml/file.h"
13
16
#include " flutter/fml/logging.h"
@@ -103,21 +106,35 @@ static std::shared_ptr<fml::UniqueFD> MakeCacheDirectory(
103
106
}
104
107
} // namespace
105
108
109
+ sk_sp<SkData> ParseBase32 (const std::string& input) {
110
+ std::pair<bool , std::string> decode_result = fml::Base32Decode (input);
111
+ if (!decode_result.first ) {
112
+ FML_LOG (ERROR) << " Base32 can't decode: " << input;
113
+ return nullptr ;
114
+ }
115
+ const std::string& data_string = decode_result.second ;
116
+ return SkData::MakeWithCopy (data_string.data (), data_string.length ());
117
+ }
118
+
119
+ sk_sp<SkData> ParseBase64 (const std::string& input) {
120
+ SkBase64 decoder;
121
+ auto error = decoder.decode (input.c_str (), input.length ());
122
+ if (error != SkBase64::Error::kNoError ) {
123
+ FML_LOG (ERROR) << " Base64 decode error: " << error;
124
+ FML_LOG (ERROR) << " Base64 can't decode: " << input;
125
+ return nullptr ;
126
+ }
127
+ return SkData::MakeWithCopy (decoder.getData (), decoder.getDataSize ());
128
+ }
129
+
106
130
std::vector<PersistentCache::SkSLCache> PersistentCache::LoadSkSLs () {
107
131
TRACE_EVENT0 (" flutter" , " PersistentCache::LoadSkSLs" );
108
132
std::vector<PersistentCache::SkSLCache> result;
109
133
fml::FileVisitor visitor = [&result](const fml::UniqueFD& directory,
110
134
const std::string& filename) {
111
- std::pair<bool , std::string> decode_result = fml::Base32Decode (filename);
112
- if (!decode_result.first ) {
113
- FML_LOG (ERROR) << " Base32 can't decode: " << filename;
114
- return true ; // continue to visit other files
115
- }
116
- const std::string& data_string = decode_result.second ;
117
- sk_sp<SkData> key =
118
- SkData::MakeWithCopy (data_string.data (), data_string.length ());
135
+ sk_sp<SkData> key = ParseBase32 (filename);
119
136
sk_sp<SkData> data = LoadFile (directory, filename);
120
- if (data != nullptr ) {
137
+ if (key != nullptr && data != nullptr ) {
121
138
result.push_back ({key, data});
122
139
} else {
123
140
FML_LOG (ERROR) << " Failed to load: " << filename;
@@ -136,11 +153,29 @@ std::vector<PersistentCache::SkSLCache> PersistentCache::LoadSkSLs() {
136
153
fml::FilePermission::kRead );
137
154
fml::UniqueFD sksl_asset_dir =
138
155
fml::OpenDirectoryReadOnly (root_asset_dir, kSkSLSubdirName );
139
- if (sksl_asset_dir. is_valid ()) {
140
- FML_LOG (INFO) << " Found sksl asset directory. Loading SkSLs from it... " ;
141
- fml::VisitFiles (sksl_asset_dir, visitor) ;
156
+ auto sksl_asset_file = fml::OpenFileReadOnly (sksl_asset_dir, kAssetFileName );
157
+ if (!sksl_asset_file. is_valid ()) {
158
+ FML_LOG (INFO) << " No sksl asset file found. " ;
142
159
} else {
143
- FML_LOG (INFO) << " No sksl asset directory found." ;
160
+ FML_LOG (INFO) << " Found sksl asset. Loading SkSLs from it..." ;
161
+ auto mapping = std::make_unique<fml::FileMapping>(sksl_asset_file);
162
+ rapidjson::Document json_doc;
163
+ rapidjson::ParseResult parse_result =
164
+ json_doc.Parse (reinterpret_cast <const char *>(mapping->GetMapping ()),
165
+ mapping->GetSize ());
166
+ if (parse_result != rapidjson::ParseErrorCode::kParseErrorNone ) {
167
+ FML_LOG (ERROR) << " Failed to parse json file: " << kAssetFileName ;
168
+ } else {
169
+ for (auto & item : json_doc[" data" ].GetObject ()) {
170
+ sk_sp<SkData> key = ParseBase32 (item.name .GetString ());
171
+ sk_sp<SkData> sksl = ParseBase64 (item.value .GetString ());
172
+ if (key != nullptr && sksl != nullptr ) {
173
+ result.push_back ({key, sksl});
174
+ } else {
175
+ FML_LOG (ERROR) << " Failed to load: " << item.name .GetString ();
176
+ }
177
+ }
178
+ }
144
179
}
145
180
146
181
return result;
0 commit comments