Skip to content
obergshavefun edited this page Mar 29, 2016 · 17 revisions

This page contains code snippets that show how a particular task may be accomplished in HDF.PInvoke. All examples using hid_t assume the statement using hid_t = System.Int32; at the top of the source file.

Attributes

String Attributes

This snippet reads the value from an attribute attached to the specified objectId.

private bool ReadStringAttribute(hid_t objectId, string title, out string value)
{
  value = "";

  hid_t attributeId = 0;
  hid_t typeId = 0;

  try
  {
    attributeId = H5A.open(objectId, title);
    typeId = H5A.get_type(attributeId);
    var sizeData = H5T.get_size(typeId);
    var size = sizeData.ToInt32();
    byte[] strBuffer = new byte[size];

    var aTypeMem = H5T.get_native_type(typeId, H5T.direction_t.ASCEND);
    GCHandle pinnedArray = GCHandle.Alloc(strBuffer, GCHandleType.Pinned);
    H5A.read(attributeId, aTypeMem, pinnedArray.AddrOfPinnedObject());
    pinnedArray.Free();
    H5T.close(aTypeMem);

    value = System.Text.ASCIIEncoding.ASCII.GetString(strBuffer);

    return true;
  }
  catch (Exception ex)
  {
    return false;
  }
  finally
  {
    if (attributeId != null) H5A.close(attributeId);
    if (typeId != null) H5T.close(typeId);
  }
}

Here we create an attribute attached to the given objectId:

private bool CreateStringAttribute(hid_t objectId, string title, string description)
{
  hid_t attributeSpace = 0;
  hid_t stringId = 0;
  hid_t attributeId = 0;

  try
  {
    attributeSpace = H5S.create(H5S.class_t.SCALAR);
    stringId = H5T.copy(H5T.C_S1);
    H5T.set_size(stringId, new IntPtr(description.Length));
    attributeId = H5A.create(objectId, title, stringId, attributeSpace);

    IntPtr descriptionArray = Marshal.StringToHGlobalAnsi(description);
    H5A.write(attributeId, stringId, descriptionArray);

    Marshal.FreeHGlobal(descriptionArray);

    return true;
  }
  catch (Exception ex)
  {
    return false;
  }
  finally
  {
    if (attributeId != 0) H5A.close(attributeId);
    if (stringId != 0) H5T.close(stringId);
    if (attributeSpace != 0) H5S.close(attributeSpace);
  }
}

Strings

Reading a dataset composed of an array of strings

This snipped reads an array of strings from the specified file. The array is padded with spaces to ensure that each record is aligned properly. The parameter recordLength specifies the width of each record.

private bool ReadStringArray(hid_t fileId, string datasetPath, int recordLength, out string[] datasetOut)
{
  datasetOut = null;
  List<string> dataset = new List<string>();

  hid_t dataSetId = 0;
  hid_t dataSpaceId = 0;
  hid_t typeId = 0;

  try
  {
    dataSetId = H5D.open(fileId, datasetPath);
    dataSpaceId = H5D.get_space(dataSetId);
    typeId = H5T.copy(H5T.C_S1);
    H5T.set_size(typeId, new IntPtr(recordLength));

    int rank = H5S.get_simple_extent_ndims(dataSpaceId);
    ulong[] dims = new ulong[rank];
    ulong[] maxDims = new ulong[rank];
    H5S.get_simple_extent_dims(dataSpaceId, dims, maxDims);
    byte[] dataBytes = new byte[dims[0] * (ulong)recordLength];

    GCHandle pinnedArray = GCHandle.Alloc(dataBytes, GCHandleType.Pinned);
    H5D.read(dataSetId, typeId, H5S.ALL, H5S.ALL, H5P.DEFAULT, pinnedArray.AddrOfPinnedObject());
    pinnedArray.Free();

    for (int i = 0; i < (int)(dims[0]); i++)
    {
      byte[] slice = dataBytes.Skip<byte>(i * recordLength).Take<byte>(recordLength).ToArray<byte>();
      var content = System.Text.Encoding.ASCII.GetString(slice).Trim();
      dataset.Add(content);
    }
  }
  catch (Exception ex)
  {
    return false;
  }
  finally
  {
    if (typeId != 0) H5T.close(typeId);
    if (dataSpaceId != 0) H5S.close(dataSpaceId);
    if (dataSetId != 0) H5D.close(dataSetId);
  }

  datasetOut = dataset.ToArray();

  return true;
}