redis-protocol 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.0
1
+ 0.1.1
@@ -1,142 +1,9 @@
1
1
  # start with *, $, alpha-numeric, \r
2
2
 
3
3
  module RedisProtocol
4
- class Request
5
- attr_reader :raw_data, :type, :component_count, :components
6
-
7
- def initialize(data)
8
- @raw_data = data
9
- @type, @components, @component_count, @current = nil, [], 0, ''
10
- @next_length = 0
11
- parse
12
- end
13
-
14
- private
15
-
16
- def parse
17
- @raw_data.chars.each do |c|
18
- @type ||= c.eql?('*') ? :standard : :inline
19
-
20
- send(@type, c)
21
- end
22
-
23
- complete_token
24
- @component_count += @components.count if @type == :inline
25
- end
26
- =begin
27
- Inline Parser
28
- =end
29
- def inline(char)
30
- c = char.strip
31
-
32
- if c.empty? and not @current.empty?
33
- complete_token
34
- else
35
- @current += c
36
- end
37
- end
38
-
39
- =begin
40
- Standard Parser
41
- =end
42
-
43
- def standard(char)
44
- @token_type ||= detect_token_type char
45
- @doubt_str = ''
46
-
47
- send(@token_type, char)
48
- end
49
-
50
- def args_counts(char)
51
- return if char.eql? '*'
52
-
53
- tokenize char do
54
- @component_count = @current.to_i
55
- clean_context
56
- end
57
- end
58
-
59
- def length(char)
60
- return if char.eql? '$'
61
-
62
- tokenize char do
63
- @next_length = @current.to_i
64
- clean_context
65
- end
66
- end
67
-
68
- def payload(char)
69
- return if char.eql? '$'
70
-
71
- @next_length = 0 if @current.length == @next_length
72
-
73
- tokenize char do
74
- @next_length = 0
75
- complete_token
76
- end
77
- end
78
-
79
- def tokenize(char, &block)
80
- reach_delimiter = consume_delimiter(char)
81
-
82
- if reach_delimiter
83
- if @doubt_str.empty?
84
- block.call
85
- end
86
- return
87
- end
88
-
89
- @current += char
90
- end
91
-
92
- =begin
93
- Common Utilities
94
- =end
95
-
96
- def complete_token
97
- @components << @current
98
- clean_context
99
- end
100
-
101
- def clean_context
102
- @current = ''
103
- @token_type = nil
104
- end
105
-
106
- def consume_delimiter(char)
107
- return false if @next_length != 0
108
-
109
- if @doubt and char.eql? "\n"
110
- @doubt_str = ''
111
- @doubt = false
112
- return true
113
- end
114
-
115
- if not @doubt and char.eql? "\r"
116
- @doubt_str = "\r"
117
- @doubt = true
118
- return true
119
- end
120
-
121
- @doubt = false
122
- @current += @doubt_str unless @doubt_str.empty?
123
- @doubt_str = ''
124
- return false
125
- end
126
-
127
- def detect_token_type(char)
128
- case char
129
- when '*'
130
- :args_counts
131
- when '$'
132
- :length
133
- else
134
- :payload
135
- end
136
- end
137
- end
138
-
139
4
  class Response
140
5
 
141
6
  end
142
- end
7
+ end
8
+
9
+ require 'redis-protocol/request'
@@ -0,0 +1,134 @@
1
+ class RedisProtocol::Request
2
+ attr_reader :raw_data, :type, :component_count, :components
3
+
4
+ def initialize(data)
5
+ @raw_data = data
6
+ @type, @components, @component_count, @current = nil, [], 0, ''
7
+ @next_length = 0
8
+ parse
9
+ end
10
+
11
+ private
12
+
13
+ def parse
14
+ @raw_data.chars.each do |c|
15
+ @type ||= c.eql?('*') ? :standard : :inline
16
+
17
+ send(@type, c)
18
+ end
19
+
20
+ complete_token
21
+ @component_count += @components.count if @type == :inline
22
+ end
23
+ =begin
24
+ Inline Parser
25
+ =end
26
+ def inline(char)
27
+ c = char.strip
28
+
29
+ if c.empty? and not @current.empty?
30
+ complete_token
31
+ else
32
+ @current += c
33
+ end
34
+ end
35
+
36
+ =begin
37
+ Standard Parser
38
+ =end
39
+
40
+ def standard(char)
41
+ @token_type ||= detect_token_type char
42
+ @doubt_str = ''
43
+
44
+ send(@token_type, char)
45
+ end
46
+
47
+ def args_counts(char)
48
+ return if char.eql? '*'
49
+
50
+ tokenize char do
51
+ @component_count = @current.to_i
52
+ clean_context
53
+ end
54
+ end
55
+
56
+ def length(char)
57
+ return if char.eql? '$'
58
+
59
+ tokenize char do
60
+ @next_length = @current.to_i
61
+ clean_context
62
+ end
63
+ end
64
+
65
+ def payload(char)
66
+ return if char.eql? '$'
67
+
68
+ @next_length = 0 if @current.length == @next_length
69
+
70
+ tokenize char do
71
+ @next_length = 0
72
+ complete_token
73
+ end
74
+ end
75
+
76
+ def tokenize(char, &block)
77
+ reach_delimiter = consume_delimiter(char)
78
+
79
+ if reach_delimiter
80
+ if @doubt_str.empty?
81
+ block.call
82
+ end
83
+ return
84
+ end
85
+
86
+ @current += char
87
+ end
88
+
89
+ =begin
90
+ Common Utilities
91
+ =end
92
+
93
+ def complete_token
94
+ @components << @current
95
+ clean_context
96
+ end
97
+
98
+ def clean_context
99
+ @current = ''
100
+ @token_type = nil
101
+ end
102
+
103
+ def consume_delimiter(char)
104
+ return false if @next_length != 0
105
+
106
+ if @doubt and char.eql? "\n"
107
+ @doubt_str = ''
108
+ @doubt = false
109
+ return true
110
+ end
111
+
112
+ if not @doubt and char.eql? "\r"
113
+ @doubt_str = "\r"
114
+ @doubt = true
115
+ return true
116
+ end
117
+
118
+ @doubt = false
119
+ @current += @doubt_str unless @doubt_str.empty?
120
+ @doubt_str = ''
121
+ return false
122
+ end
123
+
124
+ def detect_token_type(char)
125
+ case char
126
+ when '*'
127
+ :args_counts
128
+ when '$'
129
+ :length
130
+ else
131
+ :payload
132
+ end
133
+ end
134
+ end
@@ -0,0 +1,74 @@
1
+ class RedisProtocol::StaticRequest
2
+ attr_reader :raw_data, :type
3
+ OP_DELIMITER = "\r\n"
4
+
5
+ def initialize(data)
6
+ @raw_data = data
7
+ parse_request
8
+ end
9
+
10
+ def parse_request
11
+ @type = check_request_type
12
+
13
+ send @type, @raw_data
14
+ end
15
+
16
+ def self.recognize(data)
17
+ (check_request_type == :inline) ? data.split[0] : data.split(OP_DELIMITER)[2]
18
+ end
19
+
20
+ def check_request_type
21
+ (@raw_data.start_with? '*') ? :standard : :inline
22
+ end
23
+
24
+ def standard
25
+ components = []
26
+ data = @raw_data.dup
27
+ operand_length, payload = operand_length_for data.split(OP_DELIMITER)
28
+ 1.upto(operand_length).each do |_|
29
+ data, payload = unpack_payload(payload)
30
+ components << data
31
+ end
32
+ @components = components
33
+ end
34
+
35
+ def operand_length_for(data)
36
+ operand_length, payload = next_token data
37
+ raise "invalid packet : #{operand_length}" unless operand_length.start_with? '*'
38
+ operand_length = operand_length[1..-1].to_i
39
+
40
+ [operand_length, payload]
41
+ end
42
+
43
+ def unpack_payload(payload)
44
+ field_length, payload = next_token payload
45
+ raise "invalid length format : #{field_length}" unless field_length.start_with? '$'
46
+ field_length = field_length[1..-1].to_i
47
+ next_token payload, field_length
48
+ end
49
+
50
+ def inline(data)
51
+ data.split
52
+ end
53
+
54
+ def next_token(data, length = 0)
55
+ if data[0].length == length || length == 0
56
+ [data[0], data[1..-1]]
57
+ else
58
+ multiline_token(data, length)
59
+ end
60
+ end
61
+
62
+ def multiline_token(data, length)
63
+ val, index = '', 0
64
+ data.each do |token|
65
+ val.empty? ? val = token : val += "\r\n#{token}"
66
+ index += 1
67
+
68
+ break if val.length == length
69
+ end
70
+ [val, data[index..-1]]
71
+ end
72
+
73
+ private :next_token, :standard, :inline, :operand_length_for, :unpack_payload, :multiline_token
74
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: redis-protocol
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -126,6 +126,8 @@ files:
126
126
  - Rakefile
127
127
  - VERSION
128
128
  - lib/redis-protocol.rb
129
+ - lib/redis-protocol/request.rb
130
+ - lib/redis-protocol/static_request.rb
129
131
  - spec/redis-protocol/request_spec.rb
130
132
  - spec/redis-protocol_spec.rb
131
133
  - spec/spec_helper.rb
@@ -144,7 +146,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
144
146
  version: '0'
145
147
  segments:
146
148
  - 0
147
- hash: -1380845290125949891
149
+ hash: 1791670625487340402
148
150
  required_rubygems_version: !ruby/object:Gem::Requirement
149
151
  none: false
150
152
  requirements: