All Downloads are FREE. Search and download functionalities are using the official Maven repository.

ucar.atd.dorade.DoradeDescriptor Maven / Gradle / Ivy

Go to download

The NetCDF-Java Library is a Java interface to NetCDF files, as well as to many other types of scientific data formats.

There is a newer version: 4.3.22
Show newest version
/*
 * Copyright 1998-2009 University Corporation for Atmospheric Research/Unidata
 *
 * Portions of this software were developed by the Unidata Program at the
 * University Corporation for Atmospheric Research.
 *
 * Access and use of this software shall impose the following obligations
 * and understandings on the user. The user is granted the right, without
 * any fee or cost, to use, copy, modify, alter, enhance and distribute
 * this software, and any derivative works thereof, and its supporting
 * documentation for any purpose whatsoever, provided that this entire
 * notice appears in all copies of the software, derivative works and
 * supporting documentation.  Further, UCAR requests that the user credit
 * UCAR/Unidata in any publications that result from the use of this
 * software or in any product that includes this software. The names UCAR
 * and/or Unidata, however, may not be used in any advertising or publicity
 * to endorse or promote any products or commercial entity unless specific
 * written permission is obtained from UCAR/Unidata. The user also
 * understands that UCAR/Unidata is not obligated to provide the user with
 * any support, consulting, training or assistance of any kind with regard
 * to the use, operation and performance of this software nor to provide
 * the user with any updates, revisions, new versions or "bug fixes."
 *
 * THIS SOFTWARE IS PROVIDED BY UCAR/UNIDATA "AS IS" AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL UCAR/UNIDATA BE LIABLE FOR ANY SPECIAL,
 * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
 * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
 * WITH THE ACCESS, USE OR PERFORMANCE OF THIS SOFTWARE.
 */
package ucar.atd.dorade;

import java.io.RandomAccessFile;
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
import java.util.HashMap;

/**
 * 

Title: DoradeDescriptor

*

Description: Abstract class to hold one of the many types of * DORADE descriptors

*

Copyright: Copyright (c) 2003

*

Company: University Corporation for Atmospheric Research

* @author Chris Burghart */ abstract class DoradeDescriptor { protected String descName; protected String expectedName; protected RandomAccessFile file; protected boolean littleEndianData; protected boolean verbose; protected static final TimeZone TZ_UTC = TimeZone.getTimeZone("UTC"); private static boolean defaultVerboseState = false; // map from descriptor names to per-class default verbose states private static HashMap classVerboseStates = new HashMap(); /** *

Title: DescriptorException

*

Description: generic class for Exception-s from * DoradeDescriptor-s.

*

Copyright: Copyright (c) 2003

*

Company: University Corporation for Atmospheric Research

* @version $Revision:51 $ $Date:2006-07-12 17:13:13Z $ */ static class DescriptorException extends Exception { protected DescriptorException(String message) { super(message); } protected DescriptorException(Throwable cause) { super(cause); } } /** * Read and set the descriptor name, size, and endianness, and return the * entire contents of the descriptor (including the name and size) as a * byte array. The file position will be left at the beginning of the next * descriptor (or at the end of file). * @param file the DORADE sweepfile, positioned at the beginning of a * descriptor * @param littleEndianData set to true iff the file contains little-endian * data * @param expectedName the expected name for the descriptor being read * @throws DescriptorException for file read errors, descriptor name * mismatch, etc. */ protected byte[] readDescriptor(RandomAccessFile file, boolean littleEndianData, String expectedName) throws DescriptorException { this.file = file; this.littleEndianData = littleEndianData; this.expectedName = expectedName; verbose = getDefaultVerboseState(expectedName); byte[] data = null; try { // // find the next descriptor with our expected name // findNext(file); // // keep track of the start of this descriptor // long startpos = file.getFilePointer(); // // get the name and descriptor size // byte[] header = new byte[8]; file.read(header); descName = new String(header, 0, 4); int size = grabInt(header, 4); // // now back up to the start of the descriptor and read the entire // thing into a byte array // file.seek(startpos); data = new byte[size]; file.read(data); } catch (java.io.IOException ex) { throw new DescriptorException(ex); } // // now check the name we got against the expected name // if (! descName.equals(expectedName)) throw new DescriptorException("Got descriptor name '" + descName + "' when expecting name '" + expectedName + "'"); return data; } /** * Skip the current DORADE descriptor in the file, leaving the file position * at the beginning of the next descriptor (or at the end of file). * @param file the DORADE sweepfile, positioned at the beginning of a * descriptor * @throws java.io.IOException */ protected static void skipDescriptor(RandomAccessFile file, boolean littleEndianData) throws DescriptorException, java.io.IOException { try { file.read(new byte[4]); // skip name byte[] lenBytes = new byte[4]; file.read(lenBytes); int descLen = grabInt(lenBytes, 0, littleEndianData); file.read(new byte[descLen - 8]); } catch (java.io.EOFException eofex) { return; // just leave the file at EOF } catch (Exception ex) { throw new DescriptorException(ex); } } /** * Return the name of the DORADE descriptor at the current location * in the file. The current location will not be changed. * * @param file the DORADE sweep file, positioned at the beginning of a * descriptor * @return the name of the DORADE descriptor starting at the current * file position, or null if no descriptor name is available * @throws DescriptorException */ protected static String peekName(RandomAccessFile file) throws DescriptorException { try { long filepos = file.getFilePointer(); byte[] nameBytes = new byte[4]; if (file.read(nameBytes) == -1) return null; // EOF file.seek(filepos); return new String(nameBytes); } catch (Exception ex) { throw new DescriptorException(ex); } } /** * Determine if the given DORADE sweepfile contains little-endian data * (in violation of the DORADE definition...). * @param file the DORADE sweepfile, * @return true iff the file contains little-endian data * @throws DescriptorException */ public static boolean sweepfileIsLittleEndian(RandomAccessFile file) throws DescriptorException { int descLen; try { file.seek(0); // // skip the 4-byte descriptor name // byte[] bytes = new byte[4]; file.read(bytes); // // get the descriptor length // descLen = file.readInt(); file.seek(0); } catch (Exception ex) { throw new DescriptorException(ex); } return (descLen < 0 || descLen > 0xffffff); } /** * Unpack a two-byte integer from the given byte array. * @param bytes byte array to be read * @param offset number of bytes to skip in the byte array before reading * @return the unpacked short value */ protected short grabShort(byte[] bytes, int offset) { int ndx0 = offset + (littleEndianData ? 1 : 0); int ndx1 = offset + (littleEndianData ? 0 : 1); // careful that we only allow sign extension on the highest order byte return (short)(bytes[ndx0] << 8 | (bytes[ndx1] & 0xff)); } /** * Unpack a four-byte integer from the given byte array. * @param bytes byte array to be read * @param offset number of bytes to skip in the byte array before reading * @param littleEndianData true iff the byte array contains little-endian * data * @return the unpacked integer value */ protected static int grabInt(byte[] bytes, int offset, boolean littleEndianData) { int ndx0 = offset + (littleEndianData ? 3 : 0); int ndx1 = offset + (littleEndianData ? 2 : 1); int ndx2 = offset + (littleEndianData ? 1 : 2); int ndx3 = offset + (littleEndianData ? 0 : 3); // careful that we only allow sign extension on the highest order byte return (int)(bytes[ndx0] << 24 | (bytes[ndx1] & 0xff) << 16 | (bytes[ndx2] & 0xff) << 8 | (bytes[ndx3] & 0xff)); } /** * Unpack a four-byte integer from the given byte array. * @param bytes byte array to be read * @param offset number of bytes to skip in the byte array before reading * @return the unpacked integer value */ protected int grabInt(byte[] bytes, int offset) { return grabInt(bytes, offset, littleEndianData); } /** * Unpack a four-byte IEEE float from the given byte array. * @param bytes byte array to be read * @param offset number of bytes to skip in the byte array before reading * @return the unpacked float value */ protected float grabFloat(byte[] bytes, int offset) throws DescriptorException { try { byte[] src; if (littleEndianData) { src = new byte[4]; src[0] = bytes[offset + 3]; src[1] = bytes[offset + 2]; src[2] = bytes[offset + 1]; src[3] = bytes[offset + 0]; offset = 0; } else { src = bytes; } DataInputStream stream = new DataInputStream(new ByteArrayInputStream(src, offset, 4)); return stream.readFloat(); } catch (Exception ex) { throw new DescriptorException(ex); } } /** * Unpack an eight-byte IEEE float from the given byte array. * @param bytes byte array to be read * @param offset number of bytes to skip in the byte array before reading * @return the unpacked double value */ protected double grabDouble(byte[] bytes, int offset) throws DescriptorException { try { byte[] src; if (littleEndianData) { src = new byte[8]; src[0] = bytes[offset + 7]; src[1] = bytes[offset + 6]; src[2] = bytes[offset + 5]; src[3] = bytes[offset + 4]; src[4] = bytes[offset + 3]; src[5] = bytes[offset + 2]; src[6] = bytes[offset + 1]; src[7] = bytes[offset + 0]; offset = 0; } else { src = bytes; } DataInputStream stream = new DataInputStream(new ByteArrayInputStream(src, offset, 8)); return stream.readDouble(); } catch (Exception ex) { throw new DescriptorException(ex); } } protected static long findNextWithName(String expectedName, RandomAccessFile file, boolean littleEndianData) throws DescriptorException, java.io.IOException { // // Skip forward through the file until we find a descriptor with // the expected name // String descName; while ((descName = peekName(file)) != null) { if (descName.equals(expectedName)) { try { return file.getFilePointer(); } catch (java.io.IOException ex) { throw new DescriptorException(ex); } } skipDescriptor(file, littleEndianData); } throw new DescriptorException("Expected " + expectedName + " descriptor not found!"); } protected long findNext(RandomAccessFile file) throws DescriptorException, java.io.IOException { return findNextWithName(expectedName, file, littleEndianData); } /** * Return a string with a reasonable and complete representation of the * given Date, shown in UTC. * @param date Date to be represented * @return a string containing the representation of the date */ public static String formatDate(Date date) { SimpleDateFormat df = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss.SSS z"); df.setTimeZone(TZ_UTC); return df.format(date); } /** * Get the default verbose state for new DoradeDescriptor-s. */ public static boolean getDefaultVerboseState() { return defaultVerboseState; } /** * Set the default verbose state for new DoradeDescriptor-s. * @param verbose the new default verbose state */ public static void setDefaultVerboseState(boolean verbose) { defaultVerboseState = verbose; classVerboseStates.clear(); } /** * Get the default verbose state for new DoradeDescriptor-s * of the given name. * @param descriptorName the descriptor name for which the new default * verbose state will apply */ public static boolean getDefaultVerboseState(String descriptorName) { Boolean classVerboseState = classVerboseStates.get(descriptorName.toUpperCase()); if (classVerboseState != null) return classVerboseState; else return defaultVerboseState; } /** * Set the default verbose state for new DoradeDescriptor-s * of the given name. * @param descriptorName the descriptor name for which the new default * verbose state will apply * @param verbose the new default verbose state */ public static void setDefaultVerboseState(String descriptorName, boolean verbose) { classVerboseStates.put(descriptorName.toUpperCase(), verbose); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy