Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stream-related Improvements #13

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 59 additions & 25 deletions lib/header.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

107 changes: 53 additions & 54 deletions lib/parser.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@

{
"name": "node-dbf",
"version": "0.1.1",
"version": "0.1.2",
"description": "An efficient dBase DBF file parser written in pure JavaScript",
"main": "./lib/parser.js",
"repository": {
Expand Down
62 changes: 50 additions & 12 deletions src/header.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,63 @@ fs = require 'fs'

class Header

constructor: (@filename) ->
constructor: (@stream) ->
return @

parse: (callback) ->
fs.readFile @filename, (err, buffer) =>
throw err if err
_STATE_HEADER = 1
_STATE_FIELDS = 2
_STATE_FINISHING = 3
_STATE_DONE = 4
@state = _STATE_HEADER
@index = 0
@fields = []

@type = (buffer.slice 0, 1).toString 'utf-8'
@dateUpdated = @parseDate (buffer.slice 1, 4)
@numberOfRecords = @convertBinaryToInteger (buffer.slice 4, 8)
@start = @convertBinaryToInteger (buffer.slice 8, 10)
@recordLength = @convertBinaryToInteger (buffer.slice 10, 12)
doParse = () =>
ranout = false
if @state is _STATE_HEADER
buffer = @stream.read 32
if buffer is null
return

@index = 32
@type = (buffer.slice 0, 1).toString 'utf-8'
@dateUpdated = @parseDate (buffer.slice 1, 4)
@numberOfRecords = @convertBinaryToInteger (buffer.slice 4, 8)
@start = @convertBinaryToInteger (buffer.slice 8, 10)
@recordLength = @convertBinaryToInteger (buffer.slice 10, 12)

@fields = (buffer.slice i, i+32 for i in [32 .. @start - 32] by 32).map @parseFieldSubRecord
@state = _STATE_FIELDS

callback @
if @state is _STATE_FIELDS
fieldHeaderSize = 32
while buffer = @stream.read fieldHeaderSize
@index += fieldHeaderSize
if buffer[0] == 0x0D
@state = _STATE_FINISHING
break
@fields.push @parseFieldSubRecord buffer

if @state is _STATE_FINISHING
delta = @start - @index
if delta > 0
# Read up to start
buffer = @stream.read delta
if buffer is null
return
else if delta < 0
# We read too much, so put some data back on the stream.
buffer = buffer.slice delta
@stream.unshift buffer
@state = _STATE_DONE

if @state is _STATE_DONE
@stream.removeListener 'readable', doParse
callback @

@stream.on 'readable', doParse

parseDate: (buffer) =>
console.log @convertBinaryToInteger buffer.slice 0, 1
year = 1900 + @convertBinaryToInteger buffer.slice 0, 1
month = (@convertBinaryToInteger buffer.slice 1, 2) - 1
day = @convertBinaryToInteger buffer.slice 2, 3
Expand All @@ -39,4 +77,4 @@ class Header
convertBinaryToInteger: (buffer) ->
return buffer.readInt32LE 0, true

module.exports = Header
module.exports = Header
Loading