-
Notifications
You must be signed in to change notification settings - Fork 14
/
Copy pathindex.js
81 lines (75 loc) · 2.21 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
import { createDecoder } from './decoder.js';
function dbfHeader(data) {
var out = {};
out.lastUpdated = new Date(data.getUint8(1) + 1900, data.getUint8(2), data.getUint8(3));
out.records = data.getUint32(4, true);
out.headerLen = data.getUint16(8, true);
out.recLen = data.getUint16(10, true);
return out;
}
function dbfRowHeader(data, headerLen, decoder) {
var out = [];
var offset = 32;
while (offset < headerLen) {
out.push({
name: decoder(new Uint8Array(data.buffer.slice(data.byteOffset + offset, data.byteOffset + offset + 11))),
dataType: String.fromCharCode(data.getUint8(offset + 11)),
len: data.getUint8(offset + 16),
decimal: data.getUint8(offset + 17)
});
if (data.getUint8(offset + 32) === 13) {
break;
} else {
offset += 32;
}
}
return out;
}
function rowFuncs(buffer, offset, len, type, decoder) {
const data = new Uint8Array(buffer.buffer.slice(buffer.byteOffset + offset, buffer.byteOffset + offset + len));
var textData = decoder(data);
switch (type) {
case 'N':
case 'F':
case 'O':
return parseFloat(textData, 10);
case 'D':
return new Date(textData.slice(0, 4), parseInt(textData.slice(4, 6), 10) - 1, textData.slice(6, 8));
case 'L':
return textData.toLowerCase() === 'y' || textData.toLowerCase() === 't';
default:
return textData;
}
}
function parseRow(buffer, offset, rowHeaders, decoder) {
var out = {};
var i = 0;
var len = rowHeaders.length;
var field;
var header;
while (i < len) {
header = rowHeaders[i];
field = rowFuncs(buffer, offset, header.len, header.dataType, decoder);
offset += header.len;
if (typeof field !== 'undefined') {
out[header.name] = field;
}
i++;
}
return out;
}
export default function (buffer, encoding) {
var decoder = createDecoder(encoding);
var header = dbfHeader(buffer);
var rowHeaders = dbfRowHeader(buffer, header.headerLen - 1, decoder);
var offset = ((rowHeaders.length + 1) << 5) + 2;
var recLen = header.recLen;
var records = header.records;
var out = [];
while (records) {
out.push(parseRow(buffer, offset, rowHeaders, decoder));
offset += recLen;
records--;
}
return out;
}