|
Versions Of This Snippet::
Download a raw-text version of this code by clicking on "Download Version"
Latest Snippet Version: :0.1
class XBaseReader
def initialize(fileName)
@fileName = fileName
readDBASEMetaInfo()
@filter = Proc.new { |record| true }
end
def readDBASEMetaInfo()
ios = File.open(@fileName,"rb")
@hdr = {}
buff = ios.read(11)
@hdr['size'] = (buff[8..9].unpack('S'))[0]
ios.rewind
hdrBuff = ios.read(@hdr['size'])
@hdr['type'] = hdrBuff[0]
@hdr['records'] = (hdrBuff[4..7].unpack('L'))[0]
@hdr['recordSize'] = (hdrBuff[10..11].unpack('S'))[0]
# read field info from hdr
@flds = []
@fldNames = {}
start = 32
while 1 == 1
fldInfo = hdrBuff[start..(start+31)]
break if fldInfo[0] == 0x0d
fld = {}
fld['name'] = fldInfo[0..10].strip
fld['type'] = sprintf("%c",fldInfo[11])
fld['length'] = fldInfo[16]
@flds << fld
xx = fld['name']
@fldNames[xx] = @flds.size-1
start= start+32
end
ios.close
end
def fields
@flds
end
def hdr(name)
@hdr[name]
end
def fieldName(pos)
@flds[pos]['name']
end
def fieldIndex(fldName)
@fldNames[fldName]
end
def setFilter(&filterProc)
if block_given?
@filter = filterProc
else
@filter = Proc.new { |record| true }
end
end
def list(startRecord=0)
recCnt = 0
ios = File.open(@fileName,"rb")
ios.pos = @hdr['size'] + (@hdr['recordSize']*startRecord)
@hdr['records'].times { |i|
#10.times { |i|
buff = ios.read(@hdr['recordSize'])
break if buff == nil
break if buff.size != @hdr['recordSize'] # need this due to extra chars appended unexpectedly
fldStartPos = 0
currRec = []
@flds.each { |fld|
if fld['type'] == 'D'
endPos = fldStartPos+fld['length']
incr = fld['length']+1
end
# if fld['type'] == 'C' || fld['type'] == 'N'
if "CN".count(fld['type']) > 0
endPos = fldStartPos+fld['length']-1
incr = fld['length']
end
val = buff[fldStartPos..endPos].to_s.strip
fldStartPos = fldStartPos+incr
currRec << val
#puts "Name(#{fld['name']} Type(#{fld['type']}) Length(#{fld['length']}) Value(#{val})"
#print "(#{val}) "
}
if @filter.call(currRec)
yield currRec
recCnt = recCnt + 1
end
#puts
#puts buff
}
#puts buff
ios.close
return recCnt
end
end
Submit a new versionYou can submit a new version of this snippet if you have modified it and you feel it is appropriate to share with others..
|
||||||||||||||||||||||||||
