Class: Async::IO::Stream

Inherits:
Object
  • Object
show all
Defined in:
lib/async/io/stream.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(io, block_size: 1024*8, sync: true) ⇒ Stream

Returns a new instance of Stream.



27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/async/io/stream.rb', line 27

def initialize(io, block_size: 1024*8, sync: true)
	@io = io
	@eof = false
	
	# We don't want Ruby to do any IO buffering.
	@io.sync = sync
	
	@block_size = block_size
	
	@read_buffer = BinaryString.new
	@write_buffer = BinaryString.new
end

Instance Attribute Details

#block_sizeObject (readonly)

Returns the value of attribute block_size.



41
42
43
# File 'lib/async/io/stream.rb', line 41

def block_size
  @block_size
end

#ioObject (readonly)

Returns the value of attribute io.



40
41
42
# File 'lib/async/io/stream.rb', line 40

def io
  @io
end

Instance Method Details

#<<(string) ⇒ Object

Writes ‘string` to the stream and returns self.



90
91
92
93
94
# File 'lib/async/io/stream.rb', line 90

def <<(string)
	write(string)
	
	return self
end

#closeObject

Closes the stream and flushes any unwritten data.



119
120
121
122
123
# File 'lib/async/io/stream.rb', line 119

def close
	flush rescue nil
	
	@io.close
end

#eof?Boolean Also known as: eof

Returns true if the stream is at file which means there is no more data to be read.

Returns:

  • (Boolean)


126
127
128
129
130
# File 'lib/async/io/stream.rb', line 126

def eof?
	fill_read_buffer if !@eof && @read_buffer.empty?
	
	return @eof && @read_buffer.empty?
end

#flushObject

Flushes buffered data to the stream.



97
98
99
100
101
102
# File 'lib/async/io/stream.rb', line 97

def flush
	unless @write_buffer.empty?
		syswrite(@write_buffer)
		@write_buffer.clear
	end
end

#gets(separator = $/) ⇒ Object



104
105
106
107
108
# File 'lib/async/io/stream.rb', line 104

def gets(separator = $/)
	flush
	
	read_until(separator)
end

#peekObject



156
157
158
159
160
# File 'lib/async/io/stream.rb', line 156

def peek
	until yield(@read_buffer) || @eof
		fill_read_buffer
	end
end

#puts(*args, separator: $/) ⇒ Object



110
111
112
113
114
115
116
# File 'lib/async/io/stream.rb', line 110

def puts(*args, separator: $/)
	args.each do |arg|
		@write_buffer << arg << separator
	end
	
	flush
end

#read(size = nil) ⇒ Object

Reads ‘size` bytes from the stream. If size is not specified, read until end of file.



44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/async/io/stream.rb', line 44

def read(size = nil)
	return '' if size == 0
	
	if size
		if size <= @block_size
			fill_read_buffer until @eof or @read_buffer.size >= size
		else
			fill_read_buffer(size - @read_buffer.size) until @eof or @read_buffer.size >= size
		end
	else
		fill_read_buffer until @eof
	end
	
	return consume_read_buffer(size)
end

#read_partial(size = nil) ⇒ Object

Read at most ‘size` bytes from the stream. Will avoid reading from the underlying stream if possible.



61
62
63
64
65
66
67
68
69
# File 'lib/async/io/stream.rb', line 61

def read_partial(size = nil)
	return '' if size == 0
	
	if @read_buffer.empty? and !@eof
		fill_read_buffer
	end
	
	return consume_read_buffer(size)
end

#read_until(pattern) ⇒ String

Efficiently read data from the stream until encountering pattern.

Parameters:

  • pattern (String)

    The pattern to match.

Returns:

  • (String)

    The contents of the stream up until the pattern, which is consumed but not returned.



137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# File 'lib/async/io/stream.rb', line 137

def read_until(pattern)
	index = @read_buffer.index(pattern)
	
	until index
		offset = @read_buffer.size

		fill_read_buffer
		
		return if @eof

		index = @read_buffer.index(pattern, offset)
	end
	
	matched = @read_buffer.slice!(0, index)
	@read_buffer.slice!(0, pattern.bytesize)
	
	return matched
end

#write(string) ⇒ Object

Writes ‘string` to the buffer. When the buffer is full or #sync is true the buffer is flushed to the underlying `io`.

Parameters:

  • string

    the string to write to the buffer.

Returns:

  • the number of bytes appended to the buffer.



75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/async/io/stream.rb', line 75

def write(string)
	if @write_buffer.empty? and string.bytesize >= @block_size
		syswrite(string)
	else
		@write_buffer << string
		
		if @write_buffer.size >= @block_size
			flush
		end
	end
	
	return string.bytesize
end