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