diff --git a/Cakefile b/Cakefile index fe0d5a8..31e804a 100644 --- a/Cakefile +++ b/Cakefile @@ -1,10 +1,10 @@ fs = require 'fs' {print} = require 'sys' -{spawn} = require 'child_process' +{exec} = require 'child_process' build = (callback) -> - coffee = spawn 'coffee', ['-c', '-o', 'lib', 'src'] + coffee = exec 'coffee -c -o lib src' coffee.stderr.on 'data', (data) -> process.stderr.write data.toString() coffee.stdout.on 'data', (data) -> diff --git a/lib/header.js b/lib/header.js index 57438e5..23637a5 100644 --- a/lib/header.js +++ b/lib/header.js @@ -1,4 +1,4 @@ -// Generated by CoffeeScript 1.3.3 +// Generated by CoffeeScript 1.7.1 (function() { var Header, fs, __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }; @@ -6,38 +6,36 @@ fs = require('fs'); Header = (function() { - function Header(filename) { this.filename = filename; this.parseFieldSubRecord = __bind(this.parseFieldSubRecord, this); - this.parseDate = __bind(this.parseDate, this); - return this; } Header.prototype.parse = function(callback) { - var _this = this; - return fs.readFile(this.filename, function(err, buffer) { - var i; - if (err) { - throw err; - } - _this.type = (buffer.slice(0, 1)).toString('utf-8'); - _this.dateUpdated = _this.parseDate(buffer.slice(1, 4)); - _this.numberOfRecords = _this.convertBinaryToInteger(buffer.slice(4, 8)); - _this.start = _this.convertBinaryToInteger(buffer.slice(8, 10)); - _this.recordLength = _this.convertBinaryToInteger(buffer.slice(10, 12)); - _this.fields = ((function() { - var _i, _ref, _results; - _results = []; - for (i = _i = 32, _ref = this.start - 32; _i <= _ref; i = _i += 32) { - _results.push(buffer.slice(i, i + 32)); + return fs.readFile(this.filename, (function(_this) { + return function(err, buffer) { + var i; + if (err) { + throw err; } - return _results; - }).call(_this)).map(_this.parseFieldSubRecord); - return callback(_this); - }); + _this.type = (buffer.slice(0, 1)).toString('utf-8'); + _this.dateUpdated = _this.parseDate(buffer.slice(1, 4)); + _this.numberOfRecords = _this.convertBinaryToInteger(buffer.slice(4, 8)); + _this.start = _this.convertBinaryToInteger(buffer.slice(8, 10)); + _this.recordLength = _this.convertBinaryToInteger(buffer.slice(10, 12)); + _this.fields = ((function() { + var _i, _ref, _results; + _results = []; + for (i = _i = 32, _ref = this.start - 32; _i <= _ref; i = _i += 32) { + _results.push(buffer.slice(i, i + 32)); + } + return _results; + }).call(_this)).map(_this.parseFieldSubRecord); + return callback(_this); + }; + })(this)); }; Header.prototype.parseDate = function(buffer) { diff --git a/lib/parser.js b/lib/parser.js index 28edbbe..065492d 100644 --- a/lib/parser.js +++ b/lib/parser.js @@ -1,6 +1,6 @@ -// Generated by CoffeeScript 1.3.3 +// Generated by CoffeeScript 1.7.1 (function() { - var EventEmitter, Header, Parser, fs, + var EventEmitter, Header, Parser, fs, iconv, __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, __hasProp = {}.hasOwnProperty, __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; @@ -11,55 +11,56 @@ fs = require('fs'); - Parser = (function(_super) { + iconv = require('iconv-lite'); + Parser = (function(_super) { __extends(Parser, _super); - function Parser(filename) { + function Parser(filename, encoding) { this.filename = filename; + this.encoding = encoding != null ? encoding : 'utf-8'; this.parseField = __bind(this.parseField, this); - this.parseRecord = __bind(this.parseRecord, this); - this.parse = __bind(this.parse, this); - } Parser.prototype.parse = function() { - var _this = this; this.emit('start', this); this.header = new Header(this.filename); - this.header.parse(function(err) { - var sequenceNumber; - _this.emit('header', _this.header); - sequenceNumber = 0; - return fs.readFile(_this.filename, function(err, buffer) { - var loc; - if (err) { - throw err; - } - loc = _this.header.start; - while (loc < (_this.header.start + _this.header.numberOfRecords * _this.header.recordLength) && loc < buffer.length) { - _this.emit('record', _this.parseRecord(++sequenceNumber, buffer.slice(loc, loc += _this.header.recordLength))); - } - return _this.emit('end', _this); - }); - }); + this.header.parse((function(_this) { + return function(err) { + var sequenceNumber; + _this.emit('header', _this.header); + sequenceNumber = 0; + return fs.readFile(_this.filename, function(err, buffer) { + var loc; + if (err) { + throw err; + } + loc = _this.header.start; + while (loc < (_this.header.start + _this.header.numberOfRecords * _this.header.recordLength) && loc < buffer.length) { + _this.emit('record', _this.parseRecord(++sequenceNumber, buffer.slice(loc, loc += _this.header.recordLength))); + } + return _this.emit('end', _this); + }); + }; + })(this)); return this; }; Parser.prototype.parseRecord = function(sequenceNumber, buffer) { - var field, loc, record, _fn, _i, _len, _ref, - _this = this; + var field, loc, record, _fn, _i, _len, _ref; record = { '@sequenceNumber': sequenceNumber, '@deleted': (buffer.slice(0, 1))[0] !== 32 }; loc = 1; _ref = this.header.fields; - _fn = function(field) { - return record[field.name] = _this.parseField(field, buffer.slice(loc, loc += field.length)); - }; + _fn = (function(_this) { + return function(field) { + return record[field.name] = _this.parseField(field, buffer.slice(loc, loc += field.length)); + }; + })(this); for (_i = 0, _len = _ref.length; _i < _len; _i++) { field = _ref[_i]; _fn(field); @@ -69,7 +70,7 @@ Parser.prototype.parseField = function(field, buffer) { var value; - value = (buffer.toString('utf-8')).replace(/^\x20+|\x20+$/g, ''); + value = (iconv.decode(buffer, this.encoding)).trim(); if (field.type === 'N') { value = parseInt(value, 10); } diff --git a/package.json b/package.json index eab1925..e84016f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "node-dbf", - "version": "0.1.0", + "version": "0.1.1", "description": "An efficient dBase DBF file parser written in pure JavaScript", "main": "./lib/parser.js", "repository": { @@ -15,7 +15,10 @@ "devDependencies": { "coffee-script": ">=1.3.3" }, + "dependencies": { + "iconv-lite": ">=0.2.11" + }, "scripts": { "prepublish": "cake build" } -} \ No newline at end of file +} diff --git a/src/parser.coffee b/src/parser.coffee index 61ec67d..caeec70 100644 --- a/src/parser.coffee +++ b/src/parser.coffee @@ -1,10 +1,11 @@ {EventEmitter} = require 'events' Header = require './header' fs = require 'fs' +iconv = require 'iconv-lite' class Parser extends EventEmitter - constructor: (@filename) -> + constructor: (@filename, @encoding = 'utf-8') -> parse: => @emit 'start', @ @@ -41,7 +42,7 @@ class Parser extends EventEmitter return record parseField: (field, buffer) => - value = (buffer.toString 'utf-8').replace /^\x20+|\x20+$/g, '' + value = (iconv.decode buffer, @encoding).trim() if field.type is 'N' then value = parseInt value, 10