Class: RAPI::RemoteFile

Inherits:
Object
  • Object
show all
Includes:
File::Constants
Defined in:
lib/rapi/remote_file.rb

Instance Attribute Summary (collapse)

Instance Method Summary (collapse)

Constructor Details

- (RemoteFile) initialize(path, *rest)

Returns a new instance of RemoteFile



9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# File 'lib/rapi/remote_file.rb', line 9

def initialize(path, *rest)
  @path = path.freeze
  @pos = 0
  @mode, opt = splat_args(rest)

  @mode = parse_mode(@mode)
  append = @mode & APPEND != 0
  access_flags = mode_to_access(@mode)
  creation_flags = mode_to_creation(@mode)

  @handle = Native::Rapi.CeCreateFile(Util.utf16le(path), access_flags, 0, 0, creation_flags, Native::FILE_ATTRIBUTE_NORMAL, 0)

  unless @handle.valid?
    Util.handle_hresult! Util.error, "Could not create remote file."
  end

  self.pos = self.size if append
end

Instance Attribute Details

- (Object) path (readonly)

Returns the value of attribute path



5
6
7
# File 'lib/rapi/remote_file.rb', line 5

def path
  @path
end

- (Object) pos Also known as: tell

Returns the value of attribute pos



6
7
8
# File 'lib/rapi/remote_file.rb', line 6

def pos
  @pos
end

Instance Method Details

- (Object) <<(obj)



63
64
65
66
67
# File 'lib/rapi/remote_file.rb', line 63

def <<(obj)
  write(obj)

  self
end

- (Object) close



147
148
149
150
# File 'lib/rapi/remote_file.rb', line 147

def close
  @handle.close
  @handle = nil
end

- (Boolean) closed?

Returns:

  • (Boolean)


152
153
154
# File 'lib/rapi/remote_file.rb', line 152

def closed?
  @handle.nil?
end

- (Object) read(*rest)



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/rapi/remote_file.rb', line 69

def read(*rest)
  length, buffer = rest
  buffer ||= ""
  buffer.clear

  if length.nil? || (length + self.pos) > self.size
    length = self.size - self.pos
  end

  if length == 0
    return nil if rest[0] && rest[0] > 0
    return buffer
  end

  mem_buffer = FFI::MemoryPointer.new(:char, length)
  bytes_read_ptr = FFI::MemoryPointer.new(:uint)

  success = Native::Rapi.CeReadFile(@handle, mem_buffer, size, bytes_read_ptr, 0) != 0

  bytes_read = bytes_read_ptr.get_int(0)
  @pos += bytes_read

  unless success
    mem_buffer.free
    bytes_read_ptr.free
    Util.handle_hresult! Util.error, "Failed to read device data."
  end

  buffer << mem_buffer.get_bytes(0, bytes_read)


  buffer

ensure
  mem_buffer.free if mem_buffer
  bytes_read_ptr.free if bytes_read_ptr
end

- (Object) seek(amount, whence = IO::SEEK_SET)



111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
# File 'lib/rapi/remote_file.rb', line 111

def seek(amount, whence=IO::SEEK_SET)
  case whence
  when IO::SEEK_SET
    new_pos = amount
    method = Native::FILE_BEGIN
  when IO::SEEK_CUR
    new_pos = @pos + amount
    method = Native::FILE_CURRENT
  when IO::SEEK_END
    new_pos = @pos + amount
    method = Native::FILE_END
  end

  success = Native::Rapi.CeSetFilePointer(@handle, amount, nil, method) != 0xFFFFFFFF

  unless success
    Util.handle_hresult! Util.error, "Failed to move file pointer."
  end

  @pos = new_pos
end

- (Object) size



32
33
34
35
36
37
38
39
40
41
42
# File 'lib/rapi/remote_file.rb', line 32

def size
  # If I pass in a non-NULL uint* for the high DWORD,
  # the func always gives me 0 for both the low and high DWORDs...
  size = Native::Rapi.CeGetFileSize(@handle, nil)

  if size == Native::INVALID_FILE_SIZE
    Util.handle_hresult! Util.error, "Could not get file size."
  end

  size
end

- (Object) stat



28
29
30
# File 'lib/rapi/remote_file.rb', line 28

def stat
  RAPI.search(@path).first
end

- (Object) truncate(integer)



133
134
135
136
137
138
139
140
141
142
143
144
145
# File 'lib/rapi/remote_file.rb', line 133

def truncate(integer)
  old_pos = self.pos
  self.pos = integer

  success = Native::Rapi.CeSetEndOfFile(@handle) != 0

  unless success
    Util.handle_hresult! Util.error, "Failed to truncate file."
  end

ensure
  self.pos = old_pos
end

- (Object) write(obj)



44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/rapi/remote_file.rb', line 44

def write(obj)
  buffer = obj.to_s
  bytes_written_ptr = FFI::MemoryPointer.new(:uint)

  success = Native::Rapi.CeWriteFile(@handle, buffer, buffer.size, bytes_written_ptr, 0) != 0

  bytes_written = bytes_written_ptr.get_uint(0)
  @pos += bytes_written

  unless success
    Util.handle_hresult! Util.error, "Could not write to remote file."
  end

  bytes_written

ensure
  bytes_written_ptr.free if bytes_written_ptr
end