ruby-brs 1.0.1
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.
- checksums.yaml +7 -0
- data/AUTHORS +1 -0
- data/LICENSE +21 -0
- data/README.md +339 -0
- data/ext/brs_ext/buffer.c +16 -0
- data/ext/brs_ext/buffer.h +17 -0
- data/ext/brs_ext/common.h +13 -0
- data/ext/brs_ext/error.c +78 -0
- data/ext/brs_ext/error.h +34 -0
- data/ext/brs_ext/io.c +494 -0
- data/ext/brs_ext/io.h +14 -0
- data/ext/brs_ext/macro.h +13 -0
- data/ext/brs_ext/main.c +23 -0
- data/ext/brs_ext/option.c +143 -0
- data/ext/brs_ext/option.h +80 -0
- data/ext/brs_ext/stream/compressor.c +234 -0
- data/ext/brs_ext/stream/compressor.h +31 -0
- data/ext/brs_ext/stream/decompressor.c +181 -0
- data/ext/brs_ext/stream/decompressor.h +29 -0
- data/ext/brs_ext/string.c +274 -0
- data/ext/brs_ext/string.h +14 -0
- data/ext/extconf.rb +66 -0
- data/lib/brs/error.rb +21 -0
- data/lib/brs/file.rb +44 -0
- data/lib/brs/option.rb +80 -0
- data/lib/brs/stream/abstract.rb +153 -0
- data/lib/brs/stream/delegates.rb +36 -0
- data/lib/brs/stream/raw/abstract.rb +55 -0
- data/lib/brs/stream/raw/compressor.rb +97 -0
- data/lib/brs/stream/raw/decompressor.rb +70 -0
- data/lib/brs/stream/reader.rb +166 -0
- data/lib/brs/stream/reader_helpers.rb +192 -0
- data/lib/brs/stream/stat.rb +78 -0
- data/lib/brs/stream/writer.rb +145 -0
- data/lib/brs/stream/writer_helpers.rb +93 -0
- data/lib/brs/string.rb +29 -0
- data/lib/brs/validation.rb +40 -0
- data/lib/brs/version.rb +6 -0
- data/lib/brs.rb +7 -0
- metadata +165 -0
@@ -0,0 +1,55 @@
|
|
1
|
+
# Ruby bindings for brotli library.
|
2
|
+
# Copyright (c) 2019 AUTHORS, MIT License.
|
3
|
+
|
4
|
+
require "brs_ext"
|
5
|
+
|
6
|
+
require_relative "../../error"
|
7
|
+
require_relative "../../validation"
|
8
|
+
|
9
|
+
module BRS
|
10
|
+
module Stream
|
11
|
+
module Raw
|
12
|
+
class Abstract
|
13
|
+
def initialize(native_stream)
|
14
|
+
@native_stream = native_stream
|
15
|
+
@is_closed = false
|
16
|
+
end
|
17
|
+
|
18
|
+
# -- write --
|
19
|
+
|
20
|
+
def flush(&writer)
|
21
|
+
write_result(&writer)
|
22
|
+
end
|
23
|
+
|
24
|
+
protected def flush_destination_buffer(&writer)
|
25
|
+
result_bytesize = write_result(&writer)
|
26
|
+
raise NotEnoughDestinationError, "not enough destination" if result_bytesize == 0
|
27
|
+
end
|
28
|
+
|
29
|
+
protected def write_result(&_writer)
|
30
|
+
result = @native_stream.read_result
|
31
|
+
yield result
|
32
|
+
|
33
|
+
result.bytesize
|
34
|
+
end
|
35
|
+
|
36
|
+
# -- close --
|
37
|
+
|
38
|
+
protected def do_not_use_after_close
|
39
|
+
raise UsedAfterCloseError, "used after close" if closed?
|
40
|
+
end
|
41
|
+
|
42
|
+
def close(&writer)
|
43
|
+
write_result(&writer)
|
44
|
+
|
45
|
+
@native_stream.close
|
46
|
+
@is_closed = true
|
47
|
+
end
|
48
|
+
|
49
|
+
def closed?
|
50
|
+
@is_closed
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
# Ruby bindings for brotli library.
|
2
|
+
# Copyright (c) 2019 AUTHORS, MIT License.
|
3
|
+
|
4
|
+
require "brs_ext"
|
5
|
+
|
6
|
+
require_relative "abstract"
|
7
|
+
require_relative "../../error"
|
8
|
+
require_relative "../../option"
|
9
|
+
require_relative "../../validation"
|
10
|
+
|
11
|
+
module BRS
|
12
|
+
module Stream
|
13
|
+
module Raw
|
14
|
+
class Compressor < Abstract
|
15
|
+
BUFFER_LENGTH_NAMES = %i[destination_buffer_length].freeze
|
16
|
+
|
17
|
+
def initialize(options = {})
|
18
|
+
options = Option.get_compressor_options options, BUFFER_LENGTH_NAMES
|
19
|
+
native_stream = NativeCompressor.new options
|
20
|
+
|
21
|
+
super native_stream
|
22
|
+
end
|
23
|
+
|
24
|
+
def write(source, &writer)
|
25
|
+
do_not_use_after_close
|
26
|
+
|
27
|
+
Validation.validate_string source
|
28
|
+
Validation.validate_proc writer
|
29
|
+
|
30
|
+
total_bytes_written = 0
|
31
|
+
|
32
|
+
loop do
|
33
|
+
bytes_written, need_more_destination = @native_stream.write source
|
34
|
+
total_bytes_written += bytes_written
|
35
|
+
|
36
|
+
if need_more_destination
|
37
|
+
source = source.byteslice bytes_written, source.bytesize - bytes_written
|
38
|
+
flush_destination_buffer(&writer)
|
39
|
+
next
|
40
|
+
end
|
41
|
+
|
42
|
+
unless bytes_written == source.bytesize
|
43
|
+
# Compressor write should eat all provided "source" without remainder.
|
44
|
+
raise UnexpectedError, "unexpected error"
|
45
|
+
end
|
46
|
+
|
47
|
+
break
|
48
|
+
end
|
49
|
+
|
50
|
+
total_bytes_written
|
51
|
+
end
|
52
|
+
|
53
|
+
def flush(&writer)
|
54
|
+
do_not_use_after_close
|
55
|
+
|
56
|
+
Validation.validate_proc writer
|
57
|
+
|
58
|
+
loop do
|
59
|
+
need_more_destination = @native_stream.flush
|
60
|
+
|
61
|
+
if need_more_destination
|
62
|
+
flush_destination_buffer(&writer)
|
63
|
+
next
|
64
|
+
end
|
65
|
+
|
66
|
+
break
|
67
|
+
end
|
68
|
+
|
69
|
+
super
|
70
|
+
|
71
|
+
nil
|
72
|
+
end
|
73
|
+
|
74
|
+
def close(&writer)
|
75
|
+
return nil if closed?
|
76
|
+
|
77
|
+
Validation.validate_proc writer
|
78
|
+
|
79
|
+
loop do
|
80
|
+
need_more_destination = @native_stream.finish
|
81
|
+
|
82
|
+
if need_more_destination
|
83
|
+
flush_destination_buffer(&writer)
|
84
|
+
next
|
85
|
+
end
|
86
|
+
|
87
|
+
break
|
88
|
+
end
|
89
|
+
|
90
|
+
super
|
91
|
+
|
92
|
+
nil
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
# Ruby bindings for brotli library.
|
2
|
+
# Copyright (c) 2019 AUTHORS, MIT License.
|
3
|
+
|
4
|
+
require "brs_ext"
|
5
|
+
|
6
|
+
require_relative "abstract"
|
7
|
+
require_relative "../../option"
|
8
|
+
require_relative "../../validation"
|
9
|
+
|
10
|
+
module BRS
|
11
|
+
module Stream
|
12
|
+
module Raw
|
13
|
+
class Decompressor < Abstract
|
14
|
+
BUFFER_LENGTH_NAMES = %i[destination_buffer_length].freeze
|
15
|
+
|
16
|
+
def initialize(options = {})
|
17
|
+
options = Option.get_decompressor_options options, BUFFER_LENGTH_NAMES
|
18
|
+
native_stream = NativeDecompressor.new options
|
19
|
+
|
20
|
+
super native_stream
|
21
|
+
end
|
22
|
+
|
23
|
+
def read(source, &writer)
|
24
|
+
do_not_use_after_close
|
25
|
+
|
26
|
+
Validation.validate_string source
|
27
|
+
Validation.validate_proc writer
|
28
|
+
|
29
|
+
total_bytes_read = 0
|
30
|
+
|
31
|
+
loop do
|
32
|
+
bytes_read, need_more_destination = @native_stream.read source
|
33
|
+
total_bytes_read += bytes_read
|
34
|
+
|
35
|
+
if need_more_destination
|
36
|
+
source = source.byteslice bytes_read, source.bytesize - bytes_read
|
37
|
+
flush_destination_buffer(&writer)
|
38
|
+
next
|
39
|
+
end
|
40
|
+
|
41
|
+
break
|
42
|
+
end
|
43
|
+
|
44
|
+
# Please remember that "total_bytes_read" can not be equal to "source.bytesize".
|
45
|
+
total_bytes_read
|
46
|
+
end
|
47
|
+
|
48
|
+
def flush(&writer)
|
49
|
+
do_not_use_after_close
|
50
|
+
|
51
|
+
Validation.validate_proc writer
|
52
|
+
|
53
|
+
super
|
54
|
+
|
55
|
+
nil
|
56
|
+
end
|
57
|
+
|
58
|
+
def close(&writer)
|
59
|
+
return nil if closed?
|
60
|
+
|
61
|
+
Validation.validate_proc writer
|
62
|
+
|
63
|
+
super
|
64
|
+
|
65
|
+
nil
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,166 @@
|
|
1
|
+
# Ruby bindings for brotli library.
|
2
|
+
# Copyright (c) 2019 AUTHORS, MIT License.
|
3
|
+
|
4
|
+
require_relative "abstract"
|
5
|
+
require_relative "raw/decompressor"
|
6
|
+
require_relative "reader_helpers"
|
7
|
+
require_relative "../validation"
|
8
|
+
|
9
|
+
module BRS
|
10
|
+
module Stream
|
11
|
+
class Reader < Abstract
|
12
|
+
include ReaderHelpers
|
13
|
+
|
14
|
+
attr_accessor :lineno
|
15
|
+
|
16
|
+
def initialize(source_io, options = {}, *args)
|
17
|
+
@options = options
|
18
|
+
|
19
|
+
super source_io, *args
|
20
|
+
|
21
|
+
initialize_source_buffer_length
|
22
|
+
reset_io_remainder
|
23
|
+
|
24
|
+
@lineno = 0
|
25
|
+
end
|
26
|
+
|
27
|
+
protected def initialize_source_buffer_length
|
28
|
+
source_buffer_length = @options[:source_buffer_length]
|
29
|
+
Validation.validate_not_negative_integer source_buffer_length unless source_buffer_length.nil?
|
30
|
+
|
31
|
+
source_buffer_length = Buffer::DEFAULT_SOURCE_BUFFER_LENGTH_FOR_DECOMPRESSOR \
|
32
|
+
if source_buffer_length == 0 || source_buffer_length.nil?
|
33
|
+
|
34
|
+
@source_buffer_length = source_buffer_length
|
35
|
+
end
|
36
|
+
|
37
|
+
protected def create_raw_stream
|
38
|
+
Raw::Decompressor.new @options
|
39
|
+
end
|
40
|
+
|
41
|
+
protected def reset_io_remainder
|
42
|
+
@io_remainder = ::String.new :encoding => ::Encoding::BINARY
|
43
|
+
end
|
44
|
+
|
45
|
+
# -- synchronous --
|
46
|
+
|
47
|
+
def read(bytes_to_read = nil, out_buffer = nil)
|
48
|
+
Validation.validate_not_negative_integer bytes_to_read unless bytes_to_read.nil?
|
49
|
+
Validation.validate_string out_buffer unless out_buffer.nil?
|
50
|
+
|
51
|
+
return ::String.new :encoding => ::Encoding::BINARY if bytes_to_read == 0
|
52
|
+
|
53
|
+
unless bytes_to_read.nil?
|
54
|
+
return nil if eof?
|
55
|
+
|
56
|
+
read_more_from_buffer until @buffer.bytesize >= bytes_to_read || @io.eof?
|
57
|
+
|
58
|
+
return read_bytes_from_buffer bytes_to_read, out_buffer
|
59
|
+
end
|
60
|
+
|
61
|
+
read_more_from_buffer until @io.eof?
|
62
|
+
|
63
|
+
result = @buffer
|
64
|
+
reset_buffer
|
65
|
+
@pos += result.bytesize
|
66
|
+
|
67
|
+
result.force_encoding @external_encoding unless @external_encoding.nil?
|
68
|
+
result = transcode_to_internal result
|
69
|
+
result = out_buffer.replace result unless out_buffer.nil?
|
70
|
+
|
71
|
+
result
|
72
|
+
end
|
73
|
+
|
74
|
+
protected def read_more_from_buffer
|
75
|
+
io_data = @io.read @source_buffer_length
|
76
|
+
append_io_data_to_buffer io_data
|
77
|
+
end
|
78
|
+
|
79
|
+
def readpartial(bytes_to_read = nil, out_buffer = nil)
|
80
|
+
raise ::EOFError if eof?
|
81
|
+
|
82
|
+
readpartial_from_buffer until @buffer.bytesize >= bytes_to_read || @io.eof?
|
83
|
+
|
84
|
+
read_bytes_from_buffer bytes_to_read, out_buffer
|
85
|
+
end
|
86
|
+
|
87
|
+
protected def readpartial_from_buffer
|
88
|
+
io_data = @io.readpartial @source_buffer_length
|
89
|
+
append_io_data_to_buffer io_data
|
90
|
+
end
|
91
|
+
|
92
|
+
def rewind
|
93
|
+
raw_wrapper :close
|
94
|
+
|
95
|
+
reset_io_remainder
|
96
|
+
|
97
|
+
super
|
98
|
+
end
|
99
|
+
|
100
|
+
def close
|
101
|
+
raw_wrapper :close
|
102
|
+
|
103
|
+
super
|
104
|
+
end
|
105
|
+
|
106
|
+
# -- asynchronous --
|
107
|
+
|
108
|
+
def read_nonblock(bytes_to_read, out_buffer = nil, *options)
|
109
|
+
raise ::EOFError if eof?
|
110
|
+
|
111
|
+
read_more_from_buffer_nonblock(*options) until @buffer.bytesize >= bytes_to_read || @io.eof?
|
112
|
+
|
113
|
+
read_bytes_from_buffer bytes_to_read, out_buffer
|
114
|
+
end
|
115
|
+
|
116
|
+
protected def read_more_from_buffer_nonblock(*options)
|
117
|
+
io_data = @io.read_nonblock @source_buffer_length, *options
|
118
|
+
append_io_data_to_buffer io_data
|
119
|
+
end
|
120
|
+
|
121
|
+
# -- common --
|
122
|
+
|
123
|
+
def eof?
|
124
|
+
@io.eof? && @buffer.bytesize == 0
|
125
|
+
end
|
126
|
+
|
127
|
+
protected def read_bytes_from_buffer(bytes_to_read, out_buffer)
|
128
|
+
bytes_read = [@buffer.bytesize, bytes_to_read].min
|
129
|
+
|
130
|
+
# Result uses buffer binary encoding.
|
131
|
+
result = @buffer.byteslice 0, bytes_read
|
132
|
+
@buffer = @buffer.byteslice bytes_read, @buffer.bytesize - bytes_read
|
133
|
+
@pos += bytes_read
|
134
|
+
|
135
|
+
result = out_buffer.replace result unless out_buffer.nil?
|
136
|
+
result
|
137
|
+
end
|
138
|
+
|
139
|
+
protected def append_io_data_to_buffer(io_data)
|
140
|
+
io_portion = @io_remainder + io_data
|
141
|
+
bytes_read = raw_wrapper :read, io_portion
|
142
|
+
@io_remainder = io_portion.byteslice bytes_read, io_portion.bytesize - bytes_read
|
143
|
+
|
144
|
+
# We should just ignore case when "io.eof?" appears but "io_remainder" is not empty.
|
145
|
+
# Ancient compress implementations can write bytes from not initialized buffer parts to output.
|
146
|
+
raw_wrapper :flush if @io.eof?
|
147
|
+
end
|
148
|
+
|
149
|
+
protected def transcode_to_internal(data)
|
150
|
+
data = data.encode @internal_encoding, @transcode_options unless @internal_encoding.nil?
|
151
|
+
data
|
152
|
+
end
|
153
|
+
|
154
|
+
# We should be able to return data back to buffer.
|
155
|
+
# We won't use any transcode options because transcoded data should be backward compatible.
|
156
|
+
protected def transcode_to_external(data)
|
157
|
+
data = data.encode @external_encoding unless @external_encoding.nil?
|
158
|
+
data
|
159
|
+
end
|
160
|
+
|
161
|
+
protected def raw_wrapper(method_name, *args)
|
162
|
+
@raw_stream.send(method_name, *args) { |portion| @buffer << portion }
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
@@ -0,0 +1,192 @@
|
|
1
|
+
# Ruby bindings for brotli library.
|
2
|
+
# Copyright (c) 2019 AUTHORS, MIT License.
|
3
|
+
|
4
|
+
require_relative "../validation"
|
5
|
+
|
6
|
+
module BRS
|
7
|
+
module Stream
|
8
|
+
module ReaderHelpers
|
9
|
+
def getbyte
|
10
|
+
read 1
|
11
|
+
end
|
12
|
+
|
13
|
+
def each_byte(&block)
|
14
|
+
each_string method(:getbyte), &block
|
15
|
+
end
|
16
|
+
|
17
|
+
def readbyte
|
18
|
+
readstring method(:getbyte)
|
19
|
+
end
|
20
|
+
|
21
|
+
def ungetbyte(byte)
|
22
|
+
Validation.validate_string byte
|
23
|
+
|
24
|
+
@buffer.prepend byte
|
25
|
+
|
26
|
+
nil
|
27
|
+
end
|
28
|
+
|
29
|
+
# -- char --
|
30
|
+
|
31
|
+
def getc
|
32
|
+
if @external_encoding.nil?
|
33
|
+
byte = getbyte
|
34
|
+
return nil if byte.nil?
|
35
|
+
|
36
|
+
return transcode_to_internal byte
|
37
|
+
end
|
38
|
+
|
39
|
+
char = ::String.new :encoding => ::Encoding::BINARY
|
40
|
+
|
41
|
+
# Read one byte until valid string will appear.
|
42
|
+
loop do
|
43
|
+
byte = getbyte
|
44
|
+
return nil if byte.nil?
|
45
|
+
|
46
|
+
char << byte
|
47
|
+
|
48
|
+
char.force_encoding @external_encoding
|
49
|
+
return transcode_to_internal char if char.valid_encoding?
|
50
|
+
|
51
|
+
char.force_encoding ::Encoding::BINARY
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def readchar
|
56
|
+
readstring method(:getc)
|
57
|
+
end
|
58
|
+
|
59
|
+
def each_char(&block)
|
60
|
+
each_string method(:getc), &block
|
61
|
+
end
|
62
|
+
|
63
|
+
def ungetc(char)
|
64
|
+
ungetstring char
|
65
|
+
end
|
66
|
+
|
67
|
+
# -- lines --
|
68
|
+
|
69
|
+
def gets(separator = $OUTPUT_RECORD_SEPARATOR, limit = nil)
|
70
|
+
# Limit can be a first argument.
|
71
|
+
if separator.is_a? ::Numeric
|
72
|
+
limit = separator
|
73
|
+
separator = $OUTPUT_RECORD_SEPARATOR
|
74
|
+
end
|
75
|
+
|
76
|
+
line_ending =
|
77
|
+
if separator.nil?
|
78
|
+
nil
|
79
|
+
else
|
80
|
+
Validation.validate_string separator
|
81
|
+
::String.new separator, :encoding => target_encoding
|
82
|
+
end
|
83
|
+
|
84
|
+
Validation.validate_positive_integer limit unless limit.nil?
|
85
|
+
|
86
|
+
line = ::String.new :encoding => target_encoding
|
87
|
+
|
88
|
+
loop do
|
89
|
+
char = getc
|
90
|
+
|
91
|
+
if char.nil?
|
92
|
+
return nil if line.empty?
|
93
|
+
|
94
|
+
break
|
95
|
+
end
|
96
|
+
|
97
|
+
line << char
|
98
|
+
|
99
|
+
break if
|
100
|
+
(!line_ending.nil? && line.end_with?(line_ending)) ||
|
101
|
+
(!limit.nil? && line.length >= limit)
|
102
|
+
end
|
103
|
+
|
104
|
+
@lineno += 1
|
105
|
+
|
106
|
+
line
|
107
|
+
end
|
108
|
+
|
109
|
+
def readline
|
110
|
+
readstring method(:gets)
|
111
|
+
end
|
112
|
+
|
113
|
+
def readlines
|
114
|
+
lines = []
|
115
|
+
each_line { |line| lines << line }
|
116
|
+
|
117
|
+
lines
|
118
|
+
end
|
119
|
+
|
120
|
+
def each_line(&block)
|
121
|
+
each_string method(:gets), &block
|
122
|
+
end
|
123
|
+
|
124
|
+
alias each each_line
|
125
|
+
|
126
|
+
def ungetline(line)
|
127
|
+
ungetstring line
|
128
|
+
|
129
|
+
@lineno -= 1
|
130
|
+
|
131
|
+
nil
|
132
|
+
end
|
133
|
+
|
134
|
+
# -- common --
|
135
|
+
|
136
|
+
protected def readstring(each_proc)
|
137
|
+
string = each_proc.call
|
138
|
+
raise ::EOFError if string.nil?
|
139
|
+
|
140
|
+
string
|
141
|
+
end
|
142
|
+
|
143
|
+
protected def each_string(each_proc, &block)
|
144
|
+
return enum_for __method__ unless block.is_a? ::Proc
|
145
|
+
|
146
|
+
loop do
|
147
|
+
string = each_proc.call
|
148
|
+
break if string.nil?
|
149
|
+
|
150
|
+
yield string
|
151
|
+
end
|
152
|
+
|
153
|
+
nil
|
154
|
+
end
|
155
|
+
|
156
|
+
protected def ungetstring(string)
|
157
|
+
Validation.validate_string string
|
158
|
+
|
159
|
+
string = ::String.new string, :encoding => @internal_encoding unless @internal_encoding.nil?
|
160
|
+
string = transcode_to_external string unless @external_encoding.nil?
|
161
|
+
|
162
|
+
string.force_encoding ::Encoding::BINARY
|
163
|
+
@buffer.prepend string
|
164
|
+
|
165
|
+
nil
|
166
|
+
end
|
167
|
+
|
168
|
+
# -- etc --
|
169
|
+
|
170
|
+
module ClassMethods
|
171
|
+
def open(file_path, *args, &block)
|
172
|
+
Validation.validate_string file_path
|
173
|
+
Validation.validate_proc block
|
174
|
+
|
175
|
+
::File.open file_path, "rb" do |io|
|
176
|
+
reader = new io, *args
|
177
|
+
|
178
|
+
begin
|
179
|
+
yield reader
|
180
|
+
ensure
|
181
|
+
reader.close
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
def self.included(klass)
|
188
|
+
klass.extend ClassMethods
|
189
|
+
end
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
# Ruby bindings for brotli library.
|
2
|
+
# Copyright (c) 2019 AUTHORS, MIT License.
|
3
|
+
|
4
|
+
require "forwardable"
|
5
|
+
|
6
|
+
module BRS
|
7
|
+
module Stream
|
8
|
+
class Stat
|
9
|
+
# Libraries like minitar tries to access stat to know whether stream is seekable.
|
10
|
+
# We need to mark stream as not directory, file, etc, because it is not seekable.
|
11
|
+
|
12
|
+
# User can use disabled delegates using :io reader.
|
13
|
+
|
14
|
+
extend ::Forwardable
|
15
|
+
|
16
|
+
METHODS_RETURNING_FALSE = %i[
|
17
|
+
blockdev?
|
18
|
+
chardev?
|
19
|
+
directory?
|
20
|
+
executable?
|
21
|
+
executable_real?
|
22
|
+
file?
|
23
|
+
grpowned?
|
24
|
+
owned?
|
25
|
+
pipe?
|
26
|
+
setgid?
|
27
|
+
setuid?
|
28
|
+
socket?
|
29
|
+
sticky?
|
30
|
+
symlink?
|
31
|
+
zero?
|
32
|
+
]
|
33
|
+
.freeze
|
34
|
+
|
35
|
+
DELEGATES = %i[
|
36
|
+
<=>
|
37
|
+
atime
|
38
|
+
birthtime
|
39
|
+
blksize
|
40
|
+
blocks
|
41
|
+
ctime
|
42
|
+
dev
|
43
|
+
dev_major
|
44
|
+
dev_minor
|
45
|
+
ftype
|
46
|
+
gid
|
47
|
+
ino
|
48
|
+
inspect
|
49
|
+
mode
|
50
|
+
mtime
|
51
|
+
nlink
|
52
|
+
rdev
|
53
|
+
rdev_major
|
54
|
+
rdev_minor
|
55
|
+
readable?
|
56
|
+
readable_real?
|
57
|
+
size
|
58
|
+
size?
|
59
|
+
uid
|
60
|
+
world_readable?
|
61
|
+
world_writable?
|
62
|
+
writable?
|
63
|
+
writable_real?
|
64
|
+
]
|
65
|
+
.freeze
|
66
|
+
|
67
|
+
def initialize(stat)
|
68
|
+
@stat = stat
|
69
|
+
end
|
70
|
+
|
71
|
+
METHODS_RETURNING_FALSE.each do |method_name|
|
72
|
+
define_method(method_name) { false }
|
73
|
+
end
|
74
|
+
|
75
|
+
def_delegators :@stat, *DELEGATES
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|