Class: Prism::LibRubyParser::PrismString

Inherits:
Object
  • Object
show all
Defined in:
lib/prism/ffi.rb

Overview

This object represents a pm_string_t. We only use it as an opaque pointer, so it doesn’t have to be an FFI::Struct.

Constant Summary collapse

SIZEOF =

:nodoc:

LibRubyParser.pm_string_sizeof

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(pointer, length, from_string) ⇒ PrismString

Returns a new instance of PrismString.



151
152
153
154
155
# File 'lib/prism/ffi.rb', line 151

def initialize(pointer, length, from_string)
  @pointer = pointer
  @length = length
  @from_string = from_string
end

Instance Attribute Details

#lengthObject (readonly)

Returns the value of attribute length.



149
150
151
# File 'lib/prism/ffi.rb', line 149

def length
  @length
end

#pointerObject (readonly)

Returns the value of attribute pointer.



149
150
151
# File 'lib/prism/ffi.rb', line 149

def pointer
  @pointer
end

Class Method Details

.with_file(filepath) ⇒ Object

Yields a pm_string_t pointer to the given block.

Raises:

  • (TypeError)


177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
# File 'lib/prism/ffi.rb', line 177

def self.with_file(filepath)
  raise TypeError unless filepath.is_a?(String)

  # On Windows and Mac, it's expected that filepaths will be encoded in
  # UTF-8. If they are not, we need to convert them to UTF-8 before
  # passing them into pm_string_mapped_init.
  if RbConfig::CONFIG["host_os"].match?(/bccwin|cygwin|djgpp|mingw|mswin|wince|darwin/i) &&
     (encoding = filepath.encoding) != Encoding::ASCII_8BIT && encoding != Encoding::UTF_8
    filepath = filepath.encode(Encoding::UTF_8)
  end

  FFI::MemoryPointer.new(SIZEOF) do |pm_string|
    case (result = LibRubyParser.pm_string_mapped_init(pm_string, filepath))
    when :PM_STRING_INIT_SUCCESS
      pointer = LibRubyParser.pm_string_source(pm_string)
      length = LibRubyParser.pm_string_length(pm_string)
      return yield new(pointer, length, false)
    when :PM_STRING_INIT_ERROR_GENERIC
      raise SystemCallError.new(filepath, FFI.errno)
    when :PM_STRING_INIT_ERROR_DIRECTORY
      raise Errno::EISDIR.new(filepath)
    else
      raise "Unknown error initializing pm_string_t: #{result.inspect}"
    end
  ensure
    LibRubyParser.pm_string_free(pm_string)
  end
end

.with_string(string) ⇒ Object

Yields a pm_string_t pointer to the given block.

Raises:

  • (TypeError)


163
164
165
166
167
168
169
170
171
172
173
174
# File 'lib/prism/ffi.rb', line 163

def self.with_string(string)
  raise TypeError unless string.is_a?(String)

  length = string.bytesize
  # + 1 to never get an address of 0, which pm_parser_init() asserts
  FFI::MemoryPointer.new(:char, length + 1, false) do |pointer|
    pointer.write_string(string)
    # since we have the extra byte we might as well \0-terminate
    pointer.put_char(length, 0)
    return yield new(pointer, length, true)
  end
end

Instance Method Details

#readObject



157
158
159
160
# File 'lib/prism/ffi.rb', line 157

def read
  raise "should use the original String instead" if @from_string
  @pointer.read_string(@length)
end