package dods.clients.matlab;
import dods.dap.*;
import java.lang.*;
import java.util.*;
import java.io.*;
/**
* A Sequence class which will return columns of variables as well as
* individual variables.
*/
public class MatlabSequence extends DSequence {
public MatlabSequence() {
super();
}
public MatlabSequence(String name) {
super(name);
}
/**
* Returns a column in a sequence corresponding to <code>name</code>
*
* @param name The name of the variable to be retrieved. It can be of the
* form <varname>.<fieldname> or simply the name of the
* variable.
* @return The column in the sequence as an array of BaseTypes.
*/
public BaseType[] getColumn(String name)
throws NoSuchVariableException
{
int rowCount = getRowCount();
int rowWidth = elementCount();
int dotIndex = name.indexOf('.');
int rowIndex = 0;
int colIndex = -1;
BaseType[] column = new BaseType[rowCount];
Enumeration rows = allValues.elements();
if (dotIndex != -1) {
// If name is of the form <aggregate>.<field>, recurse into
// the variable <aggregate> and get sub-variable <field>.
String aggregate = name.substring(0, dotIndex);
String field = name.substring(dotIndex+1);
BaseType[] subVars = null;
for(int i=0; i<varTemplate.size(); i++) {
BaseType var = (BaseType)varTemplate.elementAt(i);
if(var.getName().equals(aggregate)) {
colIndex = i;
break;
}
}
if(colIndex == -1)
throw new NoSuchVariableException("MatlabSequence::getColumn()");
while(rows.hasMoreElements()) {
Vector row = (Vector)rows.nextElement();
BaseType var = (BaseType)row.elementAt(colIndex);
int numVars;
int i=0;
if(var instanceof MatlabSequence) {
numVars = ((MatlabSequence)var).getRowCount();
try {
subVars = ((MatlabSequence)var).getColumn(field);
}
catch (NoSuchVariableException e) {
throw(e);
}
}
else if(var instanceof DConstructor) {
subVars = new BaseType[1];
numVars = 1;
try {
subVars[0] = ((DConstructor)var).getVariable(field);
}
catch(NoSuchVariableException e) {
throw(e);
}
}
else
throw new NoSuchVariableException("MatlabSequence: getColumn()");
for(int j=0; j<numVars; j++)
column[rowIndex++] = subVars[j];
}
}
else {
for(int i=0; i<varTemplate.size(); i++) {
BaseType var = (BaseType)varTemplate.elementAt(i);
if(var.getName().equals(name)) {
colIndex = i;
break;
}
}
if(colIndex == -1)
throw new NoSuchVariableException("MatlabSequence::getColumn()");
while(rows.hasMoreElements())
column[rowIndex++] = (BaseType)((Vector)rows.nextElement()).elementAt(colIndex);
}
return column;
}
// The deserialize stuff had to be thrown in to get around a bug in
// the DAP library.
public synchronized void deserialize(DataInputStream source,
ServerVersion sv,
StatusUI statusUI)
throws IOException, EOFException, DataReadException {
// check for old servers
// Sometimes the DAP library will report the version of a server
// as 0.0, and in that case it's usually better to assume that
// it's a new server as opposed to an old one. rph 07/11/01.
if (sv.getMajor() != 0 && (sv.getMajor() < 2 || (sv.getMajor() == 2 && sv.getMinor() < 15))) {
oldDeserialize(source, sv, statusUI);
} else {
// ************* Pulled out the getLevel() check in order to support the "new"
// and "improved" serialization of dods sequences. 8/31/01 ndp
// top level of sequence handles start and end markers
//if (getLevel() == 0) {
// loop until end of sequence
for(;;) {
byte marker = readMarker(source);
if(statusUI != null)
statusUI.incrementByteCount(4);
if (marker == START_OF_INSTANCE)
deserializeSingle(source, sv, statusUI);
else if (marker == END_OF_SEQUENCE)
break;
else
throw new DataReadException("Sequence start marker not found");
}
// ************* Pulled out the getLevel() check in order to support the "new"
// and "improved" serialization of dods sequences. 8/31/01 ndp
// } else {
// lower levels only deserialize a single instance at a time
// deserializeSingle(source, sv, statusUI);
//}
}
}
private byte readMarker(DataInputStream source) throws IOException {
byte marker = source.readByte();
// pad out to a multiple of four bytes
byte unused;
for (int i=0; i<3; i++)
unused = source.readByte();
return marker;
}
private void oldDeserialize(DataInputStream source, ServerVersion sv,
StatusUI statusUI)
throws IOException, DataReadException {
try {
for(;;) {
deserializeSingle(source, sv, statusUI);
}
}
catch (EOFException e) {}
}
private void deserializeSingle(DataInputStream source, ServerVersion sv,
StatusUI statusUI)
throws IOException, EOFException, DataReadException {
// create a new instance from the variable template Vector
Vector newInstance = new Vector();
for(int i=0; i<varTemplate.size(); i++) {
BaseType bt = (BaseType)varTemplate.elementAt(i);
newInstance.addElement(bt.clone());
}
// deserialize the new instance
for (Enumeration e = newInstance.elements(); e.hasMoreElements(); ) {
if(statusUI != null && statusUI.userCancelled())
throw new DataReadException("User cancelled");
ClientIO bt = (ClientIO)e.nextElement();
bt.deserialize(source, sv, statusUI);
}
// add the new instance to the allValues vector
allValues.addElement(newInstance);
}
};