@@ -267,6 +267,56 @@ module RFC3629
267
267
# ; Is a valid RFC 3501 "atom".
268
268
TAGGED_EXT_LABEL = /#{ TAGGED_LABEL_FCHAR } #{ TAGGED_LABEL_CHAR } */n
269
269
270
+ # nz-number = digit-nz *DIGIT
271
+ # ; Non-zero unsigned 32-bit integer
272
+ # ; (0 < n < 4,294,967,296)
273
+ NZ_NUMBER = /[1-9]\d */n
274
+
275
+ # seq-number = nz-number / "*"
276
+ # ; message sequence number (COPY, FETCH, STORE
277
+ # ; commands) or unique identifier (UID COPY,
278
+ # ; UID FETCH, UID STORE commands).
279
+ # ; * represents the largest number in use. In
280
+ # ; the case of message sequence numbers, it is
281
+ # ; the number of messages in a non-empty mailbox.
282
+ # ; In the case of unique identifiers, it is the
283
+ # ; unique identifier of the last message in the
284
+ # ; mailbox or, if the mailbox is empty, the
285
+ # ; mailbox's current UIDNEXT value.
286
+ # ; The server should respond with a tagged BAD
287
+ # ; response to a command that uses a message
288
+ # ; sequence number greater than the number of
289
+ # ; messages in the selected mailbox. This
290
+ # ; includes "*" if the selected mailbox is empty.
291
+ SEQ_NUMBER = /#{ NZ_NUMBER } |\* /n
292
+
293
+ # seq-range = seq-number ":" seq-number
294
+ # ; two seq-number values and all values between
295
+ # ; these two regardless of order.
296
+ # ; Example: 2:4 and 4:2 are equivalent and
297
+ # ; indicate values 2, 3, and 4.
298
+ # ; Example: a unique identifier sequence range of
299
+ # ; 3291:* includes the UID of the last message in
300
+ # ; the mailbox, even if that value is less than
301
+ # ; 3291.
302
+ SEQ_RANGE = /#{ SEQ_NUMBER } :#{ SEQ_NUMBER } /n
303
+
304
+ # sequence-set = (seq-number / seq-range) ["," sequence-set]
305
+ # ; set of seq-number values, regardless of order.
306
+ # ; Servers MAY coalesce overlaps and/or execute
307
+ # ; the sequence in any order.
308
+ # ; Example: a message sequence number set of
309
+ # ; 2,4:7,9,12:* for a mailbox with 15 messages is
310
+ # ; equivalent to 2,4,5,6,7,9,12,13,14,15
311
+ # ; Example: a message sequence number set of
312
+ # ; *:4,5:7 for a mailbox with 10 messages is
313
+ # ; equivalent to 10,9,8,7,6,5,4,5,6,7 and MAY
314
+ # ; be reordered and overlap coalesced to be
315
+ # ; 4,5,6,7,8,9,10.
316
+ SEQUENCE_SET_ITEM = /#{ SEQ_NUMBER } |#{ SEQ_RANGE } /n
317
+ SEQUENCE_SET = /#{ SEQUENCE_SET_ITEM } (?:,#{ SEQUENCE_SET_ITEM } )*/n
318
+ SEQUENCE_SET_STR = /\A #{ SEQUENCE_SET } \z /n
319
+
270
320
# RFC3501:
271
321
# literal = "{" number "}" CRLF *CHAR8
272
322
# ; Number represents the number of CHAR8s
@@ -405,6 +455,24 @@ def unescape_quoted(quoted)
405
455
# ATOM-CHAR = <any CHAR except atom-specials>
406
456
ATOM_TOKENS = [ T_ATOM , T_NUMBER , T_NIL , T_LBRA , T_PLUS ]
407
457
458
+ SEQUENCE_SET_TOKENS = [ T_ATOM , T_NUMBER , T_STAR ]
459
+
460
+ # sequence-set = (seq-number / seq-range) ["," sequence-set]
461
+ # sequence-set =/ seq-last-command
462
+ # ; Allow for "result of the last command"
463
+ # ; indicator.
464
+ # seq-last-command = "$"
465
+ #
466
+ # *note*: doesn't match seq-last-command
467
+ def sequence_set
468
+ str = combine_adjacent ( *SEQUENCE_SET_TOKENS )
469
+ if Patterns ::SEQUENCE_SET_STR . match? ( str )
470
+ SequenceSet . new ( str )
471
+ else
472
+ parse_error ( "unexpected atom %p, expected sequence-set" , str )
473
+ end
474
+ end
475
+
408
476
# ASTRING-CHAR = ATOM-CHAR / resp-specials
409
477
# resp-specials = "]"
410
478
ASTRING_CHARS_TOKENS = [ *ATOM_TOKENS , T_RBRA ] . freeze
0 commit comments