| Index: ui/file_manager/zip_archiver/cpp/compressor_io_javascript_stream.cc
|
| diff --git a/ui/file_manager/zip_archiver/cpp/compressor_io_javascript_stream.cc b/ui/file_manager/zip_archiver/cpp/compressor_io_javascript_stream.cc
|
| index 5fdb081f15e4df94925111e85d987a8302f11d7c..92bba21f9eb16a4feadb4a7b75bfe06a2e517029 100644
|
| --- a/ui/file_manager/zip_archiver/cpp/compressor_io_javascript_stream.cc
|
| +++ b/ui/file_manager/zip_archiver/cpp/compressor_io_javascript_stream.cc
|
| @@ -7,45 +7,129 @@
|
| #include <limits>
|
| #include <thread>
|
|
|
| -#include "archive.h"
|
| #include "ppapi/cpp/logging.h"
|
|
|
| CompressorIOJavaScriptStream::CompressorIOJavaScriptStream(
|
| JavaScriptCompressorRequestorInterface* requestor)
|
| - : requestor_(requestor) {
|
| - pthread_mutex_init(&shared_state_lock_, NULL);
|
| - pthread_cond_init(&available_data_cond_, NULL);
|
| - pthread_cond_init(&data_written_cond_, NULL);
|
| + : requestor_(requestor), buffer_offset_(-1), buffer_data_length_(0) {
|
| + pthread_mutex_init(&shared_state_lock_, nullptr);
|
| + pthread_cond_init(&available_data_cond_, nullptr);
|
| + pthread_cond_init(&data_written_cond_, nullptr);
|
|
|
| pthread_mutex_lock(&shared_state_lock_);
|
| available_data_ = false;
|
| + buffer_ = new char[compressor_stream_constants::kMaximumDataChunkSize];
|
| pthread_mutex_unlock(&shared_state_lock_);
|
| }
|
|
|
| CompressorIOJavaScriptStream::~CompressorIOJavaScriptStream() {
|
| + pthread_mutex_lock(&shared_state_lock_);
|
| + delete buffer_;
|
| + pthread_mutex_unlock(&shared_state_lock_);
|
| pthread_cond_destroy(&data_written_cond_);
|
| pthread_cond_destroy(&available_data_cond_);
|
| pthread_mutex_destroy(&shared_state_lock_);
|
| };
|
|
|
| -int64_t CompressorIOJavaScriptStream::Write(int64_t byte_to_write,
|
| - const pp::VarArrayBuffer& buffer) {
|
| +int64_t CompressorIOJavaScriptStream::Flush() {
|
| pthread_mutex_lock(&shared_state_lock_);
|
| - requestor_->WriteChunkRequest(byte_to_write, buffer);
|
| +
|
| + if (buffer_data_length_ == 0) {
|
| + pthread_mutex_unlock(&shared_state_lock_);
|
| + return 0;
|
| + }
|
| +
|
| + // Copy the data in buffer_ to array_buffer.
|
| + pp::VarArrayBuffer array_buffer(buffer_data_length_);
|
| + char* array_buffer_data = static_cast<char*>(array_buffer.Map());
|
| + memcpy(array_buffer_data, buffer_, buffer_data_length_);
|
| + array_buffer.Unmap();
|
| +
|
| + requestor_->WriteChunkRequest(buffer_offset_,
|
| + buffer_data_length_,
|
| + array_buffer);
|
|
|
| pthread_cond_wait(&data_written_cond_, &shared_state_lock_);
|
|
|
| int64_t written_bytes = written_bytes_;
|
| - pthread_mutex_unlock(&shared_state_lock_);
|
| + if (written_bytes < buffer_data_length_) {
|
| + pthread_mutex_unlock(&shared_state_lock_);
|
| + return -1 /* Error */;
|
| + }
|
| +
|
| + // Reset the offset and length to the default values.
|
| + buffer_offset_ = -1;
|
| + buffer_data_length_ = 0;
|
|
|
| + pthread_mutex_unlock(&shared_state_lock_);
|
| return written_bytes;
|
| }
|
|
|
| -void CompressorIOJavaScriptStream::WriteChunkDone(int64_t written_bytes) {
|
| +int64_t CompressorIOJavaScriptStream::Write(int64_t zip_offset,
|
| + int64_t zip_length,
|
| + const char* zip_buffer) {
|
| + pthread_mutex_lock(&shared_state_lock_);
|
| +
|
| + // The offset from which the data should be written onto the archive.
|
| + int64_t current_offset = zip_offset;
|
| + int64_t left_length = zip_length;
|
| + const char* buffer_pointer = zip_buffer;
|
| +
|
| + do {
|
| + // Flush the buffer if the data in the buffer cannot be reused.
|
| + // The following is the brief explanation about the conditions of the
|
| + // following if statement.
|
| + // 1: The buffer is not in the initial state (empty).
|
| + // The buffer should have some data to flush.
|
| + // 2: This write operation is not to append the data to the buffer.
|
| + // 3: The buffer overflows if we append the data to the buffer.
|
| + // If we can append the new data to the current data in the buffer,
|
| + // we should not flush the buffer.
|
| + // 4: The index to write is outside the buffer.
|
| + // If we want to write data outside the range, we first need to flush
|
| + // the buffer, and then cache the data in the buffer.
|
| + if (buffer_offset_ >= 0 && /* 1 */
|
| + (current_offset != buffer_offset_ + buffer_data_length_ || /* 2 */
|
| + buffer_data_length_ + left_length >
|
| + compressor_stream_constants::kMaximumDataChunkSize) && /* 3 */
|
| + (current_offset < buffer_offset_ ||
|
| + buffer_offset_ + buffer_data_length_ <
|
| + current_offset + left_length) /* 4 */ ) {
|
| + pthread_mutex_unlock(&shared_state_lock_);
|
| + int64_t bytes_to_write = buffer_data_length_;
|
| + if (Flush() != bytes_to_write)
|
| + return -1;
|
| + pthread_mutex_lock(&shared_state_lock_);
|
| + }
|
| +
|
| + // How many bytes we should copy to buffer_ in this iteration.
|
| + int64_t copy_length = std::min(
|
| + left_length, compressor_stream_constants::kMaximumDataChunkSize);
|
| + // Set up the buffer_offset_ if the buffer_ has no data.
|
| + if (buffer_offset_ == -1 /* initial state */)
|
| + buffer_offset_ = current_offset;
|
| + // Calculate the relative offset from left_length.
|
| + int64_t offset_in_buffer = current_offset - buffer_offset_;
|
| + // Copy data from zip_buffer, which is pointed by buffer_pointer, to buffer_.
|
| + memcpy(buffer_ + offset_in_buffer, buffer_pointer, copy_length);
|
| +
|
| + buffer_pointer += copy_length;
|
| + buffer_data_length_ = std::max(
|
| + buffer_data_length_, offset_in_buffer + copy_length);
|
| + current_offset += copy_length;
|
| + left_length -= copy_length;
|
| + } while (left_length > 0);
|
| +
|
| + pthread_mutex_unlock(&shared_state_lock_);
|
| + return zip_length;
|
| +}
|
| +
|
| +int64_t CompressorIOJavaScriptStream::WriteChunkDone(int64_t written_bytes) {
|
| pthread_mutex_lock(&shared_state_lock_);
|
| written_bytes_ = written_bytes;
|
| pthread_cond_signal(&data_written_cond_);
|
| pthread_mutex_unlock(&shared_state_lock_);
|
| + return written_bytes;
|
| }
|
|
|
| int64_t CompressorIOJavaScriptStream::Read(int64_t bytes_to_read,
|
| @@ -65,7 +149,7 @@ int64_t CompressorIOJavaScriptStream::Read(int64_t bytes_to_read,
|
| return read_bytes;
|
| }
|
|
|
| -void CompressorIOJavaScriptStream::ReadFileChunkDone(int64_t read_bytes,
|
| +int64_t CompressorIOJavaScriptStream::ReadFileChunkDone(int64_t read_bytes,
|
| pp::VarArrayBuffer* array_buffer) {
|
| pthread_mutex_lock(&shared_state_lock_);
|
|
|
| @@ -81,4 +165,5 @@ void CompressorIOJavaScriptStream::ReadFileChunkDone(int64_t read_bytes,
|
| available_data_ = true;
|
| pthread_cond_signal(&available_data_cond_);
|
| pthread_mutex_unlock(&shared_state_lock_);
|
| + return read_bytes;
|
| }
|
|
|