![]() |
Quadcap Embeddable Server |
00001 package com.quadcap.util; 00002 00003 /* Copyright 1997 - 2003 Quadcap Software. All rights reserved. 00004 * 00005 * This software is distributed under the Quadcap Free Software License. 00006 * This software may be used or modified for any purpose, personal or 00007 * commercial. Open Source redistributions are permitted. Commercial 00008 * redistribution of larger works derived from, or works which bundle 00009 * this software requires a "Commercial Redistribution License"; see 00010 * http://www.quadcap.com/purchase. 00011 * 00012 * Redistributions qualify as "Open Source" under one of the following terms: 00013 * 00014 * Redistributions are made at no charge beyond the reasonable cost of 00015 * materials and delivery. 00016 * 00017 * Redistributions are accompanied by a copy of the Source Code or by an 00018 * irrevocable offer to provide a copy of the Source Code for up to three 00019 * years at the cost of materials and delivery. Such redistributions 00020 * must allow further use, modification, and redistribution of the Source 00021 * Code under substantially the same terms as this license. 00022 * 00023 * Redistributions of source code must retain the copyright notices as they 00024 * appear in each source code file, these license terms, and the 00025 * disclaimer/limitation of liability set forth as paragraph 6 below. 00026 * 00027 * Redistributions in binary form must reproduce this Copyright Notice, 00028 * these license terms, and the disclaimer/limitation of liability set 00029 * forth as paragraph 6 below, in the documentation and/or other materials 00030 * provided with the distribution. 00031 * 00032 * The Software is provided on an "AS IS" basis. No warranty is 00033 * provided that the Software is free of defects, or fit for a 00034 * particular purpose. 00035 * 00036 * Limitation of Liability. Quadcap Software shall not be liable 00037 * for any damages suffered by the Licensee or any third party resulting 00038 * from use of the Software. 00039 */ 00040 00041 import java.io.ByteArrayInputStream; 00042 import java.io.InputStream; 00043 import java.io.IOException; 00044 import java.io.OutputStream; 00045 00046 /** 00047 * An OctetString is a variable length string of octets. 00048 * 00049 * @author Stan Bailes 00050 */ 00051 public class OctetString { 00052 byte[] data; 00053 00054 /** 00055 * Construct a new OctetString using the specified byte array. Note 00056 * that we simply acquire the byte array -- no copying is done! 00057 * 00058 * @param data the byte array making up the string 00059 */ 00060 public OctetString(byte[] data) { 00061 this.data = data; 00062 } 00063 00064 /** 00065 * Construct a new OctetString using a substring from the specified byte 00066 * array. This constructor <b>does</b> allocate a new byte array and 00067 * copies data from the original array. 00068 * 00069 * @param data the source byte array 00070 * @param offset the position of the first character in the substring 00071 * @param len the number of bytes in the new string 00072 */ 00073 public OctetString(byte[] data, int offset, int len) { 00074 this.data = new byte[len]; 00075 System.arraycopy(data, offset, this.data, 0, len); 00076 } 00077 00078 /** 00079 * Construct a new OctetString from the specified java.lang.String value. 00080 * 00081 * @param str the string value 00082 */ 00083 public OctetString(String str) { 00084 this.data = str.getBytes(); 00085 } 00086 00087 /** 00088 * Return the string representation of this item. 00089 * 00090 * @return the string value 00091 */ 00092 public String toString() { return new String(data); } 00093 00094 /** 00095 * For types which can be directly handled by comparators, return this 00096 * object as a byte array. For special types (e.g., NIL or List), 00097 * return null. 00098 */ 00099 public byte[] getBytes() { return data; } 00100 00101 public int hashCode() { 00102 return new String(data).hashCode(); 00103 } 00104 00105 public boolean equals(Object obj) { 00106 if (obj instanceof OctetString) { 00107 return OctetComparator.cmp.compare(this, (OctetString)obj) == 0; 00108 } 00109 return false; 00110 } 00111 00112 public boolean equalsIgnoreCase(Object obj) { 00113 if (obj instanceof OctetString) { 00114 OctetString other = (OctetString)obj; 00115 return OctetComparator.casecmp.compare(this, other) == 0; 00116 } 00117 return false; 00118 } 00119 00120 /** 00121 * Return the size of this string. 00122 */ 00123 public int size() { return data.length; } 00124 00125 /** 00126 * String comparison using the binary equality comparator 00127 */ 00128 public static boolean equals(OctetString s1, int pos1, 00129 OctetString s2, int pos2, int len) { 00130 for (int i = 0; i < len; i++) { 00131 if (pos1 + i >= s1.data.length || 00132 pos2 + i >= s2.data.length) return false; 00133 if (s1.data[pos1 + i] != s2.data[pos2 + i]) return false; 00134 } 00135 return true; 00136 } 00137 00138 /** 00139 * String search for character. Should this use a comparator? XXX 00140 * 00141 * @param c the character to search for 00142 * @return the index of the first occurrence of the character in this 00143 * string, or -1 if the character does not occur in the string. 00144 */ 00145 public int indexOf(char c) { 00146 byte b = (byte)c; 00147 for (int i = 0; i < data.length; i++) if (data[i] == b) return i; 00148 return -1; 00149 } 00150 00151 /** 00152 * String search for character. Should this use a comparator? XXX 00153 * 00154 * @param c the character to search for 00155 * @return the index of the last occurrence of the character in this 00156 * string, or -1 if the character does not occur in the string. 00157 */ 00158 public int lastIndexOf(char c) { 00159 byte b = (byte)c; 00160 for (int i = data.length-1; i >= 0; i--) if (data[i] == b) return i; 00161 return -1; 00162 } 00163 00164 /** 00165 * Return a new string containing the specified substring of this string. 00166 * 00167 * @param start the position of the first character of the substring 00168 * @param end the position of the character after the substring 00169 * @return the substring 00170 */ 00171 public OctetString substring(int start, int end) { 00172 return new OctetString(data, start, end - start); 00173 } 00174 00175 /** 00176 * Return a new string containing the specified substring of this string, 00177 * starting with the specified character, and ending with the last 00178 * character of the string. 00179 * 00180 * @param start the position of the first character of the substring 00181 * @return the substring 00182 */ 00183 public OctetString substring(int start) { 00184 return substring(start, size()); 00185 } 00186 00187 00188 /** 00189 * A truly general purpose function designed for a specified task, 00190 * this returns a new string containing the portion of this string 00191 * after the last occurrence of the specified character. 00192 * 00193 * <p>For example:<pre> 00194 * "/addressbook/user/stan/ABC457".afterLast('/') returns "ABC457" 00195 * </pre> 00196 * 00197 * @param c the character 00198 * @return a new <code>OctetString</code> containing the required suffix 00199 */ 00200 public OctetString afterLast(char c) { 00201 int pos = data.length; 00202 while (pos >= 0 && c != data[--pos]) continue; 00203 pos++; 00204 int len = data.length - pos; 00205 return substring(pos); 00206 } 00207 00208 /** 00209 * Return substring containing the portion of this string before the 00210 * first occurence of the specified character. 00211 * 00212 * @param c the character 00213 * @return a new <code>OctetString</code> containing the substring. 00214 */ 00215 public OctetString before(char c) { 00216 int idx = indexOf(c); 00217 if (idx < 0) return null; 00218 return substring(0, idx); 00219 } 00220 00221 /** 00222 * A truly general purpose function designed for a specified task, 00223 * this returns a new string containing the portion of this string 00224 * before the last occurrence of the specified character. 00225 * 00226 * <p>For example:<pre> 00227 * "/addressbook/user/stan/ABC457".beforeLast('/') returns 00228 * "/addressbook/user/stan" 00229 * </pre> 00230 * 00231 * @param c the character 00232 * @return a new <code>OctetString</code> containing the required prefix 00233 */ 00234 public OctetString beforeLast(char c) { 00235 int len = data.length; 00236 while (len >= 0 && c != data[--len]) continue; 00237 return substring(0, len); 00238 } 00239 00240 /** 00241 * Another general purpose routine :-) 00242 * This one converts a particular substring of this string to an 00243 * integer. 00244 * 00245 * @param start the position of the first character of the substring 00246 * @param end the position of the character after the substring 00247 * 00248 */ 00249 public int getIntSubString(int start, int end) { 00250 int val = 0; 00251 for (int i = 0; i < end; i++) { 00252 val *= 10; 00253 val += Character.digit((char)(data[i]), 10); 00254 } 00255 return val; 00256 } 00257 00258 /** 00259 * String concatenation 00260 */ 00261 public OctetString append(String s) { 00262 return append(s.getBytes()); 00263 } 00264 00265 /** 00266 * String concatenation 00267 */ 00268 public OctetString append(OctetString s) { 00269 return append(s.data); 00270 } 00271 00272 /** 00273 * String concatenation 00274 */ 00275 public OctetString append(byte[] b) { 00276 int len = data.length + b.length; 00277 byte[] ret = new byte[len]; 00278 System.arraycopy(data, 0, ret, 0, data.length); 00279 System.arraycopy(b, 0, ret, data.length, b.length); 00280 return new OctetString(ret); 00281 } 00282 00283 } 00284