io-segmenter 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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: []