1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright (c) 1999 by Sun Microsystems, Inc. 23 * All rights reserved. 24 * 25 */ 26 27 // Opaque.java: Wrapper for byte[]. 28 // Author: James Kempf 29 // Created On: Tue Apr 7 15:21:58 1998 30 // Last Modified By: James Kempf 31 // Last Modified On: Fri Jun 5 15:26:59 1998 32 // Update Count: 38 33 // 34 35 package com.sun.slp; 36 37 import java.util.*; 38 import java.io.*; 39 40 /** 41 * The Opaque class wraps Java byte arrays so we can do object-like 42 * things, such as deep equality comparison and printing. 43 * 44 * @author James Kempf 45 */ 46 47 class Opaque extends Object { 48 49 // Character to use for fill. 50 51 private static final char ZERO = '0'; 52 53 // The byte array. 54 55 byte[] bytes; 56 57 // For identifying opaques. 58 59 final static String OPAQUE_HEADER = "\\ff"; 60 61 // Construct a Opaque. 62 63 Opaque(byte[] nb) { 64 bytes = nb; 65 66 } 67 68 // Construct a byte array from an escaped string. 69 70 static byte[] unescapeByteArray(String str) 71 throws ServiceLocationException { 72 73 // Check for opaque header. 74 75 if (!str.startsWith(OPAQUE_HEADER)) { 76 throw 77 new ServiceLocationException( 78 ServiceLocationException.PARSE_ERROR, 79 "no_opaque_header", 80 new Object[] {str}); 81 82 } 83 84 String string = str.substring(OPAQUE_HEADER.length()); 85 86 // Process escapes to remove slash. 87 // string. 88 89 int i, n = string.length(); 90 int len = 0; 91 int nlen = n / 3; 92 byte[] b = new byte[nlen]; 93 94 for (i = 0; i < n; i++) { 95 if (string.charAt(i) != ServiceLocationAttribute.ESCAPE) { 96 throw 97 new ServiceLocationException( 98 ServiceLocationException.PARSE_ERROR, 99 "escape_err", 100 new Object[] {str}); 101 102 } 103 104 // Get the next two characters. 105 106 if (i > n - 2) { 107 throw 108 new ServiceLocationException( 109 ServiceLocationException.PARSE_ERROR, 110 "nonterminating_escape", 111 new Object[] {str}); 112 } 113 114 if (len >= nlen) { 115 throw 116 new ServiceLocationException( 117 ServiceLocationException.PARSE_ERROR, 118 "wrong_char_num", 119 new Object[] {str}); 120 } 121 122 try { 123 124 i++; 125 b[len++] = (byte)(Integer.parseInt( 126 string.substring(i, i+2), 16) & 0xFF); 127 i++; 128 129 } catch (NumberFormatException ex) { 130 throw 131 new ServiceLocationException( 132 ServiceLocationException.PARSE_ERROR, 133 "not_hex", 134 new Object[] {str}); 135 136 } 137 138 } 139 140 return b; 141 } 142 143 // Overrides Object.equals(). 144 145 public boolean equals(Object o) { 146 147 if (o == this) { 148 return true; 149 150 } 151 152 if (!(o instanceof Opaque)) { 153 return false; 154 155 } 156 157 byte[] cbyte = ((Opaque)o).bytes; 158 159 // Not equal if lengths aren't. 160 161 if (cbyte.length != bytes.length) { 162 return false; 163 164 } 165 166 // Check inside. 167 168 int i; 169 170 for (i = 0; i < cbyte.length; i++) { 171 if (cbyte[i] != bytes[i]) { 172 return false; 173 174 } 175 } 176 177 return true; 178 } 179 180 public String toString() { 181 182 int i, n = bytes.length; 183 StringBuffer buf = new StringBuffer(); 184 185 buf.append(OPAQUE_HEADER); 186 187 for (i = 0; i < n; i++) { 188 String str = null; 189 190 // Convert each byte into a string, then escape. We use 191 // an 8-bit encoding, LATIN1, since escapes are two 192 // characters only. 193 194 str = Integer.toHexString(((int)bytes[i] & 0xFF)); 195 196 buf.append(ServiceLocationAttribute.ESCAPE); 197 198 if (str.length() < 2) { 199 buf.append(ZERO); 200 } 201 202 buf.append(str); 203 } 204 205 return buf.toString(); 206 } 207 208 } 209