DataIterator.coffee | |
---|---|
fs = require 'fs'
Addr64 = (require './Addr64.coffee').Addr64
LogUtil = (require './LogUtil.coffee').LogUtil
CompoundByteIteratorBase =
(require './iterate/CompoundByteIteratorBase.coffee').CompoundByteIteratorBase | |
TODO Implement many other methods!!! This class provides access to data stored in cache. It is lazy - it gets information from cache only when getValue or getData are called. Also it is changable. | class DataIterator extends CompoundByteIteratorBase |
@private | cache: undefined |
@private | addr: undefined |
@private | pageAddr: undefined |
@private | offset: undefined |
@private | buffer: undefined |
Constructor. @param cache the cache where data is stored (or where it can be loaded). @param addr the address in virtual address space. | @create$LogCache$Addr64: (cache, addr, o) ->
if !o? then o = new DataIterator
o.cache = cache
o.addr = addr
o.cache.parseAddr$Addr64 o.addr
o.pageAddr = o.cache.getPageAddr()
o.offset = o.cache.getPageOffset()
o.buffer = undefined
return o
getAddress: () ->
return @addr |
Makes a copy of the current state of iterator. @return new DataIterator | copy: () ->
return DataIterator.create$LogCache$Addr64 @cache, @addr |
Check whether there is next. | hasNext$emit: () ->
return @addr.plus$int(1).less$Addr64 @cache.getHighAddress() |
@private Moves pointer to data to the next byte. This method changes object. | moveNext: () ->
@addr = @addr.plus$int 1
@offset += 1
if @offset == @cache.getPageSize()
@pageAddr = @pageAddr.plus$int @offset
@offset = 0
@buffer = undefined |
Move pointer to data to current position plus offset. This method changes object. @param length items to skip (result is undefined for non-positive length). @return how many items were skipped, zero if no elements left. | skip$int: (length) ->
if length < 0
return undefined
if !(@cache.getHighAddress().less$Addr64 @addr.plus$int(length))
res = length
else
res = @cache.getHighAddress().diff$Addr64 @addr
@addr = @addr.plus$int res
@cache.parseAddr$Addr64 @addr
@pageAddr = @cache.getPageAddr()
@offset = @cache.getPageOffset()
@buffer = undefined
return res |
Get value of byte at current position and move next. @return If buffer is defined or can be instantly got from cache returns value. Otherwise returns undefined and emits 'getValue' event. If undefined is returned, do not call this method again before event is emitted! | next$emit: () ->
if @buffer?
res = @buffer[@offset]
@moveNext()
return res
else
addrStr = Addr64.addr64ToString$Addr64$int(@pageAddr,
LogUtil.LOG_NAME_BASE)
@cache.once 'getPage' + addrStr, (buffer, addrStr) =>
@buffer = buffer
res = @buffer[@offset]
@moveNext()
@emit 'next', res
@buffer = @cache.getPage$Addr64$emit @pageAddr
if @buffer?
res = @buffer[@offset]
@moveNext()
return res
else
return undefined
getHighAddress: () ->
return @addr |
This class should be used ONLY when it is known that the data is in one buffer and doesn't need to be uploaded from disk. It is EventEmitter to let it be used with compressor. Think twice before using it! It can be used if you have made a copy of data dorm ReadLogable and want to parse it. | class LightReadIterator extends CompoundByteIteratorBase |
@private | offset: undefined |
@private | buffer: undefined |
Constructor. @param buffer. @param offset in buffer. | @create$Buffer$int: (buffer, offset) ->
@buffer = buffer
@offset = offset |
Makes a copy of the current state of iterator. @return new DataIterator | copy: () ->
return LightReadIterator.create$Buffer$int @buffer, @offset |
Check whether there is next. | hasNext$emit: () ->
return @offset + 1 < @buffer.length |
Reads data at current position and moves pointer to data to the next byte. This method changes object. | next$emit: () ->
res = @buffer[@offset]
@offset += 1
return res |
Move pointer to data to current position plus offset. This method changes object. @param length items to skip (result is undefined for non-positive length). @return how many items were skipped, zero if no elements left. | skip$int: (length) ->
if length < 0
return undefined
rest = @buffer.length - @offset
if rest >= length
@offset += length
return length
else
@offset += rest
return rest |
Get buffer with data at current position. @param length the length of data to be read. @return buffer with data. | getData$int$emit: (length) ->
b = new Buffer(length)
@buffer.copy b, 0, @offset, @offset + length
return b
exports.DataIterator = DataIterator
exports.LightReadIterator = LightReadIterator
|