io-like 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (4) hide show
  1. data/NEWS +11 -0
  2. data/README +15 -1
  3. data/lib/io/like.rb +155 -105
  4. metadata +2 -2
data/NEWS CHANGED
@@ -6,6 +6,17 @@ detailed information is available in the rest of the documentation.
6
6
  <b>NOTE:</b> Date stamps in the following entries are in YYYY/MM/DD format.
7
7
 
8
8
 
9
+ == v0.3.0 (2009/04/29)
10
+
11
+ * Fixed the rewind method to work with write-only streams
12
+ * Fixed the read, gets, and readline methods to return partial data if they have
13
+ such data but receive low level errors before reaching a stopping point
14
+ * Renamed all private methods so that it is highly unlikely that they will be
15
+ accidentally overridden.
16
+ * Eliminated warnings caused by referencing uninitialized instance variables
17
+ * Improved the documentation for the read, gets, and readline methods
18
+
19
+
9
20
  == v0.2.0 (2009/03/11)
10
21
 
11
22
  * Added mspec tests borrowed from the rubyspec project
data/README CHANGED
@@ -78,7 +78,7 @@ A simple ROT13 codec:
78
78
  encode_rot13(@delegate_io.sysread(length))
79
79
  end
80
80
 
81
- def unbuffered_seek(offset, whence = IO::SEEKSET)
81
+ def unbuffered_seek(offset, whence = IO::SEEK_SET)
82
82
  @delegate_io.sysseek(offset, whence)
83
83
  end
84
84
 
@@ -109,6 +109,20 @@ A simple ROT13 codec:
109
109
  end
110
110
  end
111
111
 
112
+ File.open('normal_file.txt') do |f|
113
+ ROT13Filter.open(f) do |rot13|
114
+ rot13.pos = 5
115
+ puts(rot13.read) # -> vf n grfg
116
+ end
117
+ end
118
+
119
+ File.open('rot13_file.txt') do |f|
120
+ ROT13Filter.open(f) do |rot13|
121
+ rot13.pos = 5
122
+ puts(rot13.read) # -> is a test
123
+ end
124
+ end
125
+
112
126
  File.open('normal_file.txt') do |f|
113
127
  ROT13Filter.open(f) do |rot13|
114
128
  ROT13Filter.open(rot13) do |rot26| # ;-)
@@ -29,9 +29,10 @@ class IO # :nodoc:
29
29
  # ...
30
30
  # end
31
31
  #
32
- # This method must return the number of bytes written to the stream and
33
- # should raise SystemCallError on errors. Errno::EAGAIN should be raised if
34
- # no data can be written immediately and the write operation should not block.
32
+ # This method must either return the number of bytes written to the stream,
33
+ # which may be less than the length of _string_ in bytes, OR must raise an
34
+ # instance of SystemCallError. Errno::EAGAIN should be raised if no data can
35
+ # be written immediately and the write operation should not block.
35
36
  # Errno::EINTR should be raised if the write operation is interrupted before
36
37
  # any data is written.
37
38
  #
@@ -100,9 +101,9 @@ class IO # :nodoc:
100
101
  # returns +true+ and then sets a flag so that #closed? will return +true+.
101
102
  def close
102
103
  raise IOError, 'closed stream' if closed?
103
- @__io_like__closed_read = true
104
+ __io_like__close_read
104
105
  flush if writable?
105
- @__io_like__closed_write = true
106
+ __io_like__close_write
106
107
  nil
107
108
  end
108
109
 
@@ -117,11 +118,11 @@ class IO # :nodoc:
117
118
  # if #writable? returns +true+.
118
119
  def close_read
119
120
  raise IOError, 'closed stream' if closed?
120
- if @__io_like__closed_read || ! duplexed? && writable? then
121
+ if __io_like__closed_read? || ! duplexed? && writable? then
121
122
  raise IOError, 'closing non-duplex IO for reading'
122
123
  end
123
124
  if duplexed? then
124
- @__io_like__closed_read = true
125
+ __io_like__close_read
125
126
  else
126
127
  close
127
128
  end
@@ -139,12 +140,12 @@ class IO # :nodoc:
139
140
  # if #readable? returns +true+.
140
141
  def close_write
141
142
  raise IOError, 'closed stream' if closed?
142
- if @__io_like__closed_write || ! duplexed? && readable? then
143
+ if __io_like__closed_write? || ! duplexed? && readable? then
143
144
  raise IOError, 'closing non-duplex IO for reading'
144
145
  end
145
146
  if duplexed? then
146
147
  flush
147
- @__io_like__closed_write = true
148
+ __io_like__close_write
148
149
  else
149
150
  close
150
151
  end
@@ -157,8 +158,8 @@ class IO # :nodoc:
157
158
  # Returns +true+ if this object is closed or otherwise unusable for read and
158
159
  # write operations.
159
160
  def closed?
160
- (@__io_like__closed_read || ! readable?) &&
161
- (@__io_like__closed_write || ! writable?)
161
+ (__io_like__closed_read? || ! readable?) &&
162
+ (__io_like__closed_write? || ! writable?)
162
163
  end
163
164
 
164
165
  # call-seq:
@@ -302,7 +303,7 @@ class IO # :nodoc:
302
303
  # #unbuffered_write.
303
304
  def flush
304
305
  begin
305
- buffered_flush
306
+ __io_like__buffered_flush
306
307
  rescue Errno::EAGAIN, Errno::EINTR
307
308
  retry if write_ready?
308
309
  end
@@ -370,8 +371,11 @@ class IO # :nodoc:
370
371
  #
371
372
  # Calls #readline with _sep_string_ as an argument and either returns the
372
373
  # result or +nil+ if #readline raises EOFError. If #readline returns some
373
- # data, the returned data is assigned to <tt>$_</tt> and <tt>$.</tt> is set
374
- # to the value of #lineno.
374
+ # data, <tt>$.</tt> is set to the value of #lineno.
375
+ #
376
+ # <b>NOTE:</b> Due to limitations of MRI up to version 1.9.x when running
377
+ # managed (Ruby) code, this method fails to set <tt>$_</tt> to the returned
378
+ # data; however, other implementations may allow it.
375
379
  #
376
380
  # Raises IOError if #closed? returns +true+. Raises IOError unless
377
381
  # #readable? returns +true+. Raises all errors raised by #unbuffered_read
@@ -379,9 +383,9 @@ class IO # :nodoc:
379
383
  #
380
384
  # <b>NOTE:</b> When _sep_string_ is not +nil+, this method ignores
381
385
  # Errno::EAGAIN and Errno::EINTR raised by #unbuffered_read. Therefore,
382
- # this method always blocks. Aside from that exception and the conversion
383
- # of EOFError results into +nil+ results, this method will also raise the
384
- # same errors and block at the same times as #unbuffered_read.
386
+ # this method will always block in that case. Aside from that exception,
387
+ # this method will raise the same errors and block at the same times as
388
+ # #unbuffered_read.
385
389
  def gets(sep_string = $/)
386
390
  # Set the last read line in the global.
387
391
  $_ = readline(sep_string)
@@ -484,8 +488,8 @@ class IO # :nodoc:
484
488
  # also raise the same errors and block at the same times as those functions.
485
489
  def pos
486
490
  # Flush the internal write buffer for writable, non-duplexed objects.
487
- buffered_flush if writable? && ! duplexed?
488
- buffered_seek(0, IO::SEEK_CUR)
491
+ __io_like__buffered_flush if writable? && ! duplexed?
492
+ __io_like__buffered_seek(0, IO::SEEK_CUR)
489
493
  end
490
494
  alias :tell :pos
491
495
 
@@ -616,7 +620,7 @@ class IO # :nodoc:
616
620
  line = arg.nil? ?
617
621
  'nil' :
618
622
  arg.kind_of?(Array) ?
619
- array_join(arg, ors) :
623
+ __io_like__array_join(arg, ors) :
620
624
  arg.to_s
621
625
  line += ors if line.index(ors, -ors.length).nil?
622
626
  write(line)
@@ -633,8 +637,10 @@ class IO # :nodoc:
633
637
  # left to fulfill the request. If the read starts at the end of data, +nil+
634
638
  # is returned.
635
639
  #
636
- # If _length_ is unspecified or +nil+, all remaining data is returned. If
637
- # no data would be returned at all, an empty String is returned.
640
+ # If _length_ is unspecified or +nil+, an attempt to return all remaining
641
+ # data is made. Partial data will be returned if a low-level error is
642
+ # raised after some data is retrieved. If no data would be returned at all,
643
+ # an empty String is returned.
638
644
  #
639
645
  # If _buffer_ is specified, it will be converted to a String using its
640
646
  # +to_str+ method if necessary and will be filled with the returned data if
@@ -657,15 +663,18 @@ class IO # :nodoc:
657
663
  # Read and return everything.
658
664
  begin
659
665
  loop do
660
- buffer << buffered_read(4096)
666
+ buffer << __io_like__buffered_read(4096)
661
667
  end
662
668
  rescue EOFError
663
669
  # Ignore this.
670
+ rescue SystemCallError
671
+ # Reraise the error if there is nothing to return.
672
+ raise if buffer.empty?
664
673
  end
665
674
  else
666
675
  # Read and return up to length bytes.
667
676
  begin
668
- buffer << buffered_read(length)
677
+ buffer << __io_like__buffered_read(length)
669
678
  rescue EOFError
670
679
  # Return nil to the caller at end of file when requesting a specific
671
680
  # amount of data.
@@ -706,7 +715,7 @@ class IO # :nodoc:
706
715
  # provides the #unbuffered_read method but may not always be open in a
707
716
  # readable mode.
708
717
  def readable?
709
- ! @__io_like__closed_read && respond_to?(:unbuffered_read, true)
718
+ ! __io_like__closed_read? && respond_to?(:unbuffered_read, true)
710
719
  end
711
720
 
712
721
  # call-seq:
@@ -751,7 +760,7 @@ class IO # :nodoc:
751
760
  # exception, this method will also raise the same errors and block at the
752
761
  # same times as #unbuffered_read.
753
762
  def readchar
754
- buffered_read(1)[0]
763
+ __io_like__buffered_read(1)[0]
755
764
  rescue Errno::EAGAIN, Errno::EINTR
756
765
  retry if read_ready?
757
766
  end
@@ -760,14 +769,27 @@ class IO # :nodoc:
760
769
  # ios.readline(sep_string = $/) -> string
761
770
  #
762
771
  # Returns the next line from the stream, where lines are separated by
763
- # _sep_string_. Increments #lineno.
772
+ # _sep_string_. Increments #lineno by <tt>1</tt> for each call regardless
773
+ # of the value of _sep_string_.
774
+ #
775
+ # If _sep_string_ is not +nil+ and not a String, it is first converted to a
776
+ # String using its +to_str+ method and processing continues as follows.
764
777
  #
765
778
  # If _sep_string_ is +nil+, a line is defined as the remaining contents of
766
- # the stream. If _sep_string_ is not a String, it is converted to one using
767
- # its +to_str+ method. If _sep_string_ is empty, a paragraph is returned,
768
- # where a paragraph is defined as data followed by 2 or more successive
769
- # newline characters (only 2 newlines are returned at the end of the
770
- # returned data).
779
+ # the stream. Partial data will be returned if a low-level error of any
780
+ # kind is raised after some data is retrieved. This is equivalent to
781
+ # calling #read without any arguments except that this method will raise an
782
+ # EOFError if called at the end of the stream.
783
+ #
784
+ # If _sep_string_ is an empty String, a paragraph is returned, where a
785
+ # paragraph is defined as data followed by 2 or more successive newline
786
+ # characters. A maximum of 2 newlines are returned at the end of the
787
+ # returned data. Fewer may be returned if the stream ends before at least 2
788
+ # successive newlines are seen.
789
+ #
790
+ # Any other value for _sep_string_ is used as a delimiter to mark the end of
791
+ # a line. The returned data includes this delimiter unless the stream ends
792
+ # before the delimiter is seen.
771
793
  #
772
794
  # In any case, the end of the stream terminates the current line.
773
795
  #
@@ -777,8 +799,8 @@ class IO # :nodoc:
777
799
  #
778
800
  # <b>NOTE:</b> When _sep_string_ is not +nil+, this method ignores
779
801
  # Errno::EAGAIN and Errno::EINTR raised by #unbuffered_read. Therefore,
780
- # this method always blocks. Aside from that exception, this method will
781
- # also raise the same errors and block at the same times as
802
+ # this method will always block in that case. Aside from that exception,
803
+ # this method will raise the same errors and block at the same times as
782
804
  # #unbuffered_read.
783
805
  def readline(sep_string = $/)
784
806
  # Ensure that sep_string is either nil or a String.
@@ -792,7 +814,7 @@ class IO # :nodoc:
792
814
  # A nil line separator means that the user wants to capture all the
793
815
  # remaining input.
794
816
  loop do
795
- buffer << buffered_read(4096)
817
+ buffer << __io_like__buffered_read(4096)
796
818
  end
797
819
  else
798
820
  begin
@@ -806,7 +828,7 @@ class IO # :nodoc:
806
828
  # Add each character from the input to the buffer until either the
807
829
  # buffer has the right ending or the end of the input is reached.
808
830
  while buffer.index(sep_string, -sep_string.length).nil? &&
809
- (char = buffered_read(1)) do
831
+ (char = __io_like__buffered_read(1)) do
810
832
  buffer << char
811
833
  end
812
834
 
@@ -814,7 +836,7 @@ class IO # :nodoc:
814
836
  # If the user requested paragraphs instead of lines, we need to
815
837
  # consume and discard all newlines remaining at the front of the
816
838
  # input.
817
- while char == "\n" && (char = buffered_read(1)) do
839
+ while char == "\n" && (char = __io_like__buffered_read(1)) do
818
840
  nil
819
841
  end
820
842
  # Put back the last character.
@@ -824,7 +846,8 @@ class IO # :nodoc:
824
846
  retry if read_ready?
825
847
  end
826
848
  end
827
- rescue EOFError
849
+ rescue EOFError, SystemCallError
850
+ # Reraise the error if there is nothing to return.
828
851
  raise if buffer.empty?
829
852
  end
830
853
  # Increment the number of times this method has returned a "line".
@@ -889,9 +912,9 @@ class IO # :nodoc:
889
912
  buffer.slice!(0..-1)
890
913
 
891
914
  # Read and return up to length bytes.
892
- if internal_read_buffer.empty? then
915
+ if __io_like__internal_read_buffer.empty? then
893
916
  begin
894
- buffer << buffered_read(length)
917
+ buffer << __io_like__buffered_read(length)
895
918
  rescue Errno::EAGAIN, Errno::EINTR
896
919
  retry if read_ready?
897
920
  end
@@ -899,7 +922,7 @@ class IO # :nodoc:
899
922
  raise IOError, 'closed stream' if closed?
900
923
  raise IOError, 'not opened for reading' unless readable?
901
924
 
902
- buffer << internal_read_buffer.slice!(0, length)
925
+ buffer << __io_like__internal_read_buffer.slice!(0, length)
903
926
  end
904
927
  buffer
905
928
  end
@@ -909,7 +932,7 @@ class IO # :nodoc:
909
932
  #
910
933
  # Sets the position of the file pointer to the beginning of the stream and
911
934
  # returns 0 when complete. The lineno attribute is reset to 0 if
912
- # successful.
935
+ # successful and the stream is readable according to #readable?.
913
936
  #
914
937
  # As a side effect, the internal read and write buffers are flushed.
915
938
  #
@@ -921,7 +944,8 @@ class IO # :nodoc:
921
944
  # also raise the same errors and block at the same times as those functions.
922
945
  def rewind
923
946
  seek(0, IO::SEEK_SET)
924
- self.lineno = 0
947
+ self.lineno = 0 if readable?
948
+ 0
925
949
  end
926
950
 
927
951
  # call-seq:
@@ -944,7 +968,7 @@ class IO # :nodoc:
944
968
  # #unbuffered_write (when the internal write buffer is not empty), it will
945
969
  # also raise the same errors and block at the same times as those functions.
946
970
  def seek(offset, whence = IO::SEEK_SET)
947
- buffered_seek(offset, whence)
971
+ __io_like__buffered_seek(offset, whence)
948
972
  0
949
973
  end
950
974
 
@@ -1009,12 +1033,12 @@ class IO # :nodoc:
1009
1033
 
1010
1034
  raise IOError, 'closed stream' if closed?
1011
1035
  raise IOError, 'not opened for reading' unless readable?
1012
- unless internal_read_buffer.empty? then
1036
+ unless __io_like__internal_read_buffer.empty? then
1013
1037
  raise IOError, 'sysread on buffered IO'
1014
1038
  end
1015
1039
 
1016
1040
  # Flush the internal write buffer for writable, non-duplexed objects.
1017
- buffered_flush if writable? && ! duplexed?
1041
+ __io_like__buffered_flush if writable? && ! duplexed?
1018
1042
 
1019
1043
  buffer << unbuffered_read(length)
1020
1044
  end
@@ -1036,9 +1060,11 @@ class IO # :nodoc:
1036
1060
  # raise the same errors and block at the same times as that function.
1037
1061
  def sysseek(offset, whence = IO::SEEK_SET)
1038
1062
  raise IOError, 'closed stream' if closed?
1039
- raise Errno::ESPIPE, 'Illegal seek' unless seekable?
1040
- raise IOError, 'sysseek on buffered IO' unless internal_read_buffer.empty?
1041
- unless internal_write_buffer.empty? then
1063
+ raise Errno::ESPIPE unless seekable?
1064
+ unless __io_like__internal_read_buffer.empty? then
1065
+ raise IOError, 'sysseek on buffered IO'
1066
+ end
1067
+ unless __io_like__internal_write_buffer.empty? then
1042
1068
  warn('warning: sysseek on buffered IO')
1043
1069
  end
1044
1070
 
@@ -1062,15 +1088,15 @@ class IO # :nodoc:
1062
1088
  def syswrite(string)
1063
1089
  raise IOError, 'closed stream' if closed?
1064
1090
  raise IOError, 'not opened for writing' unless writable?
1065
- unless internal_write_buffer.empty? then
1091
+ unless __io_like__internal_write_buffer.empty? then
1066
1092
  warn('warning: syswrite on buffered IO')
1067
1093
  end
1068
1094
 
1069
1095
  # Flush the internal read buffer and set the unbuffered position to the
1070
1096
  # buffered position when dealing with non-duplexed objects.
1071
- unless duplexed? || internal_read_buffer.empty? then
1072
- unbuffered_seek(-internal_read_buffer.length, IO::SEEK_CUR)
1073
- internal_read_buffer.slice!(0..-1)
1097
+ unless duplexed? || __io_like__internal_read_buffer.empty? then
1098
+ unbuffered_seek(-__io_like__internal_read_buffer.length, IO::SEEK_CUR)
1099
+ __io_like__internal_read_buffer.slice!(0..-1)
1074
1100
  end
1075
1101
 
1076
1102
  unbuffered_write(string)
@@ -1107,7 +1133,7 @@ class IO # :nodoc:
1107
1133
  def unread(string)
1108
1134
  raise IOError, 'closed stream' if closed?
1109
1135
  raise IOError, 'not opened for reading' unless readable?
1110
- internal_read_buffer.insert(0, string.to_s)
1136
+ __io_like__internal_read_buffer.insert(0, string.to_s)
1111
1137
  nil
1112
1138
  end
1113
1139
 
@@ -1142,7 +1168,7 @@ class IO # :nodoc:
1142
1168
  # provides the #unbuffered_write method but may not always be open in a
1143
1169
  # writable mode.
1144
1170
  def writable?
1145
- ! @__io_like__closed_write && respond_to?(:unbuffered_write, true)
1171
+ ! __io_like__closed_write? && respond_to?(:unbuffered_write, true)
1146
1172
  end
1147
1173
 
1148
1174
  # call-seq:
@@ -1168,7 +1194,8 @@ class IO # :nodoc:
1168
1194
  bytes_written = 0
1169
1195
  while bytes_written < string.length do
1170
1196
  begin
1171
- bytes_written += buffered_write(string.to_s.slice(bytes_written..-1))
1197
+ bytes_written +=
1198
+ __io_like__buffered_write(string.to_s.slice(bytes_written..-1))
1172
1199
  rescue Errno::EAGAIN, Errno::EINTR
1173
1200
  retry if write_ready?
1174
1201
  end
@@ -1179,7 +1206,7 @@ class IO # :nodoc:
1179
1206
  private
1180
1207
 
1181
1208
  # call-seq:
1182
- # ios.buffered_flush -> 0
1209
+ # ios.__io_like__buffered_flush -> 0
1183
1210
  #
1184
1211
  # Attempts to completely flush the internal write buffer to the data stream.
1185
1212
  #
@@ -1188,18 +1215,20 @@ class IO # :nodoc:
1188
1215
  # <b>NOTE:</b> Because this method relies on #unbuffered_write, it raises
1189
1216
  # all errors raised by #unbuffered_write and blocks when #unbuffered_write
1190
1217
  # blocks.
1191
- def buffered_flush
1218
+ def __io_like__buffered_flush
1192
1219
  raise IOError, 'closed stream' if closed?
1193
1220
  raise IOError, 'not opened for writing' unless writable?
1194
1221
 
1195
- until internal_write_buffer.empty? do
1196
- internal_write_buffer.slice!(0, unbuffered_write(internal_write_buffer))
1222
+ until __io_like__internal_write_buffer.empty? do
1223
+ __io_like__internal_write_buffer.slice!(
1224
+ 0, unbuffered_write(__io_like__internal_write_buffer)
1225
+ )
1197
1226
  end
1198
1227
  0
1199
1228
  end
1200
1229
 
1201
1230
  # call-seq:
1202
- # ios.buffered_read(length) -> string
1231
+ # ios.__io_like__buffered_read(length) -> string
1203
1232
  #
1204
1233
  # Reads at most _length_ bytes first from an internal read buffer followed
1205
1234
  # by the underlying stream if necessary and returns the resulting buffer.
@@ -1210,7 +1239,7 @@ class IO # :nodoc:
1210
1239
  # <b>NOTE:</b> Because this method relies on #unbuffered_read, it raises all
1211
1240
  # errors raised by #unbuffered_read and blocks when #unbuffered_read blocks
1212
1241
  # whenever the internal read buffer is unable to fulfill the request.
1213
- def buffered_read(length)
1242
+ def __io_like__buffered_read(length)
1214
1243
  # Check the validity of the method arguments.
1215
1244
  raise ArgumentError, "non-positive length #{length} given" if length < 0
1216
1245
 
@@ -1218,30 +1247,30 @@ class IO # :nodoc:
1218
1247
  raise IOError, 'not opened for reading' unless readable?
1219
1248
 
1220
1249
  # Flush the internal write buffer for writable, non-duplexed objects.
1221
- buffered_flush if writable? && ! duplexed?
1250
+ __io_like__buffered_flush if writable? && ! duplexed?
1222
1251
 
1223
1252
  # Ensure that the internal read buffer has at least enough data to satisfy
1224
1253
  # the request.
1225
- if internal_read_buffer.length < length then
1226
- unbuffered_length = length - internal_read_buffer.length
1254
+ if __io_like__internal_read_buffer.length < length then
1255
+ unbuffered_length = length - __io_like__internal_read_buffer.length
1227
1256
  unbuffered_length = fill_size if unbuffered_length < fill_size
1228
1257
 
1229
1258
  begin
1230
- internal_read_buffer << unbuffered_read(unbuffered_length)
1259
+ __io_like__internal_read_buffer << unbuffered_read(unbuffered_length)
1231
1260
  rescue EOFError, SystemCallError
1232
1261
  # Reraise the error if there is no data to return.
1233
- raise if internal_read_buffer.empty?
1262
+ raise if __io_like__internal_read_buffer.empty?
1234
1263
  end
1235
1264
  end
1236
1265
 
1237
1266
  # Read from the internal read buffer.
1238
- buffer = internal_read_buffer.slice!(0, length)
1267
+ buffer = __io_like__internal_read_buffer.slice!(0, length)
1239
1268
 
1240
1269
  buffer
1241
1270
  end
1242
1271
 
1243
1272
  # call-seq:
1244
- # ios.buffered_seek(offset[, whence]) -> integer
1273
+ # ios.__io_like__buffered_seek(offset[, whence]) -> integer
1245
1274
  #
1246
1275
  # Sets the current data position to _offset_ based on the setting of
1247
1276
  # _whence_. If _whence_ is unspecified or IO::SEEK_SET, _offset_ counts
@@ -1260,37 +1289,40 @@ class IO # :nodoc:
1260
1289
  # <b>NOTE:</b> Because this method relies on #unbuffered_seek and
1261
1290
  # #unbuffered_write (when the internal write buffer is not empty), it will
1262
1291
  # raise the same errors and block at the same times as those functions.
1263
- def buffered_seek(offset, whence = IO::SEEK_SET)
1292
+ def __io_like__buffered_seek(offset, whence = IO::SEEK_SET)
1264
1293
  raise IOError, 'closed stream' if closed?
1265
- raise Errno::ESPIPE, 'Illegal seek' unless seekable?
1294
+ raise Errno::ESPIPE unless seekable?
1266
1295
 
1267
1296
  if whence == IO::SEEK_CUR && offset == 0 then
1268
1297
  # The seek is only determining the current position, so return the
1269
1298
  # buffered position based on the read buffer if it's not empty and the
1270
1299
  # write buffer otherwise.
1271
- internal_read_buffer.empty? ?
1272
- unbuffered_seek(0, IO::SEEK_CUR) + internal_write_buffer.length :
1273
- unbuffered_seek(0, IO::SEEK_CUR) - internal_read_buffer.length
1300
+ __io_like__internal_read_buffer.empty? ?
1301
+ unbuffered_seek(0, IO::SEEK_CUR) +
1302
+ __io_like__internal_write_buffer.length :
1303
+ unbuffered_seek(0, IO::SEEK_CUR) -
1304
+ __io_like__internal_read_buffer.length
1274
1305
  elsif whence == IO::SEEK_CUR && offset > 0 &&
1275
- internal_write_buffer.empty? &&
1276
- offset <= internal_read_buffer.length then
1306
+ __io_like__internal_write_buffer.empty? &&
1307
+ offset <= __io_like__internal_read_buffer.length then
1277
1308
  # The seek is within the read buffer, so just discard a sufficient
1278
1309
  # amount of the buffer and report the new buffered position.
1279
- internal_read_buffer.slice!(0, offset)
1280
- unbuffered_seek(0, IO::SEEK_CUR) - internal_read_buffer.length
1310
+ __io_like__internal_read_buffer.slice!(0, offset)
1311
+ unbuffered_seek(0, IO::SEEK_CUR) -
1312
+ __io_like__internal_read_buffer.length
1281
1313
  else
1282
1314
  # The seek target is outside of the buffers, so flush the buffers and
1283
1315
  # jump to the new position.
1284
1316
  if whence == IO::SEEK_CUR then
1285
1317
  # Adjust relative offsets based on the current buffered offset.
1286
- offset += internal_read_buffer.empty? ?
1287
- internal_write_buffer.length :
1288
- -internal_read_buffer.length
1318
+ offset += __io_like__internal_read_buffer.empty? ?
1319
+ __io_like__internal_write_buffer.length :
1320
+ -__io_like__internal_read_buffer.length
1289
1321
  end
1290
1322
 
1291
1323
  # Flush the internal buffers.
1292
- internal_read_buffer.slice!(0..-1)
1293
- buffered_flush if writable?
1324
+ __io_like__internal_read_buffer.slice!(0..-1)
1325
+ __io_like__buffered_flush if writable?
1294
1326
 
1295
1327
  # Move the data stream's position as requested.
1296
1328
  unbuffered_seek(offset, whence)
@@ -1298,7 +1330,7 @@ class IO # :nodoc:
1298
1330
  end
1299
1331
 
1300
1332
  # call-seq:
1301
- # ios.buffered_write(string) -> integer
1333
+ # ios.__io_like__buffered_write(string) -> integer
1302
1334
  #
1303
1335
  # Writes _string_ to the internal write buffer and returns the number of
1304
1336
  # bytes written. If the internal write buffer is overfilled by _string_, it
@@ -1311,51 +1343,72 @@ class IO # :nodoc:
1311
1343
  # all errors raised by #unbuffered_write and blocks when #unbuffered_write
1312
1344
  # blocks whenever the internal write buffer is unable to fulfill the
1313
1345
  # request.
1314
- def buffered_write(string)
1346
+ def __io_like__buffered_write(string)
1315
1347
  raise IOError, 'closed stream' if closed?
1316
1348
  raise IOError, 'not opened for writing' unless writable?
1317
1349
 
1318
1350
  # Flush the internal read buffer and set the unbuffered position to the
1319
1351
  # buffered position when dealing with non-duplexed objects.
1320
- unless duplexed? || internal_read_buffer.empty? then
1321
- unbuffered_seek(-internal_read_buffer.length, IO::SEEK_CUR)
1322
- internal_read_buffer.slice!(0..-1)
1352
+ unless duplexed? || __io_like__internal_read_buffer.empty? then
1353
+ unbuffered_seek(-__io_like__internal_read_buffer.length, IO::SEEK_CUR)
1354
+ __io_like__internal_read_buffer.slice!(0..-1)
1323
1355
  end
1324
1356
 
1325
1357
  bytes_written = 0
1326
1358
  if sync then
1327
1359
  # Flush the internal write buffer and then bypass it when in synchronous
1328
1360
  # mode.
1329
- buffered_flush
1361
+ __io_like__buffered_flush
1330
1362
  bytes_written = unbuffered_write(string)
1331
1363
  else
1332
- if internal_write_buffer.length + string.length >= flush_size then
1364
+ if __io_like__internal_write_buffer.length + string.length >= flush_size then
1333
1365
  # The tipping point for the write buffer would be surpassed by this
1334
1366
  # request, so flush everything.
1335
- buffered_flush
1367
+ __io_like__buffered_flush
1336
1368
  bytes_written = unbuffered_write(string)
1337
1369
  else
1338
1370
  # The buffer can absorb the entire request.
1339
- internal_write_buffer << string
1371
+ __io_like__internal_write_buffer << string
1340
1372
  bytes_written = string.length
1341
1373
  end
1342
1374
  end
1343
- rescue SystemCallError
1344
- raise if bytes_written == 0
1345
- else
1346
1375
  return bytes_written
1347
1376
  end
1348
1377
 
1349
1378
  # Returns a reference to the internal read buffer.
1350
- def internal_read_buffer
1379
+ def __io_like__internal_read_buffer
1351
1380
  @__io_like__read_buffer ||= ''
1352
1381
  end
1353
1382
 
1354
1383
  # Returns a reference to the internal write buffer.
1355
- def internal_write_buffer
1384
+ def __io_like__internal_write_buffer
1356
1385
  @__io_like__write_buffer ||= ''
1357
1386
  end
1358
1387
 
1388
+ # Returns +true+ if this object has been closed for reading; otherwise,
1389
+ # returns +false+.
1390
+ def __io_like__closed_read?
1391
+ @__io_like__closed_read ||= false
1392
+ end
1393
+
1394
+ # Arranges for #__io_like__closed_read? to return +true+.
1395
+ def __io_like__close_read
1396
+ @__io_like__closed_read = true
1397
+ nil
1398
+ end
1399
+
1400
+ # Returns +true+ if this object has been closed for writing; otherwise,
1401
+ # returns +false+.
1402
+ def __io_like__closed_write?
1403
+ @__io_like__closed_write ||= false
1404
+ end
1405
+
1406
+ # Arranges for #__io_like__closed_write? to return +true+.
1407
+ def __io_like__close_write
1408
+ @__io_like__closed_write = true
1409
+ nil
1410
+ end
1411
+
1359
1412
  # This method joins the elements of _array_ together with _separator_
1360
1413
  # between each element and returns the result. _seen_ is a list of object
1361
1414
  # IDs representing arrays which have already started processing.
@@ -1375,21 +1428,18 @@ class IO # :nodoc:
1375
1428
  #
1376
1429
  # Things get progressively worse as the nesting and recursion become more
1377
1430
  # convoluted.
1378
- def array_join(array, separator, seen = [])
1379
- first = true
1431
+ def __io_like__array_join(array, separator, seen = [])
1380
1432
  seen.push(array.object_id)
1433
+ need_separator = false
1381
1434
  result = array.inject('') do |memo, item|
1382
- if first then
1383
- first = false
1384
- else
1385
- memo << separator
1386
- end
1435
+ memo << separator if need_separator
1436
+ need_separator = true
1387
1437
 
1388
1438
  memo << if item.kind_of?(Array) then
1389
1439
  if seen.include?(item.object_id) then
1390
1440
  '[...]'
1391
1441
  else
1392
- array_join(item, separator, seen)
1442
+ __io_like__array_join(item, separator, seen)
1393
1443
  end
1394
1444
  else
1395
1445
  item.to_s
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: io-like
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeremy Bopp
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-03-11 00:00:00 -05:00
12
+ date: 2009-04-29 00:00:00 -05:00
13
13
  default_executable:
14
14
  dependencies: []
15
15