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