// ------------------------------------------------------------------------------
// NeXus - Neutron & X-ray Common Data Format
//
// API Delphi/Kylix Interface
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser 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
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser 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
//
// Contact for bug reports and problems :
//           F. Ott <fott@cea.fr>
//           Lab. Léon Brillouin CEA/CNRS
//           CE Saclay
//           91191 Gif sur Yvette, FRANCE
//
// For further information, see <http://www.neutron.anl.gov/NeXus/>
//
// ------------------------------------------------------------------------------
//
//  Interface unit for the NexusCoreDelphiAPI.dll library.
//
{ TO BE NOTED                                                                   }
{ * do not use the 'cdecl' calling convention, it does not work                 }
{ * the program does not seem to be sensitive to the value of NX_MaxLen         }
{   could it be that the routines resize the data automatically ?<<             }
{ * at the moment, it is not possible to use dynamical arrays directly into the C procedures  }
{   thus, the data are first copied into an fixed size array                    }
{   in the case of 2D and 3D arrays this copy may proove qute long              }
{ * the length of the arrays is set by the variable NX_MaxLen                   }
{   However, the program looks non sensitive to this size                       }
{   but htis may lead to memory problems in the long term                       }
{   If it is a pointer that is passed in the procedure, no memory leak should occur }
{   BUT, the Delphi array do not recognize the size if the arrays !!!           }
{   Nota : dynamical arrays do not work (but they are useless in practice       }
{ * the range chekcing should be deactivated                                    }
{ * NXMaxLen should be rather large                                             }
{ * a NXentry folder MUST exist otherwise lots of features simply do not work!  }
{ * the type NXhandle is replaced by integer (INT32)                            }
{   (should not make any difference                                             }
{ * putAttr cannot put attributes to a folder                                   }
{ BUGS                                                                          }
{ * un close sans fichier ouvert plante le programme                            }
{ * in NXgetattrChar everything must be called as ref otherwise it does not work !!! }
{   name should be pased as value                                               }
{ * GetDataID does not give the same value as the browser (720 instead of 700.) }
{ FUTURE IMPROVEMENTS                                                           }
{ * at the moment it is not possible to use Dynamical Arrays in the low levels  }
{   calls to the Nexus API                                                      }
{   NX_MaxLen fixes the size of the largest arrays that can be used             }
{   Even though in the Utilities Functions dynamical arrays are used, the low   }
{   level call require a transfer via static arrays ?!                          }
{   Sorry for this current limitation                                           }
{ === BUGS related to the NEXus C API                                           }
{ * in NXgetattrChar everything must be called as ref otherwise it does not work !!! }
{   for several procedures, some parameters must be passed by ref even though   }
{   it is not useful and even less documented                                   }
{ * NOTA : NXgetInfo and NXmakeData dimensions are inverted wrt gal API         }
{   that is the dimensions are given as follow NXdims[1,2,3]:=X,Y,Z ...         }
{   Otherwise, the calls are too awkward is Pascal (and in Fortran BTW)         }

unit NexusCoreDelphiAPI;

interface

uses
    Classes, SysUtils, variants;

const
// *** NeXus version parameter
   NeXus_version = '1.3.3';
// *** NeXus file access parameters
   NXACC_READ = 1;
   NXACC_RDWR = 3;
   NXACC_CREATE = 4;
// *** NeXus status parameters
   NX_OK = 1;
   NX_ERROR = 0;
   NX_EOD = -1;
// *** NeXus datatype parameters
   NX_CHAR    = 4;
   NX_FLOAT32 = 5;
   NX_FLOAT64 = 6;
   NX_INT8    = 20;
   NX_UINT8   = 21;
   NX_INT16   = 22;
   NX_UINT16  = 23;
   NX_INT32   = 24;
   NX_UINT32  = 25;
// *** NeXus compression parameters
   NX_COMP_LZW  = 4; // Defined by HDF in HCOMP.H
   NX_COMP_RLE  = 1;
   NX_COMP_HUF  = 3;
   NX_COMP_NONE = 0;
// *** NeXus Unlimited parameters
   NX_UNLIMITED = 0;
// *** NeXus limits
   NX_MAXRANK = 32; // Defined by HDF in HLIMITS.H
   NX_MAXNAMELEN = 64;
   NX_MAXSTACK = 50;

   NX_MaxLen = 2097152; //262144; // 16384; // max elements of arrays (corresponds to a max of 128x128 2D arrays}


type
    // The following datatypes corresponds to Fortran datatypes.
    TCharacter255 = array [0..255] of char;
    dimensions    = array [1..NX_maxrank] of integer; { array storing the length for the different dimensions }

    TFloat32array  = array [0..NX_MaxLen] of single;
    TFloat64array  = array [0..NX_MaxLen] of double;
    TInt8Array     = array [0..NX_MaxLen] of shortint;
    TUInt8Array    = array [0..NX_MaxLen] of byte;
    TInt16Array    = array [0..NX_MaxLen] of smallint;
    TUInt16Array   = array [0..NX_MaxLen] of word;
    TInt32Array    = array [0..NX_MaxLen] of integer;
    TUInt32Array   = array [0..NX_MaxLen] of longword;
    { dynamics arrays for use with the NXU API }
    TDynArrayChar      = array of char;
    TDynArrayInt32     = array of integer;
    TDynArrayFloat32   = array of single;
    TDynArrayFloat64   = array of double;
    TDynArray2DChar    = array of array of char;
    TDynArray2DInt32   = array of array of integer;
    TDynArray2DFloat32 = array of array of single;
    TDynArray2DFloat64 = array of array of double;
    TDynArray3DChar    = array of array of array of char;
    TDynArray3DInt32   = array of array of array of integer;
    TDynArray3DFloat32 = array of array of array of single;
    TDynArray3DFloat64 = array of array of array of double;

    NXlink = record
      tag:integer;
      ref:integer
      end;


Var { on definit quelques variables utiles en variables globales YUK!!! }

    dataF32:TFloat32array;

    dataF64:TFloat64array;
    dataI8:TInt8Array;
    dataUI8:TUInt8Array;
    dataI16:TInt16Array;
    dataUI16:TUInt16Array;
    dataI32:TInt32Array;
    dataUI32:TUInt32Array;

//
// Procedures publically available.
//
function setlength2D(var d:TDynArray2DInt32;sizeX,sizeY:integer):integer; overload;
function setlength2D(var d:TDynArray2DFloat32;sizeX,sizeY:integer):integer; overload;
function setlength2D(var d:TDynArray2DFloat64;sizeX,sizeY:integer):integer; overload;
function StrToPChar(s:string):Tcharacter255;

function NXopen(
    file_name : TCharacter255;
    access_method : integer;
    var file_id : integer):integer; stdcall; { ok }

function NXclose(
    file_id : integer):integer; stdcall; { ok }

function NXmakegroup(
    file_id : integer;
    group_name : TCharacter255;
    group_class : TCharacter255):integer; stdcall; { ok }

function NXopengroup(
    file_id : integer;
    group_name : TCharacter255;
    group_class : TCharacter255):integer; stdcall; { ok }

function NXclosegroup(
    file_id : integer):integer; stdcall; { ok }

function NXmakedata(
    file_id : integer;
    data_name : TCharacter255;
    data_type : integer;
    rank : integer;
    NXdims: dimensions):integer; stdcall; { ok }

function NXopendata(
    file_id : integer;
    data_name : TCharacter255):integer; stdcall;  { ok }

function NXcompress(
    file_id : integer;
    compress_type : integer):integer; stdcall; { ok }

function NXclosedata(
    file_id : integer):integer; stdcall; { ok }

{ ========= NXgetData ========== }
function NXgetdata(file_id:integer;var data:integer):integer; stdcall; overload;
function NXgetdata(file_id:integer;var data:single):integer; stdcall; overload;
function NXgetdata(file_id:integer;var data:double):integer; stdcall; overload;
function NXgetdata(file_id:integer;var data:string):integer; stdcall; overload;
function NXgetdata(file_id:integer;var data:TDynArrayInt32):integer; stdcall; overload;
function NXgetdata(file_id:integer;var data:TDynArrayFloat32):integer; stdcall; overload;
function NXgetdata(file_id:integer;var data:TDynArrayFloat64):integer; stdcall; overload;
function NXgetdata(file_id:integer;var data:TDynArray2DInt32):integer; stdcall; overload;
function NXgetdata(file_id:integer;var data:TDynArray2DFloat32):integer; stdcall; overload;
function NXgetdata(file_id:integer;var data:TDynArray2DFloat64):integer; stdcall; overload;
function NXgetdataChar(
    file_id : integer;
    var data : TCharacter255):integer; stdcall;
function NXgetdataInt8(
    file_id : integer;
    var data : TInt8Array):integer; stdcall;
function NXgetdataInt16(
    file_id : integer;
    var data : TInt16Array):integer; stdcall;
function NXgetdataInt32(
    file_id : integer;
    var data : TInt32Array):integer; stdcall;
function NXgetdataFloat32(
    file_id : integer;
    var data : TFloat32Array):integer; stdcall;
function NXgetdataFloat64(
    file_id : integer;
    var data : TFloat64Array):integer; stdcall;

{ at the moment, we assume that one reads only a row or a column }
{ otherwise it is two complicated to handle                      }
function NXgetslabChar(
    file_id : integer;
    var data : TCharacter255;
    start : dimensions;
    size : dimensions):integer; stdcall;
function NXgetslabInt32(
    file_id : integer;
    var data : TInt32Array;
    start : dimensions;
    size : dimensions):integer; stdcall;
function NXgetslabFloat64(
    file_id : integer;
    var data : TFloat64Array;
    start : dimensions;
    size : dimensions):integer; stdcall;

{ ========= NXgetAttr ========== }
function NXgetattr(file_id:integer;attr_name : TCharacter255;var value : integer):integer; overload;
function NXgetattr(file_id:integer;attr_name:TCharacter255;var value:TCharacter255):integer; overload;
function NXgetattrChar(
    file_id : integer;
    var attr_name : TCharacter255;
    var value : TCharacter255;
    var length : integer;
    var attr_type : integer):integer; stdcall;
function NXgetattrInt32(
    file_id : integer;
    var attr_name : TCharacter255;
    var value : TInt32Array;
    var length : integer;
    var attr_type : integer):integer; stdcall;
function NXgetattrFloat32(
    file_id : integer;
    var attr_name : TCharacter255;
    var value : TFloat32Array;
    var length : integer;
    var attr_type : integer):integer; stdcall;
function NXgetattrFloat64(
    file_id : integer;
    var attr_name : TCharacter255;
    var value : TFloat64Array;
    var length : integer;
    var attr_type : integer):integer; stdcall;
{ ========= NXputData ========== }
function NXputdata(file_id:integer;var data:integer):integer; stdcall; overload;
function NXputdata(file_id:integer;var data:single):integer; stdcall; overload;
function NXputdata(file_id:integer;var data:double):integer; stdcall; overload;
function NXputdata(file_id:integer;var data:string):integer; stdcall; overload;
function NXputdata(file_id:integer;var data:TDynArrayInt32):integer; stdcall; overload;
function NXputdata(file_id:integer;var data:TDynArrayFloat32):integer; stdcall; overload;
function NXputdata(file_id:integer;var data:TDynArrayFloat64):integer; stdcall; overload;
function NXputdata(file_id:integer;var data:TDynArray2DInt32):integer; stdcall; overload;
function NXputdata(file_id:integer;var data:TDynArray2DFloat32):integer; stdcall; overload;
function NXputdata(file_id:integer;var data:TDynArray2DFloat64):integer; stdcall; overload;
function NXputdataChar(
    file_id : integer;
    var data : TCharacter255):integer; stdcall;
function NXputdataInt8(
    file_id : integer;
    var data : TInt8Array):integer; stdcall;
function NXputdataInt16(
    file_id : integer;
    var data : TInt16Array):integer; stdcall;
function NXputdataInt32(
    file_id : integer;
    var data : TInt32Array):integer; stdcall;
function NXputdataFloat32(
    file_id : integer;
    var data : TFloat32Array):integer; stdcall;
function NXputdataFloat64(
    file_id : integer;
    var data : TFloat64Array):integer; stdcall;

function NXputslab(
    file_id : integer;
    var data : variant;
    start : integer;
    size : integer):integer; stdcall;

function NXputAttr(file_id : integer;attr_name : string;value:Integer):integer; overload;
function NXputAttr(file_id : integer;attr_name : string;value:double):integer; overload;
function NXputattrChar(
    file_id : integer;
    attr_name : TCharacter255;
    value : TCharacter255;
    length : integer;
    typee : integer):integer; stdcall;
function NXputattrInt32(
    file_id : integer;
    attr_name : TCharacter255;
    value : TInt32Array;
    length : integer;
    typee : integer):integer; stdcall;
function NXputattrFloat64(
    file_id : integer;
    attr_name : TCharacter255;
    value : TFloat64Array;
    length : integer;
    typee : integer):integer; stdcall;

function NXflush(
    var file_id : integer):integer; stdcall;

function NXgetinfo(
    file_id : integer;
    var rank : integer;
    var NXdimsAux : dimensions;
    var data_type : integer):integer; stdcall;   { ok }

function NXgetgroupinfo(
    file_id : integer;
    var item_number : integer;
    var group_name : TCharacter255;
    var group_class : TCharacter255):integer; stdcall;

function NXinitgroupdir(
    file_id : integer):integer; stdcall;

{ function NXgroupdir(
    file_id : integer;
    var item_number : integer;
    var item_name : array of TCharacter255;
    var item_class : array of TCharacter255):integer; stdcall; }

function NXgetnextentry(
    file_id : integer;
    var name : TCharacter255;
    var classe : TCharacter255;
    var data_type : integer):integer; stdcall;

function NXgetattrinfo(
    file_id : integer;
    var attr_number : integer):integer; stdcall;

function NXinitattrdir(
    file_id : integer):integer; stdcall;

{ function NXattrdir:integer; stdcall; }

function NXgetnextattr(
    file_id : integer;
    var attr_name : TCharacter255;
    var length : integer;
    var typee : integer):integer; stdcall;

function NXgetgroupID(
    file_id : integer;
    var group_id : NXlink):integer; stdcall;

function NXgetdataID(
    file_id : integer;
    var data_id : NXlink):integer; stdcall;

function NXmakelink(
    file_id : integer;
    var link : NXlink):integer; stdcall;

implementation

//
// Interface unit implemetation.
//
function setlength2D(var d:TDynArray2DInt32;sizeX,sizeY:integer):integer;
var j:integer;
begin
   setlength(d,sizeX);
   for j:=low(d) to high(d) do
        SetLength(d[j],sizeY);
end;
function setlength2D(var d:TDynArray2DFloat32;sizeX,sizeY:integer):integer;
var j:integer;
begin
   setlength(d,sizeX);
   for j:=low(d) to high(d) do
        SetLength(d[j],sizeY);
end;
function setlength2D(var d:TDynArray2DFloat64;sizeX,sizeY:integer):integer;
var j:integer;
begin
   setlength(d,sizeX);
   for j:=low(d) to high(d) do
        SetLength(d[j],sizeY);
end;


function StrToPChar(s:string):Tcharacter255;

var name:TCharacter255;
begin
   StrPCopy(name,s);
   StrToPChar:=name;
end;



function NXopen(
    file_name : TCharacter255;
    access_method : integer;
    var file_id : integer):integer; stdcall;
    external 'nexusdll.dll' name '_NXIOPEN@12'   { ok }

function NXclose(
    file_id : integer):integer; stdcall;
    external 'nexusdll.dll' name '_NXIFCLOSE@4'; { ok }
    { achtung ne marche pas avec NXICLOSE@4 }

function NXmakegroup(
    file_id : integer;
    group_name : TCharacter255;
    group_class : TCharacter255):integer; stdcall;
    external 'nexusdll.dll' name '_NXIMAKEGROUP@12';   { ok }

function NXopengroup(
    file_id : integer;
    group_name : TCharacter255;
    group_class : TCharacter255):integer; stdcall;
    external 'nexusdll.dll' name '_NXIOPENGROUP@12'; { ok }

function NXclosegroup(
    file_id : integer):integer; stdcall;
    external 'nexusdll.dll' name '_NXICLOSEGROUP@4'; { ok }

//
// DLL declaration used by NXmakedata.
//
function NXmakedataAux(
    file_id : integer;
    data_name : TCharacter255;
    data_type : integer;
    rank : integer;
    NXdims : dimensions):integer; stdcall;
    external 'nexusdll.dll'  name '_NXIMAKEDATA@20'; { ok pour NX_CHAR à 2D }
function NXmakeData(
    file_id : integer;
    data_name : TCharacter255;
    data_type : integer;
    rank : integer;
    NXdims : dimensions):integer; stdcall;
var status:integer;
    NXdimsAux:dimensions;
begin
  if rank=1 then NXdimsAux[1]:=NXdims[1];
  if rank=2 then begin NXdimsAux[1]:=NXdims[2];NXdimsAux[2]:=NXdims[1]; end;
  if rank=3 then begin NXdimsAux[1]:=NXdims[3];NXdimsAux[2]:=NXdims[2];NXdimsAux[3]:=NXdims[1]; end;
  status:=NXmakeDataAux(file_id,data_name,data_type,rank,NXdimsAux);
  NXmakeData:=status;
end;

function NXopendata(
    file_id : integer;
    data_name : TCharacter255):integer; stdcall;
    external 'nexusdll.dll' name '_NXIOPENDATA@8';    { ok }

function NXcompress(
    file_id : integer;
    compress_type : integer):integer; stdcall;
    external 'nexusdll.dll' name '_NXICOMPRESS@8';

function NXclosedata(
    file_id : integer):integer; stdcall;
    external 'nexusdll.dll' name '_NXICLOSEDATA@4'; { ok }

{ ========= NXgetAttr ========== }
function NXgetdata(file_id : integer;var data : integer):integer; { read a scalar INT32 }
var status:integer;
begin
    status:=NXGetDataInt32(file_id,dataI32);
    data:=dataI32[0];
    NXgetData:=status;
end;
function NXgetdata(file_id : integer;var data : single):integer; { read a scalar FLOAT32 }
var status:integer;
begin
    status:=NXGetDataFloat32(file_id,dataF32);
    data:=dataF32[0];
    NXgetData:=status;
end;
function NXgetdata(file_id : integer;var data : double):integer; { read a scalar FLOAT64 }
var status:integer;
begin
    status:=NXGetDataFloat64(file_id,dataF64);
    data:=dataF64[0];
    NXgetData:=status;
end;
function NXgetdata(file_id : integer;var data : string):integer; { read a STRING }
var status:integer;
    dataAux:TCharacter255;
begin
    status:=NXGetDataChar(file_id,dataAux);
    data:=dataAux;
    NXgetData:=status;
end;
function NXgetdata(file_id:integer;var data:TDynArrayInt32):integer; { read an array1D of INT32 }
var i,status,rank,data_type:integer;
    NXdims:dimensions;
begin
    status:=NXGetInfo(file_id,rank,NXdims,data_type);
    status:=NXGetDataInt32(file_id,dataI32);
    setLength(data,NXdims[1]);
    for i:=0 to NXdims[1]-1 do data[i]:=dataI32[i];
    NXgetData:=status;
end;
function NXgetdata(file_id:integer;var data:TDynArrayFloat32):integer; { read an array1D of FLOAT32 }
var i,status,rank,data_type:integer;
    NXdims:dimensions;
begin
    status:=NXGetInfo(file_id,rank,NXdims,data_type);
    status:=NXGetDataFloat32(file_id,dataF32);
    setLength(data,NXdims[1]);
    for i:=0 to NXdims[1]-1 do data[i]:=dataF32[i];
    NXgetData:=status;
end;
function NXgetdata(file_id:integer;var data:TDynArrayFloat64):integer; { read an array1D of FLOAT64 }
var i,status,rank,data_type:integer;
    NXdims:dimensions;
begin
    status:=NXGetInfo(file_id,rank,NXdims,data_type);
    status:=NXGetDataFloat64(file_id,dataF64);
    setLength(data,NXdims[1]);
    for i:=0 to NXdims[1]-1 do data[i]:=dataF64[i];
    NXgetData:=status;
end;
function NXgetdata(file_id:integer;var data:TDynArray2DInt32):integer; { read an array2D of INT32 }
var i,j,status,rank,data_type,sizeX,sizeY:integer;
    NXdims:dimensions;
begin
    status:=NXGetInfo(file_id,rank,NXdims,data_type);
    status:=NXGetDataInt32(file_id,dataI32);
    sizeX:=NXdims[1];sizeY:=NXdims[2];
    setLength2D(data,sizeX,sizeY);
    for j:=0 to sizeY-1 do
      for i:=0 to sizeX-1 do data[i,j]:=dataI32[j*(sizeX)+i];
    NXgetData:=status;
end;
function NXgetdata(file_id:integer;var data:TDynArray2DFloat32):integer; { read an array2D of FLOAT32 }
var i,j,status,rank,data_type,sizeX,sizeY:integer;
    NXdims:dimensions;
begin
    status:=NXGetInfo(file_id,rank,NXdims,data_type);
    status:=NXGetDataFloat32(file_id,dataF32);
    sizeX:=NXdims[1];sizeY:=NXdims[2];
    setLength2D(data,sizeX,sizeY);
    for j:=0 to sizeY-1 do
      for i:=0 to sizeX-1 do data[i,j]:=dataF32[j*(sizeX)+i];
    NXgetData:=status;
end;
function NXgetdata(file_id:integer;var data:TDynArray2DFloat64):integer; { read an array2D of FLOAT64 }
var i,j,status,rank,data_type,sizeX,sizeY:integer;
    NXdims:dimensions;
begin
    status:=NXGetInfo(file_id,rank,NXdims,data_type);
    status:=NXGetDataFloat64(file_id,dataF64);
    sizeX:=NXdims[1];sizeY:=NXdims[2];
    setLength2D(data,sizeX,sizeY);
    for j:=0 to sizeY-1 do
      for i:=0 to sizeX-1 do data[i,j]:=dataF64[j*(sizeX)+i];
    NXgetData:=status;
end;

function NXgetdataChar(
    file_id : integer;
    var data : TCharacter255):integer; stdcall;
    external 'nexusdll.dll' name '_NXIGETDATA@8';
function NXgetdataInt8(
    file_id : integer;
    var data : TInt8Array):integer; stdcall;
    external 'nexusdll.dll' name '_NXIGETDATA@8';
function NXgetdataInt16(
    file_id : integer;
    var data : TInt16Array):integer; stdcall;
    external 'nexusdll.dll' name '_NXIGETDATA@8';
function NXgetdataInt32(
    file_id : integer;
    var data : TInt32Array):integer; stdcall;
    external 'nexusdll.dll' name '_NXIGETDATA@8';
function NXgetdataFloat32(
    file_id : integer;
    var data : TFloat32Array):integer; stdcall;
    external 'nexusdll.dll' name '_NXIGETDATA@8';
function NXgetdataFloat64(
    file_id : integer;
    var data : TFloat64Array):integer; stdcall;
    external 'nexusdll.dll' name '_NXIGETDATA@8';

function NXgetslabChar(
    file_id : integer;
    var data : TCharacter255;
    start : dimensions;
    size : dimensions):integer; stdcall;
    external 'nexusdll.dll'  name '_NXIGETSLAB@16';
function NXgetslabInt32(
    file_id : integer;
    var data : TInt32Array;
    start : dimensions;
    size : dimensions):integer; stdcall;
    external 'nexusdll.dll'  name '_NXIGETSLAB@16';
function NXgetslabFloat64(
    file_id : integer;
    var data : TFloat64Array;
    start : dimensions;
    size : dimensions):integer; stdcall;
    external 'nexusdll.dll'  name '_NXIGETSLAB@16';

{ ========= NXgetAttr ========== }
function NXgetattr(file_id : integer;attr_name : TCharacter255;var value : integer):integer;
var status:integer;
    attr_length,attr_type:integer;
begin
    attr_length:=1;attr_type:=NX_INT32;
    status:=NXgetattrInt32(file_id,attr_name,dataI32,attr_length,attr_type);
    value:=dataI32[0];
    NXgetattr:=status;
end;
function NXgetattr(file_id : integer;attr_name : TCharacter255;var value : TCharacter255):integer;
var status:integer;
    attr_value:TCharacter255;
    attr_length,attr_type:integer;
begin
    attr_length:=255;attr_type:=NX_CHAR;
    status:=NXgetattrChar(file_id,attr_name,attr_value,attr_length,attr_type);
    value:=attr_value;
    NXgetattr:=status;
end;
function NXgetattrChar(
    file_id : integer;
    var attr_name : TCharacter255;
    var value : TCharacter255;
    var length : integer;
    var attr_type : integer):integer; stdcall;
    external 'nexusdll.dll'  name '_NXIGETATTR@20';
function NXgetattrInt32(
    file_id : integer;
    var attr_name : TCharacter255;
    var value : TInt32Array;
    var length : integer;
    var attr_type : integer):integer; stdcall;
    external 'nexusdll.dll'  name '_NXIGETATTR@20';
function NXgetattrFloat32(
    file_id : integer;
    var attr_name : TCharacter255;
    var value : TFloat32Array;
    var length : integer;
    var attr_type : integer):integer; stdcall;
    external 'nexusdll.dll'  name '_NXIGETATTR@20';
function NXgetattrFloat64(
    file_id : integer;
    var attr_name : TCharacter255;
    var value : TFloat64Array;
    var length : integer;
    var attr_type : integer):integer; stdcall;
    external 'nexusdll.dll'  name '_NXIGETATTR@20';

{ ========= NXputData ========== }
function NXputdata(file_id : integer;var data : integer):integer;  { scalar INT32 }
var status:integer;
begin
    dataI32[0]:=data;
    status:=NXputDataInt32(file_id,dataI32);
    NXputData:=status;
end;
function NXputdata(file_id : integer;var data : single):integer; { scalar FLOAT32 }
var status:integer;
begin
    dataF32[0]:=data;
    status:=NXputDataFloat32(file_id,dataF32);
    NXputData:=status;
end;
function NXputdata(file_id : integer;var data : double):integer; { scalar FLOAT64 }
var status:integer;
begin
    dataF64[0]:=data;
    status:=NXputDataFloat64(file_id,dataF64);
    NXputData:=status;
end;
function NXputdata(file_id:integer;var data:string):integer; { string }
var i,status:integer;
    dataAux:TCharacter255;
begin
    FillChar(dataAux,sizeof(dataAux),#0);
    for i:=0 to length(data)-1 do dataAux[i]:=data[i+1];
    status:=NXputDataChar(file_id,dataAux);
    NXputData:=status;
end;
function NXputdata(file_id:integer;var data:TDynArrayInt32):integer; { array1D INT32 }
var i,status:integer;
begin
    for i:=0 to high(data) do dataI32[i]:=data[i];
    status:=NXputDataInt32(file_id,dataI32);
    NXputData:=status;
end;
function NXputdata(file_id:integer;var data:TDynArrayFloat32):integer; { array1D FLOAT32 }
var i,status:integer;
begin
    for i:=0 to high(data) do dataF32[i]:=data[i];
    status:=NXputDataFloat32(file_id,dataF32);
    NXputData:=status;
end;
function NXputdata(file_id:integer;var data:TDynArrayFloat64):integer; { array1D FLOAT64 }
var i,status:integer;
begin
    for i:=0 to high(data) do dataF64[i]:=data[i];
    status:=NXputDataFloat64(file_id,dataF64);
    NXputData:=status;
end;
function NXputdata(file_id:integer;var data:TDynArray2DInt32):integer; { array2D INT32 }
var i,j,sizeX,sizeY,status:integer;
begin
    sizeX:=high(data);sizeY:=high(data[0]);
    for j:=0 to sizeY do
      for i:=0 to sizeX do dataI32[j*(sizeX+1)+i]:=data[i,j];
    status:=NXputDataInt32(file_id,dataI32);
    NXputData:=status;
end;
function NXputdata(file_id:integer;var data:TDynArray2DFloat32):integer; { array2D FLOAT32 }
var i,j,sizeX,sizeY,status:integer;
begin
    sizeX:=high(data);sizeY:=high(data[0]);
    for j:=0 to sizeY do
      for i:=0 to sizeX do dataF32[j*(sizeX+1)+i]:=data[i,j];
    status:=NXputDataFloat32(file_id,dataF32);
    NXputData:=status;
end;
function NXputdata(file_id:integer;var data:TDynArray2DFloat64):integer; { array2D FLOAT64 }
var i,j,sizeX,sizeY,status:integer;
begin
    sizeX:=high(data);sizeY:=high(data[0]);
    for j:=0 to sizeY do
      for i:=0 to sizeX do dataF64[j*(sizeX+1)+i]:=data[i,j];
    status:=NXputDataFloat64(file_id,dataF64);
    NXputData:=status;
end;
function NXputdataChar(
    file_id : integer;
    var data : TCharacter255):integer; stdcall;
    external 'nexusdll.dll' name '_NXIPUTDATA@8';
function NXputdataInt8(
    file_id : integer;
    var data : TInt8Array):integer; stdcall;
    external 'nexusdll.dll' name '_NXIPUTDATA@8';
function NXputdataInt16(
    file_id : integer;
    var data : TInt16Array):integer; stdcall;
    external 'nexusdll.dll' name '_NXIPUTDATA@8';
function NXputdataInt32(
    file_id : integer;
    var data : TInt32Array):integer; stdcall;
    external 'nexusdll.dll' name '_NXIPUTDATA@8';
function NXputdataFloat32(
    file_id : integer;
    var data : TFloat32Array):integer; stdcall;
    external 'nexusdll.dll' name '_NXIPUTDATA@8';
function NXputdataFloat64(
    file_id : integer;
    var data : TFloat64Array):integer; stdcall;
    external 'nexusdll.dll' name '_NXIPUTDATA@8';

function NXputslab(
    file_id : integer;
    var data : variant;
    start : integer;
    size : integer):integer; stdcall;
    external 'nexusdll.dll'
    name '_NXputslab@20';

function NXputAttr(file_id:integer;attr_name:string;value:Integer):integer;
var status:integer;
begin
  dataI32[0]:=value;
  status:=NXputattrInt32(file_id,StrToPChar(attr_name),dataI32,1,NX_INT32);
  NXputAttr:=status;
end;
function NXputAttr(file_id:integer;attr_name:string;value:double):integer;
var status:integer;
begin
  dataF64[0]:=value;
  status:=NXputattrFloat64(file_id,strToPChar(attr_name),dataF64,1,NX_FLOAT64);
  NXputAttr:=status;
end;
function NXputattrChar(
    file_id : integer;
    attr_name : TCharacter255;
    value : TCharacter255;
    length : integer;
    typee : integer):integer; stdcall;
    external 'nexusdll.dll' name '_NXIPUTATTR@20';
function NXputattrInt32(
    file_id : integer;
    attr_name : TCharacter255;
    value : TInt32Array;
    length : integer;
    typee : integer):integer; stdcall;
    external 'nexusdll.dll' name '_NXIPUTATTR@20';
function NXputattrFloat64(
    file_id : integer;
    attr_name : TCharacter255;
    value : TFloat64Array;
    length : integer;
    typee : integer):integer; stdcall;
    external 'nexusdll.dll' name '_NXIPUTATTR@20';

function NXflush(
    var file_id : integer):integer; stdcall;
    external 'nexusdll.dll' name '_NXIFLUSH@4';

//
// DLL declaration used by NXgetinfo.
//
function NXgetinfoAux(
    file_id : integer;
    var rank : integer;
    var NXdims:dimensions;
    var data_type : integer):integer; stdcall;
    external 'nexusdll.dll' name '_NXIGETINFO@16';
function NXgetinfo(
    file_id : integer;
    var rank : integer;
    var NXdimsAux:dimensions;
    var data_type : integer):integer;
var status:integer;
    NXdims:dimensions;
begin
  status:=NXgetInfoAux(file_id,rank,NXdims,data_type);
  if rank=1 then NXdimsAux[1]:=NXdims[1];
  if rank=2 then begin NXdimsAux[1]:=NXdims[2];NXdimsAux[2]:=NXdims[1]; end;
  if rank=3 then begin NXdimsAux[1]:=NXdims[3];NXdimsAux[2]:=NXdims[2];NXdimsAux[3]:=NXdims[1]; end;
  NXGetInfo:=status;
end;

function NXgetgroupinfo(
    file_id : integer;
    var item_number : integer;
    var group_name : TCharacter255;
    var group_class : TCharacter255):integer; stdcall;
    external 'nexusdll.dll' name '_NXIGETGROUPINFO@16';

function NXinitgroupdir(
    file_id : integer):integer; stdcall;
    external 'nexusdll.dll' name '_NXIINITGROUPDIR@4';

{ function NXgroupdir(
    file_id : integer;
    var item_number : integer;
    var item_name : array of TCharacter255;
    var item_class : array of TCharacter255):integer; stdcall;
    external 'nexusdll.dll' name '_NXIGROUPDIR@20'; }

function NXgetnextentry(
    file_id : integer;
    var name : TCharacter255;
    var classe : TCharacter255;
    var data_type : integer):integer; stdcall;
    external 'nexusdll.dll' name '_NXIGETNEXTENTRY@16';

function NXgetattrinfo(
    file_id : integer;
    var attr_number : integer):integer; stdcall;
    external 'nexusdll.dll'  name '_NXIGETATTRINFO@8';

function NXinitattrdir(
    file_id : integer):integer; stdcall;
    external 'nexusdll.dll' name '_NXIINITATTRDIR@4';

function NXgetnextattr(
    file_id : integer;
    var attr_name : TCharacter255;
    var length : integer;
    var typee : integer):integer; stdcall;
    external 'nexusdll.dll' name '_NXIGETNEXTATTR@16';

function NXgetgroupID(
    file_id : integer;
    var group_id : NXlink):integer; stdcall;
    external 'nexusdll.dll' name '_NXIGETGROUPID@8';

function NXgetdataID(
    file_id : integer;
    var data_id : NXlink):integer; stdcall;
    external 'nexusdll.dll' name '_NXIGETDATAID@8';

function NXmakelink(
    file_id : integer;
    var link : NXlink):integer; stdcall;
    external 'nexusdll.dll' name '_NXIMAKELINK@8';

end.
