Class: Svn::AprHash

Inherits:
FFI::AutoPointer
  • Object
show all
Includes:
Enumerable
Defined in:
lib/svn/apr_utils.rb

Defined Under Namespace

Modules: C

Constant Summary collapse

HASH_KEY_STRING =

when used as key length, indicates that string length should be used

-1

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(ptr, key_type, val_type, keys_null_terminated = true) ⇒ AprHash

Returns a new instance of AprHash.



16
17
18
19
20
21
22
# File 'lib/svn/apr_utils.rb', line 16

def initialize( ptr, key_type, val_type, keys_null_terminated=true)
  super( ptr )
  @key_type = key_type
  @val_type = val_type
  @pointers = []
  @keys_null_terminated = keys_null_terminated
end

Instance Attribute Details

#keys_null_terminatedObject Also known as: keys_null_terminated?

Returns the value of attribute keys_null_terminated.



13
14
15
# File 'lib/svn/apr_utils.rb', line 13

def keys_null_terminated
  @keys_null_terminated
end

Class Method Details

.create(key_type, val_type, pool = RootPool) ⇒ Object

creates a new apr_hash_t that contains contents, if given



26
27
28
29
# File 'lib/svn/apr_utils.rb', line 26

def create( key_type, val_type, pool=RootPool )
  ptr = C.create( pool )
  new( ptr, key_type, val_type )
end

.create_from(rb_hash, key_type, val_type, pool = RootPool) ⇒ Object



31
32
33
# File 'lib/svn/apr_utils.rb', line 31

def create_from( rb_hash, key_type, val_type, pool=RootPool )
  create( key_type, val_type, pool ).copy_from( rb_hash )
end

.release(ptr) ⇒ Object



35
36
37
# File 'lib/svn/apr_utils.rb', line 35

def release( ptr )
  # memory will be released with the allocation pool
end

Instance Method Details

#[](key) ⇒ Object



138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
# File 'lib/svn/apr_utils.rb', line 138

def []( key )
  val = nil # keep val in scope

  if key.is_a?( String ) && keys_null_terminated?
    val = C.get( self, key, HASH_KEY_STRING )
  elsif key.respond_to? :size
    val = C.get( self, key, key.size )
  elsif key.respond_to? :length
    val = C.get( self, key, key.length )
  else
    raise ArgumentError, "Invalid key #{key}: cannot determine length"
  end

  Utils.content_for( val, @val_type )
end

#[]=(key, val) ⇒ Object



154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
# File 'lib/svn/apr_utils.rb', line 154

def []=( key, val )
  val_ptr = Utils.pointer_for( val, @val_type )

  # because the pointers passed in are referenced in native code, keep
  # track of the pointers so they aren't garbage collected until this hash
  # is destroyed
  @pointers << val_ptr

  if key.is_a?( String ) && keys_null_terminated?
    C.set( self, key, HASH_KEY_STRING, val_ptr )
  elsif key.respond_to? :size
    C.set( self, key, key.size, val_ptr )
  elsif key.respond_to? :length
    C.set( self, key, key.length, val_ptr )
  else
    raise ArgumentError, "Invalid key #{key}: cannot determine length"
  end

  val
end

#copy_from(rb_hash) ⇒ Object



175
176
177
178
179
180
181
# File 'lib/svn/apr_utils.rb', line 175

def copy_from( rb_hash )
  rb_hash.each_pair do |key, val|
    self[ key ] = val
  end

  self
end

#each_pairObject



112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/svn/apr_utils.rb', line 112

def each_pair
  # outgoing pointers for keys and values
  key_ptr = FFI::MemoryPointer.new( :pointer )
  # apr_ssize_t => ssize_t => platform-specific long
  len_ptr = FFI::MemoryPointer.new( :long )
  val_ptr = FFI::MemoryPointer.new( :pointer )

  # initialize a hash index to the first entry
  iter = C.first( pool, self )

  while !iter.null?
    # get the key, key length, and val
    C.this( iter, key_ptr, len_ptr, val_ptr )

    # read the key
    key_len = len_ptr.read_long
    key = Utils.content_for( key_ptr.read_pointer, @key_type, key_len )

    # yield the key and value
    yield key, Utils.content_for( val_ptr.read_pointer, @val_type ) if block_given?

    # advance to the next iteration
    iter = C.next( iter )
  end
end

#to_hObject



183
184
185
186
187
188
189
# File 'lib/svn/apr_utils.rb', line 183

def to_h
  rb_hash = {}
  each_pair do |key, val|
    rb_hash[ key ] = val
  end
  rb_hash
end