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 < 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}