int countBits() {
    int total_nbits = 0;
    total_nbytesCDM = 0;

    for (DataDescriptor dd : subKeys) {
      if (dd.subKeys != null) {
        total_nbits += dd.countBits();
        total_nbytesCDM += dd.total_nbytesCDM;

      } else if (dd.f == 0) {
        total_nbits += dd.bitWidth;
        total_nbytesCDM += dd.getByteWidthCDM();
      }
    }

    // replication
    if (replication > 1) {
      total_nbits *= replication;
      total_nbytesCDM *= replication;
    }

    return total_nbits;
  }

int
countBits
(
)
{
int
total_nbits
=
0
;
total_nbytesCDM
=
0
;
for
(
DataDescriptor
dd
:
subKeys
)
{
if
(
dd
.
subKeys
!=
)
{
total_nbits
+=
dd
.
countBits
(
)
;
total_nbytesCDM
+=
dd
.
total_nbytesCDM
;
}
else
if
(
dd
.
f
==
0
)
{
total_nbits
+=
dd
.
bitWidth
;
total_nbytesCDM
+=
dd
.
getByteWidthCDM
(
)
;
}
}
// replication
if
(
replication
>
1
)
{
total_nbits
*=
replication
;
total_nbytesCDM
*=
replication
;
}
return
total_nbits
;
}

count the bits used by the data in this dd and its children
only accurate for not compressed, and not variable length

@return bits used by the data in the file

count the bits used by the data in this dd and its children only accurate for not compressed and not variable length


public boolean equals2(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;

    DataDescriptor that = (DataDescriptor) o;

    if (fxy != that.fxy) return false;
    if (replication != that.replication) return false;
    if (type != that.type) return false;
    if (subKeys != null ? !subKeys.equals(that.subKeys) : that.subKeys != null) return false;

    return true;
  }

public boolean equals2 ( Object o ) { if ( this == o ) return true ; if ( o == null || getClass ( ) != o . getClass ( ) ) return false ; DataDescriptor that = ( DataDescriptor ) o ; if ( fxy != that . fxy ) return false ; if ( replication != that . replication ) return false ; if ( type != that . type ) return false ; if ( subKeys != null ? ! subKeys . equals ( that . subKeys ) : that . subKeys != null ) return false ; return true ; }

LOOK need different hashCode, reader assumes using object id

LOOK need different hashCode reader assumes using object id


private int loadHeader() {
    if (headerLoaded) return 0;
    InputStream s = stream;
    if (s == null) return -1;
    try {
      BufferedInputStream bs = new BufferedInputStream(s);
      ds = new DataInputStream(bs);
      /* read the header as one block of bytes*/
      Header = new byte[32];
      ds.readFully(Header);
      //System.out.println("dbase header is " + Header);
      if (Header[0] == '<') { //looks like html coming back to us!
        close(ds);
        return -1;
      }
      filetype = Header[0];
      /* 4 bytes for number of records is in little endian */
      nrecords = Swap.swapInt(Header, 4);
      nbytesheader = Swap.swapShort(Header, 8);

      /* read in the Field Descriptors */
      /* have to figure how many there are from
      * the header size.  Should be nbytesheader/32 -1
      */
      nfields = (nbytesheader / 32) - 1;
      if (nfields < 1) {
        System.out.println("nfields = " + nfields);
        System.out.println("nbytesheader = " +
                nbytesheader);
        return -1;
      }
      FieldDesc = new DbaseFieldDesc[nfields];
      data = new DbaseData[nfields];
      for (int i = 0; i < nfields; i++) {
        FieldDesc[i] = new DbaseFieldDesc(ds, filetype);
        data[i] = new DbaseData(FieldDesc[i],
                nrecords);
      }

      /* read the last byte of the header (0x0d) */
      ds.readByte();

      headerLoaded = true;
    } catch (java.io.IOException e) {
      close(s);
      return -1;
    }
    return 0;
  }

Load the dbase file header.

@return 0 for success, -1 for failure


private int loadData() {
    if (!headerLoaded) return -1;
    if (dataLoaded) return 0;
    InputStream s = stream;
    if (s == null) return -1;
    try {
      /* read in the data */
      for (int i = 0; i < nrecords; i++) {
        /* read the data record indicator */
        byte recbyte = ds.readByte();
        if (recbyte == 0x20) {
          for (int j = 0; j < nfields; j++) {
            data[j].readRowN(ds, i);
          }
        } else {
          /* a deleted record */
          nrecords--;
          i--;
        }
      }
      dataLoaded = true;
    } catch (java.io.IOException e) {
      close(s);
      return -1;
    } finally {
      close(s);
    }
    return 0;
  }

private
int
loadData
(
)
{
if
(
!
headerLoaded
)
return
1
;
if
(
dataLoaded
)
return
0
;
InputStream
s
=
stream
;
if
(
s
==
)
return
1
;
try
{
/* read in the data */
for
(
int
i
=
0
;
i
<
nrecords
;
i
++
)
{
/* read the data record indicator */
byte
recbyte
=
ds
.
readByte
(
)
;
if
(
recbyte
==
0x20
)
{
for
(
int
j
=
0
;
j
<
nfields
;
j
++
)
{
data
[
j
]
.
readRowN
(
ds
,
i
)
;
}
}
else
{
/* a deleted record */
nrecords
;
i
;
}
}
dataLoaded
=
true
;
}
catch
(
java
.
io
.
IOException
e
)
{
close
(
s
)
;
return
1
;
}
finally
{
close
(
s
)
;
}
return
0
;
}

Load the dbase file data.

@return 0 for success, -1 for failure


public DbaseData getField(String Name) {
    for (int i = 0; i < nfields; i++) {
      if (FieldDesc[i].Name.equals(Name)) return data[i];
    }
    return null;
  }

public DbaseData getField ( String Name ) { for ( int i = 0 ; i < nfields ; i ++ ) { if ( FieldDesc [ i ] . Name . equals ( Name ) ) return data [ i ] ; } return null ; }

Extract the data for a given field by name.

@param Name String with the name of the field to retrieve.
@return A DbaseData object if the name was found or null if not found

Extract the data for a given field by name .


public double[] getDoublesByName(String Name) {
    DbaseData d;
    if ((d = getField(Name)) == null) return null;
    if (d.getType() == DbaseData.TYPE_CHAR) {
      String[] s = d.getStrings();
      double[] dd = new double[s.length];
      for (int i = 0; i < s.length; i++) {
        dd[i] = Double.valueOf(s[i]);
      }
      return dd;
    }
    if (d.getType() == DbaseData.TYPE_BOOLEAN) {
      boolean[] b = d.getBooleans();
      double[] dd = new double[b.length];
      for (int i = 0; i < b.length; i++) {
        if (b[i]) {
          dd[i] = 1;
        } else {
          dd[i] = 0;
        }
      }
      return dd;

    }
    return d.getDoubles();
  }

public double [ ] getDoublesByName ( String Name ) { DbaseData d ; if ( ( d = getField ( Name ) ) == null ) return null ; if ( d . getType ( ) == DbaseData . TYPE_CHAR ) { String [ ] s = d . getStrings ( ) ; double [ ] dd = new double [ s . length ] ; for ( int i = 0 ; i < s . length ; i ++ ) { dd [ i ] = Double . valueOf ( s [ i ] ) ; } return dd ; } if ( d . getType ( ) == DbaseData . TYPE_BOOLEAN ) { boolean [ ] b = d . getBooleans ( ) ; double [ ] dd = new double [ b . length ] ; for ( int i = 0 ; i < b . length ; i ++ ) { if ( b [ i ] ) { dd [ i ] = 1 ; } else { dd [ i ] = 0 ; } } return dd ; } return d . getDoubles ( ) ; }

Extract the double array of data for a field by Name.

@param Name String with the name of the field to retrieve
@return A double[] if valid numeric field, otherwise null

Extract the double array of data for a field by Name .


public String[] getStringsByName(String Name) {
    DbaseData d;
    if ((d = getField(Name)) == null) return null;
    if (d.getType() != DbaseData.TYPE_CHAR) return null;
    return d.getStrings();
  }

public String [ ] getStringsByName ( String Name ) { DbaseData d ; if ( ( d = getField ( Name ) ) == null ) return null ; if ( d . getType ( ) != DbaseData . TYPE_CHAR ) return null ; return d . getStrings ( ) ; }

Extract the string array of data for a field by Name.

@param Name String with the name of the field to retrieve
@return A String[] if valid character field, otherwise null

Extract the string array of data for a field by Name .


public boolean[] getBooleansByName(String Name) {
    DbaseData d;
    if ((d = getField(Name)) == null) return null;
    if (d.getType() != DbaseData.TYPE_BOOLEAN) return null;
    return d.getBooleans();
  }

public boolean [ ] getBooleansByName ( String Name ) { DbaseData d ; if ( ( d = getField ( Name ) ) == null ) return null ; if ( d . getType ( ) != DbaseData . TYPE_BOOLEAN ) return null ; return d . getBooleans ( ) ; }

Extract the boolean array of data for a field by Name.

@param Name String with the name of the field to retrieve
@return A boolean[] if valid character field, otherwise null

Extract the boolean array of data for a field by Name .


public String getFieldName(int i) {
    if (i >= nfields || i < 0) {
      return null;
    }
    return (FieldDesc[i].Name);
  }

public String getFieldName ( int i ) { if ( i >= nfields || i < 0 ) { return null ; } return ( FieldDesc [ i ] . Name ) ; }

Get the name of a field by column number.

@param i The column number of the field name.
@return A String with the field name or null if out of bounds

Get the name of a field by column number .


public String[] getFieldNames() {
    String[] s = new String[nfields];
    for (int i = 0; i < nfields; i++) {
      s[i] = getFieldName(i);
    }
    return s;
  }

public String [ ] getFieldNames ( ) { String [ ] s = new String [ nfields ] ; for ( int i = 0 ; i < nfields ; i ++ ) { s [ i ] = getFieldName ( i ) ; } return s ; }

Get a list of all the field names in the dbase file

@return A String array of all the field names


public static void main(String[] args) {
    if (args.length < 1) {
      System.out.println("filename or URL required");
      System.exit(-1);
    }
    for (String s : args) {
      System.out.println("*** Dump of Dbase " + s + ":");
      try {
        DbaseFile dbf = new DbaseFile(s);
        // load() method reads all data at once
        if (dbf.loadHeader() != 0) {
          System.out.println("Error loading header" + s);
          System.exit(-1);
        }

        // output schema as [type0 field0, type1 field1, ...]
        String[] fieldNames = dbf.getFieldNames();
        System.out.print("[");

        int nf = dbf.getNumFields();
        DbaseData[] dbd = new DbaseData[nf];
        for (int field = 0; field < nf; field++) {
          dbd[field] = dbf.getField(field);
          switch (dbd[field].getType()) {
            case DbaseData.TYPE_BOOLEAN:
              System.out.print("boolean ");
              break;
            case DbaseData.TYPE_CHAR:
              System.out.print("String ");
              break;
            case DbaseData.TYPE_NUMERIC:
              System.out.print("double ");
              break;
          }
          System.out.print(fieldNames[field]);
          if (field < nf - 1)
            System.out.print(", ");
        }
        System.out.println("]");

        if (dbf.loadData() != 0) {
          System.out.println("Error loading data" + s);
          System.exit(-1);
        }

        // output data
        for (int rec = 0; rec < dbf.getNumRecords(); rec++) {
          for (int field = 0; field < nf; field++) {
            System.out.print(dbd[field].getData(rec));
            if (field < nf - 1)
              System.out.print(", ");
            else
              System.out.println();
          }
        }
      } catch (IOException e) {
        e.printStackTrace();
        break;
      }
    }
  }

Test program, dumps a Dbase file to stdout.

Test program dumps a Dbase file to stdout .


public Map<String, DapAttribute> getAttributes()
    {
        if(attributes == null) attributes = new HashMap<String, DapAttribute>();
        return attributes;
    }

public Map < String , DapAttribute > getAttributes ( ) { if ( attributes == null ) attributes = new HashMap < String , DapAttribute > ( ) ; return attributes ; }

attributes are not allowed on some node types


synchronized public DapAttribute setAttribute(DapAttribute attr)
            throws DapException
    {
        if(attributes == null)
            attributes = new HashMap<String, DapAttribute>();
        DapAttribute old = attributes.get(attr.getShortName());
        attributes.put(attr.getShortName(), attr);
        attr.setParent(this);
        return old;
    }

synchronized public DapAttribute setAttribute ( DapAttribute attr ) throws DapException { if ( attributes == null ) attributes = new HashMap < String , DapAttribute > ( ) ; DapAttribute old = attributes . get ( attr . getShortName ( ) ) ; attributes . put ( attr . getShortName ( ) , attr ) ; attr . setParent ( this ) ; return old ; }

This may  occur after initial construction


public synchronized void removeAttribute(DapAttribute attr)
            throws DapException
    {
        if(this.attributes == null)
            return;
        String name = attr.getShortName();
        if(this.attributes.containsKey(name))
            this.attributes.remove(name);
    }

public synchronized void removeAttribute ( DapAttribute attr ) throws DapException { if ( this . attributes == null ) return ; String name = attr . getShortName ( ) ; if ( this . attributes . containsKey ( name ) ) this . attributes . remove ( name ) ; }

Used by AbstractDSP to suppress certain attributes.

@param attr
@throws DapException

Used by AbstractDSP to suppress certain attributes .


public DapGroup getGroup()
    {
        if(this.sort == DapSort.DATASET)
            return null;
        // Walk the parent node until we find a group
        DapNode group = parent;
        while(group != null) {
            switch (group.getSort()) {
            case DATASET:
            case GROUP:
                return (DapGroup) group;
            default:
                group = group.getParent();
                break;
            }
        }
        return (DapGroup) group;
    }

Closest containing group

@returns closest group not equal to this
or null if this is a DapDataset


public DapNode getContainer()
    {
        DapNode parent = this.parent;
        switch (getSort()) {
        default:
            break;
        case ENUMCONST:
            parent = ((DapEnumConst) this).getParent().getContainer();
            break;
        case ATTRIBUTE:
        case ATTRIBUTESET:
        case OTHERXML:
            parent = ((DapAttribute) this).getParent();
            if(parent instanceof DapVariable)
                parent = parent.getContainer();
            break;
        case MAP:
            parent = ((DapMap) this).getVariable().getContainer();
            break;
        }
        return parent;
    }

public DapNode getContainer ( ) { DapNode parent = this . parent ; switch ( getSort ( ) ) { default : break ; case ENUMCONST : parent = ( ( DapEnumConst ) this ) . getParent ( ) . getContainer ( ) ; break ; case ATTRIBUTE : case ATTRIBUTESET : case OTHERXML : parent = ( ( DapAttribute ) this ) . getParent ( ) ; if ( parent instanceof DapVariable ) parent = parent . getContainer ( ) ; break ; case MAP : parent = ( ( DapMap ) this ) . getVariable ( ) . getContainer ( ) ; break ; } return parent ; }

Closest containing group, structure, sequence

@returns closest container

Closest containing group structure sequence


public String getEscapedShortName()
    {
        if(this.escapedname == null)
            this.escapedname = Escape.backslashEscape(getShortName(), null);
        return this.escapedname;
    }

public String getEscapedShortName ( ) { if ( this . escapedname == null ) this . escapedname = Escape . backslashEscape ( getShortName ( ) , null ) ; return this . escapedname ; }

Here, escaped means backslash escaped short name

@return escaped name

Here escaped means backslash escaped short name


public List<DapNode> getContainerPath()
    {
        List<DapNode> path = new ArrayList<DapNode>();
        DapNode current = this.getContainer();
        for(; ; ) {
            path.add(0, current);
            if(current.getContainer() == null)
                break;
            current = current.getContainer();
        }
        return path;
    }

public List < DapNode > getContainerPath ( ) { List < DapNode > path = new ArrayList < DapNode > ( ) ; DapNode current = this . getContainer ( ) ; for ( ; ; ) { path . add ( 0 , current ) ; if ( current . getContainer ( ) == null ) break ; current = current . getContainer ( ) ; } return path ; }

Get the transitive list of containers
Not including this node

@return list of container nodes


public List<DapGroup> getGroupPath()
    {
        List<DapGroup> path = new ArrayList<DapGroup>();
        DapNode current = this;
        for(; ; ) {
            if(current.getSort() == DapSort.GROUP
                    || current.getSort() == DapSort.DATASET)
                path.add(0, (DapGroup) current);
            if(current.getContainer() == null)
                break;
            current = current.getContainer();
        }
        return path;
    }

public List < DapGroup > getGroupPath ( ) { List < DapGroup > path = new ArrayList < DapGroup > ( ) ; DapNode current = this ; for ( ; ; ) { if ( current . getSort ( ) == DapSort . GROUP || current . getSort ( ) == DapSort . DATASET ) path . add ( 0 , ( DapGroup ) current ) ; if ( current . getContainer ( ) == null ) break ; current = current . getContainer ( ) ; } return path ; }

Get the transitive list of containing groups
Possibly including this node

@return list of group nodes


public String
    computefqn()
    {
        List<DapNode> path = getPath(); // excludes root/wrt
        StringBuilder fqn = new StringBuilder();
        DapNode parent = path.get(0);
        for(int i = 1; i < path.size(); i++) {   // start at 1 to skip root
            DapNode current = path.get(i);
            // Depending on what parent is, use different delimiters
            switch (parent.getSort()) {
            case DATASET:
            case GROUP:
            case ENUMERATION:
                fqn.append('/');
                fqn.append(Escape.backslashEscape(current.getShortName(),"/."));
                break;
            // These use '.'
            case STRUCTURE:
            case SEQUENCE:
            case ENUMCONST:
            case VARIABLE:
                fqn.append('.');
                fqn.append(current.getEscapedShortName());
                break;
            default: // Others should never happen
                throw new IllegalArgumentException("Illegal FQN parent");
            }
            parent = current;
        }
        return fqn.toString();
    }


public boolean isTopLevel()
    {
        return parent == null
                || parent.getSort() == DapSort.DATASET
                || parent.getSort() == DapSort.GROUP;
    }

public boolean isTopLevel ( ) { return parent == null || parent . getSort ( ) == DapSort . DATASET || parent . getSort ( ) == DapSort . GROUP ; }


protected void
    build(DapDataset dmr, byte[] serialdata, ByteOrder order)
            throws DapException
    {
        setDMR(dmr);
        // "Compile" the databuffer section of the server response
        this.databuffer = ByteBuffer.wrap(serialdata).order(order);
        D4DataCompiler compiler = new D4DataCompiler(this, getChecksumMode(), getOrder(), this.databuffer);
        compiler.compile();
    }

Build the data from the incoming serial data
Note that some DSP's will not use

@param dmr
@param serialdata
@param order
@throws DapException

Build the data from the incoming serial data Note that some DSP s will not use


public void putBeanCollection(String key, Collection newValue) {
      // if matches a stored Default, dont store
      Object oldValue = getBean(key, null);
      if ((oldValue == null) || !oldValue.equals( newValue))
        keyValues.put( key, new Bean.Collection(newValue));
    }

Stores a Collection of beans. The beans are stored using simple bean properties.
The collection of beans must all be of the same class.

@param key key with which the specified collection is to be associated.
@param newValue store this collection of beans.
@throws NullPointerException if key or value is <tt>null</tt>.
@throws IllegalStateException if this node (or an ancestor) has been
removed with the {@link #removeNode()} method.

Stores a Collection of beans . The beans are stored using simple bean properties . The collection of beans must all be of the same class .


public List getList(String key, List def) {
      try {
        Object bean = getBean(key, def);
        return (List) bean;
      } catch (Exception e) {
        e.printStackTrace();
        return null;
      }
    }

public List getList ( String key , List def ) { try { Object bean = getBean ( key , def ) ; return ( List ) bean ; } catch ( Exception e ) { e . printStackTrace ( ) ; return null ; } }

Get an arrayList. This returns a copy of the stored list.

@param key key whose associated value is to be returned.
@param def the value to be returned in the event that this
preference node has no value associated with <tt>key</tt>.
@return the value associated with <tt>key</tt>, or <tt>def</tt>
if no value is associated with <tt>key</tt>.

Get an arrayList . This returns a copy of the stored list .


private Object _getObject(String keyName) {
      Object result = null;
      try {
        result = keyValues.get( keyName);
        if (result == null) {
          // if failed, check the stored Defaults
          PreferencesExt sd = getStoredDefaults();
          if (sd != null)
            result = sd.getObjectFromNode( absolutePath(), keyName);
        }
      } catch (Exception e) {
              // Ignoring exception causes default to be returned
      }
      return result;
    }


public float[] readData(RandomAccessFile raf, long drsPos) throws IOException {
    raf.seek(drsPos);
    Grib2SectionDataRepresentation drs = new Grib2SectionDataRepresentation(raf);
    Grib2SectionBitMap bms = new Grib2SectionBitMap(raf);
    Grib2SectionData dataSection = new Grib2SectionData(raf);

    Grib2Gds gds = getGDS();
    Grib2DataReader reader = new Grib2DataReader(drs.getDataTemplate(), gdss.getNumberPoints(), drs.getDataPoints(),
            getScanMode(), gds.getNxRaw(), dataSection.getStartingPosition(), dataSection.getMsgLength());

    Grib2Drs gdrs = drs.getDrs(raf);

    float[] data = reader.getData(raf, bms, gdrs);

    if (gds.isThin())
      data = QuasiRegular.convertQuasiGrid(data, gds.getNptsInLine(), gds.getNxRaw(), gds.getNyRaw(), GribData.getInterpolationMethod());

    lastRecordRead = this;
    return data;
  }

public float [ ] readData ( RandomAccessFile raf , long drsPos ) throws IOException { raf . seek ( drsPos ) ; Grib2SectionDataRepresentation drs = new Grib2SectionDataRepresentation ( raf ) ; Grib2SectionBitMap bms = new Grib2SectionBitMap ( raf ) ; Grib2SectionData dataSection = new Grib2SectionData ( raf ) ; Grib2Gds gds = getGDS ( ) ; Grib2DataReader reader = new Grib2DataReader ( drs . getDataTemplate ( ) , gdss . getNumberPoints ( ) , drs . getDataPoints ( ) , getScanMode ( ) , gds . getNxRaw ( ) , dataSection . getStartingPosition ( ) , dataSection . getMsgLength ( ) ) ; Grib2Drs gdrs = drs . getDrs ( raf ) ; float [ ] data = reader . getData ( raf , bms , gdrs ) ; if ( gds . isThin ( ) ) data = QuasiRegular . convertQuasiGrid ( data , gds . getNptsInLine ( ) , gds . getNxRaw ( ) , gds . getNyRaw ( ) , GribData . getInterpolationMethod ( ) ) ; lastRecordRead = this ; return data ; }

Read data array

@param raf    from this RandomAccessFile
@param drsPos Grib2SectionDataRepresentation starts here
@return data as float[] array
@throws IOException on read error


public DSPPrinter
    print()
            throws DapException
    {
        DapDataset dmr = this.dsp.getDMR();
        if(this.ce == null)
            this.ce = CEConstraint.getUniversal(dmr);
        this.printer.setIndent(0);
        List<DapVariable> topvars = dmr.getTopVariables();
        for(int i = 0; i < topvars.size(); i++) {
            DapVariable top = topvars.get(i);
            List<Slice> slices = this.ce.getConstrainedSlices(top);
            if(this.ce.references(top)) {
                DataCursor data = dsp.getVariableData(top);
                printVariable(data,slices);
            }
        }
        printer.eol();
        return this;
    }

public DSPPrinter print ( ) throws DapException { DapDataset dmr = this . dsp . getDMR ( ) ; if ( this . ce == null ) this . ce = CEConstraint . getUniversal ( dmr ) ; this . printer . setIndent ( 0 ) ; List < DapVariable > topvars = dmr . getTopVariables ( ) ; for ( int i = 0 ; i < topvars . size ( ) ; i ++ ) { DapVariable top = topvars . get ( i ) ; List < Slice > slices = this . ce . getConstrainedSlices ( top ) ; if ( this . ce . references ( top ) ) { DataCursor data = dsp . getVariableData ( top ) ; printVariable ( data , slices ) ; } } printer . eol ( ) ; return this ; }

Print data from a DSP
- optionally constrained

@throws DapException


protected void
    printCompoundInstance(DataCursor datav)
            throws DapException
    {
        //Index index = datav.getIndex();
        DapStructure dstruct = (DapStructure) ((DapVariable) datav.getTemplate()).getBaseType();
        switch (datav.getScheme()) {
        case STRUCTURE:
        case RECORD:
            List<DapVariable> dfields = dstruct.getFields();
            for(int f = 0; f < dfields.size(); f++) {
                DapVariable field = dfields.get(f);
                List<Slice> fieldslices = this.ce.getConstrainedSlices(field);
                DataCursor fdata = datav.readField(f);
                printVariable(fdata,fieldslices);
            }
            break;

        case SEQUENCE:
            DapSequence dseq = (DapSequence)dstruct;
            long count = datav.getRecordCount();
            for(long r = 0; r < count; r++) {
                DataCursor dr = datav.readRecord(r);
                printer.marginPrint("[");
                printer.eol();
                printer.indent();
                printCompoundInstance(dr);
                printer.outdent();
                printer.marginPrint("]");
            }
            break;
        default:
            throw new DapException("Unexpected data cursor scheme:" + datav.getScheme());
        }
    }

protected
void
printCompoundInstance
(
DataCursor
datav
)
throws
DapException
{
//Index index = datav.getIndex();
DapStructure
dstruct
=
(
DapStructure
)
(
(
DapVariable
)
datav
.
getTemplate
(
)
)
.
getBaseType
(
)
;
switch
(
datav
.
getScheme
(
)
)
{
case
STRUCTURE
:
case
RECORD
:
List
<
DapVariable
>
dfields
=
dstruct
.
getFields
(
)
;
for
(
int
f
=
0
;
f
<
dfields
.
size
(
)
;
f
++
)
{
DapVariable
field
=
dfields
.
get
(
f
)
;
List
<
Slice
>
fieldslices
=
this
.
ce
.
getConstrainedSlices
(
field
)
;
DataCursor
fdata
=
datav
.
readField
(
f
)
;
printVariable
(
fdata
,
fieldslices
)
;
}
break
;
case
SEQUENCE
:
DapSequence
dseq
=
(
DapSequence
)
dstruct
;
long
count
=
datav
.
getRecordCount
(
)
;
for
(
long
r
=
0
;
r
<
count
;
r
++
)
{
DataCursor
dr
=
datav
.
readRecord
(
r
)
;
printer
.
marginPrint
(
"["
)
;
printer
.
eol
(
)
;
printer
.
indent
(
)
;
printCompoundInstance
(
dr
)
;
printer
.
outdent
(
)
;
printer
.
marginPrint
(
"]"
)
;
}
break
;
default
:
throw
new
DapException
(
"Unexpected data cursor scheme:"
+
datav
.
getScheme
(
)
)
;
}
}

Print a single structure or sequence or record instance

@param datav
@throws DapException


public String writeToString(Element elem) {
    try (StringWriter writer = new StringWriter()) {
      writeToWriter(elem, writer);
      return writer.toString();
    } catch (IOException e) {
      throw new AssertionError("CAN'T HAPPEN: StringWriter.close() is a no-op.", e);
    }
  }

Writes an NcML element to a string.

@param elem an NcML element.
@return the string that represents the NcML document.


public void writeToFile(Element elem, File outFile) throws IOException {
    try (OutputStream outStream = new BufferedOutputStream(new FileOutputStream(outFile, false))) {
      writeToStream(elem, outStream);
    }
  }

public void writeToFile ( Element elem , File outFile ) throws IOException { try ( OutputStream outStream = new BufferedOutputStream ( new FileOutputStream ( outFile , false ) ) ) { writeToStream ( elem , outStream ) ; } }

Writes an NcML element to an output file.

@param elem  an NcML element.
@param outFile  the file to write the NcML document to.
@throws IOException  if there's any problem writing.

Writes an NcML element to an output file .


public void writeToStream(Element elem, OutputStream outStream) throws IOException {
    try (Writer writer = new BufferedWriter(new OutputStreamWriter(
            new BufferedOutputStream(outStream), xmlFormat.getEncoding()))) {
      writeToWriter(elem, writer);
    }
  }

public void writeToStream ( Element elem , OutputStream outStream ) throws IOException { try ( Writer writer = new BufferedWriter ( new OutputStreamWriter ( new BufferedOutputStream ( outStream ) , xmlFormat . getEncoding ( ) ) ) ) { writeToWriter ( elem , writer ) ; } }

Writes an NcML element to an output stream.

@param elem  an NcML element.
@param outStream  the stream to write the NcML document to. Will be closed at end of the method.
@throws IOException  if there's any problem writing.

Writes an NcML element to an output stream .


public void writeToWriter(Element elem, Writer writer) throws IOException {
    xmlOutputter.setFormat(xmlFormat);
    elem.detach();  // In case this element had previously been added to a Document.
    xmlOutputter.output(new Document(elem), writer);
  }

Writes an NcML element to a Writer.

@param elem  an NcML element.
@param writer  the Writer to write the NcML document to. Will be closed at end of the method.
@throws IOException  if there's any problem writing.


public Element makeDimensionElement(Dimension dim) throws IllegalArgumentException {
    if (!dim.isShared()) {
      throw new IllegalArgumentException("Cannot create private dimension: " +
              "in NcML, <dimension> elements are always shared.");
    }

    Element dimElem = new Element("dimension", namespace);
    dimElem.setAttribute("name", dim.getShortName());
    dimElem.setAttribute("length", Integer.toString(dim.getLength()));

    if (dim.isUnlimited())
      dimElem.setAttribute("isUnlimited", "true");

    return dimElem;
  }


public ProjectionCT makeCoordinateTransform(AttributeContainer ctv, String units) {

    int[] area = getIntArray(ctv, McIDASAreaProjection.ATTR_AREADIR);
    int[] nav = getIntArray(ctv, McIDASAreaProjection.ATTR_NAVBLOCK);
    int[] aux = null;
    if (ctv.findAttributeIgnoreCase(McIDASAreaProjection.ATTR_AUXBLOCK) != null) {
      aux = getIntArray(ctv, McIDASAreaProjection.ATTR_AUXBLOCK);
    }
    // not clear if its ok if aux is null, coverity is complaining

    McIDASAreaProjection proj = new McIDASAreaProjection(area, nav, aux);
    return new ProjectionCT(ctv.getName(), "FGDC", proj);
  }

Make the coordinate transform

@param ctv the coordinate transform variable
@return the coordinate transform


private int[] getIntArray(AttributeContainer ctv, String attName) {
    Attribute att = ctv.findAttribute(attName);
    if (att == null) {
      throw new IllegalArgumentException("McIDASArea coordTransformVariable " + ctv.getName() + " must have " + attName + " attribute");
    }

    Array arr = att.getValues();
    return (int[]) arr.get1DJavaArray(int.class);
  }

private
int
[
]
getIntArray
(
AttributeContainer
ctv
,
String
attName
)
{
Attribute
att
=
ctv
.
findAttribute
(
attName
)
;
if
(
att
==
)
{
throw
new
IllegalArgumentException
(
"McIDASArea coordTransformVariable "
+
ctv
.
getName
(
)
+
" must have "
+
attName
+
" attribute"
)
;
}
Array
arr
=
att
.
getValues
(
)
;
return
(
int
[
]
)
arr
.
get1DJavaArray
(
int
.
class
)
;
}

get the int array from the variable attribute

@param ctv     coordinate transform variable
@param attName the attribute name
@return the int array


private static BaseUnit bu(final String name, final String symbol,
                             final BaseQuantity quantity) throws NameException,
          UnitExistsException {
    return BaseUnit.getOrCreate(UnitName.newUnitName(name, null, symbol),
            quantity);
  }

private static BaseUnit bu ( final String name , final String symbol , final BaseQuantity quantity ) throws NameException , UnitExistsException { return BaseUnit . getOrCreate ( UnitName . newUnitName ( name , null , symbol ) , quantity ) ; }

Factory method for constructing a base unit.

@param name     The name of the unit.
@param symbol   The symbol for the unit.
@param quantity The base quantity of the unit.
@return The base unit corresponding to the arguments.

Factory method for constructing a base unit .


private static Unit du(final String name, final String symbol,
                         final Unit definition) throws NameException {
    return definition.clone(UnitName.newUnitName(name, null, symbol));
  }

private static Unit du ( final String name , final String symbol , final Unit definition ) throws NameException { return definition . clone ( UnitName . newUnitName ( name , null , symbol ) ) ; }

Factory method for constructing a derived unit.

@param name       The name of the unit.
@param symbol     The symbol for the unit.
@param definition The definition of the unit.
@return The derived unit corresponding to the arguments.

Factory method for constructing a derived unit .


private static UnitDBImpl baseUnitDB() throws NameException, UnitExistsException, NoSuchUnitException {
    final UnitDBImpl db = new UnitDBImpl(9, 9);
    db.addUnit(AMPERE);
    db.addUnit(CANDELA);
    db.addUnit(KELVIN);
    db.addUnit(KILOGRAM);
    db.addUnit(METER);
    db.addUnit(MOLE);
    db.addUnit(SECOND);
    db.addUnit(RADIAN);
    db.addUnit(STERADIAN);
    db.addAlias("metre", "meter");
    return db;
  }

private static UnitDBImpl baseUnitDB ( ) throws NameException , UnitExistsException , NoSuchUnitException { final UnitDBImpl db = new UnitDBImpl ( 9 , 9 ) ; db . addUnit ( AMPERE ) ; db . addUnit ( CANDELA ) ; db . addUnit ( KELVIN ) ; db . addUnit ( KILOGRAM ) ; db . addUnit ( METER ) ; db . addUnit ( MOLE ) ; db . addUnit ( SECOND ) ; db . addUnit ( RADIAN ) ; db . addUnit ( STERADIAN ) ; db . addAlias ( "metre" , "meter" ) ; return db ; }

Returns the base unit database of the SI.

@return The base unit database of the SI.
@throws NameException       Bad unit name.
@throws UnitExistsException Attempt to redefine an existing unit.
@throws NoSuchUnitException Necessary unit not found.

Returns the base unit database of the SI .


private static UnitDBImpl derivedUnitDB() throws NameException, UnitExistsException, NoSuchUnitException {
    final UnitDBImpl db = new UnitDBImpl(42, 43);

    db.addUnit(HERTZ);
    db.addUnit(NEWTON);
    db.addUnit(PASCAL);
    db.addUnit(JOULE);
    db.addUnit(WATT);
    db.addUnit(COULOMB);
    db.addUnit(VOLT);
    db.addUnit(FARAD);
    db.addUnit(OHM);
    db.addUnit(SIEMENS);
    db.addUnit(WEBER);
    db.addUnit(TESLA);
    db.addUnit(HENRY);
    db.addUnit(DEGREE_CELSIUS);
    db.addUnit(LUMEN);
    db.addUnit(LUX);

    db.addUnit(BECQUEREL);
    db.addUnit(GRAY);
    db.addUnit(SIEVERT);

    db.addUnit(MINUTE);
    db.addUnit(HOUR);
    db.addUnit(DAY);
    db.addUnit(ARC_DEGREE);
    db.addUnit(ARC_MINUTE);
    db.addUnit(ARC_SECOND);
    db.addUnit(LITER);
    db.addUnit(METRIC_TON);

    db.addUnit(NAUTICAL_MILE);
    db.addUnit(KNOT);
    db.addUnit(ANGSTROM);
    db.addUnit(ARE);
    db.addUnit(HECTARE);
    db.addUnit(BARN);
    db.addUnit(BAR);
    db.addUnit(GAL);

    db.addUnit(CURIE);
    db.addUnit(ROENTGEN);
    db.addUnit(RAD);
    db.addUnit(REM);

    db.addAlias("litre", "liter", "l");
    db.addAlias("tonne", "metric ton");
    db.addSymbol("tne", "tonne");

    return db;
  }

private
static
UnitDBImpl
derivedUnitDB
(
)
throws
NameException
,
UnitExistsException
,
NoSuchUnitException
{
final
UnitDBImpl
db
=
new
UnitDBImpl
(
42
,
43
)
;
db
.
addUnit
(
HERTZ
)
;
db
.
addUnit
(
NEWTON
)
;
db
.
addUnit
(
PASCAL
)
;
db
.
addUnit
(
JOULE
)
;
db
.
addUnit
(
WATT
)
;
db
.
addUnit
(
COULOMB
)
;
db
.
addUnit
(
VOLT
)
;
db
.
addUnit
(
FARAD
)
;
db
.
addUnit
(
OHM
)
;
db
.
addUnit
(
SIEMENS
)
;
db
.
addUnit
(
WEBER
)
;
db
.
addUnit
(
TESLA
)
;
db
.
addUnit
(
HENRY
)
;
db
.
addUnit
(
DEGREE_CELSIUS
)
;
db
.
addUnit
(
LUMEN
)
;
db
.
addUnit
(
LUX
)
;
db
.
addUnit
(
BECQUEREL
)
;
db
.
addUnit
(
GRAY
)
;
db
.
addUnit
(
SIEVERT
)
;
db
.
addUnit
(
MINUTE
)
;
db
.
addUnit
(
HOUR
)
;
db
.
addUnit
(
DAY
)
;
db
.
addUnit
(
ARC_DEGREE
)
;
db
.
addUnit
(
ARC_MINUTE
)
;
db
.
addUnit
(
ARC_SECOND
)
;
db
.
addUnit
(
LITER
)
;
db
.
addUnit
(
METRIC_TON
)
;
db
.
addUnit
(
NAUTICAL_MILE
)
;
db
.
addUnit
(
KNOT
)
;
db
.
addUnit
(
ANGSTROM
)
;
db
.
addUnit
(
ARE
)
;
db
.
addUnit
(
HECTARE
)
;
db
.
addUnit
(
BARN
)
;
db
.
addUnit
(
BAR
)
;
db
.
addUnit
(
GAL
)
;
db
.
addUnit
(
CURIE
)
;
db
.
addUnit
(
ROENTGEN
)
;
db
.
addUnit
(
RAD
)
;
db
.
addUnit
(
REM
)
;
db
.
addAlias
(
"litre"
,
"liter"
,
"l"
)
;
db
.
addAlias
(
"tonne"
,
"metric ton"
)
;
db
.
addSymbol
(
"tne"
,
"tonne"
)
;
return
db
;
}

Returns the derived unit database of the SI.

@return The derived unit database of the SI.
@throws NameException       Bad unit name.
@throws UnitExistsException Attempt to redefine an existing unit.
@throws NoSuchUnitException Necessary unit not found.

Returns the derived unit database of the SI .


public static synchronized SI instance() throws UnitSystemException {
    if (si == null) {
      try {
        si = new SI();
      } catch (final UnitException e) {
        throw new UnitSystemException("Couldn't initialize class SI", e);
      }
    }
    return si;
  }

public
static
synchronized
SI
instance
(
)
throws
UnitSystemException
{
if
(
si
==
)
{
try
{
si
=
new
SI
(
)
;
}
catch
(
final
UnitException
e
)
{
throw
new
UnitSystemException
(
"Couldn't initialize class SI"
,
e
)
;
}
}
return
si
;
}

Returns an instance of the SI system of units.

@return An instance of the SI system of units.
@throws UnitSystemException Couldn't create an instance of the SI system of units.

Returns an instance of the SI system of units .


int findCoordElement(double[] target, boolean bounded) {
    switch (axis.getSpacing()) {
      case regularInterval:
        // can use midpoint
        return findCoordElementRegular((target[0]+target[1])/2, bounded);
      case contiguousInterval:
        // can use midpoint
        return findCoordElementContiguous((target[0]+target[1])/2, bounded);
      case discontiguousInterval:
        // cant use midpoint
        return findCoordElementDiscontiguousInterval(target, bounded);
    }
    throw new IllegalStateException("unknown spacing" + axis.getSpacing());
  }

int
findCoordElement
(
double
[
]
target
,
boolean
bounded
)
{
switch
(
axis
.
getSpacing
(
)
)
{
case
regularInterval
:
// can use midpoint
return
findCoordElementRegular
(
(
target
[
0
]
+
target
[
1
]
)
/
2
,
bounded
)
;
case
contiguousInterval
:
// can use midpoint
return
findCoordElementContiguous
(
(
target
[
0
]
+
target
[
1
]
)
/
2
,
bounded
)
;
case
discontiguousInterval
:
// cant use midpoint
return
findCoordElementDiscontiguousInterval
(
target
,
bounded
)
;
}
throw
new
IllegalStateException
(
"unknown spacing"
+
axis
.
getSpacing
(
)
)
;
}

Given a coordinate interval, find what grid element matches it.
@param target  interval in this coordinate system
@param bounded if true, always return a valid index. otherwise can return < 0 or > n-1
@return index of grid point containing it, or < 0 or > n-1 if outside grid area

Given a coordinate interval find what grid element matches it .


private int findClosest(double target) {
    double minDiff = Double.MAX_VALUE;
    double useValue = Double.MIN_VALUE;
    int idxFound = -1;
    for (int i = 0; i < axis.getNcoords(); i++) {
      double coord = axis.getCoordMidpoint(i);
      double diff = Math.abs(coord - target);
      if (diff < minDiff || (diff == minDiff && coord > useValue)) {
        minDiff = diff;
        idxFound = i;
        useValue = coord;
      }
    }
    return idxFound;
  }

private int findClosest ( double target ) { double minDiff = Double . MAX_VALUE ; double useValue = Double . MIN_VALUE ; int idxFound = - 1 ; for ( int i = 0 ; i < axis . getNcoords ( ) ; i ++ ) { double coord = axis . getCoordMidpoint ( i ) ; double diff = Math . abs ( coord - target ) ; if ( diff < minDiff || ( diff == minDiff && coord > useValue ) ) { minDiff = diff ; idxFound = i ; useValue = coord ; } } return idxFound ; }


private Optional<CoverageCoordAxisBuilder> subsetValues(double minValue, double maxValue, int stride) {
    if (axis.getSpacing() == CoverageCoordAxis.Spacing.discontiguousInterval)
      return subsetValuesDiscontinuous(minValue, maxValue, stride);

    double lower = axis.isAscending() ? Math.min(minValue, maxValue) : Math.max(minValue, maxValue);
    double upper = axis.isAscending() ? Math.max(minValue, maxValue) : Math.min(minValue, maxValue);

    int minIndex = findCoordElement(lower, false);
    int maxIndex = findCoordElement(upper, false);

    if (minIndex >= axis.getNcoords())
      return Optional.empty(String.format("no points in subset: lower %f > end %f", lower, axis.getEndValue()));
    if (maxIndex < 0)
      return Optional.empty(String.format("no points in subset: upper %f < start %f", upper, axis.getStartValue()));

    if (minIndex < 0)
      minIndex = 0;
    if (maxIndex >= axis.getNcoords())
      maxIndex = axis.getNcoords() - 1;

    int count = maxIndex - minIndex + 1;
    if (count <= 0)
      throw new IllegalArgumentException("no points in subset");

    try {
      return Optional.of(subsetByIndex(new Range(minIndex, maxIndex, stride)));
    } catch (InvalidRangeException e) {
      return Optional.empty(e.getMessage());
    }
  }

look must handle discon interval different


@Nonnull
  public DataFactory.Result openFeatureDataset(Dataset Dataset, ucar.nc2.util.CancelTask task) throws IOException {
    return openFeatureDataset(null, Dataset, task, new Result());
  }

@ Nonnull public DataFactory . Result openFeatureDataset ( Dataset Dataset , ucar . nc2 . util . CancelTask task ) throws IOException { return openFeatureDataset ( null , Dataset , task , new Result ( ) ) ; }

Open a FeatureDataset from an Dataset object, deciding on which Access to use.

@param Dataset use this to figure out what type, how to open, etc
@param task       allow user to cancel; may be null
@return ThreddsDataFactory.Result check fatalError for validity
@throws IOException on read error

Open a FeatureDataset from an Dataset object deciding on which Access to use .


public DataFactory.Result openFeatureDataset(Access access, ucar.nc2.util.CancelTask task) throws IOException {
    Dataset ds = access.getDataset();
    DataFactory.Result result = new Result();
    if (ds.getFeatureType() == null) {
      result.errLog.format("InvDatasert must specify a FeatureType%n");
      result.fatalError = true;
      return result;
    }

    return openFeatureDataset(ds.getFeatureType(), access, task, result);
  }

Open a FeatureDataset from an Access object.

@param access use this Access.
@param task   may be null
@return ThreddsDataFactory.Result check fatalError for validity
@throws IOException on read error

Open a FeatureDataset from an Access object .


public static void annotate(Dataset ds, NetcdfDataset ncDataset) {
    ncDataset.setTitle(ds.getName());
    ncDataset.setId(ds.getId());

    // add properties as global attributes
    for (Property p : ds.getProperties()) {
      String name = p.getName();
      if (null == ncDataset.findGlobalAttribute(name)) {
        ncDataset.addAttribute(null, new Attribute(name, p.getValue()));
      }
    }

    /* ThreddsMetadata.GeospatialCoverage geoCoverage = ds.getGeospatialCoverage();
   if (geoCoverage != null) {
     if ( null != geoCoverage.getNorthSouthRange()) {
       ncDataset.addAttribute(null, new Attribute("geospatial_lat_min", new Double(geoCoverage.getLatSouth())));
       ncDataset.addAttribute(null, new Attribute("geospatial_lat_max", new Double(geoCoverage.getLatNorth())));
     }
     if ( null != geoCoverage.getEastWestRange()) {
       ncDataset.addAttribute(null, new Attribute("geospatial_lon_min", new Double(geoCoverage.getLonWest())));
       ncDataset.addAttribute(null, new Attribute("geospatial_lon_max", new Double(geoCoverage.getLonEast())));
     }
     if ( null != geoCoverage.getUpDownRange()) {
       ncDataset.addAttribute(null, new Attribute("geospatial_vertical_min", new Double(geoCoverage.getHeightStart())));
       ncDataset.addAttribute(null, new Attribute("geospatial_vertical_max", new Double(geoCoverage.getHeightStart() + geoCoverage.getHeightExtent())));
     }
   }

   DateRange timeCoverage = ds.getTimeCoverage();
   if (timeCoverage != null) {
     ncDataset.addAttribute(null, new Attribute("time_coverage_start", timeCoverage.getStart().toDateTimeStringISO()));
     ncDataset.addAttribute(null, new Attribute("time_coverage_end", timeCoverage.getEnd().toDateTimeStringISO()));
   } */

    ncDataset.finish();
  }

Add information from the Dataset to the NetcdfDataset.

@param ds        get info from here
@param ncDataset add to here

Add information from the Dataset to the NetcdfDataset .


public static float[] readData(RandomAccessFile raf, long startPos) throws IOException {
    raf.seek(startPos);
    Grib1Record gr = new Grib1Record(raf);
    return gr.readData(raf);
  }

public static float [ ] readData ( RandomAccessFile raf , long startPos ) throws IOException { raf . seek ( startPos ) ; Grib1Record gr = new Grib1Record ( raf ) ; return gr . readData ( raf ) ; }

Read data array by first reading in GribRecord.
All sections are read in, so scanMode is from the datafile, not the index.

@param raf      from this RandomAccessFile
@param startPos message starts here
@return data as float[] array
@throws IOException on read error

Read data array by first reading in GribRecord . All sections are read in so scanMode is from the datafile not the index .


public String
    assemble(EnumSet<Parts> parts)
    {
        StringBuilder uri = new StringBuilder();
        // Note that format and base may be same, so case it out
        int useformat = (parts.contains(Parts.FORMAT) ? 1 : 0);
        int usebase = (parts.contains(Parts.BASE) ? 2 : 0);
        switch (useformat + usebase) {
        case 0 + 0: // neither
            break;
        case 1 + 0: // FORMAT only
            uri.append(this.formatprotocol + ":");
            break;
        case 2 + 0: // BASE only
            uri.append(this.baseprotocol + ":");
            break;
        case 2 + 1: // both
            uri.append(this.formatprotocol + ":");
            if(!this.baseprotocol.equals(this.formatprotocol))
                uri.append(this.formatprotocol + ":");
            break;
        }
        uri.append(this.baseprotocol.equals("file") ? "/" : "//");

        if(userinfo != null && parts.contains(Parts.PWD))
            uri.append(this.userinfo + ":");
        if(this.host != null && parts.contains(Parts.HOST))
            uri.append(this.host);
        if(this.path != null && parts.contains(Parts.PATH))
            uri.append(this.path);
        if(this.query != null && parts.contains(Parts.QUERY))
            uri.append("?" + this.query);
        if(this.frag != null && parts.contains(Parts.FRAG))
            uri.append("#" + this.frag);
        return uri.toString();
    }

Reassemble the url using the specified parts

@param parts to include
@return the assembled uri


static public String
    canonical(String s)
    {
        if(s != null) {
            s = s.trim();
            if(s.length() == 0)
                s = null;
        }
        return s;
    }

static public String canonical ( String s ) { if ( s != null ) { s = s . trim ( ) ; if ( s . length ( ) == 0 ) s = null ; } return s ; }

Canonicalize a part of a URL

@param s part of the url


private String normalize(String units) {
    switch (units) {
      case "fraction":
        units = "";
        break;
      case "dimensionless":
        units = "";
        break;
      case "NA":
        units = "";
        break;
      case "-":
        units = "";
        break;
      default:
        units = StringUtil2.substitute(units, "**", "^");
        units = StringUtil2.remove(units, '}');
        units = StringUtil2.remove(units, '{');
        break;
    }
    return units;
  }

private String normalize ( String units ) { switch ( units ) { case "fraction" : units = "" ; break ; case "dimensionless" : units = "" ; break ; case "NA" : units = "" ; break ; case "-" : units = "" ; break ; default : units = StringUtil2 . substitute ( units , "**" , "^" ) ; units = StringUtil2 . remove ( units , ' ' ) ; units = StringUtil2 . remove ( units , ' ' ) ; break ; } return units ; }


public DapDataset
    compile()
            throws DapException
    {
        // create and fill the root group
        buildrootgroup(this.ncid);
        if(this.dmr != null) dmr.finish();
        return this.dmr;
    }

public
DapDataset
compile
(
)
throws
DapException
{
// create and fill the root group
buildrootgroup
(
this
.
ncid
)
;
if
(
this
.
dmr
!=
)
dmr
.
finish
(
)
;
return
this
.
dmr
;
}


public void finish() {
    if (init) return;
    init = true;
    if (xlinkHref == null) return;

    xlinkHref = xlinkHref.trim();
    try {
      this.xlinkUri = dataset.getParentCatalog().resolveUri(xlinkHref);
    } catch (java.net.URISyntaxException e) {
      log.append(" ** Error: Bad URL in metadata href = ").append(xlinkHref).append("\n");
      return;
    }

    // open and read the referenced catalog XML
    try {
      if (converter == null) {
        log.append("  **InvMetadata on = (").append(this).append("): has no converter\n");
        return;
      }

      contentObject = converter.readMetadataContentFromURL(dataset, xlinkUri);
      if (isThreddsMetadata)
        tm = (ThreddsMetadata) contentObject;

    } catch (java.io.IOException e) {
      log.append("  **InvMetadata on = (").append(xlinkUri).append("): Exception (").append(e.getMessage()).append(")\n");
      // e.printStackTrace();
    }
  }

Finish getting the metadata if necessary.
If this is an XLink, this will trigger a read of the href the first time called.

Finish getting the metadata if necessary . If this is an XLink this will trigger a read of the href the first time called .


public synchronized Object get(Object key) {
        int index = keys.indexOf(key);
        if (index != -1)
            return elements.elementAt(index);
        else
            return null;
    }

public synchronized Object get ( Object key ) { int index = keys . indexOf ( key ) ; if ( index != - 1 ) return elements . elementAt ( index ) ; else return null ; }

Returns the value to which the key is mapped in this table.

@param key a key in this table.
@return the value to which the key is mapped, or null if the key is not
mapped to any value in the table.

Returns the value to which the key is mapped in this table .


public synchronized Object put(Object key, Object value) throws NullPointerException {
        if (key == null || value == null)
            throw new NullPointerException();

        int index = keys.indexOf(key);
        if (index != -1) {
            Object prev = elements.elementAt(index);
            elements.setElementAt(value, index);
            return prev;
        } else {
            keys.addElement(key);
            elements.addElement(value);
            return null;
        }
    }

public synchronized Object put ( Object key , Object value ) throws NullPointerException { if ( key == null || value == null ) throw new NullPointerException ( ) ; int index = keys . indexOf ( key ) ; if ( index != - 1 ) { Object prev = elements . elementAt ( index ) ; elements . setElementAt ( value , index ) ; return prev ; } else { keys . addElement ( key ) ; elements . addElement ( value ) ; return null ; } }

Maps the specified key to the specified value in this table.

@param key   the key
@param value the value
@return the previous value to which the key is mapped, or null if the
key did not have a previous mapping.
@throws NullPointerException if the key or value is null.

Maps the specified key to the specified value in this table .


public Date getDate() {
        Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
        calendar.set(Calendar.YEAR, year);
        calendar.set(Calendar.MONTH, month - 1);  // MONTH is zero based
        calendar.set(Calendar.DAY_OF_MONTH, day);
        calendar.set(Calendar.HOUR_OF_DAY, hour);
        calendar.set(Calendar.MINUTE, minute);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    }

public
Date
getDate
(
)
{
Calendar
calendar
=
Calendar
.
getInstance
(
TimeZone
.
getTimeZone
(
"GMT"
)
)
;
calendar
.
set
(
Calendar
.
YEAR
,
year
)
;
calendar
.
set
(
Calendar
.
MONTH
,
month
1
)
;
// MONTH is zero based
calendar
.
set
(
Calendar
.
DAY_OF_MONTH
,
day
)
;
calendar
.
set
(
Calendar
.
HOUR_OF_DAY
,
hour
)
;
calendar
.
set
(
Calendar
.
MINUTE
,
minute
)
;
calendar
.
set
(
Calendar
.
SECOND
,
0
)
;
calendar
.
set
(
Calendar
.
MILLISECOND
,
0
)
;
return
calendar
.
getTime
(
)
;
}

Return this as a java Date object

@return the corresponding Date


void
    printXMLAttributes(DapNode node, CEConstraint ce, int flags)
            throws IOException
    {
        if((flags & PERLINE) != 0)
            printer.indent(2);

        // Print name first, if non-null and !NONAME
        // Note that the short name needs to use
        // entity escaping (which is done by printXMLattribute),
        // but backslash escaping is not required.
        String name = node.getShortName();
        if(name != null && (flags & NONAME) == 0) {
            name = node.getShortName();
            printXMLAttribute("name", name, flags);
        }

        switch (node.getSort()) {
        case DATASET:
            DapDataset dataset = (DapDataset) node;
            printXMLAttribute("dapVersion", dataset.getDapVersion(), flags);
            printXMLAttribute("dmrVersion", dataset.getDMRVersion(), flags);
            // boilerplate
            printXMLAttribute("xmlns", "http://xml.opendap.org/ns/DAP/4.0#", flags);
            printXMLAttribute("xmlns:dap", "http://xml.opendap.org/ns/DAP/4.0#", flags);
            break;

        case DIMENSION:
            DapDimension orig = (DapDimension) node;
            if(orig.isShared()) {//not Anonymous
                // name will have already been printed
                // Now, we need to get the size as defined by the constraint
                DapDimension actual = this.ce.getRedefDim(orig);
                if(actual == null)
                    actual = orig;
                long size = actual.getSize();
                printXMLAttribute("size", Long.toString(size), flags);
            }
            break;

        case ENUMERATION:
            printXMLAttribute("basetype", ((DapEnumeration) node).getBaseType().getTypeName(), flags);
            break;

        case VARIABLE:
            DapVariable var = (DapVariable) node;
            DapType basetype = var.getBaseType();
            if(basetype.isEnumType()) {
                printXMLAttribute("enum", basetype.getTypeName(), flags);
            }
            break;

        case ATTRIBUTE:
            DapAttribute attr = (DapAttribute) node;
            basetype = attr.getBaseType();
            printXMLAttribute("type", basetype.getTypeName(), flags);
            if(attr.getBaseType().isEnumType()) {
                printXMLAttribute("enum", basetype.getTypeName(), flags);
            }
            break;

        default:
            break; // node either has no attributes or name only
        } //switch
        if(!this.testing)
            printReserved(node);
        if((flags & PERLINE) != 0) {
            printer.outdent(2);
        }
    }

Print info from the node that needs to be in the form of xml attributes


protected void
    printXMLAttribute(String name, String value, int flags)
            throws DapException
    {
        if(name == null) return;
        if((flags & NONNIL) == 0
                && (value == null || value.length() == 0))
            return;
        if((flags & PERLINE) != 0) {
            printer.eol();
            printer.margin();
        }
        printer.print(" " + name + "=");
        printer.print("\"");

        if(value != null) {
            // add xml entity escaping
            if((flags & XMLESCAPED) == 0)
                value = Escape.entityEscape(value, "\"");
            printer.print(value);
        }
        printer.print("\"");
    }

protected
void
printXMLAttribute
(
String
name
,
String
value
,
int
flags
)
throws
DapException
{
if
(
name
==
)
return
;
if
(
(
flags
&
NONNIL
)
==
0
&&
(
value
==
||
value
.
length
(
)
==
0
)
)
return
;
if
(
(
flags
&
PERLINE
)
!=
0
)
{
printer
.
eol
(
)
;
printer
.
margin
(
)
;
}
printer
.
print
(
" "
+
name
+
"="
)
;
printer
.
print
(
"\""
)
;
if
(
value
!=
)
{
// add xml entity escaping
if
(
(
flags
&
XMLESCAPED
)
==
0
)
value
=
Escape
.
entityEscape
(
value
,
"\""
)
;
printer
.
print
(
value
)
;
}
printer
.
print
(
"\""
)
;
}

PrintXMLAttributes helper function

@param name
@param value
@param flags
@throws DapException


static boolean isSpecial(DapAttribute attr)
    {
        if(attr.getParent().getSort() == DapSort.DATASET) {
            for(String s : GROUPSPECIAL) {
                if(s.equals(attr.getShortName()))
                    return true;
            }
        } else if(attr.getParent().getSort() == DapSort.VARIABLE) {
            for(String s : VARSPECIAL) {
                if(s.equals(attr.getShortName()))
                    return true;
            }
        }
        return false;
    }

static boolean isSpecial ( DapAttribute attr ) { if ( attr . getParent ( ) . getSort ( ) == DapSort . DATASET ) { for ( String s : GROUPSPECIAL ) { if ( s . equals ( attr . getShortName ( ) ) ) return true ; } } else if ( attr . getParent ( ) . getSort ( ) == DapSort . VARIABLE ) { for ( String s : VARSPECIAL ) { if ( s . equals ( attr . getShortName ( ) ) ) return true ; } } return false ; }

Special here is not the same as reserved

@param attr
@return


void
    printDimrefs(DapVariable var)
            throws DapException
    {
        if(var.getRank() == 0) return;
        List<DapDimension> dimset = this.ce.getConstrainedDimensions(var);
        if(dimset == null)
            throw new DapException("Unknown variable: " + var);
        assert var.getRank() == dimset.size();
        for(int i = 0; i < var.getRank(); i++) {
            DapDimension dim = dimset.get(i);
            printer.marginPrint("<Dim");
            if(dim.isShared()) {
                String fqn = dim.getFQN();
                assert (fqn != null) : "Illegal Dimension reference";
                fqn = fqnXMLEscape(fqn);
                printXMLAttribute("name", fqn, XMLESCAPED);
            } else {
                long size = dim.getSize();// the size for printing purposes
                printXMLAttribute("size", Long.toString(size), NILFLAGS);
            }
            printer.println("/>");
        }
    }

void
printDimrefs
(
DapVariable
var
)
throws
DapException
{
if
(
var
.
getRank
(
)
==
0
)
return
;
List
<
DapDimension
>
dimset
=
this
.
ce
.
getConstrainedDimensions
(
var
)
;
if
(
dimset
==
)
throw
new
DapException
(
"Unknown variable: "
+
var
)
;
assert
var
.
getRank
(
)
==
dimset
.
size
(
)
;
for
(
int
i
=
0
;
i
<
var
.
getRank
(
)
;
i
++
)
{
DapDimension
dim
=
dimset
.
get
(
i
)
;
printer
.
marginPrint
(
"<Dim"
)
;
if
(
dim
.
isShared
(
)
)
{
String
fqn
=
dim
.
getFQN
(
)
;
assert
(
fqn
!=
)
:
"Illegal Dimension reference"
;
fqn
=
fqnXMLEscape
(
fqn
)
;
printXMLAttribute
(
"name"
,
fqn
,
XMLESCAPED
)
;
}
else
{
long
size
=
dim
.
getSize
(
)
;
// the size for printing purposes
printXMLAttribute
(
"size"
,
Long
.
toString
(
size
)
,
NILFLAGS
)
;
}
printer
.
println
(
"/>"
)
;
}
}

Print the dimrefs for a variable's dimensions.
If the variable has a non-whole projection, then use size
else use the dimension name.

@param var whole dimensions are to be printed
@throws DapException

Print the dimrefs for a variable s dimensions . If the variable has a non - whole projection then use size else use the dimension name .


public static boolean isValidFile(RandomAccessFile raf) {
    String fileName = raf.getLocation();
    AreaFile af = null;
    try {
      af = new AreaFile(fileName);  // LOOK opening again not ok for isValidFile
      return true;
    } catch (AreaFileException e) {
      return false;                 // barfola
    } finally {
      if (af != null) af.close();  // LOOK need to look at this code
    }
  }

Check to see if this is a valid AREA file.

@param raf the file in question
@return true if it is an AREA file.

Check to see if this is a valid AREA file .


private void setAreaDirectoryAttributes(Variable v) {
    if ((dirBlock == null) || (ad == null)) {
      return;
    }
    for (int i = 1; i < 14; i++) {
      if (i == 7) {
        continue;
      }
      v.addAttribute(new Attribute(getADDescription(i), dirBlock[i]));
    }
  }

private void setAreaDirectoryAttributes ( Variable v ) { if ( ( dirBlock == null ) || ( ad == null ) ) { return ; } for ( int i = 1 ; i < 14 ; i ++ ) { if ( i == 7 ) { continue ; } v . addAttribute ( new Attribute ( getADDescription ( i ) , dirBlock [ i ] ) ) ; } }

Set the area directory attributes on the variable

@param v the variable to set them on


private void setNavBlockAttributes(Variable v) {
    if ((navBlock == null) || (ad == null)) {
      return;
    }
    v.addAttribute(
            new Attribute(
                    "navigation_type", McIDASUtil.intBitsToString(navBlock[0])));
  }

private void setNavBlockAttributes ( Variable v ) { if ( ( navBlock == null ) || ( ad == null ) ) { return ; } v . addAttribute ( new Attribute ( "navigation_type" , McIDASUtil . intBitsToString ( navBlock [ 0 ] ) ) ) ; }

Set the navigation block attributes on the variable

@param v the variable to set them on


private int getCalType(String calName) {
    int calTypeOut = Calibrator.CAL_NONE;
    if (calName.trim().equals("ALB")) {
      calTypeOut = Calibrator.CAL_ALB;
    } else if (calName.trim().equals("BRIT")) {
      calTypeOut = Calibrator.CAL_BRIT;
    } else if (calName.trim().equals("RAD")) {
      calTypeOut = Calibrator.CAL_RAD;
    } else if (calName.trim().equals("RAW")) {
      calTypeOut = Calibrator.CAL_RAW;
    } else if (calName.trim().equals("TEMP")) {
      calTypeOut = Calibrator.CAL_TEMP;
    }
    return calTypeOut;
  }

private int getCalType ( String calName ) { int calTypeOut = Calibrator . CAL_NONE ; if ( calName . trim ( ) . equals ( "ALB" ) ) { calTypeOut = Calibrator . CAL_ALB ; } else if ( calName . trim ( ) . equals ( "BRIT" ) ) { calTypeOut = Calibrator . CAL_BRIT ; } else if ( calName . trim ( ) . equals ( "RAD" ) ) { calTypeOut = Calibrator . CAL_RAD ; } else if ( calName . trim ( ) . equals ( "RAW" ) ) { calTypeOut = Calibrator . CAL_RAW ; } else if ( calName . trim ( ) . equals ( "TEMP" ) ) { calTypeOut = Calibrator . CAL_TEMP ; } return calTypeOut ; }

Get the calibration type from the name

@param calName calibration name
@return the Calibrator class type


private void setCalTypeAttributes(Variable image, int calType) {
    String longName = "image values";
    //String unit     = "";
    switch (calType) {

      case Calibrator.CAL_ALB:
        longName = "albedo";
        //unit     = "%";
        break;

      case Calibrator.CAL_BRIT:
        longName = "brightness values";
        break;

      case Calibrator.CAL_TEMP:
        longName = "temperature";
        //unit     = "K";
        break;

      case Calibrator.CAL_RAD:
        longName = "pixel radiance values";
        //unit     = "mW/m2/sr/cm-1";
        break;

      case Calibrator.CAL_RAW:
        longName = "raw image values";
        break;

      default:
        break;
    }
    image.addAttribute(new Attribute("long_name", longName));
    if (calUnit != null) {
      image.addAttribute(new Attribute(CDM.UNITS, calUnit));
    }
    if (calScale != 1.f) {
      image.addAttribute(new Attribute("scale_factor", calScale));
    }

  }

private
void
setCalTypeAttributes
(
Variable
image
,
int
calType
)
{
String
longName
=
"image values"
;
//String unit     = "";
switch
(
calType
)
{
case
Calibrator
.
CAL_ALB
:
longName
=
"albedo"
;
//unit     = "%";
break
;
case
Calibrator
.
CAL_BRIT
:
longName
=
"brightness values"
;
break
;
case
Calibrator
.
CAL_TEMP
:
longName
=
"temperature"
;
//unit     = "K";
break
;
case
Calibrator
.
CAL_RAD
:
longName
=
"pixel radiance values"
;
//unit     = "mW/m2/sr/cm-1";
break
;
case
Calibrator
.
CAL_RAW
:
longName
=
"raw image values"
;
break
;
default
:
break
;
}
image
.
addAttribute
(
new
Attribute
(
"long_name"
,
longName
)
)
;
if
(
calUnit
!=
)
{
image
.
addAttribute
(
new
Attribute
(
CDM
.
UNITS
,
calUnit
)
)
;
}
if
(
calScale
!=
1.f
)
{
image
.
addAttribute
(
new
Attribute
(
"scale_factor"
,
calScale
)
)
;
}
}

Set the long name and units for the calibration type

@param image   image variable
@param calType calibration type


static public void findCoords(TableConfig nt, NetcdfDataset ds, Predicate p) {
    nt.lat =  findCoordShortNameByType(ds, AxisType.Lat, p);
    nt.lon =  findCoordShortNameByType(ds, AxisType.Lon, p);
    nt.time =  findCoordShortNameByType(ds, AxisType.Time, p);
    nt.elev =  findCoordShortNameByType(ds, AxisType.Height, p);
    if (nt.elev == null)
      nt.elev =  findCoordShortNameByType(ds, AxisType.Pressure, p);
  }

static public void findCoords ( TableConfig nt , NetcdfDataset ds , Predicate p ) { nt . lat = findCoordShortNameByType ( ds , AxisType . Lat , p ) ; nt . lon = findCoordShortNameByType ( ds , AxisType . Lon , p ) ; nt . time = findCoordShortNameByType ( ds , AxisType . Time , p ) ; nt . elev = findCoordShortNameByType ( ds , AxisType . Height , p ) ; if ( nt . elev == null ) nt . elev = findCoordShortNameByType ( ds , AxisType . Pressure , p ) ; }

search for Axis by Type, assign to TableConfig if found.
search for Lat, Lon, Time, Height.
@param nt set coordinates short names in this table.
@param ds search in this dataset's "Best" coordinate system. If no CoordSystem, try list of coordinate axes

search for Axis by Type assign to TableConfig if found . search for Lat Lon Time Height .


static public String findCoordNameByType(NetcdfDataset ds, AxisType atype) {
     CoordinateAxis coordAxis = findCoordByType(ds, atype);
     return coordAxis == null ? null : coordAxis.getFullName();
   }

static public String findCoordNameByType ( NetcdfDataset ds , AxisType atype ) { CoordinateAxis coordAxis = findCoordByType ( ds , atype ) ; return coordAxis == null ? null : coordAxis . getFullName ( ) ; }

search for Axis by Type.
@param ds search in this dataset's "Best" coordinate system.
@param atype search for this type of CoordinateAxis. takes the first one it finds.
@return the found CoordinateAxis name, or null if none


static public CoordinateAxis findCoordByType(NetcdfDataset ds, AxisType atype) {
    return findCoordByType(ds, atype, null);
  }

static public CoordinateAxis findCoordByType ( NetcdfDataset ds , AxisType atype ) { return findCoordByType ( ds , atype , null ) ; }

Search for Axis by Type.
@param ds search in this dataset's "Best" coordinate system.
@param atype search for this type of CoordinateAxis. takes the first one it finds.
@return the found CoordinateAxis, or null if none


static public CoordinateAxis findCoordByType(NetcdfDataset ds, AxisType atype, Predicate p) {
    // try the "best" coordinate system
    CoordinateSystem use = findBestCoordinateSystem(ds);
    if (use == null) return null;
    CoordinateAxis result = findCoordByType(use.getCoordinateAxes(), atype, p);
    if (result != null) return result;

    // try all the axes
    return findCoordByType(ds.getCoordinateAxes(), atype, p);
  }

static
public
CoordinateAxis
findCoordByType
(
NetcdfDataset
ds
,
AxisType
atype
,
Predicate
p
)
{
// try the "best" coordinate system
CoordinateSystem
use
=
findBestCoordinateSystem
(
ds
)
;
if
(
use
==
)
return
;
CoordinateAxis
result
=
findCoordByType
(
use
.
getCoordinateAxes
(
)
,
atype
,
p
)
;
if
(
result
!=
)
return
result
;
// try all the axes
return
findCoordByType
(
ds
.
getCoordinateAxes
(
)
,
atype
,
p
)
;
}

search for Axis by Type and test against a predicate
@param ds search in this dataset's "Best" coordinate system.
@param atype search for this type of CoordinateAxis.
@param p match this predicate; may be null
@return the found CoordinateAxis, or null if none


static public Dimension findDimensionByType(NetcdfDataset ds, AxisType atype) {
    CoordinateAxis axis = findCoordByType(ds, atype);
    if (axis == null) return null;
    if (axis.isScalar()) return null;
    return axis.getDimension(0);
  }

static public Dimension findDimensionByType ( NetcdfDataset ds , AxisType atype ) { CoordinateAxis axis = findCoordByType ( ds , atype ) ; if ( axis == null ) return null ; if ( axis . isScalar ( ) ) return null ; return axis . getDimension ( 0 ) ; }

search for Dimension used by axis of given by Type.
@param ds search in this dataset's "Best" coordinate system.
@param atype search for this type of CoordinateAxis. takes the first one it finds.
@return the found CoordinateAxis' first Dimension, or null if none or scalar

search for Dimension used by axis of given by Type .


static private CoordinateSystem findBestCoordinateSystem(NetcdfDataset ds) {
        // find coordinate system with highest rank (largest number of axes)
    CoordinateSystem use = null;
    for (CoordinateSystem cs : ds.getCoordinateSystems()) {
      if (use == null) use = cs;
      else if (cs.getCoordinateAxes().size() > use.getCoordinateAxes().size())
        use = cs;
    }
    return use;
  }

Find the CoordinateSystem with the most number of CoordinateAxes
@param ds search in this dataset
@return CoordinateSystem or null if none


private CoverageCoordAxis1D  findDependent( CoverageCoordAxis independentAxis, AxisType axisType) {
    for (CoverageCoordAxis axis : axes) {
      if (axis.getDependenceType() == CoverageCoordAxis.DependenceType.dependent) {
        for (String axisName : axis.dependsOn) {
          if (axisName.equalsIgnoreCase(independentAxis.getName()) && axis.getAxisType() == axisType)
            return (CoverageCoordAxis1D) axis;
        }
      }
    }
    return null;
  }

private CoverageCoordAxis1D findDependent ( CoverageCoordAxis independentAxis , AxisType axisType ) { for ( CoverageCoordAxis axis : axes ) { if ( axis . getDependenceType ( ) == CoverageCoordAxis . DependenceType . dependent ) { for ( String axisName : axis . dependsOn ) { if ( axisName . equalsIgnoreCase ( independentAxis . getName ( ) ) && axis . getAxisType ( ) == axisType ) return ( CoverageCoordAxis1D ) axis ; } } } return null ; }

find the dependent axis that depend on independentAxis


public BaseType getVariable(int row, String name) throws NoSuchVariableException {

        int dotIndex = name.indexOf('.');

        if (dotIndex != -1) {  // name contains "."
            String aggregate = name.substring(0, dotIndex);
            String field = name.substring(dotIndex + 1);

            BaseType aggRef = getVariable(aggregate);
            if (aggRef instanceof DConstructor)
                return ((DConstructor) aggRef).getVariable(field);  // recurse
            else
                ; // fall through to throw statement
        } else {
            Vector selectedRow = (Vector) allValues.elementAt(row);
            for (Enumeration e = selectedRow.elements(); e.hasMoreElements();) {
                BaseType v = (BaseType) e.nextElement();
                if (v.getEncodedName().equals(name))
                    return v;
            }
        }
        throw new NoSuchVariableException("DSequence: getVariable()");
    }

public
BaseType
getVariable
(
int
row
,
String
name
)
throws
NoSuchVariableException
{
int
dotIndex
=
name
.
indexOf
(
'
'
)
;
if
(
dotIndex
!=
1
)
{
// name contains "."
String
aggregate
=
name
.
substring
(
0
,
dotIndex
)
;
String
field
=
name
.
substring
(
dotIndex
+
1
)
;
BaseType
aggRef
=
getVariable
(
aggregate
)
;
if
(
aggRef
instanceof
DConstructor
)
return
(
(
DConstructor
)
aggRef
)
.
getVariable
(
field
)
;
// recurse
else
;
// fall through to throw statement
}
else
{
Vector
selectedRow
=
(
Vector
)
allValues
.
elementAt
(
row
)
;
for
(
Enumeration
e
=
selectedRow
.
elements
(
)
;
e
.
hasMoreElements
(
)
;
)
{
BaseType
v
=
(
BaseType
)
e
.
nextElement
(
)
;
if
(
v
.
getEncodedName
(
)
.
equals
(
name
)
)
return
v
;
}
}
throw
new
NoSuchVariableException
(
"DSequence: getVariable()"
)
;
}

Returns the named variable in the given row of the sequence.

@param row  the row number to retrieve.
@param name the name of the variable.
@return the named variable.
@throws NoSuchVariableException if the named variable does not
exist in this container.

Returns the named variable in the given row of the sequence .


private void oldDeserialize(DataInputStream source, ServerVersion sv,
                                StatusUI statusUI)
            throws IOException, DataReadException {
        try {
            for (; ;) {
                deserializeSingle(source, sv, statusUI);
            }
        }
        catch (EOFException e) {
        }
    }

private void oldDeserialize ( DataInputStream source , ServerVersion sv , StatusUI statusUI ) throws IOException , DataReadException { try { for ( ; ; ) { deserializeSingle ( source , sv , statusUI ) ; } } catch ( EOFException e ) { } }

The old deserialize protocol has a number of limitations stemming from
its inability to tell when the sequence is finished.  It's really only
good for a Dataset containing a single sequence, or where the sequence is
the last thing in the dataset.  To handle this, we just read single
instances until we get an IOException, then stop.

@param source   a DataInputStream to read from.
@param sv       the ServerVersion returned by the server.
@param statusUI the StatusUI object to use for GUI updates
and user cancellation notification (may be null).
@throws IOException       thrown on any InputStream exception other than EOF
(which is trapped here).
@throws DataReadException if an unexpected value was read.

The old deserialize protocol has a number of limitations stemming from its inability to tell when the sequence is finished . It s really only good for a Dataset containing a single sequence or where the sequence is the last thing in the dataset . To handle this we just read single instances until we get an IOException then stop .


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
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
;
}

Reads a marker byte from the input stream.

Reads a marker byte from the input stream .


protected void writeMarker(DataOutputStream sink, byte marker) throws IOException {
        //for(int i=0; i<4; i++)
        sink.writeByte(marker);
        sink.writeByte((byte) 0);
        sink.writeByte((byte) 0);
        sink.writeByte((byte) 0);
    }

protected
void
writeMarker
(
DataOutputStream
sink
,
byte
marker
)
throws
IOException
{
//for(int i=0; i<4; i++)
sink
.
writeByte
(
marker
)
;
sink
.
writeByte
(
(
byte
)
0
)
;
sink
.
writeByte
(
(
byte
)
0
)
;
sink
.
writeByte
(
(
byte
)
0
)
;
}

Writes a marker byte to the output stream.

Writes a marker byte to the output stream .


@Override
    public void fatalError(SAXParseException e)
            throws SAXException
    {
        throw new SAXParseException(
                String.format("Sax fatal error: %s; %s%n", e, report(this.locator)),
                this.locator);
    }

@
Override
public
void
fatalError
(
SAXParseException
e
)
throws
SAXException
{
throw
new
SAXParseException
(
String
.
format
(
"Sax fatal error: %s; %s%n"
,
e
,
report
(
this
.
locator
)
)
,
this
.
locator
)
;
}


private static TimeSeries createDataset(String name, double base,
          RegularTimePeriod start, int count) {

    TimeSeries series = new TimeSeries(name, start.getClass());
    RegularTimePeriod period = start;
    double value = base;
    for (int i = 0; i < count; i++) {
      series.add(period, value);
      period = period.next();
      value = value * (1 + (Math.random() - 0.495) / 10.0);
    }
    return series;

  }

private static TimeSeries createDataset ( String name , double base , RegularTimePeriod start , int count ) { TimeSeries series = new TimeSeries ( name , start . getClass ( ) ) ; RegularTimePeriod period = start ; double value = base ; for ( int i = 0 ; i < count ; i ++ ) { series . add ( period , value ) ; period = period . next ( ) ; value = value * ( 1 + ( Math . random ( ) - 0.495 ) / 10.0 ) ; } return series ; }

Creates the demo chart.

@return The chart.

private JFreeChart createChart() {

XYDataset dataset1 = createDataset("Series 1", 100.0, new Minute(), 200);

JFreeChart chart = ChartFactory.createTimeSeriesChart(
"Multiple Axis Demo 1",
"Time of Day",
"Primary Range Axis",
dataset1,
true,
true,
false
);

chart.addSubtitle(new TextTitle("Four datasets and four range axes."));
XYPlot plot = (XYPlot) chart.getPlot();
plot.setOrientation(PlotOrientation.VERTICAL);

plot.getRangeAxis().setFixedDimension(15.0);

AXIS 2
NumberAxis axis2 = new NumberAxis("Range Axis 2");
axis2.setFixedDimension(10.0);
axis2.setAutoRangeIncludesZero(false);
plot.setRangeAxis(1, axis2);
plot.setRangeAxisLocation(1, AxisLocation.BOTTOM_OR_LEFT);

XYDataset dataset2 = createDataset("Series 2", 1000.0, new Minute(),
170);
plot.setDataset(1, dataset2);
plot.mapDatasetToRangeAxis(1, 1);
XYItemRenderer renderer2 = new StandardXYItemRenderer();
plot.setRenderer(1, renderer2);

AXIS 3
NumberAxis axis3 = new NumberAxis("Range Axis 3");
plot.setRangeAxis(2, axis3);

XYDataset dataset3 = createDataset("Series 3", 10000.0, new Minute(),
170);
plot.setDataset(2, dataset3);
plot.mapDatasetToRangeAxis(2, 2);
XYItemRenderer renderer3 = new StandardXYItemRenderer();
plot.setRenderer(2, renderer3);

AXIS 4
NumberAxis axis4 = new NumberAxis("Range Axis 4");
plot.setRangeAxis(3, axis4);

XYDataset dataset4 = createDataset("Series 4", 25.0, new Minute(), 200);
plot.setDataset(3, dataset4);
plot.mapDatasetToRangeAxis(3, 3);

XYItemRenderer renderer4 = new StandardXYItemRenderer();
plot.setRenderer(3, renderer4);

ChartUtilities.applyCurrentTheme(chart);

change the series and axis colours after the theme has
been applied...
plot.getRenderer().setSeriesPaint(0, Color.black);
renderer2.setSeriesPaint(0, Color.red);
axis2.setLabelPaint(Color.red);
axis2.setTickLabelPaint(Color.red);
renderer3.setSeriesPaint(0, Color.blue);
axis3.setLabelPaint(Color.blue);
axis3.setTickLabelPaint(Color.blue);
renderer4.setSeriesPaint(0, Color.green);
axis4.setLabelPaint(Color.green);
axis4.setTickLabelPaint(Color.green);

return chart;
}

Creates a sample dataset.

@param name  the dataset name.
@param base  the starting value.
@param start the starting period.
@param count the number of values to generate.
@return The dataset.


public static void main(String[] args) {

    TimeSeries dataset1 = createDataset("Series 1", 100.0, new Minute(), 200);

    MultipleAxisChart demo = new MultipleAxisChart(
            "Multiple Axis Demo 1",
            "Time of Day",
            "Primary Range Axis",
            dataset1);

    /* AXIS 2
    NumberAxis axis2 = new NumberAxis("Range Axis 2");
    axis2.setFixedDimension(10.0);
    axis2.setAutoRangeIncludesZero(false);
    plot.setRangeAxis(1, axis2);
    plot.setRangeAxisLocation(1, AxisLocation.BOTTOM_OR_LEFT); /

    plot.setDataset(1, dataset2);
    plot.mapDatasetToRangeAxis(1, 1);
    XYItemRenderer renderer2 = new StandardXYItemRenderer();
    plot.setRenderer(1, renderer2); */

    TimeSeries dataset2 = createDataset("Series 2", 1000.0, new Minute(), 170);
    demo.addSeries("Range Axis 2", dataset2);

    /*     // AXIS 3
    NumberAxis axis3 = new NumberAxis("Range Axis 3");
    plot.setRangeAxis(2, axis3);

    XYDataset dataset3 = createDataset("Series 3", 10000.0, new Minute(), 170);
    plot.setDataset(2, dataset3);
    plot.mapDatasetToRangeAxis(2, 2);
    XYItemRenderer renderer3 = new StandardXYItemRenderer();
    plot.setRenderer(2, renderer3);
    */
    TimeSeries dataset3 = createDataset("Series 3", 10000.0, new Minute(), 170);
    demo.addSeries("Range Axis 3", dataset3);

    /* AXIS 4
    NumberAxis axis4 = new NumberAxis("Range Axis 4");
    plot.setRangeAxis(3, axis4);

    XYDataset dataset4 = createDataset("Series 4", 25.0, new Minute(), 200);
    plot.setDataset(3, dataset4);
    plot.mapDatasetToRangeAxis(3, 3);

    XYItemRenderer renderer4 = new StandardXYItemRenderer();
    plot.setRenderer(3, renderer4); */
    TimeSeries dataset4 = createDataset("Series 4", 25.0, new Minute(), 200);
    demo.addSeries("Range Axis 4", dataset4);

    demo.finish(new java.awt.Dimension(600, 270));

    JFrame frame = new JFrame("Demovabulous ");
    frame.getContentPane().add(demo, BorderLayout.CENTER);
    frame.setSize(640, 480);
    frame.setVisible(true);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  }

Starting point for the demonstration application.

@param args ignored.

Starting point for the demonstration application .


public String[] getJavaArrayString(StructureMembers.Member m) {
    if (m.getDataType() == DataType.STRING) {
      Array data = getArray(m);
      int n = m.getSize();
      String[] result = new String[n];
      for (int i = 0; i < result.length; i++)
        result[i] = (String) data.getObject(i);
      return result;

    } else if (m.getDataType() == DataType.CHAR) {
      ArrayChar data = (ArrayChar) getArray(m);
      ArrayChar.StringIterator iter = data.getStringIterator();
      String[] result = new String[iter.getNumElems()];
      int count = 0;
      while (iter.hasNext())
        result[count++] = iter.next();
      return result;
    }

    throw new IllegalArgumentException("getJavaArrayString: not String DataType :" + m.getDataType());
  }


public DoradePARM[] getParamList() {
        int paramCount = 0;
        for (int i = 0; i < nSensors; i++)
            paramCount += myRADDs[i].getNParams();

        DoradePARM[] list = new DoradePARM[paramCount];
        int next = 0;
        for (int i = 0; i < nSensors; i++) {
            int nParams = myRADDs[i].getNParams();
            System.arraycopy(myRADDs[i].getParamList(), 0, list, next, nParams);
            next += nParams;
        }
        return list;
    }

public DoradePARM [ ] getParamList ( ) { int paramCount = 0 ; for ( int i = 0 ; i < nSensors ; i ++ ) paramCount += myRADDs [ i ] . getNParams ( ) ; DoradePARM [ ] list = new DoradePARM [ paramCount ] ; int next = 0 ; for ( int i = 0 ; i < nSensors ; i ++ ) { int nParams = myRADDs [ i ] . getNParams ( ) ; System . arraycopy ( myRADDs [ i ] . getParamList ( ) , 0 , list , next , nParams ) ; next += nParams ; } return list ; }

Get the array of available parameter names for this volume.
@return an array of parameter names

Get the array of available parameter names for this volume .


public void setStations(java.util.List stns) {
    stnRender.setStations(stns);
    redraw(true);
  }

public void setStations ( java . util . List stns ) { stnRender . setStations ( stns ) ; redraw ( true ) ; }

Set the list of Stations.

@param stns list of Station


public void setSelectedStation(String id) {
    stnRender.setSelectedStation(id);
    selectedStation = stnRender.getSelectedStation();
    assert selectedStation != null;
    np.setLatLonCenterMapArea(selectedStation.getLatitude(), selectedStation.getLongitude());
    redraw();
  }

public void setSelectedStation ( String id ) { stnRender . setSelectedStation ( id ) ; selectedStation = stnRender . getSelectedStation ( ) ; assert selectedStation != null ; np . setLatLonCenterMapArea ( selectedStation . getLatitude ( ) , selectedStation . getLongitude ( ) ) ; redraw ( ) ; }

Looks for the station with given id. If found, makes it current. Redraws.

@param id must match stationIF.getID().

Looks for the station with given id . If found makes it current . Redraws .


protected void redraw() {
    long tstart = System.currentTimeMillis();

    java.awt.Graphics2D gNP = np.getBufferedImageGraphics();
    if (gNP == null) // panel not drawn on screen yet
      return;

    // clear it
    gNP.setBackground(np.getBackgroundColor());
    java.awt.Rectangle r = gNP.getClipBounds();
    gNP.clearRect(r.x, r.y, r.width, r.height);

    if (regionSelect && geoSelectionMode) {
      if (geoSelection != null) drawBB(gNP, geoSelection, Color.cyan);
      if (geoBounds != null) drawBB(gNP, geoBounds, null);
      // System.out.println("GeoRegionChooser.redraw geoBounds= "+geoBounds);

      if (geoSelection != null) {
        // gNP.setColor( Color.orange);
        Navigation navigate = np.getNavigation();
        double handleSize = RubberbandRectangleHandles.handleSizePixels / navigate.getPixPerWorld();
        Rectangle2D rect = new Rectangle2D.Double(geoSelection.getX(), geoSelection.getY(), geoSelection.getWidth(), geoSelection.getHeight());
        RubberbandRectangleHandles.drawHandledRect(gNP, rect, handleSize);
        if (debug) System.out.println("GeoRegionChooser.drawHandledRect=" + handleSize + " = " + geoSelection);
      }
    }

    for (int i = 0; i < renderers.size(); i++) {
      ucar.nc2.ui.util.Renderer rend = (Renderer) renderers.get(i);
      rend.draw(gNP, atI);
    }
    gNP.dispose();

    if (debug) {
      long tend = System.currentTimeMillis();
      System.out.println("StationRegionDateChooser draw time = " + (tend - tstart) / 1000.0 + " secs");
    }

    // copy buffer to the screen
    np.repaint();
  }


private void readObject(ObjectInputStream s)
          throws IOException, ClassNotFoundException {
    double x = s.readDouble();
    double y = s.readDouble();
    double w = s.readDouble();
    double h = s.readDouble();
    setRect(x, y, w, h);
  }

private void readObject ( ObjectInputStream s ) throws IOException , ClassNotFoundException { double x = s . readDouble ( ) ; double y = s . readDouble ( ) ; double w = s . readDouble ( ) ; double h = s . readDouble ( ) ; setRect ( x , y , w , h ) ; }

Read the object from the input stream of the serialized object

@param s stream to read
@throws ClassNotFoundException couldn't file the class
@throws IOException            Problem reading from stream


private void writeObject(ObjectOutputStream s) throws IOException {
    s.writeDouble(getX());
    s.writeDouble(getY());
    s.writeDouble(getWidth());
    s.writeDouble(getHeight());
  }

private void writeObject ( ObjectOutputStream s ) throws IOException { s . writeDouble ( getX ( ) ) ; s . writeDouble ( getY ( ) ) ; s . writeDouble ( getWidth ( ) ) ; s . writeDouble ( getHeight ( ) ) ; }

Wrtie the object to the output stream

@param s stream to write
@throws IOException Problem writing to stream


public void add(final UnitDBImpl that) throws UnitExistsException {
		unitSet.addAll(that.unitSet);
		nameMap.putAll(that.nameMap);
		symbolMap.putAll(that.symbolMap);
	}

public void add ( final UnitDBImpl that ) throws UnitExistsException { unitSet . addAll ( that . unitSet ) ; nameMap . putAll ( that . nameMap ) ; symbolMap . putAll ( that . symbolMap ) ; }

Adds all the entries in another UnitDBImpl to this database.

@param that
The other UnitDBImpl.
@throws UnitExistsException
Attempt to redefine an existing entry.

Adds all the entries in another UnitDBImpl to this database .


public void addUnit(final Unit unit) throws UnitExistsException,
			NameException {
		if (unit.getName() == null) {
			throw new NameException("Unit name can't be null");
		}
		addByName(unit.getName(), unit);
		addByName(unit.getPlural(), unit);
		addBySymbol(unit.getSymbol(), unit);
		unitSet.add(unit);
	}

public
void
addUnit
(
final
Unit
unit
)
throws
UnitExistsException
,
NameException
{
if
(
unit
.
getName
(
)
==
)
{
throw
new
NameException
(
"Unit name can't be null"
)
;
}
addByName
(
unit
.
getName
(
)
,
unit
)
;
addByName
(
unit
.
getPlural
(
)
,
unit
)
;
addBySymbol
(
unit
.
getSymbol
(
)
,
unit
)
;
unitSet
.
add
(
unit
)
;
}

Adds a unit to the database.

@param unit
The unit to be added.
@throws UnitExistsException
Another unit with the same name or symbol already exists in
the database.
@throws NameException
Bad unit name.


public final void addSymbol(final String symbol, final String name)
			throws NoSuchUnitException, UnitExistsException {
		addAlias(null, name, symbol, null);
	}

public final void addSymbol ( final String symbol , final String name ) throws NoSuchUnitException , UnitExistsException { addAlias ( null , name , symbol , null ) ; }

Adds a symbol for a unit already in the database.

@param symbol
The symbol for the unit.
@param name
The name of the unit already in the database.
@throws UnitExistsException
Another unit with the same name or symbol already exists in
the database.
@throws NoSuchUnitException
The unit isn't in the database.

Adds a symbol for a unit already in the database .


public Unit get(final String id) {
		Unit unit = getBySymbol(id);
		if (unit == null) {
			unit = getByName(id);
		}
		return unit;
	}

public Unit get ( final String id ) { Unit unit = getBySymbol ( id ) ; if ( unit == null ) { unit = getByName ( id ) ; } return unit ; }

Gets a unit by either name, plural, or symbol. Retrieving the unit by
symbol is attempted before retrieving the unit by name because symbol
comparisons are case sensitive and, hence, should be more robust.

@param id
The id to be matched.
@return The unit whose name, plural, or symbol matches or
null if no such unit was found.

Gets a unit by either name plural or symbol . Retrieving the unit by symbol is attempted before retrieving the unit by name because symbol comparisons are case sensitive and hence should be more robust .


private final void addByName(final String name, final Unit newUnit)
			throws UnitExistsException {
		if (name != null) {
			addUnique(nameMap, canonicalize(name), newUnit);
		}
	}

private final void addByName ( final String name , final Unit newUnit ) throws UnitExistsException { if ( name != null ) { addUnique ( nameMap , canonicalize ( name ) , newUnit ) ; } }

Adds a unit to the database by name.

@param name
The name of the unit. If null then the unit is
not added.
@param newUnit
The unit to be added.
@throws UnitExistsException
Attempt to redefine an existing unit.


private final void addBySymbol(final String symbol, final Unit newUnit)
			throws UnitExistsException {
		if (symbol != null) {
			addUnique(symbolMap, symbol, newUnit);
		}
	}

private final void addBySymbol ( final String symbol , final Unit newUnit ) throws UnitExistsException { if ( symbol != null ) { addUnique ( symbolMap , symbol , newUnit ) ; } }

Adds a unit to the database by symbol.

@param symbol
The symbol for the unit. If null then the unit is
not added.
@param newUnit
The unit to be added.
@throws UnitExistsException
Attempt to redefine an existing unit.


private static final void addUnique(final Map<String, Unit> map,
			final String key, final Unit newUnit) throws UnitExistsException {
		final Unit oldUnit = map.put(key, newUnit);
		if (oldUnit != null && !oldUnit.equals(newUnit)) {
			throw new UnitExistsException(oldUnit, newUnit);
		}
	}

private static final void addUnique ( final Map < String , Unit > map , final String key , final Unit newUnit ) throws UnitExistsException { final Unit oldUnit = map . put ( key , newUnit ) ; if ( oldUnit != null && ! oldUnit . equals ( newUnit ) ) { throw new UnitExistsException ( oldUnit , newUnit ) ; } }

Adds a unique unit to a map..

@param map
The map to be added to.
@param key
The key for the unit entry.
@param newUnit
The unit to be added.
@throws UnitExistsException
Attempt to redefine an existing unit.


public void addToMenu(final JMenu menu) {
        final UIManager.LookAndFeelInfo[] plafInfo = UIManager.getInstalledLookAndFeels();
        for (UIManager.LookAndFeelInfo aPlafInfo : plafInfo) {
            addToMenu(aPlafInfo.getName(), aPlafInfo.getClassName(), menu);
        }

        final LookAndFeel current = UIManager.getLookAndFeel();
        System.out.printf("current L&F=%s%n", current.getName());
    }

public
void
addToMenu
(
final
JMenu
menu
)
{
final
UIManager
.
LookAndFeelInfo
[
]
plafInfo
=
UIManager
.
getInstalledLookAndFeels
(
)
;
for
(
UIManager
.
LookAndFeelInfo
aPlafInfo
:
plafInfo
)
{
addToMenu
(
aPlafInfo
.
getName
(
)
,
aPlafInfo
.
getClassName
(
)
,
menu
)
;
}
final
LookAndFeel
current
=
UIManager
.
getLookAndFeel
(
)
;
System
.
out
.
printf
(
"current L&F=%s%n"
,
current
.
getName
(
)
)
;
}

Add a set of MenuItems to the given JMenu, one for each possible L&F.
if this platform doesnt support the L&F, disable the MenuItem.

Add a set of MenuItems to the given JMenu one for each possible L&F . if this platform doesnt support the L&F disable the MenuItem .


@Nullable
  public static Grib2Record findRecordByDrspos(RandomAccessFile raf, long drsPos) throws IOException {
    long pos = Math.max(0, drsPos- (20*1000)); // go back 20K
    Grib2RecordScanner scan = new Grib2RecordScanner(raf, pos);
    while (scan.hasNext()) {
      ucar.nc2.grib.grib2.Grib2Record gr = scan.next();
      Grib2SectionDataRepresentation drs = gr.getDataRepresentationSection();
      if (drsPos == drs.getStartingPosition()) return gr;
      if (raf.getFilePointer() > drsPos) break;   // missed it.
    }
    return null;
  }

@
Nullable
public
static
Grib2Record
findRecordByDrspos
(
RandomAccessFile
raf
,
long
drsPos
)
throws
IOException
{
long
pos
=
Math
.
max
(
0
,
drsPos
(
20
*
1000
)
)
;
// go back 20K
Grib2RecordScanner
scan
=
new
Grib2RecordScanner
(
raf
,
pos
)
;
while
(
scan
.
hasNext
(
)
)
{
ucar
.
nc2
.
grib
.
grib2
.
Grib2Record
gr
=
scan
.
next
(
)
;
Grib2SectionDataRepresentation
drs
=
gr
.
getDataRepresentationSection
(
)
;
if
(
drsPos
==
drs
.
getStartingPosition
(
)
)
return
gr
;
if
(
raf
.
getFilePointer
(
)
>
drsPos
)
break
;
// missed it.
}
return
;
}

tricky bit of business. recapture the entire record based on drs position.
for validation.
@param raf             from this RandomAccessFile
@param drsPos          Grib2SectionDataRepresentation starts here

tricky bit of business . recapture the entire record based on drs position . for validation .


public boolean read(String datasetName, Object specialO) throws NoSuchVariableException,
    IOException {

    // read the scalar structure into memory
    StructureData sdata = ncVar.readStructure();
    setData( sdata);
    return(false);
  }


public void serialize(String dataset,DataOutputStream sink,CEEvaluator ce,Object specialO)
                                    throws NoSuchVariableException, DAP2ServerSideException, IOException {

    if (org == null) {
      super.serialize(dataset, sink, ce, specialO);
      return;
    }

    // use the projection info in the original
    java.util.Enumeration vars = org.getVariables();

    // run through each structure member
    StructureMembers sm = sdata.getStructureMembers();

    int count = 0;
    while (vars.hasMoreElements()) {
      HasNetcdfVariable sm_org = (HasNetcdfVariable) vars.nextElement();
      boolean isProjected = ((ServerMethods) sm_org).isProject();
      if (isProjected) {
        StructureMembers.Member m = sm.getMember(count);
        sm_org.serialize( sink, sdata, m);
      }
      count++;
    }

  }