Jump To …

LightOutputStream.coffee

fs = require 'fs'

This is hack used to resolve cyclic reference.

ArrayByteIterableFile = (require './ArrayByteIterable.coffee')

TODO many-many tests!!! TODO verify interface. This class allows writing various data to buffer.

class LightOutputStream
  NULL_STRING_UTF_VALUE: 0xFF
  @DEFAULT_INIT_SIZE: 8

@private

  len: undefined

@private

  buf: undefined

Constructor.

  @create: (o) ->
    return @create$int LightOutputStream.DEFAULT_INIT_SIZE, o

Constructor.

@param initialSize the size of buffer to start with.

  @create$int: (initialSize, o) ->
    return @create$Buffer new Buffer initialSize, o

Constructor.

@param buffer.

  @create$Buffer: (buffer, o) ->
    if !o? then o = new LightOutputStream
    o.buf = buffer
    o.len = 0
    return o

@return ArrayByteIterable to work with.

  asArrayByteIterable: () ->
    return ArrayByteIterableFile.ArrayByteIterable.create$Buffer$int @buf, @len

  clear: () ->
    @len = 0

--- begin ByteArrayOutputStream compatible methods ---

  size: () ->
    return @len

Write.

@param b number.

  write$int: (b) ->
    @writeFast$int b

Write.

@param fromBuf buffer.

  write$Buffer: (fromBuf) ->
    @ensureCapacity$int @len + fromBuf.length
    fromBuf.copy @buf, @len, 0, fromBuf.length
    @len += fromBuf.length

Write.

@param fromBuf buffer. @param offset. @param length.

  write$Buffer$int$int: (fromBuf, offset, length) ->
    @ensureCapacity$int @len + fromBuf.length
    fromBuf.copy @buf, @len, offset, length
    @len += fromBuf.length

  toString: () ->
    return @buf.toString()

--- end ByteArrayOutputStream compatible methods ---

Write number.

@param val.

  writeByte$int: (val) ->
    @writeFast$int val ^ 0x80

Write number.

@param b.

  writeFast$int: (b) ->
    if @len >= @buf.length
      @ensureCapacity$int @len + 1
    @buf[@len++] = b

Write boolean.

@param val.

  writeBoolean$boolean: (val) ->
    @writeFast$int val? 1: 0

Write number.

@param val.

  writeShort$int: (val) ->
    @writeUnsignedShort$int val ^ 0x8000

Write number.

@param val.

  writeInt$int: (val) ->
    @writeUnsignedInt$int val ^ 0x80000000

Write number.

@param val.

  writeLong$int: (val) ->
    @writeUnsignedLong$int val ^ 0x8000000000000000

Write number.

@param val.

  writeFloat$double: (val) ->

really?

    @writeUnsignedInt$int val

Write number.

@param val.

  writeDouble$double: (val) ->

is this true?

    @writeUnsignedLong$int val

Write String.

@param val.

  writeString$String: (val) ->
    if val?
      if val.length != 0
        utfLength = @getUtfByteLength$String val
        @ensureCapacity$int len + utfLength
        @utfCharsToBytes$String$int$Buffer$int$int val, 0, @getBufferBytes(),
                @getBufferLength(), val.length
        len += utfLength
    else
      @writeFast$int @NULL_STRING_UTF_VALUE
    @writeFast$int 0 # terminator

will next three methods work? is the question... Write number.

@param val.

  writeUnsignedShort$int: (val) ->
    @writeFast$int val >>> 8
    @writeFast$int val

Write number.

@param val.

  writeUnsignedInt$int: (val) ->
    @writeFast$int val >>> 24
    @writeFast$int val >>> 16
    @writeFast$int val >>> 8
    @writeFast$int val

@private Write number.

@param val.

  writeUnsignedLong$int: (val) ->
    @writeFast$int val >>> 56
    @writeFast$int val >>> 48
    @writeFast$int val >>> 40
    @writeFast$int val >>> 32
    @writeFast$int val >>> 24
    @writeFast$int val >>> 16
    @writeFast$int val >>> 8
    @writeFast$int val

  getBufferBytes: () ->
    return @buf

  getBufferLength: () ->
    return @len

Resize buffer if necessary so that capacity will be enough.

@param requiredCapacity.

  ensureCapacity$int: (requiredCapacity) ->
    bufLen = @buf.length
    if bufLen < requiredCapacity
      nextAllowedCapacity = Math.round((bufLen << 3) / 5)
      if nextAllowedCapacity > requiredCapacity
        requiredCapacity = nextAllowedCapacity
      newBuf = new Buffer requiredCapacity
      @buf.copy newBuf, 0, 0, @buf.length
      @buf = newBuf

Get string length in utf.

@param chars the string. @retuan length.

  @getUtfByteLength$String: (chars) ->
    length = chars.length
    len = 0
    for i in [0..length - 1]
      c = chars[i]
      if c >= 0x0001 && c <= 0x007F
        len += 1
      else if c > 0x07FF
        len += 3
      else
        len += 2
    return len

Write string as utf in buffer.

@param chars the string. @param bytes the Buffer to write this string in. @param charLength the length of string.

  @utfCharsToBytes$String$int$Buffer$int$int: (chars, bytes, charLength) ->
    LightOutputStream.utfCharsToBytes$String$int$Buffer$int$int chars, 0,
            bytes, 0, charLength

Write string as utf in buffer.

@param chars the string. @param charOffset offset inside this string. @param bytes the Buffer to write this string in. @param byteOffset offset inside Buffer. @param charLength the length of string.

  @utfCharsToBytes$String$int$Buffer$int$int: (chars, charOffset, bytes, byteOffset, charLength) ->
    if charOffset == undefined
      charOffset = 0
    if byteOffset == undefined
      byteOffset = 0
    charLength += charOffset
    for i in [charOffset..charLength - 1]
      c = chars[i]
      if c >= 0x0001 && c <= 0x007F
        bytes[byteOffset++] = c
      else if c > 0x07FF
        bytes[byteOffset++] = (0xE0 | ((c >> 12) & 0x0F))
        bytes[byteOffset++] = (0x80 | ((c >> 6) & 0x3F))
        bytes[byteOffset++] = (0x80 | ((c >> 0) & 0x3F))
      else
        bytes[byteOffset++] = (0xC0 | ((c >> 6) & 0x1F))
        bytes[byteOffset++] = (0x80 | ((c >> 0) & 0x3F))

exports.LightOutputStream = LightOutputStream