thread_queues 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c6ca817b3ff688ca8b86e3999a607c3df3b1303e
4
- data.tar.gz: df412baf2c93ed8012664f669948277e01b45169
3
+ metadata.gz: ccec23b5ab55ae4400aee2fe167c800f77f8a92c
4
+ data.tar.gz: 4949876041f7070682817bb1429cc83264b96630
5
5
  SHA512:
6
- metadata.gz: c5b7b8fdfda30821ab583c5eaf9a518876aa85b80795cd85430c355a93c7a914d545e0639697ed9a972d8f1cfcde4f33d420cff2256bdfa639288a5a729745fd
7
- data.tar.gz: 3828274cd1da77a1d9f2209c75eaf44a0a16aefc697b90f3603149ba2b9cb586716677a3b8743c08b22b22d85ab819853b284f85ce3fc71cc4fa94bf54d4dae1
6
+ metadata.gz: c9a5c77bba20b9eb89f9fa96976d4e2483a4146641dbbbed241bbd213b30f7709661cf1fdebfcfa9dc25c1eaf1fc66fb0dadf618efeed6f4ef86dc5b78ac289f
7
+ data.tar.gz: c2fd0bfa948a3f8c9e32b685ff1f78da6f3a840ae3108d4c9c0bd9af4c99bf0f9f4519504b3b6eef303a4bf60f206582ca145004d868b31d1133920954b223ec
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.2
1
+ 0.0.3
@@ -1,18 +1,34 @@
1
1
  require "monitor"
2
2
 
3
3
  class ThreadQueues::StringBuffer
4
+ attr_reader :lineno, :pos
5
+
4
6
  def initialize(queue)
5
7
  @queue = queue
6
8
  @buffer = ""
7
9
  @mutex = Monitor.new
10
+ @lineno = 0
11
+ @pos = 0
8
12
  end
9
13
 
10
- def gets
14
+ def gets(sep = "\n", limit = nil)
15
+ if limit == nil && !sep.is_a?(String)
16
+ limit = sep
17
+ sep = "\n"
18
+ end
19
+
11
20
  @mutex.synchronize do
12
21
  loop do
13
- if match = @buffer.match(/\A(.+)\n/)
14
- @buffer.gsub!(/\A(.+)\n/, "")
15
- return match[0]
22
+ if match = @buffer.match(/\A([\s\S]+?)#{Regexp.escape(sep)}/)
23
+ take = match[0]
24
+ if limit && take.length > limit
25
+ take = take.slice(0, limit)
26
+ end
27
+
28
+ @buffer.gsub!(/\A#{Regexp.escape(take)}/, "")
29
+ @lineno += 1
30
+ @pos += match[0].bytesize
31
+ return take
16
32
  end
17
33
 
18
34
  begin
@@ -25,31 +41,121 @@ class ThreadQueues::StringBuffer
25
41
  end
26
42
  end
27
43
 
28
- def read(length)
44
+ def each_line(&blk)
45
+ with_enumerator(blk) do |y|
46
+ begin
47
+ loop do
48
+ y << gets
49
+ end
50
+ rescue EOFError
51
+ end
52
+ end
53
+ end
54
+
55
+ def each_char(&blk)
56
+ with_enumerator(blk) do |y|
57
+ each_chunk do |chunk|
58
+ chunk.each_char do |char|
59
+ y << char
60
+ end
61
+ end
62
+ end
63
+ end
64
+
65
+ def each_byte(&blk)
66
+ with_enumerator(blk) do |y|
67
+ each_chunk do |chunk|
68
+ chunk.each_byte do |byte|
69
+ y << byte
70
+ end
71
+ end
72
+ end
73
+ end
74
+
75
+ def read(length = nil, outbuf = nil)
76
+ return read_all if length == nil
77
+
78
+ content = nil
79
+
29
80
  @mutex.synchronize do
30
81
  loop do
31
82
  if @buffer.length >= length
32
- return @buffer.slice!(0, length)
83
+ content = @buffer.slice!(0, length)
84
+ @pos += content.bytesize
85
+ break
33
86
  end
34
87
 
35
88
  begin
36
89
  store_more_in_buffer
37
90
  rescue EOFError => e
38
- return rest_of_buffer if @buffer.length > 0
39
- raise e
91
+ if @buffer.length > 0
92
+ content = rest_of_buffer
93
+ break
94
+ end
95
+
96
+ # Return nil if length is set like a normal IO - otherwise an empty string.
97
+ if length
98
+ return nil
99
+ else
100
+ content = ""
101
+ end
40
102
  end
41
103
  end
42
104
  end
105
+
106
+ if outbuf
107
+ outbuf.clear
108
+ outbuf << content
109
+ end
110
+
111
+ return content
112
+ end
113
+
114
+ def empty?
115
+ if @pos == 0 && !@closed
116
+ begin
117
+ store_more_in_buffer
118
+ rescue EOFError
119
+ end
120
+ end
121
+
122
+ @pos == 0 && @buffer.empty?
43
123
  end
44
124
 
45
125
  private
46
126
 
127
+ def read_all
128
+ str = ""
129
+ each_line do |line|
130
+ str << line
131
+ end
132
+
133
+ return str
134
+ end
135
+
47
136
  def rest_of_buffer
48
137
  buffer = @buffer
49
138
  @buffer = ""
139
+ @pos += buffer.bytesize
50
140
  return buffer
51
141
  end
52
142
 
143
+ def each_chunk
144
+ begin
145
+ loop do
146
+ begin
147
+ content = @queue.pop.to_s
148
+ @pos += content.bytesize
149
+ yield content
150
+ rescue Exception => e
151
+ raise EOFError, "No live threads left. Deadlock?" if e.message == "No live threads left. Deadlock?"
152
+ raise e
153
+ end
154
+ end
155
+ rescue EOFError
156
+ end
157
+ end
158
+
53
159
  def store_more_in_buffer
54
160
  @mutex.synchronize do
55
161
  begin
@@ -60,4 +166,16 @@ private
60
166
  end
61
167
  end
62
168
  end
169
+
170
+ def with_enumerator(blk)
171
+ enum = Enumerator.new do |y|
172
+ yield(y)
173
+ end
174
+
175
+ if blk
176
+ enum.each(&blk)
177
+ else
178
+ enum
179
+ end
180
+ end
63
181
  end
@@ -1,8 +1,10 @@
1
1
  require "spec_helper"
2
2
 
3
3
  describe ThreadQueues::StringBuffer do
4
- it "works with gets" do
5
- queue = ThreadQueues::BlockingQueue.new
4
+ let(:queue) { ThreadQueues::BlockingQueue.new }
5
+ let(:lines) { lines = ["hello\n", "my\r\n", "name\n", "is kasper\n"] }
6
+ let(:whole_string) { lines.join("") }
7
+ let(:string_buffer) {
6
8
  string_buffer = ThreadQueues::StringBuffer.new(queue)
7
9
 
8
10
  Thread.new do
@@ -17,35 +19,132 @@ describe ThreadQueues::StringBuffer do
17
19
  queue.close
18
20
  end
19
21
 
20
- string_buffer.gets.should eq "hello\n"
21
- string_buffer.gets.should eq "my\r\n"
22
- string_buffer.gets.should eq "name\n"
23
- string_buffer.gets.should eq "is kasper\n"
22
+ string_buffer
23
+ }
24
24
 
25
- expect { string_buffer.gets }.to raise_error(EOFError)
25
+ describe "#gets" do
26
+ it "returns lines as default" do
27
+ string_buffer.gets.should eq "hello\n"
28
+ string_buffer.gets.should eq "my\r\n"
29
+ string_buffer.gets.should eq "name\n"
30
+ string_buffer.gets.should eq "is kasper\n"
31
+
32
+ expect { string_buffer.gets }.to raise_error(EOFError)
33
+ end
34
+
35
+ it "accepts custom seperators" do
36
+ string_buffer.gets("\r").should eq "hello\nmy\r"
37
+ string_buffer.gets("\r").should eq "\nname\nis kasper\n"
38
+ expect { string_buffer.gets }.to raise_error(EOFError)
39
+ end
40
+
41
+ it "accepts a limit" do
42
+ string_buffer.gets(3).should eq "hel"
43
+ string_buffer.gets(10).should eq "lo\n"
44
+ string_buffer.gets(10).should eq "my\r\n"
45
+ end
46
+
47
+ it "accepts both a limit and a custom seperator" do
48
+ string_buffer.gets("\r", 3).should eq "hel"
49
+ string_buffer.gets("\r", 999).should eq "lo\nmy\r"
50
+ string_buffer.gets("\r", 999).should eq "\nname\nis kasper\n"
51
+ end
26
52
  end
27
53
 
28
- it "should read the right lengths" do
29
- queue = ThreadQueues::BufferedQueue.new(5)
30
- string_buffer = ThreadQueues::StringBuffer.new(queue)
54
+ describe "#read" do
55
+ it "with a given length" do
56
+ string_buffer.read(6).should eq "hello\n"
57
+ string_buffer.read(4).should eq "my\r\n"
58
+ string_buffer.read(5).should eq "name\n"
59
+ string_buffer.read(10).should eq "is kasper\n"
31
60
 
32
- Thread.new do
33
- Thread.current.abort_on_exception = true
61
+ expect { string_buffer.gets }.to raise_error(EOFError)
62
+ end
34
63
 
35
- queue.push("hel")
36
- queue.push("lo\n")
37
- queue.push("my\r\n")
38
- queue.push("nam")
39
- queue.push("e\n")
40
- queue.push("is kasper\n")
41
- queue.close
64
+ it "reads the whole thing when length is nil" do
65
+ string_buffer.read.should eq whole_string
66
+ end
67
+
68
+ it "supports outbuf argument" do
69
+ outbuf = "kasper"
70
+ string_buffer.read(6, outbuf).should eq "hello\n"
71
+ outbuf.should eq "hello\n"
72
+ end
73
+
74
+ it "should return the correct values when it has reaches eof" do
75
+ string_buffer.read.should eq whole_string
76
+ string_buffer.read.should eq ""
77
+ string_buffer.read(5).should eq nil
42
78
  end
79
+ end
80
+
81
+ it "#each_line" do
82
+ count = 0
83
+ string_buffer.each_line do |line|
84
+ line.should eq lines[count]
85
+ count += 1
86
+ end
87
+ end
88
+
89
+ it "#each_char" do
90
+ count = 0
91
+ string_buffer.each_char do |char|
92
+ char.should eq whole_string.slice(count, 1)
93
+ count += 1
94
+ end
95
+
96
+ string_buffer.pos.should eq 25
97
+ end
98
+
99
+ it "#each_byte" do
100
+ count = 0
101
+ string_buffer.each_byte do |byte|
102
+ byte.should eq whole_string.bytes[count]
103
+ count += 1
104
+ end
105
+
106
+ string_buffer.pos.should eq 25
107
+ end
43
108
 
44
- string_buffer.read(6).should eq "hello\n"
45
- string_buffer.read(4).should eq "my\r\n"
46
- string_buffer.read(5).should eq "name\n"
47
- string_buffer.read(10).should eq "is kasper\n"
109
+ it "#lineno" do
110
+ string_buffer.lineno.should eq 0
111
+
112
+ string_buffer.gets
113
+ string_buffer.lineno.should eq 1
114
+
115
+ string_buffer.gets
116
+ string_buffer.lineno.should eq 2
117
+
118
+ string_buffer.gets
119
+ string_buffer.lineno.should eq 3
120
+
121
+ string_buffer.gets
122
+ string_buffer.lineno.should eq 4
48
123
 
49
124
  expect { string_buffer.gets }.to raise_error(EOFError)
125
+ string_buffer.lineno.should eq 4
126
+ end
127
+
128
+ it "#pos" do
129
+ string_buffer.pos.should eq 0
130
+ string_buffer.gets
131
+ string_buffer.pos.should eq 6
132
+ string_buffer.read(4)
133
+ string_buffer.pos.should eq 10
134
+ string_buffer.read(999)
135
+ string_buffer.pos.should eq 25
136
+ end
137
+
138
+ describe "#empty?" do
139
+ it "returns false when empty" do
140
+ string_buffer.empty?.should eq false
141
+ end
142
+
143
+ it "returns true when not empty" do
144
+ queue = ThreadQueues::BlockingQueue.new
145
+ sbuffer = ThreadQueues::StringBuffer.new(queue)
146
+ queue.close
147
+ sbuffer.empty?.should eq true
148
+ end
50
149
  end
51
150
  end
@@ -2,16 +2,16 @@
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
3
  # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
- # stub: thread_queues 0.0.2 ruby lib
5
+ # stub: thread_queues 0.0.3 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "thread_queues"
9
- s.version = "0.0.2"
9
+ s.version = "0.0.3"
10
10
 
11
11
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
12
12
  s.require_paths = ["lib"]
13
13
  s.authors = ["kaspernj"]
14
- s.date = "2014-12-07"
14
+ s.date = "2014-12-09"
15
15
  s.description = "Do thread-related work with BlockingQueue and BufferedQueue in Ruby."
16
16
  s.email = "k@spernj.org"
17
17
  s.extra_rdoc_files = [
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: thread_queues
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - kaspernj
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-12-07 00:00:00.000000000 Z
11
+ date: 2014-12-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: string-cases