UNPKG

aux-dbf

Version:

DBF for price PSM

147 lines (118 loc) 5.24 kB
import { DBFReader } from "./DBFReader"; import { DBF_MODE } from "./DBF_MODE"; import { LanguageDBF7 } from "./LanguageDBF7"; import { Column, COLUMN_TYPE } from "./Column"; const iconv = require("iconv-lite"); export class DBF7Reader extends DBFReader { protected sizeFieldDescriptior = 68; protected sizeHeadLength = 48; 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 .subarray(32, 63) .filter((r) => r != 0) .toString(); // -1 - это байт окончания заголовка this.ColumnCount = (this.HeaderSize - this.sizeFieldDescriptior - 1) / this.sizeHeadLength; 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 .subarray(offset, offset + 31) .filter((r) => r != 0) .toString(); let type = this.readChar(offset + 32) as COLUMN_TYPE; let size = this.file.readUInt8(offset + 33); let decimalPlaces = this.file.readUInt8(offset + 34); let isMDX = this.file.readUInt8(offset + 37).toString() != "0"; column.Add(name, size, type, index, decimalPlaces, isMDX); return column; }); if (this.mode == DBF_MODE.TEST) { this.printColumns(); } } printHeader() { super.printHeader(); let lan = LanguageDBF7.find((r) => { return r.innerName == (this.Encode as string); }); if(!lan) return console.log("[X] Driver language is not Defined"); console.log(`[*] Driver language: '${this.Encode}' ${lan.fullName} | ${lan.voc}`); console.log(""); } readTable(): any[][] { console.time("READ DATA SOURCE"); let array = new 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.DOUBLE) { for(let row = 0; row < this.RecordsCount; row++) { array[row][column] = this.readIEEE754(this.file.subarray(position + offsetLeft, position + offsetLeft + 8)); position += this.RecordSize; } } else 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(); // array[row][column] =this.file.subarray(position + offsetLeft, position + offsetLeft + size); position += this.RecordSize; } } else if(this.columns[column].getType() == COLUMN_TYPE.INTEGER) { for(let row = 0; row < this.RecordsCount; row++) { array[row][column] = this.file.readUInt32BE(position + offsetLeft) & (~0x80000000); position += this.RecordSize; } } else if(this.columns[column].getType() == COLUMN_TYPE.LOGICAL) { for(let row = 0; row < this.RecordsCount; row++) { let logicalValue = this.file.readUInt8(position + offsetLeft); array[row][column] = (logicalValue == 1 || logicalValue == 0x54 || logicalValue == 0x74 || logicalValue == 0x59 || logicalValue == 0x79 ); 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) { return buffer.toString("ascii", 0 ,4) + "-"+buffer.toString("ascii", 4 ,6 )+ "-"+buffer.toString("ascii", 6 ,8 ); } private readIEEE754(buffer: Buffer) { return -buffer.readDoubleBE(0); } private t8(position) { return this.file.readUInt8(position).toString(16).padStart(2,"0") } }