Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2017 The Chromium OS Authors. All rights reserved. | 1 // Copyright 2017 The Chromium OS Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "compressor_io_javascript_stream.h" | 5 #include "compressor_io_javascript_stream.h" |
| 6 | 6 |
| 7 #include <limits> | 7 #include <limits> |
| 8 #include <thread> | 8 #include <thread> |
| 9 | 9 |
| 10 #include "archive.h" | |
| 11 #include "ppapi/cpp/logging.h" | 10 #include "ppapi/cpp/logging.h" |
| 12 | 11 |
| 13 CompressorIOJavaScriptStream::CompressorIOJavaScriptStream( | 12 CompressorIOJavaScriptStream::CompressorIOJavaScriptStream( |
| 14 JavaScriptCompressorRequestorInterface* requestor) | 13 JavaScriptCompressorRequestorInterface* requestor) |
| 15 : requestor_(requestor) { | 14 : requestor_(requestor), buffer_offset_(-1), buffer_data_length_(0) { |
| 16 pthread_mutex_init(&shared_state_lock_, NULL); | 15 pthread_mutex_init(&shared_state_lock_, NULL); |
| 17 pthread_cond_init(&available_data_cond_, NULL); | 16 pthread_cond_init(&available_data_cond_, NULL); |
| 18 pthread_cond_init(&data_written_cond_, NULL); | 17 pthread_cond_init(&data_written_cond_, NULL); |
| 19 | 18 |
| 20 pthread_mutex_lock(&shared_state_lock_); | 19 pthread_mutex_lock(&shared_state_lock_); |
| 21 available_data_ = false; | 20 available_data_ = false; |
| 22 pthread_mutex_unlock(&shared_state_lock_); | 21 pthread_mutex_unlock(&shared_state_lock_); |
| 23 } | 22 } |
| 24 | 23 |
| 25 CompressorIOJavaScriptStream::~CompressorIOJavaScriptStream() { | 24 CompressorIOJavaScriptStream::~CompressorIOJavaScriptStream() { |
| 26 pthread_cond_destroy(&data_written_cond_); | 25 pthread_cond_destroy(&data_written_cond_); |
| 27 pthread_cond_destroy(&available_data_cond_); | 26 pthread_cond_destroy(&available_data_cond_); |
| 28 pthread_mutex_destroy(&shared_state_lock_); | 27 pthread_mutex_destroy(&shared_state_lock_); |
| 29 }; | 28 }; |
| 30 | 29 |
| 31 int64_t CompressorIOJavaScriptStream::Write(int64_t byte_to_write, | 30 int64_t CompressorIOJavaScriptStream::Flush() { |
| 32 const pp::VarArrayBuffer& buffer) { | |
| 33 pthread_mutex_lock(&shared_state_lock_); | 31 pthread_mutex_lock(&shared_state_lock_); |
| 34 requestor_->WriteChunkRequest(byte_to_write, buffer); | 32 |
| 33 if (buffer_data_length_ == 0) { | |
| 34 pthread_mutex_unlock(&shared_state_lock_); | |
| 35 return 0; | |
| 36 } | |
| 37 | |
| 38 // Copy the data in buffer_ to array_buffer. | |
| 39 pp::VarArrayBuffer array_buffer(buffer_data_length_); | |
| 40 char* array_buffer_data = static_cast<char*>(array_buffer.Map()); | |
| 41 memcpy(array_buffer_data, buffer_, buffer_data_length_); | |
| 42 array_buffer.Unmap(); | |
| 43 | |
| 44 requestor_->WriteChunkRequest(buffer_offset_, | |
| 45 buffer_data_length_, | |
| 46 array_buffer); | |
| 35 | 47 |
| 36 pthread_cond_wait(&data_written_cond_, &shared_state_lock_); | 48 pthread_cond_wait(&data_written_cond_, &shared_state_lock_); |
| 37 | 49 |
| 38 int64_t written_bytes = written_bytes_; | 50 int64_t written_bytes = written_bytes_; |
| 51 if (written_bytes < buffer_data_length_) { | |
| 52 pthread_mutex_unlock(&shared_state_lock_); | |
| 53 return -1 /* Error */; | |
| 54 } | |
| 55 | |
| 56 // Reset the offset and length to the default values. | |
| 57 buffer_offset_ = -1; | |
| 58 buffer_data_length_ = 0; | |
| 59 | |
| 39 pthread_mutex_unlock(&shared_state_lock_); | 60 pthread_mutex_unlock(&shared_state_lock_); |
| 40 | 61 return buffer_data_length_; |
| 41 return written_bytes; | |
| 42 } | 62 } |
| 43 | 63 |
| 44 void CompressorIOJavaScriptStream::WriteChunkDone(int64_t written_bytes) { | 64 int64_t CompressorIOJavaScriptStream::Write(int64_t zip_offset, |
| 65 int64_t zip_length, | |
| 66 const void* zip_buffer) { | |
|
mtomasz
2017/04/10 07:15:09
nit: Do we need const void* here? Can we have cons
takise
2017/04/11 06:00:51
Done.
| |
| 67 pthread_mutex_lock(&shared_state_lock_); | |
| 68 | |
| 69 int64_t current_offset = zip_offset; | |
| 70 int64_t left_length = zip_length; | |
| 71 const char* buffer_pointer = static_cast<const char*>(zip_buffer); | |
| 72 | |
| 73 do { | |
| 74 // Flush the buffer if the data in the buffer cannot be reused. | |
| 75 // The following is the brief explanation about the conditions of the | |
| 76 // following if statement. | |
| 77 // 1: The buffer is not in the initial state (empty). | |
| 78 // The buffer should have some data to flush. | |
| 79 // 2: This write operation is not to append the data to the buffer. | |
| 80 // 3: The buffer overflows if we append the data to the buffer. | |
| 81 // If we can append the new data to the current data in the buffer, | |
| 82 // we should not flush the buffer. | |
| 83 // 4: The index to write is outside the buffer. | |
| 84 // If we want to write data outside the range, we first need to flush | |
| 85 // the buffer, and then cache the data in the buffer. | |
| 86 if (buffer_offset_ >= 0 && /* 1 */ | |
| 87 (current_offset != buffer_offset_ + buffer_data_length_ || /* 2 */ | |
| 88 buffer_data_length_ + left_length > | |
| 89 compressor_stream_constants::kMaximumDataChunkSize) && /* 3 */ | |
| 90 (current_offset < buffer_offset_ || | |
| 91 buffer_offset_ + buffer_data_length_ < | |
| 92 current_offset + left_length) /* 4 */ | |
| 93 ) { | |
|
mtomasz
2017/04/10 07:15:09
nit: Please check the indent.
takise
2017/04/11 06:00:51
Done.
| |
| 94 pthread_mutex_unlock(&shared_state_lock_); | |
| 95 Flush(); | |
| 96 pthread_mutex_lock(&shared_state_lock_); | |
| 97 } | |
| 98 | |
| 99 int64_t copy_length = std::min( | |
|
mtomasz
2017/04/10 07:15:08
nit: Please add some comments, as the code below i
takise
2017/04/11 06:00:51
Done.
| |
| 100 left_length, compressor_stream_constants::kMaximumDataChunkSize); | |
| 101 if (buffer_offset_ == -1) | |
| 102 buffer_offset_ = current_offset; | |
| 103 int64_t offset_in_buffer = current_offset - buffer_offset_; | |
| 104 memcpy(buffer_ + offset_in_buffer, buffer_pointer, copy_length); | |
| 105 | |
| 106 buffer_pointer += copy_length; | |
| 107 if (buffer_offset_ == -1 /* initial state */) | |
| 108 buffer_offset_ = current_offset; | |
| 109 buffer_data_length_ = std::max( | |
| 110 buffer_data_length_, current_offset + copy_length - buffer_offset_); | |
| 111 current_offset += copy_length; | |
| 112 left_length -= copy_length; | |
| 113 } while (left_length > 0); | |
| 114 | |
| 115 pthread_mutex_unlock(&shared_state_lock_); | |
| 116 return zip_length; | |
| 117 } | |
| 118 | |
| 119 int64_t CompressorIOJavaScriptStream::WriteChunkDone(int64_t written_bytes) { | |
| 45 pthread_mutex_lock(&shared_state_lock_); | 120 pthread_mutex_lock(&shared_state_lock_); |
| 46 written_bytes_ = written_bytes; | 121 written_bytes_ = written_bytes; |
| 47 pthread_cond_signal(&data_written_cond_); | 122 pthread_cond_signal(&data_written_cond_); |
| 48 pthread_mutex_unlock(&shared_state_lock_); | 123 pthread_mutex_unlock(&shared_state_lock_); |
| 124 return written_bytes; | |
| 49 } | 125 } |
| 50 | 126 |
| 51 int64_t CompressorIOJavaScriptStream::Read(int64_t bytes_to_read, | 127 int64_t CompressorIOJavaScriptStream::Read(int64_t bytes_to_read, |
| 52 char* destination_buffer) { | 128 char* destination_buffer) { |
| 53 pthread_mutex_lock(&shared_state_lock_); | 129 pthread_mutex_lock(&shared_state_lock_); |
| 54 | 130 |
| 55 destination_buffer_ = destination_buffer; | 131 destination_buffer_ = destination_buffer; |
| 56 requestor_->ReadFileChunkRequest(bytes_to_read); | 132 requestor_->ReadFileChunkRequest(bytes_to_read); |
| 57 | 133 |
| 58 while (!available_data_) { | 134 while (!available_data_) { |
| 59 pthread_cond_wait(&available_data_cond_, &shared_state_lock_); | 135 pthread_cond_wait(&available_data_cond_, &shared_state_lock_); |
| 60 } | 136 } |
| 61 | 137 |
| 62 int64_t read_bytes = read_bytes_; | 138 int64_t read_bytes = read_bytes_; |
| 63 available_data_ = false; | 139 available_data_ = false; |
| 64 pthread_mutex_unlock(&shared_state_lock_); | 140 pthread_mutex_unlock(&shared_state_lock_); |
| 65 return read_bytes; | 141 return read_bytes; |
| 66 } | 142 } |
| 67 | 143 |
| 68 void CompressorIOJavaScriptStream::ReadFileChunkDone(int64_t read_bytes, | 144 int64_t CompressorIOJavaScriptStream::ReadFileChunkDone(int64_t read_bytes, |
| 69 pp::VarArrayBuffer* array_buffer) { | 145 pp::VarArrayBuffer* array_buffer) { |
| 70 pthread_mutex_lock(&shared_state_lock_); | 146 pthread_mutex_lock(&shared_state_lock_); |
| 71 | 147 |
| 72 // JavaScript sets a negative value in read_bytes if an error occurred while | 148 // JavaScript sets a negative value in read_bytes if an error occurred while |
| 73 // reading a chunk. | 149 // reading a chunk. |
| 74 if (read_bytes >= 0) { | 150 if (read_bytes >= 0) { |
| 75 char* array_buffer_data = static_cast<char*>(array_buffer->Map()); | 151 char* array_buffer_data = static_cast<char*>(array_buffer->Map()); |
| 76 memcpy(destination_buffer_, array_buffer_data, read_bytes); | 152 memcpy(destination_buffer_, array_buffer_data, read_bytes); |
| 77 array_buffer->Unmap(); | 153 array_buffer->Unmap(); |
| 78 } | 154 } |
| 79 | 155 |
| 80 read_bytes_ = read_bytes; | 156 read_bytes_ = read_bytes; |
| 81 available_data_ = true; | 157 available_data_ = true; |
| 82 pthread_cond_signal(&available_data_cond_); | 158 pthread_cond_signal(&available_data_cond_); |
| 83 pthread_mutex_unlock(&shared_state_lock_); | 159 pthread_mutex_unlock(&shared_state_lock_); |
| 160 return read_bytes; | |
| 84 } | 161 } |
| OLD | NEW |