UNPKG

aux-dbf

Version:

DBF for price PSM

132 lines (118 loc) 4.23 kB
import { DBFReader } from "./DBFReader"; import { DBF_MODE } from "./DBF_MODE"; import { Column, COLUMN_TYPE } from "./Column"; const iconv = require("iconv-lite"); export class DBF4Reader extends DBFReader { protected sizeFieldDescriptior = 32; protected sizeHeadLength = 32; readHeader() { this.TypeTable = this.file.readInt8(0); this.DateHeaderY = this.file.readInt8(1) - 100 + 2000; this.DateHeaderM = this.file.readInt8(2); this.DateHeaderD = this.file.readInt8(3) % 31; this.RecordsCount = this.file.readInt32LE(4); this.HeaderSize = this.file.readInt16LE(8); this.RecordSize = this.file.readInt16LE(10); this.Encode = this.file.readInt8(29); this.ColumnCount = (this.HeaderSize - this.sizeHeadLength - 1) / this.sizeFieldDescriptior; if (this.mode == DBF_MODE.TEST) { this.printHeader(); } } readSignature() { this.columns = Array(this.ColumnCount) .fill(new Column()) .map<Column>((_) => new Column()) .map<Column>((column, index) => { let offset = index * this.sizeHeadLength + this.sizeFieldDescriptior; let name = this.file .slice(offset, offset + 10) .filter((r) => r != 0) .toString(); let size = this.file.readUInt8(offset + 16); let type = this.readChar(offset + 11) as COLUMN_TYPE; let decimalPlaces = this.file.readUInt8(offset + 17); let isMDX = this.file.readUInt8(offset + 31).toString() != "0"; column.Add(name, size, type, index, decimalPlaces, isMDX); return column; }); if (this.mode == DBF_MODE.TEST) { this.printColumns(); } } readTable(): any[][] { console.time("READ DATA SOURCE"); let array = Array(this.RecordsCount) .fill(new Array(this.ColumnCount).fill(null)) .map((r) => { return new Array(this.ColumnCount); }); const startPosition = this.HeaderSize; let offsetLeft = 0; for (let column = 0; column < this.ColumnCount; column++) { let position = startPosition + 1; if (this.columns[column].getType() == COLUMN_TYPE.CHARACTER) { let size = this.columns[column].getSize(); for (let row = 0; row < this.RecordsCount; row++) { // TODO array[row][column] = //iconv.decode( this.file.subarray( position + offsetLeft, position + offsetLeft + size ); //, "win1251" ).trim(); position += this.RecordSize; } } else if (this.columns[column].getType() == COLUMN_TYPE.NUMBER) { let size = this.columns[column].getSize(); for (let row = 0; row < this.RecordsCount; row++) { array[row][column] = +this.file.toString( "ascii", position + offsetLeft, position + offsetLeft + size ); position += this.RecordSize; } } else if (this.columns[column].getType() == COLUMN_TYPE.FLOAT) { let size = this.columns[column].getSize(); for (let row = 0; row < this.RecordsCount; row++) { array[row][column] = +this.file.toString( "ascii", position + offsetLeft, position + offsetLeft + size ); position += this.RecordSize; } } else if (this.columns[column].getType() == COLUMN_TYPE.DATE) { for (let row = 0; row < this.RecordsCount; row++) { array[row][column] = this.readDate( this.file.subarray(position + offsetLeft, position + offsetLeft + 8) ); let p = position + offsetLeft; position += this.RecordSize; } } else { throw new Error("[X] Непредсказуемый тип колонки"); } offsetLeft += this.columns[column].getSize(); } console.timeEnd("READ DATA SOURCE"); return array; } private readDate(buffer: Buffer) { let date = ( buffer.toString("ascii", 0, 4) + "-" + buffer.toString("ascii", 4, 6) + "-" + buffer.toString("ascii", 6, 8) ); if(/(\d{4}-\d{2}-\d{2})/.test(date)) { return date; } else { return "0000-00-00"; } } }