1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238
|
package uk.ac.bristol.star.cdf.util;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import uk.ac.bristol.star.cdf.AttributeEntry;
import uk.ac.bristol.star.cdf.CdfContent;
import uk.ac.bristol.star.cdf.CdfReader;
import uk.ac.bristol.star.cdf.DataType;
import uk.ac.bristol.star.cdf.GlobalAttribute;
import uk.ac.bristol.star.cdf.Variable;
import uk.ac.bristol.star.cdf.VariableAttribute;
/**
* Utility to describe a CDF file, optionally with record data.
* Intended to be used from the commandline via the <code>main</code> method.
* The output format is somewhat reminiscent of the <code>cdfdump</code>
* command in the CDF distribution.
*
* @author Mark Taylor
* @since 21 Jun 2013
*/
public class CdfList {
private final CdfContent cdf_;
private final PrintStream out_;
private final boolean writeData_;
private static final String[] NOVARY_MARKS = { "{ ", " }" };
private static final String[] VIRTUAL_MARKS = { "[ ", " ]" };
private static final String[] REAL_MARKS = { " ", "" };
/**
* Constructor.
*
* @param cdf CDF content
* @param out output stream for listing
* @param writeData true if data values as well as metadata are to
* be written
*/
public CdfList( CdfContent cdf, PrintStream out, boolean writeData ) {
cdf_ = cdf;
out_ = out;
writeData_ = writeData;
}
/**
* Does the work, writing output.
*/
public void run() throws IOException {
// Read the CDF.
GlobalAttribute[] gAtts = cdf_.getGlobalAttributes();
VariableAttribute[] vAtts = cdf_.getVariableAttributes();
Variable[] vars = cdf_.getVariables();
// Write global attribute information.
header( "Global Attributes" );
for ( int iga = 0; iga < gAtts.length; iga++ ) {
GlobalAttribute gAtt = gAtts[ iga ];
out_.println( " " + gAtt.getName() );
AttributeEntry[] entries = gAtt.getEntries();
for ( int ie = 0; ie < entries.length; ie++ ) {
out_.println( " " + entries[ ie ] );
}
}
// Write variable information.
for ( int iv = 0; iv < vars.length; iv++ ) {
out_.println();
Variable var = vars[ iv ];
header( "Variable " + var.getNum() + ": " + var.getName()
+ " --- " + var.getSummary() );
for ( int ia = 0; ia < vAtts.length; ia++ ) {
VariableAttribute vAtt = vAtts[ ia ];
AttributeEntry entry = vAtt.getEntry( var );
if ( entry != null ) {
out_.println( " " + vAtt.getName() + ":\t" + entry );
}
}
// Optionally write variable data as well.
if ( writeData_ ) {
DataType dataType = var.getDataType();
Object abuf = var.createRawValueArray();
boolean isVar = var.getRecordVariance();
int nrec = var.getRecordCount();
int nrdigit = Integer.toString( nrec ).length();
for ( int ir = 0; ir < nrec; ir++ ) {
var.readRawRecord( ir, abuf );
final String[] marks;
if ( ! isVar ) {
marks = NOVARY_MARKS;
}
else if ( ! var.hasRecord( ir ) ) {
marks = VIRTUAL_MARKS;
}
else {
marks = REAL_MARKS;
}
String sir = Integer.toString( ir );
StringBuffer sbuf = new StringBuffer()
.append( marks[ 0 ] )
.append( CdfDump.spaces( nrdigit - sir.length() ) )
.append( sir )
.append( ':' )
.append( '\t' )
.append( formatValues( abuf, dataType ) )
.append( marks[ 1 ] );
out_.println( sbuf.toString() );
}
}
}
}
/**
* Applies string formatting to a value of a given data type.
*
* @param abuf array buffer containing data
* @param dataType data type for data
* @return string representation of value
*/
private String formatValues( Object abuf, DataType dataType ) {
StringBuffer sbuf = new StringBuffer();
if ( abuf == null ) {
}
else if ( abuf.getClass().isArray() ) {
int groupSize = dataType.getGroupSize();
int len = Array.getLength( abuf );
for ( int i = 0; i < len; i += groupSize ) {
if ( i > 0 ) {
sbuf.append( ", " );
}
sbuf.append( dataType.formatArrayValue( abuf, i ) );
}
}
else {
sbuf.append( dataType.formatScalarValue( abuf ) );
}
return sbuf.toString();
}
/**
* Writes a header to the output listing.
*
* @param txt header text
*/
private void header( String txt ) {
out_.println( txt );
StringBuffer sbuf = new StringBuffer( txt.length() );
for ( int i = 0; i < txt.length(); i++ ) {
sbuf.append( '-' );
}
out_.println( sbuf.toString() );
}
/**
* Does the work for the command line tool, handling arguments.
* Sucess is indicated by the return value.
*
* @param args command-line arguments
* @return 0 for success, non-zero for failure
*/
public static int runMain( String[] args ) throws IOException {
// Usage string.
String usage = new StringBuffer()
.append( "\n Usage: " )
.append( CdfList.class.getName() )
.append( " [-help]" )
.append( " [-verbose]" )
.append( " [-data]" )
.append( " <cdf-file>" )
.append( "\n" )
.toString();
// Process arguments.
List<String> argList = new ArrayList<String>( Arrays.asList( args ) );
File file = null;
boolean writeData = false;
int verb = 0;
for ( Iterator<String> it = argList.iterator(); it.hasNext(); ) {
String arg = it.next();
if ( arg.startsWith( "-h" ) ) {
it.remove();
System.out.println( usage );
return 0;
}
else if ( arg.equals( "-verbose" ) || arg.equals( "-v" ) ) {
it.remove();
verb++;
}
else if ( arg.equals( "+verbose" ) || arg.equals( "+v" ) ) {
it.remove();
verb--;
}
else if ( arg.equals( "-data" ) ) {
it.remove();
writeData = true;
}
else if ( file == null ) {
it.remove();
file = new File( arg );
}
}
// Validate arguments.
if ( ! argList.isEmpty() ) {
System.err.println( "Unused args: " + argList );
System.err.println( usage );
return 1;
}
if ( file == null ) {
System.err.println( usage );
return 1;
}
// Configure and run.
LogUtil.setVerbosity( verb );
new CdfList( new CdfContent( new CdfReader( file ) ),
System.out, writeData ).run();
return 0;
}
/**
* Main method. Use -help for arguments.
*/
public static void main( String[] args ) throws IOException {
int status = runMain( args );
if ( status != 0 ) {
System.exit( status );
}
}
}
|