Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(912)

Unified Diff: ui/file_manager/zip_archiver/unpacker/cpp/volume.cc

Issue 2804453002: Move files from zip_archiver/unpacker/ to zip_archiver/. (Closed)
Patch Set: Move files from zip_archiver/unpacker/ to zip_archiver/. Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: ui/file_manager/zip_archiver/unpacker/cpp/volume.cc
diff --git a/ui/file_manager/zip_archiver/unpacker/cpp/volume.cc b/ui/file_manager/zip_archiver/unpacker/cpp/volume.cc
deleted file mode 100644
index 588698f57c291199ede886f2c899912420dfeacc..0000000000000000000000000000000000000000
--- a/ui/file_manager/zip_archiver/unpacker/cpp/volume.cc
+++ /dev/null
@@ -1,489 +0,0 @@
-// Copyright 2014 The Chromium OS 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 "volume.h"
-
-#include <cstring>
-#include <sstream>
-
-#include "request.h"
-#include "volume_archive_libarchive.h"
-#include "volume_reader_javascript_stream.h"
-
-namespace {
-
-#define LOG(x) \
- do { \
- std::stringstream fmt; \
- fmt << x; \
- message_sender_->CONSOLE_LOG(file_system_id_, request_id, fmt.str()); \
- } while (0)
-
-typedef std::map<std::string, VolumeArchive*>::const_iterator
- volume_archive_iterator;
-
-const char kPathDelimiter[] = "/";
-
-// size is int64_t and modification_time is time_t because this is how
-// libarchive is going to pass them to us.
-pp::VarDictionary CreateEntry(int64_t index,
- const std::string& name,
- bool is_directory,
- int64_t size,
- time_t modification_time) {
- pp::VarDictionary entry_metadata;
- // index is int64_t, unsupported by pp::Var
- std::stringstream ss_index;
- ss_index << index;
- entry_metadata.Set("index", ss_index.str());
- entry_metadata.Set("isDirectory", is_directory);
- entry_metadata.Set("name", name);
- // size is int64_t, unsupported by pp::Var
- std::stringstream ss_size;
- ss_size << size;
- entry_metadata.Set("size", ss_size.str());
- // mtime is time_t, unsupported by pp::Var
- std::stringstream ss_modification_time;
- ss_modification_time << modification_time;
- entry_metadata.Set("modificationTime", ss_modification_time.str());
-
- if (is_directory)
- entry_metadata.Set("entries", pp::VarDictionary());
-
- return entry_metadata;
-}
-
-void ConstructMetadata(int64_t index,
- const std::string& entry_path,
- int64_t size,
- bool is_directory,
- time_t modification_time,
- pp::VarDictionary* parent_metadata) {
- if (entry_path == "")
- return;
-
- pp::VarDictionary parent_entries =
- pp::VarDictionary(parent_metadata->Get("entries"));
-
- unsigned int position = entry_path.find(kPathDelimiter);
- pp::VarDictionary entry_metadata;
- std::string entry_name;
-
- if (position == std::string::npos) { // The entry itself.
- entry_name = entry_path;
- entry_metadata =
- CreateEntry(index, entry_name, is_directory, size, modification_time);
-
- // Update directory information. Required as sometimes the directory itself
- // is returned after the files inside it.
- pp::Var old_entry_metadata_var = parent_entries.Get(entry_name);
- if (!old_entry_metadata_var.is_undefined()) {
- pp::VarDictionary old_entry_metadata =
- pp::VarDictionary(old_entry_metadata_var);
- PP_DCHECK(old_entry_metadata.Get("isDirectory").AsBool());
- entry_metadata.Set("entries", old_entry_metadata.Get("entries"));
- }
- } else { // Get next parent on the way to the entry.
- entry_name = entry_path.substr(0, position);
-
- // Get next parent metadata. If none, create a new directory entry for it.
- // Some archives don't have directory information inside and for some the
- // information is returned later than the files inside it.
- pp::Var entry_metadata_var = parent_entries.Get(entry_name);
- if (entry_metadata_var.is_undefined())
- entry_metadata = CreateEntry(-1, entry_name, true, 0, modification_time);
- else
- entry_metadata = pp::VarDictionary(parent_entries.Get(entry_name));
-
- // Continue to construct metadata for all directories on the path to the
- // to the entry and for the entry itself.
- std::string entry_path_without_next_parent = entry_path.substr(
- position + sizeof(kPathDelimiter) - 1 /* Last char is '\0'. */);
-
- ConstructMetadata(index,
- entry_path_without_next_parent,
- size,
- is_directory,
- modification_time,
- &entry_metadata);
- }
-
- // Recreate parent_metadata. This is necessary because pp::VarDictionary::Get
- // returns a Var, not a Var& or Var* to directly modify the result.
- parent_entries.Set(entry_name, entry_metadata);
- parent_metadata->Set("entries", parent_entries);
-}
-
-// An internal implementation of JavaScriptRequestorInterface.
-class JavaScriptRequestor : public JavaScriptRequestorInterface {
- public:
- // JavaScriptRequestor does not own the volume pointer.
- explicit JavaScriptRequestor(Volume* volume) : volume_(volume) {}
-
- virtual void RequestFileChunk(const std::string& request_id,
- int64_t offset,
- int64_t bytes_to_read) {
- PP_DCHECK(offset >= 0);
- PP_DCHECK(bytes_to_read > 0);
- volume_->message_sender()->SendFileChunkRequest(
- volume_->file_system_id(), request_id, offset, bytes_to_read);
- }
-
- virtual void RequestPassphrase(const std::string& request_id) {
- volume_->message_sender()->SendPassphraseRequest(
- volume_->file_system_id(), request_id);
- }
-
- private:
- Volume* volume_;
-};
-
-// An internal implementation of VolumeArchiveFactoryInterface for default
-// Volume constructor.
-class VolumeArchiveFactory : public VolumeArchiveFactoryInterface {
- public:
- virtual VolumeArchive* Create(VolumeReader* reader) {
- return new VolumeArchiveLibarchive(reader);
- }
-};
-
-// An internal implementation of VolumeReaderFactoryInterface for default Volume
-// constructor.
-class VolumeReaderFactory : public VolumeReaderFactoryInterface {
- public:
- // VolumeReaderFactory does not own the volume pointer.
- explicit VolumeReaderFactory(Volume* volume) : volume_(volume) {}
-
- virtual VolumeReader* Create(int64_t archive_size) {
- return new VolumeReaderJavaScriptStream(archive_size, volume_->requestor());
- }
-
- private:
- Volume* volume_;
-};
-
-} // namespace
-
-struct Volume::OpenFileArgs {
- OpenFileArgs(const std::string& request_id,
- int64_t index,
- const std::string& encoding,
- int64_t archive_size) : request_id(request_id),
- index(index),
- encoding(encoding),
- archive_size(archive_size) {}
- const std::string request_id;
- const int64_t index;
- const std::string encoding;
- const int64_t archive_size;
-};
-
-Volume::Volume(const pp::InstanceHandle& instance_handle,
- const std::string& file_system_id,
- JavaScriptMessageSenderInterface* message_sender)
- : volume_archive_(NULL),
- file_system_id_(file_system_id),
- message_sender_(message_sender),
- worker_(instance_handle),
- callback_factory_(this) {
- requestor_ = new JavaScriptRequestor(this);
- volume_archive_factory_ = new VolumeArchiveFactory();
- volume_reader_factory_ = new VolumeReaderFactory(this);
- // Delegating constructors only from c++11.
-}
-
-Volume::Volume(const pp::InstanceHandle& instance_handle,
- const std::string& file_system_id,
- JavaScriptMessageSenderInterface* message_sender,
- VolumeArchiveFactoryInterface* volume_archive_factory,
- VolumeReaderFactoryInterface* volume_reader_factory)
- : volume_archive_(NULL),
- file_system_id_(file_system_id),
- message_sender_(message_sender),
- worker_(instance_handle),
- callback_factory_(this),
- volume_archive_factory_(volume_archive_factory),
- volume_reader_factory_(volume_reader_factory) {
- requestor_ = new JavaScriptRequestor(this);
-}
-
-Volume::~Volume() {
- worker_.Join();
-
- if (volume_archive_) {
- volume_archive_->Cleanup();
- delete volume_archive_;
- }
-
- delete requestor_;
- delete volume_archive_factory_;
- delete volume_reader_factory_;
-}
-
-bool Volume::Init() {
- return worker_.Start();
-}
-
-void Volume::ReadMetadata(const std::string& request_id,
- const std::string& encoding,
- int64_t archive_size) {
- worker_.message_loop().PostWork(callback_factory_.NewCallback(
- &Volume::ReadMetadataCallback, request_id, encoding, archive_size));
-}
-
-void Volume::OpenFile(const std::string& request_id,
- int64_t index,
- const std::string& encoding,
- int64_t archive_size) {
- worker_.message_loop().PostWork(callback_factory_.NewCallback(
- &Volume::OpenFileCallback, OpenFileArgs(request_id, index, encoding,
- archive_size)));
-}
-
-void Volume::CloseFile(const std::string& request_id,
- const std::string& open_request_id) {
- // Though close file could be executed on main thread, we send it to worker_
- // in order to ensure thread safety.
- worker_.message_loop().PostWork(callback_factory_.NewCallback(
- &Volume::CloseFileCallback, request_id, open_request_id));
-}
-
-void Volume::ReadFile(const std::string& request_id,
- const pp::VarDictionary& dictionary) {
- worker_.message_loop().PostWork(callback_factory_.NewCallback(
- &Volume::ReadFileCallback, request_id, dictionary));
-}
-
-void Volume::ReadChunkDone(const std::string& request_id,
- const pp::VarArrayBuffer& array_buffer,
- int64_t read_offset) {
- PP_DCHECK(volume_archive_);
-
- job_lock_.Acquire();
- if (request_id == reader_request_id_) {
- static_cast<VolumeReaderJavaScriptStream*>(volume_archive_->reader())->
- SetBufferAndSignal(array_buffer, read_offset);
- }
- job_lock_.Release();
-}
-
-void Volume::ReadChunkError(const std::string& request_id) {
- PP_DCHECK(volume_archive_);
- job_lock_.Acquire();
- if (request_id == reader_request_id_) {
- static_cast<VolumeReaderJavaScriptStream*>(volume_archive_->reader())->
- ReadErrorSignal();
- }
- job_lock_.Release();
-}
-
-void Volume::ReadPassphraseDone(const std::string& request_id,
- const std::string& passphrase) {
- PP_DCHECK(volume_archive_);
-
- job_lock_.Acquire();
- if (request_id == reader_request_id_) {
- static_cast<VolumeReaderJavaScriptStream*>(volume_archive_->reader())->
- SetPassphraseAndSignal(passphrase);
- }
- job_lock_.Release();
-}
-
-void Volume::ReadPassphraseError(const std::string& request_id) {
- PP_DCHECK(volume_archive_);
-
- job_lock_.Acquire();
- if (request_id == reader_request_id_) {
- static_cast<VolumeReaderJavaScriptStream*>(volume_archive_->reader())->
- PassphraseErrorSignal();
- }
- job_lock_.Release();
-}
-
-void Volume::ReadMetadataCallback(int32_t /*result*/,
- const std::string& request_id,
- const std::string& encoding,
- int64_t archive_size) {
- if (volume_archive_) {
- message_sender_->SendFileSystemError(
- file_system_id_, request_id, "ALREADY_OPENED");
- }
-
- job_lock_.Acquire();
- volume_archive_ = volume_archive_factory_->Create(
- volume_reader_factory_->Create(archive_size));
- static_cast<VolumeReaderJavaScriptStream*>(volume_archive_->reader())->
- SetRequestId(request_id);
- reader_request_id_ = request_id;
- job_lock_.Release();
-
- if (!volume_archive_->Init(encoding)) {
- message_sender_->SendFileSystemError(
- file_system_id_, request_id, volume_archive_->error_message());
- ClearJob();
- delete volume_archive_;
- volume_archive_ = NULL;
- return;
- }
-
- // Read and construct metadata.
- pp::VarDictionary root_metadata = CreateEntry(-1, "" /* name */, true, 0, 0);
-
- const char* path_name = NULL;
- int64_t size = 0;
- bool is_directory = false;
- time_t modification_time = 0;
- int64_t index = 0;
-
- for (;;) {
- VolumeArchive::Result ret = volume_archive_->GetNextHeader(
- &path_name, &size, &is_directory, &modification_time);
- if (ret == VolumeArchive::RESULT_FAIL) {
- message_sender_->SendFileSystemError(
- file_system_id_, request_id, volume_archive_->error_message());
- ClearJob();
- delete volume_archive_;
- volume_archive_ = NULL;
- return;
- } else if (ret == VolumeArchive::RESULT_EOF)
- break;
-
- ConstructMetadata(index, path_name, size, is_directory, modification_time,
- &root_metadata);
-
- ++index;
- }
-
- ClearJob();
-
- // Send metadata back to JavaScript.
- message_sender_->SendReadMetadataDone(
- file_system_id_, request_id, root_metadata);
-}
-
-void Volume::OpenFileCallback(int32_t /*result*/,
- const OpenFileArgs& args) {
- if (!volume_archive_) {
- message_sender_->SendFileSystemError(
- file_system_id_, args.request_id, "NOT_OPENED");
- return;
- }
-
- job_lock_.Acquire();
- if (!reader_request_id_.empty()) {
- // It is illegal to open a file while another operation is in progress or
- // another file is opened.
- message_sender_->SendFileSystemError(
- file_system_id_, args.request_id, "ILLEGAL");
- job_lock_.Release();
- return;
- }
- static_cast<VolumeReaderJavaScriptStream*>(volume_archive_->reader())->
- SetRequestId(args.request_id);
- reader_request_id_ = args.request_id;
- job_lock_.Release();
-
- if (!volume_archive_->SeekHeader(args.index)) {
- message_sender_->SendFileSystemError(
- file_system_id_, args.request_id, volume_archive_->error_message());
- ClearJob();
- return;
- }
-
- if (volume_archive_->GetNextHeader() == VolumeArchive::RESULT_FAIL) {
- message_sender_->SendFileSystemError(
- file_system_id_, args.request_id, volume_archive_->error_message());
- ClearJob();
- return;
- }
-
- // Send successful opened file response to NaCl.
- message_sender_->SendOpenFileDone(file_system_id_, args.request_id);
-}
-
-void Volume::CloseFileCallback(int32_t /*result*/,
- const std::string& request_id,
- const std::string& open_request_id) {
- job_lock_.Acquire();
- reader_request_id_ = "";
- job_lock_.Release();
-
- message_sender_->SendCloseFileDone(
- file_system_id_, request_id, open_request_id);
-}
-
-void Volume::ReadFileCallback(int32_t /*result*/,
- const std::string& request_id,
- const pp::VarDictionary& dictionary) {
- if (!volume_archive_) {
- message_sender_->SendFileSystemError(
- file_system_id_, request_id, "NOT_OPENED");
- return;
- }
-
- std::string open_request_id(
- dictionary.Get(request::key::kOpenRequestId).AsString());
- int64_t offset =
- request::GetInt64FromString(dictionary, request::key::kOffset);
- int64_t length =
- request::GetInt64FromString(dictionary, request::key::kLength);
- PP_DCHECK(length > 0); // JavaScript must not make requests with length <= 0.
-
- job_lock_.Acquire();
- if (open_request_id != reader_request_id_) {
- // The file is not opened.
- message_sender_->SendFileSystemError(
- file_system_id_, request_id, "FILE_NOT_OPENED");
- job_lock_.Release();
- return;
- }
- job_lock_.Release();
-
- // Decompress data and send it to JavaScript. Sending data is done in chunks
- // depending on how many bytes VolumeArchive::ReadData returns.
- int64_t left_length = length;
- while (left_length > 0) {
- const char* destination_buffer = NULL;
- int64_t read_bytes = volume_archive_->ReadData(
- offset, left_length, &destination_buffer);
-
- if (read_bytes < 0) {
- // Error messages should be sent to the read request (request_id), not
- // open request (open_request_id), as the last one has finished and this
- // is a read file.
- message_sender_->SendFileSystemError(
- file_system_id_, request_id, volume_archive_->error_message());
-
- // Should not cleanup VolumeArchive as Volume::CloseFile will be called in
- // case of failure.
- return;
- }
-
- // Send response back to ReadFile request.
- pp::VarArrayBuffer array_buffer(read_bytes);
- if (read_bytes > 0) {
- char* array_buffer_data = static_cast<char*>(array_buffer.Map());
- memcpy(array_buffer_data, destination_buffer, read_bytes);
- array_buffer.Unmap();
- }
-
- bool has_more_data = left_length - read_bytes > 0 && read_bytes > 0;
- message_sender_->SendReadFileDone(
- file_system_id_, request_id, array_buffer, has_more_data);
-
- if (read_bytes == 0)
- break; // No more available data.
-
- left_length -= read_bytes;
- offset += read_bytes;
- }
- volume_archive_->MaybeDecompressAhead();
-}
-
-
-void Volume::ClearJob() {
- job_lock_.Acquire();
- reader_request_id_ = "";
- job_lock_.Release();
-}
« no previous file with comments | « ui/file_manager/zip_archiver/unpacker/cpp/volume.h ('k') | ui/file_manager/zip_archiver/unpacker/cpp/volume_archive.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698