aerospike 2.24.0 → 2.26.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +27 -0
- data/lib/aerospike/cdt/context.rb +136 -69
- data/lib/aerospike/cdt/map_policy.rb +16 -2
- data/lib/aerospike/cdt/map_return_type.rb +9 -1
- data/lib/aerospike/client.rb +30 -32
- data/lib/aerospike/command/command.rb +104 -98
- data/lib/aerospike/command/operate_args.rb +99 -0
- data/lib/aerospike/command/operate_command.rb +6 -11
- data/lib/aerospike/exp/exp.rb +401 -334
- data/lib/aerospike/exp/exp_bit.rb +388 -0
- data/lib/aerospike/exp/exp_hll.rb +169 -0
- data/lib/aerospike/exp/exp_list.rb +403 -0
- data/lib/aerospike/exp/exp_map.rb +493 -0
- data/lib/aerospike/exp/operation.rb +56 -0
- data/lib/aerospike/features.rb +13 -0
- data/lib/aerospike/operation.rb +20 -22
- data/lib/aerospike/policy/policy.rb +25 -12
- data/lib/aerospike/query/filter.rb +44 -32
- data/lib/aerospike/query/query_executor.rb +7 -9
- data/lib/aerospike/query/query_partition_command.rb +32 -31
- data/lib/aerospike/query/recordset.rb +9 -9
- data/lib/aerospike/query/scan_executor.rb +7 -5
- data/lib/aerospike/task/execute_task.rb +17 -14
- data/lib/aerospike/utils/buffer.rb +46 -38
- data/lib/aerospike/utils/packer.rb +7 -6
- data/lib/aerospike/value/value.rb +21 -51
- data/lib/aerospike/version.rb +1 -1
- data/lib/aerospike.rb +156 -148
- metadata +8 -2
@@ -0,0 +1,403 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# Copyright 2014-2022 Aerospike, Inc.
|
3
|
+
#
|
4
|
+
# Portions may be licensed to Aerospike, Inc. under one or more contributor
|
5
|
+
# license agreements.
|
6
|
+
#
|
7
|
+
# Licensed under the Apache License, Version 2.0 (the "License") you may n
|
8
|
+
# use this file except in compliance with the License. You may obtain a copy of
|
9
|
+
# the License at http:#www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
13
|
+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
14
|
+
# License for the specific language governing permissions and limitations under
|
15
|
+
# the License.
|
16
|
+
|
17
|
+
module Aerospike
|
18
|
+
|
19
|
+
# List expression generator. See {@link Exp}.
|
20
|
+
#
|
21
|
+
# The bin expression argument in these methods can be a reference to a bin or the
|
22
|
+
# result of another expression. Expressions that modify bin values are only used
|
23
|
+
# for temporary expression evaluation and are not permanently applied to the bin.
|
24
|
+
#
|
25
|
+
# List modify expressions the bin's value. This value will be a list except
|
26
|
+
# when the list is nested within a map. In that case, a map is returned for the
|
27
|
+
# list modify expression.
|
28
|
+
#
|
29
|
+
# List expressions support negative indexing. If the index is negative, the
|
30
|
+
# resolved index starts backwards from end of list. If an index is out of bounds,
|
31
|
+
# a parameter error will be returned. If a range is partially out of bounds, the
|
32
|
+
# valid part of the range will be returned. Index/Range examples:
|
33
|
+
#
|
34
|
+
# Index 0: First item in list.
|
35
|
+
# Index 4: Fifth item in list.
|
36
|
+
# Index -1: Last item in list.
|
37
|
+
# Index -3: Third to last item in list.
|
38
|
+
# Index 1 Count 2: Second and third items in list.
|
39
|
+
# Index -3 Count 3: Last three items in list.
|
40
|
+
# Index -5 Count 4: Range between fifth to last item to second to last item inclusive.
|
41
|
+
#
|
42
|
+
# Nested expressions are supported by optional CTX context arguments. Example:
|
43
|
+
#
|
44
|
+
# bin = [[7,9,5],[1,2,3],[6,5,4,1]]
|
45
|
+
# Get size of last list.
|
46
|
+
# ListExp.size(Exp.listBin("bin"), CTX.listIndex(-1))
|
47
|
+
# result = 4
|
48
|
+
class Exp::List
|
49
|
+
|
50
|
+
# Create expression that appends value to end of list.
|
51
|
+
def self.append(value, bin, ctx: nil, policy: CDT::ListPolicy::DEFAULT)
|
52
|
+
bytes = Exp.pack(ctx, APPEND, value, policy.order, policy.flags)
|
53
|
+
self.add_write(bin, bytes, ctx)
|
54
|
+
end
|
55
|
+
|
56
|
+
# Create expression that appends list items to end of list.
|
57
|
+
def self.append_items(list, bin, ctx: nil, policy: CDT::ListPolicy::DEFAULT)
|
58
|
+
bytes = Exp.pack(ctx, APPEND_ITEMS, list, policy.order, policy.flags)
|
59
|
+
self.add_write(bin, bytes, ctx)
|
60
|
+
end
|
61
|
+
|
62
|
+
# Create expression that inserts value to specified index of list.
|
63
|
+
def self.insert(index, value, bin, ctx: nil, policy: CDT::ListPolicy::DEFAULT)
|
64
|
+
bytes = Exp.pack(ctx, INSERT, index, value, policy.flags)
|
65
|
+
self.add_write(bin, bytes, ctx)
|
66
|
+
end
|
67
|
+
|
68
|
+
# Create expression that inserts each input list item starting at specified index of list.
|
69
|
+
def self.insert_items(index, list, bin, ctx: nil, policy: CDT::ListPolicy::DEFAULT)
|
70
|
+
bytes = Exp.pack(ctx, INSERT_ITEMS, index, list, policy.flags)
|
71
|
+
self.add_write(bin, bytes, ctx)
|
72
|
+
end
|
73
|
+
|
74
|
+
# Create expression that increments list[index] by value.
|
75
|
+
# Value expression should resolve to a number.
|
76
|
+
def self.increment(index, value, bin, ctx: nil, policy: CDT::ListPolicy::DEFAULT)
|
77
|
+
bytes = Exp.pack(ctx, INCREMENT, index, value, policy.order, policy.flags)
|
78
|
+
self.add_write(bin, bytes, ctx)
|
79
|
+
end
|
80
|
+
|
81
|
+
# Create expression that sets item value at specified index in list.
|
82
|
+
def self.set(index, value, bin, ctx: nil, policy: CDT::ListPolicy::DEFAULT)
|
83
|
+
bytes = Exp.pack(ctx, SET, index, value, policy.flags)
|
84
|
+
self.add_write(bin, bytes, ctx)
|
85
|
+
end
|
86
|
+
|
87
|
+
# Create expression that removes all items in list.
|
88
|
+
def self.clear(bin, ctx: nil)
|
89
|
+
bytes = Exp.pack(ctx, CLEAR)
|
90
|
+
self.add_write(bin, bytes, ctx)
|
91
|
+
end
|
92
|
+
|
93
|
+
# Create expression that sorts list according to sort_flags.
|
94
|
+
#
|
95
|
+
# @param sort_flags sort flags. See {@link ListSortFlagsend.
|
96
|
+
# @param bin bin or list value expression
|
97
|
+
# @param ctx optional context path for nested CDT
|
98
|
+
def self.sort(sort_flags, bin, ctx: nil)
|
99
|
+
bytes = Exp.pack(ctx, SORT, sort_flags)
|
100
|
+
self.add_write(bin, bytes, ctx)
|
101
|
+
end
|
102
|
+
|
103
|
+
# Create expression that removes list items identified by value.
|
104
|
+
def self.remove_by_value(value, bin, ctx: nil)
|
105
|
+
bytes = Exp.pack(ctx, REMOVE_BY_VALUE, CDT::ListReturnType::NONE, value)
|
106
|
+
self.add_write(bin, bytes, ctx)
|
107
|
+
end
|
108
|
+
|
109
|
+
# Create expression that removes list items identified by values.
|
110
|
+
def self.remove_by_value_list(values, bin, ctx: nil)
|
111
|
+
bytes = Exp.pack(ctx, REMOVE_BY_VALUE_LIST, CDT::ListReturnType::NONE, values)
|
112
|
+
self.add_write(bin, bytes, ctx)
|
113
|
+
end
|
114
|
+
|
115
|
+
# Create expression that removes list items identified by value range (value_begin inclusive, value_end exclusive).
|
116
|
+
# If value_begin is nil, the range is less than value_end. If value_end is nil, the range is
|
117
|
+
# greater than equal to value_begin.
|
118
|
+
def self.remove_by_value_range(value_begin, value_end, bin, ctx: nil)
|
119
|
+
bytes = self.pack_range_operation(REMOVE_BY_VALUE_INTERVAL, CDT::ListReturnType::NONE, value_begin, value_end, ctx)
|
120
|
+
self.add_write(bin, bytes, ctx)
|
121
|
+
end
|
122
|
+
|
123
|
+
# Create expression that removes list items nearest to value and greater by relative rank with a count limit if provided.
|
124
|
+
#
|
125
|
+
# Examples for ordered list [0,4,5,9,11,15]:
|
126
|
+
#
|
127
|
+
# (value,rank,count) = [removed items]
|
128
|
+
# (5,0,2) = [5,9]
|
129
|
+
# (5,1,1) = [9]
|
130
|
+
# (5,-1,2) = [4,5]
|
131
|
+
# (3,0,1) = [4]
|
132
|
+
# (3,3,7) = [11,15]
|
133
|
+
# (3,-3,2) = []
|
134
|
+
def self.remove_by_value_relative_rank_range(value, rank, bin, ctx: nil, count: nil)
|
135
|
+
unless count.nil?
|
136
|
+
bytes = Exp.pack(ctx, REMOVE_BY_VALUE_REL_RANK_RANGE, CDT::ListReturnType::NONE, value, rank, count)
|
137
|
+
else
|
138
|
+
bytes = Exp.pack(ctx, REMOVE_BY_VALUE_REL_RANK_RANGE, CDT::ListReturnType::NONE, value, rank)
|
139
|
+
end
|
140
|
+
self.add_write(bin, bytes, ctx)
|
141
|
+
end
|
142
|
+
|
143
|
+
# Create expression that removes list item identified by index.
|
144
|
+
def self.remove_by_index(index, bin, ctx: nil)
|
145
|
+
bytes = Exp.pack(ctx, REMOVE_BY_INDEX, CDT::ListReturnType::NONE, index)
|
146
|
+
self.add_write(bin, bytes, ctx)
|
147
|
+
end
|
148
|
+
|
149
|
+
# Create expression that removes "count" list items starting at specified index.
|
150
|
+
def self.remove_by_index_range(index, bin, ctx: nil, count: nil)
|
151
|
+
unless count.nil?
|
152
|
+
bytes = Exp.pack(ctx, REMOVE_BY_INDEX_RANGE, CDT::ListReturnType::NONE, index, count)
|
153
|
+
else
|
154
|
+
bytes = Exp.pack(ctx, REMOVE_BY_INDEX_RANGE, CDT::ListReturnType::NONE, index)
|
155
|
+
end
|
156
|
+
self.add_write(bin, bytes, ctx)
|
157
|
+
end
|
158
|
+
|
159
|
+
# Create expression that removes list item identified by rank.
|
160
|
+
def self.remove_by_rank(rank, bin, ctx: nil)
|
161
|
+
bytes = Exp.pack(ctx, REMOVE_BY_RANK, CDT::ListReturnType::NONE, rank)
|
162
|
+
self.add_write(bin, bytes, ctx)
|
163
|
+
end
|
164
|
+
|
165
|
+
# Create expression that removes "count" list items starting at specified rank.
|
166
|
+
def self.remove_by_rank_range(rank, bin, ctx: nil, count: nil)
|
167
|
+
unless count.nil?
|
168
|
+
bytes = Exp.pack(ctx, REMOVE_BY_RANK_RANGE, CDT::ListReturnType::NONE, rank, count)
|
169
|
+
else
|
170
|
+
bytes = Exp.pack(ctx, REMOVE_BY_RANK_RANGE, CDT::ListReturnType::NONE, rank)
|
171
|
+
end
|
172
|
+
self.add_write(bin, bytes, ctx)
|
173
|
+
end
|
174
|
+
|
175
|
+
# Create expression that returns list size.
|
176
|
+
#
|
177
|
+
# ==== Examples
|
178
|
+
# # List bin "a" size > 7
|
179
|
+
# Exp.gt(ListExp.size(Exp.listBin("a")), Exp.val(7))
|
180
|
+
# end</pre>
|
181
|
+
def self.size(bin, ctx: nil)
|
182
|
+
bytes = Exp.pack(ctx, SIZE)
|
183
|
+
self.add_read(bin, bytes, Exp::Type::INT)
|
184
|
+
end
|
185
|
+
|
186
|
+
# Create expression that selects list items identified by value and returns selected
|
187
|
+
# data specified by return_type.
|
188
|
+
#
|
189
|
+
# ==== Examples
|
190
|
+
# # List bin "a" contains at least one item == "abc"
|
191
|
+
# Exp.gt(
|
192
|
+
# ListExp.getByValue(CDT::ListReturnType::COUNT, Exp.val("abc"), Exp.listBin("a")),
|
193
|
+
# Exp.val(0))
|
194
|
+
# end</pre>
|
195
|
+
#
|
196
|
+
# @param return_type metadata attributes to return. See {@link CDT::ListReturnTypeend
|
197
|
+
# @param value search expression
|
198
|
+
# @param bin list bin or list value expression
|
199
|
+
# @param ctx optional context path for nested CDT
|
200
|
+
def self.get_by_value(return_type, value, bin, ctx: nil)
|
201
|
+
bytes = Exp.pack(ctx, GET_BY_VALUE, return_type, value)
|
202
|
+
self.add_read(bin, bytes, get_value_type(return_type))
|
203
|
+
end
|
204
|
+
|
205
|
+
# Create expression that selects list items identified by value range and returns selected data
|
206
|
+
# specified by return_type.
|
207
|
+
#
|
208
|
+
# ==== Examples
|
209
|
+
# # List bin "a" items >= 10 && items < 20
|
210
|
+
# ListExp.getByValueRange(CDT::ListReturnType::VALUE, Exp.val(10), Exp.val(20), Exp.listBin("a"))
|
211
|
+
# end</pre>
|
212
|
+
#
|
213
|
+
# @param return_type metadata attributes to return. See {@link CDT::ListReturnTypeend
|
214
|
+
# @param value_begin begin expression inclusive. If nil, range is less than value_end.
|
215
|
+
# @param value_end end expression exclusive. If nil, range is greater than equal to value_begin.
|
216
|
+
# @param bin bin or list value expression
|
217
|
+
# @param ctx optional context path for nested CDT
|
218
|
+
def self.get_by_value_range(return_type, value_begin, value_end, bin, ctx: nil)
|
219
|
+
bytes = self.pack_range_operation(GET_BY_VALUE_INTERVAL, return_type, value_begin, value_end, ctx)
|
220
|
+
self.add_read(bin, bytes, get_value_type(return_type))
|
221
|
+
end
|
222
|
+
|
223
|
+
# Create expression that selects list items identified by values and returns selected data
|
224
|
+
# specified by return_type.
|
225
|
+
def self.get_by_value_list(return_type, values, bin, ctx: nil)
|
226
|
+
bytes = Exp.pack(ctx, GET_BY_VALUE_LIST, return_type, values)
|
227
|
+
self.add_read(bin, bytes, get_value_type(return_type))
|
228
|
+
end
|
229
|
+
|
230
|
+
# Create expression that selects list items nearest to value and greater by relative rank with a count limit
|
231
|
+
# and returns selected data specified by return_type (See {@link CDT::ListReturnTypeend).
|
232
|
+
#
|
233
|
+
# Examples for ordered list [0,4,5,9,11,15]:
|
234
|
+
#
|
235
|
+
# (value,rank,count) = [selected items]
|
236
|
+
# (5,0,2) = [5,9]
|
237
|
+
# (5,1,1) = [9]
|
238
|
+
# (5,-1,2) = [4,5]
|
239
|
+
# (3,0,1) = [4]
|
240
|
+
# (3,3,7) = [11,15]
|
241
|
+
# (3,-3,2) = []
|
242
|
+
def self.get_by_value_relative_rank_range(return_type, value, rank, bin, ctx: nil, count: nil)
|
243
|
+
unless count.nil?
|
244
|
+
bytes = Exp.pack(ctx, GET_BY_VALUE_REL_RANK_RANGE, return_type, value, rank, count)
|
245
|
+
else
|
246
|
+
bytes = Exp.pack(ctx, GET_BY_VALUE_REL_RANK_RANGE, return_type, value, rank)
|
247
|
+
end
|
248
|
+
self.add_read(bin, bytes, get_value_type(return_type))
|
249
|
+
end
|
250
|
+
|
251
|
+
# Create expression that selects list item identified by index and returns
|
252
|
+
# selected data specified by return_type.
|
253
|
+
#
|
254
|
+
# ==== Examples
|
255
|
+
# # a[3] == 5
|
256
|
+
# Exp.eq(
|
257
|
+
# ListExp.getByIndex(CDT::ListReturnType::VALUE, Exp::Type::INT, Exp.val(3), Exp.listBin("a")),
|
258
|
+
# Exp.val(5))
|
259
|
+
# end</pre>
|
260
|
+
#
|
261
|
+
# @param return_type metadata attributes to return. See {@link CDT::ListReturnTypeend
|
262
|
+
# @param value_type expected type of value
|
263
|
+
# @param index list index expression
|
264
|
+
# @param bin list bin or list value expression
|
265
|
+
# @param ctx optional context path for nested CDT
|
266
|
+
def self.get_by_index(return_type, value_type, index, bin, ctx: nil)
|
267
|
+
bytes = Exp.pack(ctx, GET_BY_INDEX, return_type, index)
|
268
|
+
self.add_read(bin, bytes, value_type)
|
269
|
+
end
|
270
|
+
|
271
|
+
# Create expression that selects list items starting at specified index to the end of list
|
272
|
+
# and returns selected data specified by return_type (See {@link CDT::ListReturnTypeend).
|
273
|
+
def self.get_by_index_range(return_type, index, bin, ctx: nil)
|
274
|
+
bytes = Exp.pack(ctx, GET_BY_INDEX_RANGE, return_type, index)
|
275
|
+
self.add_read(bin, bytes, get_value_type(return_type))
|
276
|
+
end
|
277
|
+
|
278
|
+
# Create expression that selects "count" list items starting at specified index
|
279
|
+
# and returns selected data specified by return_type (See {@link CDT::ListReturnTypeend).
|
280
|
+
def self.get_by_index_range(return_type, index, bin, ctx: nil, count: nil)
|
281
|
+
unless count.nil?
|
282
|
+
bytes = Exp.pack(ctx, GET_BY_INDEX_RANGE, return_type, index, count)
|
283
|
+
else
|
284
|
+
bytes = Exp.pack(ctx, GET_BY_INDEX_RANGE, return_type, index)
|
285
|
+
end
|
286
|
+
self.add_read(bin, bytes, get_value_type(return_type))
|
287
|
+
end
|
288
|
+
|
289
|
+
# Create expression that selects list item identified by rank and returns selected
|
290
|
+
# data specified by return_type.
|
291
|
+
#
|
292
|
+
# ==== Examples
|
293
|
+
# # Player with lowest score.
|
294
|
+
# ListExp.getByRank(CDT::ListReturnType::VALUE, Type.STRING, Exp.val(0), Exp.listBin("a"))
|
295
|
+
# end</pre>
|
296
|
+
#
|
297
|
+
# @param return_type metadata attributes to return. See {@link CDT::ListReturnTypeend
|
298
|
+
# @param value_type expected type of value
|
299
|
+
# @param rank rank expression
|
300
|
+
# @param bin list bin or list value expression
|
301
|
+
# @param ctx optional context path for nested CDT
|
302
|
+
def self.get_by_rank(return_type, value_type, rank, bin, ctx: nil)
|
303
|
+
bytes = Exp.pack(ctx, GET_BY_RANK, return_type, rank)
|
304
|
+
self.add_read(bin, bytes, value_type)
|
305
|
+
end
|
306
|
+
|
307
|
+
# Create expression that selects list items starting at specified rank to the last ranked item
|
308
|
+
# and returns selected data specified by return_type (See {@link CDT::ListReturnTypeend).
|
309
|
+
def self.get_by_rank_range(return_type, rank, bin, ctx: nil)
|
310
|
+
bytes = Exp.pack(ctx, GET_BY_RANK_RANGE, return_type, rank)
|
311
|
+
self.add_read(bin, bytes, get_value_type(return_type))
|
312
|
+
end
|
313
|
+
|
314
|
+
# Create expression that selects "count" list items starting at specified rank and returns
|
315
|
+
# selected data specified by return_type (See {@link CDT::ListReturnTypeend).
|
316
|
+
def self.get_by_rank_range(return_type, rank, bin, ctx: nil, count: nil)
|
317
|
+
unless count.nil?
|
318
|
+
bytes = Exp.pack(ctx, GET_BY_RANK_RANGE, return_type, rank, count)
|
319
|
+
else
|
320
|
+
bytes = Exp.pack(ctx, GET_BY_RANK_RANGE, return_type, rank)
|
321
|
+
end
|
322
|
+
self.add_read(bin, bytes, get_value_type(return_type))
|
323
|
+
end
|
324
|
+
|
325
|
+
private
|
326
|
+
|
327
|
+
MODULE = 0
|
328
|
+
APPEND = 1
|
329
|
+
APPEND_ITEMS = 2
|
330
|
+
INSERT = 3
|
331
|
+
INSERT_ITEMS = 4
|
332
|
+
SET = 9
|
333
|
+
CLEAR = 11
|
334
|
+
INCREMENT = 12
|
335
|
+
SORT = 13
|
336
|
+
SIZE = 16
|
337
|
+
GET_BY_INDEX = 19
|
338
|
+
GET_BY_RANK = 21
|
339
|
+
GET_BY_VALUE = 22 # GET_ALL_BY_VALUE on server
|
340
|
+
GET_BY_VALUE_LIST = 23
|
341
|
+
GET_BY_INDEX_RANGE = 24
|
342
|
+
GET_BY_VALUE_INTERVAL = 25
|
343
|
+
GET_BY_RANK_RANGE = 26
|
344
|
+
GET_BY_VALUE_REL_RANK_RANGE = 27
|
345
|
+
REMOVE_BY_INDEX = 32
|
346
|
+
REMOVE_BY_RANK = 34
|
347
|
+
REMOVE_BY_VALUE = 35
|
348
|
+
REMOVE_BY_VALUE_LIST = 36
|
349
|
+
REMOVE_BY_INDEX_RANGE = 37
|
350
|
+
REMOVE_BY_VALUE_INTERVAL = 38
|
351
|
+
REMOVE_BY_RANK_RANGE = 39
|
352
|
+
REMOVE_BY_VALUE_REL_RANK_RANGE = 40
|
353
|
+
|
354
|
+
def self.add_write(bin, bytes, ctx)
|
355
|
+
if ctx.to_a.empty?
|
356
|
+
ret_type = Exp::Type::LIST
|
357
|
+
else
|
358
|
+
ret_type = ((ctx[0].id & 0x10) == 0) ? Exp::Type::MAP : Exp::Type::LIST
|
359
|
+
end
|
360
|
+
Exp::Module.new(bin, bytes, ret_type, MODULE | Exp::MODIFY)
|
361
|
+
end
|
362
|
+
|
363
|
+
def self.add_read(bin, bytes, ret_type)
|
364
|
+
Exp::Module.new(bin, bytes, ret_type, MODULE)
|
365
|
+
end
|
366
|
+
|
367
|
+
def self.get_value_type(return_type)
|
368
|
+
if (return_type & ~CDT::ListReturnType::INVERTED) == CDT::ListReturnType::VALUE
|
369
|
+
Exp::Type::LIST
|
370
|
+
else
|
371
|
+
Exp::Type::INT
|
372
|
+
end
|
373
|
+
end
|
374
|
+
|
375
|
+
def self.pack_range_operation(command, return_type, value_begin, value_end, ctx)
|
376
|
+
Packer.use do |packer|
|
377
|
+
Exp.pack_ctx(packer, ctx)
|
378
|
+
packer.write_array_header(value_end.nil? ? 3 : 4)
|
379
|
+
packer.write(command)
|
380
|
+
packer.write(return_type)
|
381
|
+
|
382
|
+
unless value_begin.nil?
|
383
|
+
if value_begin.is_a?(Exp)
|
384
|
+
value_begin.pack(packer)
|
385
|
+
else
|
386
|
+
Value.of(value_begin).pack(packer)
|
387
|
+
end
|
388
|
+
else
|
389
|
+
packer.write(nil)
|
390
|
+
end
|
391
|
+
|
392
|
+
unless value_end.nil?
|
393
|
+
if value_end.is_a?(Exp)
|
394
|
+
value_end.pack(packer)
|
395
|
+
else
|
396
|
+
Value.of(value_end).pack(packer)
|
397
|
+
end
|
398
|
+
end
|
399
|
+
packer.bytes
|
400
|
+
end
|
401
|
+
end
|
402
|
+
end # class Exp::List
|
403
|
+
end # module
|