Class: Rednode::Bindings::Buffer::Buffer

Inherits:
Object
  • Object
show all
Defined in:
lib/rednode/bindings/buffer.rb

Instance Method Summary collapse

Constructor Details

#initialize(opt, *args) ⇒ Buffer

Returns a new instance of Buffer.



8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/rednode/bindings/buffer.rb', line 8

def initialize(opt, *args)
  case opt
  when Numeric
    @data = Array.new(opt.to_i, 0)
  when V8::Array
    @data = opt.to_a
  when String
    encoding = args.first
    @data = case encoding
    when 'ascii'                        then opt.unpack('U*')
    when 'utf8','utf-8','binary',nil    then opt.unpack('C*')
    when 'base64'
      (opt + "=" * (4 - opt.length % 4)).unpack('m').first.unpack('C*')
    else
      raise "Unknown encoding '#{encoding}'"
    end
  when self.class
    start, stop = args[0],args[1]
    @data = opt.send(:data)[start..stop-1]
  else
    raise "Bad argument"
  end
end

Instance Method Details

#[](index) ⇒ Object



36
37
38
# File 'lib/rednode/bindings/buffer.rb', line 36

def [](index)
  index.kind_of?(Numeric) ? @data[index] : yield
end

#[]=(index, value) ⇒ Object



40
41
42
# File 'lib/rednode/bindings/buffer.rb', line 40

def []=(index, value)
  index.kind_of?(Numeric) ? @data[index] = value : yield
end

#asciiSlice(start, stop) ⇒ Object

Raises:

  • (ArgumentError)


59
60
61
62
63
64
65
66
67
68
# File 'lib/rednode/bindings/buffer.rb', line 59

def asciiSlice(start, stop)
  raise ArgumentError, "Bad argument." unless start.kind_of?(Numeric) && stop.kind_of?(Numeric)
  raise ArgumentError, "Bad argument." if start < 0 || stop < 0
  raise ArgumentError, "Must have start <= end" unless start <= stop
  raise ArgumentError, "end cannot be longer than parent" if stop > @data.length

  @data[start..stop-1].pack('C*').tap do |slice|
    # puts "Buffer(#{self.length}).asciiSlice(#{start}, #{stop}) -> #{slice}"
  end
end

#asciiWrite(string, offset) ⇒ Object



90
91
92
93
94
95
96
# File 'lib/rednode/bindings/buffer.rb', line 90

def asciiWrite(string, offset)
  raise "Argument must be a string" unless string.kind_of?(String)
  raise "Offset is out of bounds" if string.length > 0 && offset >= self.length
  to_write = [string.length, self.length - offset].min
  @data[offset, to_write] = string.unpack('C*')
  to_write
end

#base64Slice(start, stop) ⇒ Object



74
75
76
# File 'lib/rednode/bindings/buffer.rb', line 74

def base64Slice(start, stop)
  [@data[start..stop-1].pack('C*')].pack('m').gsub(/\n/,'')
end

#base64Write(string, offset) ⇒ Object



103
104
105
106
107
108
109
110
# File 'lib/rednode/bindings/buffer.rb', line 103

def base64Write(string, offset)
  return 0 if offset == 0 && self.length == 0
  raise "Offset is out of bounds" if offset >= self.length
  bytes = string.unpack('m').first.unpack('C*')
  raise "Buffer too small" if bytes.length > (self.length - offset)
  @data[offset, bytes.length] = bytes
  bytes.length
end

#binarySlice(start, stop) ⇒ Object



70
71
72
# File 'lib/rednode/bindings/buffer.rb', line 70

def binarySlice(start, stop)
  @data[start..stop-1]
end

#binaryWrite(string, offset) ⇒ Object



98
99
100
101
# File 'lib/rednode/bindings/buffer.rb', line 98

def binaryWrite(string, offset)
  raise "Argument must be a string" unless string.kind_of?(String)
  0
end

#copy(target, position, start, finish = self.length) ⇒ Object



112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/rednode/bindings/buffer.rb', line 112

def copy(target, position, start, finish = self.length)
  raise "First arg should be a Buffer" unless target.kind_of?(self.class)
  raise "sourceEnd < sourceStart" if finish < start
  return 0 if start == finish

  raise "targetStart out of bounds" if position < 0 || position >= target.length
  raise "sourceStart out of bounds" if start < 0 || start >= self.length
  raise "sourceEnd out of bounds" if finish < 0 || finish > self.length

  to_copy = [finish - start, target.length - position].min.tap do |bytes|
    for i in 0..bytes - 1
      target[i] = self[i]
    end
  end
end

#lengthObject



32
33
34
# File 'lib/rednode/bindings/buffer.rb', line 32

def length
  @data.length
end

#slice(start, stop) ⇒ Object



44
45
46
# File 'lib/rednode/bindings/buffer.rb', line 44

def slice(start, stop)
  Buffer.new(self, start, stop)
end

#to_sObject



128
129
130
# File 'lib/rednode/bindings/buffer.rb', line 128

def to_s
  @data.pack("C*")
end

#unpack(format, index) ⇒ Object

Raises:

  • (ArgumentError)


48
49
50
51
52
53
# File 'lib/rednode/bindings/buffer.rb', line 48

def unpack(format, index)
  raise ArgumentError, "Argument must be a string" unless format.kind_of?(String)
  @data[index..-1].pack('C*').unpack(format).tap do |array|
    raise ArgumentError, "Out of bounds" if array.last.nil?
  end
end

#utf8Slice(start, stop) ⇒ Object



55
56
57
# File 'lib/rednode/bindings/buffer.rb', line 55

def utf8Slice(start, stop)
  @data[start..stop-1].pack('C*')
end

#utf8Write(string, offset) ⇒ Object



78
79
80
81
82
83
84
85
86
87
88
# File 'lib/rednode/bindings/buffer.rb', line 78

def utf8Write(string, offset)
  written = 0
  string.scan(/./mu) do |codepoint|
    bytes = codepoint.unpack('C*')
    if bytes.length <= self.length - offset - written
      @data[offset + written, bytes.length] = bytes
      written += bytes.length
    end
  end
  return written
end