import {DataTypeEnum} from '../lang/DataTypeEnum'; import {Fatal} from '../lang/Fatal'; import {StringBuffer} from '../lang/StringBuffer'; import {DataViewer} from './DataViewer'; //========================================================== // 数据流基类。 // // @author maocy // @history 150105 //========================================================== export class DataStream extends DataViewer { // 数据视图 public viewer: DataView; // 位置 public position: number = 0; //========================================================== // 构造处理。 //========================================================== public constructor(memory?: any) { super(); // 设置属性 this.position = 0; } //========================================================== // 关联数据。 // // @param memory 内存 //========================================================== public link(data: any): void { // 获得缓冲 var buffer = null; var dataClass = data.constructor; if (dataClass == Array) { var inputData = new Uint8Array(data); buffer = inputData.buffer; } else if (dataClass == Uint8Array) { buffer = data.buffer; } else if (dataClass == ArrayBuffer) { buffer = data; } else { throw new Fatal(this, 'Unknown data type.'); } // 设置视图 this.viewer = new DataView(buffer); this.position = 0; } //========================================================== // 测试字符串。 // // @return 字符串 //========================================================== public testString(): string { var position = this.position; var length = this.viewer.getUint16(position, this.endianCd); position += 2; var result = new StringBuffer(); for (var i = 0; i < length; i++) { var value = this.viewer.getUint16(position, this.endianCd); position += 2; result.push(String.fromCharCode(value)); } return result.flush(); } //========================================================== // 读取布尔值。 // // @method // @return Boolean 布尔值 //========================================================== public readBoolean() { var value = this.viewer.getInt8(this.position); this.position++; return value > 0; } //========================================================== // 读取有8位有符号整数。 // // @method // @return Integer 8位有符号整数 //========================================================== public readInt8() { var value = this.viewer.getInt8(this.position); this.position++; return value; } //========================================================== // 读取有16位有符号整数。 // // @method // @return Integer 16位有符号整数 //========================================================== public readInt16() { var value = this.viewer.getInt16(this.position, this.endianCd); this.position += 2; return value; } //========================================================== // 读取有32位有符号整数。 // // @method // @return Integer 32位有符号整数 //========================================================== public readInt32() { var value = this.viewer.getInt32(this.position, this.endianCd); this.position += 4; return value; } //========================================================== // 读取有64位有符号整数。 // // @method // @return Integer 64位有符号整数 //========================================================== public readInt64() { var value1 = this.viewer.getInt32(this.position, this.endianCd); this.position += 4; var value2 = this.viewer.getInt32(this.position, this.endianCd); this.position += 4; return value2 << 32 + value1; } //========================================================== // 读取有8位无符号整数。 // // @method // @return Integer 8位无符号整数 //========================================================== public readUint8() { var value = this.viewer.getUint8(this.position); this.position += 1; return value; } //========================================================== // 读取有16位无符号整数。 // // @method // @return Integer 16位无符号整数 //========================================================== public readUint16() { var value = this.viewer.getUint16(this.position, this.endianCd); this.position += 2; return value; } //========================================================== // 读取有32位无符号整数。 // // @method // @return Integer 32位无符号整数 //========================================================== public readUint32() { var value = this.viewer.getUint32(this.position, this.endianCd); this.position += 4; return value; } //========================================================== // 读取有64位无符号整数。 // // @method // @return Integer 64位无符号整数 //========================================================== public readUint64() { var endianCd = this.endianCd; var value1 = this.viewer.getUint32(this.position, endianCd); this.position += 4; var value2 = this.viewer.getUint32(this.position, endianCd); this.position += 4; var value = 0; if (endianCd) { value = (value2 << 32) + value1; } else { value = (value1 << 32) + value2; } return value; } //========================================================== // 读取浮点数。 // // @method // @return Number 浮点数 //========================================================== public readFloat() { var value = this.viewer.getFloat32(this.position, this.endianCd); this.position += 4; return value; } //========================================================== // 读取双精度浮点数。 // // @method // @return Number 双精度浮点数 //========================================================== public readDouble() { var value = this.viewer.getFloat64(this.position, this.endianCd); this.position += 8; return value; } //========================================================== // 读取字符串。 // // @method // @return String 字符串 //========================================================== public readString() { var viewer = this.viewer; var endianCd = this.endianCd; var position = this.position; var length = viewer.getUint16(position, endianCd); position += 2; var value = new StringBuffer(); for (var i = 0; i < length; i++) { var character = viewer.getUint16(position, endianCd); value.push(String.fromCharCode(character)); position += 2; } this.position = position; return value.flush(); } //========================================================== // 读取字节数组。 // // @method // @param data:ArrayBuffer 数组 // @param offset:Integer 开始位置 // @param length:Integer 长度 // @return Integer 读取长度 //========================================================== public readBytes(data, offset, length) { var viewer = this.viewer; // 检查长度 if (length <= 0) { return; } // 暂时不支持开始位置选择 if (offset != 0) { throw new Fatal(this, 'Unsupport.'); } var position = this.position; var endianCd = this.endianCd; // 8字节复制 if (length % 8 == 0) { var array: any = new Float64Array(data); var count = length >> 3; for (var i = 0; i < count; i++) { array[i] = viewer.getFloat64(position, endianCd); position += 8; } this.position = position; return; } // 4字节复制 if (length % 4 == 0) { var array: any = new Uint32Array(data); var count = length >> 2; for (var i = 0; i < count; i++) { array[i] = viewer.getUint32(position, endianCd); position += 4; } this.position = position; return; } // 2字节复制 if (length % 2 == 0) { var array: any = new Uint16Array(data); var count = length >> 1; for (var i = 0; i < count; i++) { array[i] = viewer.getUint16(position, endianCd); position += 2; } this.position = position; return; } // 逐字节复制 var array: any = new Uint8Array(data); for (var i = 0; i < length; i++) { array[i] = viewer.getUint8(position++); } this.position = position; } //========================================================== // 读取类型数据。 // // @method // @param dataCd:EDataType 数据类型 // @return Object 数据 //========================================================== public readData(dataCd): any { switch (dataCd) { case DataTypeEnum.Int8: return this.readInt8(); case DataTypeEnum.Int16: return this.readInt16(); case DataTypeEnum.Int32: return this.readInt32(); case DataTypeEnum.Int64: return this.readInt64(); case DataTypeEnum.Uint8: return this.readUint8(); case DataTypeEnum.Uint16: return this.readUint16(); case DataTypeEnum.Uint32: return this.readUint32(); case DataTypeEnum.Uint64: return this.readUint64(); case DataTypeEnum.Float32: return this.readFloat(); case DataTypeEnum.Float64: return this.readDouble(); case DataTypeEnum.String: return this.readString(); } throw new Fatal(this, 'Unknown data cd. (data_cd={1})', dataCd); } //========================================================== // 写入布尔值。 // // @method // @return value:Boolean 布尔值 //========================================================== public writeBoolean(value) { this.viewer.setInt8(this.position, (value > 0) ? 1 : 0); this.position++; } //========================================================== // 写入8位有符号整数。 // // @method // @return value:Integer 8位有符号整数 //========================================================== public writeInt8(value) { this.viewer.setInt8(this.position, value); this.position++; } //========================================================== // 写入16位有符号整数。 // // @method // @return value:Integer 16位有符号整数 //========================================================== public writeInt16(value) { this.viewer.setInt16(this.position, value, this.endianCd); this.position += 2; } //========================================================== // 写入32位有符号整数。 // // @method // @return value:Integer 32位有符号整数 //========================================================== public writeInt32(value) { this.viewer.setInt32(this.position, value, this.endianCd); this.position += 4; } //========================================================== // 写入64位有符号整数。 // // @method // @return value:Integer 64位有符号整数 //========================================================== public writeInt64(value) { this.viewer.setInt32(this.position, value, this.endianCd); this.viewer.setInt32(this.position, value >> 32, this.endianCd); this.position += 8; } //========================================================== // 写入8位无符号整数。 // // @method // @return value:Integer 8位无符号整数 //========================================================== public writeUint8(value) { this.viewer.setUint8(this.position, value); this.position += 1; } //========================================================== // 写入16位无符号整数。 // // @method // @return value:Integer 16位无符号整数 //========================================================== public writeUint16(value) { this.viewer.setUint16(this.position, value, this.endianCd); this.position += 2; } //========================================================== // 写入32位无符号整数。 // // @method // @return value:Integer 32位无符号整数 //========================================================== public writeUint32(value) { this.viewer.setUint32(this.position, value, this.endianCd); this.position += 4; } //========================================================== // 写入64位无符号整数。 // // @method // @return value:Integer 64位无符号整数 //========================================================== public writeUint64(value) { this.viewer.setUint32(this.position, value, this.endianCd); this.viewer.setUint32(this.position, value >> 32, this.endianCd); this.position += 8; } //========================================================== // 写入浮点数。 // // @method // @return value:Number 浮点数 //========================================================== public writeFloat(value) { this.viewer.setFloat32(this.position, value, this.endianCd); this.position += 4; } //========================================================== // 写入双精度浮点数。 // // @method // @return value:Number 双精度浮点数 //========================================================== public writeDouble(value) { this.viewer.setFloat64(this.position, value, this.endianCd); this.position += 8; } //========================================================== // 写入字符串。 // // @method // @return value:String 字符串 //========================================================== public writeString(value) { var viewer: DataView = this.viewer; var length = value.length; var endianCd = this.endianCd; var position = this.position; viewer.setUint16(position, length, endianCd); position += 2; for (var i = 0; i < length; i++) { viewer.setUint16(position, value.charCodeAt(i), endianCd); position += 2; } this.position = position; } //========================================================== // 写入字节数组。 // // @method // @param data:ArrayBuffer 数组 // @param offset:Integer 开始位置 // @param length:Integer 长度 // @return Integer 读取长度 //========================================================== public writeBytes(data, offset, length) { var viewer = this.viewer; // 检查长度 if (length <= 0) { return; } // 暂时不支持开始位置选择 if (offset != 0) { throw new Fatal(this, 'Unsupport.'); } var position = this.position; var endianCd = this.endianCd; // 8字节复制 if (length % 8 == 0) { var array: any = new Float64Array(data); var count = length >> 3; for (var i = 0; i < count; i++) { viewer.setFloat64(position, array[i], endianCd); position += 8; } this.position = position; return; } // 4字节复制 if (length % 4 == 0) { var array: any = new Uint32Array(data); var count = length >> 2; for (var i = 0; i < count; i++) { viewer.setUint32(position, array[i], endianCd); position += 4; } this.position = position; return; } // 2字节复制 if (length % 2 == 0) { var array: any = new Uint16Array(data); var count = length >> 1; for (var i = 0; i < count; i++) { viewer.setUint16(position, array[i], endianCd); position += 2; } this.position = position; return; } // 逐字节复制 var array: any = new Uint8Array(data); for (var i = 0; i < length; i++) { viewer.setUint8(position++, array[i]); } this.position = position; } //========================================================== // 写入类型数据。 // // @method // @param dataCd:EDataType 数据类型 // @param value:Object 数据 //========================================================== public writeData(dataCd, value) { switch (dataCd) { case DataTypeEnum.Int8: return this.writeInt8(value); case DataTypeEnum.Int16: return this.writeInt16(value); case DataTypeEnum.Int32: return this.writeInt32(value); case DataTypeEnum.Int64: return this.writeInt64(value); case DataTypeEnum.Uint8: return this.writeUint8(value); case DataTypeEnum.Uint16: return this.writeUint16(value); case DataTypeEnum.Uint32: return this.writeUint32(value); case DataTypeEnum.Uint64: return this.writeUint64(value); case DataTypeEnum.Float32: return this.writeFloat(value); case DataTypeEnum.Float64: return this.writeDouble(value); case DataTypeEnum.String: return this.writeString(value); } throw new Fatal(this, 'Unknown data cd. (data_cd={1})', dataCd); } }