// $Id: StringCharAdapter.java,v 1.3 2003-02-03 20:09:07 donm Exp $
/*
* Copyright 1997-2000 Unidata Program Center/University Corporation for
* Atmospheric Research, P.O. Box 3000, Boulder, CO 80307,
* support@unidata.ucar.edu.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or (at
* your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
* General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package ucar.multiarray;
import java.io.IOException;
/**
* This MultiArray implementation wraps another MultiArray
* of Character componentType to produce a MultiArray of
* one less rank with String componentType.
*
* @see MultiArray
* @author $Author: donm $
* @version $Revision: 1.3 $ $Date: 2003-02-03 20:09:07 $
*/
public class StringCharAdapter implements MultiArray {
/**
* Construct a new proxy.
* @param delegate MultiArray of Character componentType
* @param fillValue char which used as terminator and fill value
*/
public
StringCharAdapter(MultiArray delegate, char fillValue)
{
if(delegate.getComponentType() != Character.TYPE)
throw new IllegalArgumentException(
"Not a Character Array");
delegate_ = delegate;
fillValue_ = fillValue;
lengths_ = new int [delegate_.getRank() -1];
final int [] dlengths = delegate_.getLengths();
System.arraycopy(dlengths, 0,
lengths_, 0, lengths_.length);
maxStringLen_ = dlengths[lengths_.length];
}
public char
getFillValue()
{ return fillValue_; }
/* Begin MultiArrayInfo */
/**
* Returns the Class object representing the component
* type of the array.
* @return Class The componentType
* @see java.lang.Class#getComponentType
*/
public Class
getComponentType()
{
// There has got to be a better way to do this.
try {
return Class.forName("java.lang.String");
}
catch (ClassNotFoundException cnfe) {
throw new RuntimeException("Implementation problem");
}
}
/**
* Returns the number of dimensions of the backing MultiArray,
* as transformed by the <code>rankInverseMap()</code> method of
* the IndexMap.
* @return int number of dimensions
*/
public int
getRank()
{ return lengths_.length; }
/**
* Returns the shape of the backing MultiArray as transformed
* by the <code>dimensionsInverseMap()</code> method of
* the IndexMap.
* @return int array whose length is the rank of this
* MultiArray and whose elements represent the
* length of each of it's dimensions
*/
public int []
getLengths()
{
if(isUnlimited())
{
// The delegate lengths might have changed.
// This could better be handle by an event.
System.arraycopy(delegate_.getLengths(), 0,
lengths_, 0, lengths_.length);
}
return (int []) lengths_.clone();
}
/**
* Returns <code>true</code> if and only if the effective dimension
* lengths can change.
*/
public boolean
isUnlimited()
{ return delegate_.isUnlimited(); }
/**
* Convenience interface; return <code>true</code>
* if and only if the rank is zero.
* @return boolean <code>true</code> iff rank == 0
*/
public boolean
isScalar()
{
return 0 == this.getRank();
}
/* End MultiArrayInfo */
/* Begin Accessor */
/**
* @return Object value at <code>index</code>
* Length of index must equal rank() of this.
* Values of index components must be less than corresponding
* values from getLengths().
*/
public Object
get(int [] index)
throws IOException
{
final int [] dIndex = new int [lengths_.length +1];
System.arraycopy(index, 0,
dIndex, 0, lengths_.length);
final char [] buf = new char[maxStringLen_];
int ii = 0;
for(; ii < maxStringLen_; ii++)
{
dIndex[lengths_.length] = ii;
buf[ii] = delegate_.getChar(dIndex);
if(buf[ii] == fillValue_)
break;
}
return new String(buf, 0, ii);
}
public boolean
getBoolean(int[] index)
{
throw new IllegalArgumentException();
}
public char
getChar(int[] index)
throws IOException
{
if(index.length > lengths_.length)
return delegate_.getChar(index);
throw new IllegalArgumentException();
}
public byte
getByte(int[] index)
{
throw new IllegalArgumentException();
}
public short
getShort(int[] index)
{
throw new IllegalArgumentException();
}
public int
getInt(int[] index)
{
throw new IllegalArgumentException();
}
public long
getLong(int[] index)
{
throw new IllegalArgumentException();
}
public float
getFloat(int[] index)
{
throw new IllegalArgumentException();
}
public double
getDouble(int[] index)
{
throw new IllegalArgumentException();
}
/**
* Length of index must equal rank() of this.
* Values of index components must be less than corresponding
* values from getLengths().
*/
public void
set(int [] index, Object value)
throws IOException
{
if( value instanceof String)
{
final int [] dIndex = new int [lengths_.length +1];
System.arraycopy(index, 0,
dIndex, 0, lengths_.length);
final String sValue = (String) value;
final int stringLen = ((String)value).length();
for(int ii = 0; ii < maxStringLen_; ii++)
{
dIndex[lengths_.length] = ii;
if(ii >= stringLen)
{
delegate_.setChar(dIndex,
fillValue_);
continue;
}
// else
delegate_.setChar(dIndex,
((String)value).charAt(ii));
}
return;
}
// else
throw new IllegalArgumentException();
}
public void
setBoolean(int [] index, boolean value)
{
throw new IllegalArgumentException();
}
public void
setChar(int [] index, char value)
{
throw new IllegalArgumentException();
}
public void
setByte(int [] index, byte value)
{
throw new IllegalArgumentException();
}
public void
setShort(int [] index, short value)
{
throw new IllegalArgumentException();
}
public void
setInt(int [] index, int value)
{
throw new IllegalArgumentException();
}
public void
setLong(int [] index, long value)
{
throw new IllegalArgumentException();
}
public void
setFloat(int [] index, float value)
{
throw new IllegalArgumentException();
}
public void
setDouble(int[] index, double value)
{
throw new IllegalArgumentException();
}
/**
* @see Accessor#copyout
*/
public MultiArray
copyout(int [] origin, int [] shape)
throws IOException
{
final int rank = getRank();
if(origin.length != rank
|| shape.length != rank)
throw new IllegalArgumentException("Rank Mismatch");
final MultiArrayImpl data = new MultiArrayImpl(
getComponentType(),
shape);
AbstractAccessor.copyO(this, origin, data, shape);
return data;
}
/**
* @see Accessor#copyin
*/
public void
copyin(int [] origin, MultiArray data)
throws IOException
{
final int rank = getRank();
if(origin.length != rank
|| data.getRank() != rank)
throw new IllegalArgumentException("Rank Mismatch");
// else
if(data.getComponentType() != getComponentType())
throw new ArrayStoreException();
// else
AbstractAccessor.copy(data, data.getLengths(), this, origin);
}
/**
* @see Accessor#toArray
* TODO: optimize?
*/
public Object
toArray()
throws IOException
{
return this.toArray(null, null, null);
}
/**
* @see Accessor#toArray
* TODO: optimize?
*/
public Object
getStorage ()
{
return delegate_.getStorage ();
}
/**
* @see Accessor#toArray
* TODO: optimize?
*/
public Object
toArray(Object dst, int [] origin, int [] shape)
throws IOException
{
final int rank = getRank();
if(origin == null)
origin = new int[rank];
else if(origin.length != rank)
throw new IllegalArgumentException("Rank Mismatch");
int [] shp = null;
if(shape == null)
shp = getLengths();
else if(shape.length == rank)
shp = (int []) shape.clone();
else
throw new IllegalArgumentException("Rank Mismatch");
final int [] products = new int[rank];
final int length = MultiArrayImpl.numberOfElements(shp,
products);
dst = MultiArrayImpl.fixDest(dst, length, getComponentType());
final MultiArrayImpl data = new MultiArrayImpl(shp, products,
dst);
AbstractAccessor.copyO(this, origin, data, shp);
return dst;
}
/* End Accessor */
private final MultiArray delegate_;
private final char fillValue_;
private final int [] lengths_;
private final int maxStringLen_;
/* Begin Test */
private static String
MultiArrayToString(MultiArray ma) {
StringBuffer buf = new StringBuffer();
final int rank = ma.getRank();
if (rank > 0)
{
buf.append("{\n\t");
final int [] dims = ma.getLengths();
final int last = dims[0] -1;
for(int ii = 0; ii <= last; ii++)
{
final MultiArray inner =
new MultiArrayProxy(ma,
new SliceMap(0, ii));
buf.append(MultiArrayToString(inner));
if(ii != last)
buf.append(", ");
}
buf.append("\n}");
}
else
{
try {
buf.append(ma.get((int [])null));
} catch (IOException ee) {}
}
return buf.toString();
}
public static void
main(String[] args)
{
MultiArray cha = new MultiArrayImpl(Character.TYPE,
new int[]{4, 5});
MultiArray sta = new StringCharAdapter(cha, (char)0);
int [] index = {0};
try {
sta.set(index, "KDEN");
index[0]++;
sta.set(index, "KBOU");
index[0]++;
sta.set(index, "KABQ");
index[0]++;
sta.set(index, "KPHX");
System.out.println(MultiArrayToString(sta));
System.out.println(MultiArrayToString(cha));
}
// catch (java.io.IOException ee) {}
catch (Exception ee) {}
}
/* End Test */
}