ncsa.hdf.object.h4.H4File Maven / Gradle / Ivy
/*****************************************************************************
* Copyright by The HDF Group. *
* Copyright by the Board of Trustees of the University of Illinois. *
* All rights reserved. *
* *
* This file is part of the HDF Java Products distribution. *
* The full copyright notice, including terms governing use, modification, *
* and redistribution, is contained in the files COPYING and Copyright.html. *
* COPYING can be found at the root of the source code distribution tree. *
* Or, see http://hdfgroup.org/products/hdf-java/doc/Copyright.html. *
* If you do not have access to either file, you may request a copy from *
* [email protected]. *
****************************************************************************/
package ncsa.hdf.object.h4;
import java.io.File;
import java.lang.reflect.Array;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.MutableTreeNode;
import javax.swing.tree.TreeNode;
import ncsa.hdf.hdflib.HDFConstants;
import ncsa.hdf.hdflib.HDFException;
import ncsa.hdf.hdflib.HDFLibrary;
import ncsa.hdf.object.Attribute;
import ncsa.hdf.object.Dataset;
import ncsa.hdf.object.Datatype;
import ncsa.hdf.object.FileFormat;
import ncsa.hdf.object.Group;
import ncsa.hdf.object.HObject;
/**
* This class provides file level APIs. File access APIs include retrieving the
* file hierarchy, opening and closing file, and writing file content to disk.
*
* @version 2.4 9/4/2007
* @author Peter X. Cao
*/
public class H4File extends FileFormat
{
/**
*
*/
private static final long serialVersionUID = 8985533001471224030L;
// make sure that the library is loaded.
static { HDFLibrary.loadH4Lib(); }
/**
* the file access flag.
*/
private int flag;
/**
* The root node of the tree structure of this file.
*/
private DefaultMutableTreeNode rootNode;
/**
* The list of unique (tag, ref) pairs.
* It is used to avoid duplicate objects in memory.
*/
private List objList;
/**
* The GR interface identifier.
* The identifier is returned by GRstart(fid), which initializes the GR
* interface for the file specified by the parameter. GRstart(fid) is an
* expensive call. It should be called only once. Calling GRstart(fid) in
* a loop should be avoided.
*/
private int grid;
private boolean isNetCDF = false;
/**
* The SDS interface identifier.
* The identifier is returned by SDstart(fname, flag), which initializes the
* SD interface for the file specified by the parameter.
* SDstart(fname, flag) is an expensive call. It should be called only once
* Calling SDstart(fname, flag) in a loop should be avoided.
*/
private int sdid;
/* secret flag: show CDF0.0, etc., to help debug
*/
private boolean showAll = false;
/**
* Creates an H4File with read only access.
*/
public H4File()
{
this("", WRITE);
}
/**
* Creates an H4File with read only access.
*/
public H4File(String pathname)
{
this(pathname, WRITE);
}
/**
* Creates an H4File instance with specified file name and access.
*
* The access parameter values and corresponding behaviors:
*
* - READ: Read-only access; open() will fail file doesn't exist.
*
- WRITE: Read/Write access; if file doesn't exist, open() will
* create it; open() will fail if read/write access not allowed.
*
- CREATE: Read/Write access; create a new file or truncate
* an existing one; open() will fail if file can't be created or if
* file exists but can't be opened read/write.
*
*
* This constructor does not open the file for access, nor does it
* confirm that the file can later be opened read/write or created.
*
* The flag returned by {@link #isReadOnly()} is set to true if the access
* parameter value is READ, even though the file isn't yet open.
*
* @param fileName A valid file name, with a relative or absolute path.
* @param access The file access flag, which determines behavior when file
* is opened.
* Acceptable values are READ, WRITE,
* and CREATE
.
* @throws NullPointerException If the fileName
argument is
* null
.
*/
public H4File(String fileName, int access)
{
super(fileName);
isReadOnly = (access == READ);
objList = new Vector();
this.fid = -1;
if (access == READ) {
flag = HDFConstants.DFACC_READ;
} else if (access == WRITE) {
flag = HDFConstants.DFACC_WRITE;
} else if (access == CREATE) {
flag = HDFConstants.DFACC_CREATE;
} else {
flag = access;
}
String shwAll = System.getProperty("h4showall");
if (shwAll != null) {
showAll = true;
//System.err.println("show all is on");
} else {
//System.err.println("show all is off");
}
}
/**
* Checks if the given file format is an HDF4 file.
*
* @param fileformat the fileformat to be checked.
* @return true if the given file is an HDF4 file; otherwise returns false.
*/
@Override
public boolean isThisType(FileFormat fileformat)
{
return (fileformat instanceof H4File);
}
/**
* Checks if the given file is an HDF4 file or netCDF.
* HDF4 library supports netCDF version 2.3.2. It only supports SDS APIs.
*
* @param filename the file to be checked.
* @return true if the given file is an HDF4 file; otherwise returns false.
*/
@Override
public boolean isThisType(String filename)
{
boolean isH4 = false;
try {
isH4 = HDFLibrary.Hishdf(filename);
} catch (HDFException ex)
{
isH4 = false;
}
if (!isH4) {
isH4 = isNetCDF(filename);
}
return isH4;
}
/**
* Creates an HDF4 file with the specified name and returns a new
* H4File instance associated with the file.
*
* @throws HDFException If the file cannot be created or if createFlag
* has unexpected value.
* @see ncsa.hdf.object.FileFormat#createFile(java.lang.String, int)
* @see #H4File(String, int)
*/
@Override
public FileFormat createFile(String filename, int createFlag)
throws Exception
{
// Flag if we need to create or truncate the file.
Boolean doCreateFile = true;
// Won't create or truncate if CREATE_OPEN specified and file exists
if (createFlag == FILE_CREATE_OPEN) {
File f = new File( filename );
if ( f.exists() ) {
doCreateFile = false;
}
}
if (doCreateFile) {
int fileid = HDFLibrary.Hopen(filename, HDFConstants.DFACC_CREATE);
try {
HDFLibrary.Hclose(fileid);
} catch (HDFException ex) {}
}
return new H4File(filename, WRITE);
}
/**
* Creates an H4File instance with specified file name and access.
*
* @see ncsa.hdf.object.FileFormat#createInstance(java.lang.String, int)
* @see #H4File(String, int)
*/
@Override
public FileFormat createInstance(String filename, int access)
throws Exception
{
return new H4File(filename, access);
}
// Implementing FileFormat
@Override
public int open() throws Exception
{
if ( fid >=0 ) {
return fid; // file is openned already
}
// check for valid file access permission
if (flag < 0) // invalid access id
{
throw new HDFException("Invalid access identifer -- "+flag);
}
else if (flag == HDFConstants.DFACC_READ)
{
if (!exists()) {
throw new HDFException("File does not exist -- "+fullFileName);
} else if (exists() && !canRead()) {
throw new HDFException("Cannot read file -- "+fullFileName);
}
}
else if ((flag == HDFConstants.DFACC_WRITE) ||
(flag == HDFConstants.DFACC_CREATE))
{
if (exists() && !canWrite()) {
throw new HDFException("Cannot write file, try open as read-only -- "+fullFileName);
}
}
isNetCDF = isNetCDF(fullFileName);
if (isNetCDF) {
isReadOnly = true; // read only for netCDF
}
// only support SDS APIs for netCDF
if (isNetCDF) {
fid = 0;
} else {
fid = HDFLibrary.Hopen( fullFileName, flag);
HDFLibrary.Vstart(fid);
grid = HDFLibrary.GRstart(fid);
}
sdid = HDFLibrary.SDstart(fullFileName, flag);
// load the file hierarchy
rootNode = loadTree();
return fid;
}
// Implementing FileFormat
@Override
public void close() throws HDFException
{
// clean unused objects
if (rootNode != null)
{
DefaultMutableTreeNode theNode = null;
HObject theObj = null;
Enumeration local_enum = (rootNode).breadthFirstEnumeration();
while(local_enum.hasMoreElements())
{
theNode = (DefaultMutableTreeNode)local_enum.nextElement();
theObj = (HObject)theNode.getUserObject();
if (theObj instanceof Dataset) {
((Dataset)theObj).clearData();
}
theObj = null;
theNode = null;
}
}
try { HDFLibrary.GRend(grid); } catch (HDFException ex) {}
try { HDFLibrary.SDend(sdid); } catch (HDFException ex) {}
try { HDFLibrary.Vend(fid); } catch (HDFException ex) {}
HDFLibrary.Hclose(fid);
fid = -1;
objList = null;
}
// Implementing FileFormat
@Override
public TreeNode getRootNode()
{
return rootNode;
}
@Override
public Group createGroup(String name, Group pgroup) throws Exception
{
return H4Group.create(name, pgroup);
}
@Override
public Datatype createDatatype(
int tclass,
int tsize,
int torder,
int tsign) throws Exception
{
return new H4Datatype(tclass, tsize, torder, tsign);
}
@Override
public Datatype createDatatype(
int tclass,
int tsize,
int torder,
int tsign,
String name) throws Exception
{
throw new UnsupportedOperationException("HDF4 does not support named datatype.");
}
@Override
public Dataset createScalarDS(
String name,
Group pgroup,
Datatype type,
long[] dims,
long[] maxdims,
long[] chunks,
int gzip,
Object fillValue,
Object data) throws Exception
{
return H4SDS.create(name, pgroup, type, dims, maxdims, chunks, gzip, fillValue, data);
}
@Override
public Dataset createImage(
String name,
Group pgroup,
Datatype type,
long[] dims,
long[] maxdims,
long[] chunks,
int gzip,
int ncomp,
int interlace,
Object data) throws Exception
{
H4GRImage dataset = H4GRImage.create(name, pgroup, type, dims, maxdims, chunks, gzip, ncomp, interlace, data);
return dataset;
}
/**
* Delete an object from the file.
* @param obj the data object to delete.
*/
@Override
public void delete(HObject obj) throws Exception
{
throw (new UnsupportedOperationException(
"Cannot delete HDF4 object."));
}
/**
* Copy an object to a group.
* @param srcObj the object to copy.
* @param dstGroup the destination group.
* @return the new node containing the new object.
*/
@Override
public TreeNode copy(HObject srcObj, Group dstGroup, String dstName) throws Exception
{
TreeNode newNode = null;
if ((srcObj == null) || (dstGroup == null)) {
return null;
}
if (dstName == null) {
dstName = srcObj.getName();
}
if (srcObj instanceof H4SDS)
{
newNode = new DefaultMutableTreeNode(
((H4SDS)srcObj).copy(dstGroup, dstName, null, null));
}
else if (srcObj instanceof H4GRImage)
{
newNode = new DefaultMutableTreeNode(
((H4GRImage)srcObj).copy(dstGroup, dstName, null, null));
}
else if (srcObj instanceof H4Vdata)
{
newNode = new DefaultMutableTreeNode(((H4Vdata)srcObj).copy(dstGroup, null, null, null));
}
else if (srcObj instanceof H4Group)
{
newNode = copyGroup((H4Group)srcObj, (H4Group)dstGroup);
}
return newNode;
}
/**
* Creates a new attribute and attached to the object if attribute does
* not exist. Otherwise, just update the value of the attribute.
*
*
* @param obj the object which the attribute is to be attached to.
* @param attr the attribute to attach.
* @param isSDglobalAttr The indicator if the given attribute exists.
*/
@Override
public void writeAttribute(HObject obj, Attribute attr,
boolean isSDglobalAttr) throws HDFException
{
String attrName = attr.getName();
int attrType = attr.getType().toNative();
long[] dims = attr.getDataDims();
int count = 1;
if (dims != null)
{
for (int i=0; i count)
{
// truncate the extra characters
strValue = strValue.substring(0, count);
Array.set(attrValue, 0, strValue);
}
else
{
// pad space to the unused space
for (int i=strValue.length(); i0))
{
Iterator iterator = members.iterator();
while (iterator.hasNext())
{
HObject mObj = (HObject)iterator.next();
try {
newNode.add((MutableTreeNode)copy(mObj, group));
} catch (Exception ex) {}
}
}
srcGroup.close(srcgid);
try { HDFLibrary.Vdetach(dstgid); }
catch (Exception ex) { ; }
return newNode;
}
/**
* Retrieves and returns the file structure from disk.
*
* First gets the top level objects or objects that do not belong to any groups.
* If a top level object is a group, call the depth_first() to retrieve
* the sub-tree of that group, recursively.
*
*/
private DefaultMutableTreeNode loadTree()
{
if (fid <0 ) {
return null;
}
long[] oid = {0, 0};
int n=0, ref=-1;
int[] argv = null;
MutableTreeNode node = null;
H4Group rootGroup = new H4Group(
this,
"/",
null, // root node does not have a parent path
null, // root node does not have a parent node
oid);
DefaultMutableTreeNode root = new DefaultMutableTreeNode(rootGroup)
{
private static final long serialVersionUID = 3507473044690724650L;
@Override
public boolean isLeaf() { return false; }
};
// get top level VGroup
int[] tmpN = new int[1];
int[] refs = null;
try {
// first call to get the number of lone Vgroup
n = HDFLibrary.Vlone(fid, tmpN, 0);
refs = new int[n];
// second call to get the references of all lone Vgroup
n = HDFLibrary.Vlone(fid, refs, n);
} catch (HDFException ex) { n = 0; }
int i0 = Math.max(0, getStartMembers());
int i1 = getMaxMembers();
if (i1 >= n)
{
i1 = n;
i0 = 0; // load all members
}
i1 += i0;
i1 = Math.min(i1, n);
//Iterate through the file to see members of the group
for ( int i = i0; i < i1; i++)
{
ref = refs[i];
H4Group g = getVGroup(HDFConstants.DFTAG_VG, ref, HObject.separator, rootGroup, false);
if (g != null)
{
node = new DefaultMutableTreeNode(g)
{
private static final long serialVersionUID = 8927502967802143369L;
@Override
public boolean isLeaf() { return false; }
};
root.add( node );
rootGroup.addToMemberList(g);
// recursively get the sub-tree
depth_first(node, null);
}
} // for (int i=0; i
* @param parentNode the parent node.
*/
private void depth_first(MutableTreeNode parentNode, H4Group pgroup)
{
if ((pgroup == null) && (parentNode == null)) {
return;
}
//System.out.println("H4File.depth_first() pnode = "+parentNode);
int nelems=0, ref=-1, tag=-1, index=-1;
int[] tags = null;
int[] refs = null;
MutableTreeNode node = null;
DefaultMutableTreeNode pnode = null;
if (parentNode != null) {
pnode = (DefaultMutableTreeNode)parentNode;
pgroup = (H4Group)(pnode.getUserObject());
}
String fullPath = pgroup.getPath()+pgroup.getName()+HObject.separator;
int gid = pgroup.open();
if (gid == HDFConstants.FAIL)
{
return;
}
try
{
nelems = HDFLibrary.Vntagrefs(gid);
tags = new int[nelems];
refs = new int[nelems];
nelems = HDFLibrary.Vgettagrefs(gid, tags, refs, nelems);
} catch (HDFException ex)
{
nelems = 0;
} finally
{
pgroup.close(gid);
}
int i0 = Math.max(0, getStartMembers());
int i1 = getMaxMembers();
if (i1 >= nelems)
{
i1 = nelems;
i0 = 0; // load all members
}
i1 += i0;
i1 = Math.min(i1, nelems);
//Iterate through the file to see members of the group
for ( int i = i0; i < i1; i++)
{
tag = tags[i];
ref = refs[i];
switch (tag)
{
case HDFConstants.DFTAG_RIG:
case HDFConstants.DFTAG_RI:
case HDFConstants.DFTAG_RI8:
try {
index = HDFLibrary.GRreftoindex(grid, (short)ref);
} catch (HDFException ex)
{
index = HDFConstants.FAIL;
}
if (index != HDFConstants.FAIL)
{
H4GRImage gr = getGRImage(tag, index, fullPath, true);
pgroup.addToMemberList(gr);
if ((gr != null) && (pnode != null))
{
node = new DefaultMutableTreeNode(gr);
pnode.add( node );
}
}
break;
case HDFConstants.DFTAG_SD:
case HDFConstants.DFTAG_SDG:
case HDFConstants.DFTAG_NDG:
try {
index = HDFLibrary.SDreftoindex(sdid, ref);
} catch (HDFException ex)
{
index = HDFConstants.FAIL;
}
if (index != HDFConstants.FAIL)
{
H4SDS sds = getSDS(tag, index, fullPath, true);
pgroup.addToMemberList(sds);
if ((sds != null) && (pnode != null))
{
node = new DefaultMutableTreeNode(sds);
pnode.add( node );
}
}
break;
case HDFConstants.DFTAG_VH:
case HDFConstants.DFTAG_VS:
H4Vdata vdata = getVdata(tag, ref, fullPath, true);
pgroup.addToMemberList(vdata);
if ((vdata != null) && (pnode != null))
{
node = new DefaultMutableTreeNode(vdata);
pnode.add( node );
}
break;
case HDFConstants.DFTAG_VG:
H4Group vgroup = getVGroup(tag, ref, fullPath, pgroup, true);
pgroup.addToMemberList(vgroup);
if ((vgroup != null) && (pnode != null))
{
node = new DefaultMutableTreeNode(vgroup)
{
private static final long serialVersionUID = -8774836537322039221L;
@Override
public boolean isLeaf() { return false; }
};
pnode.add( node );
// check for loops
boolean looped = false;
DefaultMutableTreeNode theNode = pnode;
while ((theNode != null) && !looped)
{
H4Group theGroup = (H4Group)theNode.getUserObject();
long[] oid = {tag, ref};
if (theGroup.equalsOID(oid)) {
looped = true;
} else {
theNode = (DefaultMutableTreeNode)theNode.getParent();
}
}
if (!looped) {
depth_first(node, null);
}
}
break;
default:
break;
} //switch (tag)
} //for (int i=0; i
* @param index the index of the image.
* @param path the path of the image.
* @param copyAllowed The indicator if multiple copies of an object is allowed.
* @return the new H5GRImage if successful; otherwise returns null.
*/
private final H4GRImage getGRImage(int tag, int index, String path, boolean copyAllowed)
{
int id=-1, ref=-1;
H4GRImage gr = null;
String[] objName = {""};
int[] imgInfo = new int[4];
int[] dim_sizes = {0, 0};
//int tag = HDFConstants.DFTAG_RIG;
try
{
id = HDFLibrary.GRselect(grid, index);
ref = HDFLibrary.GRidtoref(id);
HDFLibrary.GRgetiminfo(id, objName, imgInfo, dim_sizes);
} catch (HDFException ex)
{
id = HDFConstants.FAIL;
}
finally
{
try { HDFLibrary.GRendaccess(id); }
catch (HDFException ex ) {}
}
if (id != HDFConstants.FAIL)
{
long oid[] = {tag, ref};
if (copyAllowed)
{
objList.add(oid);
} else if (find(oid))
{
return null;
}
gr = new H4GRImage(
this,
objName[0],
path,
oid);
}
return gr;
}
/**
* Retrieve a SDS for the given sds identifier and index.
*
* @param sdid the SDS idendifier.
* @param index the index of the SDS.
* @param path the path of the SDS.
* @param copyAllowed The indicator if multiple copies of an object is allowed.
* @return the new H4SDS if successful; otherwise returns null.
*/
private final H4SDS getSDS(int tag, int index, String path, boolean copyAllowed)
{
int id=-1, ref=-1;
H4SDS sds = null;
String[] objName = {""};
int[] tmpInfo = new int[HDFConstants.MAX_VAR_DIMS];
int[] sdInfo = {0, 0, 0};
//int tag = HDFConstants.DFTAG_NDG;
boolean isCoordvar = false;
try
{
id = HDFLibrary.SDselect(sdid, index);
if (isNetCDF)
{
ref = index; //HDFLibrary.SDidtoref(id) fails for netCDF
tag = H4SDS.DFTAG_NDG_NETCDF;
} else {
ref = HDFLibrary.SDidtoref(id);
}
HDFLibrary.SDgetinfo(id, objName, tmpInfo, sdInfo);
isCoordvar = HDFLibrary.SDiscoordvar(id);
} catch (HDFException ex)
{
id = HDFConstants.FAIL;
}
finally
{
try { HDFLibrary.SDendaccess(id); }
catch (HDFException ex) {}
}
// check if the given SDS has dimension metadata
// Coordinate variables are not displayed. They are created to store
// metadata associated with dimensions. To ensure compatibility with
// netCDF, coordinate variables are implemented as data sets
if (isCoordvar)
{
objName[0] += " (dimension)";
}
if (id != HDFConstants.FAIL)// && !isCoordvar)
{
long oid[] = {tag, ref};
if (copyAllowed)
{
objList.add(oid);
} else if (find(oid))
{
return null;
}
sds = new H4SDS(
this,
objName[0],
path,
oid);
}
return sds;
}
/**
* Retrieve a Vdata for the given Vdata identifier and index.
*
* @param ref the reference idendifier of the Vdata.
* @param path the path of the Vdata.
* @param copyAllowed The indicator if multiple copies of an object is allowed.
* @return the new H4Vdata if successful; otherwise returns null.
*/
private final H4Vdata getVdata(int tag, int ref, String path, boolean copyAllowed)
{
int id=-1;
H4Vdata vdata = null;
String[] objName = {""};
String[] vClass = {""};
//int tag = HDFConstants.DFTAG_VS;
long oid[] = {tag, ref};
if (copyAllowed)
{
objList.add(oid);
} else if (find(oid))
{
return null;
}
try
{
id = HDFLibrary.VSattach(fid, ref, "r");
HDFLibrary.VSgetclass(id, vClass);
vClass[0] = vClass[0].trim();
HDFLibrary.VSgetname(id, objName);
} catch (HDFException ex)
{
id = HDFConstants.FAIL;
}
finally
{
try { HDFLibrary.VSdetach(id); }
catch (HDFException ex) {}
}
if (showAll || ((id != HDFConstants.FAIL) &&
// do not display Vdata named "Attr0.0" // commented out for bug 1737
//!vClass[0].equalsIgnoreCase(HDFConstants.HDF_ATTRIBUTE) &&
// do not display internal Vdata, "_HDF_CHK_TBL_"
!vClass[0].startsWith(HDFConstants.HDF_CHK_TBL) &&
// do not display internal vdata for CDF, "CDF0.0"
!vClass[0].equalsIgnoreCase(HDFConstants.HDF_CDF)))
{
vdata = new H4Vdata(
this,
objName[0],
path,
oid);
}
return vdata;
}
/**
* Retrieve a VGroup for the given VGroup identifier and index.
*
* @param ref the reference idendifier of the VGroup.
* @param path the path of the VGroup.
* @param pgroup the parent group.
* @param copyAllowed The indicator if multiple copies of an object is allowed.
* @return the new H4VGroup if successful; otherwise returns null.
*/
private final H4Group getVGroup(int tag, int ref, String path, H4Group pgroup, boolean copyAllowed)
{
int id=-1;
H4Group vgroup = null;
String[] objName = {""};
String[] vClass = {""};
//int tag = HDFConstants.DFTAG_VG;
long oid[] = {tag, ref};
if (copyAllowed)
{
objList.add(oid);
} else if (find(oid))
{
return null;
}
try
{
id = HDFLibrary.Vattach(fid, ref, "r");
HDFLibrary.Vgetclass(id, vClass);
vClass[0] = vClass[0].trim();
HDFLibrary.Vgetname(id, objName);
} catch (HDFException ex)
{
id = HDFConstants.FAIL;
}
finally
{
try { HDFLibrary.Vdetach(id); }
catch (HDFException ex) {}
}
// ignore the Vgroups created by the GR interface
if (showAll || ((id != HDFConstants.FAIL) &&
// do not display Vdata named "Attr0.0"
!vClass[0].equalsIgnoreCase(HDFConstants.GR_NAME) &&
!vClass[0].equalsIgnoreCase(HDFConstants.RI_NAME) &&
!vClass[0].equalsIgnoreCase(HDFConstants.RIGATTRNAME) &&
!vClass[0].equalsIgnoreCase(HDFConstants.RIGATTRCLASS) &&
!vClass[0].equalsIgnoreCase(HDFConstants.HDF_CDF)))
{
vgroup = new H4Group( this, objName[0], path, pgroup, oid);
}
return vgroup;
}
/**
* Check if object already exists in memory by match the (tag, ref) pairs.
*/
private final boolean find(long[] oid)
{
boolean existed = false;
if (objList == null) {
return false;
}
int n = objList.size();
long[] theOID = null;
for (int i=0; i
* @param fid the file identifier.
* @param attrList the list of attributes.
* @return the updated attribute list.
*/
private List getFileAnnotation(int fid, List attrList)
throws HDFException
{
if (fid < 0 ) {
return attrList;
}
int anid = HDFConstants.FAIL;
try
{
anid = HDFLibrary.ANstart(fid);
// fileInfo[0] = n_file_label, fileInfo[1] = n_file_desc,
// fileInfo[2] = n_data_label, fileInfo[3] = n_data_desc
int[] fileInfo = new int[4];
HDFLibrary.ANfileinfo(anid, fileInfo);
if (fileInfo[0]+fileInfo[1] <= 0)
{
try { HDFLibrary.ANend(anid); } catch (HDFException ex) {}
return attrList;
}
if (attrList == null) {
attrList = new Vector(fileInfo[0]+fileInfo[1], 5);
}
// load file labels and descriptions
int id = -1;
int[] annTypes = {HDFConstants.AN_FILE_LABEL, HDFConstants.AN_FILE_DESC};
for (int j=0; j<2; j++)
{
String annName = null;
if (j == 0) {
annName = "File Label";
} else {
annName = "File Description";
}
for (int i=0; i < fileInfo[j]; i++)
{
try {
id = HDFLibrary.ANselect(anid, i, annTypes[j]);
} catch (HDFException ex)
{
id = HDFConstants.FAIL;
}
if (id == HDFConstants.FAIL)
{
try { HDFLibrary.ANendaccess(id); } catch (HDFException ex) {}
continue;
}
int length = 0;
try {
length = HDFLibrary.ANannlen(id)+1;
} catch (HDFException ex)
{
length = 0;
}
if (length > 0)
{
boolean b = false;
String str[] = {""};
try { b = HDFLibrary.ANreadann(id, str, length);
} catch ( HDFException ex) { b = false; }
if (b && (str[0].length()>0))
{
long attrDims[] = {str[0].length()};
Attribute newAttr = new Attribute(
annName +" #"+i,
new H4Datatype(HDFConstants.DFNT_CHAR),
attrDims);
attrList.add(newAttr);
newAttr.setValue(str[0]);
}
}
try { HDFLibrary.ANendaccess(id); } catch (HDFException ex) {}
} // for (int i=0; i < fileInfo[annTYpe]; i++)
} // for (int annType=0; annType<2; annType++)
} finally
{
try { HDFLibrary.ANend(anid); } catch (HDFException ex) {}
}
return attrList;
}
/**
* Reads GR globle attributes into memory.
* The attributes sre stroed as attributes of the root group.
*
* @param grid the GR identifier.
* @param attrList the list of attributes.
* @return the updated attribute list.
*/
private List getGRglobleAttribute(int grid, List attrList)
throws HDFException
{
if (grid == HDFConstants.FAIL) {
return attrList;
}
int[] attrInfo = {0, 0};
HDFLibrary.GRfileinfo(grid, attrInfo);
int numberOfAttributes = attrInfo[1];
if (numberOfAttributes>0)
{
if (attrList == null) {
attrList = new Vector(numberOfAttributes, 5);
}
String[] attrName = new String[1];
for (int i=0; i0)
return attrList;
}
/**
* Reads SDS globle attributes into memory.
* The attributes sre stroed as attributes of the root group.
*
* @param sdid the SD identifier.
* @param attrList the list of attributes.
* @return the updated attribute list.
*/
private List getSDSglobleAttribute(int sdid, List attrList)
throws HDFException
{
if (sdid == HDFConstants.FAIL) {
return attrList;
}
int[] attrInfo = {0, 0};
HDFLibrary.SDfileinfo(sdid, attrInfo);
int numberOfAttributes = attrInfo[1];
if (numberOfAttributes>0)
{
if (attrList == null) {
attrList = new Vector(numberOfAttributes, 5);
}
String[] attrName = new String[1];
for (int i=0; i0)
return attrList;
}
/**
* Returns the version of the HDF4 library.
*/
@Override
public String getLibversion()
{
int[] vers = new int[3];
String ver = "HDF ";
String[] verStr = {""};
try { HDFLibrary.Hgetlibversion(vers, verStr); }
catch (HDFException ex) {}
ver += vers[0] + "." + vers[1] +"."+vers[2];
return ver;
}
/** HDF4 library supports netCDF version 2.3.2. It only supports SDS APIs.*/
private boolean isNetCDF(String filename)
{
boolean isnetcdf = false;
java.io.RandomAccessFile raf = null;
try { raf = new java.io.RandomAccessFile(filename, "r"); }
catch (Exception ex)
{
try { raf.close();} catch (Exception ex2) {}
raf = null;
}
if (raf == null) {
return false;
}
byte[] header = new byte[4];
try { raf.read(header); }
catch (Exception ex) { header = null; }
if (header != null)
{
if (
// netCDF
((header[0]==67) &&
(header[1]==68) &&
(header[2]==70) &&
(header[3]==1)) ) {
isnetcdf = true;
} else {
isnetcdf = false;
}
}
try { raf.close();} catch (Exception ex) {}
return isnetcdf;
}
/**
* Get an individual HObject with a given path. It deoes not load the whole
* file structure.
*/
@Override
public HObject get(String path) throws Exception
{
if (objList == null) {
objList = new Vector();
}
if ((path == null) || (path.length() <= 0)) {
return null;
}
path = path.replace('\\', '/');
if (!path.startsWith("/")) {
path = "/"+path;
}
String name=null, pPath=null;
boolean isRoot = false;
if (path.equals("/"))
{
name = "/"; // the root
isRoot = true;
} else
{
if (path.endsWith("/")) {
path = path.substring(0, path.length()-2);
}
int idx = path.lastIndexOf('/');
name = path.substring(idx+1);
if (idx == 0) {
pPath = "/";
} else {
pPath = path.substring(0, idx);
}
}
HObject obj = null;
isReadOnly = false;
if (fid < 0)
{
fid = HDFLibrary.Hopen( fullFileName, HDFConstants.DFACC_WRITE);
if (fid < 0)
{
isReadOnly = true;
fid = HDFLibrary.Hopen( fullFileName, HDFConstants.DFACC_READ);
}
HDFLibrary.Vstart(fid);
grid = HDFLibrary.GRstart(fid);
sdid = HDFLibrary.SDstart(fullFileName, flag);
}
if (isRoot) {
obj = getRootGroup();
} else {
obj = getAttachedObject(pPath, name);
}
return obj;
}
/** get the root group and all the alone objects */
private H4Group getRootGroup()
{
H4Group rootGroup = null;
long[] oid = {0, 0};
int n=0, ref=-1;
int[] argv = null;
rootGroup = new H4Group(this,"/", null, null, oid);
// get top level VGroup
int[] tmpN = new int[1];
int[] refs = null;
try {
// first call to get the number of lone Vgroup
n = HDFLibrary.Vlone(fid, tmpN, 0);
refs = new int[n];
// second call to get the references of all lone Vgroup
n = HDFLibrary.Vlone(fid, refs, n);
} catch (HDFException ex) { n = 0; }
//Iterate through the file to see members of the group
for ( int i = 0; i < n; i++)
{
ref = refs[i];
H4Group g = getVGroup(HDFConstants.DFTAG_VG, ref, HObject.separator, rootGroup, false);
if (g != null) {
rootGroup.addToMemberList(g);
}
} // for (int i=0; i= 0 ) {
return getGRImage(HDFConstants.DFTAG_RIG, idx, HObject.separator, false);
}
// get top level SDS
try {
idx = HDFLibrary.SDnametoindex(sdid, name);
} catch (HDFException ex) { idx = -1; }
if ( idx >= 0 )
{
return getSDS(HDFConstants.DFTAG_NDG, idx, HObject.separator, false);
} // if (sdid != HDFConstants.FAIL && HDFLibrary.SDfileinfo(sdid, argv))
int ref = 0;
try {
ref = HDFLibrary.Vfind(fid, name);
} catch (HDFException ex) { ref = -1; }
if (ref > 0)
{
long oid[] = {HDFConstants.DFTAG_VG, ref};
H4Group g = new H4Group( this, objName[0], path, null, oid);
depth_first(null, g);
return g;
}
// get top level VData
try {
ref = HDFLibrary.VSfind(fid, name);
} catch (HDFException ex) { ref = -1; }
if (ref > 0)
{
return getVdata(HDFConstants.DFTAG_VS, ref, HObject.separator, false);
} // for (int i=0; i