io-segmenter 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. checksums.yaml +7 -0
  2. data/lib/io-segmenter.rb +88 -0
  3. metadata +43 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 794c025371c0f2a36e5648199101b20294bfb4ffb160c9d1c8d55d016115d660
4
+ data.tar.gz: 821db4894a29799ab3f2a84a0574839470d9080bebeedfee8e368ef09f73b2ba
5
+ SHA512:
6
+ metadata.gz: 5e4a7a3bfedac02138e053800bb619a5e38e5e19a4d3b623f7cb82abb04fddb9b3458d5c88bc0a07ffc8d1fa81350e5e8db227cb8cab8dd736d3dc585c127789
7
+ data.tar.gz: 7a12973857ed46aaef093870ff5a008649500404bb7911966eb9258d5d7e96ac5d765988d721ec50ad9e71e3a4870fa48180a3f6bf7cdfb32eef5742291841d0
@@ -0,0 +1,88 @@
1
+ # frozen_string_literal: true
2
+
3
+ # IO iterator for parsing segments of streams
4
+ class IOSegmenter
5
+ include Enumerable
6
+
7
+ def initialize(io, starting_char = '{', ending_char = '}', quote_char = '"', escape_char = '\\', max_read_size = 8192)
8
+ @io = io
9
+ @starting_char = starting_char
10
+ @ending_char = ending_char
11
+ @quote_char = quote_char
12
+ @escape_char = escape_char
13
+ @max_read_size = max_read_size
14
+
15
+ terms = [
16
+ @starting_char,
17
+ @ending_char,
18
+ @quote_char,
19
+ @escape_char
20
+ ]
21
+ terms.compact!
22
+ terms.map! { |str| Regexp.escape(str) }
23
+
24
+ @search = Regexp.new('(:?' + terms.join('|') + ')')
25
+ end
26
+
27
+ def each
28
+ buffer = String.new
29
+
30
+ until @io.eof?
31
+ buffer << @io.read(@max_read_size)
32
+ each_segment(buffer) do |segment|
33
+ yield segment
34
+ end
35
+ end
36
+ end
37
+
38
+ def self.foreach(*args, &block)
39
+ new(*args).each(&block)
40
+ end
41
+
42
+ private
43
+
44
+ def each_segment(buffer)
45
+ return unless (start_offset = buffer.index(@starting_char))
46
+
47
+ brackets = 1
48
+ offset = start_offset
49
+
50
+ opened_quote = false
51
+
52
+ while (offset = buffer.index(@search, offset + 1))
53
+ case buffer[offset]
54
+ when @ending_char
55
+ next if opened_quote
56
+ brackets -= 1
57
+ when @starting_char
58
+ next if opened_quote
59
+ brackets += 1
60
+ when @quote_char
61
+ opened_quote = !opened_quote
62
+ next
63
+ when @escape_char
64
+ offset += @escape_char.size
65
+ next
66
+ else
67
+ if @ending_char == buffer[offset, @ending_char.size]
68
+ next if opened_quote
69
+ brackets -= 1
70
+ elsif @starting_char == buffer[offset, @starting_char.size]
71
+ next if opened_quote
72
+ brackets += 1
73
+ else
74
+ raise("unhandled offset #{offset}, at #{buffer[offset, 20]}...")
75
+ end
76
+ end
77
+
78
+ next unless brackets.zero?
79
+
80
+ len = (offset + @ending_char.size) - start_offset
81
+ yield buffer[start_offset, len]
82
+ buffer.slice!(0, offset + @ending_char.size)
83
+ return unless (start_offset = buffer.index(@starting_char))
84
+ offset = start_offset
85
+ brackets = 1
86
+ end
87
+ end
88
+ end
metadata ADDED
@@ -0,0 +1,43 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: io-segmenter
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.6.0
5
+ platform: ruby
6
+ authors:
7
+ - Doug Youch
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2018-09-09 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Used to iterate over segments of data in IO objects
14
+ email: dyouch5@yahoo.com
15
+ executables: []
16
+ extensions: []
17
+ extra_rdoc_files: []
18
+ files:
19
+ - lib/io-segmenter.rb
20
+ homepage: https://github.com/dougyouch/io-segemnter
21
+ licenses: []
22
+ metadata: {}
23
+ post_install_message:
24
+ rdoc_options: []
25
+ require_paths:
26
+ - lib
27
+ required_ruby_version: !ruby/object:Gem::Requirement
28
+ requirements:
29
+ - - ">="
30
+ - !ruby/object:Gem::Version
31
+ version: '0'
32
+ required_rubygems_version: !ruby/object:Gem::Requirement
33
+ requirements:
34
+ - - ">="
35
+ - !ruby/object:Gem::Version
36
+ version: '0'
37
+ requirements: []
38
+ rubyforge_project:
39
+ rubygems_version: 2.7.6
40
+ signing_key:
41
+ specification_version: 4
42
+ summary: IO Segemnter
43
+ test_files: []