UNPKG

dbf

Version:
105 lines (89 loc) 3.05 kB
var fieldSize = require('./fieldsize'), lib = require('./lib'), fields = require('./fields'); /** * @param {Array} data * @param {Array} meta * @returns {Object} view */ module.exports = function structure(data, meta) { var field_meta = meta || fields.multi(data), fieldDescLength = (32 * field_meta.length) + 1, bytesPerRecord = fields.bytesPer(field_meta), // deleted flag buffer = new ArrayBuffer( // field header fieldDescLength + // header 32 + // contents (bytesPerRecord * data.length) + // EOF marker 1 ), now = new Date(), view = new DataView(buffer); // version number - dBase III view.setUint8(0, 0x03); // date of last update view.setUint8(1, now.getFullYear() - 1900); view.setUint8(2, now.getMonth() + 1); view.setUint8(3, now.getDate()); // number of records view.setUint32(4, data.length, true); // length of header var headerLength = fieldDescLength + 32; view.setUint16(8, headerLength, true); // length of each record view.setUint16(10, bytesPerRecord, true); // Terminator view.setInt8(32 + fieldDescLength - 1, 0x0D); field_meta.forEach(function(f, i) { // field name f.name.split('').slice(0, 10).forEach(function(c, x) { view.setInt8(32 + i * 32 + x, c.charCodeAt(0)); }); // field type view.setInt8(32 + i * 32 + 11, f.type.charCodeAt(0)); // field length view.setInt8(32 + i * 32 + 16, f.size); if (f.type == 'N') view.setInt8(32 + i * 32 + 17, 3); }); var offset = fieldDescLength + 32; data.forEach(function(row, num) { // delete flag: this is not deleted view.setUint8(offset, 32); offset++; field_meta.forEach(function(f) { var val = row[f.name]; if (val === null || typeof val === 'undefined') val = ''; switch (f.type) { // boolean case 'L': view.setUint8(offset, val ? 84 : 70); offset++; break; // date case 'D': offset = lib.writeField(view, 8, lib.lpad(val.toString(), 8, ' '), offset); break; // number case 'N': offset = lib.writeField(view, f.size, lib.lpad(val.toString(), f.size, ' ').substr(0, 18), offset); break; // string case 'C': offset = lib.writeField(view, f.size, lib.rpad(val.toString(), f.size, ' '), offset); break; default: throw new Error('Unknown field type'); } }); }); // EOF flag view.setUint8(offset, 0x1A); return view; };