001/*
002 * CDDL HEADER START
003 *
004 * The contents of this file are subject to the terms of the
005 * Common Development and Distribution License, Version 1.0 only
006 * (the "License").  You may not use this file except in compliance
007 * with the License.
008 *
009 * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt
010 * or http://forgerock.org/license/CDDLv1.0.html.
011 * See the License for the specific language governing permissions
012 * and limitations under the License.
013 *
014 * When distributing Covered Code, include this CDDL HEADER in each
015 * file and include the License file at legal-notices/CDDLv1_0.txt.
016 * If applicable, add the following below this CDDL HEADER, with the
017 * fields enclosed by brackets "[]" replaced with your own identifying
018 * information:
019 *      Portions Copyright [yyyy] [name of copyright owner]
020 *
021 * CDDL HEADER END
022 *
023 *
024 *      Copyright 2009 Sun Microsystems, Inc.
025 *      Portions copyright 2011-2015 ForgeRock AS
026 */
027package org.forgerock.opendj.ldap;
028
029import java.io.IOException;
030import java.io.OutputStream;
031import java.nio.BufferOverflowException;
032import java.nio.ByteBuffer;
033import java.nio.CharBuffer;
034import java.nio.charset.CharsetDecoder;
035import java.util.Comparator;
036
037/**
038 * A {@code ByteSequence} is a readable sequence of byte values. This interface
039 * provides uniform, read-only access to many different kinds of byte sequences.
040 */
041public interface ByteSequence extends Comparable<ByteSequence> {
042
043    /** A byte array comparator. */
044    Comparator<byte[]> BYTE_ARRAY_COMPARATOR = new Comparator<byte[]>() {
045        @Override
046        public int compare(final byte[] b1, final byte[] b2) {
047            return ByteString.compareTo(b1, 0, b1.length, b2, 0, b2.length);
048        }
049    };
050
051    /** A ByteSequence comparator. */
052    Comparator<ByteSequence> COMPARATOR = new Comparator<ByteSequence>() {
053        @Override
054        public int compare(final ByteSequence o1, final ByteSequence o2) {
055            return o1.compareTo(o2);
056        }
057    };
058
059    /**
060     * Returns a {@link ByteSequenceReader} which can be used to incrementally
061     * read and decode data from this byte sequence.
062     * <p>
063     * <b>NOTE:</b> any concurrent changes to the underlying byte sequence (if
064     * mutable) may cause subsequent reads to overrun and fail.
065     *
066     * @return The {@link ByteSequenceReader} which can be used to incrementally
067     *         read and decode data from this byte sequence.
068     */
069    ByteSequenceReader asReader();
070
071    /**
072     * Returns the byte value at the specified index.
073     * <p>
074     * An index ranges from zero to {@code length() - 1}. The first byte value
075     * of the sequence is at index zero, the next at index one, and so on, as
076     * for array indexing.
077     *
078     * @param index
079     *            The index of the byte to be returned.
080     * @return The byte value at the specified index.
081     * @throws IndexOutOfBoundsException
082     *             If the index argument is negative or not less than length().
083     */
084    byte byteAt(int index);
085
086    /**
087     * Compares this byte sequence with the specified byte array sub-sequence
088     * for order. Returns a negative integer, zero, or a positive integer
089     * depending on whether this byte sequence is less than, equal to, or
090     * greater than the specified byte array sub-sequence.
091     *
092     * @param bytes
093     *            The byte array to compare.
094     * @param offset
095     *            The offset of the sub-sequence in the byte array to be
096     *            compared; must be non-negative and no larger than
097     *            {@code bytes.length} .
098     * @param length
099     *            The length of the sub-sequence in the byte array to be
100     *            compared; must be non-negative and no larger than
101     *            {@code bytes.length - offset}.
102     * @return A negative integer, zero, or a positive integer depending on
103     *         whether this byte sequence is less than, equal to, or greater
104     *         than the specified byte array sub-sequence.
105     * @throws IndexOutOfBoundsException
106     *             If {@code offset} is negative or if {@code length} is
107     *             negative or if {@code offset + length} is greater than
108     *             {@code bytes.length}.
109     */
110    int compareTo(byte[] bytes, int offset, int length);
111
112    /**
113     * Compares this byte sequence with the specified byte sequence for order.
114     * Returns a negative integer, zero, or a positive integer depending on
115     * whether this byte sequence is less than, equal to, or greater than the
116     * specified object.
117     *
118     * @param o
119     *            The byte sequence to be compared.
120     * @return A negative integer, zero, or a positive integer depending on
121     *         whether this byte sequence is less than, equal to, or greater
122     *         than the specified object.
123     */
124    @Override
125    int compareTo(ByteSequence o);
126
127    /**
128     * Copies the contents of this byte sequence to the provided byte array.
129     * <p>
130     * Copying will stop when either the entire content of this sequence has
131     * been copied or if the end of the provided byte array has been reached.
132     * <p>
133     * An invocation of the form:
134     *
135     * <pre>
136     * src.copyTo(bytes)
137     * </pre>
138     *
139     * Behaves in exactly the same way as the invocation:
140     *
141     * <pre>
142     * src.copyTo(bytes, 0);
143     * </pre>
144     *
145     * @param bytes
146     *            The byte array to which bytes are to be copied.
147     * @return The byte array.
148     */
149    byte[] copyTo(byte[] bytes);
150
151    /**
152     * Copies the contents of this byte sequence to the specified location in
153     * the provided byte array.
154     * <p>
155     * Copying will stop when either the entire content of this sequence has
156     * been copied or if the end of the provided byte array has been reached.
157     * <p>
158     * An invocation of the form:
159     *
160     * <pre>
161     * src.copyTo(bytes, offset)
162     * </pre>
163     *
164     * Behaves in exactly the same way as the invocation:
165     *
166     * <pre>
167     * int len = Math.min(src.length(), bytes.length - offset);
168     * for (int i = 0; i &lt; len; i++)
169     *     bytes[offset + i] = src.get(i);
170     * </pre>
171     *
172     * Except that it is potentially much more efficient.
173     *
174     * @param bytes
175     *            The byte array to which bytes are to be copied.
176     * @param offset
177     *            The offset within the array of the first byte to be written;
178     *            must be non-negative and no larger than bytes.length.
179     * @return The byte array.
180     * @throws IndexOutOfBoundsException
181     *             If {@code offset} is negative.
182     */
183    byte[] copyTo(byte[] bytes, int offset);
184
185    /**
186     * Appends the entire contents of this byte sequence to the provided
187     * {@link ByteStringBuilder}.
188     *
189     * @param builder
190     *            The builder to copy to.
191     * @return The builder.
192     */
193    ByteStringBuilder copyTo(ByteStringBuilder builder);
194
195    /**
196     * Appends the content of this byte sequence to the provided {@link ByteBuffer}.
197     *
198     * @param buffer
199     *            The buffer to copy to.
200     *            It must be large enough to receive all bytes.
201     * @return The buffer.
202     * @throws BufferOverflowException
203     *            If there is insufficient space in the provided buffer
204     */
205    ByteBuffer copyTo(ByteBuffer buffer);
206
207    /**
208     * Appends the content of this byte sequence decoded using provided charset decoder,
209     * to the provided {@link CharBuffer}.
210     *
211     * @param charBuffer
212     *            The buffer to copy to, if decoding is successful.
213     *            It must be large enough to receive all decoded characters.
214     * @param decoder
215     *            The charset decoder to use for decoding.
216     * @return {@code true} if byte string was successfully decoded and charBuffer is
217     *         large enough to receive the resulting string, {@code false} otherwise
218     */
219    boolean copyTo(CharBuffer charBuffer, CharsetDecoder decoder);
220
221    /**
222     * Copies the entire contents of this byte sequence to the provided
223     * {@code OutputStream}.
224     *
225     * @param stream
226     *            The {@code OutputStream} to copy to.
227     * @return The {@code OutputStream}.
228     * @throws IOException
229     *             If an error occurs while writing to the {@code OutputStream}.
230     */
231    OutputStream copyTo(OutputStream stream) throws IOException;
232
233    /**
234     * Indicates whether the provided byte array sub-sequence is equal to this
235     * byte sequence. In order for it to be considered equal, the provided byte
236     * array sub-sequence must contain the same bytes in the same order.
237     *
238     * @param bytes
239     *            The byte array for which to make the determination.
240     * @param offset
241     *            The offset of the sub-sequence in the byte array to be
242     *            compared; must be non-negative and no larger than
243     *            {@code bytes.length} .
244     * @param length
245     *            The length of the sub-sequence in the byte array to be
246     *            compared; must be non-negative and no larger than
247     *            {@code bytes.length - offset}.
248     * @return {@code true} if the content of the provided byte array
249     *         sub-sequence is equal to that of this byte sequence, or
250     *         {@code false} if not.
251     * @throws IndexOutOfBoundsException
252     *             If {@code offset} is negative or if {@code length} is
253     *             negative or if {@code offset + length} is greater than
254     *             {@code bytes.length}.
255     */
256    boolean equals(byte[] bytes, int offset, int length);
257
258    /**
259     * Indicates whether the provided object is equal to this byte sequence. In
260     * order for it to be considered equal, the provided object must be a byte
261     * sequence containing the same bytes in the same order.
262     *
263     * @param o
264     *            The object for which to make the determination.
265     * @return {@code true} if the provided object is a byte sequence whose
266     *         content is equal to that of this byte sequence, or {@code false}
267     *         if not.
268     */
269    @Override
270    boolean equals(Object o);
271
272    /**
273     * Returns a hash code for this byte sequence. It will be the sum of all of
274     * the bytes contained in the byte sequence.
275     *
276     * @return A hash code for this byte sequence.
277     */
278    @Override
279    int hashCode();
280
281    /**
282     * Returns {@code true} if this byte sequence has a length of zero.
283     *
284     * @return {@code true} if this byte sequence has a length of zero.
285     */
286    boolean isEmpty();
287
288    /**
289     * Returns the length of this byte sequence.
290     *
291     * @return The length of this byte sequence.
292     */
293    int length();
294
295    /**
296     * Returns a new byte sequence that is a subsequence of this byte sequence.
297     * <p>
298     * The subsequence starts with the byte value at the specified {@code start}
299     * index and ends with the byte value at index {@code end - 1}. The length
300     * (in bytes) of the returned sequence is {@code end - start}, so if
301     * {@code start
302     * == end} then an empty sequence is returned.
303     * <p>
304     * <b>NOTE:</b> changes to the underlying byte sequence (if mutable) may
305     * render the returned sub-sequence invalid.
306     *
307     * @param start
308     *            The start index, inclusive.
309     * @param end
310     *            The end index, exclusive.
311     * @return The newly created byte subsequence.
312     * @throws IndexOutOfBoundsException
313     *             If {@code start} or {@code end} are negative, if {@code end}
314     *             is greater than {@code length()}, or if {@code start} is
315     *             greater than {@code end}.
316     */
317    ByteSequence subSequence(int start, int end);
318
319    /**
320     * Tests if this ByteSequence starts with the specified prefix.
321     *
322     * @param prefix
323     *            The prefix.
324     * @return true if the byte sequence represented by the argument is a prefix of the byte sequence represented by
325     *         this ByteSequence; false otherwise. Note also that true will be returned if the argument is an empty
326     *         sequence or is equal to this ByteSequence object as determined by the equals(Object) method.
327     */
328    boolean startsWith(ByteSequence prefix);
329
330    /**
331     * Returns the Base64 encoded string representation of this byte string.
332     *
333     * @return The Base64 encoded string representation of this byte string.
334     * @see ByteString#valueOfBase64(String)
335     */
336    String toBase64String();
337
338    /**
339     * Returns a byte array containing the bytes in this sequence in the same
340     * order as this sequence. The length of the byte array will be the length
341     * of this sequence.
342     * <p>
343     * An invocation of the form:
344     *
345     * <pre>
346     * src.toByteArray()
347     * </pre>
348     *
349     * Behaves in exactly the same way as the invocation:
350     *
351     * <pre>
352     * src.copyTo(new byte[src.length()]);
353     * </pre>
354     *
355     * @return A byte array consisting of exactly this sequence of bytes.
356     */
357    byte[] toByteArray();
358
359    /**
360     * Returns the {@link ByteString} representation of this byte sequence.
361     *
362     * @return The {@link ByteString} representation of this byte sequence.
363     */
364    ByteString toByteString();
365
366    /**
367     * Returns the UTF-8 decoded string representation of this byte sequence. If
368     * UTF-8 decoding fails, the platform's default encoding will be used.
369     *
370     * @return The string representation of this byte sequence.
371     */
372    @Override
373    String toString();
374}