rrb 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
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.