Module: Ascii85Native

Extended by:
FFI::Library
Defined in:
lib/ascii85_native.rb

Class Method Summary collapse

Class Method Details

.decode(input, force_delimiter = false) ⇒ Object



51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/ascii85_native.rb', line 51

def self.decode(input, force_delimiter=false)
  return "" if input.nil? || input.size == 0

  # Array slicing in ruby 3.0.1 appears to be constant time O(1): no performance hit based on array size.
  # No reason to implement this code segment in C if this holds true.
  if force_delimiter
    input = input[2..-3]
  else
    stream_start = find_stream_start(input)
    stream_end = find_stream_end(input)
    input = input[stream_start..stream_end] if stream_start != 0 || stream_end != -1
  end

  FFI::MemoryPointer.new(:char, input.size) do |in_char|
    in_char.write_string(input)
    out_size = self.a85_decoded_size(input.size)

    FFI::MemoryPointer.new(:uint8, out_size) do |output|
      self.a85_decode(in_char, input.size, output)
      return output.read_string()
    end
  end
end

.encode(input, include_delimiter = false) ⇒ Object



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/ascii85_native.rb', line 22

def self.encode(input, include_delimiter=false)
  if input.nil? || input.size == 0 
    return '<~~>' if include_delimiter
    return ''
  end

  if input.class == String
    input_data = []
    input.each_byte { |byte| input_data << byte }
  else
    input_data = input
  end

  FFI::MemoryPointer.new(:uint8, input_data.size) do |in_uint8|
    in_uint8.write_array_of_type(FFI::TYPE_UINT8, :put_uint8, input_data)
    out_size = self.a85_encoded_size(input_data.size, true)

    FFI::MemoryPointer.new(:uint8, out_size) do |output|
      self.a85_encode(in_uint8, input_data.size, output, true)
      if include_delimiter
        return '<~' + (output.read_string() || '') + '~>'
      else
        return output.read_string()
      end
    end
  end
end

.find_stream_end(input) ⇒ Object



94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/ascii85_native.rb', line 94

def self.find_stream_end(input)
  end_slice = -1
  cursor = -1

  input.size.times do |i|
    if ["\n", "\r", ' '].include?(input[cursor])
      cursor -= 1
      next
    elsif input[cursor] == '>' && input[cursor-1] == '~'
      end_slice = cursor - 2
      break
    else
      break # input is not delimited
    end
  end

  return end_slice
end

.find_stream_start(input) ⇒ Object



75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/ascii85_native.rb', line 75

def self.find_stream_start(input)
  start_slice = 0
  cursor = 0 

  input.size.times do |i|
    if ["\n", "\r", ' '].include?(input[cursor])
      cursor += 1
      next
    elsif input[cursor] == '<' && input[cursor+1] == '~'
      start_slice = cursor + 2
      break
    else
      break # input is not delimited
    end
  end

  return start_slice
end