signature:
public class CoreTypeFcns { /** * Force a numeric value to be in a specified range
 * Only defined for simple integers ( ValueClass LONG )
 * WARNING : unsigned values are forced into the
 * signed size , but the proper bit pattern is maintained .
 * The term " force " means that if the value is outside the typed
 * min / max values , it is pegged to the min or max value depending
 * on the sign . Note that truncation is not used .
 * @ param basetype the type to force value to in range
 * @ param value the value to force
 * @ return forced value
 * @ throws ConversionException if forcing is not possible */
static public long forceRange ( TypeSort basetype , long value ) { } }

implementation:
assert basetype . isIntegerType ( ) : "Internal error" ; switch ( basetype ) { case Char : value = minmax ( value , 0 , 255 ) ; break ; case Int8 : value = minmax ( value , ( long ) Byte . MIN_VALUE , ( long ) Byte . MAX_VALUE ) ; break ; case UInt8 : value = value & 0xFFL ; break ; case Int16 : value = minmax ( value , ( long ) Short . MIN_VALUE , ( long ) Short . MAX_VALUE ) ; break ; case UInt16 : value = value & 0xFFFFL ; break ; case Int32 : value = minmax ( value , ( long ) Integer . MIN_VALUE , ( long ) Integer . MAX_VALUE ) ; break ; case UInt32 : value = value & 0xFFFFFFFFL ; break ; case Int64 : case UInt64 : break ; // value = value case Int64:
default : } return value ;


signature:
public class CoreTypeFcns { /** * Peg a value to either the min or max
 * depending on sign .
 * @ param value the value to peg
 * @ param min peg to this if value is < min
 * @ param max peg to this if value is > max
 * @ return pegg ' ed value */
static protected long minmax ( long value , long min , long max ) { } }

implementation: if ( value < min ) return min ; if ( value > max ) return max ; return value ;


signature:
public class TdsPathUtils { /** * For " removePrefix / path " style servlet mappings . */
public static String extractPath ( HttpServletRequest req , String removePrefix ) { } }

implementation:
// may be in pathInfo ( Servlet ) or servletPath ( Controller )
String dataPath = req . getPathInfo ( ) ; if ( dataPath == null ) { dataPath = req . getServletPath ( ) ; } if ( dataPath == null ) // not sure if this is possible
return "" ; // removePrefix or " / " + removePrefix
if ( removePrefix != null ) { if ( dataPath . startsWith ( removePrefix ) ) { dataPath = dataPath . substring ( removePrefix . length ( ) ) ; } else if ( dataPath . startsWith ( "/" ) ) { dataPath = dataPath . substring ( 1 ) ; if ( dataPath . startsWith ( removePrefix ) ) dataPath = dataPath . substring ( removePrefix . length ( ) ) ; } } if ( dataPath . startsWith ( "/" ) ) dataPath = dataPath . substring ( 1 ) ; if ( dataPath . contains ( ".." ) ) // LOOK what about escapes ? ?
throw new IllegalArgumentException ( "path cannot contain '..'" ) ; return dataPath ;


signature: public class TdsPathUtils { public static String getFileNameForResponse ( String pathInfo , NetcdfFileWriter . Version version ) { } }

implementation: Preconditions . checkNotNull ( version , "version == null" ) ; return getFileNameForResponse ( pathInfo , version . getSuffix ( ) ) ;


signature:
public class Vis5DGridDefRecord { /** * _ more _
 * @ param Projection _ more _
 * @ param projargs _ more _ */
public static void printProjArgs ( int Projection , double [ ] projargs ) { } }

implementation:
double NorthBound ; double SouthBound ; double WestBound ; double EastBound ; double RowInc ; double ColInc ; double Lat1 ; double Lat2 ; double PoleRow ; double PoleCol ; double CentralLat ; double CentralLon ; double CentralRow ; double CentralCol ; double Rotation ; /* radians */
double Cone ; double Hemisphere ; double ConeFactor ; double CosCentralLat ; double SinCentralLat ; double StereoScale ; double InvScale ; double CylinderScale ; switch ( Projection ) { case PROJ_GENERIC : case PROJ_LINEAR : case PROJ_CYLINDRICAL : case PROJ_SPHERICAL : NorthBound = projargs [ 0 ] ; WestBound = projargs [ 1 ] ; RowInc = projargs [ 2 ] ; ColInc = projargs [ 3 ] ; System . out . println ( "Generic, Linear, Cylindrical, Spherical:" ) ; System . out . println ( "NB: " + NorthBound + ", WB: " + WestBound + ", rowInc: " + RowInc + ", colInc: " + ColInc ) ; break ; case PROJ_ROTATED : NorthBound = projargs [ 0 ] ; WestBound = projargs [ 1 ] ; RowInc = projargs [ 2 ] ; ColInc = projargs [ 3 ] ; CentralLat = projargs [ 4 ] ; CentralLon = projargs [ 5 ] ; Rotation = projargs [ 6 ] ; System . out . println ( "Rotated:" ) ; System . out . println ( "NB: " + NorthBound + ", WB: " + WestBound + ", rowInc: " + RowInc + ", colInc: " + ColInc + ", clat: " + CentralLat + ", clon: " + CentralLon + ", rotation: " + Rotation ) ; break ; case PROJ_LAMBERT : Lat1 = projargs [ 0 ] ; Lat2 = projargs [ 1 ] ; PoleRow = projargs [ 2 ] ; PoleCol = projargs [ 3 ] ; CentralLon = projargs [ 4 ] ; ColInc = projargs [ 5 ] ; System . out . println ( "Lambert: " ) ; System . out . println ( "lat1: " + Lat1 + ", lat2: " + Lat2 + ", poleRow: " + PoleRow + ", PoleCol: " + PoleCol + ", clon: " + CentralLon + ", colInc: " + ColInc ) ; break ; case PROJ_STEREO : CentralLat = projargs [ 0 ] ; CentralLon = projargs [ 1 ] ; CentralRow = projargs [ 2 ] ; CentralCol = projargs [ 3 ] ; ColInc = projargs [ 4 ] ; System . out . println ( "Stereo: " ) ; System . out . println ( "clat: " + CentralLat + ", clon: " + CentralLon + ", cRow: " + CentralRow + ", cCol: " + CentralCol + ", colInc: " + ColInc ) ; break ; default : System . out . println ( "Projection unknown" ) ; }


signature:
public class CEConstraint { /** * Evaluate a filter with respect to a Sequence record .
 * Assumes the filter has been canonicalized so that
 * the lhs is a variable .
 * @ param seq the template
 * @ param record the record to evaluate
 * @ param expr the filter
 * @ throws DapException
 * @ returns the value of the expression ( usually a Boolean ) */
protected Object eval ( DapVariable var , DapSequence seq , DataCursor record , CEAST expr ) throws DapException { } }

implementation: switch ( expr . sort ) { case CONSTANT : return expr . value ; case SEGMENT : return fieldValue ( var , seq , record , expr . name ) ; case EXPR : Object lhs = eval ( var , seq , record , expr . lhs ) ; Object rhs = ( expr . rhs == null ? null : eval ( var , seq , record , expr . rhs ) ) ; if ( rhs != null ) switch ( expr . op ) { case LT : return compare ( lhs , rhs ) < 0 ; case LE : return compare ( lhs , rhs ) <= 0 ; case GT : return compare ( lhs , rhs ) > 0 ; case GE : return compare ( lhs , rhs ) >= 0 ; case EQ : return lhs . equals ( rhs ) ; case NEQ : return ! lhs . equals ( rhs ) ; case REQ : return lhs . toString ( ) . matches ( rhs . toString ( ) ) ; case AND : return ( ( Boolean ) lhs ) && ( ( Boolean ) rhs ) ; } else switch ( expr . op ) { case NOT : return ! ( ( Boolean ) lhs ) ; } } throw new DapException ( "Malformed Filter" ) ;


signature:
public class CEConstraint { /** * Convert the view to a constraint string suitable
 * for use in a URL , except not URL encoded .
 * @ return constraint string */
public String toConstraintString ( ) { } }

implementation: StringBuilder buf = new StringBuilder ( ) ; boolean first = true ; for ( int i = 0 ; i < segments . size ( ) ; i ++ ) { Segment seg = segments . get ( i ) ; if ( ! seg . var . isTopLevel ( ) ) continue ; if ( ! first ) buf . append ( ";" ) ; first = false ; dumpvar ( seg , buf , true ) ; } return buf . toString ( ) ;


signature:
public class CEConstraint { /** * Recursive helper for tostring / toConstraintString
 * @ param seg
 * @ param buf
 * @ param forconstraint */
protected void dumpvar ( Segment seg , StringBuilder buf , boolean forconstraint ) { } }

implementation:
if ( seg . var . isTopLevel ( ) ) buf . append ( seg . var . getFQN ( ) ) ; else buf . append ( seg . var . getShortName ( ) ) ; List < DapDimension > dimset = seg . var . getDimensions ( ) ; // Add any slices
List < Slice > slices = seg . slices ; if ( slices == null ) dimset = new ArrayList < DapDimension > ( ) ; else assert ( dimset . size ( ) == 0 && DapUtil . isScalarSlices ( slices ) ) || ( dimset . size ( ) == slices . size ( ) ) ; for ( int i = 0 ; i < dimset . size ( ) ; i ++ ) { Slice slice = slices . get ( i ) ; DapDimension dim = dimset . get ( i ) ; try { buf . append ( forconstraint ? slice . toConstraintString ( ) : slice . toString ( ) ) ; } catch ( DapException de ) { } } DapType basetype = seg . var . getBaseType ( ) ; // if the var is atomic , then we are done
if ( basetype . isAtomic ( ) ) return ; // If structure and all fields are in the view , then done
if ( basetype . getTypeSort ( ) . isCompound ( ) ) { DapStructure struct = ( DapStructure ) basetype ; if ( ! isWholeCompound ( struct ) ) { // Need to insert { . . . } and recurse
buf . append ( LBRACE ) ; boolean first = true ; for ( DapVariable field : struct . getFields ( ) ) { if ( ! first ) buf . append ( ";" ) ; first = false ; Segment fseg = findSegment ( field ) ; dumpvar ( fseg , buf , forconstraint ) ; } buf . append ( RBRACE ) ; } if ( basetype . getTypeSort ( ) . isSeqType ( ) && seg . filter != null ) { buf . append ( "|" ) ; buf . append ( seg . filter . toString ( ) ) ; } }


signature:
public class CEConstraint { /** * Reference X match
 * @ param node to test
 * @ return true if node is referenced by this constraint */
public boolean references ( DapNode node ) { } }

implementation: boolean isref = false ; switch ( node . getSort ( ) ) { case DIMENSION : DapDimension dim = this . redef . get ( ( DapDimension ) node ) ; if ( dim == null ) dim = ( DapDimension ) node ; isref = this . dimrefs . contains ( dim ) ; break ; case ENUMERATION : isref = ( this . enums . contains ( ( DapEnumeration ) node ) ) ; break ; case VARIABLE : isref = ( findVariableIndex ( ( DapVariable ) node ) >= 0 ) ; break ; case GROUP : case DATASET : isref = ( this . groups . contains ( ( DapGroup ) node ) ) ; break ; default : break ; } return isref ;


signature:
public class CEConstraint { /** * Selection X match
 * Evaluate a filter with respect to a Sequence record .
 * Assumes the filter has been canonicalized .
 * @ param seq the template
 * @ param rec the record to evaluate
 * @ throws DapException
 * @ returns true if the filter matches the record */
public boolean match ( DapVariable sqvar , DapSequence seq , DataCursor rec ) throws DapException { } }

implementation: Segment sseq = findSegment ( sqvar ) ; if ( sseq == null ) return false ; CEAST filter = sseq . filter ; if ( filter == null ) return true ; return matches ( sqvar , seq , rec , filter ) ;


signature:
public class CEConstraint { /** * Evaluate a filter with respect to a Sequence record .
 * @ param seq the template
 * @ param rec the record to evaluate
 * @ param filter the filter
 * @ throws DapException
 * @ returns true if a match */
protected boolean matches ( DapVariable var , DapSequence seq , DataCursor rec , CEAST filter ) throws DapException { } }

implementation: Object value = eval ( var , seq , rec , filter ) ; return ( ( Boolean ) value ) ;


signature:
public class CEConstraint { /** * / * Search the set of variables */
protected int findVariableIndex ( DapVariable var ) { } }

implementation: for ( int i = 0 ; i < variables . size ( ) ; i ++ ) { if ( variables . get ( i ) == var ) return i ; } return - 1 ;


signature:
public class CEConstraint { /** * Locate each unexpanded Structure | Sequence and :
 * 1 . check that none of its fields is referenced = > do not expand
 * 2 . add all of its fields as leaves
 * Note that # 2 may end up adding additional leaf structs & / or seqs */
public void expand ( ) { } }

implementation:
// Create a queue of unprocessed leaf compounds
Queue < DapVariable > queue = new ArrayDeque < DapVariable > ( ) ; for ( int i = 0 ; i < variables . size ( ) ; i ++ ) { DapVariable var = variables . get ( i ) ; if ( ! var . isTopLevel ( ) ) continue ; // prime the queue
DapType base = var . getBaseType ( ) ; if ( base . getTypeSort ( ) . isCompound ( ) ) { DapStructure struct = ( DapStructure ) base ; // remember Sequence subclass Structure
if ( expansionCount ( struct ) == 0 ) queue . add ( var ) ; } } // Process the queue in prefix order
while ( queue . size ( ) > 0 ) { DapVariable vvstruct = queue . remove ( ) ; DapStructure dstruct = ( DapStructure ) vvstruct . getBaseType ( ) ; for ( DapVariable field : dstruct . getFields ( ) ) { if ( findVariableIndex ( field ) < 0 ) { // Add field as leaf
this . segments . add ( new Segment ( field ) ) ; this . variables . add ( field ) ; } DapType fbase = field . getBaseType ( ) ; if ( fbase . getTypeSort ( ) . isCompound ( ) ) { if ( expansionCount ( ( DapStructure ) fbase ) == 0 ) queue . add ( field ) ; } } } this . expansion = Expand . EXPANDED ;


signature:
public class CEConstraint { /** * Locate each Structure | Sequence and :
 * 1 . check that all of its fields are referenced recursively and not constrained ,
 * otherwise ignore
 * 2 . contract by removing all of the fields of the Structure or Sequence .
 * This is intended to be ( not quite ) the dual of expand ( ) ; */
public void contract ( ) { } }

implementation:
// Create a set of contracted compounds
Set < DapStructure > contracted = new HashSet < > ( ) ; for ( int i = 0 ; i < variables . size ( ) ; i ++ ) { DapVariable var = variables . get ( i ) ; if ( var . isTopLevel ( ) ) { DapType base = var . getBaseType ( ) ; if ( base . getTypeSort ( ) . isCompound ( ) ) { contractR ( ( DapStructure ) base , contracted ) ; } } } this . expansion = Expand . CONTRACTED ;


signature:
public class CEConstraint { /** * Recursive helper
 * @ param dstruct to contract
 * @ param contracted set of already contracted compounds
 * @ return true if this structure was contracted , false otherwise */
protected boolean contractR ( DapStructure dstruct , Set < DapStructure > contracted ) { } }

implementation:
if ( contracted . contains ( dstruct ) ) return true ; int processed = 0 ; List < DapVariable > fields = dstruct . getFields ( ) ; for ( DapVariable field : fields ) { if ( findVariableIndex ( field ) < 0 ) break ; // this compound cannot be contracted
DapType base = field . getBaseType ( ) ; if ( base . getTypeSort ( ) . isCompound ( ) && ! contracted . contains ( ( field ) ) ) { if ( ! contractR ( ( DapStructure ) base , contracted ) ) break ; // this compound cannot be contracted
} processed ++ ; } if ( processed < fields . size ( ) ) return false ; contracted . add ( dstruct ) ; // all compound fields were successfully contracted .
return true ;


signature:
public class CEConstraint { /** * Count the number of fields of a structure that
 * already in this view .
 * @ param struct the dapstructure to check
 * @ return # of fields in this view
 * @ throws DapException */
protected int expansionCount ( DapStructure struct ) { } }

implementation: int count = 0 ; for ( DapVariable field : struct . getFields ( ) ) { if ( findVariableIndex ( field ) >= 0 ) count ++ ; } return count ;


signature:
public class CEConstraint { /** * See if a structure is " whole " , which
 * means that none of its fields is missing from the
 * constraint , all of fields use default ( non - constrained )
 * dimension ) , and all of its fields are also whole .
 * This must be done recursively .
 * @ param dstruct to test
 * @ return true if this structure is whole . */
protected boolean isWholeCompound ( DapStructure dstruct ) { } }

implementation:
int processed = 0 ; List < DapVariable > fields = dstruct . getFields ( ) ; for ( DapVariable field : fields ) { // not contractable if this field has non - original dimensions
Segment seg = findSegment ( field ) ; if ( seg == null ) break ; // this compound is not whole
List < Slice > slices = seg . slices ; if ( slices != null ) { for ( Slice slice : slices ) { if ( slice . isConstrained ( ) ) break ; } } DapType base = field . getBaseType ( ) ; if ( base . getTypeSort ( ) . isCompound ( ) ) { if ( ! isWholeCompound ( ( DapStructure ) base ) ) break ; // this compound is not whole
} processed ++ ; } return ( processed == fields . size ( ) ) ;


signature:
public class CEConstraint { /** * Compute dimension related information
 * using slicing and redef info .
 * In effect , this is where projection constraints
 * are applied
 * Assume that the constraint compiler has given us the following info :
 * < ol >
 * < li > A list of the variables to include .
 * < li > A pair ( DapDimension , Slice ) for each redef
 * < li > For each variable in # 1 , a list of slices
 * taken from the constraint expression
 * < / ol >
 * Two products will be produced .
 * < ol >
 * < li > The variables map will be modified so that the
 * slices properly reflect any original or redef dimensions .
 * < li > A set , dimrefs , of all referenced original dimensions .
 * < / ol >
 * The processing is as follows
 * < ol >
 * < li > For each redef create a new redef dimension
 * < li > For each variable :
 * < ol >
 * < li > if the variable is scalar , do nothing .
 * < li > if the variable has no associated slices , then make its
 * new dimensions be the original dimensions .
 * < li > otherwise , walk the slices and create new dimensions
 * from them ; use redefs where indicated
 * < li >
 * < / ol >
 * < / ol > */
protected void computedimensions ( ) throws DapException { } }

implementation:
// Build the redefmap
for ( DapDimension key : redefslice . keySet ( ) ) { Slice slice = redefslice . get ( key ) ; DapDimension newdim = ( DapDimension ) key . clone ( ) ; newdim . setSize ( slice . getCount ( ) ) ; redef . put ( key , newdim ) ; } // Process each variable
for ( int i = 0 ; i < segments . size ( ) ; i ++ ) { Segment seg = segments . get ( i ) ; if ( seg . var . getRank ( ) == 0 ) continue ; List < Slice > slices = seg . slices ; List < DapDimension > orig = seg . var . getDimensions ( ) ; List < DapDimension > newdims = new ArrayList < > ( ) ; // If the slice list is short then pad it with
// default slices
if ( slices == null ) slices = new ArrayList < Slice > ( ) ; while ( slices . size ( ) < orig . size ( ) ) // pad
{ slices . add ( new Slice ( ) . setConstrained ( false ) ) ; } assert ( slices != null && slices . size ( ) == orig . size ( ) ) ; for ( int j = 0 ; j < slices . size ( ) ; j ++ ) { Slice slice = slices . get ( j ) ; DapDimension dim0 = orig . get ( j ) ; DapDimension newdim = redef . get ( dim0 ) ; if ( newdim == null ) newdim = dim0 ; // fill in the undefined last value
slice . setMaxSize ( newdim . getSize ( ) ) ; slice . finish ( ) ; Slice newslice = null ; if ( slice . isConstrained ( ) ) { // Construct an anonymous dimension for this slice
newdim = new DapDimension ( slice . getCount ( ) ) ; } else { // replace with a new slice from the dim
newslice = new Slice ( newdim ) ; if ( newslice != null ) { // track set of referenced non - anonymous dimensions
if ( ! dimrefs . contains ( dim0 ) ) dimrefs . add ( dim0 ) ; slices . set ( j , newslice ) ; } } // record the dimension per variable
newdims . add ( newdim ) ; } seg . setDimset ( newdims ) ; }


signature:
public class CEConstraint { /** * Walk all the included variables and accumulate
 * the referenced enums */
protected void computeenums ( ) { } }

implementation: for ( int i = 0 ; i < variables . size ( ) ; i ++ ) { DapVariable var = variables . get ( i ) ; if ( var . getSort ( ) != DapSort . VARIABLE ) continue ; DapType daptype = var . getBaseType ( ) ; if ( ! daptype . isEnumType ( ) ) continue ; if ( ! this . enums . contains ( ( DapEnumeration ) daptype ) ) this . enums . add ( ( DapEnumeration ) daptype ) ; }


signature:
public class CEConstraint { /** * Walk all the included declarations
 * and accumulate the set of referenced groups */
protected void computegroups ( ) { } }

implementation:
// 1 . variables
for ( int i = 0 ; i < variables . size ( ) ; i ++ ) { DapVariable var = variables . get ( i ) ; List < DapGroup > path = var . getGroupPath ( ) ; for ( DapGroup group : path ) { if ( ! this . groups . contains ( group ) ) this . groups . add ( group ) ; } } // 2 . Dimensions
for ( DapDimension dim : this . dimrefs ) { if ( ! dim . isShared ( ) ) continue ; List < DapGroup > path = dim . getGroupPath ( ) ; for ( DapGroup group : path ) { if ( ! this . groups . contains ( group ) ) this . groups . add ( group ) ; } } // 2 . enumerations
for ( DapEnumeration en : this . enums ) { List < DapGroup > path = en . getGroupPath ( ) ; for ( DapGroup group : path ) { if ( ! this . groups . contains ( group ) ) this . groups . add ( group ) ; } }


signature:
public class CEConstraint { /** * Static Utility for compiling a constraint string */
static public CEConstraint compile ( String sce , DapDataset dmr ) throws DapException { } }

implementation:
// Process any constraint
if ( sce == null || sce . length ( ) == 0 ) return CEConstraint . getUniversal ( dmr ) ; CEParserImpl ceparser = new CEParserImpl ( dmr ) ; if ( PARSEDEBUG ) ceparser . setDebugLevel ( 1 ) ; if ( DEBUG ) { System . err . println ( "Dap4Servlet: parsing constraint: |" + sce + "|" ) ; } boolean ok ; try { ok = ceparser . parse ( sce ) ; } catch ( ParseException pe ) { ok = false ; } if ( ! ok ) throw new DapException ( "Constraint parse failed: " + sce ) ; CEAST root = ceparser . getCEAST ( ) ; CECompiler compiler = new CECompiler ( ) ; CEConstraint ce = compiler . compile ( dmr , root ) ; ce . expand ( ) ; ce . finish ( ) ; return ce ;


signature:
public class PrimitiveVector { /** * Write the variable ' s declaration in a C - style syntax . This
 * method is used to create textual representation of the Data
 * Descriptor Structure ( DDS ) .
 * @ param os The < code > PrintWriter < / code > on which to print the
 * declaration .
 * @ param space Each line of the declaration will begin with the
 * characters in this string . Usually used for leading spaces .
 * @ param print _ semi a boolean value indicating whether to print a
 * semicolon at the end of the declaration .
 * @ see BaseType # printDecl ( PrintWriter , String , boolean ) */
public final void printDecl ( PrintWriter os , String space , boolean print_semi ) { } }

implementation: printDecl ( os , space , print_semi , false ) ;


signature:
public class PrimitiveVector { /** * Returns a clone of this < code > PrimitiveVector < / code > .
 * See DAPNode . cloneDag ( )
 * @ param map track previously cloned nodes
 * @ return a clone of this < code > PrimitiveVector < / code > . */
public DAPNode cloneDAG ( CloneMap map ) throws CloneNotSupportedException { } }

implementation: PrimitiveVector v = ( PrimitiveVector ) super . cloneDAG ( map ) ; v . var = ( BaseType ) cloneDAG ( map , var ) ; return v ;


signature:
public class Time2DCoordSys { /** * 1 ) single runtime
 * 1a timeOffset
 * 1b time or timeRange
 * 1c none = constant runtime dataset
 * 2 ) multiple runtimes
 * 2a timeOffset = constant offset dataset
 * 2b time ( not range ) = constant forecast dataset */
public Optional < List < CoverageCoordAxis > > subset ( SubsetParams params , AtomicBoolean isConstantForcast , boolean makeCFcompliant ) { } }

implementation:
return Optional . empty ( "not implemented by " + getClass ( ) . getName ( ) ) ; /* List < CoverageCoordAxis > result = new ArrayList < > ( ) ;
 Optional < CoverageCoordAxis > axiso = runAxis . subset ( params ) ;
 if ( ! axiso . isPresent ( ) )
 return Optional . empty ( axiso . getErrorMessage ( ) ) ;
 CoverageCoordAxis1D runAxisSubset = ( CoverageCoordAxis1D ) axiso . get ( ) ;
 result . add ( runAxisSubset ) ;
 / / subset on timeOffset ( 1a , 1c , 2a )
 if ( params . hasTimeOffsetParam ( ) | | ! params . hasTimeParam ( ) ) {
 axiso = timeAxis2D . subset ( params ) ;
 if ( ! axiso . isPresent ( ) )
 return Optional . empty ( axiso . getErrorMessage ( ) ) ;
 CoverageCoordAxis timeOffsetSubset = axiso . get ( ) ;
 result . add ( timeOffsetSubset ) ;
 if ( makeCFcompliant )
 result . add ( makeCFTimeCoord ( runAxisSubset , ( CoverageCoordAxis1D ) timeOffsetSubset ) ) ; / / possible the twoD time case , if nruns > 1
 return Optional . of ( result ) ;
 / / subset on time , # runtimes = 1 ( 1b )
 if ( runAxisSubset . getNcoords ( ) = = 1 ) {
 double val = runAxisSubset . getCoord ( 0 ) ; / / not sure runAxis is needed . maybe use runtimeSubset
 CalendarDate runDate = runAxisSubset . makeDate ( val ) ;
 Optional < TimeOffsetAxis > too = timeAxis2D . subsetFromTime ( params , runDate ) ;
 if ( ! too . isPresent ( ) )
 return Optional . empty ( too . getErrorMessage ( ) ) ;
 TimeOffsetAxis timeOffsetSubset = too . get ( ) ;
 result . add ( timeOffsetSubset ) ;
 if ( makeCFcompliant )
 result . add ( makeCFTimeCoord ( runAxisSubset , timeOffsetSubset ) ) ;
 return Optional . of ( result ) ;
 / / tricky case 2b time ( point only not range ) = constant forecast dataset
 / / data reader has to skip around the 2D times
 / / 1 ) the runtimes may be subset by whats available
 / / 2 ) timeOffset could become an aux coordinate
 / / 3 ) time coordinate becomes a scalar ,
 isConstantForcast . set ( true ) ;
 CalendarDate dateWanted ;
 if ( params . isTrue ( SubsetParams . timePresent ) )
 dateWanted = CalendarDate . present ( ) ;
 else
 dateWanted = ( CalendarDate ) params . get ( SubsetParams . time ) ;
 if ( dateWanted = = null )
 throw new IllegalStateException ( " Must have time parameter " ) ;
 double wantOffset = runAxisSubset . convert ( dateWanted ) ; / / forecastDate offset from refdate
 double start = timeAxis . getStartValue ( ) ;
 double end = timeAxis . getEndValue ( ) ;
 CoordAxisHelper helper = new CoordAxisHelper ( timeOffset ) ;
 / / brute force search LOOK specialize for regular ?
 List < Integer > runtimeIdx = new ArrayList < > ( ) ; / / list of runtime indexes that have this forecast
 / / List < Integer > offsetIdx = new ArrayList < > ( ) ; / / list of offset indexes that have this forecast
 List < Double > offset = new ArrayList < > ( ) ; / / corresponding offset from start of run
 for ( int i = 0 ; i < runAxisSubset . getNcoords ( ) ; i + + ) {
 / / public double getOffsetInTimeUnits ( CalendarDate convertFrom , CalendarDate convertTo ) ;
 double runOffset = runAxisSubset . getCoord ( i ) ;
 if ( end + runOffset < wantOffset ) continue ;
 if ( wantOffset < start + runOffset ) break ;
 int idx = helper . search ( wantOffset - runOffset ) ;
 if ( idx > = 0 ) {
 runtimeIdx . add ( i ) ; / / the ith runtime
 / / offsetIdx . add ( idx ) ; / / the idx time offset
 offset . add ( wantOffset - runOffset ) ; / / the offset from the runtime
 / / here are the runtimes
 int ncoords = runtimeIdx . size ( ) ;
 double [ ] runValues = new double [ ncoords ] ;
 double [ ] offsetValues = new double [ ncoords ] ;
 int count = 0;
 for ( int k = 0 ; k < ncoords ; k + + ) {
 offsetValues [ count ] = offset . get ( k ) ;
 runValues [ count + + ] = runAxisSubset . getCoord ( runtimeIdx . get ( k ) ) ;
 CoverageCoordAxisBuilder runbuilder = new CoverageCoordAxisBuilder ( runAxisSubset )
 . subset ( null , CoverageCoordAxis . Spacing . irregularPoint , ncoords , runValues ) ; / / LOOK check for regular ( in CovCoordAxis ? )
 CoverageCoordAxis1D runAxisSubset2 = new CoverageCoordAxis1D ( runbuilder ) ;
 CoverageCoordAxisBuilder timebuilder = new CoverageCoordAxisBuilder ( timeOffset )
 . subset ( runAxisSubset2 . getName ( ) , CoverageCoordAxis . Spacing . irregularPoint , ncoords , offsetValues ) ; / / aux coord ( LOOK interval ) ? ?
 CoverageCoordAxis1D timeOffsetSubset = new TimeOffsetAxis ( timebuilder ) ;
 CoverageCoordAxis scalarTimeCoord = makeScalarTimeCoord ( wantOffset , runAxisSubset ) ;
 / / nothing needed for CF , the run coordinate acts as the CF time independent coord . timeOffset is aux , forecastTime is scalar
 return Optional . of ( Lists . newArrayList ( runAxisSubset2 , timeOffsetSubset , scalarTimeCoord ) ) ; / / */


signature:
public class Grib2Iosp { /** * accept grib2 or ncx files */
@ Override public boolean isValidFile ( RandomAccessFile raf ) throws IOException { } }

implementation:
if ( raf instanceof HTTPRandomAccessFile ) { // only do remote if memory resident
if ( raf . length ( ) > raf . getBufferSize ( ) ) return false ; } else { // wont accept remote index
GribCdmIndex . GribCollectionType type = GribCdmIndex . getType ( raf ) ; if ( type == GribCdmIndex . GribCollectionType . GRIB2 ) return true ; if ( type == GribCdmIndex . GribCollectionType . Partition2 ) return true ; } // check for GRIB2 data file
return Grib2RecordScanner . isValidFile ( raf ) ;


signature:
public class ThreddsUI { /** * save all data in the PersistentStore */
public void storePersistentData ( ) { } }

implementation:
store . putBeanObject ( VIEWER_SIZE , getSize ( ) ) ; store . putBeanObject ( SOURCE_WINDOW_SIZE , ( Rectangle ) sourceWindow . getBounds ( ) ) ; if ( fileChooser != null ) fileChooser . save ( ) ; if ( datasetChooser != null ) datasetChooser . save ( ) ; if ( sourcePane != null ) sourcePane . save ( ) ; /* if ( catEditor ! = null ) catEditor . save ( ) ;
 if ( catCrawler ! = null ) catCrawler . save ( ) ;
 if ( serverConfigure ! = null ) serverConfigure . save ( ) ;
 if ( catCopier ! = null ) catCopier . save ( ) ; */


signature:
public class ThreddsUI { /** * actions that are system - wide */
private void makeActionsSystem ( ) { } }

implementation:
/* aboutAction = new AbstractAction ( ) {
 public void actionPerformed ( ActionEvent evt ) {
 new AboutWindow ( ) ;
 BAMutil . setActionProperties ( aboutAction , null , " About " , false , ' A ' , 0 ) ; */
/* printAction = new AbstractAction ( ) {
 public void actionPerformed ( ActionEvent e ) {
 PrinterJob printJob = PrinterJob . getPrinterJob ( ) ;
 PageFormat pf = printJob . defaultPage ( ) ;
 / / do we need to rotate ? ?
 if ( panz . wantRotate ( pf . getImageableWidth ( ) , pf . getImageableHeight ( ) ) )
 pf . setOrientation ( PageFormat . LANDSCAPE ) ;
 else
 pf . setOrientation ( PageFormat . PORTRAIT ) ;
 printJob . setPrintable ( controller . getPrintable ( ) , pf ) ;
 if ( printJob . printDialog ( ) ) {
 try {
 if ( Debug . isSet ( " print . job " ) ) System . out . println ( " call printJob . print " ) ;
 printJob . print ( ) ;
 if ( Debug . isSet ( " print . job " ) ) System . out . println ( " printJob done " ) ;
 } catch ( Exception PrintException ) {
 PrintException . printStackTrace ( ) ;
 BAMutil . setActionProperties ( printAction , " Print " , " Print . . . " , false , ' P ' , KeyEvent . VK _ P ) ;
 sysConfigAction = new AbstractAction ( ) {
 public void actionPerformed ( ActionEvent e ) {
 if ( sysConfigDialog = = null )
 makeSysConfigWindow ( ) ;
 sysConfigDialog . show ( ) ;
 BAMutil . setActionProperties ( sysConfigAction , " Preferences " , " Configure . . . " , false , ' C ' , - 1 ) ;
 clearDebugFlagsAction = new AbstractAction ( ) {
 public void actionPerformed ( ActionEvent e ) { Debug . clear ( ) ; }
 BAMutil . setActionProperties ( clearDebugFlagsAction , null , " Clear DebugFlags " , false , ' D ' , - 1 ) ;
 clearRecentAction = new AbstractAction ( ) {
 public void actionPerformed ( ActionEvent e ) {
 recentDatasetList = new ArrayList ( ) ;
 BAMutil . setActionProperties ( clearRecentAction , null , " Clear Recent Datasets " , false , ' R ' , - 1 ) ; */
AbstractAction clearDebugFlagsAction = new AbstractAction ( ) { public void actionPerformed ( ActionEvent e ) { /* Debug . clear ( ) ; */
} } ; BAMutil . setActionProperties ( clearDebugFlagsAction , null , "Clear Debug Flags" , false , 'D' , - 1 ) ; /* AbstractAction setDebugFlagsAction = new AbstractAction ( ) {
 public void actionPerformed ( ActionEvent e ) {
 / / LOOK set netcdf debug flags
 InvCatalogFactory . debugURL = Debug . isSet ( " InvCatalogFactory / debugURL " ) ;
 InvCatalogFactory . debugOpen = Debug . isSet ( " InvCatalogFactory / debugOpen " ) ;
 InvCatalogFactory . debugVersion = Debug . isSet ( " InvCatalogFactory / debugVersion " ) ;
 InvCatalogFactory . showParsedXML = Debug . isSet ( " InvCatalogFactory / showParsedXML " ) ;
 InvCatalogFactory . showStackTrace = Debug . isSet ( " InvCatalogFactory / showStackTrace " ) ;
 InvCatalogFactory . debugXML = Debug . isSet ( " InvCatalogFactory / debugXML " ) ;
 InvCatalogFactory . debugDBurl = Debug . isSet ( " InvCatalogFactory / debugDBurl " ) ;
 InvCatalogFactory . debugXMLopen = Debug . isSet ( " InvCatalogFactory / debugXMLopen " ) ;
 InvCatalogFactory . showCatalogXML = Debug . isSet ( " InvCatalogFactory / showCatalogXML " ) ;
 BAMutil . setActionProperties ( setDebugFlagsAction , null , " Set Debug Flags " , false , ' S ' , - 1 ) ; */
/* exitAction = new AbstractAction ( ) {
 public void actionPerformed ( ActionEvent e ) {
 topLevel . close ( ) ;
 BAMutil . setActionProperties ( exitAction , " Exit " , " Exit " , false , ' X ' , - 1 ) ; */


signature: public class GCsummary { boolean init ( ) { } }

implementation:
System . setProperty ( "tds.log.dir" , contentTdmDir . toString ( ) ) ; if ( ! Files . exists ( threddsConfig ) ) { log . error ( "config file {} does not exist, set -Dtds.content.root.path=<dir>" , threddsConfig ) ; System . out . printf ( "threddsConfig does not exist=%s%n" , threddsConfig ) ; return false ; } ThreddsConfigReader reader = new ThreddsConfigReader ( threddsConfig . toString ( ) , log ) ; for ( String location : reader . getRootList ( "catalogRoot" ) ) { Resource r = new FileSystemResource ( contentThreddsDir . toString ( ) + "/" + location ) ; catalogRoots . add ( r ) ; } // LOOK check TdsInit
/* 4.3.15 : grib index file placement , using DiskCache2 */
String gribIndexDir = reader . get ( "GribIndex.dir" , new File ( contentThreddsDir . toString ( ) , "cache/grib/" ) . getPath ( ) ) ; Boolean gribIndexAlwaysUse = reader . getBoolean ( "GribIndex.alwaysUse" , false ) ; Boolean gribIndexNeverUse = reader . getBoolean ( "GribIndex.neverUse" , false ) ; String gribIndexPolicy = reader . get ( "GribIndex.policy" , null ) ; DiskCache2 gribCache = gribIndexNeverUse ? DiskCache2 . getNoop ( ) : new DiskCache2 ( gribIndexDir , false , - 1 , - 1 ) ; gribCache . setPolicy ( gribIndexPolicy ) ; gribCache . setAlwaysUseCache ( gribIndexAlwaysUse ) ; gribCache . setNeverUseCache ( gribIndexNeverUse ) ; GribIndexCache . setDiskCache2 ( gribCache ) ; log . info ( "TDM set " + gribCache ) ; return true ;


signature:
public class GempakFileReader { /** * Initialize the file , read in all the metadata ( ala DM _ OPEN )
 * @ param raf RandomAccessFile to read .
 * @ param fullCheck if true , check entire structure
 * @ return a GempakFileReader
 * @ throws IOException problem reading file */
public static GempakFileReader getInstance ( RandomAccessFile raf , boolean fullCheck ) throws IOException { } }

implementation: GempakFileReader gfr = new GempakFileReader ( ) ; gfr . init ( raf , fullCheck ) ; return gfr ;


signature:
public class GempakFileReader { /** * Initialize the file , read in all the metadata ( ala DM _ OPEN )
 * @ param raf RandomAccessFile to read .
 * @ param fullCheck if true , check entire structure
 * @ throws IOException problem reading file */
public boolean init ( RandomAccessFile raf , boolean fullCheck ) throws IOException { } }

implementation: setByteOrder ( ) ; rf = raf ; fileSize = rf . length ( ) ; raf . seek ( 0 ) ; return init ( fullCheck ) ;


signature:
public class GempakFileReader { /** * Initialize the file , read in all the metadata ( ala DM _ OPEN )
 * @ param fullCheck if true , check entire structure
 * @ return true if successful
 * @ throws IOException problem reading file */
protected boolean init ( boolean fullCheck ) throws IOException { } }

implementation:
if ( rf == null ) { throw new IOException ( "file has not been set" ) ; } dmLabel = new DMLabel ( ) ; boolean labelOk = dmLabel . init ( ) ; if ( ! labelOk ) { logError ( "not a GEMPAK file" ) ; return false ; } // Read the keys ( DM _ RKEY )
readKeys ( ) ; if ( keys == null ) { logError ( "Couldn't read keys" ) ; return false ; } // Read the headers ( DM _ RHDA )
readHeaders ( ) ; if ( headers == null ) { logError ( "Couldn't read headers" ) ; return false ; } // Read the parts ( DM _ RPRT )
readParts ( ) ; if ( parts == null ) { logError ( "Couldn't read parts" ) ; return false ; } // Read the file header info ( DM _ RFIL )
readFileHeaderInfo ( ) ; if ( fileHeaderInfo == null ) { logError ( "Couldn't read file header info" ) ; return false ; } return true ;


signature:
public class GempakFileReader { /** * Get the byte order for the machine type .
 * @ param kmachn maching type
 * @ return byte order */
public int getByteOrder ( int kmachn ) { } }

implementation: if ( ( kmachn == MTVAX ) || ( kmachn == MTULTX ) || ( kmachn == MTALPH ) || ( kmachn == MTLNUX ) || ( kmachn == MTIGPH ) ) { return RandomAccessFile . LITTLE_ENDIAN ; } return RandomAccessFile . BIG_ENDIAN ;


signature:
public class GempakFileReader { /** * LOOK WTF ? ?
 * Set the machine type for this system .
 * @ see < a href = " http : / / lopica . sourceforge . net / os . html " > http : / / lopica . sourceforge . net / os . html < / a > */
void setByteOrder ( ) { } }

implementation:
String arch = System . getProperty ( "os.arch" ) ; if ( arch . equals ( "x86" ) || // Windows , Linux
arch . equals ( "arm" ) || // Window CE
arch . equals ( "x86_64" ) || // Windows64 , Mac OS - X
arch . equals ( "amd64" ) || // Linux64?
arch . equals ( "alpha" ) ) { // Utrix , VAX , DECOS
MTMACH = RandomAccessFile . LITTLE_ENDIAN ; } else { MTMACH = RandomAccessFile . BIG_ENDIAN ; }


signature:
public class GempakFileReader { /** * Read the file header info ( DM _ RFIL )
 * @ throws IOException problem reading file */
protected void readFileHeaderInfo ( ) throws IOException { } }

implementation: if ( dmLabel == null ) { return ; } int iread = dmLabel . kpfile ; int numheaders = dmLabel . kfhdrs ; String [ ] names = new String [ numheaders ] ; int [ ] lens = new int [ numheaders ] ; int [ ] types = new int [ numheaders ] ; for ( int i = 0 ; i < numheaders ; i ++ ) { names [ i ] = DM_RSTR ( iread ++ ) ; } for ( int i = 0 ; i < numheaders ; i ++ ) { lens [ i ] = DM_RINT ( iread ++ ) ; } for ( int i = 0 ; i < numheaders ; i ++ ) { types [ i ] = DM_RINT ( iread ++ ) ; } fileHeaderInfo = new ArrayList < > ( ) ; for ( int i = 0 ; i < numheaders ; i ++ ) { DMFileHeaderInfo ghi = new DMFileHeaderInfo ( ) ; ghi . kfhnam = names [ i ] ; ghi . kfhlen = lens [ i ] ; ghi . kfhtyp = types [ i ] ; fileHeaderInfo . add ( ghi ) ; }


signature:
public class GempakFileReader { /** * Read in the row and column keys ( DM _ KEY )
 * @ throws IOException problem reading file */
protected void readKeys ( ) throws IOException { } }

implementation:
if ( dmLabel == null ) { return ; } keys = new DMKeys ( ) ; // read the row keys
int num = dmLabel . krkeys ; List < Key > rkeys = new ArrayList < > ( num ) ; for ( int i = 0 ; i < num ; i ++ ) { String key = DM_RSTR ( dmLabel . kprkey + i ) ; rkeys . add ( new Key ( key , i , ROW ) ) ; } keys . kkrow = rkeys ; num = dmLabel . kckeys ; List < Key > ckeys = new ArrayList < > ( num ) ; for ( int i = 0 ; i < num ; i ++ ) { String key = DM_RSTR ( dmLabel . kpckey + i ) ; ckeys . add ( new Key ( key , i , COL ) ) ; } keys . kkcol = ckeys ;


signature:
public class GempakFileReader { /** * Read the headers ( DM _ RHDA )
 * @ throws IOException problem reading file */
protected void readHeaders ( ) throws IOException { } }

implementation:
if ( dmLabel == null ) { return ; } headers = new DMHeaders ( ) ; List < int [ ] > rowHeaders = new ArrayList < > ( dmLabel . krow ) ; int istart = dmLabel . kprowh ; // first word is a valid flag so we have to add 1 to size
int [ ] header ; for ( int i = 0 ; i < dmLabel . krow ; i ++ ) { header = new int [ dmLabel . krkeys + 1 ] ; DM_RINT ( istart , header ) ; if ( header [ 0 ] != IMISSD ) { headers . lstrw = i ; } rowHeaders . add ( header ) ; istart += header . length ; } headers . rowHeaders = rowHeaders ; List < int [ ] > colHeaders = new ArrayList < > ( dmLabel . kcol ) ; istart = dmLabel . kpcolh ; for ( int i = 0 ; i < dmLabel . kcol ; i ++ ) { header = new int [ dmLabel . kckeys + 1 ] ; DM_RINT ( istart , header ) ; if ( header [ 0 ] != IMISSD ) { headers . lstcl = i ; } colHeaders . add ( header ) ; istart += header . length ; } headers . colHeaders = colHeaders ; // some of the words are characters
if ( needToSwap ) { int [ ] keyLoc = new int [ swapKeys . length ] ; String [ ] keyType = new String [ swapKeys . length ] ; boolean haveRow = false ; boolean haveCol = false ; for ( int i = 0 ; i < swapKeys . length ; i ++ ) { Key key = findKey ( swapKeys [ i ] ) ; keyLoc [ i ] = ( key != null ) ? key . loc + 1 : 0 ; keyType [ i ] = ( key != null ) ? key . type : "" ; if ( keyType [ i ] . equals ( ROW ) ) { haveRow = true ; } if ( keyType [ i ] . equals ( COL ) ) { haveCol = true ; } } if ( haveRow ) { for ( int [ ] toCheck : headers . rowHeaders ) { for ( int j = 0 ; j < swapKeys . length ; j ++ ) { if ( keyType [ j ] . equals ( ROW ) ) { if ( swapKeys [ j ] . equals ( "GVCD" ) && ! ( toCheck [ keyLoc [ j ] ] > GempakUtil . vertCoords . length ) ) { continue ; } GempakUtil . swp4 ( toCheck , keyLoc [ j ] , swapNum [ j ] ) ; } } } } if ( haveCol ) { for ( int [ ] toCheck : headers . colHeaders ) { for ( int j = 0 ; j < swapKeys . length ; j ++ ) { if ( keyType [ j ] . equals ( COL ) ) { if ( swapKeys [ j ] . equals ( "GVCD" ) && ! ( toCheck [ keyLoc [ j ] ] > GempakUtil . vertCoords . length ) ) { continue ; } GempakUtil . swp4 ( toCheck , keyLoc [ j ] , swapNum [ j ] ) ; } } } } }


signature:
public class GempakFileReader { /** * Read the parts ( DM _ RPRT )
 * @ throws IOException problem reading file */
protected void readParts ( ) throws IOException { } }

implementation:
if ( dmLabel == null ) { return ; } int iread = dmLabel . kppart ; int numParts = dmLabel . kprt ; DMPart [ ] partArray = new DMPart [ numParts ] ; // read the part names
for ( int i = 0 ; i < numParts ; i ++ ) { partArray [ i ] = new DMPart ( ) ; partArray [ i ] . kprtnm = DM_RSTR ( iread ++ ) ; } // read the part header lengths
for ( int i = 0 ; i < numParts ; i ++ ) { partArray [ i ] . klnhdr = DM_RINT ( iread ++ ) ; } // read the part types
for ( int i = 0 ; i < numParts ; i ++ ) { partArray [ i ] . ktyprt = DM_RINT ( iread ++ ) ; } // get number of parameters / per part .
for ( int i = 0 ; i < numParts ; i ++ ) { partArray [ i ] . kparms = DM_RINT ( iread ++ ) ; } // read parameter names
for ( int i = 0 ; i < numParts ; i ++ ) { int numParms = partArray [ i ] . kparms ; List < DMParam > parms = new ArrayList < > ( numParms ) ; for ( int j = 0 ; j < numParms ; j ++ ) { DMParam dmp = new DMParam ( ) ; parms . add ( dmp ) ; dmp . kprmnm = DM_RSTR ( iread ++ ) ; } partArray [ i ] . params = parms ; } // read the scale
for ( int i = 0 ; i < numParts ; i ++ ) { int numParms = partArray [ i ] . kparms ; List parms = partArray [ i ] . params ; for ( int j = 0 ; j < numParms ; j ++ ) { DMParam dmp = ( DMParam ) parms . get ( j ) ; dmp . kscale = DM_RINT ( iread ++ ) ; } } // read the offset
for ( int i = 0 ; i < numParts ; i ++ ) { int numParms = partArray [ i ] . kparms ; List parms = partArray [ i ] . params ; for ( int j = 0 ; j < numParms ; j ++ ) { DMParam dmp = ( DMParam ) parms . get ( j ) ; dmp . koffst = DM_RINT ( iread ++ ) ; } } // read the nbits
for ( int i = 0 ; i < numParts ; i ++ ) { int numParms = partArray [ i ] . kparms ; List parms = partArray [ i ] . params ; for ( int j = 0 ; j < numParms ; j ++ ) { DMParam dmp = ( DMParam ) parms . get ( j ) ; dmp . kbits = DM_RINT ( iread ++ ) ; } } parts = new ArrayList < > ( numParts ) ; parts . addAll ( Arrays . asList ( partArray ) . subList ( 0 , numParts ) ) ; for ( DMPart part : parts ) { if ( part . ktyprt == MDRPCK ) { part . packInfo = new PackingInfo ( part ) ; } }


signature:
public class GempakFileReader { /** * Run the program
 * @ param args filename
 * @ throws IOException problem reading the file */
public static void main ( String [ ] args ) throws IOException { } }

implementation: if ( args . length == 0 ) { System . out . println ( "need to supply a GEMPAK grid file name" ) ; System . exit ( 1 ) ; } GempakFileReader gfr = getInstance ( getFile ( args [ 0 ] ) , true ) ; gfr . printFileLabel ( ) ; gfr . printKeys ( ) ; gfr . printHeaders ( ) ; gfr . printParts ( ) ;


signature:
public class GempakFileReader { /** * Find a key with the given name
 * @ param name the name of the key
 * @ return the key or null ; */
public Key findKey ( String name ) { } }

implementation:
if ( keys == null ) { return null ; } // search rows
for ( Key key : keys . kkrow ) { if ( key . name . equals ( name ) ) { return key ; } } // search columns
for ( Key key : keys . kkcol ) { if ( key . name . equals ( name ) ) { return key ; } } return null ;


signature:
public class GempakFileReader { /** * Find the file header with this name
 * @ param name name of header
 * @ return headerinfo or null if not found */
public DMFileHeaderInfo findFileHeader ( String name ) { } }

implementation: if ( ( fileHeaderInfo == null ) || fileHeaderInfo . isEmpty ( ) ) { return null ; } for ( DMFileHeaderInfo fhi : fileHeaderInfo ) { if ( name . equals ( fhi . kfhnam ) ) { return fhi ; } } return null ;


signature:
public class GempakFileReader { /** * Read in the values for the file header
 * @ param name name of header
 * @ return values or null if not found
 * @ throws IOException problem reading file */
public float [ ] getFileHeader ( String name ) throws IOException { } }

implementation:
DMFileHeaderInfo fh = findFileHeader ( name ) ; if ( ( fh == null ) || ( fh . kfhtyp != MDREAL ) ) { return null ; } int knt = fileHeaderInfo . indexOf ( fh ) ; // 0 based
int iread = dmLabel . kpfile + 3 * dmLabel . kfhdrs ; for ( int i = 0 ; i < knt ; i ++ ) { DMFileHeaderInfo fhi = fileHeaderInfo . get ( i ) ; iread = iread + fhi . kfhlen + 1 ; } int nword = DM_RINT ( iread ) ; if ( nword <= 0 ) { logError ( "Invalid header length for " + name ) ; return null ; } iread ++ ; float [ ] rheader = new float [ nword ] ; if ( name . equals ( "NAVB" ) && needToSwap ) { DM_RFLT ( iread , 1 , rheader , 0 ) ; needToSwap = false ; iread ++ ; DM_RFLT ( iread , 1 , rheader , 1 ) ; needToSwap = true ; iread ++ ; DM_RFLT ( iread , nword - 2 , rheader , 2 ) ; } else { DM_RFLT ( iread , rheader ) ; } return rheader ;


signature:
public class GempakFileReader { /** * Print the part information */
public void printParts ( ) { } }

implementation: if ( parts == null ) { return ; } for ( int i = 0 ; i < parts . size ( ) ; i ++ ) { System . out . println ( "\nParts[" + i + "]:" ) ; System . out . println ( parts . get ( i ) ) ; }


signature:
public class GempakFileReader { /** * Find the part with the particular name .
 * @ param name name of part to find
 * @ return part number . */
public int getPartNumber ( String name ) { } }

implementation:
int part = 0 ; if ( ( parts != null ) && ! parts . isEmpty ( ) ) { for ( int i = 0 ; i < parts . size ( ) ; i ++ ) { String partName = parts . get ( i ) . kprtnm ; if ( partName . equals ( name ) ) { // gotta add 1 because parts are 1 based
part = i + 1 ; break ; } } } return part ;


signature:
public class GempakFileReader { /** * Find the part with the particular name .
 * @ param name name of part to find
 * @ return part or null if not found */
public DMPart getPart ( String name ) { } }

implementation: if ( ( parts != null ) && ! parts . isEmpty ( ) ) { for ( DMPart part : parts ) { String partName = part . kprtnm ; if ( partName . equals ( name ) ) { return part ; } } } return null ;


signature:
public class GempakFileReader { /** * Get the pointer to the data . Taken from DM _ RDTR
 * @ param irow row number
 * @ param icol column number
 * @ param partName name of the part
 * @ return word ( 1 based ) of start of data . */
public int getDataPointer ( int irow , int icol , String partName ) { } }

implementation:
int ipoint = - 1 ; if ( ( irow < 1 ) || ( irow > dmLabel . krow ) || ( icol < 1 ) || ( icol > dmLabel . kcol ) ) { System . out . println ( "bad row or column number: " + irow + "/" + icol ) ; return ipoint ; } int iprt = getPartNumber ( partName ) ; if ( iprt == 0 ) { System . out . println ( "couldn't find part" ) ; return ipoint ; } // gotta subtract 1 because parts are 1 but List is 0 based
DMPart part = parts . get ( iprt - 1 ) ; // check for valid data type
if ( ( part . ktyprt != MDREAL ) && ( part . ktyprt != MDGRID ) && ( part . ktyprt != MDRPCK ) ) { System . out . println ( "Not a valid type" ) ; return ipoint ; } int ilenhd = part . klnhdr ; ipoint = dmLabel . kpdata + ( irow - 1 ) * dmLabel . kcol * dmLabel . kprt + ( icol - 1 ) * dmLabel . kprt + ( iprt - 1 ) ; return ipoint ;


signature:
public class GempakFileReader { /** * Read an integer
 * @ param word word in file ( 1 based ) to read
 * @ return int read
 * @ throws IOException problem reading file */
public int DM_RINT ( int word ) throws IOException { } }

implementation:
if ( rf == null ) { throw new IOException ( "DM_RINT: no file to read from" ) ; } if ( dmLabel == null ) { throw new IOException ( "DM_RINT: reader not initialized" ) ; } rf . seek ( getOffset ( word ) ) ; // set the order
if ( needToSwap ) { // if ( ( dmLabel . kmachn ! = MTMACH ) & &
// ( ( dmLabel . kvmst & & ! mvmst ) | |
// ( mvmst & & ! dmLabel . kvmst ) ) ) {
rf . order ( RandomAccessFile . LITTLE_ENDIAN ) ; // swap
} else { rf . order ( RandomAccessFile . BIG_ENDIAN ) ; } int idata = rf . readInt ( ) ; if ( IMISSD != dmLabel . kmissd ) { if ( idata == dmLabel . kmissd ) { idata = IMISSD ; } } rf . order ( RandomAccessFile . BIG_ENDIAN ) ; return idata ;


signature:
public class GempakFileReader { /** * Read into an array of ints .
 * @ param word word in file ( 1 based ) to read
 * @ param iarray array to read into
 * @ param start starting word in the array ( 0 based )
 * @ param num number of words to read
 * @ throws IOException problem reading file */
public void DM_RINT ( int word , int num , int [ ] iarray , int start ) throws IOException { } }

implementation: for ( int i = 0 ; i < num ; i ++ ) { if ( start + i > iarray . length ) { throw new IOException ( "DM_RINT: start+num exceeds iarray length" ) ; } iarray [ start + i ] = DM_RINT ( word + i ) ; }


signature:
public class GempakFileReader { /** * Read a float
 * @ param word word in file ( 1 based ) to read
 * @ return float read
 * @ throws IOException problem reading file */
public float DM_RFLT ( int word ) throws IOException { } }

implementation:
if ( rf == null ) { throw new IOException ( "DM_RFLT: no file to read from" ) ; } if ( dmLabel == null ) { throw new IOException ( "DM_RFLT: reader not initialized" ) ; } rf . seek ( getOffset ( word ) ) ; if ( needToSwap ) { // set the order
// if ( ( dmLabel . kmachn ! = MTMACH ) & &
// ( ( dmLabel . kvmst & & ! mvmst ) | |
// ( mvmst & & ! dmLabel . kvmst ) ) ) {
rf . order ( RandomAccessFile . LITTLE_ENDIAN ) ; // swap
} else { rf . order ( RandomAccessFile . BIG_ENDIAN ) ; } float rdata = rf . readFloat ( ) ; if ( RMISSD != dmLabel . smissd ) { if ( Math . abs ( rdata - dmLabel . smissd ) < RDIFFD ) { rdata = RMISSD ; } } // reset to read normally
rf . order ( RandomAccessFile . BIG_ENDIAN ) ; return rdata ;


signature:
public class GempakFileReader { /** * Read into an array of ints .
 * @ param word word in file ( 1 based ) to read
 * @ param num number of words to read
 * @ param rarray array to read into
 * @ param start starting word in the array ( 0 based )
 * @ throws IOException problem reading file */
public void DM_RFLT ( int word , int num , float [ ] rarray , int start ) throws IOException { } }

implementation: for ( int i = 0 ; i < num ; i ++ ) { if ( start + i > rarray . length ) { throw new IOException ( "DM_RFLT: start+num exceeds rarray length" ) ; } rarray [ start + i ] = DM_RFLT ( word + i ) ; }


signature:
public class GempakFileReader { /** * Read a String
 * @ param isword offset in file ( 1 based FORTRAN word )
 * @ param nchar number of characters to read
 * @ return String read
 * @ throws IOException problem reading file */
public String DM_RSTR ( int isword , int nchar ) throws IOException { } }

implementation: if ( rf == null ) { throw new IOException ( "DM_RSTR: no file to read from" ) ; } rf . seek ( getOffset ( isword ) ) ; return rf . readString ( nchar ) ;


signature:
public class GempakFileReader { /** * Read the data
 * @ param irow row to read
 * @ param icol column to read
 * @ param partName part name
 * @ return the header and data array or null ;
 * @ throws IOException problem reading file */
public RData DM_RDTR ( int irow , int icol , String partName ) throws IOException { } }

implementation: return DM_RDTR ( irow , icol , partName , 1 ) ;


signature:
public class GempakFileReader { /** * Read the real ( float ) data
 * @ param irow row to read
 * @ param icol column to read
 * @ param partName part name
 * @ param decimalScale scaling factor ( power of 10 ) ;
 * @ return the header and data array or null ;
 * @ throws IOException problem reading file */
public RData DM_RDTR ( int irow , int icol , String partName , int decimalScale ) throws IOException { } }

implementation:
int ipoint = - 1 ; if ( ( irow < 1 ) || ( irow > dmLabel . krow ) || ( icol < 1 ) || ( icol > dmLabel . kcol ) ) { System . out . println ( "bad row/column number " + irow + "/" + icol ) ; return null ; } // System . out . println ( " reading row " + irow + " , column " + icol ) ;
int iprt = getPartNumber ( partName ) ; if ( iprt == 0 ) { System . out . println ( "couldn't find part: " + partName ) ; return null ; } // gotta subtract 1 because parts are 1 but List is 0 based
DMPart part = parts . get ( iprt - 1 ) ; // check for valid real data type
if ( ( part . ktyprt != MDREAL ) && ( part . ktyprt != MDGRID ) && ( part . ktyprt != MDRPCK ) ) { System . out . println ( "Not a valid type" ) ; return null ; } int ilenhd = part . klnhdr ; ipoint = dmLabel . kpdata + ( irow - 1 ) * dmLabel . kcol * dmLabel . kprt + ( icol - 1 ) * dmLabel . kprt + ( iprt - 1 ) ; float [ ] rdata ; int [ ] header = null ; int istart = DM_RINT ( ipoint ) ; if ( istart == 0 ) { return null ; } // start catching up here because some files are incorrectly written
try { int length = DM_RINT ( istart ) ; int isword = istart + 1 ; if ( length <= ilenhd ) { // System . out . println ( " length ( " + length
// + " ) is less than header length ( " + ilenhd
return null ; } else if ( Math . abs ( length ) > 10000000 ) { // System . out . println ( " length is huge " ) ;
return null ; } header = new int [ ilenhd ] ; DM_RINT ( isword , header ) ; int nword = length - ilenhd ; isword += header . length ; if ( part . ktyprt == MDREAL ) { rdata = new float [ nword ] ; DM_RFLT ( isword , rdata ) ; } else if ( part . ktyprt == MDGRID ) { rdata = DM_RPKG ( isword , nword , decimalScale ) ; } else { // packed ints
int [ ] idata = new int [ nword ] ; DM_RINT ( isword , idata ) ; rdata = DM_UNPK ( part , idata ) ; } } catch ( EOFException eof ) { // System . err . println ( " reading off end of file " ) ;
rdata = null ; } RData rd = null ; if ( rdata != null ) { rd = new RData ( header , rdata ) ; } return rd ;


signature:
public class GempakFileReader { /** * Unpack an array of packed integers .
 * @ param part the part with packing info
 * @ param ibitst packed integer bit string
 * @ return unpacked ints as floats */
public float [ ] DM_UNPK ( DMPart part , int [ ] ibitst ) { } }

implementation:
int nparms = part . kparms ; int nwordp = part . kwordp ; int npack = ( ibitst . length - 1 ) / nwordp + 1 ; if ( npack * nwordp != ibitst . length ) { // logError ( " number of packed records not correct " ) ;
// System . out . println ( " number of packed records not correct : "
// + npack * nwordp + " vs . " + ibitst . length ) ;
return null ; } float [ ] data = new float [ nparms * npack ] ; PackingInfo pkinf = part . packInfo ; int ir = 0 ; int ii = 0 ; for ( int pack = 0 ; pack < npack ; pack ++ ) { // Move bitstring into internal words . TODO : necessary ?
int [ ] jdata = new int [ nwordp ] ; System . arraycopy ( ibitst , ii , jdata , 0 , nwordp ) ; // Extract each data value .
for ( int idata = 0 ; idata < nparms ; idata ++ ) { // Extract correct bits from words using shift and mask
// operations .
int jbit = pkinf . nbitsc [ idata ] ; int jsbit = pkinf . isbitc [ idata ] ; int jshift = 1 - jsbit ; int jsword = pkinf . iswrdc [ idata ] ; int jword = jdata [ jsword ] ; // use > > > to shift avoid carrying sign along
int mask = mskpat >>> ( 32 - jbit ) ; int ifield = jword >>> Math . abs ( jshift ) ; ifield = ifield & mask ; if ( ( jsbit + jbit - 1 ) > 32 ) { jword = jdata [ jsword + 1 ] ; jshift = jshift + 32 ; int iword = jword << jshift ; iword = iword & mask ; ifield = ifield | iword ; } // The integer data is now in ifield . Use the scaling and
// offset terms to convert to REAL data .
if ( ifield == pkinf . imissc [ idata ] ) { data [ ir + idata ] = RMISSD ; } else { data [ ir + idata ] = ( ifield + pkinf . koffst [ idata ] ) * ( float ) pkinf . scalec [ idata ] ; } } ir += nparms ; ii += nwordp ; } return data ;


signature:
public class GempakFileReader { /** * Get a bit string for an integer
 * @ param b the integer
 * @ return a bit string ( e . g . : 01100001 | 1100000 | 10011010 | 10110100 | ) */
protected static String getBits ( int b ) { } }

implementation: Formatter s = new Formatter ( ) ; for ( int i = 31 ; i >= 0 ; i -- ) { if ( ( b & ( 1 << i ) ) != 0 ) { s . format ( "1" ) ; } else { s . format ( "0" ) ; } if ( i % 8 == 0 ) { s . format ( "|" ) ; } } return s . toString ( ) ;


signature: public class N3channelWriter { public void writeDataAll ( WritableByteChannel channel ) throws IOException , InvalidRangeException { } }

implementation:
for ( Vinfo vinfo : vinfoList ) { if ( ! vinfo . isRecord ) { Variable v = vinfo . v ; // assert filePos = = vinfo . offset ;
// if ( debugPos ) System . out . println ( " writing at " + filePos + " should be " + vinfo . offset + " " + v . getFullName ( ) ) ;
int nbytes = ( int ) v . readToByteChannel ( v . getShapeAsSection ( ) , channel ) ; filePos += nbytes ; filePos += pad ( channel , nbytes ) ; if ( debugPos ) System . out . printf ( " read=%d vinfo=%s%n" , nbytes , vinfo ) ; } } // must use record dimension if it exists +
boolean useRecordDimension = ncfile . hasUnlimitedDimension ( ) ; if ( useRecordDimension ) { ncfile . sendIospMessage ( NetcdfFile . IOSP_MESSAGE_ADD_RECORD_STRUCTURE ) ; Structure recordVar = ( Structure ) ncfile . findVariable ( "record" ) ; Section section = new Section ( ) . appendRange ( null ) ; long bytesDone = 0 ; long done = 0 ; long nrecs = ( int ) recordVar . getSize ( ) ; int structureSize = recordVar . getElementSize ( ) ; int readAtaTime = Math . max ( 10 , buffer_size / structureSize ) ; for ( int count = 0 ; count < nrecs ; count += readAtaTime ) { long last = Math . min ( nrecs , done + readAtaTime ) ; // dont go over nrecs
int need = ( int ) ( last - done ) ; // how many to read this time
section . setRange ( 0 , new Range ( count , count + need - 1 ) ) ; try { bytesDone += recordVar . readToByteChannel ( section , channel ) ; done += need ; } catch ( InvalidRangeException e ) { e . printStackTrace ( ) ; break ; } } assert done == nrecs ; bytesDone /= 1000 * 1000 ; if ( debugWrite ) System . out . println ( "write record var; total = " + bytesDone + " Mbytes # recs=" + done ) ; // remove the record structure this is rather fishy , perhaps better to leave it
ncfile . sendIospMessage ( NetcdfFile . IOSP_MESSAGE_REMOVE_RECORD_STRUCTURE ) ; ncfile . finish ( ) ; }


signature: public class N3channelWriter { public static void writeFromFile ( NetcdfFile fileIn , String fileOutName ) throws IOException , InvalidRangeException { } }

implementation: try ( FileOutputStream stream = new FileOutputStream ( fileOutName ) ) { WritableByteChannel channel = stream . getChannel ( ) ; DataOutputStream dout = new DataOutputStream ( Channels . newOutputStream ( channel ) ) ; N3channelWriter writer = new N3channelWriter ( fileIn ) ; int numrec = fileIn . getUnlimitedDimension ( ) == null ? 0 : fileIn . getUnlimitedDimension ( ) . getLength ( ) ; writer . writeHeader ( dout , numrec ) ; dout . flush ( ) ; writer . writeDataAll ( channel ) ; }


signature:
public class N3channelWriter { /** * Write ncfile to a WritableByteChannel .
 * @ param ncfile the file to write
 * @ param wbc write to this WritableByteChannel .
 * If its a Socket , must have been opened through a call to java . nio . channels . SocketChannel . open ( )
 * @ throws IOException on IO error
 * @ throws InvalidRangeException range error */
public static void writeToChannel ( NetcdfFile ncfile , WritableByteChannel wbc ) throws IOException , InvalidRangeException { } }

implementation:
DataOutputStream stream = new DataOutputStream ( new BufferedOutputStream ( Channels . newOutputStream ( wbc ) , 8000 ) ) ; // DataOutputStream stream = new DataOutputStream ( Channels . newOutputStream ( wbc ) ) ; / / buffering seems to improve by 5%
N3channelWriter writer = new N3channelWriter ( ncfile ) ; int numrec = ncfile . getUnlimitedDimension ( ) == null ? 0 : ncfile . getUnlimitedDimension ( ) . getLength ( ) ; writer . writeHeader ( stream , numrec ) ; stream . flush ( ) ; writer . writeDataAll ( wbc ) ;


signature:
public class DDSXMLParser { /** * Parse the DDX waiting in the < code > InputStream < / code > and instantiate all of
 * the member < code > BaseType < / code > variables and their associated < code > Attributes
 * < / code > into a < code > DDS < / code > using the passed < code > BaseTypeFactory < / code >
 * @ param ddx A JDOM < code > Document < / code > containing the DDX to parse .
 * @ param targetDDS The < code > DDS < / code > in which to place all of the < code > BaseType
 * < / code > variables and their associated < code > Attributes < / code > .
 * @ param fac The < code > BaseTypeFactory < / code > to use when creating new
 * < code > BaseType < / code > variables .
 * @ param validation Is a boolean indicating whether or not the parser should
 * validate the XML document using the Schema ( typically referenced in the
 * document itself ) . In general server side applications should always vaidate ,
 * while clients shouldn ' t bother ( since they are ostensibly receiving the
 * document from a server that has already done so . )
 * @ see DDS
 * @ see BaseTypeFactory */
public void parse ( Document ddx , DDS targetDDS , BaseTypeFactory fac , boolean validation ) throws DAP2Exception { } }

implementation:
dds = targetDDS ; factory = fac ; // Build up the OPeNDAP data objects rpresented by the XML document .
// Additional validation will take place during this process .
Element root = ddx . getRootElement ( ) ; lastDoc = ddx ; // This is just a little tracker to help with debugging .
parseLevel = 0 ; // Make sure the root element is in fact a Dataset .
// Trying to enforce this in the schema would create a
// contrived and difficult to interpret schema design .
String type = root . getName ( ) ; if ( ! ( type . equals ( "Dataset" ) ) ) { throw new NoSuchTypeException ( "Root Element MUST be <Dataset>. Found: " + type ) ; } String name = root . getAttribute ( "name" ) . getValue ( ) ; // System . out . println ( " DDS should be named : " + name ) ;
dds . setClearName ( name ) ; parentDC = dds ; currentBT = dds ; // Parse any Attributes ( or AttributeTables / containers ) at the
// top level in the Dataset .
parseAttributes ( root , "-- " ) ; // Parse any Aliases at the
// top level in the Dataset .
parseAliases ( root , "++ " ) ; // Parse all of the child elements ( which would be OPeNDAP
// BaseType variables ) in the Dataset .
Iterator ci = root . getChildren ( ) . iterator ( ) ; while ( ci . hasNext ( ) ) { Element child = ( Element ) ci . next ( ) ; parseBase ( child , "    " ) ; } // catch ( Exception e ) {
// throw new DAP2Exception ( " PARSER ERROR ! \ n " +
// e . getClass ( ) . getName ( ) + " : " + e . getMessage ( ) ) ;


signature:
public class DDSXMLParser { /** * Parse the DDX waiting in the < code > InputStream < / code > and instantiate all of
 * the member < code > BaseType < / code > variables and their associated < code > Attributes
 * < / code > into a < code > DDS < / code > using the passed < code > BaseTypeFactory < / code >
 * @ param is The < code > InputStream < / code > containing the DDX to parse .
 * @ param targetDDS The < code > DDS < / code > in which to place all of the < code > BaseType
 * < / code > variables and their associated < code > Attributes < / code > .
 * @ param fac The < code > BaseTypeFactory < / code > to use when creating new
 * < code > BaseType < / code > variables .
 * @ param validation Is a boolean indicating whether or not the parser should
 * validate the XML document using the Schema ( typically referenced in the
 * document itself ) . In general server side applications should always vaidate ,
 * while clients shouldn ' t bother ( since they are ostensibly receiving the
 * document from a server that has already done so . )
 * @ see DDS
 * @ see BaseTypeFactory */
public void parse ( InputStream is , DDS targetDDS , BaseTypeFactory fac , boolean validation ) throws DAP2Exception { } }

implementation:
try { // get a jdom parser to parse and validate the XML document .
SAXBuilder parser = new SAXBuilder ( ) ; // optionally turn on validation
parser . setFeature ( "http://apache.org/xml/features/validation/schema" , validation ) ; // parse the document into a hierarchical document
Document doc = parser . build ( is ) ; if ( _Debug ) System . out . println ( "Document is " + ( validation ? "valid and " : "" ) + "well-formed.\nContent: " + doc ) ; parse ( doc , targetDDS , fac , validation ) ; } catch ( JDOMException jde ) { throw new DAP2Exception ( jde ) ; } catch ( IOException ioe ) { throw new DAP2Exception ( ioe ) ; }


signature:
public class DDSXMLParser { /** * This method recursively travels through the DOM tree , locating
 * BaseType derived nodes and placing them in the DDS . The structure
 * of the BaseType derived elements in the XML instance document
 * is captured in the DOM object that is being parsed . This structure
 * again reflected in the resulting DDS . */
private void parseBase ( Element e , String indent ) throws DASException , NoSuchTypeException , BadSemanticsException { } }

implementation:
parseLevel ++ ; String type = e . getName ( ) ; if ( type . equals ( "Attribute" ) ) { // Do nothing here , the Attributes get parsed when the BaseType ' s
// get built . This conditional basically serves as a " trap " to
// ignore the < Attribute > tag .
} else if ( type . equals ( "Alias" ) ) { // Do nothing here , the Aliases get parsed when the BaseType ' s
// get built . This conditional basically serves as a " trap " to
// ignore the < Alias > tag .
} else if ( type . equals ( "dataBLOB" ) ) { // dataBLOB ?
// The schema says that the href attribute is
// required for the dataBLOB element .
org . jdom2 . Attribute hrefAttr = e . getAttribute ( "href" ) ; // Since it ' s required we know that the getAttribute ( )
// method is not going to return null .
String contentID = hrefAttr . getValue ( ) ; if ( _Debug ) System . out . println ( "Found dataBLOB element. contentID=\"" + contentID + "\"" ) ; dds . setBlobContentID ( contentID ) ; } else { // What ' s left must be a OPeNDAP BaseType
if ( _Debug ) System . out . println ( "Parsing new BaseType element. Parse level: " + parseLevel ) ; if ( _Debug ) showXMLElement ( e , indent ) ; // Go get a new BaseType formed from this element
BaseType bt = newBaseType ( e ) ; // Set it ' s parent .
// bt . setParent ( parentDC ) ;
// Add it to it ' s parent ( container )
parentDC . addVariable ( bt ) ; // Now we need to make sure this particular BaseType
// derived element isn ' t some special type that needs
// additional parsing :
// Is it a container ?
if ( bt instanceof DConstructor ) { // Up date the parsers state , ( cache my parent )
DConstructor myParentDC = parentDC ; parentDC = ( DConstructor ) bt ; try { // Grids are special containers , handle them
if ( bt instanceof DGrid ) { parseGrid ( e , indent ) ; } else { // Otherwise , recurse on the children
for ( Element child : e . getChildren ( ) ) { parseBase ( child , indent + "    " ) ; } } } finally { // restore my parent
parentDC = myParentDC ; } } else if ( bt instanceof DArray ) { // Array ' s are special , better build it if it is one
if ( _Debug ) System . out . println ( "Parsing Array instance.  Array name: '" + bt . getClearName ( ) + "'" ) ; parseArray ( e , ( DArray ) bt , indent ) ; } } parseLevel -- ;


signature:
public class DDSXMLParser { /** * Arrays have special parsing need as their syntax is different from
 * that of a typical BaseType derived type or a container type . The
 * array is based on a template variable that can have ANY structure
 * that can be represented by the OPeNDAP data model . With the exception
 * of ( you knew this was comming , right ? ) of other arrays . IE You can ' t
 * have Arrays of Arrays . This caveat is enforced by the XML schema . */
private void parseArray ( Element ArrayElement , DArray da , String indent ) throws DASException , NoSuchTypeException , BadSemanticsException { } }

implementation:
int countTemplateVars = 0 ; int numDims = 0 ; for ( Element e : ArrayElement . getChildren ( ) ) { if ( _Debug ) System . out . println ( indent + "Working on Array element: " + e . getName ( ) ) ; // Is this element an Attribute of the Array ?
if ( e . getName ( ) . equals ( "Attribute" ) ) { // Then ignore it !
} // Is this element an Attribute of the Alias ?
else if ( e . getName ( ) . equals ( "Alias" ) ) { // Then ignore it !
} // Is this element an array dimension ?
else if ( e . getName ( ) . equals ( "dimension" ) ) { // Then count it ,
numDims ++ ; // And now let ' s add it to the array . . .
// Array dimension are not required to have names , so
// the schema does not enforce the use of the name attribute .
// try to get the dimension ' s name , and use it id it ' s there .
String name = null ; Attribute nameAttr = e . getAttribute ( "name" ) ; if ( nameAttr != null ) name = nameAttr . getValue ( ) ; // The presence of the ' size ' attribute is enforeced by the schema .
// get it , parse it , use it .
int size = Integer . parseInt ( e . getAttribute ( "size" ) . getValue ( ) ) ; // add the dimension to the array .
da . appendDim ( size , ( name ) ) ; } else { // otherwise , it must be THE template element .
// Just to make sure the schema validation didn ' t fail ( because
// I am basically paranoid about software ) count the number of
// template candidates we find and throw an Exception later
// if there was more than one .
countTemplateVars ++ ; // The template element is just another BaseType
// derived element . So , let ' s go build it !
BaseType template = buildArrayTemplate ( e , indent ) ; // Oddly , in the OPeNDAP implementation of Array , the Array variable
// takes it ' s name from it ' s ( internal ) template variable . This
// is probably an artifact of the original DDSParser .
// So , set the name of the template variable to the name of the Array .
template . setClearName ( da . getClearName ( ) ) ; // Add the template variable to the Array
da . addVariable ( template ) ; } } if ( _Debug ) { System . out . println ( indent + "Built Array: " ) ; da . printDecl ( System . out , indent ) ; System . out . println ( indent + "dimensions: " + numDims + "  templates: " + countTemplateVars ) ; } if ( countTemplateVars != 1 ) { throw new NoSuchTypeException ( "ONLY ONE (1) TEMPLATE VARIABLE ALLOWED PER ARRAY!" ) ; }


signature:
public class DDSXMLParser { /** * Builds the template variable for an array . The logic here has a lot
 * in common with the logic in parseBase . I considered trying to
 * refactor the code so that the two methods could utilize the same logic ,
 * but I bagged it . Cie ' la vie .
 * Arrays of arrays are not allowed this rule should is enforced
 * through the schema validation process . */
private BaseType buildArrayTemplate ( Element template , String indent ) throws DASException , NoSuchTypeException , BadSemanticsException { } }

implementation:
BaseType bt = null ; if ( _Debug ) showXMLElement ( template , indent + "...:" ) ; // Get all of the Attribute elements ( tagged < Attribute > )
Iterator attrElements = template . getChildren ( "Attribute" , opendapNameSpace ) . iterator ( ) ; if ( attrElements . hasNext ( ) ) throw new BadSemanticsException ( "Array Template Variables MAY NOT have Attributes" ) ; // Build the appropriate BaseType from the tag .
bt = newBaseType ( template ) ; if ( _Debug ) System . out . println ( "Got template: " + bt . getTypeName ( ) + "   " + bt . getClearName ( ) ) ; // Now we need to make sure this particular BaseType
// derived element isn ' t some special type that needs
// additional parsing :
// Is it a container ?
if ( bt instanceof DConstructor ) { // Up date the parsers state , ( cache my parent )
DConstructor myParentDC = parentDC ; parentDC = ( DConstructor ) bt ; try { // Grids are special containers , handle them
if ( bt instanceof DGrid ) { parseGrid ( template , indent ) ; } else { // Otherwise , recurse on the children
for ( Element child : template . getChildren ( ) ) { parseBase ( child , indent + "    " ) ; } } } finally { // restore my parent
parentDC = myParentDC ; } } return ( bt ) ;


signature:
public class DDSXMLParser { /** * Grids are unusual examples of DConstructor and require special
 * handling when parsing . */
private void parseGrid ( Element gridElement , String indent ) throws DASException , NoSuchTypeException , BadSemanticsException { } }

implementation:
parseLevel ++ ; // Grab the parent object ( which better be a Grid ! )
// just to elminate the hassle of casting everytime . . .
DGrid myGrid = ( DGrid ) parentDC ; if ( _Debug ) { System . out . println ( "Parsing Grid Element: " + gridElement ) ; System . out . println ( "Grid Elements: " ) ; // showXMLElement ( gridElement , indent ) ;
for ( Element element : gridElement . getChildren ( ) ) System . out . println ( element ) ; } // Get and parse the grid ' s Array element .
String eName = "Array" ; if ( _Debug ) { System . out . println ( "Parsing Array element." ) ; System . out . println ( "Asking for element: '" + eName + "' in namespace: '" + opendapNameSpace + "'" ) ; } Element arrayElement = gridElement . getChild ( eName , opendapNameSpace ) ; if ( _Debug ) System . out . println ( "Got Array element: " + arrayElement ) ; DArray gridArray = ( DArray ) newBaseType ( arrayElement ) ; parseArray ( arrayElement , gridArray , indent + "    " ) ; // Add it to the Grid
myGrid . addVariable ( gridArray , DGrid . ARRAY ) ; // Get the Map elements
eName = "Map" ; if ( _Debug ) { System . out . println ( "Parsing Map elements." ) ; System . out . println ( "Asking for element: '" + eName + "' in namespace: '" + opendapNameSpace + "'" ) ; } List < Element > mapElements = gridElement . getChildren ( "Map" , opendapNameSpace ) ; // Make sure the number of Map elements matches the dimension of the Grid Array .
if ( mapElements . size ( ) != gridArray . numDimensions ( ) ) throw new BadSemanticsException ( "Error in Grid syntax: " + "The number of Map arrays must " + "equal the number of dimensions " + "of the data array." ) ; // Parse each Map element and poke it into the Grid .
for ( Element mapElement : mapElements ) { DArray thisMap = ( DArray ) newBaseType ( mapElement ) ; parseArray ( mapElement , thisMap , indent + "    " ) ; if ( thisMap . numDimensions ( ) != 1 ) throw new BadSemanticsException ( "Error in Grid syntax: " + "Maps may have only one dimension." ) ; myGrid . addVariable ( thisMap , DGrid . MAPS ) ; } parseLevel -- ;


signature:
public class DDSXMLParser { /** * A convienience function used for displaying information in _ Debug mode .
 * Prints an XML element ' s name , content ( if any ) and Attributes to
 * System . out */
private void showXMLElement ( Element e , String indent ) { } }

implementation:
System . out . print ( parseLevel + indent + "Element: " + e . getName ( ) + "  " ) ; String text = e . getTextNormalize ( ) ; if ( ! text . equals ( "" ) ) System . out . print ( " = " + text + "   " ) ; // System . out . println ( " " ) ;
for ( Attribute att : e . getAttributes ( ) ) { // System . out . print ( parseLevel + indent + " " ) ;
System . out . print ( att . getName ( ) + ": " + att . getValue ( ) + "  " ) ; } System . out . println ( "" ) ; for ( Element kid : e . getChildren ( ) ) { showXMLElement ( kid , indent + "    " ) ; }


signature:
public class DDSXMLParser { /** * Builds a new BaseType derived type from the passed XML element .
 * < p > This happens in 4 steps :
 * < ul >
 * < li > 1 ) Determine the OPeNDAP type and vairiable name < / li >
 * < li > 2 ) Get an new one of the thing in ( 1 ) < / li >
 * < li > 3 ) Parse any Attribute tags associated with this OPeNDAP type .
 * ( They appear as children of the XML element ) < / li >
 * < li > 4 ) Parse any Alias tags associated with this OPeNDAP type .
 * ( They appear as children of the XML element ) < / li >
 * < / ul > */
private BaseType newBaseType ( Element e ) throws DASException , NoSuchTypeException { } }

implementation:
if ( _Debug ) System . out . println ( "Getting new BaseType() from: " + e ) ; // What ' s the Element Name ? This IS the OPeNDAP typename .
String type = e . getName ( ) ; // What is the name of this variable ? Since BaseType derived types
// are not required to have names we have to do this carefully .
String name = null ; org . jdom2 . Attribute nameAttr = e . getAttribute ( "name" ) ; if ( nameAttr != null ) name = nameAttr . getValue ( ) ; if ( _Debug ) System . out . println ( "    type: " + type + "   name: '" + name + "'" ) ; // GO get a fresh new OPeNDAP variable ( BaseType derived type )
currentBT = newBaseTypeFactory ( type , name ) ; // Parse any Attribute tagged child elements for this variable .
parseAttributes ( e , "--- " ) ; // Parse any Alias tagged child elements for this variable .
parseAliases ( e , "+++ " ) ; return ( currentBT ) ;


signature:
public class DDSXMLParser { /** * The name of this method might be a bit misleading . This method is basically
 * a wrapper for the BaseTypeFactory associated with the DDS that we are building .
 * I think it should really be a method of BaseTypeFactory .
 * Something like :
 * BaseTypeFactory . getNewVariable ( String typeString , String name )
 * But , well BaseTypeFactory is an interface , so that ' s a crappy idea . * sigh * */
private BaseType newBaseTypeFactory ( String typeString , String name ) throws NoSuchTypeException { } }

implementation: BaseType bt ; if ( typeString . equals ( "Array" ) || typeString . equals ( "Map" ) ) { bt = factory . newDArray ( ) ; bt . setClearName ( name ) ; } else if ( typeString . equals ( "Grid" ) ) { bt = factory . newDGrid ( ) ; bt . setClearName ( name ) ; } else if ( typeString . equals ( "Structure" ) ) { bt = factory . newDStructure ( ) ; bt . setClearName ( name ) ; } else if ( typeString . equals ( "Sequence" ) ) { bt = factory . newDSequence ( ) ; bt . setClearName ( name ) ; } else if ( typeString . equals ( "Int16" ) ) { bt = factory . newDInt16 ( ) ; bt . setClearName ( name ) ; } else if ( typeString . equals ( "UInt16" ) ) { bt = factory . newDUInt16 ( ) ; bt . setClearName ( name ) ; } else if ( typeString . equals ( "Int32" ) ) { bt = factory . newDInt32 ( ) ; bt . setClearName ( name ) ; } else if ( typeString . equals ( "UInt32" ) ) { bt = factory . newDUInt32 ( ) ; bt . setClearName ( name ) ; } else if ( typeString . equals ( "Float32" ) ) { bt = factory . newDFloat32 ( ) ; bt . setClearName ( name ) ; } else if ( typeString . equals ( "Float64" ) ) { bt = factory . newDFloat64 ( ) ; bt . setClearName ( name ) ; } else if ( typeString . equals ( "Byte" ) ) { bt = factory . newDByte ( ) ; bt . setClearName ( name ) ; } else if ( typeString . equals ( "String" ) ) { bt = factory . newDString ( ) ; bt . setClearName ( name ) ; } else if ( typeString . equals ( "Url" ) ) { bt = factory . newDURL ( ) ; bt . setClearName ( name ) ; } else throw new NoSuchTypeException ( "Unknown Type: " + typeString ) ; return bt ;


signature:
public class DDSXMLParser { /** * Parse the Attribute tags for a given variable element in the XML document .
 * Build the appropriate Attributes and AttributeTables and add them to the
 * the current variable ' s ( currentBT ' s ) AttributeTable . */
private void parseAttributes ( Element e , String indent ) throws DASException , NoSuchTypeException { } }

implementation:
parseLevel ++ ; String subIndent = indent + "    " ; if ( _Debug ) System . out . println ( indent + "Parsing Attributes: " ) ; if ( _Debug ) System . out . println ( subIndent + "currentBT: " + currentBT . getTypeName ( ) + " " + currentBT . getClearName ( ) ) ; // Get all of the Attribute elements ( tagged < Attribute > )
for ( Element attrElement : e . getChildren ( "Attribute" , opendapNameSpace ) ) { String name = null ; Attribute nameAttr = attrElement . getAttribute ( "name" ) ; // no need to check that the getAttribute call worked because the Schema enforces
// the presence of the " name " attribute for the < Attribute > tag in the OPeNDAP namespace
name = nameAttr . getValue ( ) ; String typeName = null ; Attribute typeAttr = attrElement . getAttribute ( "type" ) ; // no need to check that the getAttribute call worked because the Schema enforces
// the presence of the " type " attribute for the < Attribute > tag in the OPeNDAP namespace
typeName = typeAttr . getValue ( ) ; // Is this Attribute a container ? ?
if ( typeName . equals ( "Container" ) ) { // Make sure that the document is valid for Attribute Containers and Values
Iterator valueChildren = attrElement . getChildren ( "value" , opendapNameSpace ) . iterator ( ) ; if ( valueChildren . hasNext ( ) ) throw new AttributeBadValueException ( "Container Attributes may " + "contain only other Attributes.\n" + "Container Attributes may NOT " + "contain values." ) ; // Cache the currentAT ( AttributeTable ) , this might be a null
// in which case the the container should be added to the currentBT .
AttributeTable cacheAttributeTable = currentAT ; if ( _Debug ) System . out . println ( indent + "currentBT: " + currentBT . getTypeName ( ) + " " + currentBT . getClearName ( ) ) ; if ( _Debug ) System . out . println ( indent + "Attribute '" + name + "' is type " + typeName ) ; // Add the Attribute container to the appropriate object .
// If the currentAT is null , this indicates that we are working
// on the top level attributes for the currentBT , if it ' s not
// then we are working on the Attributes for some AttributeTable
// contained within the top level Attributes in the currentBT .
// Set the currentAT to the newly built ( and returned ) AttributeTable
if ( currentAT == null ) currentAT = currentBT . appendAttributeContainer ( name ) ; else currentAT = currentAT . appendContainer ( name ) ; // Go parse the child Attributes of this Attribute table .
// Note that this is a recursive call .
parseAttributes ( attrElement , indent + "    " ) ; // Now parse all of the Aliases that exist in this Attribute table .
parseAliases ( attrElement , "+++ " ) ; // restore the currentAT from the cached one , thus regaining the
// the state that we entered this method with .
currentAT = cacheAttributeTable ; } else { // Make sure that the document is valid for Attribute Containers and Values
Iterator attrChildren = attrElement . getChildren ( "Attribute" , opendapNameSpace ) . iterator ( ) ; if ( attrChildren . hasNext ( ) ) throw new AttributeBadValueException ( "Attributes must be of type Container " + "in order to contain other Attributes.\n" + "Attributes of types other than Container " + "must contain values." ) ; // Walk through the < value > elements
for ( Element valueChild : attrElement . getChildren ( "value" , opendapNameSpace ) ) { // Get the content of the value .
// There are several methods for getting this content in the
// org . jdom2 . Element object . The method getText ( ) makes no effort
// to " normalize " the white space content . IE tabs , spaces ,
// carriage return , newlines are all preserved . This might not
// be the right thing to do , but only time will tell .
String value = valueChild . getText ( ) ; if ( _Debug ) { System . out . println ( subIndent + "Attribute '" + name + "' of " + currentBT . getClearName ( ) + " is type " + typeName + " and has value: " + value ) ; } // get the Attribute value type code .
int typeVal = opendap . dap . Attribute . getTypeVal ( typeName ) ; // Add the attribute and it ' s value to the appropriat
// container . Note that the interface for appending
// values to opendap . dap . Attributes is built such that
// the Attribute must be named each time . If the Attribte
// name already exists , then the value is added to the list
// of values for the Attribute . If the Attribute name does not
// already exist , a new Attribute is made to hold the value .
if ( currentAT == null ) currentBT . appendAttribute ( name , typeVal , value , true ) ; else currentAT . appendAttribute ( name , typeVal , value , true ) ; } } } parseLevel -- ;


signature:
public class DDSXMLParser { /** * Parse all of the Alias tags in this element of the XML document .
 * Add each one to the correct Attribute Table . */
private void parseAliases ( Element e , String indent ) throws DASException { } }

implementation:
parseLevel ++ ; String subIndent = indent + "    " ; if ( _Debug ) System . out . println ( indent + "Parsing Aliases: " ) ; if ( _Debug ) System . out . println ( subIndent + "currentBT: " + currentBT . getTypeName ( ) + " " + currentBT . getClearName ( ) ) ; // Get the Alias elements
for ( Element aliasElement : e . getChildren ( "Alias" , opendapNameSpace ) ) { String name = null ; Attribute nameAttr = aliasElement . getAttribute ( "name" ) ; // no need to check that the getAttribute call worked because the Schema enforces
// the presence of the " name " attribute for the < Alias > tag in the OPeNDAP namespace
name = nameAttr . getValue ( ) ; String attributeName = null ; Attribute attributeAttr = aliasElement . getAttribute ( "Attribute" ) ; // no need to check that the getAttribute call worked because the Schema enforces
// the presence of the " Attribute " attribute for the < Alias > tag in the OPeNDAP namespace
attributeName = attributeAttr . getValue ( ) ; if ( _Debug ) { System . out . println ( subIndent + "The name '" + name + "' is aliased to dds attribute: '" + attributeName + "'" ) ; } // Add the Alias to the appropriate container .
if ( currentAT == null ) currentBT . addAttributeAlias ( name , attributeName ) ; else currentAT . addAlias ( name , attributeName ) ; } parseLevel -- ;


signature:
public class DDSXMLParser { /** * This method is used to normalize strings prior
 * to their inclusion in XML documents . XML has certain parsing requirements
 * around reserved characters . These reserved characters must be replaced with
 * symbols recognized by the XML parser as place holder for the actual symbol .
 * The rule for this normalization is as follows :
 * < ul >
 * < li > The & lt ; ( less than ) character is replaced with & amp ; lt ;
 * < li > The & gt ; ( greater than ) character is replaced with & amp ; gt ;
 * < li > The & amp ; ( ampersand ) character is replaced with & amp ; amp ;
 * < li > The ' ( apostrophe ) character is replaced with & amp ; apos ;
 * < li > The & quot ; ( double quote ) character is replaced with & amp ; quot ;
 * < / ul >
 * @ param s The String to be normalized .
 * @ return The normalized String . */
public static String normalizeToXML ( String s ) { } }

implementation:
// Some handy definitons .
String xmlGT = ">" ; String xmlLT = "<" ; String xmlAmp = "&" ; String xmlApos = "'" ; String xmlQuote = """ ; boolean Debug = false ; StringBuilder sb = new StringBuilder ( s ) ; for ( int offset = 0 ; offset < sb . length ( ) ; offset ++ ) { char c = sb . charAt ( offset ) ; switch ( c ) { case '>' : // GreaterThan
sb . replace ( offset , offset + 1 , xmlGT ) ; break ; case '<' : // Less Than
sb . replace ( offset , offset + 1 , xmlLT ) ; break ; case '&' : // Ampersand
sb . replace ( offset , offset + 1 , xmlAmp ) ; break ; case '\'' : // Single Quote
sb . replace ( offset , offset + 1 , xmlApos ) ; break ; case '\"' : // Double Quote
sb . replace ( offset , offset + 1 , xmlQuote ) ; break ; default : break ; } } // Coverity [ DEADCODE ]
if ( Debug ) System . out . println ( "String: `" + s + "` normalized to: `" + sb + "`" ) ; return ( sb . toString ( ) ) ;


signature:
public class NcFeaturePropertyType { /** * wml2 : Collection / wml2 : observationMember / om : OM _ Observation / om : featureOfInterest */
public static FeaturePropertyType initFeatureOfInterest ( FeaturePropertyType featureOfInterest , StationTimeSeriesFeature stationFeat ) { } }

implementation:
// wml2 : MonitoringPoint
MonitoringPointDocument monitoringPointDoc = MonitoringPointDocument . Factory . newInstance ( ) ; NcMonitoringPointType . initMonitoringPointType ( monitoringPointDoc . addNewMonitoringPoint ( ) , stationFeat ) ; featureOfInterest . set ( monitoringPointDoc ) ; return featureOfInterest ;


signature:
public class DataDescriptorTreeConstructor { /** * convert ids to DataDescriptors , expand table D */
private List < DataDescriptor > decode ( List < Short > keyDesc , BufrTableLookup lookup ) { } }

implementation: if ( keyDesc == null ) return null ; List < DataDescriptor > keys = new ArrayList < DataDescriptor > ( ) ; for ( short id : keyDesc ) { DataDescriptor dd = new DataDescriptor ( id , lookup ) ; keys . add ( dd ) ; if ( dd . f == 3 ) { TableD . Descriptor tdd = lookup . getDescriptorTableD ( dd . fxy ) ; if ( tdd == null || tdd . getSequence ( ) == null ) { dd . bad = true ; } else { dd . name = tdd . getName ( ) ; dd . subKeys = decode ( tdd . getSequence ( ) , lookup ) ; } } } return keys ;


signature:
public class DataDescriptorTreeConstructor { /** * look for replication , move replicated items into subtree */
private List < DataDescriptor > replicate ( List < DataDescriptor > keys ) { } }

implementation:
List < DataDescriptor > tree = new ArrayList < DataDescriptor > ( ) ; Iterator < DataDescriptor > dkIter = keys . iterator ( ) ; while ( dkIter . hasNext ( ) ) { DataDescriptor dk = dkIter . next ( ) ; if ( dk . f == 1 ) { dk . subKeys = new ArrayList < DataDescriptor > ( ) ; dk . replication = dk . y ; // replication count
if ( dk . replication == 0 ) { // delayed replication
root . isVarLength = true ; // variable sized data = = deferred replication = = sequence data
// the next one is the replication count size : does not count in field count ( x )
DataDescriptor replication = dkIter . next ( ) ; if ( replication . y == 0 ) dk . replicationCountSize = 1 ; else if ( replication . y == 1 ) dk . replicationCountSize = 8 ; else if ( replication . y == 2 ) dk . replicationCountSize = 16 ; else if ( replication . y == 11 ) dk . repetitionCountSize = 8 ; else if ( replication . y == 12 ) dk . repetitionCountSize = 16 ; else log . error ( "Unknown replication type= " + replication ) ; } // transfer to the subKey list
for ( int j = 0 ; j < dk . x && dkIter . hasNext ( ) ; j ++ ) { dk . subKeys . add ( dkIter . next ( ) ) ; } // recurse
dk . subKeys = replicate ( dk . subKeys ) ; } else if ( ( dk . f == 3 ) && ( dk . subKeys != null ) ) { dk . subKeys = replicate ( dk . subKeys ) ; // do at all levels
} tree . add ( dk ) ; } return tree ;


signature:
public class DataDescriptorTreeConstructor { /** * / * try to grab names of compounds ( structs )
 * if f = 1 is followed by f = 3 , eg :
 * 0-40-20 : GQisFlagQualDetailed - Quality flag for the system
 * 1-01-010 : replication
 * 3-40-2 : ( IASI Level 1c band description )
 * 0-25-140 : Start channel
 * 0-25-141 : End channel
 * 0-25-142 : Channel scale factor
 * 1-01-087 : replication
 * 3-40-3 : ( IASI Level 1c 100 channels )
 * 1-04-100 : replication
 * 2-01-136 : Operator = change data width
 * 0-5-42 : Channel number
 * 2-01-000 : Operator = change data width
 * 0-14-46 : Scaled IASI radiance
 * 0-2-19 : Satellite instruments
 * 0-25-51 : AVHRR channel combination
 * 1-01-007 : replication
 * 3-40-4 : ( IASI Level 1c AVHRR single scene )
 * 0-5-60 : Y angular position from centre of gravity
 * 0-5-61 : Z angular position from centre of gravity
 * 0-25-85 : Fraction of clear pixels in HIRS FOV
 * sequence :
 * 3-60-4 : DRP1BIT
 * 1-01-000 : replication
 * 0-31-0 : DRF1BIT
 * 3-61-38 : TMPSQ2 SYNOPTIC REPORT WET BULB TEMPERATURE DATA
 * 0-2-39 : MWBT
 * 0-12-102 : TMWB
 * 0-13-3 : REHU
 * which has been preflattened into :
 * 1-01-000 : replication
 * 0-31-0 : DRF1BIT
 * 3-61-38 : TMPSQ2 SYNOPTIC REPORT WET BULB TEMPERATURE DATA
 * 0-2-39 : MWBT
 * 0-12-102 : TMWB
 * 0-13-3 : REHU */
private void grabCompoundNames ( List < DataDescriptor > tree ) { } }

implementation:
for ( int i = 0 ; i < tree . size ( ) ; i ++ ) { DataDescriptor key = tree . get ( i ) ; if ( key . bad ) continue ; if ( ( key . f == 3 ) && ( key . subKeys != null ) ) { grabCompoundNames ( key . subKeys ) ; } else if ( key . f == 1 && key . x == 1 && i < tree . size ( ) - 1 ) { // replicator with 1 element
DataDescriptor nextKey = tree . get ( i + 1 ) ; if ( nextKey . f == 3 ) { // the one element is a compound
if ( nextKey . name != null && ! nextKey . name . isEmpty ( ) ) key . name = nextKey . name ; } else if ( key . y == 0 && i < tree . size ( ) - 2 ) { // seq has an extra key before the 3
DataDescriptor nnKey = tree . get ( i + 2 ) ; if ( nnKey . f == 3 ) if ( nnKey . name != null && ! nnKey . name . isEmpty ( ) ) key . name = nnKey . name ; } } }


signature:
public class DataDescriptorTreeConstructor { /** * flatten the compounds ( type 3 ) ; but dont remove bad ones */
private void flatten ( List < DataDescriptor > result , List < DataDescriptor > tree ) { } }

implementation:
for ( DataDescriptor key : tree ) { if ( key . bad ) { root . isBad = true ; result . add ( key ) ; // add it anyway so we can see it in debug
continue ; } if ( ( key . f == 3 ) && ( key . subKeys != null ) ) { flatten ( result , key . subKeys ) ; } else if ( key . f == 1 ) { // flatten the subtrees
List < DataDescriptor > subTree = new ArrayList < DataDescriptor > ( ) ; flatten ( subTree , key . subKeys ) ; key . subKeys = subTree ; result . add ( key ) ; } else { result . add ( key ) ; } }


signature:
public class DataDescriptorTreeConstructor { /** * assume theres only one in effect at a time */
private void operate ( List < DataDescriptor > tree ) { } }

implementation:
if ( tree == null ) return ; boolean hasAssFields = false ; // boolean hasDpiFields = false ;
DataDescriptor . AssociatedField assField = null ; // 02 04 Y
Iterator < DataDescriptor > iter = tree . iterator ( ) ; while ( iter . hasNext ( ) ) { DataDescriptor dd = iter . next ( ) ; if ( dd . f == 2 ) { if ( dd . x == 1 ) { changeWidth = ( dd . y == 0 ) ? null : dd ; iter . remove ( ) ; } else if ( dd . x == 2 ) { changeScale = ( dd . y == 0 ) ? null : dd ; iter . remove ( ) ; // throw new UnsupportedOperationException ( " 2-2 - Y ( change scale ) " ) ;
} else if ( dd . x == 3 ) { changeRefval = ( dd . y == 255 ) ? null : dd ; iter . remove ( ) ; // throw new UnsupportedOperationException ( " 2-3 - Y ( change reference values ) " ) ; / / untested - no examples
} else if ( dd . x == 4 ) { assField = ( dd . y == 0 ) ? null : new DataDescriptor . AssociatedField ( dd . y ) ; iter . remove ( ) ; hasAssFields = true ; } else if ( dd . x == 5 ) { // char data - this allows arbitrary string to be inserted
dd . type = 1 ; // String
dd . bitWidth = dd . y * 8 ; dd . name = "Note" ; } else if ( dd . x == 6 ) { // see L3-82 ( 3.1.6.5)
// " Y bits of data are described by the immediately following descriptor " . could they speak English ?
iter . remove ( ) ; if ( ( dd . y != 0 ) && iter . hasNext ( ) ) { // fnmoc using 2-6-0 as cancel ( apparently )
DataDescriptor next = iter . next ( ) ; next . bitWidth = dd . y ; } } else if ( dd . x == 7 ) { changeWtf = ( dd . y == 0 ) ? null : dd ; iter . remove ( ) ; } else if ( dd . x == 36 ) { if ( iter . hasNext ( ) ) { DataDescriptor dpi_dd = iter . next ( ) ; // this should be a replicated data present field
dpi = new DataPresentIndicator ( tree , dpi_dd ) ; dd . dpi = dpi ; dpi_dd . dpi = dpi ; } } else if ( ( dd . x == 37 ) && ( dd . y == 255 ) ) { // cancel dpi
dpi = null ; } else if ( ( dd . x == 24 ) && ( dd . y == 255 ) ) { dd . dpi = dpi ; } } else if ( dd . subKeys != null ) { operate ( dd . subKeys ) ; } else if ( dd . f == 0 ) { if ( dd . type != 3 ) { // numeric or string or enum , not compound
if ( changeWidth != null ) dd . bitWidth += changeWidth . y - 128 ; if ( changeScale != null ) dd . scale += changeScale . y - 128 ; if ( changeRefval != null ) dd . refVal += changeRefval . y - 128 ; // LOOK wrong
if ( changeWtf != null && dd . type == 0 ) { // see I . 2 – BUFR Table C — 4
// For Table B elements , which are not CCITT IA5 ( character data ) , code tables , or flag tables :
// 1 . Add Y to the existing scale factor
// 2 . Multiply the existing reference value by 10 Y
// 3 . Calculate ( ( 10 x Y ) + 2 ) ÷ 3 , disregard any fractional remainder and add the result to the existing bit width .
// HAHAHAHAHAHAHAHA
int y = changeWtf . y ; dd . scale += y ; dd . refVal *= Math . pow ( 10 , y ) ; int wtf = ( ( 10 * y ) + 2 ) / 3 ; dd . bitWidth += wtf ; } } if ( ( dd . f == 0 ) && ( assField != null ) ) { assField . nfields ++ ; dd . assField = assField ; assField . dataFldName = dd . name ; } } } if ( hasAssFields ) addAssFields ( tree ) ; // if ( hasDpiFields ) addDpiFields ( tree ) ;