From c0ec8d9f069da8dedad460fcba49ea3c287da7b6 Mon Sep 17 00:00:00 2001 From: Stanislav Baranov Date: Fri, 1 Jun 2018 12:46:27 -0700 Subject: [PATCH] Restore archive support removed in #5305. Codepush bundles use zip. (#5441) --- assets/BUILD.gn | 7 ++ assets/zip_asset_store.cc | 124 ++++++++++++++++++++++++ assets/zip_asset_store.h | 51 ++++++++++ travis/licenses_golden/licenses_flutter | 2 + 4 files changed, 184 insertions(+) create mode 100644 assets/zip_asset_store.cc create mode 100644 assets/zip_asset_store.h diff --git a/assets/BUILD.gn b/assets/BUILD.gn index 7247a2f3d..28d7e5696 100644 --- a/assets/BUILD.gn +++ b/assets/BUILD.gn @@ -9,6 +9,8 @@ source_set("assets") { "asset_resolver.h", "directory_asset_bundle.cc", "directory_asset_bundle.h", + "zip_asset_store.cc", + "zip_asset_store.h", ] deps = [ @@ -16,6 +18,11 @@ source_set("assets") { "$flutter_root/fml", "$flutter_root/glue", "//garnet/public/lib/fxl", + "//garnet/public/lib/zip", + ] + + public_deps = [ + "//third_party/zlib:minizip", ] public_configs = [ "$flutter_root:config" ] diff --git a/assets/zip_asset_store.cc b/assets/zip_asset_store.cc new file mode 100644 index 000000000..1b9216bd3 --- /dev/null +++ b/assets/zip_asset_store.cc @@ -0,0 +1,124 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "flutter/assets/zip_asset_store.h" +#include "lib/fxl/build_config.h" + +#include + +#if !defined(OS_WIN) +#include +#endif + +#include +#include + +#include "flutter/glue/trace_event.h" + +namespace blink { + +ZipAssetStore::ZipAssetStore(std::string file_path) + : file_path_(std::move(file_path)) { + BuildStatCache(); +} + +ZipAssetStore::~ZipAssetStore() = default; + +zip::UniqueUnzipper ZipAssetStore::CreateUnzipper() const { + return zip::UniqueUnzipper{::unzOpen2(file_path_.c_str(), nullptr)}; +} + +// |blink::AssetResolver| +bool ZipAssetStore::IsValid() const { + return stat_cache_.size() > 0; +} + +// |blink::AssetResolver| +bool ZipAssetStore::GetAsBuffer(const std::string& asset_name, + std::vector* data) const { + TRACE_EVENT0("flutter", "ZipAssetStore::GetAsBuffer"); + auto found = stat_cache_.find(asset_name); + + if (found == stat_cache_.end()) { + return false; + } + + auto unzipper = CreateUnzipper(); + + if (!unzipper.is_valid()) { + return false; + } + + int result = UNZ_OK; + + result = unzGoToFilePos(unzipper.get(), &(found->second.file_pos)); + if (result != UNZ_OK) { + FXL_LOG(WARNING) << "unzGetCurrentFileInfo failed, error=" << result; + return false; + } + + result = unzOpenCurrentFile(unzipper.get()); + if (result != UNZ_OK) { + FXL_LOG(WARNING) << "unzOpenCurrentFile failed, error=" << result; + return false; + } + + data->resize(found->second.uncompressed_size); + int total_read = 0; + while (total_read < static_cast(data->size())) { + int bytes_read = unzReadCurrentFile( + unzipper.get(), data->data() + total_read, data->size() - total_read); + if (bytes_read <= 0) { + return false; + } + total_read += bytes_read; + } + + return true; +} + +void ZipAssetStore::BuildStatCache() { + TRACE_EVENT0("flutter", "ZipAssetStore::BuildStatCache"); + + auto unzipper = CreateUnzipper(); + + if (!unzipper.is_valid()) { + return; + } + + if (unzGoToFirstFile(unzipper.get()) != UNZ_OK) { + return; + } + + do { + int result = UNZ_OK; + + // Get the current file name. + unz_file_info file_info = {}; + char file_name[255]; + result = unzGetCurrentFileInfo(unzipper.get(), &file_info, file_name, + sizeof(file_name), nullptr, 0, nullptr, 0); + if (result != UNZ_OK) { + continue; + } + + if (file_info.uncompressed_size == 0) { + continue; + } + + // Get the current file position. + unz_file_pos file_pos = {}; + result = unzGetFilePos(unzipper.get(), &file_pos); + if (result != UNZ_OK) { + continue; + } + + std::string file_name_key(file_name, file_info.size_filename); + CacheEntry entry(file_pos, file_info.uncompressed_size); + stat_cache_.emplace(std::move(file_name_key), std::move(entry)); + + } while (unzGoToNextFile(unzipper.get()) == UNZ_OK); +} + +} // namespace blink diff --git a/assets/zip_asset_store.h b/assets/zip_asset_store.h new file mode 100644 index 000000000..558678e25 --- /dev/null +++ b/assets/zip_asset_store.h @@ -0,0 +1,51 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FLUTTER_ASSETS_ZIP_ASSET_STORE_H_ +#define FLUTTER_ASSETS_ZIP_ASSET_STORE_H_ + +#include + +#include "flutter/assets/asset_resolver.h" +#include "lib/fxl/macros.h" +#include "lib/fxl/memory/ref_counted.h" +#include "lib/zip/unique_unzipper.h" +#include "third_party/zlib/contrib/minizip/unzip.h" + +namespace blink { + +class ZipAssetStore final : public AssetResolver { + public: + ZipAssetStore(std::string file_path); + + ~ZipAssetStore() override; + + private: + struct CacheEntry { + unz_file_pos file_pos; + size_t uncompressed_size; + CacheEntry(unz_file_pos p_file_pos, size_t p_uncompressed_size) + : file_pos(p_file_pos), uncompressed_size(p_uncompressed_size) {} + }; + + std::string file_path_; + mutable std::map stat_cache_; + + // |blink::AssetResolver| + bool IsValid() const override; + + // |blink::AssetResolver| + bool GetAsBuffer(const std::string& asset_name, + std::vector* data) const override; + + void BuildStatCache(); + + zip::UniqueUnzipper CreateUnzipper() const; + + FXL_DISALLOW_COPY_AND_ASSIGN(ZipAssetStore); +}; + +} // namespace blink + +#endif // FLUTTER_ASSETS_ZIP_ASSET_STORE_H_ diff --git a/travis/licenses_golden/licenses_flutter b/travis/licenses_golden/licenses_flutter index c8a178ad7..efeeb86c8 100644 --- a/travis/licenses_golden/licenses_flutter +++ b/travis/licenses_golden/licenses_flutter @@ -322,6 +322,8 @@ ORIGIN: ../../../flutter/assets/directory_asset_bundle.cc + ../../../LICENSE TYPE: LicenseType.bsd FILE: ../../../flutter/assets/directory_asset_bundle.cc FILE: ../../../flutter/assets/directory_asset_bundle.h +FILE: ../../../flutter/assets/zip_asset_store.cc +FILE: ../../../flutter/assets/zip_asset_store.h FILE: ../../../flutter/common/settings.cc FILE: ../../../flutter/common/settings.h FILE: ../../../flutter/flow/export_node.cc -- GitLab