Class: Idevice::AFCFile

Inherits:
Object
  • Object
show all
Defined in:
lib/idevice/afc.rb

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(afcclient, handle) ⇒ AFCFile

Returns a new instance of AFCFile.



290
291
292
293
294
# File 'lib/idevice/afc.rb', line 290

def initialize(afcclient, handle)
  @afcclient = afcclient
  @handle = handle
  @closed = false
end

Class Method Details

.open(afcclient, path, mode = :RDONLY) ⇒ Object



256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
# File 'lib/idevice/afc.rb', line 256

def self.open(afcclient, path, mode=:RDONLY)
  m = case mode
      when Symbol
        mode
      when 'r',nil
        :RDONLY
      when 'r+'
        :RW
      when 'w'
        :WRONLY
      when 'w+'
        :WR
      when 'a'
        :APPEND
      when 'a+'
        :RDAPPEND
      else
        raise ArgumentError, "invalid file mode: #{mode.inspect}"
      end

  afcfile=nil
  FFI::MemoryPointer.new(:uint64) do |p_handle|
    err =C.afc_file_open(afcclient, path, m, p_handle)
    raise AFCError, "AFC error: #{err}" if err != :SUCCESS
    afcfile = new(afcclient, p_handle.read_uint64)
  end

  begin
    yield(afcfile)
  ensure
    afcfile.close unless afcfile.closed?
  end
end

Instance Method Details

#closeObject

Raises:



296
297
298
299
300
# File 'lib/idevice/afc.rb', line 296

def close
  err = C.afc_file_close(@afcclient, @handle)
  raise AFCError, "AFC error: #{err}" if err != :SUCCESS
  @closed = true
end

#closed?Boolean

Returns:

  • (Boolean)


302
303
304
# File 'lib/idevice/afc.rb', line 302

def closed?
  @closed == true
end

#lock(op) ⇒ Object

Raises:



310
311
312
313
314
# File 'lib/idevice/afc.rb', line 310

def lock(op)
  err = C.afc_file_lock(@afcclient, @handle, op)
  raise AFCError, "AFC error: #{err}" if err != :SUCCESS
  return true
end

#open?Boolean

Returns:

  • (Boolean)


306
307
308
# File 'lib/idevice/afc.rb', line 306

def open?
  not closed?
end

#pos=(offset) ⇒ Object



330
331
332
# File 'lib/idevice/afc.rb', line 330

def pos=(offset)
  seek(offset, :SEEK_SET)
end

#read(len = nil, &block) ⇒ Object



361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
# File 'lib/idevice/afc.rb', line 361

def read(len=nil, &block)
  return read_all(nil, &block) if len.nil?

  ret = nil

  FFI::MemoryPointer.new(len) do |buf|
    FFI::MemoryPointer.new(:uint32) do |p_rlen|
      while (err=C.afc_file_read(@afcclient, @handle, buf, len, p_rlen)) == :SUCCESS
        rlen = p_rlen.read_uint32
        ret ||= StringIO.new
        ret << buf.read_bytes(rlen)
        len -= rlen
        break if len <= 0
      end
      raise AFCError, "AFC error: #{err}" unless [:SUCCESS, :END_OF_DATA].include?(err)
    end
  end

  return ret.string unless ret.nil?
end

#read_all(chunksz = nil) ⇒ Object



338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
# File 'lib/idevice/afc.rb', line 338

def read_all(chunksz=nil)
  chunksz ||= AFC_DEFAULT_CHUNKSIZE
  ret = nil
  FFI::MemoryPointer.new(chunksz) do |buf|
    FFI::MemoryPointer.new(:uint32) do |p_rlen|
      while (err=C.afc_file_read(@afcclient, @handle, buf, buf.size, p_rlen)) == :SUCCESS
        rlen = p_rlen.read_uint32
        chunk = buf.read_bytes(rlen)
        if block_given?
          yield chunk
        else
          ret ||= StringIO.new unless block_given?
          ret << chunk
        end
        break if rlen == 0
      end
      raise AFCError, "AFC error: #{err}" unless [:SUCCESS, :END_OF_DATA].include?(err)
    end
  end

  return ret.string unless ret.nil?
end

#rewindObject



334
335
336
# File 'lib/idevice/afc.rb', line 334

def rewind
  self.pos=0
end

#seek(offset, whence) ⇒ Object

Raises:



316
317
318
319
# File 'lib/idevice/afc.rb', line 316

def seek(offset, whence)
  err = C.afc_file_seek(@afcclient, @handle, offset, whence)
  raise AFCError, "AFC error: #{err}" if err != :SUCCESS
end

#tellObject Also known as: pos



321
322
323
324
325
326
327
# File 'lib/idevice/afc.rb', line 321

def tell
  FFI::MemoryPointer.new(:pointer) do |p_pos|
    err = C.afc_file_tell(@afcclient, @handle, p_pos)
    raise AFCError, "AFC error: #{err}" if err != :SUCCESS
    return p_pos.read_uint16
  end
end

#write(data) ⇒ Object



382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
# File 'lib/idevice/afc.rb', line 382

def write(data)
  bytes_written = 0
  FFI::MemoryPointer.from_bytes(data) do |p_data|
    FFI::MemoryPointer.new(:uint32) do |p_wlen|
      while bytes_written < p_data.size
        err = C.afc_file_write(@afcclient, @handle, p_data, p_data.size, p_wlen)
        raise AFCError, "AFC error: #{err}" if err != :SUCCESS

        wlen = p_wlen.read_uint32
        p_data += wlen
        bytes_written += wlen
      end
    end
  end
  return bytes_written
end