/////////////////////////////////////////////////////////////////////////////
// Copyright (c) 1998, California Institute of Technology.
// ALL RIGHTS RESERVED. U.S. Government Sponsorship acknowledged.
//
// Please read the full copyright notice in the file COPYRIGHT
// in this directory.
//
// Author: Jake Hamby, NASA/Jet Propulsion Laboratory
// Jake.Hamby@jpl.nasa.gov
/////////////////////////////////////////////////////////////////////////////
package dods.dap;
import java.util.Enumeration;
import java.util.Vector;
/**
* The Util class holds static methods used by this package.
*
* @version $Revision: 1.1.1.1 $
* @author jehamby
*/
class Util {
/**
* Compares elements in a <code>Vector</code> of <code>BaseType</code>s and
* throw a <code>BadSemanticsException</code> if there are any
* duplicate elements.
*
* @param v The <code>Vector</code> to check
* @param varName the name of the variable which called us
* @param typeName the type name of the variable which called us
* @exception BadSemanticsException if there are duplicate elements
* @exception IndexOutOfBoundsException if size doesn't match the number
* of elements in the <code>Enumeration</code>
*/
static void uniqueNames(Vector v, String varName,
String typeName) throws BadSemanticsException {
String[] names = sortedNames(v);
// DEBUG: print out names
//for(int i=0; i<names.length; i++) {
// System.err.println("names[" + i + "] = " + names[i]);
//}
// look for any instance of consecutive names that are ==
for(int i=1; i<names.length; i++) {
if (names[i-1].equals(names[i])) {
throw new BadSemanticsException("The variable `" + names[i] +
"' is used more than once in " + typeName + " `" +
varName + "'");
}
}
}
/**
* Takes a <code>Vector</code> of <code>BaseType</code>s, retrieves their
* names into an array of <code>String</code>s, and performs a Quick Sort
* on that array.
*
* @param v The Vector to check
* @return a sorted array of <code>String</code>
* @exception BadSemanticsException if there is an element with no name
*/
static String[] sortedNames(Vector v) throws BadSemanticsException {
String[] names = new String[v.size()];
int count = 0;
for(Enumeration e = v.elements(); e.hasMoreElements(); ) {
BaseType bt = (BaseType)e.nextElement();
String tempName = bt.getName();
if(tempName == null)
throw new BadSemanticsException(bt.getClass().getName() + " variable with no name");
names[count++] = tempName;
}
// DEBUG: print out names
//for(int i=0; i<names.length; i++) {
// System.err.println("names[" + i + "] = " + names[i]);
//}
// assert that size is correct
if (count != names.length)
throw new IndexOutOfBoundsException("Vector size changed unexpectedly");
quickSort(names, 0, names.length-1);
return names;
}
/**
* Internal recursive method to perform Quick Sort on name array.
*
* @param a an array of <code>String</code>.
* @param lo0 the low index to sort.
* @param hi0 the high index to sort.
*/
static private void quickSort(String a[], int lo0, int hi0) {
int lo = lo0;
int hi = hi0;
String mid;
if (hi0 > lo0) {
// Arbitrarily establishing partition element as the array midpoint */
mid = a[(lo0 + hi0)/2];
// loop through the array until indices cross
while(lo <= hi) {
// find the first element that is >= the partition element
// starting from the left index.
while ((lo < hi0) && (a[lo].compareTo(mid) < 0))
++lo;
// find an element that is <= the partition element
// starting from the right index.
while ((hi > lo0) && (a[hi].compareTo(mid) > 0))
--hi;
// if the indexes have not crossed, swap
if (lo <= hi) {
swap(a, lo, hi);
++lo;
--hi;
}
}
// If the right index has not reached the left side of array,
// sort the left partition.
if (lo0 < hi)
quickSort(a, lo0, hi);
// If the left index has not reached the right side of array,
// sort the right partition.
if (lo < hi0)
quickSort(a, lo, hi0);
}
}
/**
* Private method to swap two elements in the array
* @param a an array of <code>String</code>.
* @param i the index of the first element.
* @param j the index of the second element.
*/
static private void swap(String a[], int i, int j) {
String T;
T = a[i];
a[i] = a[j];
a[j] = T;
}
/**
* This function escapes non-printable characters and quotes. This is used
* to make <code>printVal</code> output <code>DString</code> data in the
* same way as the C++ version. Since Java supports Unicode, this will
* need to be altered if it's desired to print <code>DString</code> as
* UTF-8 or some other character encoding.
*
* @param s the input <code>String</code>.
* @return the escaped <code>String</code>.
*/
static String escattr(String s) {
StringBuffer buf = new StringBuffer(s.length());
for(int i=0; i<s.length(); i++) {
char c = s.charAt(i);
if(c == ' ' || (c >= '!' && c <= '~')) {
// printable ASCII character
buf.append(c);
} else {
// non-printable ASCII character: print as unsigned octal integer
// padded with leading zeros
buf.append('\\');
String numVal = Integer.toString((int)c & 0xFF, 8);
for(int pad=0; pad<(3-numVal.length()); pad++)
buf.append('0');
buf.append(numVal);
}
}
return buf.toString();
}
}