Module: Packable::Extensions::IO
- Defined in:
- lib/packable/extensions/io.rb
Constant Summary collapse
- SEEKABLE_API =
Methods supported by seekable streams.
%i[pos pos= seek rewind].freeze
Class Method Summary collapse
-
.included(base) ⇒ Object
:nodoc:.
Instance Method Summary collapse
-
#>>(options) ⇒ Object
Usage: io >> Class io >> [Class, options] io >> :shortcut.
- #each_with_packing(*options, &block) ⇒ Object
- #pack_and_write(*arg) ⇒ Object
-
#packed ⇒ Object
Returns (or yields) a modified IO object that will always pack/unpack when writing/reading.
-
#pos_change(&block) ⇒ Object
Returns the change in io.pos caused by the block.
-
#read_exactly(n) ⇒ Object
returns a string of exactly n bytes, or else raises an EOFError.
- #read_with_packing(*arg) ⇒ Object
-
#seekable? ⇒ Boolean
Check whether can seek without errors.
- #write_with_packing(*arg) ⇒ Object
Class Method Details
.included(base) ⇒ Object
:nodoc:
7 8 9 10 11 |
# File 'lib/packable/extensions/io.rb', line 7 def self.included(base) #:nodoc: base.alias_method_chain :read, :packing base.alias_method_chain :write, :packing base.alias_method_chain :each, :packing end |
Instance Method Details
#>>(options) ⇒ Object
Usage:
io >> Class
io >> [Class, ]
io >> :shortcut
44 45 46 47 48 49 50 51 52 53 54 |
# File 'lib/packable/extensions/io.rb', line 44 def >> () r = [] class << r attr_accessor :stream def >> () self << stream.read() end end r.stream = self r >> end |
#each_with_packing(*options, &block) ⇒ Object
74 75 76 77 78 |
# File 'lib/packable/extensions/io.rb', line 74 def each_with_packing(*, &block) return each_without_packing(*, &block) if .empty? || (Integer === .first) || (String === .first) || !seekable? return Enumerator.new(self, :each_with_packing, *) unless block_given? yield read(*) until eof? end |
#pack_and_write(*arg) ⇒ Object
104 105 106 107 108 109 110 111 112 113 114 |
# File 'lib/packable/extensions/io.rb', line 104 def pack_and_write(*arg) original_pos = pos Packable::Packers.to_object_option_list(*arg).each do |obj, | if [:write_packed] [:write_packed].bind(obj).call(self) else obj.write_packed(self, ) end end pos - original_pos end |
#packed ⇒ Object
Returns (or yields) a modified IO object that will always pack/unpack when writing/reading.
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
# File 'lib/packable/extensions/io.rb', line 57 def packed packedio = clone packedio.set_encoding("ascii-8bit") if packedio.respond_to? :set_encoding class << packedio def << (arg) arg = [arg, :default] unless arg.instance_of?(::Array) pack_and_write(*arg) self end def packed block_given? ? yield(self) : self end alias_method :write, :pack_and_write #bypass test for argument length end block_given? ? yield(packedio) : packedio end |
#pos_change(&block) ⇒ Object
Returns the change in io.pos caused by the block. Has nothing to do with packing, but quite helpful and so simple…
34 35 36 37 38 |
# File 'lib/packable/extensions/io.rb', line 34 def pos_change(&block) delta =- pos yield delta += pos end |
#read_exactly(n) ⇒ Object
returns a string of exactly n bytes, or else raises an EOFError
97 98 99 100 101 102 |
# File 'lib/packable/extensions/io.rb', line 97 def read_exactly(n) return "" if n.zero? s = read_without_packing(n) raise EOFError if s.nil? || s.length < n s end |
#read_with_packing(*arg) ⇒ Object
84 85 86 87 88 89 90 91 92 93 94 |
# File 'lib/packable/extensions/io.rb', line 84 def read_with_packing(*arg) return read_without_packing(*arg) if arg.empty? || arg.first.nil? || arg.first.is_a?(Numeric) || !seekable? values = Packable::Packers.to_class_option_list(*arg).map do |klass, , original| if [:read_packed] [:read_packed].call(self) else klass.read_packed(self, ) end end return values.size > 1 ? values : values.first end |
#seekable? ⇒ Boolean
Check whether can seek without errors.
17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
# File 'lib/packable/extensions/io.rb', line 17 def seekable? if !defined?(@seekable) @seekable = # The IO class throws an exception at runtime if we try to change # position on a non-regular file. if respond_to?(:stat) stat.file? else # Duck-type the rest of this. SEEKABLE_API.all? { |m| respond_to?(m) } end end @seekable end |
#write_with_packing(*arg) ⇒ Object
80 81 82 |
# File 'lib/packable/extensions/io.rb', line 80 def write_with_packing(*arg) (arg.length <= 1 || !seekable?) ? write_without_packing(*arg) : pack_and_write(*arg) end |