rrb 0.0.4 → 0.0.5

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 41791058f4c6b1f6c6295182df8f1edae27a3aa6e89655bc11530863d7d136b5
4
- data.tar.gz: 5457ead97de7f07f2bb09bdbd3254eaf6dc4ded42b08943f9fba860ad0af9149
3
+ metadata.gz: 5fa8cdaebd91d028bc2a93d59e00c45c7d61090f4fb8547b224ed2d78aa7fea9
4
+ data.tar.gz: 69968f16213b56e75f9a96e18a1d5f2a56c187a783820de396c2453398657a9d
5
5
  SHA512:
6
- metadata.gz: d1f5a2425a35ab452d24442399c31ea3e3bb1acb20dba030e6cc85458e929b6199de6074e02132f313f843fc3169af7c282038e2605f196dabe3e2221d32291c
7
- data.tar.gz: 5f39f2186da44056283a23921b252b30efbb27a0c0dd3ada6b0f1875f4e8ecd30d8a45e36c1c7a740b058698cf92f977649eeef789494cc793877851b77b473e
6
+ metadata.gz: 91e576b8fbf50b633175d3084f18a7abd5d0b24ab1a71a951e4144d889de7078ae66fc7bace3f8aeb384b793d67b11805dbf536cfcf13da1b42325298bd1345c
7
+ data.tar.gz: '09dcd69d25de941f26dd0551276b45170bbd8464675a95ddeb6dbed6adb145aabc536549db28cff504f049c2fc5b7f55e8603dc48652a0a2b5c7e6144c28dfff'
@@ -0,0 +1,134 @@
1
+ # The IO module provides objects, modules, and functions to handle input/output operations.
2
+ module RuneRb::IO
3
+
4
+ # A Buffer object encapsulates a string of binary data and dynamically includes functions to interact with that data depending on the modestring.
5
+ class Buffer
6
+ include RuneRb::Utils::Logging
7
+
8
+ # @return [Boolean] is {bit_access} enabled?
9
+ attr_reader :bit_access
10
+
11
+ # @return [String] the access mode.
12
+ attr_reader :mode
13
+
14
+ # @return [String] the data.
15
+ attr_reader :data
16
+
17
+ # Construct a new instance of {Buffer}.
18
+ # @param modestring [String] the mode for the buffer. ['r', 'w']
19
+ # @param data [String] the data.
20
+ # @return [Buffer] the created instance.
21
+ def initialize(modestring, data: '')
22
+ raise "Invalid mode-string for Buffer! Expecting: r, rn, w, rw Got: #{modestring}" unless /(?i)r|n|w/.match?(modestring)
23
+
24
+ @data = data
25
+ @mode = modestring
26
+
27
+ enable_readable if /(?i)r/.match?(modestring)
28
+ enable_writeable if /(?i)w/.match?(modestring)
29
+ enable_native_readable if /(?i)n/.match?(modestring)
30
+
31
+ self
32
+ end
33
+
34
+ # The length of the underlying data.
35
+ # @return [Integer]
36
+ def length
37
+ @data.length
38
+ end
39
+
40
+ alias size length
41
+
42
+ # Fetches a snapshot of the message payload content.
43
+ # @return [String] a snapshot of the payload
44
+ def peek
45
+ @data.force_encoding(Encoding::BINARY)
46
+ end
47
+
48
+ alias snapshot peek
49
+
50
+ # Push data directly to the {Buffer#data} object.
51
+ # @param data [String] the data to write.
52
+ def push(data = '')
53
+ @data.concat(data) unless data.empty?
54
+ end
55
+
56
+ alias << push
57
+
58
+ def inspect
59
+ if @mode.include?('w')
60
+ "[BufferMode:] #{@mode} || [BodyLength:] #{@data.length} || [BitAccess:] #{@bit_access} || [Payload:] #{hex}"
61
+ else
62
+ "[BufferMode:] #{@mode} || [BodyLength:] #{@data.length} || [Payload:] #{hex}"
63
+ end
64
+ end
65
+
66
+ # @return [String] hex representation of the buffer's data.
67
+ def hex
68
+ res = ''
69
+ peek.each_byte { res << "#{_1 < 16 ? '0' : ''}#{_1.to_s(16)} " }
70
+ res.strip
71
+ end
72
+
73
+ private
74
+
75
+ # Enables Writeable functions for the Message.
76
+ def enable_writeable
77
+ @bit_access = false
78
+ @bit_position = 0
79
+ singleton_class.include(RuneRb::IO::Writeable)
80
+ end
81
+
82
+ # Enables Readable functions for the Message.
83
+ def enable_readable
84
+ singleton_class.include(RuneRb::IO::Readable)
85
+ end
86
+
87
+ # Enables Native reading functions for the Message.
88
+ def enable_native_readable
89
+ singleton_class.include(RuneRb::IO::NativeReadable)
90
+ end
91
+
92
+ # Mutates the value according to the passed mutation
93
+ # @param value [Integer] the value to mutate
94
+ # @param mutation [Symbol] the mutation to apply to the value.
95
+ def mutate(value, mutation)
96
+ case mutation
97
+ when :STD then value
98
+ when :ADD then value += 128
99
+ when :NEG then value = -value
100
+ when :SUB then value -= 128
101
+ else mutate(value, :STD)
102
+ end
103
+ value
104
+ end
105
+ end
106
+ end
107
+
108
+ # Copyright (c) 2022, Patrick W.
109
+ # All rights reserved.
110
+ #
111
+ # Redistribution and use in source and binary forms, with or without
112
+ # modification, are permitted provided that the following conditions are met:
113
+ #
114
+ # * Redistributions of source code must retain the above copyright notice, this
115
+ # list of conditions and the following disclaimer.
116
+ #
117
+ # * Redistributions in binary form must reproduce the above copyright notice,
118
+ # this list of conditions and the following disclaimer in the documentation
119
+ # and/or other materials provided with the distribution.
120
+ #
121
+ # * Neither the name of the copyright holder nor the names of its
122
+ # contributors may be used to endorse or promote products derived from
123
+ # this software without specific prior written permission.
124
+ #
125
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
126
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
127
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
128
+ # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
129
+ # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
130
+ # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
131
+ # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
132
+ # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
133
+ # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
134
+ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,125 @@
1
+ # The IO module provides objects, modules, and functions to handle input/output operations.
2
+ module RuneRb::IO
3
+
4
+ # Represents a composable/decomposable network message that is either sent or received via a TCPSocket.
5
+ class Message
6
+ include RuneRb::Utils::Logging
7
+
8
+ # @return [Struct] the header for the message.
9
+ attr :header
10
+
11
+ # @return [Buffer] the access mode for the message.
12
+ attr :body
13
+
14
+ # Models the heading of a protocol data unit received from a peer socket.
15
+ # @param op_code [Integer] the Operation Code of the data unit
16
+ # @param length [Integer] the length of data unit's payload, excluding the header.
17
+ # @param type [Symbol] the type of header of the data unit.
18
+ # @return [Struct]
19
+ Header = Struct.new(:op_code, :length, :type) do
20
+
21
+ # Generates a binary string representation of the {Header} object.
22
+ # @return [String, NilClass] binary representation of the header.
23
+ def compile_header
24
+ case self.type
25
+ when :FIXED then [self.op_code].pack('C') # Fixed packet lengths are known by both the client and server, so no length packing is necesssary
26
+ when :RAW then ''
27
+ when :VARIABLE_SHORT then [self.op_code, self.length].pack('Cn') # Variable Short packet lengths fall into the range of a short type and can be packed as such
28
+ when :VARIABLE_BYTE # Variable Byte packet lengths fall into the range of a byte type and can be packed as such
29
+ if self.length.nonzero? && self.length.positive?
30
+ [self.op_code, self.length].pack('Cc')
31
+ elsif self.length.nonzero? && self.length.negative?
32
+ self.type = :FIXED
33
+ compile_header
34
+ end
35
+ else compile_header
36
+ end
37
+ end
38
+
39
+ def inspect
40
+ "[Header]: [OpCode]: #{self.op_code} || [Length]: #{self.length}"
41
+ end
42
+ end
43
+
44
+ # Called when a new Message is created
45
+ # @param op_code [Integer] the message's operation code.
46
+ # @param type [Symbol] the message type. [:VARIABLE_BYTE, :VARIABLE_SHORT, :FIXED]
47
+ # @param body [String, RuneRb::Network::Buffer] an optional body payload for the message.
48
+ # @return [Message] the instance created.
49
+ def initialize(op_code: -1, type: :FIXED, body: RuneRb::IO::Buffer.new('rw'))
50
+ @header = Header.new(op_code, 0, type)
51
+ @body = case body
52
+ when RuneRb::IO::Buffer then body
53
+ when String then RuneRb::IO::Buffer.new('r', data: body)
54
+ else raise "Invalid body type for message! Expecting: Buffer, String Got: #{body.class}"
55
+ end
56
+ update_length
57
+
58
+ self
59
+ end
60
+
61
+ # Compiles the {Message} into a string of binary data.
62
+ # @return [String] binary representation of the message.
63
+ def compile
64
+ @header.compile_header + @body.snapshot
65
+ end
66
+
67
+ def inspect
68
+ "#{@header.inspect} || #{@body.inspect}"
69
+ end
70
+
71
+ # @abstract parses the message object.
72
+ def parse(_session); end
73
+
74
+ # Read data from the {Message#body}
75
+ # @param type [Symbol] the type of data to read
76
+ # @param signed [Boolean] should the value be signed
77
+ # @param mutation [Symbol] the mutation that should be applied to the data
78
+ # @param order [String] the byte order to read the data in.
79
+ def read(type: :byte, signed: false, mutation: :STD, order: 'BIG')
80
+ @body.read(type: type, signed: signed, mutation: mutation, order: order)
81
+ end
82
+
83
+ # Write data to the {Message#body}
84
+ def write(value, type: :byte, mutation: :STD, order: 'BIG', options: {})
85
+ @body.write(value, type: type, mutation: mutation, order: order, options: options)
86
+ update_length
87
+ self
88
+ end
89
+
90
+ private
91
+
92
+ # Updates the length of the <@header>
93
+ def update_length
94
+ @header.length = @body.length
95
+ end
96
+ end
97
+ end
98
+
99
+ # Copyright (c) 2022, Patrick W.
100
+ # All rights reserved.
101
+ #
102
+ # Redistribution and use in source and binary forms, with or without
103
+ # modification, are permitted provided that the following conditions are met:
104
+ #
105
+ # * Redistributions of source code must retain the above copyright notice, this
106
+ # list of conditions and the following disclaimer.
107
+ #
108
+ # * Redistributions in binary form must reproduce the above copyright notice,
109
+ # this list of conditions and the following disclaimer in the documentation
110
+ # and/or other materials provided with the distribution.
111
+ #
112
+ # * Neither the name of the copyright holder nor the names of its
113
+ # contributors may be used to endorse or promote products derived from
114
+ # this software without specific prior written permission.
115
+ #
116
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
117
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
118
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
119
+ # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
120
+ # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
121
+ # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
122
+ # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
123
+ # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
124
+ # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
125
+ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,123 @@
1
+ # The IO module provides objects, modules, and functions to handle input/output operations.
2
+ module RuneRb::IO
3
+
4
+ # Provides functions to read integer values from a string-based buffer using native ruby methods.
5
+ module NativeReadable
6
+ # Read a byte value from the {Buffer#data}
7
+ # @param signed [Boolean] should the value be signed.
8
+ # @param mutation [String] mutation that should be applied to the byte value.
9
+ def read_byte(mutation: :STD, signed: false)
10
+ mutate(@data.slice!(0)&.unpack1(signed ? 'c' : 'C') || 0, mutation)
11
+ end
12
+
13
+ # Reads a short value from the {Buffer#data}
14
+ # @param signed [Boolean] should the value be signed.
15
+ # @param mutation [String] mutation that should be applied to the short value
16
+ # @param order [String] they byte order to read the short value
17
+ def read_short(signed: false, mutation: :STD, order: 'BIG')
18
+ val = 0
19
+ case order
20
+ when 'BIG'
21
+ val += mutate(@data.slice!(0..1).unpack1(signed ? 's>' : 'S>'), mutation)
22
+ when 'LITTLE'
23
+ val += mutate(@data.slice!(0..1).unpack1(signed ? 's<' : 'S<'), mutation)
24
+ else read_short(signed: signed, mutation: mutation, order: 'BIG')
25
+ end
26
+ val
27
+ end
28
+
29
+ # Reads a medium value from the {Buffer#data}
30
+ # @param signed [Boolean] should the value be signed.
31
+ # @param mutation [String] mutation that should be applied to the medium value
32
+ # @param order [String] they byte order to read the medium value
33
+ def read_medium(signed: false, mutation: :STD, order: 'BIG')
34
+ val = 0
35
+ case order
36
+ when 'BIG'
37
+ val += read_byte(signed: signed) << 16
38
+ val += read_byte(signed: signed) << 8
39
+ val += read_byte(signed: signed, mutation: mutation)
40
+ when 'MIDDLE'
41
+ val += read_byte(signed: signed) << 8
42
+ val += read_byte(signed: signed, mutation: mutation)
43
+ val += read_byte(signed: signed) << 16
44
+ when 'LITTLE'
45
+ val += read_byte(signed: signed, mutation: mutation)
46
+ val += read_byte(signed: signed) << 8
47
+ val += read_byte(signed: signed) << 16
48
+ else read_medium(signed: signed, mutation: mutation, order: 'BIG')
49
+ end
50
+ val
51
+ end
52
+
53
+ # Reads a integer value from the {Buffer#data}
54
+ # @param signed [Boolean] should the value be signed.
55
+ # @param mutation [String] mutation that should be applied to the integer value
56
+ # @param order [String] they byte order to read the integer value
57
+ def read_int(signed: false, mutation: :STD, order: 'BIG')
58
+ val = 0
59
+ case order
60
+ when 'BIG'
61
+ val += mutate(@data.slice!(0..3).unpack1(signed ? 'i>' : 'I>'), mutation)
62
+ when 'MIDDLE'
63
+ val += read_byte(signed: signed) << 8
64
+ val += read_byte(signed: signed, mutation: mutation)
65
+ val += read_byte(signed: signed) << 24
66
+ val += read_byte(signed: signed) << 16
67
+ return val
68
+ when 'INVERSE_MIDDLE'
69
+ val += read_byte(signed: signed) << 16
70
+ val += read_byte(signed: signed) << 24
71
+ val += read_byte(signed: signed, mutation: mutation)
72
+ val += read_byte(signed: signed) << 8
73
+ return val
74
+ when 'LITTLE'
75
+ val += mutate(@data.slice!(0..3).unpack1(signed ? 'i<' : 'I<'), mutation)
76
+ else read_int(signed: signed, mutation: mutation, order: 'BIG')
77
+ end
78
+ val
79
+ end
80
+
81
+ # Reads a long value from the {Buffer#data}
82
+ # @param signed [Boolean] should the value be signed.
83
+ # @param mutation [String] mutation that should be applied to the long value
84
+ # @param order [String] they byte order to read the long value
85
+ def read_long(signed: false, mutation: :STD, order: 'BIG')
86
+ case order
87
+ when 'BIG'
88
+ mutate(@data.slice!(0..7).unpack1(signed ? 'q>' : 'Q>'), mutation)
89
+ when 'LITTLE'
90
+ mutate(@data.slice!(0..7).unpack1(signed ? 'q<' : 'Q<'), mutation)
91
+ else read_long(signed: signed, mutation: mutation, order: 'BIG')
92
+ end
93
+ end
94
+ end
95
+ end
96
+
97
+ # Copyright (c) 2022, Patrick W.
98
+ # All rights reserved.
99
+ #
100
+ # Redistribution and use in source and binary forms, with or without
101
+ # modification, are permitted provided that the following conditions are met:
102
+ #
103
+ # * Redistributions of source code must retain the above copyright notice, this
104
+ # list of conditions and the following disclaimer.
105
+ #
106
+ # * Redistributions in binary form must reproduce the above copyright notice,
107
+ # this list of conditions and the following disclaimer in the documentation
108
+ # and/or other materials provided with the distribution.
109
+ #
110
+ # * Neither the name of the copyright holder nor the names of its
111
+ # contributors may be used to endorse or promote products derived from
112
+ # this software without specific prior written permission.
113
+ #
114
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
115
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
116
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
117
+ # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
118
+ # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
119
+ # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
120
+ # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
121
+ # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
122
+ # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
123
+ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,199 @@
1
+ # The IO module of the Rune.rb framework provides objects, modules, and functions to handle input/output operations.
2
+ module RuneRb::IO
3
+
4
+ # Provides functions for reading integer values from a string-based buffer.
5
+ module Readable
6
+ using RuneRb::Patches::IntegerRefinements
7
+
8
+ # Read data from the payload according to the option parameter.
9
+ # @param type [Symbol] the type of database to read
10
+ # @param mutation [Symbol] an option mutation to apply to the read value.
11
+ def read(type: :byte, signed: false, mutation: :STD, order: 'BIG', options: {})
12
+ return unless RuneRb::IO::Validation.validate(self, 'read', { bit_access: @bit_access, mutation: mutation, order: order })
13
+
14
+ case type
15
+ when :bits then read_bits(options[:amount])
16
+ when :byte then read_byte(signed: signed, mutation: mutation)
17
+ when :bytes then read_bytes(options[:amount] || 1, mutation: mutation)
18
+ when :short then read_short(signed: signed, mutation: mutation, order: order)
19
+ when :medium then read_medium(signed: signed, mutation: mutation, order: order)
20
+ when :int then read_int(signed: signed, mutation: mutation, order: order)
21
+ when :long then read_long(signed: signed, mutation: mutation, order: order)
22
+ when :smart then read_smart(signed: signed, mutation: mutation)
23
+ when :string then read_string
24
+ when :reverse_bytes then read_bytes_reverse(options[:amount] || 1, mutation: mutation)
25
+ else raise "Unrecognized read type! #{type}"
26
+ end
27
+ end
28
+
29
+ private
30
+
31
+ # Read multiple bytes from the {Buffer#data}
32
+ # @param amount [Integer] the amount of bytes to read
33
+ # @param mutation [Symbol] the mutation to apply to read bytes.
34
+ def read_bytes(amount, mutation)
35
+ amount.times.each_with_object([]) { |_idx, arr| arr << read_byte(signed: false, mutation: mutation) }
36
+ end
37
+
38
+ # Probably did this wrong
39
+ # @param amount [Integer] the amount of bytes to read
40
+ # @param mutation [Symbol] an optional mutation to apply to the result.
41
+ def read_bytes_reverse(amount, mutation)
42
+ @data.reverse
43
+ value = read_bytes(amount, mutation)
44
+ @data.reverse
45
+ value
46
+ end
47
+
48
+ # Read a byte value from the {Buffer#data}
49
+ # @param signed [Boolean] should the value be signed.
50
+ # @param mutation [String] mutation that should be applied to the byte value.
51
+ def read_byte(mutation: :STD, signed: false)
52
+ val = mutate(@data.slice!(0)&.unpack1(signed ? 'c' : 'C') || 0, mutation)
53
+ signed ? val.signed(:byte) : val.unsigned(:byte)
54
+ end
55
+
56
+ # Reads a short value from the {Buffer#data}
57
+ # @param signed [Boolean] should the value be signed.
58
+ # @param mutation [String] mutation that should be applied to the short value
59
+ # @param order [String] they byte order to read the short value
60
+ def read_short(signed: false, mutation: :STD, order: 'BIG')
61
+ val = 0
62
+ case order
63
+ when 'BIG'
64
+ val += read_byte(signed: signed) << 8
65
+ val += read_byte(mutation: mutation, signed: signed)
66
+ when 'LITTLE'
67
+ val += read_byte(mutation: mutation, signed: signed)
68
+ val += read_byte(signed: signed) << 8
69
+ else read_short(signed: signed, mutation: mutation, order: 'BIG')
70
+ end
71
+ val
72
+ end
73
+
74
+ # Reads a medium value from the {Buffer#data}
75
+ # @param signed [Boolean] should the value be signed.
76
+ # @param mutation [String] mutation that should be applied to the medium value
77
+ # @param order [String] they byte order to read the medium value
78
+ def read_medium(signed: false, mutation: :STD, order: 'BIG')
79
+ val = 0
80
+ case order
81
+ when 'BIG'
82
+ val += read_byte(signed: signed) << 16
83
+ val += read_byte(signed: signed) << 8
84
+ val += read_byte(signed: signed, mutation: mutation)
85
+ when 'MIDDLE'
86
+ val += read_byte(signed: signed) << 8
87
+ val += read_byte(signed: signed, mutation: mutation)
88
+ val += read_byte(signed: signed) << 16
89
+ when 'LITTLE'
90
+ val += read_byte(signed: signed, mutation: mutation)
91
+ val += read_byte(signed: signed) << 8
92
+ val += read_byte(signed: signed) << 16
93
+ else read_medium(signed: signed, mutation: mutation, order: 'BIG')
94
+ end
95
+ val
96
+ end
97
+
98
+ # Reads a integer value from the {Buffer#data}
99
+ # @param signed [Boolean] should the value be signed.
100
+ # @param mutation [String] mutation that should be applied to the integer value
101
+ # @param order [String] they byte order to read the integer value
102
+ def read_int(signed: false, mutation: :STD, order: 'BIG')
103
+ val = 0
104
+ case order
105
+ when 'BIG'
106
+ val += read_byte(signed: signed) << 24
107
+ val += read_byte(signed: signed) << 16
108
+ val += read_byte(signed: signed) << 8
109
+ val += read_byte(signed: signed, mutation: mutation)
110
+ when 'MIDDLE'
111
+ val += read_byte(signed: signed) << 8
112
+ val += read_byte(signed: signed, mutation: mutation)
113
+ val += read_byte(signed: signed) << 24
114
+ val += read_byte(signed: signed) << 16
115
+ when 'INVERSE_MIDDLE'
116
+ val += read_byte(signed: signed) << 16
117
+ val += read_byte(signed: signed) << 24
118
+ val += read_byte(signed: signed, mutation: mutation)
119
+ val += read_byte(signed: signed) << 8
120
+ when 'LITTLE'
121
+ val += read_byte(signed: signed, mutation: mutation)
122
+ val += read_byte(signed: signed) << 8
123
+ val += read_byte(signed: signed) << 16
124
+ val += read_byte(signed: signed) << 24
125
+ else read_int(signed: signed, mutation:mutation, order: 'BIG')
126
+ end
127
+ val
128
+ end
129
+
130
+ # Reads a long value from the {Buffer#data}
131
+ # @param signed [Boolean] should the value be signed.
132
+ # @param mutation [String] mutation that should be applied to the long value
133
+ # @param order [String] they byte order to read the long value
134
+ def read_long(signed: false, mutation: :STD, order: 'BIG')
135
+ val = 0
136
+ case order
137
+ when 'BIG'
138
+ (RuneRb::IO::BYTE_SIZE * 7).downto(0) { |div| ((div % 8).zero? and div.positive?) ? val |= read_byte(signed: signed) << div : next }
139
+ val += read_byte(signed: signed, mutation: mutation)
140
+ when 'LITTLE'
141
+ val += read_byte(signed: signed, mutation: mutation)
142
+ (0).upto(RuneRb::IO::BYTE_SIZE * 7) { |div| ((div % 8).zero? and div.positive?) ? val |= read_byte(signed: signed) << div: next }
143
+ else read_long(signed: signed, mutation: mutation, order: 'BIG')
144
+ end
145
+ val
146
+ end
147
+
148
+ # Read a smart value from the {Buffer#data}
149
+ # @param signed [Boolean] should the value be signed.
150
+ # @param mutation [String] mutation that should be applied to the long value
151
+ def read_smart(signed: false, mutation: :STD)
152
+ val = peek.slice(0).unpack1(signed ? 'c' : 'C')
153
+ case signed
154
+ when true then val < 128 ? read_byte(mutation: mutation, signed: signed) - 64 : read_short(mutation: mutation, signed: signed, order: 'BIG') - 49_152
155
+ when false then val < 128 ? read_byte(mutation: mutation, signed: signed) : read_short(mutation: mutation, signed: signed, order: 'BIG') - 32_768
156
+ end
157
+ end
158
+
159
+ # Reads a string from the {Buffer#data}
160
+ # @return [String] the resulting string.
161
+ def read_string
162
+ val = ''
163
+ while (res = read_byte; res != 10)
164
+ break if res == "\n"
165
+
166
+ val << res
167
+ end
168
+ val
169
+ end
170
+ end
171
+ end
172
+
173
+ # Copyright (c) 2022, Patrick W.
174
+ # All rights reserved.
175
+ #
176
+ # Redistribution and use in source and binary forms, with or without
177
+ # modification, are permitted provided that the following conditions are met:
178
+ #
179
+ # * Redistributions of source code must retain the above copyright notice, this
180
+ # list of conditions and the following disclaimer.
181
+ #
182
+ # * Redistributions in binary form must reproduce the above copyright notice,
183
+ # this list of conditions and the following disclaimer in the documentation
184
+ # and/or other materials provided with the distribution.
185
+ #
186
+ # * Neither the name of the copyright holder nor the names of its
187
+ # contributors may be used to endorse or promote products derived from
188
+ # this software without specific prior written permission.
189
+ #
190
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
191
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
192
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
193
+ # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
194
+ # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
195
+ # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
196
+ # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
197
+ # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
198
+ # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
199
+ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.