aux-dbf
Version:
DBF for price PSM
147 lines (118 loc) • 5.24 kB
text/typescript
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")
}
}