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.


335
336
337
338
339
# File 'lib/idevice/afc.rb', line 335

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

Class Method Details

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


301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
# File 'lib/idevice/afc.rb', line 301

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:


341
342
343
344
345
# File 'lib/idevice/afc.rb', line 341

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

#closed?Boolean

Returns:

  • (Boolean)

347
348
349
# File 'lib/idevice/afc.rb', line 347

def closed?
  @closed == true
end

#lock(op) ⇒ Object

Raises:


355
356
357
358
359
# File 'lib/idevice/afc.rb', line 355

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)

351
352
353
# File 'lib/idevice/afc.rb', line 351

def open?
  not closed?
end

#pos=(offset) ⇒ Object


375
376
377
# File 'lib/idevice/afc.rb', line 375

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

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


406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
# File 'lib/idevice/afc.rb', line 406

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


383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
# File 'lib/idevice/afc.rb', line 383

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


379
380
381
# File 'lib/idevice/afc.rb', line 379

def rewind
  self.pos=0
end

#seek(offset, whence) ⇒ Object

Raises:


361
362
363
364
# File 'lib/idevice/afc.rb', line 361

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


366
367
368
369
370
371
372
# File 'lib/idevice/afc.rb', line 366

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


427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
# File 'lib/idevice/afc.rb', line 427

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