-
-
Notifications
You must be signed in to change notification settings - Fork 26
/
volume_reader_javascript_stream.h
122 lines (96 loc) · 5.43 KB
/
volume_reader_javascript_stream.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
// 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.
#ifndef VOLUME_READER_JAVSCRIPT_STREAM_H_
#define VOLUME_READER_JAVSCRIPT_STREAM_H_
#include <pthread.h>
#include "archive.h"
#include "ppapi/cpp/var_array_buffer.h"
#include "javascript_requestor_interface.h"
#include "volume_reader.h"
// A VolumeReader that reads the content of the volume's archive from
// JavaScript. All methods including the constructor and destructor should be
// called from the same thread with the exception of SetBufferAndSignal and
// ReadErrorSignal which MUST be called from another thread.
class VolumeReaderJavaScriptStream : public VolumeReader {
public:
// archive_size is used by Seek method in order to seek from volume's
// archive end.
// requestor is used to request more data from JavaScript.
VolumeReaderJavaScriptStream(int64_t archive_size,
JavaScriptRequestorInterface* requestor);
virtual ~VolumeReaderJavaScriptStream();
// Sets the internal array buffer used for reads and signal the blocked
// VolumeReaderJavaScriptStream::Read to continue execution. Must be done in
// a different thread from VolumeReaderJavaScriptStream::Read method.
// read_offset represents the offset from which VolumeReaderJavaScriptStream
// requested a chunk read from JavaScriptRequestorInterface. May block for a
// few cycles in order to synchronize with VolumeReaderJavaScriptStream::Read.
void SetBufferAndSignal(const pp::VarArrayBuffer& array_buffer,
int64_t read_offset);
// Signal the blocked VolumeReaderJavaScriptStream::Read to continue execution
// and return an error code. Must be called from a different thread than
// VolumeReaderJavaScriptStream::Read. May block for a few cycles in order
// to synchronize with VolumeReaderJavaScriptStream::Read.
void ReadErrorSignal();
// Sets the passphrase and signals the blocked Passphrase() to continue
// execution. Must be done in a different thread from Passphrase() method.
// Reporting an error is not supported. Returning an empty string indicates
// an error.
void SetPassphraseAndSignal(const std::string& passphrase);
// Signal the blocked VolumeReaderJavaScriptStream::Passphrase to continue
// execution and return an error code. Must be called from a different thread
// than VolumeReaderJavaScriptStream::Passphrase. May block for a few cycles
// in order to synchronize with VolumeReaderJavaScriptStream::Passphrase.
void PassphraseErrorSignal();
// See volume_reader.h for description. This method blocks on
// available_data_cond_. SetBufferAndSignal should unblock it from another
// thread.
virtual int64_t Read(int64_t bytes_to_read, const void** destination_buffer);
// See volume_reader.h for description.
virtual int64_t Skip(int64_t bytes_to_skip);
// See volume_reader.h for description.
virtual int64_t Seek(int64_t offset, int whence);
// Sets the request Id to be used by the reader.
void SetRequestId(const std::string& request_id);
// See volume_reader.h for description. The method blocks on
// available_passphrase_cond_. SetPassphraseAndSignal should unblock it from
// another thread.
virtual const char* Passphrase();
int64_t offset() const { return offset_; }
private:
// Request a chunk of length number of bytes from JavaScript starting from
// offset_ member. Should be run within a lock.
void RequestChunk(int64_t length);
std::string request_id_; // The request id for which the reader was
// created.
const int64_t archive_size_; // The archive size.
// A requestor that makes calls to JavaScript to obtain file chunks.
JavaScriptRequestorInterface* requestor_;
bool available_data_; // Indicates whether any data is available.
bool read_error_; // Marks an error in reading from JavaScript.
std::string available_passphrase_; // Stores a passphrase from JavaScript.
bool passphrase_error_; // Marks an error in getting the passphrase.
// Must use POSIX mutexes instead of pp::Lock because there is no pp::Cond.
// pp::Lock uses POSIX mutexes anyway on Linux, but pp::Lock can also pe used
// on other operating systems as Windows. For now this is not an issue as this
// extension is used only on Chromebooks. The shared_state_lock_ is used to
// protect members which are accessed by more than one thread.
pthread_mutex_t shared_state_lock_;
pthread_cond_t available_data_cond_;
pthread_cond_t available_passphrase_cond_;
int64_t offset_; // The offset from where read should be done.
int64_t last_read_chunk_offset_; // The offset reached after last call to
// VolumeReaderJavaScriptStream::Read.
// Two buffers used to store the actual data used by libarchive and the data
// read ahead.
pp::VarArrayBuffer first_array_buffer_;
pp::VarArrayBuffer second_array_buffer_;
// A pointer to first_arrray_buffer_ or second_array_buffer_. This is used in
// order to avoid an extra copy from the second buffer to the first buffer
// when data is available for VolumeReaderJavaScriptStream::Read method.
// It points to the array buffer used for reading ahead when data is received
// from JavaScript at VolumeReaderJavaScriptStream::SetBufferAndSignal.
pp::VarArrayBuffer* read_ahead_array_buffer_ptr_;
};
#endif // VOLUME_READER_JAVSCRIPT_STREAM_H_