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} starting at it's current position.
197     * The position of the buffer is then incremented by the length of this sequence.
198     *
199     * @param buffer
200     *            The buffer to copy to.
201     *            It must be large enough to receive all bytes.
202     * @return The buffer.
203     * @throws BufferOverflowException
204     *            If there is insufficient space in the provided buffer
205     */
206    ByteBuffer copyTo(ByteBuffer buffer);
207
208    /**
209     * Appends the content of this byte sequence decoded using provided charset decoder to the provided
210     * {@link CharBuffer} starting at it's current position. The position of charBuffer is then incremented by the
211     * length of this sequence.
212     *
213     * @param charBuffer
214     *            The buffer to copy to, if decoding is successful.
215     *            It must be large enough to receive all decoded characters.
216     * @param decoder
217     *            The charset decoder to use for decoding.
218     * @return {@code true} if byte string was successfully decoded and charBuffer is
219     *         large enough to receive the resulting string, {@code false} otherwise
220     */
221    boolean copyTo(CharBuffer charBuffer, CharsetDecoder decoder);
222
223    /**
224     * Copies the entire contents of this byte sequence to the provided
225     * {@code OutputStream}.
226     *
227     * @param stream
228     *            The {@code OutputStream} to copy to.
229     * @return The {@code OutputStream}.
230     * @throws IOException
231     *             If an error occurs while writing to the {@code OutputStream}.
232     */
233    OutputStream copyTo(OutputStream stream) throws IOException;
234
235    /**
236     * Indicates whether the provided byte array sub-sequence is equal to this
237     * byte sequence. In order for it to be considered equal, the provided byte
238     * array sub-sequence must contain the same bytes in the same order.
239     *
240     * @param bytes
241     *            The byte array for which to make the determination.
242     * @param offset
243     *            The offset of the sub-sequence in the byte array to be
244     *            compared; must be non-negative and no larger than
245     *            {@code bytes.length} .
246     * @param length
247     *            The length of the sub-sequence in the byte array to be
248     *            compared; must be non-negative and no larger than
249     *            {@code bytes.length - offset}.
250     * @return {@code true} if the content of the provided byte array
251     *         sub-sequence is equal to that of this byte sequence, or
252     *         {@code false} if not.
253     * @throws IndexOutOfBoundsException
254     *             If {@code offset} is negative or if {@code length} is
255     *             negative or if {@code offset + length} is greater than
256     *             {@code bytes.length}.
257     */
258    boolean equals(byte[] bytes, int offset, int length);
259
260    /**
261     * Indicates whether the provided object is equal to this byte sequence. In
262     * order for it to be considered equal, the provided object must be a byte
263     * sequence containing the same bytes in the same order.
264     *
265     * @param o
266     *            The object for which to make the determination.
267     * @return {@code true} if the provided object is a byte sequence whose
268     *         content is equal to that of this byte sequence, or {@code false}
269     *         if not.
270     */
271    @Override
272    boolean equals(Object o);
273
274    /**
275     * Returns a hash code for this byte sequence. It will be the sum of all of
276     * the bytes contained in the byte sequence.
277     *
278     * @return A hash code for this byte sequence.
279     */
280    @Override
281    int hashCode();
282
283    /**
284     * Returns {@code true} if this byte sequence has a length of zero.
285     *
286     * @return {@code true} if this byte sequence has a length of zero.
287     */
288    boolean isEmpty();
289
290    /**
291     * Returns the length of this byte sequence.
292     *
293     * @return The length of this byte sequence.
294     */
295    int length();
296
297    /**
298     * Returns a new byte sequence that is a subsequence of this byte sequence.
299     * <p>
300     * The subsequence starts with the byte value at the specified {@code start}
301     * index and ends with the byte value at index {@code end - 1}. The length
302     * (in bytes) of the returned sequence is {@code end - start}, so if
303     * {@code start
304     * == end} then an empty sequence is returned.
305     * <p>
306     * <b>NOTE:</b> changes to the underlying byte sequence (if mutable) may
307     * render the returned sub-sequence invalid.
308     *
309     * @param start
310     *            The start index, inclusive.
311     * @param end
312     *            The end index, exclusive.
313     * @return The newly created byte subsequence.
314     * @throws IndexOutOfBoundsException
315     *             If {@code start} or {@code end} are negative, if {@code end}
316     *             is greater than {@code length()}, or if {@code start} is
317     *             greater than {@code end}.
318     */
319    ByteSequence subSequence(int start, int end);
320
321    /**
322     * Tests if this ByteSequence starts with the specified prefix.
323     *
324     * @param prefix
325     *            The prefix.
326     * @return true if the byte sequence represented by the argument is a prefix of the byte sequence represented by
327     *         this ByteSequence; false otherwise. Note also that true will be returned if the argument is an empty
328     *         sequence or is equal to this ByteSequence object as determined by the equals(Object) method.
329     */
330    boolean startsWith(ByteSequence prefix);
331
332    /**
333     * Returns the Base64 encoded string representation of this byte string.
334     *
335     * @return The Base64 encoded string representation of this byte string.
336     * @see ByteString#valueOfBase64(String)
337     */
338    String toBase64String();
339
340    /**
341     * Returns a byte array containing the bytes in this sequence in the same
342     * order as this sequence. The length of the byte array will be the length
343     * of this sequence.
344     * <p>
345     * An invocation of the form:
346     *
347     * <pre>
348     * src.toByteArray()
349     * </pre>
350     *
351     * Behaves in exactly the same way as the invocation:
352     *
353     * <pre>
354     * src.copyTo(new byte[src.length()]);
355     * </pre>
356     *
357     * @return A byte array consisting of exactly this sequence of bytes.
358     */
359    byte[] toByteArray();
360
361    /**
362     * Returns the {@link ByteString} representation of this byte sequence.
363     *
364     * @return The {@link ByteString} representation of this byte sequence.
365     */
366    ByteString toByteString();
367
368    /**
369     * Returns the UTF-8 decoded string representation of this byte sequence. If
370     * UTF-8 decoding fails, the platform's default encoding will be used.
371     *
372     * @return The string representation of this byte sequence.
373     */
374    @Override
375    String toString();
376}