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 
Opaque(byte[] nb)63     Opaque(byte[] nb) {
64 	bytes = nb;
65 
66     }
67 
68     // Construct a byte array from an escaped string.
69 
unescapeByteArray(String str)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 
equals(Object o)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 
toString()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