blob: b0dcb001e7df4364deaac91e8b70eafac226f796 [file] [log] [blame]
// 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.
'use strict';
/**
* Defines the protocol used to communicate between JS and NaCL.
* This should be consistent with cpp/request.h.
* @namespace
*/
unpacker.request = {
/**
* Defines request ids. Every key should be unique and the same as the keys
* on the NaCL side.
* @enum {string}
*/
Key: {
// Mandatory keys for all unpacking operations.
OPERATION: 'operation', // Should be a unpacker.request.Operation.
FILE_SYSTEM_ID: 'file_system_id', // Should be a string.
REQUEST_ID: 'request_id', // Should be a string.
// Optional keys unique to unpacking operations.
METADATA: 'metadata', // Should be a dictionary.
ARCHIVE_SIZE: 'archive_size', // Should be a string as only int is
// supported by pp::Var on C++.
INDEX: 'index', // Should be a string. Same reason as ARCHIVE_SIZE.
ENCODING: 'encoding', // Should be a string.
OPEN_REQUEST_ID: 'open_request_id', // Should be a string, just like
// REQUEST_ID.
READ_FILE_DATA: 'read_file_data', // Should be an ArrayBuffer.
HAS_MORE_DATA: 'has_more_data', // Should be a boolean.
PASSPHRASE: 'passphrase', // Should be a string.
// Mandatory keys for all packing operations.
COMPRESSOR_ID: 'compressor_id', // Should be an int.
// Optional keys unique to packing operations.
ENTRY_ID: 'entry_id', // Should be an int.
PATHNAME: 'pathname', // should be a string.
FILE_SIZE: 'file_size', // should be a string. Same reason
// as ARCHIVE_SIZE.
IS_DIRECTORY: 'is_directory', // should be a boolean.
MODIFICATION_TIME: 'modification_time', // should be a string.
// (mm/dd/yy h:m:s)
HAS_ERROR: 'has_error', // Should be a boolean Sent from JS
// to NaCL.
// Optional keys used for both packing and unpacking operations.
ERROR: 'error', // Should be a string.
CHUNK_BUFFER: 'chunk_buffer', // Should be an ArrayBuffer.
OFFSET: 'offset', // Should be a string. Same reason as ARCHIVE_SIZE.
LENGTH: 'length', // Should be a string. Same reason as ARCHIVE_SIZE.
SRC_FILE: 'src_file', // Should be a string.
SRC_LINE: 'src_line', // Should be a int.
SRC_FUNC: 'src_func', // Should be a string.
MESSAGE: 'message', // Should be a string.
},
/**
* Defines request operations. These operation should be the same as the
* operations on the NaCL side. FILE_SYSTEM_ID and REQUEST_ID are mandatory
* for all unpack requests, while COMPRESSOR_ID is required for all pack
* requests. All the values of unpacking operations must be smaller than any
* packing operation (except errors).
* @enum {number}
*/
Operation: {
READ_METADATA: 0,
READ_METADATA_DONE: 1,
READ_CHUNK: 2,
READ_CHUNK_DONE: 3,
READ_CHUNK_ERROR: 4,
READ_PASSPHRASE: 5,
READ_PASSPHRASE_DONE: 6,
READ_PASSPHRASE_ERROR: 7,
CLOSE_VOLUME: 8,
OPEN_FILE: 9,
OPEN_FILE_DONE: 10,
CLOSE_FILE: 11,
CLOSE_FILE_DONE: 12,
READ_FILE: 13,
READ_FILE_DONE: 14,
CONSOLE_LOG: 15,
CONSOLE_DEBUG: 16,
CREATE_ARCHIVE: 17,
CREATE_ARCHIVE_DONE: 18,
ADD_TO_ARCHIVE: 19,
ADD_TO_ARCHIVE_DONE: 20,
READ_FILE_CHUNK: 21,
READ_FILE_CHUNK_DONE: 22,
WRITE_CHUNK: 23,
WRITE_CHUNK_DONE: 24,
CLOSE_ARCHIVE: 25,
CLOSE_ARCHIVE_DONE: 26,
FILE_SYSTEM_ERROR: -1,
COMPRESSOR_ERROR: -2
},
/**
* Operations greater than or equal to this value are for packing.
* @const {number}
*/
MINIMUM_PACK_REQUEST_VALUE: 17,
/**
* Return true if the given operation is related to packing.
* @param {!unpacker.request.Operation} operation
* @return {boolean}
*/
isPackRequest: function(operation) {
return unpacker.request.MINIMUM_PACK_REQUEST_VALUE <= operation ||
operation == unpacker.request.Operation.COMPRESSOR_ERROR;
},
/**
* Creates a basic request with mandatory fields.
* @param {!unpacker.request.Operation} operation
* @param {!unpacker.types.FileSystemId} fileSystemId
* @param {!unpacker.types.RequestId} requestId The request id. Should be
* unique only per file system.
* @private
* @return {!Object} A new request with mandatory fields.
*/
createBasic_: function(operation, fileSystemId, requestId) {
var basicRequest = {};
basicRequest[unpacker.request.Key.OPERATION] = operation;
basicRequest[unpacker.request.Key.FILE_SYSTEM_ID] = fileSystemId;
basicRequest[unpacker.request.Key.REQUEST_ID] = requestId.toString();
return basicRequest;
},
/**
* Creates a read metadata request.
* @param {!unpacker.types.FileSystemId} fileSystemId
* @param {!unpacker.types.RequestId} requestId
* @param {string} encoding Default encoding for the archive.
* @param {number} archiveSize The size of the archive for fileSystemId.
* @return {!Object} A read metadata request.
*/
createReadMetadataRequest: function(fileSystemId, requestId, encoding,
archiveSize) {
var readMetadataRequest = unpacker.request.createBasic_(
unpacker.request.Operation.READ_METADATA, fileSystemId, requestId);
readMetadataRequest[unpacker.request.Key.ENCODING] = encoding;
readMetadataRequest[unpacker.request.Key.ARCHIVE_SIZE] =
archiveSize.toString();
return readMetadataRequest;
},
/**
* Creates a read chunk done response. This is a response to a READ_CHUNK
* request from NaCl.
* @param {!unpacker.types.FileSystemId} fileSystemId
* @param {!unpacker.types.RequestId} requestId
* @param {!ArrayBuffer} buffer A buffer containing the data that was read.
* @param {number} readOffset The offset from where buffer starts. This is
* required for distinguishing multiple read chunk requests done in
* parallel for different offsets.
* @return {!Object} A read chunk done response.
*/
createReadChunkDoneResponse: function(fileSystemId, requestId, buffer,
readOffset) {
var response = unpacker.request.createBasic_(
unpacker.request.Operation.READ_CHUNK_DONE, fileSystemId, requestId);
response[unpacker.request.Key.CHUNK_BUFFER] = buffer;
response[unpacker.request.Key.OFFSET] = readOffset.toString();
return response;
},
/**
* Creates a read chunk error response. This is a response to a READ_CHUNK
* request from NaCl in case of any errors in order for NaCl to cleanup
* resources.
* @param {!unpacker.types.FileSystemId} fileSystemId
* @param {!unpacker.types.RequestId} requestId
* @return {!Object} A read chunk error response.
*/
createReadChunkErrorResponse: function(fileSystemId, requestId) {
return unpacker.request.createBasic_(
unpacker.request.Operation.READ_CHUNK_ERROR, fileSystemId, requestId);
},
/**
* Creates a read passphrase done response. This is a response to a
* READ_PASSPHRASE request from NaCl.
* @param {!unpacker.types.FileSystemId} fileSystemId
* @param {!unpacker.types.RequestId} requestId
* @param {string} passphrase The passphrase.
* @return {!Object} A read passphrase done response.
*/
createReadPassphraseDoneResponse: function(fileSystemId, requestId,
passphrase) {
var response = unpacker.request.createBasic_(
unpacker.request.Operation.READ_PASSPHRASE_DONE, fileSystemId,
requestId);
response[unpacker.request.Key.PASSPHRASE] = passphrase;
return response;
},
/**
* Creates a read passphrase error response. This is a response to a
* READ_PASSPHRASE request from NaCl in case of any errors in order for NaCl
* to cleanup resources.
* @param {!unpacker.types.FileSystemId} fileSystemId
* @param {!unpacker.types.RequestId} requestId
* @return {!Object} A read passphrase error response.
*/
createReadPassphraseErrorResponse: function(fileSystemId, requestId) {
return unpacker.request.createBasic_(
unpacker.request.Operation.READ_PASSPHRASE_ERROR, fileSystemId,
requestId);
},
/**
* Creates a request to close a volume related to a fileSystemId.
* Can be called after any request.
* @param {!unpacker.types.FileSystemId} fileSystemId
* @return {!Object} A close volume request.
*/
createCloseVolumeRequest: function(fileSystemId) {
return unpacker.request.createBasic_(
unpacker.request.Operation.CLOSE_VOLUME, fileSystemId, -1);
},
/**
* Creates an open file request.
* @param {!unpacker.types.FileSystemId} fileSystemId
* @param {number} index The index of the file in the header list.
* @param {string} encoding Default encoding for the archive.
* @param {number} archiveSize The size of the volume's archive.
* @return {!Object} An open file request.
*/
createOpenFileRequest: function(fileSystemId, requestId, index, encoding,
archiveSize) {
var openFileRequest = unpacker.request.createBasic_(
unpacker.request.Operation.OPEN_FILE, fileSystemId, requestId);
openFileRequest[unpacker.request.Key.INDEX] = index.toString();
openFileRequest[unpacker.request.Key.ENCODING] = encoding;
openFileRequest[unpacker.request.Key.ARCHIVE_SIZE] = archiveSize.toString();
return openFileRequest;
},
/**
* Creates a close file request.
* @param {!unpacker.types.FileSystemId} fileSystemId
* @param {!unpacker.types.RequestId} requestId
* @param {!unpacker.types.RequestId} openRequestId
* @return {!Object} A close file request.
*/
createCloseFileRequest: function(fileSystemId, requestId, openRequestId) {
var closeFileRequest = unpacker.request.createBasic_(
unpacker.request.Operation.CLOSE_FILE, fileSystemId, requestId);
closeFileRequest[unpacker.request.Key.OPEN_REQUEST_ID] =
openRequestId.toString();
return closeFileRequest;
},
/**
* Creates a read file request.
* @param {!unpacker.types.FileSystemId} fileSystemId
* @param {!unpacker.types.RequestId} requestId
* @param {!unpacker.types.RequestId} openRequestId
* @param {number} offset The offset from where read is done.
* @param {number} length The number of bytes required.
* @return {!Object} A read file request.
*/
createReadFileRequest: function(fileSystemId, requestId, openRequestId,
offset, length) {
var readFileRequest = unpacker.request.createBasic_(
unpacker.request.Operation.READ_FILE, fileSystemId, requestId);
readFileRequest[unpacker.request.Key.OPEN_REQUEST_ID] =
openRequestId.toString();
readFileRequest[unpacker.request.Key.OFFSET] = offset.toString();
readFileRequest[unpacker.request.Key.LENGTH] = length.toString();
return readFileRequest;
},
/**
* Creates a create archive request for compressor.
* @param {!unpacker.types.CompressorId} compressorId
* @return {!Object} A create archive request.
*/
createCreateArchiveRequest: function(compressorId) {
var request = {};
request[unpacker.request.Key.OPERATION] =
unpacker.request.Operation.CREATE_ARCHIVE;
request[unpacker.request.Key.COMPRESSOR_ID] = compressorId;
return request;
},
/**
* Creates an add to archive request for compressor.
* @param {!unpacker.types.CompressorId} compressorId
* @param {!unpacker.types.EntryId} entryId
* @param {string} pathname The relative path of the entry.
* @param {number} fileSize The size of the entry.
* @param {string} modificationTime The modification time of the entry.
* @param {boolean} isDirectory Whether the entry is a directory or not.
* @return {!Object} An add to archive request.
*/
createAddToArchiveRequest: function(compressorId, entryId, pathname,
fileSize, modificationTime, isDirectory) {
var request = {};
request[unpacker.request.Key.OPERATION] =
unpacker.request.Operation.ADD_TO_ARCHIVE;
request[unpacker.request.Key.COMPRESSOR_ID] = compressorId;
request[unpacker.request.Key.ENTRY_ID] = entryId;
request[unpacker.request.Key.PATHNAME] = pathname.toString();
request[unpacker.request.Key.FILE_SIZE] = fileSize.toString();
request[unpacker.request.Key.MODIFICATION_TIME] =
modificationTime.toString();
request[unpacker.request.Key.IS_DIRECTORY] = isDirectory;
return request;
},
/**
* Creates a read file chunk response for compressor.
* @param {!unpacker.types.CompressorId} compressorId
* @param {number} length The number of bytes read from the entry.
* @param {!ArrayBuffer} buffer A buffer containing the data that was read.
* @return {!Object} A read file chunk done response.
*/
createReadFileChunkDoneResponse: function(compressorId, length, buffer) {
var response = {};
response[unpacker.request.Key.OPERATION] =
unpacker.request.Operation.READ_FILE_CHUNK_DONE;
response[unpacker.request.Key.COMPRESSOR_ID] = compressorId;
response[unpacker.request.Key.LENGTH] = length.toString();
response[unpacker.request.Key.CHUNK_BUFFER] = buffer;
return response;
},
/**
* Creates a write chunk done response for compressor.
* @param {!unpacker.types.CompressorId} compressorId
* @param {number} length The number of bytes written onto the archive file.
* @return {!Object} A write chunk done response.
*/
createWriteChunkDoneResponse: function(compressorId, length) {
var response = {};
response[unpacker.request.Key.OPERATION] =
unpacker.request.Operation.WRITE_CHUNK_DONE;
response[unpacker.request.Key.COMPRESSOR_ID] = compressorId;
response[unpacker.request.Key.LENGTH] = length.toString();
return response;
},
/**
* Creates a close archive request for compressor.
* @param {!unpacker.types.CompressorId} compressorId
* @param {boolean} hasError True if some error occurred.
* @return {!Object} A close archive request.
*/
createCloseArchiveRequest: function(compressorId, hasError) {
var request = {};
request[unpacker.request.Key.OPERATION] =
unpacker.request.Operation.CLOSE_ARCHIVE;
request[unpacker.request.Key.COMPRESSOR_ID] = compressorId;
request[unpacker.request.Key.HAS_ERROR] = hasError;
return request;
}
};