blob: a40afc366df3ea2bf213d4ea0a6427d1059493ab [file] [log] [blame]
// Copyright (c) 2017 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';
/**
* A general packet. Utilizes an offset to keep track of data being read/written.
*/
nassh.sftp.Packet = function(opt_packet) {
this.offset_ = 0;
this.packet_ = opt_packet || '';
};
/**
* Sets a uint8 at the current offset.
*/
nassh.sftp.Packet.prototype.setUint8 = function(uint8) {
this.packet_ += nassh.sftp.Packet.intToNByteArrayString(uint8, 1);
this.offset_ += 1;
};
/**
* Sets a uint32 at the current offset.
*/
nassh.sftp.Packet.prototype.setUint32 = function(uint32) {
this.packet_ += nassh.sftp.Packet.intToNByteArrayString(uint32, 4);
this.offset_ += 4;
};
/**
* Sets a uint64 at the current offset.
*/
nassh.sftp.Packet.prototype.setUint64 = function(uint64) {
this.packet_ += nassh.sftp.Packet.intToNByteArrayString(uint64, 8);
this.offset_ += 8;
};
/**
* Sets a string at the current offset.
*/
nassh.sftp.Packet.prototype.setString = function(string) {
var stringLength = string.length;
this.setUint32(stringLength); //sets strings length
this.packet_ += string;
this.offset_ += stringLength;
};
/**
* Sets data at the current offset.
*/
nassh.sftp.Packet.prototype.setData = function(data) {
this.packet_ += data;
this.offset_ += data.length;
};
/**
* Gets a uint8 from the current offset, if possible.
*/
nassh.sftp.Packet.prototype.getUint8 = function() {
if (this.offset_ + 1 > this.packet_.length) {
throw new Error('Packet too short to read a uint8');
}
var uint8 = this.packet_.charCodeAt(this.offset_);
this.offset_ += 1;
return uint8;
};
/**
* Gets a uint32 from the current offset, if possible.
*/
nassh.sftp.Packet.prototype.getUint32 = function() {
if (this.offset_ + 4 > this.packet_.length) {
throw new Error('Packet too short to read a uint32');
}
var uint32Slice = this.packet_.slice(this.offset_, this.offset_ + 4);
var uint32 = nassh.sftp.Packet.byteArrayStringToInt(uint32Slice);
this.offset_ += 4;
return uint32;
};
/**
* Gets a uint64 from the current offset, if possible.
*/
nassh.sftp.Packet.prototype.getUint64 = function() {
if (this.offset_ + 8 > this.packet_.length) {
throw new Error('Packet too short to read a uint64');
}
var uint64Slice = this.packet_.slice(this.offset_, this.offset_ + 8);
var uint64 = nassh.sftp.Packet.byteArrayStringToInt(uint64Slice);
this.offset_ += 8;
return uint64;
};
/**
* Gets a string from the current offset, if possible.
*/
nassh.sftp.Packet.prototype.getString = function() {
var stringLength = this.getUint32();
if (this.offset_ + stringLength > this.packet_.length) {
throw new Error('Packet too short to read a string');
}
var string = this.packet_.substr(this.offset_, stringLength);
this.offset_ += stringLength;
return string;
};
/**
* Gets the remaining data from the packet at the current offset.
*/
nassh.sftp.Packet.prototype.getData = function() {
var data = this.packet_.substr(this.offset_);
this.offset_ += data.length;
return data;
};
/**
* Slices the packet from beginSlice to the optional endSlice (else end of
* packet).
*/
nassh.sftp.Packet.prototype.slice = function(beginSlice, opt_endSlice) {
var endSlice = opt_endSlice || this.packet_.length;
this.packet_ = this.packet_.slice(beginSlice, endSlice);
};
/**
* Returns the toString representation of the packet.
*/
nassh.sftp.Packet.prototype.toString = function() {
return this.packet_;
};
/**
* Returns the byteArray representation of the packet.
*/
nassh.sftp.Packet.prototype.toByteArray = function() {
var array = new Uint8Array(this.packet_.length);
for (var i = 0; i < array.length; i++) {
array[i] = this.packet_.charCodeAt(i);
}
return array;
};
/**
* Returns the length of the packet.
*/
nassh.sftp.Packet.prototype.getLength = function() {
return this.packet_.length;
};
/**
* Converts a byte array string to an int
*/
nassh.sftp.Packet.byteArrayStringToInt = function(byteArray) {
var int = 0;
// converts the byte array into its int form
for (var i = 0; i < byteArray.length; i++) {
int = (int * 256) + byteArray.charCodeAt(i);
}
if (int > Number.MAX_SAFE_INTEGER) {
throw new RangeError('get int failed: int is too large to represent exactly'
+ '(was greater than 2^53-1)');
}
return int;
};
/**
* Converts an int to an n byte array string.
*/
nassh.sftp.Packet.intToNByteArrayString = function(int, n) {
var byteArray = [];
// creates a n byte long array
for (var i = 0; i < n; i++) {
byteArray.push(0);
}
// converts the int into its byte array form
for (var i = n-1; i >= 0; i--) {
var byte = int & 0xff;
byteArray[i] = byte;
int = (int - byte) / 256;
}
// return the byte array represented as a string
return String.fromCharCode.apply(String, byteArray);
};