/*
VisAD system for interactive analysis and visualization of numerical
data.  Copyright (C) 1996 - 2017 Bill Hibbard, Curtis Rueden, Tom
Rink, Dave Glowacki, Steve Emmerson, Tom Whittaker, Don Murray, and
Tommy Jasmin.

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Library General Public License for more details.

You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
MA 02111-1307, USA
*/

/****************************************************************************
 * NCSA HDF                                                                 *
 * National Comptational Science Alliance                                   *
 * University of Illinois at Urbana-Champaign                               *
 * 605 E. Springfield, Champaign IL 61820                                   *
 *                                                                          *
 * For conditions of distribution and use, see the accompanying             *
 * hdf/COPYING file.                                                        *
 *                                                                          *
 ****************************************************************************/


package visad.data.hdf5;

import visad.*;
import visad.data.*;
import visad.UnimplementedException;
import java.rmi.*;
import java.net.URL;

import ncsa.hdf.hdf5lib.H5;
import ncsa.hdf.hdf5lib.HDF5Constants;
import ncsa.hdf.hdf5lib.HDF5CDataTypes;
import ncsa.hdf.hdf5lib.exceptions.HDF5Exception;

/**
	HDF5Form is a data form adapter for HDF5 files. 
 */
public class HDF5Form
	extends Form
	implements FormFileInformer
{
	public HDF5Form()
	{
		this( "HDF5 Data" );
	}

	public HDF5Form(String name )
	{
		super( name );
	}

	public boolean isThisType(String name)
	{
		boolean retVal = false;

		try { retVal = H5.H5Fis_hdf5(name); }
		catch (Exception ex) {;}

		return retVal;
	}

	public boolean isThisType(byte[] block)
	{
		int firstByte = (new Byte(block[0]).intValue());
		if (firstByte != 137)
			return false;

		String bytes2to4 = new String( block, 1, 4 );
		return bytes2to4.startsWith("HDF");
	}

	public String[] getDefaultSuffixes()
	{
		String[] suffs = { "hdf", "h5"};
		return suffs;
	}

	public FormNode getForms( Data data )
	{
		return this;
	}

	public DataImpl open( String file_path )
		throws VisADException, RemoteException
	{
		HDF5FileAdapted file = null;

		try {
			file = new HDF5FileAdapted(
				file_path,
				HDF5Constants.H5F_ACC_RDONLY,
				HDF5Constants.H5P_DEFAULT );
		} catch (HDF5Exception e) {System.err.println(e); }

		return getFileData( file );
	}

	public DataImpl open( URL url )
		throws VisADException
	{
		throw new UnimplementedException( "HDF5Form.open( URL )" );
	}

	public void add( String id, Data data, boolean replace )
		throws BadFormException
	{
		throw new BadFormException( "HDF5Form.add( String, Data, boolean )" );
	}

	public void save( String filename, Data data, boolean replace )
		throws BadFormException, RemoteException, VisADException
	{
		//System.out.println("\n\nHDF5Form.save called.");

		int fid=0, did=0, gid=0;

		try {
			fid = H5.H5Fcreate(filename,
				HDF5Constants.H5F_ACC_TRUNC,
				HDF5Constants.H5P_DEFAULT,
				HDF5Constants.H5P_DEFAULT);
		} catch (HDF5Exception e) {
			throw new HDF5AdapterException(
			"HDF5Form.save() failed: cannot create file "+filename);
		} catch (NoClassDefFoundError e) {
			throw new HDF5AdapterException(
			"HDF5Form.save() failed: cannot create file "+filename);
                }

		try { save(fid, data, 0, 0); }
		catch (BadFormException e) {
			throw e;
		}
		catch (RemoteException e) {
			throw e;
		}
		catch (VisADException e) {
			throw e;
		}
		catch (HDF5Exception e) {
			throw new HDF5AdapterException(e.toString());
		}
		finally {
			try{H5.H5Fclose(fid);} catch (Exception e) {}
		}
	}

	/** Save only tuple and field.
		Tuple is mapped to HDF5 groups and Field is mapped to
		HDF5 dataset. Only the first range value, i.e. value[][0]
		is written to the output file. We don't know how to deal
		with compound data.
	 */
	private void save( int pid, Data data, int level, int index)
		throws BadFormException, RemoteException, VisADException, HDF5Exception
	{
		if (data instanceof Tuple)
		{
			int g_idx=0, new_pid=0;
			Data d = null;
			Tuple tuple = (Tuple)data;

			String gname = "Group"+index+"at"+level;

			if (level==0 )
			{
				new_pid=pid;
                g_idx = -1;
			}
			else
			{
				new_pid = H5.H5Gcreate(pid, gname, -1);
			}

			int	n = tuple.getDimension();
			for (int i = 0; i < n; i++)
			{
				d = tuple.getComponent(i);
				//if (data instanceof Tuple) g_idx++;
				save(new_pid, d, level+1, g_idx++);
			}
		}
		else if (data instanceof Field)
		{
			Field field = (Field)data;
			RealType[] rTypes = ((FunctionType) field.getType()).getRealComponents();

			Set dset = field.getDomainSet();
			if (!(dset instanceof GriddedSet) ||
				rTypes == null)
				return;

			GriddedSet domain = (GriddedSet)dset;
			RealType rangeType = (RealType) rTypes[0];

			int sid=0, did=0, tid=0;
			int l = domain.getLength();
			int[] ddims = domain.getLengths();
			int rank = ddims.length;
			long[] dims = new long[rank];
			for (int i=0; i 

Ads help maintain this website.