diff --git a/lib/net/imap/response_parser.rb b/lib/net/imap/response_parser.rb index fe6badc8..34aa8ea0 100644 --- a/lib/net/imap/response_parser.rb +++ b/lib/net/imap/response_parser.rb @@ -62,6 +62,10 @@ def parse(str) T_TEXT = :TEXT # any char except CRLF T_EOF = :EOF # end of response string + # Use to avoid allocation when we know the result is empty + EMPTY_ARRAY = [].freeze + private_constant :EMPTY_ARRAY + module ResponseConditions OK = "OK" NO = "NO" @@ -596,7 +600,7 @@ def tagged_ext_simple # "(" [tagged-ext-comp] ")" def tagged_ext_val if lpar? - _ = peek_rpar? ? [] : tagged_ext_comp + _ = peek_rpar? ? EMPTY_ARRAY : tagged_ext_comp rpar _ else @@ -1367,7 +1371,7 @@ def mailbox_data__list # ; This is the list information pointed to by the ABNF # ; item "mailbox-data", which is defined above def mailbox_list - lpar; attr = peek_rpar? ? [] : mbx_list_flags; rpar + lpar; attr = peek_rpar? ? EMPTY_ARRAY : mbx_list_flags; rpar SP!; delim = nquoted SP!; name = mailbox # TODO: mbox-list-extended @@ -1467,8 +1471,12 @@ def acl_data # obsolete-search-response = "SEARCH" *(SP nz-number) def mailbox_data__search name = label_in("SEARCH", "SORT") - data = [] - while _ = SP? && nz_number? do data << _ end + if (_ = SP? && nz_number?) + data = [_] + while _ = SP? && nz_number? do data << _ end + else + data = EMPTY_ARRAY + end if lpar? label("MODSEQ"); SP! modseq = mod_sequence_value @@ -1517,7 +1525,7 @@ def thread_members else nested = thread_nested; break end end - members.reverse.inject(nested || []) {|subthreads, number| + members.reverse.inject(nested || EMPTY_ARRAY) {|subthreads, number| [ThreadMember.new(number, subthreads)] }.first end @@ -1689,7 +1697,7 @@ def namespace_response # namespace = nil / "(" 1*namespace-descr ")" def namespace - NIL? and return [] + NIL? and return EMPTY_ARRAY lpar list = [namespace_descr] list << namespace_descr until rpar? @@ -1816,13 +1824,13 @@ def resp_text_code data = case name when "CAPABILITY" then resp_code__capability - when "PERMANENTFLAGS" then SP? ? flag_perm__list : [] + when "PERMANENTFLAGS" then SP? ? flag_perm__list : EMPTY_ARRAY when "UIDNEXT" then SP!; nz_number when "UIDVALIDITY" then SP!; nz_number when "UNSEEN" then SP!; nz_number # rev1 only when "APPENDUID" then SP!; resp_code_apnd__data # rev2, UIDPLUS when "COPYUID" then SP!; resp_code_copy__data # rev2, UIDPLUS - when "BADCHARSET" then SP? ? charset__list : [] + when "BADCHARSET" then SP? ? charset__list : EMPTY_ARRAY when "ALERT", "PARSE", "READ-ONLY", "READ-WRITE", "TRYCREATE", "UNAVAILABLE", "AUTHENTICATIONFAILED", "AUTHORIZATIONFAILED", "EXPIRED", "PRIVACYREQUIRED", "CONTACTADMIN", "NOPERM", "INUSE", @@ -1953,7 +1961,7 @@ def x_gm_label; accept(T_BSLASH) ? atom.capitalize.to_sym : astring end # See https://developers.google.com/gmail/imap/imap-extensions def x_gm_labels - lpar; return [] if rpar? + lpar; return EMPTY_ARRAY if rpar? labels = [] labels << x_gm_label labels << x_gm_label while SP?