org.eclipse.angus.mail.imap.protocol.UIDSet Maven / Gradle / Ivy
/*
* Copyright (c) 1997, 2023 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the
* Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
* version 2 with the GNU Classpath Exception, which is available at
* https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
*/
package org.eclipse.angus.mail.imap.protocol;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
/**
* This class holds the 'start' and 'end' for a range of UIDs.
* Just like MessageSet except using long instead of int.
*/
public class UIDSet {
public long start;
public long end;
public UIDSet() {
}
public UIDSet(long start, long end) {
this.start = start;
this.end = end;
}
/**
* Count the total number of elements in a UIDSet
*
* @return the number of elements
*/
public long size() {
return end - start + 1;
}
/**
* Convert an array of longs into an array of UIDSets
*
* @param uids the UIDs
* @return array of UIDSet objects
*/
public static UIDSet[] createUIDSets(long[] uids) {
if (uids == null)
return null;
List v = new ArrayList<>();
int i, j;
for (i = 0; i < uids.length; i++) {
UIDSet ms = new UIDSet();
ms.start = uids[i];
// Look for contiguous elements
for (j = i + 1; j < uids.length; j++) {
if (uids[j] != uids[j - 1] + 1)
break;
}
ms.end = uids[j - 1];
v.add(ms);
i = j - 1; // i gets incremented @ top of the loop
}
UIDSet[] uidset = new UIDSet[v.size()];
return v.toArray(uidset);
}
/**
* Parse a string in IMAP UID range format.
*
* @param uids UID string
* @return array of UIDSet objects
* @since JavaMail 1.5.1
*/
public static UIDSet[] parseUIDSets(String uids) {
if (uids == null)
return null;
List v = new ArrayList<>();
StringTokenizer st = new StringTokenizer(uids, ",:", true);
UIDSet cur = null;
try {
while (st.hasMoreTokens()) {
String s = st.nextToken();
if (s.equals(",")) {
if (cur != null)
v.add(cur);
cur = null;
} else if (s.equals(":")) {
// nothing to do, wait for next number
} else { // better be a number
long n = Long.parseLong(s);
if (cur != null)
cur.end = n;
else
cur = new UIDSet(n, n);
}
}
} catch (NumberFormatException nex) {
// give up and return what we have so far
}
if (cur != null)
v.add(cur);
UIDSet[] uidset = new UIDSet[v.size()];
return v.toArray(uidset);
}
/**
* Convert an array of UIDSets into an IMAP sequence range.
*
* @param uidset the UIDSets
* @return the IMAP sequence string
*/
public static String toString(UIDSet[] uidset) {
if (uidset == null)
return null;
if (uidset.length == 0) // Empty uidset
return "";
int i = 0; // uidset index
StringBuilder s = new StringBuilder();
int size = uidset.length;
long start, end;
for (; ; ) {
start = uidset[i].start;
end = uidset[i].end;
if (end > start)
s.append(start).append(':').append(end);
else // end == start means only one element
s.append(start);
i++; // Next UIDSet
if (i >= size) // No more UIDSets
break;
else
s.append(',');
}
return s.toString();
}
/**
* Convert an array of UIDSets into a array of long UIDs.
*
* @param uidset the UIDSets
* @return arrray of UIDs
* @since JavaMail 1.5.1
*/
public static long[] toArray(UIDSet[] uidset) {
//return toArray(uidset, -1);
if (uidset == null)
return null;
long[] uids = new long[(int) UIDSet.size(uidset)];
int i = 0;
for (UIDSet u : uidset) {
for (long n = u.start; n <= u.end; n++)
uids[i++] = n;
}
return uids;
}
/**
* Convert an array of UIDSets into a array of long UIDs.
* Don't include any UIDs larger than uidmax.
*
* @param uidset the UIDSets
* @param uidmax maximum UID
* @return arrray of UIDs
* @since JavaMail 1.5.1
*/
public static long[] toArray(UIDSet[] uidset, long uidmax) {
if (uidset == null)
return null;
long[] uids = new long[(int) UIDSet.size(uidset, uidmax)];
int i = 0;
for (UIDSet u : uidset) {
for (long n = u.start; n <= u.end; n++) {
if (uidmax >= 0 && n > uidmax)
break;
uids[i++] = n;
}
}
return uids;
}
/**
* Count the total number of elements in an array of UIDSets.
*
* @param uidset the UIDSets
* @return the number of elements
*/
public static long size(UIDSet[] uidset) {
long count = 0;
if (uidset != null)
for (UIDSet u : uidset)
count += u.size();
return count;
}
/**
* Count the total number of elements in an array of UIDSets.
* Don't count UIDs greater then uidmax.
*
* @since JavaMail 1.5.1
*/
private static long size(UIDSet[] uidset, long uidmax) {
long count = 0;
if (uidset != null)
for (UIDSet u : uidset) {
if (uidmax < 0)
count += u.size();
else if (u.start <= uidmax) {
if (u.end < uidmax)
count += u.end - u.start + 1;
else
count += uidmax - u.start + 1;
}
}
return count;
}
}