aerospike 2.13.0 → 2.18.0

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