2N/A/*
2N/A * CDDL HEADER START
2N/A *
2N/A * The contents of this file are subject to the terms of the
2N/A * Common Development and Distribution License (the "License").
2N/A * You may not use this file except in compliance with the License.
2N/A *
2N/A * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
2N/A * or http://www.opensolaris.org/os/licensing.
2N/A * See the License for the specific language governing permissions
2N/A * and limitations under the License.
2N/A *
2N/A * When distributing Covered Code, include this CDDL HEADER in each
2N/A * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
2N/A * If applicable, add the following below this CDDL HEADER, with the
2N/A * fields enclosed by brackets "[]" replaced with your own identifying
2N/A * information: Portions Copyright [yyyy] [name of copyright owner]
2N/A *
2N/A * CDDL HEADER END
2N/A */
2N/A/*
2N/A * Copyright (c) 1999 by Sun Microsystems, Inc.
2N/A * All rights reserved.
2N/A *
2N/A */
2N/A
2N/A// Opaque.java: Wrapper for byte[].
2N/A// Author: James Kempf
2N/A// Created On: Tue Apr 7 15:21:58 1998
2N/A// Last Modified By: James Kempf
2N/A// Last Modified On: Fri Jun 5 15:26:59 1998
2N/A// Update Count: 38
2N/A//
2N/A
2N/Apackage com.sun.slp;
2N/A
2N/Aimport java.util.*;
2N/Aimport java.io.*;
2N/A
2N/A/**
2N/A * The Opaque class wraps Java byte arrays so we can do object-like
2N/A * things, such as deep equality comparison and printing.
2N/A *
2N/A * @author James Kempf
2N/A */
2N/A
2N/Aclass Opaque extends Object {
2N/A
2N/A // Character to use for fill.
2N/A
2N/A private static final char ZERO = '0';
2N/A
2N/A // The byte array.
2N/A
2N/A byte[] bytes;
2N/A
2N/A // For identifying opaques.
2N/A
2N/A final static String OPAQUE_HEADER = "\\ff";
2N/A
2N/A // Construct a Opaque.
2N/A
2N/A Opaque(byte[] nb) {
2N/A bytes = nb;
2N/A
2N/A }
2N/A
2N/A // Construct a byte array from an escaped string.
2N/A
2N/A static byte[] unescapeByteArray(String str)
2N/A throws ServiceLocationException {
2N/A
2N/A // Check for opaque header.
2N/A
2N/A if (!str.startsWith(OPAQUE_HEADER)) {
2N/A throw
2N/A new ServiceLocationException(
2N/A ServiceLocationException.PARSE_ERROR,
2N/A "no_opaque_header",
2N/A new Object[] {str});
2N/A
2N/A }
2N/A
2N/A String string = str.substring(OPAQUE_HEADER.length());
2N/A
2N/A // Process escapes to remove slash.
2N/A // string.
2N/A
2N/A int i, n = string.length();
2N/A int len = 0;
2N/A int nlen = n / 3;
2N/A byte[] b = new byte[nlen];
2N/A
2N/A for (i = 0; i < n; i++) {
2N/A if (string.charAt(i) != ServiceLocationAttribute.ESCAPE) {
2N/A throw
2N/A new ServiceLocationException(
2N/A ServiceLocationException.PARSE_ERROR,
2N/A "escape_err",
2N/A new Object[] {str});
2N/A
2N/A }
2N/A
2N/A // Get the next two characters.
2N/A
2N/A if (i > n - 2) {
2N/A throw
2N/A new ServiceLocationException(
2N/A ServiceLocationException.PARSE_ERROR,
2N/A "nonterminating_escape",
2N/A new Object[] {str});
2N/A }
2N/A
2N/A if (len >= nlen) {
2N/A throw
2N/A new ServiceLocationException(
2N/A ServiceLocationException.PARSE_ERROR,
2N/A "wrong_char_num",
2N/A new Object[] {str});
2N/A }
2N/A
2N/A try {
2N/A
2N/A i++;
2N/A b[len++] = (byte)(Integer.parseInt(
2N/A string.substring(i, i+2), 16) & 0xFF);
2N/A i++;
2N/A
2N/A } catch (NumberFormatException ex) {
2N/A throw
2N/A new ServiceLocationException(
2N/A ServiceLocationException.PARSE_ERROR,
2N/A "not_hex",
2N/A new Object[] {str});
2N/A
2N/A }
2N/A
2N/A }
2N/A
2N/A return b;
2N/A }
2N/A
2N/A // Overrides Object.equals().
2N/A
2N/A public boolean equals(Object o) {
2N/A
2N/A if (o == this) {
2N/A return true;
2N/A
2N/A }
2N/A
2N/A if (!(o instanceof Opaque)) {
2N/A return false;
2N/A
2N/A }
2N/A
2N/A byte[] cbyte = ((Opaque)o).bytes;
2N/A
2N/A // Not equal if lengths aren't.
2N/A
2N/A if (cbyte.length != bytes.length) {
2N/A return false;
2N/A
2N/A }
2N/A
2N/A // Check inside.
2N/A
2N/A int i;
2N/A
2N/A for (i = 0; i < cbyte.length; i++) {
2N/A if (cbyte[i] != bytes[i]) {
2N/A return false;
2N/A
2N/A }
2N/A }
2N/A
2N/A return true;
2N/A }
2N/A
2N/A public String toString() {
2N/A
2N/A int i, n = bytes.length;
2N/A StringBuffer buf = new StringBuffer();
2N/A
2N/A buf.append(OPAQUE_HEADER);
2N/A
2N/A for (i = 0; i < n; i++) {
2N/A String str = null;
2N/A
2N/A // Convert each byte into a string, then escape. We use
2N/A // an 8-bit encoding, LATIN1, since escapes are two
2N/A // characters only.
2N/A
2N/A str = Integer.toHexString(((int)bytes[i] & 0xFF));
2N/A
2N/A buf.append(ServiceLocationAttribute.ESCAPE);
2N/A
2N/A if (str.length() < 2) {
2N/A buf.append(ZERO);
2N/A }
2N/A
2N/A buf.append(str);
2N/A }
2N/A
2N/A return buf.toString();
2N/A }
2N/A
2N/A}