aerospike 2.13.0 → 2.18.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +44 -1
  3. data/lib/aerospike.rb +14 -0
  4. data/lib/aerospike/cdt/bit_operation.rb +376 -0
  5. data/lib/aerospike/cdt/bit_overflow_action.rb +46 -0
  6. data/lib/aerospike/cdt/bit_policy.rb +36 -0
  7. data/lib/aerospike/cdt/bit_resize_flags.rb +44 -0
  8. data/lib/aerospike/cdt/bit_write_flags.rb +51 -0
  9. data/lib/aerospike/cdt/context.rb +113 -0
  10. data/lib/aerospike/cdt/hll_operation.rb +200 -0
  11. data/lib/aerospike/cdt/hll_policy.rb +34 -0
  12. data/lib/aerospike/cdt/hll_write_flags.rb +53 -0
  13. data/lib/aerospike/cdt/list_operation.rb +155 -96
  14. data/lib/aerospike/cdt/list_order.rb +7 -0
  15. data/lib/aerospike/cdt/list_sort_flags.rb +10 -2
  16. data/lib/aerospike/cdt/map_operation.rb +179 -92
  17. data/lib/aerospike/cdt/map_order.rb +3 -3
  18. data/lib/aerospike/client.rb +24 -7
  19. data/lib/aerospike/cluster.rb +47 -0
  20. data/lib/aerospike/cluster/rack_parser.rb +117 -0
  21. data/lib/aerospike/command/batch_direct_command.rb +1 -0
  22. data/lib/aerospike/command/batch_index_command.rb +1 -0
  23. data/lib/aerospike/command/command.rb +76 -7
  24. data/lib/aerospike/command/multi_command.rb +44 -1
  25. data/lib/aerospike/command/read_command.rb +34 -2
  26. data/lib/aerospike/command/touch_command.rb +34 -1
  27. data/lib/aerospike/features.rb +5 -0
  28. data/lib/aerospike/node.rb +18 -1
  29. data/lib/aerospike/node/rebalance.rb +50 -0
  30. data/lib/aerospike/node/refresh/info.rb +4 -1
  31. data/lib/aerospike/node/refresh/racks.rb +47 -0
  32. data/lib/aerospike/node/refresh/reset.rb +1 -0
  33. data/lib/aerospike/node/verify/rebalance_generation.rb +43 -0
  34. data/lib/aerospike/operation.rb +7 -2
  35. data/lib/aerospike/policy/client_policy.rb +15 -0
  36. data/lib/aerospike/policy/policy.rb +11 -3
  37. data/lib/aerospike/policy/replica.rb +7 -0
  38. data/lib/aerospike/result_code.rb +102 -0
  39. data/lib/aerospike/socket/base.rb +3 -2
  40. data/lib/aerospike/utils/buffer.rb +13 -3
  41. data/lib/aerospike/utils/unpacker.rb +2 -2
  42. data/lib/aerospike/value/particle_type.rb +1 -1
  43. data/lib/aerospike/value/value.rb +107 -5
  44. data/lib/aerospike/version.rb +1 -1
  45. metadata +15 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7bef523a7e7500d8e39cb80f3b9ee6831a5ddc0bd6d782685181cae6a6c6ada5
4
- data.tar.gz: 760d626bffac6ed69bcdda048daf39b07a12a85264b67be0677ad5d552c5473c
3
+ metadata.gz: 35e9a8a3ec876281db49c949373f2e1f34fb38ed86f4cf62074990ef66637e22
4
+ data.tar.gz: 9fcd59bb4c7137be98624f6de64beff53ec0d526309ea7403e7e2596057c216b
5
5
  SHA512:
6
- metadata.gz: df19a0c2900463a35b73ba52bfae3bdb2c5f6cbdaba3ab17172219e96ad3de3878bbc1ff57403fbbffe0fb48cc147ee642297e2fe47c829d768e76b1e4dee0fa
7
- data.tar.gz: 528ade6f9abfb9b9e266439fefa6606f2623aec2503ec6c5466a5c3f9ffd9656debea49ff434f715f042c3ae319546e80352aa36cdc925ed351cab2633c75c4b
6
+ metadata.gz: da0e22181c8410de556a7f5baf7d14a53ad0ddacc95e3a24e7442ab15196b70bfd4c79259ea9502ec18dc9cb1978d68c1b5bc5192dbba4821d267d8497c0e8ba
7
+ data.tar.gz: 02b0fe95378602aed2d7cb232f61453d87cac2824c4b832cd40187925376f37afef6df3a7b1c1261f426e898f8f4d82136f3da42edf454834a0c91f913318e5d
@@ -2,7 +2,50 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file.
4
4
 
5
- ## [2.13.0] - 2019-07-17
5
+ ## [2.18.0] - 2020-12-01
6
+
7
+ * **Bug Fixes**
8
+ * Avoid panic if `Command#get_node` fails in `Command#execute`. Resolves issue #101.
9
+ * Fix wrong method invocation inside `Client#truncate` method. Thanks to [Alexander](https://github.com/selivandex)
10
+
11
+ * **Improvements**
12
+ * Added missing server error codes.
13
+
14
+ ## [2.17.0] - 2020-10-15
15
+
16
+ * **New Features**
17
+ * [CLIENT-1246] Adds missing API for Context#list_index_create and Context#map_key_create
18
+
19
+ * **Bug Fixes**
20
+ * Fixed an issue were MsgPack extensions were not recursively cleared from the CDTs during unpacking.
21
+
22
+ ## [2.16.0] - 2020-10-12
23
+
24
+ * **New Features**
25
+ * [CLIENT-1173], [CLIENT-1246] Support Nested CDT operations with Context.
26
+ * [CLIENT-1179], Support Bitwise operations.
27
+
28
+ * **Changes**
29
+ * `ListSortFlags` now has an `ASCENDING` option, with `DEFAULT` mapping to it.
30
+
31
+ ## [2.15.0] - 2020-10-05
32
+
33
+ * **New Features**
34
+ * [CLIENT-1254] Adds support for HyperLogLog.
35
+
36
+ * **Changes**
37
+ * `Client#operate` now uses `OperatePolicy` by default.
38
+
39
+ ## [2.14.0] - 2020-08-06
40
+
41
+ * **New Features**
42
+ * Adds support for rack-aware reads.
43
+ * Adds support for client-server compression.
44
+
45
+ * **Improvements**
46
+ * Adds support for `truncate-namespace` command.
47
+
48
+ ## [2.13.0] - 2020-07-17
6
49
 
7
50
  * **New Features**
8
51
  * Adds support for replica policies.
@@ -22,6 +22,7 @@ require "timeout"
22
22
  require 'resolv'
23
23
  require 'msgpack'
24
24
  require 'bcrypt'
25
+ require 'zlib'
25
26
 
26
27
  require 'aerospike/atomic/atomic'
27
28
 
@@ -64,6 +65,7 @@ require 'aerospike/command/admin_command'
64
65
  require 'aerospike/command/unsupported_particle_type_validator'
65
66
  require 'aerospike/key'
66
67
  require 'aerospike/operation'
68
+ require 'aerospike/cdt/context'
67
69
  require 'aerospike/cdt/list_operation'
68
70
  require 'aerospike/cdt/list_order'
69
71
  require 'aerospike/cdt/list_return_type'
@@ -76,6 +78,14 @@ require 'aerospike/cdt/map_return_type'
76
78
  require 'aerospike/cdt/map_write_flags'
77
79
  require 'aerospike/cdt/map_write_mode'
78
80
  require 'aerospike/cdt/map_policy'
81
+ require 'aerospike/cdt/hll_operation'
82
+ require 'aerospike/cdt/hll_write_flags'
83
+ require 'aerospike/cdt/hll_policy'
84
+ require 'aerospike/cdt/bit_operation'
85
+ require 'aerospike/cdt/bit_overflow_action'
86
+ require 'aerospike/cdt/bit_resize_flags'
87
+ require 'aerospike/cdt/bit_write_flags'
88
+ require 'aerospike/cdt/bit_policy'
79
89
  require 'aerospike/geo_json'
80
90
  require 'aerospike/ttl'
81
91
 
@@ -105,17 +115,21 @@ require 'aerospike/cluster/find_nodes_to_remove'
105
115
  require 'aerospike/cluster/find_node'
106
116
  require 'aerospike/cluster/partition'
107
117
  require 'aerospike/cluster/partition_parser'
118
+ require 'aerospike/cluster/rack_parser'
108
119
  require 'aerospike/node'
109
120
  require 'aerospike/node/generation'
121
+ require 'aerospike/node/rebalance'
110
122
  require 'aerospike/node/refresh/failed'
111
123
  require 'aerospike/node/refresh/friends'
112
124
  require 'aerospike/node/refresh/info'
113
125
  require 'aerospike/node/refresh/partitions'
126
+ require 'aerospike/node/refresh/racks'
114
127
  require 'aerospike/node/refresh/peers'
115
128
  require 'aerospike/node/refresh/reset'
116
129
  require 'aerospike/node/verify/cluster_name'
117
130
  require 'aerospike/node/verify/name'
118
131
  require 'aerospike/node/verify/partition_generation'
132
+ require 'aerospike/node/verify/rebalance_generation'
119
133
  require 'aerospike/node/verify/peers_generation'
120
134
  require 'aerospike/node_validator'
121
135
  require 'aerospike/peer'
@@ -0,0 +1,376 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright 2016-2020 Aerospike, Inc.
4
+ #
5
+ # Portions may be licensed to Aerospike, Inc. under one or more contributor
6
+ # license agreements.
7
+ #
8
+ # Licensed under the Apache License, Version 2.0 (the "License"); you may not
9
+ # use this file except in compliance with the License. You may obtain a copy of
10
+ # the License at
11
+ #
12
+ # http:#www.apache.org/licenses/LICENSE-2.0
13
+ #
14
+ # Unless required by applicable law or agreed to in writing, software
15
+ # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
16
+ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
17
+ # License for the specific language governing permissions and limitations under
18
+ # the License.
19
+
20
+ module Aerospike
21
+ module CDT
22
+
23
+ ##
24
+ # Bit operations. Create bit operations used by client operate command.
25
+ # Offset orientation is left-to-right. Negative offsets are supported.
26
+ # If the offset is negative, the offset starts backwards from end of the bitmap.
27
+ # If an offset is out of bounds, a parameter error will be returned.
28
+ #
29
+ # Nested CDT operations are supported by optional context arguments. Example:
30
+ # bin = [[0b00000001, 0b01000010],[0b01011010]]
31
+ # Resize first bitmap (in a list of bitmaps) to 3 bytes.
32
+ # BitOperation.resize("bin", 3, BitResizeFlags::DEFAULT, ctx: [Context.list_index(0)])
33
+ # bin result = [[0b00000001, 0b01000010, 0b00000000],[0b01011010]]
34
+ class BitOperation < Operation
35
+
36
+ RESIZE = 0
37
+ INSERT = 1
38
+ REMOVE = 2
39
+ SET = 3
40
+ OR = 4
41
+ XOR = 5
42
+ AND = 6
43
+ NOT = 7
44
+ LSHIFT = 8
45
+ RSHIFT = 9
46
+ ADD = 10
47
+ SUBTRACT = 11
48
+ SET_INT = 12
49
+ GET = 50
50
+ COUNT = 51
51
+ LSCAN = 52
52
+ RSCAN = 53
53
+ GET_INT = 54
54
+
55
+ INT_FLAGS_SIGNED = 1
56
+
57
+ attr_reader :bit_op, :arguments, :policy, :ctx
58
+
59
+ def initialize(op_type, bit_op, bin_name, *arguments, ctx: nil, policy: nil)
60
+ @op_type = op_type
61
+ @bin_name = bin_name
62
+ @bin_value = nil
63
+ @bit_op = bit_op
64
+ @ctx = ctx
65
+ @arguments = arguments
66
+ end
67
+
68
+
69
+ # BitResizeOp creates byte "resize" operation.
70
+ # Server resizes byte[] to byte_size according to resize_flags (See {@link BitResizeFlags}).
71
+ # Server does not return a value.
72
+ # Example:
73
+ # bin = [0b00000001, 0b01000010]
74
+ # byte_size = 4
75
+ # resize_flags = 0
76
+ # bin result = [0b00000001, 0b01000010, 0b00000000, 0b00000000]
77
+ def self.resize(bin_name, byte_size, resize_flags, ctx: nil, policy: BitPolicy::DEFAULT)
78
+ BitOperation.new(Operation::BIT_MODIFY, RESIZE, bin_name, byte_size, policy.flags, resize_flags, ctx: ctx, policy: policy)
79
+ end
80
+
81
+ # BitInsertOp creates byte "insert" operation.
82
+ # Server inserts value bytes into byte[] bin at byte_offset.
83
+ # Server does not return a value.
84
+ # Example:
85
+ # bin = [0b00000001, 0b01000010, 0b00000011, 0b00000100, 0b00000101]
86
+ # byte_offset = 1
87
+ # value = [0b11111111, 0b11000111]
88
+ # bin result = [0b00000001, 0b11111111, 0b11000111, 0b01000010, 0b00000011, 0b00000100, 0b00000101]
89
+ def self.insert(bin_name, byte_offset, value, ctx: nil, policy: BitPolicy::DEFAULT)
90
+ BitOperation.new(Operation::BIT_MODIFY, INSERT, bin_name, byte_offset, value_to_bytes(value), policy.flags, ctx: ctx, policy: policy)
91
+ end
92
+
93
+ # BitRemoveOp creates byte "remove" operation.
94
+ # Server removes bytes from byte[] bin at byte_offset for byte_size.
95
+ # Server does not return a value.
96
+ # Example:
97
+ # bin = [0b00000001, 0b01000010, 0b00000011, 0b00000100, 0b00000101]
98
+ # byte_offset = 2
99
+ # byte_size = 3
100
+ # bin result = [0b00000001, 0b01000010]
101
+ def self.remove(bin_name, byte_offset, byte_size, ctx: nil, policy: BitPolicy::DEFAULT)
102
+ BitOperation.new(Operation::BIT_MODIFY, REMOVE, bin_name, byte_offset, byte_size, policy.flags, ctx: ctx, policy: policy)
103
+ end
104
+
105
+ # BitSetOp creates bit "set" operation.
106
+ # Server sets value on byte[] bin at bit_offset for bit_size.
107
+ # Server does not return a value.
108
+ # Example:
109
+ # bin = [0b00000001, 0b01000010, 0b00000011, 0b00000100, 0b00000101]
110
+ # bit_offset = 13
111
+ # bit_size = 3
112
+ # value = [0b11100000]
113
+ # bin result = [0b00000001, 0b01000111, 0b00000011, 0b00000100, 0b00000101]
114
+ def self.set(bin_name, bit_offset, bit_size, value, ctx: nil, policy: BitPolicy::DEFAULT)
115
+ BitOperation.new(Operation::BIT_MODIFY, SET, bin_name, bit_offset, bit_size, value_to_bytes(value), policy.flags, ctx: ctx, policy: policy)
116
+ end
117
+
118
+ # BitOrOp creates bit "or" operation.
119
+ # Server performs bitwise "or" on value and byte[] bin at bit_offset for bit_size.
120
+ # Server does not return a value.
121
+ # Example:
122
+ # bin = [0b00000001, 0b01000010, 0b00000011, 0b00000100, 0b00000101]
123
+ # bit_offset = 17
124
+ # bit_size = 6
125
+ # value = [0b10101000]
126
+ # bin result = [0b00000001, 0b01000010, 0b01010111, 0b00000100, 0b00000101]
127
+ def self.or(bin_name, bit_offset, bit_size, value, ctx: nil, policy: BitPolicy::DEFAULT)
128
+ BitOperation.new(Operation::BIT_MODIFY, OR, bin_name, bit_offset, bit_size, value_to_bytes(value), policy.flags, ctx: ctx, policy: policy)
129
+ end
130
+
131
+ # BitXorOp creates bit "exclusive or" operation.
132
+ # Server performs bitwise "xor" on value and byte[] bin at bit_offset for bit_size.
133
+ # Server does not return a value.
134
+ # Example:
135
+ # bin = [0b00000001, 0b01000010, 0b00000011, 0b00000100, 0b00000101]
136
+ # bit_offset = 17
137
+ # bit_size = 6
138
+ # value = [0b10101100]
139
+ # bin result = [0b00000001, 0b01000010, 0b01010101, 0b00000100, 0b00000101]
140
+ def self.xor(bin_name, bit_offset, bit_size, value, ctx: nil, policy: BitPolicy::DEFAULT)
141
+ BitOperation.new(Operation::BIT_MODIFY, XOR, bin_name, bit_offset, bit_size, value_to_bytes(value), policy.flags, ctx: ctx, policy: policy)
142
+ end
143
+
144
+ # BitAndOp creates bit "and" operation.
145
+ # Server performs bitwise "and" on value and byte[] bin at bit_offset for bit_size.
146
+ # Server does not return a value.
147
+ # Example:
148
+ # bin = [0b00000001, 0b01000010, 0b00000011, 0b00000100, 0b00000101]
149
+ # bit_offset = 23
150
+ # bit_size = 9
151
+ # value = [0b00111100, 0b10000000]
152
+ # bin result = [0b00000001, 0b01000010, 0b00000010, 0b00000000, 0b00000101]
153
+ def self.and(bin_name, bit_offset, bit_size, value, ctx: nil, policy: BitPolicy::DEFAULT)
154
+ BitOperation.new(Operation::BIT_MODIFY, AND, bin_name, bit_offset, bit_size, value_to_bytes(value), policy.flags, ctx: ctx, policy: policy)
155
+ end
156
+
157
+ # BitNotOp creates bit "not" operation.
158
+ # Server negates byte[] bin starting at bit_offset for bit_size.
159
+ # Server does not return a value.
160
+ # Example:
161
+ # bin = [0b00000001, 0b01000010, 0b00000011, 0b00000100, 0b00000101]
162
+ # bit_offset = 25
163
+ # bit_size = 6
164
+ # bin result = [0b00000001, 0b01000010, 0b00000011, 0b01111010, 0b00000101]
165
+ def self.not(bin_name, bit_offset, bit_size, ctx: nil, policy: BitPolicy::DEFAULT)
166
+ BitOperation.new(Operation::BIT_MODIFY, NOT, bin_name, bit_offset, bit_size, policy.flags, ctx: ctx, policy: policy)
167
+ end
168
+
169
+ # BitLShiftOp creates bit "left shift" operation.
170
+ # Server shifts left byte[] bin starting at bit_offset for bit_size.
171
+ # Server does not return a value.
172
+ # Example:
173
+ # bin = [0b00000001, 0b01000010, 0b00000011, 0b00000100, 0b00000101]
174
+ # bit_offset = 32
175
+ # bit_size = 8
176
+ # shift = 3
177
+ # bin result = [0b00000001, 0b01000010, 0b00000011, 0b00000100, 0b00101000]
178
+ def self.lshift(bin_name, bit_offset, bit_size, shift, ctx: nil, policy: BitPolicy::DEFAULT)
179
+ BitOperation.new(Operation::BIT_MODIFY, LSHIFT, bin_name, bit_offset, bit_size, shift, policy.flags, ctx: ctx, policy: policy)
180
+ end
181
+
182
+ # BitRShiftOp creates bit "right shift" operation.
183
+ # Server shifts right byte[] bin starting at bit_offset for bit_size.
184
+ # Server does not return a value.
185
+ # Example:
186
+ # bin = [0b00000001, 0b01000010, 0b00000011, 0b00000100, 0b00000101]
187
+ # bit_offset = 0
188
+ # bit_size = 9
189
+ # shift = 1
190
+ # bin result = [0b00000000, 0b11000010, 0b00000011, 0b00000100, 0b00000101]
191
+ def self.rshift(bin_name, bit_offset, bit_size, shift, ctx: nil, policy: BitPolicy::DEFAULT)
192
+ BitOperation.new(Operation::BIT_MODIFY, RSHIFT, bin_name, bit_offset, bit_size, shift, policy.flags, ctx: ctx, policy: policy)
193
+ end
194
+
195
+ # BitAddOp creates bit "add" operation.
196
+ # Server adds value to byte[] bin starting at bit_offset for bit_size. Bit_size must be <= 64.
197
+ # Signed indicates if bits should be treated as a signed number.
198
+ # If add overflows/underflows, {@link BitOverflowAction} is used.
199
+ # Server does not return a value.
200
+ # Example:
201
+ # bin = [0b00000001, 0b01000010, 0b00000011, 0b00000100, 0b00000101]
202
+ # bit_offset = 24
203
+ # bit_size = 16
204
+ # value = 128
205
+ # signed = false
206
+ # bin result = [0b00000001, 0b01000010, 0b00000011, 0b00000100, 0b10000101]
207
+ def self.add(
208
+ bin_name,
209
+ bit_offset,
210
+ bit_size,
211
+ value,
212
+ signed,
213
+ action,
214
+ ctx: nil,
215
+ policy: BitPolicy::DEFAULT
216
+ )
217
+ actionFlags = action
218
+ actionFlags |= INT_FLAGS_SIGNED if signed
219
+
220
+ BitOperation.new(Operation::BIT_MODIFY, ADD, bin_name, bit_offset, bit_size, value, policy.flags, actionFlags, ctx: ctx, policy: policy)
221
+ end
222
+
223
+ # BitSubtractOp creates bit "subtract" operation.
224
+ # Server subtracts value from byte[] bin starting at bit_offset for bit_size. Bit_size must be <= 64.
225
+ # Signed indicates if bits should be treated as a signed number.
226
+ # If add overflows/underflows, {@link BitOverflowAction} is used.
227
+ # Server does not return a value.
228
+ # Example:
229
+ # bin = [0b00000001, 0b01000010, 0b00000011, 0b00000100, 0b00000101]
230
+ # bit_offset = 24
231
+ # bit_size = 16
232
+ # value = 128
233
+ # signed = false
234
+ # bin result = [0b00000001, 0b01000010, 0b00000011, 0b0000011, 0b10000101]
235
+ def self.subtract(
236
+ bin_name,
237
+ bit_offset,
238
+ bit_size,
239
+ value,
240
+ signed,
241
+ action,
242
+ ctx: nil,
243
+ policy: BitPolicy::DEFAULT
244
+ )
245
+ actionFlags = action
246
+ actionFlags |= INT_FLAGS_SIGNED if signed
247
+
248
+ BitOperation.new(Operation::BIT_MODIFY, SUBTRACT, bin_name, bit_offset, bit_size, value, policy.flags, actionFlags, ctx: ctx, policy: policy)
249
+ end
250
+
251
+ # BitSetIntOp creates bit "setInt" operation.
252
+ # Server sets value to byte[] bin starting at bit_offset for bit_size. Size must be <= 64.
253
+ # Server does not return a value.
254
+ # Example:
255
+ # bin = [0b00000001, 0b01000010, 0b00000011, 0b00000100, 0b00000101]
256
+ # bit_offset = 1
257
+ # bit_size = 8
258
+ # value = 127
259
+ # bin result = [0b00111111, 0b11000010, 0b00000011, 0b0000100, 0b00000101]
260
+ def self.set_int(bin_name, bit_offset, bit_size, value, ctx: nil, policy: BitPolicy::DEFAULT)
261
+ BitOperation.new(Operation::BIT_MODIFY, SET_INT, bin_name, bit_offset, bit_size, value, policy.flags, ctx: ctx, policy: policy)
262
+ end
263
+
264
+ # BitGetOp creates bit "get" operation.
265
+ # Server returns bits from byte[] bin starting at bit_offset for bit_size.
266
+ # Example:
267
+ # bin = [0b00000001, 0b01000010, 0b00000011, 0b00000100, 0b00000101]
268
+ # bit_offset = 9
269
+ # bit_size = 5
270
+ # returns [0b1000000]
271
+ def self.get(bin_name, bit_offset, bit_size, ctx: nil)
272
+ BitOperation.new(Operation::BIT_READ, GET, bin_name, bit_offset, bit_size, ctx: ctx)
273
+ end
274
+
275
+ # BitCountOp creates bit "count" operation.
276
+ # Server returns integer count of set bits from byte[] bin starting at bit_offset for bit_size.
277
+ # Example:
278
+ # bin = [0b00000001, 0b01000010, 0b00000011, 0b00000100, 0b00000101]
279
+ # bit_offset = 20
280
+ # bit_size = 4
281
+ # returns 2
282
+ def self.count(bin_name, bit_offset, bit_size, ctx: nil)
283
+ BitOperation.new(Operation::BIT_READ, COUNT, bin_name, bit_offset, bit_size, ctx: ctx)
284
+ end
285
+
286
+ # BitLScanOp creates bit "left scan" operation.
287
+ # Server returns integer bit offset of the first specified value bit in byte[] bin
288
+ # starting at bit_offset for bit_size.
289
+ # Example:
290
+ # bin = [0b00000001, 0b01000010, 0b00000011, 0b00000100, 0b00000101]
291
+ # bit_offset = 24
292
+ # bit_size = 8
293
+ # value = true
294
+ # returns 5
295
+ def self.lscan(bin_name, bit_offset, bit_size, value, ctx: nil)
296
+ BitOperation.new(Operation::BIT_READ, LSCAN, bin_name, bit_offset, bit_size, value && true, ctx: ctx)
297
+ end
298
+
299
+ # BitRScanOp creates bit "right scan" operation.
300
+ # Server returns integer bit offset of the last specified value bit in byte[] bin
301
+ # starting at bit_offset for bit_size.
302
+ # Example:
303
+ # bin = [0b00000001, 0b01000010, 0b00000011, 0b00000100, 0b00000101]
304
+ # bit_offset = 32
305
+ # bit_size = 8
306
+ # value = true
307
+ # returns 7
308
+ def self.rscan(bin_name, bit_offset, bit_size, value, ctx: nil)
309
+ BitOperation.new(Operation::BIT_READ, RSCAN, bin_name, bit_offset, bit_size, value && true, ctx: ctx)
310
+ end
311
+
312
+ # BitGetIntOp creates bit "get integer" operation.
313
+ # Server returns integer from byte[] bin starting at bit_offset for bit_size.
314
+ # Signed indicates if bits should be treated as a signed number.
315
+ # Example:
316
+ # bin = [0b00000001, 0b01000010, 0b00000011, 0b00000100, 0b00000101]
317
+ # bit_offset = 8
318
+ # bit_size = 16
319
+ # signed = false
320
+ # returns 16899
321
+ def self.get_int(bin_name, bit_offset, bit_size, signed, ctx: nil)
322
+ if signed
323
+ BitOperation.new(Operation::BIT_READ, GET_INT, bin_name, bit_offset, bit_size, INT_FLAGS_SIGNED, ctx: ctx)
324
+ else
325
+ BitOperation.new(Operation::BIT_READ, GET_INT, bin_name, bit_offset, bit_size, ctx: ctx)
326
+ end
327
+ end
328
+
329
+ def bin_value
330
+ @bin_value ||= pack_bin_value
331
+ end
332
+
333
+ private
334
+
335
+ def self.value_to_bytes(value)
336
+ case value
337
+ when Integer
338
+ [value].pack('C*')
339
+ when Array
340
+ value.pack('C*')
341
+ when String
342
+ BytesValue.new(value)
343
+ when StringValue
344
+ BytesValue.new(value.get)
345
+ else
346
+ value
347
+ end
348
+ end
349
+
350
+ def pack_bin_value
351
+ bytes = nil
352
+ args = arguments.dup
353
+ Packer.use do |packer|
354
+ if @ctx != nil && @ctx.length > 0
355
+ packer.write_array_header(3)
356
+ Value.of(0xff).pack(packer)
357
+
358
+ packer.write_array_header(@ctx.length*2)
359
+ @ctx.each do |ctx|
360
+ Value.of(ctx.id).pack(packer)
361
+ Value.of(ctx.value, true).pack(packer)
362
+ end
363
+ end
364
+
365
+ packer.write_array_header(args.length+1)
366
+ Value.of(@bit_op, true).pack(packer)
367
+ args.each do |value|
368
+ Value.of(value, true).pack(packer)
369
+ end
370
+ bytes = packer.bytes
371
+ end
372
+ BytesValue.new(bytes)
373
+ end
374
+ end
375
+ end
376
+ end