Skip to contentPackage: UIDSet
UIDSet
Coverage
1: /*
2: * Copyright (c) 1997, 2023 Oracle and/or its affiliates. All rights reserved.
3: *
4: * This program and the accompanying materials are made available under the
5: * terms of the Eclipse Public License v. 2.0, which is available at
6: * http://www.eclipse.org/legal/epl-2.0.
7: *
8: * This Source Code may also be made available under the following Secondary
9: * Licenses when the conditions for such availability set forth in the
10: * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
11: * version 2 with the GNU Classpath Exception, which is available at
12: * https://www.gnu.org/software/classpath/license.html.
13: *
14: * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
15: */
16:
17: package org.eclipse.angus.mail.imap.protocol;
18:
19: import java.util.List;
20: import java.util.ArrayList;
21: import java.util.StringTokenizer;
22:
23: /**
24: * This class holds the 'start' and 'end' for a range of UIDs.
25: * Just like MessageSet except using long instead of int.
26: */
27: public class UIDSet {
28:
29: public long start;
30: public long end;
31:
32: public UIDSet() { }
33:
34: public UIDSet(long start, long end) {
35:         this.start = start;
36:         this.end = end;
37: }
38:
39: /**
40: * Count the total number of elements in a UIDSet
41: *
42: * @return        the number of elements
43: */
44: public long size() {
45:         return end - start + 1;
46: }
47:
48: /**
49: * Convert an array of longs into an array of UIDSets
50: *
51: * @param        uids        the UIDs
52: * @return                array of UIDSet objects
53: */
54: public static UIDSet[] createUIDSets(long[] uids) {
55:•        if (uids == null)
56:          return null;
57:         List<UIDSet> v = new ArrayList<>();
58:         int i,j;
59:
60:•        for (i=0; i < uids.length; i++) {
61:          UIDSet ms = new UIDSet();
62:          ms.start = uids[i];
63:
64:          // Look for contiguous elements
65:•         for (j=i+1; j < uids.length; j++) {
66:•                if (uids[j] != uids[j-1] +1)
67:                  break;
68:          }
69:          ms.end = uids[j-1];
70:          v.add(ms);
71:          i = j-1; // i gets incremented @ top of the loop
72:         }
73:         UIDSet[] uidset = new UIDSet[v.size()];        
74:         return v.toArray(uidset);
75: }
76:
77: /**
78: * Parse a string in IMAP UID range format.
79: *
80: * @param        uids        UID string
81: * @return                array of UIDSet objects
82: * @since        JavaMail 1.5.1
83: */
84: public static UIDSet[] parseUIDSets(String uids) {
85:•        if (uids == null)
86:          return null;
87:         List<UIDSet> v = new ArrayList<>();
88:         StringTokenizer st = new StringTokenizer(uids, ",:", true);
89:         UIDSet cur = null;
90:         try {
91:•         while(st.hasMoreTokens()) {
92:                 String s = st.nextToken();
93:•                if (s.equals(",")) {
94:•                 if (cur != null)
95:                         v.add(cur);
96:                  cur = null;
97:•                } else if (s.equals(":")) {
98:                  // nothing to do, wait for next number
99:                 } else {        // better be a number
100:                  long n = Long.parseLong(s);
101:•                 if (cur != null)
102:                         cur.end = n;
103:                  else
104:                         cur = new UIDSet(n, n);
105:                 }
106:          }
107:         } catch (NumberFormatException nex) {
108:          // give up and return what we have so far
109:         }
110:•        if (cur != null)
111:          v.add(cur);
112:         UIDSet[] uidset = new UIDSet[v.size()];
113:         return v.toArray(uidset);
114: }
115:
116: /**
117: * Convert an array of UIDSets into an IMAP sequence range.
118: *
119: * @param        uidset        the UIDSets
120: * @return                the IMAP sequence string
121: */
122: public static String toString(UIDSet[] uidset) {
123:•        if (uidset == null)
124:          return null;
125:•        if (uidset.length == 0) // Empty uidset
126:          return "";
127:
128:         int i = 0; // uidset index
129:         StringBuilder s = new StringBuilder();
130:         int size = uidset.length;
131:         long start, end;
132:
133:         for (;;) {
134:          start = uidset[i].start;
135:          end = uidset[i].end;
136:
137:•         if (end > start)
138:                 s.append(start).append(':').append(end);
139:          else // end == start means only one element
140:                 s.append(start);
141:         
142:          i++; // Next UIDSet
143:•         if (i >= size) // No more UIDSets
144:                 break;
145:          else
146:                 s.append(',');
147:         }
148:         return s.toString();
149: }
150:
151: /**
152: * Convert an array of UIDSets into a array of long UIDs.
153: *
154: * @param        uidset        the UIDSets
155: * @return                arrray of UIDs
156: * @since        JavaMail 1.5.1
157: */
158: public static long[] toArray(UIDSet[] uidset) {
159:         //return toArray(uidset, -1);
160:•        if (uidset == null)
161:          return null;
162:         long[] uids = new long[(int)UIDSet.size(uidset)];
163:         int i = 0;
164:•        for (UIDSet u : uidset) {
165:•         for (long n = u.start; n <= u.end; n++)
166:                 uids[i++] = n;
167:         }
168:         return uids;
169: }
170:
171: /**
172: * Convert an array of UIDSets into a array of long UIDs.
173: * Don't include any UIDs larger than uidmax.
174: *
175: * @param        uidset        the UIDSets
176: * @param        uidmax        maximum UID
177: * @return                arrray of UIDs
178: * @since        JavaMail 1.5.1
179: */
180: public static long[] toArray(UIDSet[] uidset, long uidmax) {
181:•        if (uidset == null)
182:          return null;
183:         long[] uids = new long[(int)UIDSet.size(uidset, uidmax)];
184:         int i = 0;
185:•        for (UIDSet u : uidset) {
186:•         for (long n = u.start; n <= u.end; n++) {
187:•                if (uidmax >= 0 && n > uidmax)
188:                  break;
189:                 uids[i++] = n;
190:          }
191:         }
192:         return uids;
193: }
194:
195: /**
196: * Count the total number of elements in an array of UIDSets.
197: *
198: * @param        uidset        the UIDSets
199: * @return                the number of elements
200: */
201: public static long size(UIDSet[] uidset) {
202:         long count = 0;
203:
204:•        if (uidset != null)
205:•         for (UIDSet u : uidset)
206:                 count += u.size();
207:         
208:         return count;
209: }
210:
211: /**
212: * Count the total number of elements in an array of UIDSets.
213: * Don't count UIDs greater then uidmax.
214: *
215: * @since        JavaMail 1.5.1
216: */
217: private static long size(UIDSet[] uidset, long uidmax) {
218:         long count = 0;
219:
220:•        if (uidset != null)
221:•         for (UIDSet u : uidset) {
222:•                if (uidmax < 0)
223:                  count += u.size();
224:•                else if (u.start <= uidmax) {
225:•                 if (u.end < uidmax)
226:                         count += u.end - u.start + 1;
227:                  else
228:                         count += uidmax - u.start + 1;
229:                 }
230:          }
231:         
232:         return count;
233: }
234: }