[ruby-netcdf] 06/07: Running more tests
Youhei SASAKI
uwabami-guest at moszumanska.debian.org
Thu Jul 30 10:56:45 UTC 2015
This is an automated email from the git hooks/post-receive script.
uwabami-guest pushed a commit to branch master
in repository ruby-netcdf.
commit 90fd861616b64dde7c1892809d18652fbe0ca40b
Author: Youhei SASAKI <uwabami at gfd-dennou.org>
Date: Thu Jul 30 19:48:58 2015 +0900
Running more tests
Signed-off-by: Youhei SASAKI <uwabami at gfd-dennou.org>
---
debian/patches/0001-Change-FHS-For-RubyGems | 11966 ++++++++++++++++++++++++++
debian/ruby-netcdf.examples | 3 +
debian/ruby-test-files.yaml | 10 +
debian/ruby-tests.rake | 8 -
debian/rules | 6 +-
5 files changed, 11984 insertions(+), 9 deletions(-)
diff --git a/debian/patches/0001-Change-FHS-For-RubyGems b/debian/patches/0001-Change-FHS-For-RubyGems
new file mode 100644
index 0000000..6b7da38
--- /dev/null
+++ b/debian/patches/0001-Change-FHS-For-RubyGems
@@ -0,0 +1,11966 @@
+From: Debian GIS Project <pkg-grass-devel at lists.alioth.debian.org>
+Date: Thu, 30 Jul 2015 19:31:55 +0900
+Subject: Change FHS for RubyGems
+
+Signed-off-by: Youhei SASAKI <uwabami at gfd-dennou.org>
+---
+ ext/numru/extconf.rb | 173 ++
+ ext/numru/netcdfraw.c | 4721 +++++++++++++++++++++++++++++++++++++++
+ extconf.rb | 173 --
+ lib/netcdf.rb | 809 +------
+ lib/netcdf_miss.rb | 203 --
+ lib/numru/netcdf.rb | 808 +++++++
+ lib/numru/netcdf/netcdf_miss.rb | 203 ++
+ lib/numru/netcdf/version.rb | 5 +
+ lib/version.rb | 5 -
+ metadata.yml | 11 +-
+ netcdfraw.c | 4721 ---------------------------------------
+ ruby-netcdf.gemspec | 2 +-
+ test/test.rb | 7 +-
+ 13 files changed, 5919 insertions(+), 5922 deletions(-)
+ create mode 100644 ext/numru/extconf.rb
+ create mode 100644 ext/numru/netcdfraw.c
+ delete mode 100644 extconf.rb
+ delete mode 100644 lib/netcdf_miss.rb
+ create mode 100644 lib/numru/netcdf.rb
+ create mode 100644 lib/numru/netcdf/netcdf_miss.rb
+ create mode 100644 lib/numru/netcdf/version.rb
+ delete mode 100644 lib/version.rb
+ delete mode 100644 netcdfraw.c
+
+diff --git a/ext/numru/extconf.rb b/ext/numru/extconf.rb
+new file mode 100644
+index 0000000..1ad8b17
+--- /dev/null
++++ b/ext/numru/extconf.rb
+@@ -0,0 +1,173 @@
++require "mkmf"
++require "rubygems" unless defined?(Gem)
++
++ar = ARGV.grep( /^--with-netcdf-version=/ )
++if ar.length > 0
++ ncversion = ar[0].sub(/^--with-netcdf-version=/,"")
++else
++ ncversion = nil
++end
++
++if Gem.respond_to?(:find_files)
++ require "rbconfig"
++ so = RbConfig::CONFIG["DLEXT"]
++ narray_include = File.expand_path(File.dirname(Gem.find_files("narray.h")[0]))
++ narray_lib = File.expand_path(File.dirname(Gem.find_files("narray." + so)[0]))
++else
++ gem_home=(`gem environment GEM_HOME`).chomp
++ narray_dir = Dir.glob("#{gem_home}/gems/narray-*").sort[-1]
++ if narray_dir
++ narray_include = narray_lib = narray_dir
++ else
++ narray_include = narray_lib = [ $sitearchdir, $vendorarchdir]
++ end
++end
++dir_config('narray', narray_include, narray_lib)
++
++dir_config('netcdf', '/usr/local')
++
++if ( ! ( have_header("narray.h") && have_header("narray_config.h") ) ) then
++print <<EOS
++** configure error **
++ Header narray.h or narray_config.h is not found. If you have these files in
++ /narraydir/include, try the following:
++
++ % ruby extconf.rb --with-narray-include=/narraydir/include
++
++EOS
++ exit(-1)
++end
++
++unless ncversion
++ # configure netcdf version
++ if xsystem("nc-config --version")
++ ncversion = `nc-config --version`.chomp!.sub!(/^n.* /i,"") # rm "netCDF "
++ ncversion.sub!(/^([^\.]+\.[^\.]+\.[^\.]+).+$/,'\1') # e.g. 4.2.1.1 -> 4.2.1
++ else
++ ncversion = "3.0.0" # assume version 3 (only for compilation)
++ # For compilation, there is no difference among subversions of netcdf 3
++ end
++end
++
++ncver0 = ncversion[0..0] # "3" or "4"
++ncver = ncversion.gsub(/\./,'')
++unless /^\d\d\d$/ =~ ncver # 3 digits
++ raise("Invalid netcdf version: #{ncversion}. Use --with-netcdf-version=")
++end
++$CFLAGS += ' -DNCVER='+ncver
++
++case ncver0
++when "4"
++ if xsystem("nc-config --libs") # for NetCDF 4
++ cflags = `nc-config --cflags`.gsub(/\n/, " ")
++ libs = `nc-config --libs`.gsub(/\n/, " ")
++ prefix_nc = `nc-config --prefix`.gsub(/\n/, "")
++
++ dir_config("netcdf",prefix_nc)
++ $CFLAGS += ' ' + cflags
++ $LOCAL_LIBS += ' ' + libs
++ end
++when "3"
++ # for NetCDF 3, which needs external libraries for OpenDAP
++ if xsystem("ncdap-config --libs")
++ libncdods = "nc-dap"
++ cflags = `ncdap-config --cflags`.gsub(/\n/, " ")
++ libs = `ncdap-config --libs`.gsub(/\n/, " ")
++ prefix_dods = `ncdap-config --prefix`.gsub(/\n/, "")
++ elsif xsystem("opendap-config --libs")
++ libncdods = "nc-dods"
++ cflags = `opendap-config --cflags`.gsub(/\n/, " ")
++ libs = `opendap-config --libs-nc`.gsub(/\n/, " ")
++ prefix_dods = `opendap-config --prefix`.gsub(/\n/, "")
++ end
++ if (enable_config('opendap',true) && ( xsystem("opendap-config --libs") ||
++ xsystem("ncdap-config --libs") ) )
++
++ dir_config(libncdods,prefix_dods)
++
++ if (!have_library(libncdods))
++ print <<-EOS
++ ** ERROR ** Library not found: nc-dods (OPeNDAP/DODS-enabled NetCDF lib)
++ Install it, or run extconf.rb with option --disable-opendap.
++ ^^^^^^^^^^^^^^^^^
++ EOS
++ exit(-1)
++ else
++ print <<-EOS
++ ** Message ** Compiling with OPeNDAP/DODS-enabled NetCDF library.
++
++ This is because the command opendap-config is found in your system.
++ If you want to use the ordinary (non-DODS) version of NetCDF,
++ run extconf.rb with option --disable-opendap.
++ ^^^^^^^^^^^^^^^^^
++ EOS
++ end
++
++ $CFLAGS += ' '+cflags
++ $LOCAL_LIBS += ' ' + libs
++
++ # non portable treatments: should be improved (by Horinouchi)
++ CONFIG['LDSHARED'].sub!(/gcc/,'g++')
++ $LIBS.sub!(/-lc\s/,'') ; $LIBS.sub!(/-lc$/,'')
++ print <<-EOS
++ ** Warning ** non-portable treatments are made,
++ which was sucessfull redhat linux 9:
++ * gcc was replaced with g++ in CONFIG['LDSHARED']
++ * -lc library was removed if in $LIBS
++
++ EOS
++ # p '@@@'
++ # ary = []
++ # CONFIG.each{|k,v| ary.push([k,v])}
++ # ary.sort.each{|x| p x}
++ else
++ if ( ! ( have_header("netcdf.h") && have_library("netcdf") ) )then
++ print <<-EOS
++ ** configure error **
++ Header netcdf.h or the compiled netcdf library is not found.
++ If you have the library installed under /netcdfdir (that is, netcdf.h is
++ in /netcdfdir/include and the library in /netcdfdir/lib/),
++ try the following:
++
++ % ruby extconf.rb --with-netcdf-dir=/netcdfdir
++
++ Alternatively, you can specify the two directory separately
++ with --with-netcdf-include and --with-netcdf-lib.
++ EOS
++ exit(-1)
++ end
++ end
++else
++ raise "Netcdf version #{ncver0} is not supported"
++end
++
++
++
++if /cygwin|mingw/ =~ RUBY_PLATFORM
++ have_library("narray") || raise("ERROR: narray library is not found")
++end
++
++create_makefile "numru/netcdfraw"
++
++###### Modify Makefile: #######
++File.rename("Makefile","Makefile.orig")
++oldmkfl = File.open("Makefile.orig")
++newmkfl = File.open("Makefile","w")
++oldmkfl.each_line{ |line|
++ case(line)
++ when /^distclean:/
++ newmkfl.puts(line)
++ newmkfl.puts("\t\t@$(RM) *.nc demo/*.nc demo/*~ lib/*~ doc/*~ test/*.nc test/*~ Makefile.orig")
++ when /^all:/
++ newmkfl.puts(line)
++ newmkfl.puts("")
++ newmkfl.puts("test: all") # insert the "test" target
++ newmkfl.puts("\t\t at cd test && ruby test.rb && echo 'test did not fail :-p (please ignore the warnings)' && cd ..")
++# when /lib\/netcdf/
++# line = line.chomp! + "/"
++# newmkfl.puts(line)
++ else
++ newmkfl.puts(line)
++ end
++}
++newmkfl.close
+diff --git a/ext/numru/netcdfraw.c b/ext/numru/netcdfraw.c
+new file mode 100644
+index 0000000..200e8f3
+--- /dev/null
++++ b/ext/numru/netcdfraw.c
+@@ -0,0 +1,4721 @@
++#include<stdio.h>
++#include "ruby.h"
++#include "narray.h"
++#include<netcdf.h>
++#include<string.h>
++
++/* for compatibility with ruby 1.6 */
++#ifndef RSTRING_PTR
++#define RSTRING_PTR(s) (RSTRING(s)->ptr)
++#endif
++#ifndef RSTRING_LEN
++#define RSTRING_LEN(s) (RSTRING(s)->len)
++#endif
++#ifndef RARRAY_PTR
++#define RARRAY_PTR(a) (RARRAY(a)->ptr)
++#endif
++#ifndef RARRAY_LEN
++#define RARRAY_LEN(a) (RARRAY(a)->len)
++#endif
++#ifndef StringValueCStr
++#define StringValueCStr(s) STR2CSTR(s)
++#endif
++#ifndef SafeStringValue
++#define SafeStringValue(s) Check_SafeStr(s)
++#endif
++
++/* for compatibility for NArray and NArray with big memory patch */
++#ifndef NARRAY_BIGMEM
++typedef int na_shape_t;
++#endif
++
++/* Data to NArray */
++
++/* memcpy(ary->ptr,nc_ptr,na_sizeof[NA_SINT]*ary->total); \ */
++
++#define Cbyte_to_NArray(v, rank, shape, up) \
++{ \
++ struct NARRAY *ary; \
++ v = na_make_object(NA_BYTE, rank, shape, cNArray); \
++ GetNArray(v,ary); \
++ up = (unsigned char *)ary->ptr; \
++}
++
++#define Csint_to_NArray(v, rank, shape, sp) \
++{ \
++ struct NARRAY *ary; \
++ v = na_make_object(NA_SINT, rank, shape, cNArray); \
++ GetNArray(v, ary); \
++ sp = (short *)ary->ptr; \
++}
++
++#define Clint_to_NArray(v, rank, shape, lp) \
++{ \
++ struct NARRAY *ary; \
++ v = na_make_object(NA_LINT, rank, shape, cNArray); \
++ GetNArray(v, ary); \
++ lp = (int *)ary->ptr; \
++}
++#define Cfloat_to_NArray(v, rank, shape, fp) \
++{ \
++ struct NARRAY *ary; \
++ v = na_make_object(NA_SFLOAT, rank, shape, cNArray); \
++ GetNArray(v, ary); \
++ fp = (float *)ary->ptr; \
++}
++#define Cdouble_to_NArray(v, rank, shape, dp); \
++{ \
++ struct NARRAY *ary; \
++ v = na_make_object(NA_DFLOAT, rank, shape, cNArray); \
++ GetNArray(v, ary); \
++ dp = (double *)ary->ptr; \
++}
++
++/* Array or NArray to pointer and length (with no new allocation) */
++
++#define Array_to_Cfloat_len(obj, ptr, len) \
++{ \
++ struct NARRAY *na; \
++ obj = na_cast_object(obj, NA_SFLOAT); \
++ GetNArray(obj, na); \
++ ptr = (float *) NA_PTR(na,0); \
++ len = na->total; \
++}
++
++#define Array_to_Cfloat_len_shape(obj, ptr, len, shape) \
++{ \
++ struct NARRAY *na; \
++ obj = na_cast_object(obj, NA_SFLOAT); \
++ GetNArray(obj, na); \
++ ptr = (float *) NA_PTR(na,0); \
++ len = na->total; \
++ shape = na->shape; \
++}
++
++#define Array_to_Cdouble_len(obj, ptr, len) \
++{ \
++ struct NARRAY *na; \
++ obj = na_cast_object(obj, NA_DFLOAT); \
++ GetNArray(obj, na); \
++ ptr = (double *) NA_PTR(na,0); \
++ len = na->total; \
++}
++#define Array_to_Cdouble_len_shape(obj, ptr, len, shape) \
++{ \
++ struct NARRAY *na; \
++ obj = na_cast_object(obj, NA_DFLOAT); \
++ GetNArray(obj, na); \
++ ptr = (double *) NA_PTR(na,0); \
++ len = na->total; \
++ shape = na->shape; \
++}
++
++#define Array_to_Cbyte_len(obj, ptr, len) \
++{ \
++ struct NARRAY *na; \
++ obj = na_cast_object(obj, NA_BYTE); \
++ GetNArray(obj, na); \
++ ptr = (u_int8_t *) NA_PTR(na,0); \
++ len = na->total; \
++}
++
++#define Array_to_Cbyte_len_shape(obj, ptr, len, shape) \
++{ \
++ struct NARRAY *na; \
++ obj = na_cast_object(obj, NA_BYTE); \
++ GetNArray(obj, na); \
++ ptr = (u_int8_t *) NA_PTR(na,0); \
++ len = na->total; \
++ shape = na->shape; \
++}
++
++#define Array_to_Csint_len(obj, ptr, len) \
++{ \
++ struct NARRAY *na; \
++ obj = na_cast_object(obj, NA_SINT); \
++ GetNArray(obj, na); \
++ ptr = (int16_t *) NA_PTR(na,0); \
++ len = na->total; \
++}
++
++#define Array_to_Csint_len_shape(obj, ptr, len, shape) \
++{ \
++ struct NARRAY *na; \
++ obj = na_cast_object(obj, NA_SINT); \
++ GetNArray(obj, na); \
++ ptr = (int16_t *) NA_PTR(na,0); \
++ len = na->total; \
++ shape = na->shape; \
++}
++
++
++#define Array_to_Clint_len(obj, ptr, len) \
++{ \
++ struct NARRAY *na; \
++ obj = na_cast_object(obj, NA_LINT); \
++ GetNArray(obj, na); \
++ ptr = (int32_t *) NA_PTR(na,0); \
++ len = na->total; \
++}
++
++#define Array_to_Clint_len_shape(obj, ptr, len, shape) \
++{ \
++ struct NARRAY *na; \
++ obj = na_cast_object(obj, NA_LINT); \
++ GetNArray(obj, na); \
++ ptr = (int32_t *) NA_PTR(na,0); \
++ len = na->total; \
++ shape = na->shape; \
++}
++
++
++/* Array or NArray to pointer (with no new allocation) */
++
++#define Array_to_Cfloat(obj, ptr) \
++{ \
++ struct NARRAY *na; \
++ obj = na_cast_object(obj, NA_SFLOAT); \
++ GetNArray(obj, na); \
++ ptr = (float *) NA_PTR(na,0); \
++}
++#define Array_to_Cdouble(obj, ptr) \
++{ \
++ struct NARRAY *na; \
++ obj = na_cast_object(obj, NA_DFLOAT); \
++ GetNArray(obj, na); \
++ ptr = (double *) NA_PTR(na,0); \
++}
++#define Array_to_Cbyte(obj, ptr) \
++{ \
++ struct NARRAY *na; \
++ obj = na_cast_object(obj, NA_BYTE); \
++ GetNArray(obj, na); \
++ ptr = (u_int8_t *) NA_PTR(na,0); \
++}
++#define Array_to_Csint(obj, ptr) \
++{ \
++ struct NARRAY *na; \
++ obj = na_cast_object(obj, NA_SINT); \
++ GetNArray(obj, na); \
++ ptr = (int16_t *) NA_PTR(na,0); \
++}
++#define Array_to_Clint(obj, ptr) \
++{ \
++ struct NARRAY *na; \
++ obj = na_cast_object(obj, NA_LINT); \
++ GetNArray(obj, na); \
++ ptr = (int32_t *) NA_PTR(na,0); \
++}
++
++#define NC_RAISE(status) rb_raise(err_status2class(status),"%s",(nc_strerror(status)))
++#define NC_RAISE2(status, str) rb_raise(err_status2class(status),"%s (%s)",nc_strerror(status),(str) )
++
++static VALUE mNumRu = 0;
++static VALUE cNetCDF;
++static VALUE cNetCDFDim;
++static VALUE cNetCDFAtt;
++static VALUE cNetCDFVar;
++
++static VALUE rb_eNetcdfError;
++static VALUE rb_eNetcdfBadid;
++static VALUE rb_eNetcdfNfile;
++static VALUE rb_eNetcdfExist;
++static VALUE rb_eNetcdfInval;
++static VALUE rb_eNetcdfPerm;
++static VALUE rb_eNetcdfNotindefine;
++static VALUE rb_eNetcdfIndefine;
++static VALUE rb_eNetcdfInvalcoords;
++static VALUE rb_eNetcdfMaxdims;
++static VALUE rb_eNetcdfNameinuse;
++static VALUE rb_eNetcdfNotatt;
++static VALUE rb_eNetcdfMaxatts;
++static VALUE rb_eNetcdfBadtype;
++static VALUE rb_eNetcdfBaddim;
++static VALUE rb_eNetcdfUnlimpos;
++static VALUE rb_eNetcdfMaxvars;
++static VALUE rb_eNetcdfNotvar;
++static VALUE rb_eNetcdfGlobal;
++static VALUE rb_eNetcdfNotnc;
++static VALUE rb_eNetcdfSts;
++static VALUE rb_eNetcdfMaxname;
++static VALUE rb_eNetcdfUnlimit;
++static VALUE rb_eNetcdfNorecvars;
++static VALUE rb_eNetcdfChar;
++static VALUE rb_eNetcdfEdge;
++static VALUE rb_eNetcdfStride;
++static VALUE rb_eNetcdfBadname;
++static VALUE rb_eNetcdfRange;
++static VALUE rb_eNetcdfNomem;
++
++/* Special Error */
++/* Global error status */
++
++static VALUE rb_eNetcdfFatal;
++
++/* Global options variable. Used to determine behavior of error handler. */
++
++static VALUE rb_eNetcdfEntool;
++static VALUE rb_eNetcdfExdr;
++static VALUE rb_eNetcdfSyserr;
++
++
++struct Netcdf{
++ int ncid;
++ char *name;
++ int closed;
++};
++
++struct NetCDFDim{
++ int dimid;
++ int ncid;
++};
++
++struct NetCDFVar{
++ int varid;
++ int ncid;
++ VALUE file;
++};
++
++struct NetCDFAtt{
++ int varid;
++ int ncid;
++ char *name;
++};
++
++static struct Netcdf *
++NetCDF_init(int ncid,char *filename)
++{
++ struct Netcdf *Netcdffile;
++ Netcdffile=xmalloc(sizeof(struct Netcdf));
++ Netcdffile->ncid=ncid;
++ Netcdffile->closed=0;
++ Netcdffile->name=xmalloc((strlen(filename)+1)*sizeof(char));
++ strcpy(Netcdffile->name,filename);
++ return(Netcdffile);
++}
++
++static struct NetCDFDim *
++NetCDF_dim_init(int ncid,int dimid)
++{
++ struct NetCDFDim *Netcdf_dim;
++ Netcdf_dim=xmalloc(sizeof(struct NetCDFDim));
++ Netcdf_dim->dimid=dimid;
++ Netcdf_dim->ncid=ncid;
++ return(Netcdf_dim);
++}
++
++static struct NetCDFVar *
++NetCDF_var_init(int ncid,int varid,VALUE file)
++{
++ struct NetCDFVar *Netcdf_var;
++ Netcdf_var=xmalloc(sizeof(struct NetCDFVar));
++ Netcdf_var->varid=varid;
++ Netcdf_var->ncid=ncid;
++ Netcdf_var->file=file;
++ return(Netcdf_var);
++}
++static struct NetCDFAtt *
++NetCDF_att_init(int ncid,int varid,char *attname)
++{
++ struct NetCDFAtt *Netcdf_att;
++ Netcdf_att=xmalloc(sizeof(struct NetCDFAtt));
++ Netcdf_att->ncid=ncid;
++ Netcdf_att->varid=varid;
++ Netcdf_att->name=xmalloc((strlen(attname)+1)*sizeof(char));
++ strcpy(Netcdf_att->name,attname);
++ return(Netcdf_att);
++}
++
++void
++Netcdf_att_free(struct NetCDFAtt *Netcdf_att)
++{
++ free(Netcdf_att->name);
++ free(Netcdf_att);
++}
++
++void
++NetCDF_var_free(struct NetCDFVar *Netcdf_var)
++{
++ free(Netcdf_var);
++}
++
++void
++NetCDF_dim_free(struct NetCDFDim *Netcdf_dim)
++{
++ free(Netcdf_dim);
++}
++
++void
++NetCDF_free(struct Netcdf *Netcdffile)
++{
++ if (!Netcdffile->closed){
++ nc_close(Netcdffile->ncid); /* no error check -- not to stop during GC */
++ }
++ free(Netcdffile->name);
++ free(Netcdffile);
++}
++
++static VALUE
++err_status2class(int status)
++{
++ if(NC_ISSYSERR(status)){
++ return(rb_eNetcdfSyserr);
++ }
++ switch(status)
++ {
++ case(NC_EBADID):
++ return(rb_eNetcdfBadid);break;
++ case(NC_ENFILE):
++ return(rb_eNetcdfNfile);break;
++ case(NC_EEXIST):
++ return(rb_eNetcdfExist);break;
++ case(NC_EINVAL):
++ return(rb_eNetcdfInval);break;
++ case(NC_EPERM):
++ return(rb_eNetcdfPerm);break;
++ case(NC_ENOTINDEFINE):
++ return(rb_eNetcdfNotindefine);break;
++ case(NC_EINDEFINE):
++ return(rb_eNetcdfIndefine);break;
++ case(NC_EINVALCOORDS):
++ return(rb_eNetcdfInvalcoords);break;
++ case(NC_EMAXDIMS):
++ return(rb_eNetcdfMaxdims);break;
++ case(NC_ENAMEINUSE):
++ return(rb_eNetcdfNameinuse);break;
++ case(NC_ENOTATT):
++ return(rb_eNetcdfNotatt);break;
++ case(NC_EMAXATTS):
++ return(rb_eNetcdfMaxatts);break;
++ case(NC_EBADTYPE):
++ return(rb_eNetcdfBadtype);break;
++ case(NC_EBADDIM):
++ return(rb_eNetcdfBaddim);break;
++ case(NC_EUNLIMPOS):
++ return(rb_eNetcdfUnlimpos);break;
++ case(NC_EMAXVARS):
++ return(rb_eNetcdfMaxvars);break;
++ case(NC_ENOTVAR):
++ return(rb_eNetcdfNotvar);break;
++ case(NC_EGLOBAL):
++ return(rb_eNetcdfGlobal);break;
++ case(NC_ENOTNC):
++ return(rb_eNetcdfNotnc);break;
++ case(NC_ESTS):
++ return(rb_eNetcdfSts);break;
++ case(NC_EMAXNAME):
++ return(rb_eNetcdfMaxname);break;
++ case(NC_EUNLIMIT):
++ return(rb_eNetcdfUnlimit);break;
++ case(NC_ENORECVARS):
++ return(rb_eNetcdfNorecvars);break;
++ case(NC_ECHAR):
++ return(rb_eNetcdfChar);break;
++ case(NC_EEDGE):
++ return(rb_eNetcdfEdge);break;
++ case(NC_ESTRIDE):
++ return(rb_eNetcdfStride);break;
++ case(NC_EBADNAME):
++ return(rb_eNetcdfBadname);break;
++ case(NC_ERANGE):
++ return(rb_eNetcdfRange);break;
++ case(NC_ENOMEM):
++ return(rb_eNetcdfNomem);break;
++ /* case(NC_ENTOOL):
++ return(rb_eNetcdfEntool);break; */
++ case(NC_EXDR):
++ return(rb_eNetcdfExdr);break;
++ case(NC_SYSERR):
++ return(rb_eNetcdfSyserr);break;
++ case(NC_FATAL):
++ return(rb_eNetcdfFatal);break;
++ }
++ return rb_eNetcdfError;
++}
++
++static const char*
++nctype2natype(int nctype){
++ switch(nctype){
++ case NC_CHAR:
++ return("char");
++ case NC_BYTE:
++ return("byte");
++ case NC_SHORT:
++ return("sint");
++ case NC_INT:
++ return("int");
++ case NC_FLOAT:
++ return("sfloat");
++ case NC_DOUBLE:
++ return("float");
++ default:
++ rb_raise(rb_eNetcdfError, "No such netcdf type number %d\n",nctype);
++ }
++}
++
++static int
++nctype2natypecode(int nctype){
++ switch(nctype){
++ case NC_CHAR:
++ return(NA_BYTE);
++ case NC_BYTE:
++ return(NA_BYTE);
++ case NC_SHORT:
++ return(NA_SINT);
++ case NC_INT:
++ return(NA_LINT);
++ case NC_FLOAT:
++ return(NA_SFLOAT);
++ case NC_DOUBLE:
++ return(NA_DFLOAT);
++ default:
++ rb_raise(rb_eNetcdfError, "No such netcdf type number %d\n",nctype);
++ }
++}
++
++static int
++natype2nctype(char *natype)
++{
++ if(strcmp(natype,"byte")==0) return(NC_BYTE);
++ else if(strcmp(natype,"char")==0) return(NC_CHAR);
++ else if(strcmp(natype,"text")==0) return(NC_CHAR); /* alias of char */
++ else if(strcmp(natype,"string")==0) return(NC_CHAR); /* alias of char */
++ else if(strcmp(natype,"sint")==0) return(NC_SHORT);
++ else if(strcmp(natype,"int")==0) return(NC_INT);
++ else if(strcmp(natype,"sfloat")==0) return(NC_FLOAT);
++ else if(strcmp(natype,"float")==0) return(NC_DOUBLE);
++ else rb_raise(rb_eNetcdfError, "No such NArray type '%s'",natype);
++}
++
++static int
++natypecode2nctype(int natypecode)
++{
++ if(natypecode==NA_BYTE) return(NC_BYTE);
++ else if(natypecode==NA_SINT) return(NC_SHORT);
++ else if(natypecode==NA_LINT) return(NC_INT);
++ else if(natypecode==NA_SFLOAT) return(NC_FLOAT);
++ else if(natypecode==NA_DFLOAT) return(NC_DOUBLE);
++ else rb_raise(rb_eNetcdfError, "No such NArray typecode '%d'",natypecode);
++}
++
++static void
++nc_mark_obj(struct NetCDFVar *netcdf_var)
++{
++ VALUE ptr;
++
++ ptr = netcdf_var->file;
++ rb_gc_mark(ptr);
++}
++
++
++VALUE
++NetCDF_clone(VALUE file)
++{
++ VALUE clone;
++ struct Netcdf *nc1, *nc2;
++
++ Data_Get_Struct(file, struct Netcdf, nc1);
++ nc2 = NetCDF_init(nc1->ncid, nc1->name);
++ clone = Data_Wrap_Struct(cNetCDF, 0, NetCDF_free, nc2);
++ CLONESETUP(clone, file);
++ return clone;
++}
++
++VALUE
++NetCDF_dim_clone(VALUE dim)
++{
++ VALUE clone;
++ struct NetCDFDim *nd1, *nd2;
++
++ Data_Get_Struct(dim, struct NetCDFDim, nd1);
++ nd2 = NetCDF_dim_init(nd1->ncid, nd1->dimid);
++ clone = Data_Wrap_Struct(cNetCDFDim, 0, NetCDF_dim_free, nd2);
++ CLONESETUP(clone, dim);
++ return clone;
++}
++
++VALUE
++NetCDF_att_clone(VALUE att)
++{
++ VALUE clone;
++ struct NetCDFAtt *na1, *na2;
++
++ Data_Get_Struct(att, struct NetCDFAtt, na1);
++ na2 = NetCDF_att_init(na1->ncid, na1->varid, na1->name);
++ clone = Data_Wrap_Struct(cNetCDFAtt, 0, Netcdf_att_free, na2);
++ CLONESETUP(clone, att);
++ return clone;
++}
++
++VALUE
++NetCDF_var_clone(VALUE var)
++{
++ VALUE clone;
++ struct NetCDFVar *nv1, *nv2;
++
++ Data_Get_Struct(var, struct NetCDFVar, nv1);
++ nv2 = NetCDF_var_init(nv1->ncid, nv1->varid, nv1->file);
++ clone = Data_Wrap_Struct(cNetCDFVar, nc_mark_obj, NetCDF_var_free, nv2);
++ CLONESETUP(clone, var);
++ return clone;
++}
++
++VALUE
++NetCDF_inq_libvers(VALUE mod)
++{
++ VALUE str;
++ str = rb_str_new2(nc_inq_libvers());
++ return(str);
++}
++
++VALUE
++NetCDF_close(file)
++ VALUE file;
++{
++ int status;
++ int ncid;
++ struct Netcdf *Netcdffile;
++
++ if (rb_safe_level() >= 3 && !OBJ_TAINTED(file)) {
++ rb_raise(rb_eSecurityError, "Insecure: can't close");
++ }
++ Data_Get_Struct(file,struct Netcdf,Netcdffile);
++ ncid=Netcdffile->ncid;
++ if(!Netcdffile->closed){
++ status = nc_close(ncid);
++ if(status != NC_NOERR) NC_RAISE(status);
++ Netcdffile->closed = 1;
++ } else {
++ rb_warn("file %s is already closed", Netcdffile->name);
++ }
++ return Qnil;
++}
++
++VALUE
++NetCDF_def_dim(VALUE file,VALUE dim_name,VALUE length)
++{
++ char* c_dim_name;
++ size_t c_length;
++ int ncid;
++ int dimidp;
++ int status;
++ struct Netcdf *Netcdffile;
++ struct NetCDFDim *Netcdf_dim;
++ VALUE Dimension;
++
++ rb_secure(3);
++ Data_Get_Struct(file,struct Netcdf,Netcdffile);
++
++ Check_Type(dim_name,T_STRING);
++ c_dim_name=RSTRING_PTR(dim_name);
++ c_length=NUM2UINT(length);
++ ncid=Netcdffile->ncid;
++
++ status = nc_def_dim(ncid,c_dim_name,c_length,&dimidp);
++ if(status !=NC_NOERR) NC_RAISE(status);
++
++ Netcdf_dim = NetCDF_dim_init(ncid,dimidp);
++
++ Dimension = Data_Wrap_Struct(cNetCDFDim,0,NetCDF_dim_free,Netcdf_dim);
++ return Dimension;
++}
++
++
++static VALUE
++NetCDF_put_att_char(int ncid, char *name,VALUE value,VALUE atttype, int varid)
++{
++ int status;
++ struct NetCDFAtt *ncatt;
++
++ /* check atttype (not necessarily needed but it's better to do it) */
++ if (TYPE(atttype) == T_STRING){
++ if ( natype2nctype(RSTRING_PTR(atttype)) != NC_CHAR ) {
++ rb_raise(rb_eNetcdfError,
++ "attribute type must be 'char' (or nil) for a String value");
++ }
++ } else if (TYPE(atttype) != T_NIL) {
++ rb_raise(rb_eNetcdfError,
++ "type specfication must be by a string or nil");
++ }
++ /* put value */
++ Check_Type(value,T_STRING);
++ status = nc_put_att_text(ncid, varid, name,
++ RSTRING_LEN(value), RSTRING_PTR(value));
++ if(status != NC_NOERR) NC_RAISE(status);
++
++ ncatt = NetCDF_att_init(ncid,varid,name);
++ return (Data_Wrap_Struct(cNetCDFAtt,0,Netcdf_att_free,ncatt));
++}
++
++static VALUE
++NetCDF_put_att_numeric(int ncid, char *name,VALUE value,VALUE atttype, int varid)
++{
++ VALUE val;
++ struct NARRAY *na_val;
++ int na_typecode, status, len;
++ char *ptr;
++ struct NetCDFAtt *ncatt;
++
++ /* check atttype and cast to an appropriate NArray if needed */
++
++ if (TYPE(atttype) != T_NIL){
++ na_typecode = na_get_typecode(atttype);
++ GetNArray( na_cast_object(value, na_typecode), na_val );
++ } else {
++ if (TYPE(value)==T_ARRAY) {
++ val = RARRAY_PTR(value)[0]; /* to check the 1st elemnt if Array */
++ } else {
++ val = value;
++ }
++ switch(TYPE(val)){
++ case T_FIXNUM:
++ case T_BIGNUM:
++ na_typecode = NA_LINT;
++ GetNArray( na_cast_object(value, na_typecode), na_val );
++ break;
++ case T_FLOAT:
++ na_typecode = NA_DFLOAT;
++ GetNArray( na_cast_object(value, na_typecode), na_val );
++ break;
++ case T_DATA:
++ if ( IsNArray(value) ){
++ GetNArray(value,na_val);
++ na_typecode = na_val->type;
++ } else {
++ rb_raise(rb_eNetcdfError,"value has a wrong data type");
++ }
++ break;
++ default:
++ rb_raise(rb_eNetcdfError,
++ "value (or its first element) has a wrong type");
++ }
++ }
++
++ /* put value */
++
++ len = na_val->total;
++ ptr = na_val->ptr;
++ switch(na_typecode){
++ case NA_BYTE:
++ status = nc_put_att_uchar(ncid,varid,name,NC_BYTE,len,(unsigned char *)ptr);
++ break;
++ case NA_SINT:
++ status = nc_put_att_short(ncid,varid,name,NC_SHORT,len,(short *)ptr);
++ break;
++ case NA_LINT:
++ status = nc_put_att_int(ncid,varid,name,NC_INT,len,(int *)ptr);
++ break;
++ case NA_SFLOAT:
++ status = nc_put_att_float(ncid,varid,name,NC_FLOAT,len,(float *)ptr);
++ break;
++ case NA_DFLOAT:
++ status = nc_put_att_double(ncid,varid,name,NC_DOUBLE,len,(double*)ptr);
++ break;
++ default:
++ rb_raise(rb_eNetcdfError,
++ "unsupported type. code = %d",na_typecode);
++ }
++ if(status != NC_NOERR) NC_RAISE(status);
++
++ ncatt = NetCDF_att_init(ncid,varid,name);
++ return (Data_Wrap_Struct(cNetCDFAtt,0,Netcdf_att_free,ncatt));
++}
++
++static VALUE
++NetCDF_put_att__(int ncid, char *name, VALUE value, VALUE atttype, int varid)
++ /*
++ * atttype: nil or a String ("string","int",etc). If nil,
++ * the type of attribute is determined from the type of value
++ */
++{
++ switch(TYPE(value)){
++ case T_STRING:
++ return(NetCDF_put_att_char(ncid, name, value, atttype, varid));
++ default:
++ return(NetCDF_put_att_numeric(ncid, name, value, atttype, varid));
++ }
++}
++
++VALUE
++NetCDF_put_att(VALUE file,VALUE att_name,VALUE value,VALUE atttype)
++ /*
++ * atttype: nil or a String ("string","int",etc). If nil,
++ * the type of attribute is determined from the type of value
++ */
++{
++ struct Netcdf *ncfile;
++ char *name;
++
++ rb_secure(3);
++ Data_Get_Struct(file,struct Netcdf,ncfile);
++ Check_Type(att_name,T_STRING);
++ name = RSTRING_PTR(att_name);
++
++ return( NetCDF_put_att__(ncfile->ncid, name, value, atttype, NC_GLOBAL) );
++}
++
++VALUE
++NetCDF_put_att_var(VALUE var,VALUE att_name,VALUE value,VALUE atttype)
++ /*
++ * atttype: nil or a String ("string","int",etc). If nil,
++ * the type of attribute is determined from the type of value
++ */
++{
++ struct NetCDFVar *ncvar;
++ char *name;
++
++ rb_secure(3);
++ Data_Get_Struct(var,struct NetCDFVar,ncvar);
++ Check_Type(att_name,T_STRING);
++ name = RSTRING_PTR(att_name);
++
++ return( NetCDF_put_att__(ncvar->ncid, name, value, atttype, ncvar->varid));
++}
++
++
++VALUE
++NetCDF_def_var(VALUE file,VALUE var_name,VALUE vartype,VALUE dimensions)
++{
++ int ncid;
++ char *c_var_name;
++ static int xtype;
++ long c_ndims;
++ int varidp;
++ int dimidp;
++ int i=0;
++ int status;
++ char *c_dim_name;
++ int c_dimids[NC_MAX_DIMS];
++ struct Netcdf *Netcdffile;
++ struct NetCDFVar *Netcdf_var;
++ struct NetCDFDim *Netcdf_dim;
++ VALUE Var;
++
++ rb_secure(3);
++ Check_Type(var_name,T_STRING);
++ Check_Type(dimensions,T_ARRAY);
++
++ c_var_name=RSTRING_PTR(var_name);
++ c_ndims=RARRAY_LEN(dimensions);
++
++ Data_Get_Struct(file,struct Netcdf,Netcdffile);
++ ncid=Netcdffile->ncid;
++
++ if (TYPE(vartype) == T_STRING){
++ xtype = natype2nctype(RSTRING_PTR(vartype));
++ } else if (TYPE(vartype) == T_FIXNUM){
++ xtype = natypecode2nctype(NUM2INT(vartype));
++ } else {
++ rb_raise(rb_eNetcdfError,
++ "type specfication must be by a string or nil");
++ }
++
++ for(i=0;i<c_ndims;i++){
++ switch(TYPE(RARRAY_PTR(dimensions)[c_ndims-1-i])){
++ case T_STRING:
++ Check_Type(RARRAY_PTR(dimensions)[c_ndims-1-i],T_STRING);
++ c_dim_name=StringValueCStr(RARRAY_PTR(dimensions)[c_ndims-1-i]);
++ status=nc_inq_dimid(ncid,c_dim_name,&dimidp);
++ if(status != NC_NOERR) NC_RAISE(status);
++ c_dimids[i]=dimidp;
++ break;
++ case T_DATA:
++ Data_Get_Struct(RARRAY_PTR(dimensions)[c_ndims-1-i],struct NetCDFDim,Netcdf_dim);
++ c_dimids[i]=Netcdf_dim->dimid;
++ break;
++ default:
++ rb_raise(rb_eNetcdfError, "No such object of the netCDF dimension class.");
++ }
++ }
++
++ status = nc_def_var(ncid,c_var_name,xtype,c_ndims,c_dimids,&varidp);
++ if(status != NC_NOERR) NC_RAISE(status);
++
++ Netcdf_var = NetCDF_var_init(ncid,varidp,file);
++
++ Var=Data_Wrap_Struct(cNetCDFVar,nc_mark_obj,NetCDF_var_free,Netcdf_var);
++ return Var;
++}
++
++VALUE
++NetCDF_dim(VALUE file,VALUE dim_name)
++{
++ int ncid;
++ char *c_dim_name;
++ int dimidp;
++ int status;
++ struct Netcdf *Netcdffile;
++ struct NetCDFDim *Netcdf_dim;
++ VALUE Dimension;
++
++ Data_Get_Struct(file,struct Netcdf,Netcdffile);
++ ncid=Netcdffile->ncid;
++ Check_Type(dim_name,T_STRING);
++ c_dim_name=RSTRING_PTR(dim_name);
++
++ status = nc_inq_dimid(ncid,c_dim_name,&dimidp);
++ if(status !=NC_NOERR){
++ if(status == NC_EBADDIM){
++ return(Qnil); /*2003/08/27 back to orig (from changes on 2003/02/03)*/
++ } else{
++ NC_RAISE(status);
++ }
++ }
++
++ Netcdf_dim=NetCDF_dim_init(ncid,dimidp);
++
++ Dimension = Data_Wrap_Struct(cNetCDFDim,0,NetCDF_dim_free,Netcdf_dim);
++ return Dimension;
++}
++
++VALUE
++NetCDF_var(VALUE file,VALUE var_name)
++{
++ int ncid;
++ int status;
++ int varidp;
++ char *c_var_name;
++ struct Netcdf *Netcdffile;
++ struct NetCDFVar *Netcdf_var;
++ VALUE Variable;
++
++ Data_Get_Struct(file,struct Netcdf,Netcdffile);
++ ncid=Netcdffile->ncid;
++ Check_Type(var_name,T_STRING);
++ c_var_name=RSTRING_PTR(var_name);
++
++ status=nc_inq_varid(ncid,c_var_name,&varidp);
++ if(status != NC_NOERR){
++ if(status == NC_ENOTVAR){
++ return(Qnil); /*2003/08/27 back to orig (from changes on 2003/02/03)*/
++ } else{
++ NC_RAISE(status);
++ }
++ }
++
++ Netcdf_var = NetCDF_var_init(ncid,varidp,file);
++ Variable = Data_Wrap_Struct(cNetCDFVar,nc_mark_obj,NetCDF_var_free,Netcdf_var);
++ return Variable;
++}
++
++VALUE
++NetCDF_att(VALUE file,VALUE att_name)
++{
++ int ncid;
++ int status;
++ int attnump;
++ char *c_att_name;
++ struct Netcdf *Netcdffile;
++ struct NetCDFAtt *Netcdf_att;
++ VALUE Attribute;
++
++ Data_Get_Struct(file,struct Netcdf,Netcdffile);
++ ncid=Netcdffile->ncid;
++ Check_Type(att_name,T_STRING);
++ c_att_name=RSTRING_PTR(att_name);
++
++
++ status = nc_inq_attid(ncid,NC_GLOBAL,c_att_name,&attnump);
++ if(status != NC_NOERR){
++ if(status == NC_ENOTATT){
++ return(Qnil);
++ }
++ else{
++ NC_RAISE(status);
++ }
++ }
++
++ Netcdf_att = NetCDF_att_init(ncid,NC_GLOBAL,c_att_name);
++
++ Attribute = Data_Wrap_Struct(cNetCDFAtt,0,Netcdf_att_free,Netcdf_att);
++
++ return Attribute;
++}
++VALUE
++NetCDF_fill(VALUE file,VALUE mode)
++{
++ int ncid;
++ int status;
++ struct Netcdf *Netcdffile;
++ int old_modep;
++
++ Data_Get_Struct(file,struct Netcdf,Netcdffile);
++ ncid = Netcdffile->ncid;
++ if(mode==Qfalse){
++ status = nc_set_fill(ncid,NC_NOFILL,&old_modep);
++ if(status != NC_NOERR) NC_RAISE(status);
++ }
++ else if(mode == Qtrue){
++ status = nc_set_fill(ncid,NC_FILL,&old_modep);
++ if(status != NC_NOERR) NC_RAISE(status);
++ }
++ else
++ rb_raise(rb_eNetcdfError,"Usage:self.fill(true) or self.fill(false)");
++ return Qnil;
++}
++
++VALUE
++NetCDF_redef(VALUE file)
++{
++ int ncid;
++ int status;
++ struct Netcdf *Netcdffile;
++
++ rb_secure(3);
++ Data_Get_Struct(file,struct Netcdf,Netcdffile);
++ ncid=Netcdffile->ncid;
++ status = nc_redef(ncid);
++ if(status !=NC_NOERR){
++ if(status == NC_EINDEFINE){
++ return Qnil;
++ }
++ else{
++ NC_RAISE(status);
++ }
++ }
++ return Qtrue;
++}
++
++VALUE
++NetCDF_enddef(VALUE file)
++{
++ int ncid;
++ int status;
++ struct Netcdf *Netcdffile;
++
++ rb_secure(3);
++ Data_Get_Struct(file,struct Netcdf,Netcdffile);
++ ncid=Netcdffile->ncid;
++ status = nc_enddef(ncid);
++ if(status !=NC_NOERR){
++ if(status == NC_ENOTINDEFINE){
++ return Qnil;
++ }
++ else{
++ NC_RAISE(status);
++ }
++ }
++ return Qtrue;
++}
++
++VALUE
++NetCDF_whether_in_define_mode(VALUE file)
++{
++ /* returns true if the NetCDF object is currently in the define mode,
++ false if in the data mode, and
++ nil if else (possibly the file is read-only, or some other
++ error occurred)
++ */
++ int ncid;
++ int status;
++ struct Netcdf *Netcdffile;
++
++ rb_secure(3);
++ Data_Get_Struct(file,struct Netcdf,Netcdffile);
++ ncid=Netcdffile->ncid;
++ status = nc_redef(ncid);
++ if(status == NC_EINDEFINE){
++ return Qtrue;
++ } else if(status == NC_NOERR) {
++ /* was in the data mode --> recover the data mode and report false */
++ status = nc_enddef(ncid);
++ if(status == NC_NOERR) {
++ return Qfalse;
++ } else {
++ return Qnil;
++ }
++ } else {
++ return Qnil;
++ }
++}
++
++VALUE
++NetCDF_open(VALUE mod,VALUE filename,VALUE omode)
++{
++ int status;
++ int ncid;
++ char* c_filename;
++ int c_omode;
++ struct Netcdf *ncfile;
++ VALUE retval;
++
++ Check_Type(filename,T_STRING);
++ SafeStringValue(filename);
++ c_filename=RSTRING_PTR(filename);
++ Check_Type(omode,T_FIXNUM);
++ c_omode=NUM2INT(omode);
++
++ status = nc_open(c_filename,c_omode,&ncid);
++ if(status !=NC_NOERR){NC_RAISE2(status,c_filename);}
++
++ ncfile = NetCDF_init(ncid,c_filename);
++ retval = Data_Wrap_Struct(cNetCDF,0,NetCDF_free,ncfile);
++ return( retval );
++}
++
++VALUE
++NetCDF_create(VALUE mod,VALUE filename,VALUE cmode)
++{
++ int ncid;
++ int status;
++ char* c_filename;
++ int c_cmode;
++ struct Netcdf *ncfile;
++
++ Check_Type(filename,T_STRING);
++ SafeStringValue(filename);
++ c_filename=RSTRING_PTR(filename);
++ Check_Type(cmode,T_FIXNUM);
++ c_cmode=NUM2INT(cmode);
++
++ status = nc_create(c_filename,c_cmode,&ncid);
++ if(status != NC_NOERR) NC_RAISE2(status, c_filename);
++
++ ncfile = NetCDF_init(ncid,c_filename);
++ return( Data_Wrap_Struct(cNetCDF,0,NetCDF_free,ncfile) );
++}
++
++VALUE
++NetCDF_ndims(VALUE file)
++{
++ int ncid;
++ int ndimsp;
++ VALUE Integer;
++ int status;
++ struct Netcdf *ncfile;
++
++ Data_Get_Struct(file,struct Netcdf,ncfile);
++ ncid=ncfile->ncid;
++ status = nc_inq_ndims(ncid,&ndimsp);
++ if(status != NC_NOERR) NC_RAISE (status);
++ Integer = INT2NUM(ndimsp);
++ return Integer;
++}
++
++VALUE
++NetCDF_nvars(VALUE file)
++{
++ int ncid;
++ int nvarsp;
++ int status;
++ VALUE Integer;
++ struct Netcdf *ncfile;
++ Data_Get_Struct(file,struct Netcdf,ncfile);
++ ncid=ncfile->ncid;
++ status = nc_inq_nvars(ncid,&nvarsp);
++ if(status != NC_NOERR) NC_RAISE (status);
++ Integer = INT2NUM(nvarsp);
++ return Integer;
++}
++
++VALUE
++NetCDF_natts(VALUE file)
++{
++ int ncid;
++ int nattsp;
++ int status;
++ VALUE Integer;
++ struct Netcdf *ncfile;
++
++ Data_Get_Struct(file,struct Netcdf,ncfile);
++ ncid=ncfile->ncid;
++ status=nc_inq_natts(ncid,&nattsp);
++ if(status != NC_NOERR) NC_RAISE (status);
++ Integer = INT2NUM(nattsp);
++ return Integer;
++}
++
++VALUE
++NetCDF_unlimited(VALUE file)
++{
++ int ncid;
++ int unlimdimidp;
++ int status;
++ struct Netcdf *ncfile;
++ struct NetCDFDim *Netcdf_dim;
++ VALUE Dimension;
++
++ Data_Get_Struct(file,struct Netcdf,ncfile);
++ ncid=ncfile->ncid;
++ status=nc_inq_unlimdim(ncid,&unlimdimidp);
++ if(status !=NC_NOERR) NC_RAISE(status);
++
++ Netcdf_dim = NetCDF_dim_init(ncid,unlimdimidp);
++
++ /* If unlimdimidp=-1,No unlimited dimension is defined in the netCDF dataset */
++ if(unlimdimidp != -1)
++ {
++ Dimension = Data_Wrap_Struct(cNetCDFDim,0,NetCDF_dim_free,Netcdf_dim);
++ return Dimension;
++ }
++ else
++ {
++ return Qnil;
++ }
++}
++
++VALUE
++NetCDF_sync(VALUE file)
++{
++ int ncid;
++ int status;
++ struct Netcdf *ncfile;
++
++ rb_secure(3);
++ Data_Get_Struct(file,struct Netcdf,ncfile);
++ ncid=ncfile->ncid;
++ status = nc_sync(ncid);
++ if(status !=NC_NOERR) NC_RAISE (status);
++ return Qnil;
++}
++
++VALUE
++NetCDF_path(VALUE file)
++{
++ char *path;
++ struct Netcdf *ncfile;
++
++ Data_Get_Struct(file,struct Netcdf,ncfile);
++ path=ncfile->name;
++ return(rb_str_new2(path));
++}
++
++VALUE
++NetCDF_dim_length(VALUE Dim)
++{
++ int ncid;
++ int status;
++ int dimid;
++ size_t lengthp;
++ struct NetCDFDim *Netcdf_dim;
++
++ Data_Get_Struct(Dim,struct NetCDFDim,Netcdf_dim);
++ ncid=Netcdf_dim->ncid;
++ dimid=Netcdf_dim->dimid;
++
++ status = nc_inq_dimlen(ncid,dimid,&lengthp);
++ if(status != NC_NOERR) NC_RAISE(status);
++
++ return(INT2NUM(lengthp));
++}
++
++VALUE
++NetCDF_dim_name(VALUE Dim,VALUE dimension_newname)
++{
++ int ncid;
++ int status;
++ int dimid;
++ char *c_dim_name;
++ struct NetCDFDim *Netcdf_dim;
++
++ rb_secure(3);
++ Data_Get_Struct(Dim,struct NetCDFDim,Netcdf_dim);
++ ncid=Netcdf_dim->ncid;
++ dimid=Netcdf_dim->dimid;
++ Check_Type(dimension_newname,T_STRING);
++ c_dim_name = StringValueCStr(dimension_newname);
++
++ status = nc_rename_dim(ncid,dimid,c_dim_name);
++ if(status !=NC_NOERR) NC_RAISE(status);
++
++ return Qnil;
++}
++
++VALUE
++NetCDF_dim_inqname(VALUE Dim)
++{
++ int ncid;
++ int status;
++ int dimid;
++ char c_dim_name[NC_MAX_NAME];
++ struct NetCDFDim *Netcdf_dim;
++ VALUE str;
++
++ Data_Get_Struct(Dim,struct NetCDFDim,Netcdf_dim);
++ ncid=Netcdf_dim->ncid;
++ dimid=Netcdf_dim->dimid;
++
++ status = nc_inq_dimname(ncid,dimid,c_dim_name);
++ if(status !=NC_NOERR) NC_RAISE(status);
++
++ str = rb_str_new2(c_dim_name);
++ OBJ_TAINT(str);
++ return(str);
++}
++
++VALUE
++NetCDF_dim_whether_unlimited(VALUE Dim)
++{
++ int status;
++ int uldid;
++ struct NetCDFDim *Netcdf_dim;
++
++ Data_Get_Struct(Dim,struct NetCDFDim,Netcdf_dim);
++ status=nc_inq_unlimdim(Netcdf_dim->ncid,&uldid);
++ if(status !=NC_NOERR) NC_RAISE(status);
++ if(Netcdf_dim->dimid == uldid){
++ return(Qtrue);
++ } else {
++ return(Qfalse);
++ }
++}
++
++VALUE
++NetCDF_att_inq_name(VALUE Att)
++{
++ char *c_att_name;
++ struct NetCDFAtt *Netcdf_att;
++ VALUE str;
++
++ Data_Get_Struct(Att,struct NetCDFAtt,Netcdf_att);
++ c_att_name=Netcdf_att->name;
++
++ str = rb_str_new2(c_att_name);
++ OBJ_TAINT(str);
++ return(str);
++}
++
++VALUE
++NetCDF_att_rename(VALUE Att,VALUE new_att_name)
++{
++ int ncid;
++ int status;
++ int varid;
++ char *c_att_name;
++ char *c_new_att_name;
++ struct NetCDFAtt *Netcdf_att;
++ Data_Get_Struct(Att,struct NetCDFAtt,Netcdf_att);
++ ncid=Netcdf_att->ncid;
++ varid=Netcdf_att->varid;
++
++ c_att_name=Netcdf_att->name;
++
++ Check_Type(new_att_name,T_STRING);
++ SafeStringValue(new_att_name);
++ c_new_att_name=StringValueCStr(new_att_name);
++
++ status = nc_rename_att(ncid,varid,c_att_name,c_new_att_name);
++ if(status != NC_NOERR) NC_RAISE(status);
++
++ strcpy(Netcdf_att->name,c_new_att_name);
++ return Qnil;
++}
++
++VALUE
++NetCDF_id2dim(VALUE file,VALUE dimid)
++{
++ int ncid;
++ int c_dimid;
++ struct Netcdf *ncfile;
++ struct NetCDFDim *Netcdf_dim;
++ VALUE Dim;
++
++ Data_Get_Struct(file,struct Netcdf,ncfile);
++ ncid=ncfile->ncid;
++ Check_Type(dimid,T_FIXNUM);
++ c_dimid=NUM2INT(dimid);
++ Netcdf_dim = NetCDF_dim_init(ncid,c_dimid);
++ Dim=Data_Wrap_Struct(cNetCDFDim,0,NetCDF_dim_free,Netcdf_dim);
++ return(Dim);
++}
++
++VALUE
++NetCDF_id2var(VALUE file,VALUE varid)
++{
++ int ncid;
++ int c_varid;
++ struct Netcdf *ncfile;
++ struct NetCDFVar *Netcdf_var;
++ VALUE Var;
++
++ Data_Get_Struct(file,struct Netcdf,ncfile);
++ ncid=ncfile->ncid;
++ Check_Type(varid,T_FIXNUM);
++ c_varid=NUM2INT(varid);
++ Netcdf_var = NetCDF_var_init(ncid,c_varid,file);
++ Var=Data_Wrap_Struct(cNetCDFVar,nc_mark_obj,NetCDF_var_free,Netcdf_var);
++ return(Var);
++}
++
++
++VALUE
++NetCDF_id2att(VALUE file,VALUE attnum)
++{
++ int ncid;
++ int c_attnum;
++ int status;
++ struct Netcdf *ncfile;
++ struct NetCDFAtt *Netcdf_att;
++ char *c_att_name;
++ VALUE Att;
++ c_att_name=ALLOCA_N(char,NC_MAX_NAME);
++
++ Data_Get_Struct(file,struct Netcdf,ncfile);
++ ncid=ncfile->ncid;
++
++ Check_Type(attnum,T_FIXNUM);
++ c_attnum=NUM2INT(attnum);
++
++ status = nc_inq_attname(ncid,NC_GLOBAL,c_attnum,c_att_name);
++ if(status != NC_NOERR) NC_RAISE(status);
++
++ Netcdf_att=NetCDF_att_init(ncid,NC_GLOBAL,c_att_name);
++
++ Att=Data_Wrap_Struct(cNetCDFAtt,0,Netcdf_att_free,Netcdf_att);
++ return(Att);
++
++}
++
++#if NCVER >= 400
++/* USAGE
++ NetCDFVar#deflate(deflate_level, shuffle=false)
++ */
++VALUE
++NetCDF_var_deflate(int argc, VALUE *argv, VALUE Var)
++{
++ int ncid, varid, status;
++ struct NetCDFVar *Netcdf_var;
++
++ int shuffle;
++ /* If non-zero, turn on the shuffle filter.
++
++ http://www.unidata.ucar.edu/software/netcdf/papers/AMS_2008.pdf :
++ The shuffle algorithm changes the byte order in the data stream;
++ when used with integers that are all close together, this
++ results in a better compression ratio. There is no benefit
++ from using the shuffle filter without also using
++ compression.
++
++ MEMO by horinouchi: shuffling filter was also effective for float
++ variables in some test (demo5-netcdf4.rb).
++ */
++ int deflate_level;
++ int deflate=1;
++ /* Always set to non-zero:
++ See https://www.unidata.ucar.edu/software/netcdf/docs/netcdf-c/nc_005fdef_005fvar_005fdeflate.html#nc_005fdef_005fvar_005fdeflate
++ If non-zero, turn on the deflate filter at the
++ level specified by the deflate_level parameter.
++ */
++
++ if (argc>2 || argc<1) rb_raise(rb_eArgError,
++ "wrong # of arguments (%d). It must be 1 or 2", argc);
++
++ Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
++ ncid = Netcdf_var->ncid;
++ varid = Netcdf_var->varid;
++
++ deflate_level = NUM2INT(argv[0]);
++
++ if (argc==1) {
++ shuffle = 0; /* default: false */
++ } else {
++ if ( argv[1] == Qnil || argv[1] == Qfalse ) {
++ shuffle = 0;
++ } else {
++ shuffle = 1;
++ }
++ }
++
++ status = nc_def_var_deflate(ncid, varid, shuffle, deflate, deflate_level);
++ if(status != NC_NOERR) NC_RAISE(status);
++
++ return(Var);
++}
++
++VALUE
++NetCDF_var_deflate_params(VALUE Var)
++{
++ int ncid, varid, status;
++ struct NetCDFVar *Netcdf_var;
++ int shufflep, deflatep, deflate_levelp;
++ VALUE sh, df, params;
++
++ Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
++ ncid = Netcdf_var->ncid;
++ varid = Netcdf_var->varid;
++ status = nc_inq_var_deflate(ncid, varid, &shufflep, &deflatep,
++ &deflate_levelp);
++ if(status != NC_NOERR) NC_RAISE(status);
++ if (shufflep==0) {sh=Qfalse;} else {sh=Qtrue;}
++ if (deflatep==0) {df=Qfalse;} else {df=Qtrue;}
++ params = rb_ary_new3(3, sh, df, INT2NUM(deflate_levelp) );
++ return(params);
++}
++
++VALUE
++NetCDF_var_set_endian(VALUE Var, VALUE endian)
++{
++ int ncid, varid, status;
++ struct NetCDFVar *Netcdf_var;
++
++ Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
++ ncid = Netcdf_var->ncid;
++ varid = Netcdf_var->varid;
++ status = nc_def_var_endian(ncid, varid, NUM2INT(endian));
++ if(status != NC_NOERR) NC_RAISE(status);
++ return(Var);
++}
++
++VALUE
++NetCDF_var_endian(VALUE Var)
++{
++ int ncid, varid, status;
++ struct NetCDFVar *Netcdf_var;
++ int endian;
++
++ Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
++ ncid = Netcdf_var->ncid;
++ varid = Netcdf_var->varid;
++ status = nc_inq_var_endian(ncid, varid, &endian);
++ if(status != NC_NOERR) NC_RAISE(status);
++ return(INT2FIX(endian));
++}
++
++#endif
++
++VALUE
++NetCDF_var_id2att(VALUE Var,VALUE attnum)
++{
++ int ncid;
++ int c_attnum;
++ int status;
++ int c_varid;
++ struct NetCDFVar *Netcdf_var;
++ struct NetCDFAtt *Netcdf_att;
++ char *c_att_name;
++ VALUE Att;
++
++ Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
++ ncid=Netcdf_var->ncid;
++ c_varid=Netcdf_var->varid;
++
++ Check_Type(attnum,T_FIXNUM);
++ c_attnum=NUM2INT(attnum);
++
++ c_att_name=ALLOCA_N(char,NC_MAX_NAME);
++
++ status = nc_inq_attname(ncid,c_varid,c_attnum,c_att_name);
++ if(status != NC_NOERR) NC_RAISE(status);
++
++ Netcdf_att=NetCDF_att_init(ncid,c_varid,c_att_name);
++ Att=Data_Wrap_Struct(cNetCDFAtt,0,Netcdf_att_free,Netcdf_att);
++ return(Att);
++}
++
++VALUE
++NetCDF_var_dims(VALUE Var)
++{
++ int ncid, *dimids, ndims, varid, i, status;
++ struct NetCDFVar *Netcdf_var;
++ struct NetCDFDim *Netcdf_dim;
++ VALUE Dims;
++
++ Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
++ ncid = Netcdf_var->ncid;
++ varid = Netcdf_var->varid;
++ status = nc_inq_varndims(ncid,varid,&ndims);
++ if(status != NC_NOERR) NC_RAISE(status);
++ dimids=ALLOCA_N(int,ndims);
++ status = nc_inq_vardimid(ncid,varid,dimids);
++ if(status != NC_NOERR) NC_RAISE(status);
++ Dims = rb_ary_new();
++ for(i=0;i<ndims;i++){
++ Netcdf_dim = NetCDF_dim_init(ncid,dimids[ndims-1-i]);
++ rb_ary_push(Dims,
++ Data_Wrap_Struct(cNetCDFDim,0,NetCDF_dim_free,Netcdf_dim));
++ }
++ return(Dims);
++}
++
++VALUE
++NetCDF_var_dim(VALUE Var, VALUE ith)
++{
++ int ncid, *dimids, ndims, varid, status, c_ith;
++ struct NetCDFVar *Netcdf_var;
++ struct NetCDFDim *Netcdf_dim;
++ VALUE Dim;
++
++ Check_Type(ith,T_FIXNUM);
++ c_ith=NUM2INT(ith);
++ Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
++ ncid = Netcdf_var->ncid;
++ varid = Netcdf_var->varid;
++ status = nc_inq_varndims(ncid,varid,&ndims);
++ if(status != NC_NOERR) NC_RAISE(status);
++ if(c_ith < 0 || c_ith >= ndims) {
++ rb_raise(rb_eNetcdfError, "dimension count less than zero or greater than ndims-1");
++ }
++ dimids=ALLOCA_N(int,ndims);
++ status = nc_inq_vardimid(ncid,varid,dimids);
++ if(status != NC_NOERR) NC_RAISE(status);
++ Netcdf_dim = NetCDF_dim_init(ncid,dimids[ndims-1-c_ith]);
++ Dim = Data_Wrap_Struct(cNetCDFDim,0,NetCDF_dim_free,Netcdf_dim);
++ return(Dim);
++}
++
++VALUE
++NetCDF_att_copy(VALUE Att,VALUE Var_or_File)
++{
++ int ncid_in,ncid_out;
++ int status;
++ int varid_in,varid_out;
++ char *att_name;
++ struct NetCDFAtt *Netcdf_att;
++ struct NetCDFVar *Netcdf_var;
++ struct Netcdf *ncfile;
++ struct NetCDFAtt *Netcdf_att_out;
++
++ rb_secure(3);
++ Data_Get_Struct(Att,struct NetCDFAtt,Netcdf_att);
++ ncid_in=Netcdf_att->ncid;
++ varid_in=Netcdf_att->varid;
++ att_name=Netcdf_att->name;
++
++ if( rb_obj_is_kind_of(Var_or_File, cNetCDFVar) ){
++ Data_Get_Struct(Var_or_File,struct NetCDFVar, Netcdf_var);
++ ncid_out=Netcdf_var->ncid;
++ varid_out=Netcdf_var->varid;
++ } else if ( rb_obj_is_kind_of(Var_or_File, cNetCDF) ){
++ Data_Get_Struct(Var_or_File,struct Netcdf, ncfile);
++ ncid_out=ncfile->ncid;
++ varid_out=NC_GLOBAL;
++ } else {
++ rb_raise(rb_eNetcdfError,"The argument must be a NetCDFVar or a NetCDF");
++ }
++
++ status = nc_copy_att(ncid_in,varid_in,att_name,ncid_out,varid_out);
++ if(status != NC_NOERR) NC_RAISE(status);
++ Netcdf_att_out = NetCDF_att_init(ncid_out,varid_out,att_name);
++ return (Data_Wrap_Struct(cNetCDFAtt,0,Netcdf_att_free,Netcdf_att_out));
++}
++
++VALUE
++NetCDF_att_atttype(VALUE Att)
++{
++ int ncid;
++ int varid;
++ int status;
++ char *att_name;
++ const char *Attname;
++ struct NetCDFAtt *Netcdf_att;
++ nc_type xtypep;
++
++ Data_Get_Struct(Att,struct NetCDFAtt,Netcdf_att);
++ ncid = Netcdf_att->ncid;
++ varid = Netcdf_att->varid;
++ att_name = Netcdf_att->name;
++
++ status = nc_inq_atttype(ncid,varid,att_name,&xtypep);
++ if(status != NC_NOERR) NC_RAISE(status);
++
++ Attname = nctype2natype(xtypep);
++ return(rb_str_new2(Attname));
++}
++
++VALUE
++NetCDF_att_typecode(VALUE Att)
++{
++ int ncid;
++ int varid;
++ int status;
++ char *att_name;
++ struct NetCDFAtt *Netcdf_att;
++ nc_type xtypep;
++
++ Data_Get_Struct(Att,struct NetCDFAtt,Netcdf_att);
++ ncid = Netcdf_att->ncid;
++ varid = Netcdf_att->varid;
++ att_name = Netcdf_att->name;
++
++ status = nc_inq_atttype(ncid,varid,att_name,&xtypep);
++ if(status != NC_NOERR) NC_RAISE(status);
++
++ return(INT2NUM(nctype2natypecode(xtypep)));
++}
++
++VALUE
++NetCDF_att_delete(VALUE Att)
++{
++ int ncid;
++ int status;
++ int varid;
++ char *c_att_name;
++ struct NetCDFAtt *Netcdf_att;
++
++ rb_secure(3);
++ Data_Get_Struct(Att,struct NetCDFAtt,Netcdf_att);
++
++ ncid=Netcdf_att->ncid;
++ varid=Netcdf_att->varid;
++ c_att_name=Netcdf_att->name;
++
++ status = nc_del_att(ncid,varid,c_att_name);
++ if(status != NC_NOERR) NC_RAISE(status);
++
++ return Qnil;
++}
++
++VALUE
++NetCDF_att_put(VALUE Att,VALUE value,VALUE atttype)
++ /*
++ * atttype: nil or a String ("string","int",etc). If nil,
++ * the type of attribute is determined from the type of value
++ */
++{
++ struct NetCDFAtt *ncatt;
++
++ rb_secure(3);
++ Data_Get_Struct(Att,struct NetCDFAtt,ncatt);
++ return( NetCDF_put_att__(ncatt->ncid, ncatt->name, value,
++ atttype, ncatt->varid) );
++}
++
++VALUE
++NetCDF_att_get(VALUE Att)
++{
++ int ncid;
++ int varid;
++ char *c_attname;
++ int status;
++ struct NetCDFAtt *Netcdf_att;
++ nc_type xtypep;
++ size_t lenp;
++ na_shape_t attlen[1]; /* NArray uses int instead of size_t */
++ char *tp;
++ unsigned char *up;
++ short *sp;
++ int *ip;
++ float *fp;
++ double *dp;
++ VALUE NArray;
++ VALUE str;
++
++ Data_Get_Struct(Att,struct NetCDFAtt,Netcdf_att);
++ ncid = Netcdf_att->ncid;
++ varid = Netcdf_att->varid;
++ c_attname = Netcdf_att->name;
++
++ status = nc_inq_atttype(ncid,varid,c_attname,&xtypep);
++ if(status != NC_NOERR) NC_RAISE(status);
++
++ switch(xtypep){
++ case NC_CHAR:
++ status = nc_inq_attlen(ncid,varid,c_attname,&lenp);
++ if(status != NC_NOERR) NC_RAISE(status);
++ tp = ALLOCA_N(char,lenp+1);
++ tp[lenp]= '\0';
++ status = nc_get_att_text(ncid,varid,c_attname,tp);
++ if(status != NC_NOERR) NC_RAISE(status);
++ str = rb_str_new2(tp);
++ OBJ_TAINT(str);
++ return(str);
++ break;
++ case NC_BYTE:
++ status = nc_inq_attlen(ncid,varid,c_attname,&lenp);
++ if(status != NC_NOERR) NC_RAISE(status);
++
++ attlen[0]=lenp;
++ Cbyte_to_NArray(NArray,1,attlen,up);
++
++ status = nc_get_att_uchar(ncid,varid,c_attname,up);
++ if(status != NC_NOERR) NC_RAISE(status);
++
++ OBJ_TAINT(NArray);
++ return NArray;
++ break;
++ case NC_SHORT:
++ status = nc_inq_attlen(ncid,varid,c_attname,&lenp);
++ if(status != NC_NOERR) NC_RAISE(status);
++
++ attlen[0]=lenp;
++ Csint_to_NArray(NArray,1,attlen,sp);
++
++ status = nc_get_att_short(ncid,varid,c_attname,sp);
++ if(status != NC_NOERR) NC_RAISE(status);
++ OBJ_TAINT(NArray);
++ return NArray;
++ break;
++ case NC_INT:
++ status = nc_inq_attlen(ncid,varid,c_attname,&lenp);
++ if(status != NC_NOERR) NC_RAISE(status);
++
++ attlen[0]=lenp;
++ Clint_to_NArray(NArray,1,attlen,ip);
++
++ status = nc_get_att_int(ncid,varid,c_attname,ip);
++ if(status != NC_NOERR) NC_RAISE(status);
++
++ OBJ_TAINT(NArray);
++ return NArray;
++ break;
++ case NC_FLOAT:
++ status = nc_inq_attlen(ncid,varid,c_attname,&lenp);
++ if(status != NC_NOERR) NC_RAISE(status);
++
++ attlen[0]=lenp;
++ Cfloat_to_NArray(NArray,1,attlen,fp);
++
++ status = nc_get_att_float(ncid,varid,c_attname,fp);
++ if(status != NC_NOERR) NC_RAISE(status);
++
++ OBJ_TAINT(NArray);
++ return NArray;
++ break;
++ case NC_DOUBLE:
++ status = nc_inq_attlen(ncid,varid,c_attname,&lenp);
++ if(status != NC_NOERR) NC_RAISE(status);
++
++ attlen[0]=lenp;
++ Cdouble_to_NArray(NArray,1,attlen,dp);
++
++ status = nc_get_att_double(ncid,varid,c_attname,dp);
++ if(status != NC_NOERR) NC_RAISE(status);
++ OBJ_TAINT(NArray);
++ return NArray;
++ break;
++ default:
++ rb_raise(rb_eNetcdfError,"atttype isn't supported in netCDF");
++ }
++ return Qnil;
++}
++
++
++VALUE
++NetCDF_var_inq_name(VALUE Var)
++{
++ int ncid;
++ int status;
++ int varid;
++ char c_var_name[NC_MAX_NAME];
++ struct NetCDFVar *Netcdf_var;
++ VALUE Var_name;
++
++ Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
++
++ ncid=Netcdf_var->ncid;
++ varid=Netcdf_var->varid;
++ status = nc_inq_varname(ncid,varid,c_var_name);
++ if(status != NC_NOERR) NC_RAISE(status);
++
++ Var_name=rb_str_new2(c_var_name);
++ OBJ_TAINT(Var_name);
++ return Var_name;
++}
++
++VALUE
++NetCDF_var_ndims(VALUE Var)
++{
++ int ncid;
++ int status;
++ int varid;
++ int ndimsp;
++ struct NetCDFVar *Netcdf_var;
++ VALUE Var_ndims;
++
++ Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
++
++ ncid=Netcdf_var->ncid;
++ varid=Netcdf_var->varid;
++ status = nc_inq_varndims(ncid,varid,&ndimsp);
++ if(status != NC_NOERR) NC_RAISE(status);
++ Var_ndims=INT2FIX(ndimsp);
++ return Var_ndims;
++}
++
++VALUE
++NetCDF_var_vartype(VALUE Var)
++{
++ int ncid;
++ int status;
++ int varid;
++ nc_type xtypep;
++ struct NetCDFVar *Netcdf_var;
++ const char *Vartype;
++
++ Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
++
++ ncid=Netcdf_var->ncid;
++ varid=Netcdf_var->varid;
++
++ status = nc_inq_vartype(ncid,varid,&xtypep);
++ if(status != NC_NOERR) NC_RAISE(status);
++
++ Vartype=nctype2natype(xtypep);
++ return(rb_str_new2(Vartype));
++}
++
++VALUE
++NetCDF_var_typecode(VALUE Var)
++{
++ int ncid;
++ int status;
++ int varid;
++ nc_type xtypep;
++ struct NetCDFVar *Netcdf_var;
++
++ Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
++
++ ncid=Netcdf_var->ncid;
++ varid=Netcdf_var->varid;
++
++ status = nc_inq_vartype(ncid,varid,&xtypep);
++ if(status != NC_NOERR) NC_RAISE(status);
++
++ return(INT2NUM(nctype2natypecode(xtypep)));
++}
++
++
++VALUE
++NetCDF_var_natts(VALUE Var)
++{
++ int ncid;
++ int status;
++ int varid;
++ int nattsp;
++ struct NetCDFVar *Netcdf_var;
++ VALUE Var_natts;
++
++
++ Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
++
++ ncid=Netcdf_var->ncid;
++ varid=Netcdf_var->varid;
++
++ status= nc_inq_varnatts(ncid,varid,&nattsp);
++ if(status !=NC_NOERR) NC_RAISE(status);
++
++ Var_natts=INT2FIX(nattsp);
++ return Var_natts;
++}
++
++VALUE
++NetCDF_var_file(VALUE Var)
++{
++ struct NetCDFVar *Netcdf_var;
++ /* VALUE file; */
++ Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
++
++ return (Netcdf_var->file);
++}
++
++VALUE
++NetCDF_var_rename(VALUE Var,VALUE var_new_name)
++{
++ int ncid;
++ int status;
++ int varid;
++ char *c_var_new_name;
++ struct NetCDFVar *Netcdf_var;
++
++ rb_secure(3);
++ Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
++ ncid=Netcdf_var->ncid;
++ varid=Netcdf_var->varid;
++
++ Check_Type(var_new_name,T_STRING);
++ c_var_new_name=StringValueCStr(var_new_name);
++
++ status = nc_rename_var(ncid,varid,c_var_new_name);
++ if(status !=NC_NOERR) NC_RAISE(status);
++
++ return Qnil;
++}
++
++VALUE
++NetCDF_var_att(VALUE Var,VALUE att_name)
++{
++ int ncid;
++ int status;
++ int varid;
++ char *c_att_name;
++ int c_attnump;
++ struct NetCDFVar *Netcdf_var;
++ struct NetCDFAtt *Netcdf_att;
++ VALUE Att;
++
++ Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
++
++ ncid=Netcdf_var->ncid;
++ varid=Netcdf_var->varid;
++
++ Check_Type(att_name,T_STRING);
++ c_att_name=StringValueCStr(att_name);
++
++ status = nc_inq_attid(ncid,varid,c_att_name,&c_attnump);
++ if(status == NC_NOERR){
++ Netcdf_att=NetCDF_att_init(ncid,varid,c_att_name);
++ Att=Data_Wrap_Struct(cNetCDFAtt,0,Netcdf_att_free,Netcdf_att);
++ return Att;
++ }
++ else if(status == NC_ENOTATT){
++ return Qnil;
++ }
++ else{
++ NC_RAISE(status);
++ return Qnil;
++ }
++}
++
++/* Redifinition of the "==" and "eql?" methods */
++
++VALUE
++NetCDF_eql(VALUE filea,VALUE fileb)
++{
++ struct Netcdf *ncfilea;
++ struct Netcdf *ncfileb;
++
++ if( rb_obj_is_kind_of(fileb, cNetCDF) ){
++ Data_Get_Struct(filea,struct Netcdf,ncfilea);
++ Data_Get_Struct(fileb,struct Netcdf,ncfileb);
++
++ if(ncfilea->ncid == ncfileb->ncid &&
++ strcmp(ncfilea->name,ncfileb->name)==0){
++ return Qtrue;
++ } else {
++ return Qfalse;
++ }
++ } else {
++ return Qfalse;
++ }
++}
++
++VALUE
++NetCDF_var_eql(VALUE Vara,VALUE Varb)
++{
++ struct NetCDFVar *Netcdf_vara;
++ struct NetCDFVar *Netcdf_varb;
++
++ if( rb_obj_is_kind_of(Varb, cNetCDFVar) ){
++ Data_Get_Struct(Vara,struct NetCDFVar,Netcdf_vara);
++ Data_Get_Struct(Varb,struct NetCDFVar,Netcdf_varb);
++
++ if(Netcdf_vara->ncid == Netcdf_varb->ncid &&
++ Netcdf_vara->varid == Netcdf_varb->varid){
++ return Qtrue;
++ } else {
++ return Qfalse;
++ }
++ } else {
++ return Qfalse;
++ }
++}
++
++VALUE
++NetCDF_dim_eql(VALUE Dima,VALUE Dimb)
++{
++ struct NetCDFDim *Netcdf_dima;
++ struct NetCDFDim *Netcdf_dimb;
++
++ if( rb_obj_is_kind_of(Dimb, cNetCDFDim) ){
++ Data_Get_Struct(Dima,struct NetCDFDim,Netcdf_dima);
++ Data_Get_Struct(Dimb,struct NetCDFDim,Netcdf_dimb);
++
++ if(Netcdf_dima->ncid == Netcdf_dimb->ncid &&
++ Netcdf_dima->dimid == Netcdf_dimb->dimid){
++ return Qtrue;
++ } else {
++ return Qfalse;
++ }
++ } else {
++ return Qfalse;
++ }
++}
++
++VALUE
++NetCDF_att_eql(VALUE Atta,VALUE Attb)
++{
++ struct NetCDFAtt *Netcdf_atta;
++ struct NetCDFAtt *Netcdf_attb;
++
++ if( rb_obj_is_kind_of(Attb, cNetCDFAtt) ){
++ Data_Get_Struct(Atta,struct NetCDFAtt,Netcdf_atta);
++ Data_Get_Struct(Attb,struct NetCDFAtt,Netcdf_attb);
++
++ if(Netcdf_atta->ncid == Netcdf_atta->ncid &&
++ Netcdf_atta->varid == Netcdf_attb->varid &&
++ strcmp(Netcdf_atta->name,Netcdf_attb->name)==0){
++ return Qtrue;
++ } else {
++ return Qfalse;
++ }
++ } else {
++ return Qfalse;
++ }
++}
++
++/* Follow methods is to connect "NArray" with "Netcdf" */
++VALUE
++NetCDF_get_var_char(VALUE Var)
++{
++ int ncid;
++ int varid;
++ int status;
++ unsigned char *ptr;
++ struct NetCDFVar *Netcdf_var;
++ int i=0;
++ int ndimsp;
++ int *dimids;
++ size_t lengthp;
++ na_shape_t *shape; /* NArray uses int instead of size_t */
++ VALUE NArray;
++
++ Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
++ ncid = Netcdf_var->ncid;
++ varid = Netcdf_var->varid;
++ status = nc_inq_varndims(ncid,varid,&ndimsp);
++ if(status != NC_NOERR) NC_RAISE(status);
++ dimids = ALLOCA_N(int,ndimsp);
++ if (ndimsp != 0){
++ shape = ALLOCA_N(na_shape_t,ndimsp);
++ for(i=0;i<ndimsp;i++){
++ status = nc_inq_vardimid(ncid,varid,dimids);
++ if(status != NC_NOERR) NC_RAISE(status);
++ nc_inq_dimlen(ncid,dimids[i],&lengthp);
++ shape[ndimsp-1-i]=lengthp;
++ }
++ } else {
++ ndimsp = 1;
++ shape = ALLOCA_N(na_shape_t,1);
++ shape[0]=1;
++ }
++
++ Cbyte_to_NArray(NArray,ndimsp,shape,ptr);
++
++ status = nc_get_var_text(ncid,varid,(char *)ptr);
++ if(status != NC_NOERR) NC_RAISE(status);
++
++ OBJ_TAINT(NArray);
++ return NArray;
++}
++
++VALUE
++NetCDF_get_var_byte(VALUE Var)
++{
++ int ncid;
++ int varid;
++ int status;
++ unsigned char *ptr;
++ struct NetCDFVar *Netcdf_var;
++ int i=0;
++ int ndimsp;
++ int *dimids;
++ size_t lengthp;
++ na_shape_t *shape; /* NArray uses int instead of size_t */
++ VALUE NArray;
++
++ Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
++ ncid = Netcdf_var->ncid;
++ varid = Netcdf_var->varid;
++ status = nc_inq_varndims(ncid,varid,&ndimsp);
++ if(status != NC_NOERR) NC_RAISE(status);
++ dimids = ALLOCA_N(int,ndimsp);
++ if (ndimsp != 0){
++ shape = ALLOCA_N(na_shape_t,ndimsp);
++ for(i=0;i<ndimsp;i++){
++ status = nc_inq_vardimid(ncid,varid,dimids);
++ if(status != NC_NOERR) NC_RAISE(status);
++ nc_inq_dimlen(ncid,dimids[i],&lengthp);
++ shape[ndimsp-1-i]=lengthp;
++ }
++ } else {
++ ndimsp = 1;
++ shape = ALLOCA_N(na_shape_t,1);
++ shape[0]=1;
++ }
++
++ Cbyte_to_NArray(NArray,ndimsp,shape,ptr);
++
++ status = nc_get_var_uchar(ncid,varid,ptr);
++ if(status != NC_NOERR) NC_RAISE(status);
++
++ OBJ_TAINT(NArray);
++ return NArray;
++}
++
++VALUE
++NetCDF_get_var_sint(VALUE Var)
++{
++ int ncid;
++ int varid;
++ int status;
++ short *ptr;
++ struct NetCDFVar *Netcdf_var;
++ int i=0;
++ int ndimsp;
++ int *dimids;
++ size_t lengthp;
++ na_shape_t *shape; /* NArray uses int instead of size_t */
++ VALUE NArray;
++
++ Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
++ ncid = Netcdf_var->ncid;
++ varid = Netcdf_var->varid;
++ status = nc_inq_varndims(ncid,varid,&ndimsp);
++ if(status != NC_NOERR) NC_RAISE(status);
++ dimids = ALLOCA_N(int,ndimsp);
++ if (ndimsp != 0){
++ shape = ALLOCA_N(na_shape_t,ndimsp);
++ for(i=0;i<ndimsp;i++){
++ status = nc_inq_vardimid(ncid,varid,dimids);
++ if(status != NC_NOERR) NC_RAISE(status);
++ nc_inq_dimlen(ncid,dimids[i],&lengthp);
++ shape[ndimsp-1-i]=lengthp;
++ }
++ } else {
++ ndimsp = 1;
++ shape = ALLOCA_N(na_shape_t,1);
++ shape[0]=1;
++ }
++
++ Csint_to_NArray(NArray,ndimsp,shape,ptr);
++
++ status = nc_get_var_short(ncid,varid,ptr);
++ if(status != NC_NOERR) NC_RAISE(status);
++
++ OBJ_TAINT(NArray);
++ return NArray;
++}
++
++VALUE
++NetCDF_get_var_int(VALUE Var)
++{
++ int ncid;
++ int varid;
++ int status;
++ int *ptr;
++ struct NetCDFVar *Netcdf_var;
++ int i=0;
++ int ndimsp;
++ int *dimids;
++ size_t lengthp;
++ na_shape_t *shape; /* NArray uses int instead of size_t */
++ VALUE NArray;
++
++ Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
++ ncid = Netcdf_var->ncid;
++ varid = Netcdf_var->varid;
++ status = nc_inq_varndims(ncid,varid,&ndimsp);
++ if(status != NC_NOERR) NC_RAISE(status);
++ dimids = ALLOCA_N(int,ndimsp);
++ if (ndimsp != 0){
++ shape = ALLOCA_N(na_shape_t,ndimsp);
++ for(i=0;i<ndimsp;i++){
++ status = nc_inq_vardimid(ncid,varid,dimids);
++ if(status != NC_NOERR) NC_RAISE(status);
++ nc_inq_dimlen(ncid,dimids[i],&lengthp);
++ shape[ndimsp-1-i]=lengthp;
++ }
++ } else {
++ ndimsp = 1;
++ shape = ALLOCA_N(na_shape_t,1);
++ shape[0]=1;
++ }
++
++ Clint_to_NArray(NArray,ndimsp,shape,ptr);
++
++ status = nc_get_var_int(ncid,varid,ptr);
++ if(status != NC_NOERR) NC_RAISE(status);
++
++ OBJ_TAINT(NArray);
++ return NArray;
++}
++
++VALUE
++NetCDF_get_var_float(VALUE Var)
++{
++ int ncid;
++ int varid;
++ int status;
++ float *ptr;
++ struct NetCDFVar *Netcdf_var;
++ int i=0;
++ int ndimsp;
++ int *dimids;
++ size_t lengthp;
++ na_shape_t *shape; /* NArray uses int instead of size_t */
++ VALUE NArray;
++
++ Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
++ ncid = Netcdf_var->ncid;
++ varid = Netcdf_var->varid;
++ status = nc_inq_varndims(ncid,varid,&ndimsp);
++ if(status != NC_NOERR) NC_RAISE(status);
++ dimids = ALLOCA_N(int,ndimsp);
++ if (ndimsp != 0){
++ shape = ALLOCA_N(na_shape_t,ndimsp);
++ for(i=0;i<ndimsp;i++){
++ status = nc_inq_vardimid(ncid,varid,dimids);
++ if(status != NC_NOERR) NC_RAISE(status);
++ nc_inq_dimlen(ncid,dimids[i],&lengthp);
++ shape[ndimsp-1-i]=lengthp;
++ }
++ } else {
++ ndimsp = 1;
++ shape = ALLOCA_N(na_shape_t,1);
++ shape[0]=1;
++ }
++
++ Cfloat_to_NArray(NArray,ndimsp,shape,ptr);
++
++ status = nc_get_var_float(ncid,varid,ptr);
++ if(status != NC_NOERR) NC_RAISE(status);
++
++ OBJ_TAINT(NArray);
++ return NArray;
++}
++
++VALUE
++NetCDF_get_var_double(VALUE Var)
++{
++ int ncid;
++ int varid;
++ int status;
++ double *ptr;
++ struct NetCDFVar *Netcdf_var;
++ int i=0;
++ int ndimsp;
++ int *dimids;
++ size_t lengthp;
++ na_shape_t *shape; /* NArray uses int instead of size_t */
++ VALUE NArray;
++
++ Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
++ ncid = Netcdf_var->ncid;
++ varid = Netcdf_var->varid;
++ status = nc_inq_varndims(ncid,varid,&ndimsp);
++ if(status != NC_NOERR) NC_RAISE(status);
++ dimids = ALLOCA_N(int,ndimsp);
++ if (ndimsp != 0){
++ shape = ALLOCA_N(na_shape_t,ndimsp);
++ for(i=0;i<ndimsp;i++){
++ status = nc_inq_vardimid(ncid,varid,dimids);
++ if(status != NC_NOERR) NC_RAISE(status);
++ nc_inq_dimlen(ncid,dimids[i],&lengthp);
++ shape[ndimsp-1-i]=lengthp;
++ }
++ } else {
++ ndimsp = 1;
++ shape = ALLOCA_N(na_shape_t,1);
++ shape[0]=1;
++ }
++
++ Cdouble_to_NArray(NArray,ndimsp,shape,ptr);
++
++ status = nc_get_var_double(ncid,varid,ptr);
++ if(status != NC_NOERR) NC_RAISE(status);
++
++ OBJ_TAINT(NArray);
++ return NArray;
++}
++
++VALUE
++NetCDF_get_var1_char(VALUE Var,VALUE start)
++{
++ int ncid;
++ int varid;
++ int status;
++ unsigned char *ptr;
++ int i;
++ struct NetCDFVar *Netcdf_var;
++ na_shape_t l_start;
++ size_t *c_start;
++ int ndims;
++ int dimids[NC_MAX_DIMS];
++ size_t dimlen;
++ na_shape_t *c_count;
++ VALUE NArray;
++
++
++ Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
++ ncid = Netcdf_var->ncid;
++ varid = Netcdf_var->varid;
++ status = nc_inq_varndims(ncid, varid, &ndims);
++ if(status != NC_NOERR)NC_RAISE(status);
++ if(ndims == 0) {
++ rb_raise(rb_eNetcdfError,"Cannot specify a subset of a rank-0 scalar\n");
++ }
++
++ Check_Type(start,T_ARRAY);
++ if(RARRAY_LEN(start) < ndims) {
++ rb_raise(rb_eNetcdfError,"Length of 'start' is too short\n");
++ }
++
++ c_start=ALLOCA_N(size_t,ndims);
++ c_count=ALLOCA_N(na_shape_t,ndims);
++ for(i=0;i<ndims;i++){
++ l_start = NUM2INT(RARRAY_PTR(start)[ndims-1-i]);
++ status = nc_inq_vardimid(ncid,varid,dimids);
++ if(status != NC_NOERR) NC_RAISE(status);
++ if(l_start < 0) {
++ status = nc_inq_dimlen(ncid,dimids[i],&dimlen);
++ if(status != NC_NOERR) NC_RAISE(status);
++ l_start += dimlen;
++ }
++ c_start[i]=l_start;
++
++ c_count[i]=1;
++ }
++
++
++
++
++ Cbyte_to_NArray(NArray,ndims,c_count,ptr);
++ status = nc_get_var1_text(ncid,varid,c_start,(char *)ptr);
++ if(status != NC_NOERR) NC_RAISE(status);
++
++ OBJ_TAINT(NArray);
++ return NArray;
++
++}
++
++VALUE
++NetCDF_get_var1_byte(VALUE Var,VALUE start)
++{
++ int ncid;
++ int varid;
++ int status;
++ unsigned char *ptr;
++ int i;
++ struct NetCDFVar *Netcdf_var;
++ na_shape_t l_start;
++ size_t *c_start;
++ int ndims;
++ int dimids[NC_MAX_DIMS];
++ size_t dimlen;
++ na_shape_t *c_count;
++ VALUE NArray;
++
++
++ Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
++ ncid = Netcdf_var->ncid;
++ varid = Netcdf_var->varid;
++ status = nc_inq_varndims(ncid, varid, &ndims);
++ if(status != NC_NOERR)NC_RAISE(status);
++ if(ndims == 0) {
++ rb_raise(rb_eNetcdfError,"Cannot specify a subset of a rank-0 scalar\n");
++ }
++
++ Check_Type(start,T_ARRAY);
++ if(RARRAY_LEN(start) < ndims) {
++ rb_raise(rb_eNetcdfError,"Length of 'start' is too short\n");
++ }
++
++ c_start=ALLOCA_N(size_t,ndims);
++ c_count=ALLOCA_N(na_shape_t,ndims);
++ for(i=0;i<ndims;i++){
++ l_start = NUM2INT(RARRAY_PTR(start)[ndims-1-i]);
++ status = nc_inq_vardimid(ncid,varid,dimids);
++ if(status != NC_NOERR) NC_RAISE(status);
++ if(l_start < 0) {
++ status = nc_inq_dimlen(ncid,dimids[i],&dimlen);
++ if(status != NC_NOERR) NC_RAISE(status);
++ l_start += dimlen;
++ }
++ c_start[i]=l_start;
++
++ c_count[i]=1;
++ }
++
++
++
++
++ Cbyte_to_NArray(NArray,ndims,c_count,ptr);
++ status = nc_get_var1_uchar(ncid,varid,c_start,ptr);
++ if(status != NC_NOERR) NC_RAISE(status);
++
++ OBJ_TAINT(NArray);
++ return NArray;
++
++}
++
++VALUE
++NetCDF_get_var1_sint(VALUE Var,VALUE start)
++{
++ int ncid;
++ int varid;
++ int status;
++ short *ptr;
++ int i;
++ struct NetCDFVar *Netcdf_var;
++ na_shape_t l_start;
++ size_t *c_start;
++ int ndims;
++ int dimids[NC_MAX_DIMS];
++ size_t dimlen;
++ na_shape_t *c_count;
++ VALUE NArray;
++
++ Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
++ ncid = Netcdf_var->ncid;
++ varid = Netcdf_var->varid;
++ status = nc_inq_varndims(ncid, varid, &ndims);
++ if(status != NC_NOERR) NC_RAISE(status);
++ if(ndims == 0) {
++ rb_raise(rb_eNetcdfError,"Cannot specify a subset of a rank-0 scalar\n");
++ }
++
++ Check_Type(start,T_ARRAY);
++ if(RARRAY_LEN(start) < ndims) {
++ rb_raise(rb_eNetcdfError,"Length of 'start' is too short\n");
++ }
++
++ c_start=ALLOCA_N(size_t,ndims);
++ c_count=ALLOCA_N(na_shape_t,ndims);
++ for(i=0;i<ndims;i++){
++ l_start = NUM2INT(RARRAY_PTR(start)[ndims-1-i]);
++ status = nc_inq_vardimid(ncid,varid,dimids);
++ if(status != NC_NOERR) NC_RAISE(status);
++ if(l_start < 0) {
++ status = nc_inq_dimlen(ncid,dimids[i],&dimlen);
++ if(status != NC_NOERR) NC_RAISE(status);
++ l_start += dimlen;
++ }
++ c_start[i]=l_start;
++ c_count[i]=1;
++ }
++
++ Csint_to_NArray(NArray,ndims,c_count,ptr);
++
++ status = nc_get_var1_short(ncid,varid,c_start,ptr);
++ if(status != NC_NOERR) NC_RAISE(status);
++
++ OBJ_TAINT(NArray);
++ return NArray;
++
++}
++
++VALUE
++NetCDF_get_var1_int(VALUE Var,VALUE start)
++{
++ int ncid;
++ int varid;
++ int status;
++ int *ptr;
++ int i;
++ struct NetCDFVar *Netcdf_var;
++ na_shape_t l_start;
++ size_t *c_start;
++ int ndims;
++ int dimids[NC_MAX_DIMS];
++ size_t dimlen;
++ na_shape_t *c_count;
++ VALUE NArray;
++
++ Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
++ ncid = Netcdf_var->ncid;
++ varid = Netcdf_var->varid;
++ status = nc_inq_varndims(ncid, varid, &ndims);
++ if(status != NC_NOERR)NC_RAISE(status);
++ if(ndims == 0) {
++ rb_raise(rb_eNetcdfError,"Cannot specify a subset of a rank-0 scalar\n");
++ }
++
++ Check_Type(start,T_ARRAY);
++ if(RARRAY_LEN(start) < ndims) {
++ rb_raise(rb_eNetcdfError,"Length of 'start' is too short\n");
++ }
++
++ c_start=ALLOCA_N(size_t,ndims);
++ c_count=ALLOCA_N(na_shape_t,ndims);
++ for(i=0;i<ndims;i++){
++ l_start = NUM2INT(RARRAY_PTR(start)[ndims-1-i]);
++ status = nc_inq_vardimid(ncid,varid,dimids);
++ if(status != NC_NOERR) NC_RAISE(status);
++ if(l_start < 0) {
++ status = nc_inq_dimlen(ncid,dimids[i],&dimlen);
++ if(status != NC_NOERR) NC_RAISE(status);
++ l_start += dimlen;
++ }
++ c_start[i]=l_start;
++ c_count[i]=1;
++ }
++
++ Clint_to_NArray(NArray,ndims,c_count,ptr);
++
++ status = nc_get_var1_int(ncid,varid,c_start,ptr);
++ if(status != NC_NOERR) NC_RAISE(status);
++
++ OBJ_TAINT(NArray);
++ return NArray;
++
++}
++
++VALUE
++NetCDF_get_var1_float(VALUE Var,VALUE start)
++{
++ int ncid;
++ int varid;
++ int status;
++ float *ptr;
++ int i;
++ struct NetCDFVar *Netcdf_var;
++ na_shape_t l_start;
++ size_t *c_start;
++ int ndims;
++ int dimids[NC_MAX_DIMS];
++ size_t dimlen;
++ na_shape_t *c_count;
++ VALUE NArray;
++
++ Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
++ ncid = Netcdf_var->ncid;
++ varid = Netcdf_var->varid;
++ status = nc_inq_varndims(ncid, varid, &ndims);
++ if(status != NC_NOERR)NC_RAISE(status);
++ if(ndims == 0) {
++ rb_raise(rb_eNetcdfError,"Cannot specify a subset of a rank-0 scalar\n");
++ }
++
++ Check_Type(start,T_ARRAY);
++ if(RARRAY_LEN(start) < ndims) {
++ rb_raise(rb_eNetcdfError,"Length of 'start' is too short\n");
++ }
++
++ c_start=ALLOCA_N(size_t,ndims);
++ c_count=ALLOCA_N(na_shape_t,ndims);
++ for(i=0;i<ndims;i++){
++ l_start = NUM2INT(RARRAY_PTR(start)[ndims-1-i]);
++ status = nc_inq_vardimid(ncid, varid, dimids);
++ if(status != NC_NOERR) NC_RAISE(status);
++ if(l_start < 0) {
++ status = nc_inq_dimlen(ncid,dimids[i],&dimlen);
++ if(status != NC_NOERR) NC_RAISE(status);
++ l_start += dimlen;
++ }
++ c_start[i]=l_start;
++ c_count[i]=1;
++ }
++
++ Cfloat_to_NArray(NArray,ndims,c_count,ptr);
++
++ status = nc_get_var1_float(ncid,varid,c_start,ptr);
++ if(status != NC_NOERR) NC_RAISE(status);
++
++ OBJ_TAINT(NArray);
++ return NArray;
++
++}
++
++VALUE
++NetCDF_get_var1_double(VALUE Var,VALUE start)
++{
++ int ncid;
++ int varid;
++ int status;
++ double *ptr;
++ int i;
++ struct NetCDFVar *Netcdf_var;
++ na_shape_t l_start;
++ size_t *c_start;
++ int ndims;
++ int dimids[NC_MAX_DIMS];
++ size_t dimlen;
++ na_shape_t *c_count;
++ VALUE NArray;
++
++ Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
++ ncid = Netcdf_var->ncid;
++ varid = Netcdf_var->varid;
++ status = nc_inq_varndims(ncid, varid, &ndims);
++ if(status != NC_NOERR)NC_RAISE(status);
++ if(ndims == 0) {
++ rb_raise(rb_eNetcdfError,"Cannot specify a subset of a rank-0 scalar\n");
++ }
++
++ Check_Type(start,T_ARRAY);
++ if(RARRAY_LEN(start) < ndims) {
++ rb_raise(rb_eNetcdfError,"Length of 'start' is too short\n");
++ }
++
++ c_start=ALLOCA_N(size_t,ndims);
++ c_count=ALLOCA_N(na_shape_t,ndims);
++ for(i=0;i<ndims;i++){
++ l_start = NUM2INT(RARRAY_PTR(start)[ndims-1-i]);
++ status = nc_inq_vardimid(ncid,varid,dimids);
++ if(status !=NC_NOERR) NC_RAISE(status);
++ if(l_start < 0) {
++ status = nc_inq_dimlen(ncid,dimids[i],&dimlen);
++ if(status != NC_NOERR) NC_RAISE(status);
++ l_start += dimlen;
++ }
++ c_start[i]=l_start;
++ c_count[i]=1;
++ }
++
++ Cdouble_to_NArray(NArray,ndims,c_count,ptr);
++
++ status = nc_get_var1_double(ncid,varid,c_start,ptr);
++ if(status != NC_NOERR) NC_RAISE(status);
++
++ OBJ_TAINT(NArray);
++ return NArray;
++
++}
++
++VALUE
++NetCDF_get_vars_char(VALUE Var,VALUE start,VALUE end,VALUE stride)
++{
++ int ncid;
++ int varid;
++ int status;
++ unsigned char *ptr;
++ int i;
++ struct NetCDFVar *Netcdf_var;
++ na_shape_t l_start, l_end;
++ size_t *c_start;
++ size_t *c_count;
++ ptrdiff_t *c_stride;
++ na_shape_t *shape; /* NArray uses int instead of size_t */
++ int ndims;
++ int *dimids;
++ size_t dimlen;
++ VALUE NArray;
++
++ Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
++ ncid = Netcdf_var->ncid;
++ varid = Netcdf_var->varid;
++
++ status = nc_inq_varndims(ncid,varid,&ndims);
++ if(status != NC_NOERR) NC_RAISE(status);
++ if(ndims == 0) {
++ rb_raise(rb_eNetcdfError,"Cannot specify a subset of a rank-0 scalar\n");
++ }
++
++ dimids = ALLOCA_N(int,ndims);
++ status = nc_inq_vardimid(ncid,varid,dimids);
++ if(status != NC_NOERR) NC_RAISE(status);
++
++ Check_Type(start,T_ARRAY);
++ if(RARRAY_LEN(start) < ndims){
++ rb_raise(rb_eNetcdfError, "Length of 'start' is too short\n");
++ }
++ c_start = ALLOCA_N(size_t,ndims);
++ for(i=0; i<ndims; i++){
++ l_start=NUM2INT(RARRAY_PTR(start)[ndims-1-i]);
++
++ if(l_start < 0) {
++ status = nc_inq_dimlen(ncid, dimids[i], &dimlen);
++ if(status != NC_NOERR) NC_RAISE(status);
++ l_start += dimlen;
++ }
++ c_start[i]=l_start;
++ }
++
++ c_stride=ALLOCA_N(ptrdiff_t,ndims);
++ switch(TYPE(stride)){
++ case T_NIL:
++ for(i=0; i<ndims; i++){
++ c_stride[i]=1;
++ }
++ break;
++ default:
++ Check_Type(stride,T_ARRAY);
++ if(RARRAY_LEN(stride) < ndims) {
++ rb_raise(rb_eNetcdfError, "Length of 'stride is too short\n");
++ }
++ for(i=0;i<ndims; i++){
++ c_stride[i]=NUM2INT(RARRAY_PTR(stride)[ndims-1-i]);
++ if(c_stride[i]==0){
++ rb_raise(rb_eNetcdfError,"stride cannot be zero\n");
++ }
++ }
++ }
++
++ c_count=ALLOCA_N(size_t,ndims);
++ switch(TYPE(end)){
++ case T_NIL:
++ for(i=0; i<ndims; i++){
++ nc_inq_dimlen(ncid,dimids[i],&dimlen);
++ c_count[i]=(dimlen-c_start[i]-1)/c_stride[i]+1;
++ }
++ break;
++ default:
++ Check_Type(end,T_ARRAY);
++ if(RARRAY_LEN(end) <ndims) {
++ rb_raise(rb_eNetcdfError, "Length of 'end' is too short\n");
++ }
++ for(i=0; i<ndims; i++){
++ l_end= NUM2INT(RARRAY_PTR(end)[ndims-1-i]);
++ if(l_end < 0) {
++ status = nc_inq_dimlen(ncid,dimids[i],&dimlen);
++ if(status != NC_NOERR) NC_RAISE(status);
++ l_end +=dimlen;
++ }
++ c_count[i]=(l_end-c_start[i])/c_stride[i]+1;
++ }
++ }
++
++
++ shape = ALLOCA_N(na_shape_t,ndims);
++ for(i=0;i<ndims;i++){
++ shape[ndims-1-i]=c_count[i];
++ }
++
++ Cbyte_to_NArray(NArray,ndims,shape,ptr);
++
++ status = nc_get_vars_text(ncid,varid,c_start,c_count,c_stride,(char *)ptr);
++ if(status != NC_NOERR) NC_RAISE(status);
++
++ OBJ_TAINT(NArray);
++ return NArray;
++}
++
++VALUE
++NetCDF_get_vars_byte(VALUE Var,VALUE start,VALUE end,VALUE stride)
++{
++ int ncid;
++ int varid;
++ int status;
++ unsigned char *ptr;
++ int i;
++ struct NetCDFVar *Netcdf_var;
++ na_shape_t l_start, l_end;
++ size_t *c_start;
++ size_t *c_count;
++ ptrdiff_t *c_stride;
++ na_shape_t *shape; /* NArray uses int instead of size_t */
++ int ndims;
++ int *dimids;
++ size_t dimlen;
++ VALUE NArray;
++
++ Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
++ ncid = Netcdf_var->ncid;
++ varid = Netcdf_var->varid;
++
++ status = nc_inq_varndims(ncid,varid,&ndims);
++ if(status != NC_NOERR) NC_RAISE(status);
++ if(ndims == 0) {
++ rb_raise(rb_eNetcdfError,"Cannot specify a subset of a rank-0 scalar\n");
++ }
++
++ dimids = ALLOCA_N(int,ndims);
++ status = nc_inq_vardimid(ncid,varid,dimids);
++ if(status != NC_NOERR) NC_RAISE(status);
++
++ Check_Type(start,T_ARRAY);
++ if(RARRAY_LEN(start) < ndims){
++ rb_raise(rb_eNetcdfError, "Length of 'start' is too short\n");
++ }
++ c_start = ALLOCA_N(size_t,ndims);
++ for(i=0; i<ndims; i++){
++ l_start=NUM2INT(RARRAY_PTR(start)[ndims-1-i]);
++
++ if(l_start < 0) {
++ status = nc_inq_dimlen(ncid, dimids[i], &dimlen);
++ if(status != NC_NOERR) NC_RAISE(status);
++ l_start += dimlen;
++ }
++ c_start[i]=l_start;
++ }
++
++ c_stride=ALLOCA_N(ptrdiff_t,ndims);
++ switch(TYPE(stride)){
++ case T_NIL:
++ for(i=0; i<ndims; i++){
++ c_stride[i]=1;
++ }
++ break;
++ default:
++ Check_Type(stride,T_ARRAY);
++ if(RARRAY_LEN(stride) < ndims) {
++ rb_raise(rb_eNetcdfError, "Length of 'stride is too short\n");
++ }
++ for(i=0;i<ndims; i++){
++ c_stride[i]=NUM2INT(RARRAY_PTR(stride)[ndims-1-i]);
++ if(c_stride[i]==0){
++ rb_raise(rb_eNetcdfError,"stride cannot be zero\n");
++ }
++ }
++ }
++
++ c_count=ALLOCA_N(size_t,ndims);
++ switch(TYPE(end)){
++ case T_NIL:
++ for(i=0; i<ndims; i++){
++ nc_inq_dimlen(ncid,dimids[i],&dimlen);
++ c_count[i]=(dimlen-c_start[i]-1)/c_stride[i]+1;
++ }
++ break;
++ default:
++ Check_Type(end,T_ARRAY);
++ if(RARRAY_LEN(end) <ndims) {
++ rb_raise(rb_eNetcdfError, "Length of 'end' is too short\n");
++ }
++ for(i=0; i<ndims; i++){
++ l_end= NUM2INT(RARRAY_PTR(end)[ndims-1-i]);
++ if(l_end < 0) {
++ status = nc_inq_dimlen(ncid,dimids[i],&dimlen);
++ if(status != NC_NOERR) NC_RAISE(status);
++ l_end +=dimlen;
++ }
++ c_count[i]=(l_end-c_start[i])/c_stride[i]+1;
++ }
++ }
++
++
++ shape = ALLOCA_N(na_shape_t,ndims);
++ for(i=0;i<ndims;i++){
++ shape[ndims-1-i]=c_count[i];
++ }
++
++ Cbyte_to_NArray(NArray,ndims,shape,ptr);
++
++ status = nc_get_vars_uchar(ncid,varid,c_start,c_count,c_stride,ptr);
++ if(status != NC_NOERR) NC_RAISE(status);
++
++ OBJ_TAINT(NArray);
++ return NArray;
++}
++
++VALUE
++NetCDF_get_vars_sint(VALUE Var,VALUE start,VALUE end,VALUE stride)
++{
++ int ncid;
++ int varid;
++ int status;
++ short *ptr;
++ int i;
++ struct NetCDFVar *Netcdf_var;
++ na_shape_t l_start, l_end;
++ size_t *c_start;
++ size_t *c_count;
++ ptrdiff_t *c_stride;
++ na_shape_t *shape; /* NArray uses int instead of size_t */
++ int ndims;
++ int *dimids;
++ size_t dimlen;
++ VALUE NArray;
++
++ Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
++ ncid = Netcdf_var->ncid;
++ varid = Netcdf_var->varid;
++
++ status = nc_inq_varndims(ncid,varid,&ndims);
++ if(status != NC_NOERR) NC_RAISE(status);
++ if(ndims == 0) {
++ rb_raise(rb_eNetcdfError,"Cannot specify a subset of a rank-0 scalar\n");
++ }
++
++ dimids = ALLOCA_N(int,ndims);
++ status = nc_inq_vardimid(ncid,varid,dimids);
++ if(status != NC_NOERR) NC_RAISE(status);
++
++ Check_Type(start,T_ARRAY);
++ if(RARRAY_LEN(start) < ndims){
++ rb_raise(rb_eNetcdfError, "Length of 'start' is too short\n");
++ }
++ c_start = ALLOCA_N(size_t,ndims);
++ for(i=0; i<ndims; i++){
++ l_start=NUM2INT(RARRAY_PTR(start)[ndims-1-i]);
++
++ if(l_start < 0) {
++ status = nc_inq_dimlen(ncid, dimids[i], &dimlen);
++ if(status != NC_NOERR) NC_RAISE(status);
++ l_start += dimlen;
++ }
++ c_start[i]=l_start;
++ }
++
++ c_stride=ALLOCA_N(ptrdiff_t,ndims);
++ switch(TYPE(stride)){
++ case T_NIL:
++ for(i=0; i<ndims; i++){
++ c_stride[i]=1;
++ }
++ break;
++ default:
++ Check_Type(stride,T_ARRAY);
++ if(RARRAY_LEN(stride) < ndims) {
++ rb_raise(rb_eNetcdfError, "Length of 'stride is too short\n");
++ }
++ for(i=0;i<ndims; i++){
++ c_stride[i]=NUM2INT(RARRAY_PTR(stride)[ndims-1-i]);
++ if(c_stride[i]==0){
++ rb_raise(rb_eNetcdfError,"stride cannot be zero\n");
++ }
++ }
++ }
++
++ c_count=ALLOCA_N(size_t,ndims);
++ switch(TYPE(end)){
++ case T_NIL:
++ for(i=0; i<ndims; i++){
++ nc_inq_dimlen(ncid,dimids[i],&dimlen);
++ c_count[i]=(dimlen-c_start[i]-1)/c_stride[i]+1;
++ }
++ break;
++ default:
++ Check_Type(end,T_ARRAY);
++ if(RARRAY_LEN(end) <ndims) {
++ rb_raise(rb_eNetcdfError, "Length of 'end' is too short\n");
++ }
++ for(i=0; i<ndims; i++){
++ l_end= NUM2INT(RARRAY_PTR(end)[ndims-1-i]);
++ if(l_end < 0) {
++ status = nc_inq_dimlen(ncid,dimids[i],&dimlen);
++ if(status != NC_NOERR) NC_RAISE(status);
++ l_end +=dimlen;
++ }
++ c_count[i]=(l_end-c_start[i])/c_stride[i]+1;
++ }
++ }
++
++
++ shape = ALLOCA_N(na_shape_t,ndims);
++ for(i=0;i<ndims;i++){
++ shape[ndims-1-i]=c_count[i];
++ }
++
++ Csint_to_NArray(NArray,ndims,shape,ptr);
++
++
++ status = nc_get_vars_short(ncid,varid,c_start,c_count,c_stride,ptr);
++ if(status != NC_NOERR) NC_RAISE(status);
++
++ OBJ_TAINT(NArray);
++ return NArray;
++}
++
++VALUE
++NetCDF_get_vars_int(VALUE Var,VALUE start,VALUE end,VALUE stride)
++{
++ int ncid;
++ int varid;
++ int status;
++ int *ptr;
++ int i;
++ struct NetCDFVar *Netcdf_var;
++ na_shape_t l_start, l_end;
++ size_t *c_start;
++ size_t *c_count;
++ ptrdiff_t *c_stride;
++ na_shape_t *shape; /* NArray uses int instead of size_t */
++ int ndims;
++ int *dimids;
++ size_t dimlen;
++ VALUE NArray;
++
++ Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
++ ncid = Netcdf_var->ncid;
++ varid = Netcdf_var->varid;
++
++ status = nc_inq_varndims(ncid,varid,&ndims);
++ if(status != NC_NOERR) NC_RAISE(status);
++ if(ndims == 0) {
++ rb_raise(rb_eNetcdfError,"Cannot specify a subset of a rank-0 scalar\n");
++ }
++
++ dimids = ALLOCA_N(int,ndims);
++ status = nc_inq_vardimid(ncid,varid,dimids);
++ if(status != NC_NOERR) NC_RAISE(status);
++
++ Check_Type(start,T_ARRAY);
++ if(RARRAY_LEN(start) < ndims){
++ rb_raise(rb_eNetcdfError, "Length of 'start' is too short\n");
++ }
++ c_start = ALLOCA_N(size_t,ndims);
++ for(i=0; i<ndims; i++){
++ l_start=NUM2INT(RARRAY_PTR(start)[ndims-1-i]);
++
++ if(l_start < 0) {
++ status = nc_inq_dimlen(ncid, dimids[i], &dimlen);
++ if(status != NC_NOERR) NC_RAISE(status);
++ l_start += dimlen;
++ }
++ c_start[i]=l_start;
++ }
++
++ c_stride=ALLOCA_N(ptrdiff_t,ndims);
++ switch(TYPE(stride)){
++ case T_NIL:
++ for(i=0; i<ndims; i++){
++ c_stride[i]=1;
++ }
++ break;
++ default:
++ Check_Type(stride,T_ARRAY);
++ if(RARRAY_LEN(stride) < ndims) {
++ rb_raise(rb_eNetcdfError, "Length of 'stride is too short\n");
++ }
++ for(i=0;i<ndims; i++){
++ c_stride[i]=NUM2INT(RARRAY_PTR(stride)[ndims-1-i]);
++ if(c_stride[i]==0){
++ rb_raise(rb_eNetcdfError,"stride cannot be zero\n");
++ }
++ }
++ }
++
++ c_count=ALLOCA_N(size_t,ndims);
++ switch(TYPE(end)){
++ case T_NIL:
++ for(i=0; i<ndims; i++){
++ nc_inq_dimlen(ncid,dimids[i],&dimlen);
++ c_count[i]=(dimlen-c_start[i]-1)/c_stride[i]+1;
++ }
++ break;
++ default:
++ Check_Type(end,T_ARRAY);
++ if(RARRAY_LEN(end) <ndims) {
++ rb_raise(rb_eNetcdfError, "Length of 'end' is too short\n");
++ }
++ for(i=0; i<ndims; i++){
++ l_end= NUM2INT(RARRAY_PTR(end)[ndims-1-i]);
++ if(l_end < 0) {
++ status = nc_inq_dimlen(ncid,dimids[i],&dimlen);
++ if(status != NC_NOERR) NC_RAISE(status);
++ l_end +=dimlen;
++ }
++ c_count[i]=(l_end-c_start[i])/c_stride[i]+1;
++ }
++ }
++
++
++ shape = ALLOCA_N(na_shape_t,ndims);
++ for(i=0;i<ndims;i++){
++ shape[ndims-1-i]=c_count[i];
++ }
++
++ Clint_to_NArray(NArray,ndims,shape,ptr);
++
++
++ status = nc_get_vars_int(ncid,varid,c_start,c_count,c_stride,ptr);
++ if(status != NC_NOERR) NC_RAISE(status);
++
++ OBJ_TAINT(NArray);
++ return NArray;
++}
++
++VALUE
++NetCDF_get_vars_float(VALUE Var,VALUE start,VALUE end,VALUE stride)
++{
++ int ncid;
++ int varid;
++ int status;
++ float *ptr;
++ int i;
++ struct NetCDFVar *Netcdf_var;
++ na_shape_t l_start, l_end;
++ size_t *c_start;
++ size_t *c_count;
++ ptrdiff_t *c_stride;
++ na_shape_t *shape; /* NArray uses int instead of size_t */
++ int ndims;
++ int *dimids;
++ size_t dimlen;
++ VALUE NArray;
++
++ Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
++ ncid = Netcdf_var->ncid;
++ varid = Netcdf_var->varid;
++
++ status = nc_inq_varndims(ncid,varid,&ndims);
++ if(status != NC_NOERR) NC_RAISE(status);
++ if(ndims == 0) {
++ rb_raise(rb_eNetcdfError,"Cannot specify a subset of a rank-0 scalar\n");
++ }
++
++ dimids = ALLOCA_N(int,ndims);
++ status = nc_inq_vardimid(ncid,varid,dimids);
++ if(status != NC_NOERR) NC_RAISE(status);
++
++ Check_Type(start,T_ARRAY);
++ if(RARRAY_LEN(start) < ndims){
++ rb_raise(rb_eNetcdfError, "Length of 'start' is too short\n");
++ }
++ c_start = ALLOCA_N(size_t,ndims);
++ for(i=0; i<ndims; i++){
++ l_start=NUM2INT(RARRAY_PTR(start)[ndims-1-i]);
++
++ if(l_start < 0) {
++ status = nc_inq_dimlen(ncid, dimids[i], &dimlen);
++ if(status != NC_NOERR) NC_RAISE(status);
++ l_start += dimlen;
++ }
++ c_start[i]=l_start;
++ }
++
++ c_stride=ALLOCA_N(ptrdiff_t,ndims);
++ switch(TYPE(stride)){
++ case T_NIL:
++ for(i=0; i<ndims; i++){
++ c_stride[i]=1;
++ }
++ break;
++ default:
++ Check_Type(stride,T_ARRAY);
++ if(RARRAY_LEN(stride) < ndims) {
++ rb_raise(rb_eNetcdfError, "Length of 'stride is too short\n");
++ }
++ for(i=0;i<ndims; i++){
++ c_stride[i]=NUM2INT(RARRAY_PTR(stride)[ndims-1-i]);
++ if(c_stride[i]==0){
++ rb_raise(rb_eNetcdfError,"stride cannot be zero\n");
++ }
++ }
++ }
++
++ c_count=ALLOCA_N(size_t,ndims);
++ switch(TYPE(end)){
++ case T_NIL:
++ for(i=0; i<ndims; i++){
++ nc_inq_dimlen(ncid,dimids[i],&dimlen);
++ c_count[i]=(dimlen-c_start[i]-1)/c_stride[i]+1;
++ }
++ break;
++ default:
++ Check_Type(end,T_ARRAY);
++ if(RARRAY_LEN(end) <ndims) {
++ rb_raise(rb_eNetcdfError, "Length of 'end' is too short\n");
++ }
++ for(i=0; i<ndims; i++){
++ l_end= NUM2INT(RARRAY_PTR(end)[ndims-1-i]);
++ if(l_end < 0) {
++ status = nc_inq_dimlen(ncid,dimids[i],&dimlen);
++ if(status != NC_NOERR) NC_RAISE(status);
++ l_end +=dimlen;
++ }
++ c_count[i]=(l_end-c_start[i])/c_stride[i]+1;
++ }
++ }
++
++
++ shape = ALLOCA_N(na_shape_t,ndims);
++ for(i=0;i<ndims;i++){
++ shape[ndims-1-i]=c_count[i];
++ }
++
++ Cfloat_to_NArray(NArray,ndims,shape,ptr);
++
++
++ status = nc_get_vars_float(ncid,varid,c_start,c_count,c_stride,ptr);
++ if(status != NC_NOERR) NC_RAISE(status);
++
++ OBJ_TAINT(NArray);
++ return NArray;
++}
++
++VALUE
++NetCDF_get_vars_double(VALUE Var,VALUE start,VALUE end,VALUE stride)
++{
++ int ncid;
++ int varid;
++ int status;
++ double *ptr;
++ int i;
++ struct NetCDFVar *Netcdf_var;
++ na_shape_t l_start, l_end;
++ size_t *c_start;
++ size_t *c_count;
++ ptrdiff_t *c_stride;
++ na_shape_t *shape; /* NArray uses int instead of size_t */
++ int ndims;
++ int *dimids;
++ size_t dimlen;
++ VALUE NArray;
++
++ Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
++ ncid = Netcdf_var->ncid;
++ varid = Netcdf_var->varid;
++
++ status = nc_inq_varndims(ncid,varid,&ndims);
++ if(status != NC_NOERR) NC_RAISE(status);
++ if(ndims == 0) {
++ rb_raise(rb_eNetcdfError,"Cannot specify a subset of a rank-0 scalar\n");
++ }
++
++ dimids = ALLOCA_N(int,ndims);
++ status = nc_inq_vardimid(ncid,varid,dimids);
++ if(status != NC_NOERR) NC_RAISE(status);
++
++ Check_Type(start,T_ARRAY);
++ if(RARRAY_LEN(start) < ndims){
++ rb_raise(rb_eNetcdfError, "Length of 'start' is too short\n");
++ }
++ c_start = ALLOCA_N(size_t,ndims);
++ for(i=0; i<ndims; i++){
++ l_start=NUM2INT(RARRAY_PTR(start)[ndims-1-i]);
++
++ if(l_start < 0) {
++ status = nc_inq_dimlen(ncid, dimids[i], &dimlen);
++ if(status != NC_NOERR) NC_RAISE(status);
++ l_start += dimlen;
++ }
++ c_start[i]=l_start;
++ }
++
++ c_stride=ALLOCA_N(ptrdiff_t,ndims);
++ switch(TYPE(stride)){
++ case T_NIL:
++ for(i=0; i<ndims; i++){
++ c_stride[i]=1;
++ }
++ break;
++ default:
++ Check_Type(stride,T_ARRAY);
++ if(RARRAY_LEN(stride) < ndims) {
++ rb_raise(rb_eNetcdfError, "Length of 'stride is too short\n");
++ }
++ for(i=0;i<ndims; i++){
++ c_stride[i]=NUM2INT(RARRAY_PTR(stride)[ndims-1-i]);
++ if(c_stride[i]==0){
++ rb_raise(rb_eNetcdfError,"stride cannot be zero\n");
++ }
++ }
++ }
++
++ c_count=ALLOCA_N(size_t,ndims);
++ switch(TYPE(end)){
++ case T_NIL:
++ for(i=0; i<ndims; i++){
++ nc_inq_dimlen(ncid,dimids[i],&dimlen);
++ c_count[i]=(dimlen-c_start[i]-1)/c_stride[i]+1;
++ }
++ break;
++ default:
++ Check_Type(end,T_ARRAY);
++ if(RARRAY_LEN(end) <ndims) {
++ rb_raise(rb_eNetcdfError, "Length of 'end' is too short\n");
++ }
++ for(i=0; i<ndims; i++){
++ l_end= NUM2INT(RARRAY_PTR(end)[ndims-1-i]);
++ if(l_end < 0) {
++ status = nc_inq_dimlen(ncid,dimids[i],&dimlen);
++ if(status != NC_NOERR) NC_RAISE(status);
++ l_end +=dimlen;
++ }
++ c_count[i]=(l_end-c_start[i])/c_stride[i]+1;
++ }
++ }
++
++
++ shape = ALLOCA_N(na_shape_t,ndims);
++ for(i=0;i<ndims;i++){
++ shape[ndims-1-i]=c_count[i];
++ }
++
++ Cdouble_to_NArray(NArray,ndims,shape,ptr);
++
++ status = nc_get_vars_double(ncid,varid,c_start,c_count,c_stride,ptr);
++ if(status != NC_NOERR) NC_RAISE(status);
++
++ OBJ_TAINT(NArray);
++ return NArray;
++}
++
++
++VALUE
++NetCDF_put_var_char(VALUE Var,VALUE NArray)
++{
++ int ncid;
++ int varid;
++ int status;
++ unsigned char *ptr,scalar;
++ na_shape_t len,i=0;
++ struct NetCDFVar *Netcdf_var;
++ na_shape_t nc_tlen=1;
++ int ndimsp;
++ int dimids[NC_MAX_DIMS];
++ size_t lengthp;
++ char *var_name;
++
++ rb_secure(3);
++ Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
++ ncid=Netcdf_var->ncid;
++ varid=Netcdf_var->varid;
++
++ Array_to_Cbyte_len(NArray,ptr,len);
++
++ status = nc_inq_varndims(ncid,varid,&ndimsp);
++ if(status != NC_NOERR) NC_RAISE(status);
++ for(i=0;i<ndimsp;i++){
++ status = nc_inq_vardimid(ncid,varid,dimids);
++ if(status != NC_NOERR) NC_RAISE(status);
++ nc_inq_dimlen(ncid,dimids[i],&lengthp);
++ nc_tlen=lengthp*nc_tlen;
++ }
++ if(len == 1 && len != nc_tlen){
++ scalar = *ptr;
++ ptr = ALLOCA_N(unsigned char,nc_tlen);
++ for(i=0;i<nc_tlen;i++){ptr[i]=scalar;}
++ } else if(len != nc_tlen){
++ var_name=ALLOCA_N(char,NC_MAX_NAME);
++ status = nc_inq_varname(ncid,varid,var_name);
++ if(status != NC_NOERR) NC_RAISE(status );
++ rb_raise(rb_eNetcdfError,"Length of NArray don't equal to length of total array in the '%s'\n",var_name);
++ }
++ status = nc_put_var_text(ncid,varid,(char *)ptr);
++ if(status !=NC_NOERR) NC_RAISE(status);
++ return Qnil;
++}
++
++VALUE
++NetCDF_put_var_byte(VALUE Var,VALUE NArray)
++{
++ int ncid;
++ int varid;
++ int status;
++ unsigned char *ptr,scalar;
++ na_shape_t len,i=0;
++ struct NetCDFVar *Netcdf_var;
++ na_shape_t nc_tlen=1;
++ int ndimsp;
++ int dimids[NC_MAX_DIMS];
++ size_t lengthp;
++ char *var_name;
++
++ rb_secure(3);
++ Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
++ ncid=Netcdf_var->ncid;
++ varid=Netcdf_var->varid;
++
++ Array_to_Cbyte_len(NArray,ptr,len);
++
++ status = nc_inq_varndims(ncid,varid,&ndimsp);
++ if(status != NC_NOERR) NC_RAISE(status);
++ for(i=0;i<ndimsp;i++){
++ status = nc_inq_vardimid(ncid,varid,dimids);
++ if(status != NC_NOERR) NC_RAISE(status);
++ nc_inq_dimlen(ncid,dimids[i],&lengthp);
++ nc_tlen=lengthp*nc_tlen;
++ }
++ if(len == 1 && len != nc_tlen){
++ scalar = *ptr;
++ ptr = ALLOCA_N(unsigned char,nc_tlen);
++ for(i=0;i<nc_tlen;i++){ptr[i]=scalar;}
++ } else if(len != nc_tlen){
++ var_name=ALLOCA_N(char,NC_MAX_NAME);
++ status = nc_inq_varname(ncid,varid,var_name);
++ if(status != NC_NOERR) NC_RAISE(status );
++ rb_raise(rb_eNetcdfError,"Length of NArray don't equal to length of total array in the '%s'\n",var_name);
++ }
++ status = nc_put_var_uchar(ncid,varid,ptr);
++ if(status !=NC_NOERR) NC_RAISE(status);
++ return Qnil;
++}
++
++VALUE
++NetCDF_put_var_short(VALUE Var,VALUE NArray)
++{
++ int ncid;
++ int varid;
++ int status;
++ short *ptr,scalar;
++ na_shape_t len,i=0;
++ struct NetCDFVar *Netcdf_var;
++ na_shape_t nc_tlen=1;
++ int ndimsp;
++ int dimids[NC_MAX_DIMS];
++ size_t lengthp;
++ char *var_name;
++
++ rb_secure(3);
++ Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
++ ncid=Netcdf_var->ncid;
++ varid=Netcdf_var->varid;
++ Array_to_Csint_len(NArray,ptr,len);
++
++ status = nc_inq_varndims(ncid,varid,&ndimsp);
++ if(status != NC_NOERR) NC_RAISE(status);
++ for(i=0;i<ndimsp;i++){
++ status = nc_inq_vardimid(ncid,varid,dimids);
++ if(status != NC_NOERR) NC_RAISE(status);
++ nc_inq_dimlen(ncid,dimids[i],&lengthp);
++ nc_tlen=lengthp*nc_tlen;
++ }
++ if(len == 1 && len != nc_tlen){
++ scalar = *ptr;
++ ptr = ALLOCA_N(short,nc_tlen);
++ for(i=0;i<nc_tlen;i++){ptr[i]=scalar;}
++ } else if(len != nc_tlen){
++ var_name=ALLOCA_N(char,NC_MAX_NAME);
++ status = nc_inq_varname(ncid,varid,var_name);
++ if(status != NC_NOERR) NC_RAISE(status);
++ rb_raise(rb_eNetcdfError,"Length of NArray don't equal to length of total array length in the '%s'\n",var_name);
++ }
++
++ status = nc_put_var_short(ncid,varid,ptr);
++ if(status !=NC_NOERR) NC_RAISE(status);
++ return Qnil;
++}
++
++VALUE
++NetCDF_put_var_int(VALUE Var,VALUE NArray)
++{
++ int ncid;
++ int varid;
++ int status;
++ int *ptr,scalar;
++ na_shape_t len,i=0;
++ struct NetCDFVar *Netcdf_var;
++ na_shape_t nc_tlen=1;
++ int ndimsp;
++ int dimids[NC_MAX_DIMS];
++ size_t lengthp;
++ char *var_name;
++
++ rb_secure(3);
++ Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
++ ncid=Netcdf_var->ncid;
++ varid=Netcdf_var->varid;
++
++ Array_to_Clint_len(NArray,ptr,len);
++
++ status = nc_inq_varndims(ncid,varid,&ndimsp);
++ if(status != NC_NOERR) NC_RAISE(status);
++ for(i=0;i<ndimsp;i++){
++ status = nc_inq_vardimid(ncid,varid,dimids);
++ if(status != NC_NOERR) NC_RAISE(status);
++ nc_inq_dimlen(ncid,dimids[i],&lengthp);
++ nc_tlen=lengthp*nc_tlen;
++ }
++ if(len == 1 && len != nc_tlen){
++ scalar = *ptr;
++ ptr = ALLOCA_N(int,nc_tlen);
++ for(i=0;i<nc_tlen;i++){ptr[i]=scalar;}
++ } else if(len != nc_tlen){
++ var_name=ALLOCA_N(char,NC_MAX_NAME);
++ status = nc_inq_varname(ncid,varid,var_name);
++ if(status != NC_NOERR) NC_RAISE(status);
++ rb_raise(rb_eNetcdfError,"Length of NArray don't equal to length of total array length in the '%s'\n",var_name);
++ }
++
++
++ status = nc_put_var_int(ncid,varid,ptr);
++ if(status !=NC_NOERR) NC_RAISE(status);
++ return Qnil;
++}
++
++
++VALUE
++NetCDF_put_var_float(VALUE Var,VALUE NArray)
++{
++ int ncid;
++ int varid;
++ int status;
++ float *ptr,scalar;
++ na_shape_t len,i=0;
++ struct NetCDFVar *Netcdf_var;
++ na_shape_t nc_tlen=1;
++ int ndimsp;
++ int dimids[NC_MAX_DIMS];
++ size_t lengthp;
++ char *var_name;
++
++
++ rb_secure(3);
++ Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
++ ncid=Netcdf_var->ncid;
++ varid=Netcdf_var->varid;
++
++ Array_to_Cfloat_len(NArray,ptr,len);
++
++ status = nc_inq_varndims(ncid,varid,&ndimsp);
++ if(status != NC_NOERR) NC_RAISE(status);
++ for(i=0;i<ndimsp;i++){
++ status = nc_inq_vardimid(ncid,varid,dimids);
++ if(status != NC_NOERR) NC_RAISE(status);
++ nc_inq_dimlen(ncid,dimids[i],&lengthp);
++ nc_tlen=lengthp*nc_tlen;
++ }
++ if(len == 1 && len != nc_tlen){
++ scalar = *ptr;
++ ptr = ALLOCA_N(float,nc_tlen);
++ for(i=0;i<nc_tlen;i++){ptr[i]=scalar;}
++ } else if(len != nc_tlen){
++ var_name=ALLOCA_N(char,NC_MAX_NAME);
++ status = nc_inq_varname(ncid,varid,var_name);
++ if(status != NC_NOERR) NC_RAISE(status);
++ rb_raise(rb_eNetcdfError,"Length of NArray don't equal to length of total array length in the '%s'\n",var_name);
++ }
++
++ status = nc_put_var_float(ncid,varid,ptr);
++ if(status !=NC_NOERR) NC_RAISE(status);
++ return Qnil;
++}
++
++VALUE
++NetCDF_put_var_double(VALUE Var,VALUE NArray)
++{
++ int ncid;
++ int varid;
++ int status;
++ double *ptr,scalar;
++ na_shape_t len,i=0;
++ struct NetCDFVar *Netcdf_var;
++ na_shape_t nc_tlen=1;
++ int ndimsp;
++ int dimids[NC_MAX_DIMS];
++ size_t lengthp;
++ char *var_name;
++
++
++ rb_secure(3);
++ Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
++ ncid=Netcdf_var->ncid;
++ varid=Netcdf_var->varid;
++
++ Array_to_Cdouble_len(NArray,ptr,len);
++
++ status = nc_inq_varndims(ncid,varid,&ndimsp);
++ if(status != NC_NOERR) NC_RAISE(status);
++ for(i=0;i<ndimsp;i++){
++ status = nc_inq_vardimid(ncid,varid,dimids);
++ if(status != NC_NOERR) NC_RAISE(status);
++ nc_inq_dimlen(ncid,dimids[i],&lengthp);
++ nc_tlen=lengthp*nc_tlen;
++ }
++ if(len == 1 && len != nc_tlen){
++ scalar = *ptr;
++ ptr = ALLOCA_N(double,nc_tlen);
++ for(i=0;i<nc_tlen;i++){ptr[i]=scalar;}
++ } else if(len != nc_tlen){
++ var_name=ALLOCA_N(char,NC_MAX_NAME);
++ status = nc_inq_varname(ncid,varid,var_name);
++ if(status != NC_NOERR) NC_RAISE(status);
++ rb_raise(rb_eNetcdfError,"Length of NArray don't equal to length of total array length in the '%s'\n",var_name);
++ }
++
++ status = nc_put_var_double(ncid,varid,ptr);
++ if(status !=NC_NOERR) NC_RAISE(status);
++ return Qnil;
++}
++
++VALUE
++NetCDF_put_var1_char(VALUE Var,VALUE NArray,VALUE start)
++{
++ int ncid;
++ int varid;
++ int status;
++ unsigned char *ptr;
++ int i;
++ struct NetCDFVar *Netcdf_var;
++ na_shape_t l_start;
++ size_t *c_start;
++ int ndims;
++ int *dimids;
++ size_t dimlen;
++
++ rb_secure(3);
++ Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
++ ncid=Netcdf_var->ncid;
++ varid=Netcdf_var->varid;
++ status = nc_inq_varndims(ncid,varid,&ndims);
++ if(status != NC_NOERR) NC_RAISE(status);
++
++
++ dimids = ALLOCA_N(int,ndims);
++ status = nc_inq_vardimid(ncid,varid,dimids);
++ if(status != NC_NOERR) NC_RAISE(status);
++
++ Check_Type(start,T_ARRAY);
++ if(RARRAY_LEN(start) <ndims) {
++ rb_raise(rb_eNetcdfError,"Length of 'start' is too short\n");
++ }
++
++ c_start=ALLOCA_N(size_t,ndims);
++ for(i=0;i<ndims;i++){
++ l_start=NUM2INT(RARRAY_PTR(start)[ndims-1-i]);
++
++ if(l_start < 0) {
++ status = nc_inq_dimlen(ncid,dimids[i],&dimlen);
++ if(status != NC_NOERR) NC_RAISE(status);
++ l_start += dimlen;
++ }
++ c_start[i]=l_start;
++
++ }
++ Array_to_Cbyte(NArray,ptr);
++
++ status = nc_put_var1_text(ncid,varid,c_start,(char *)ptr);
++ if(status != NC_NOERR) NC_RAISE(status);
++ return Qnil;
++}
++
++VALUE
++NetCDF_put_var1_byte(VALUE Var,VALUE NArray,VALUE start)
++{
++ int ncid;
++ int varid;
++ int status;
++ unsigned char *ptr;
++ int i;
++ struct NetCDFVar *Netcdf_var;
++ na_shape_t l_start;
++ size_t *c_start;
++ int ndims;
++ int *dimids;
++ size_t dimlen;
++
++ rb_secure(3);
++ Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
++ ncid=Netcdf_var->ncid;
++ varid=Netcdf_var->varid;
++ status = nc_inq_varndims(ncid,varid,&ndims);
++ if(status != NC_NOERR) NC_RAISE(status);
++
++
++ dimids = ALLOCA_N(int,ndims);
++ status = nc_inq_vardimid(ncid,varid,dimids);
++ if(status != NC_NOERR) NC_RAISE(status);
++
++ Check_Type(start,T_ARRAY);
++ if(RARRAY_LEN(start) <ndims) {
++ rb_raise(rb_eNetcdfError,"Length of 'start' is too short\n");
++ }
++
++ c_start=ALLOCA_N(size_t,ndims);
++ for(i=0;i<ndims;i++){
++ l_start=NUM2INT(RARRAY_PTR(start)[ndims-1-i]);
++
++ if(l_start < 0) {
++ status = nc_inq_dimlen(ncid,dimids[i],&dimlen);
++ if(status != NC_NOERR) NC_RAISE(status);
++ l_start += dimlen;
++ }
++ c_start[i]=l_start;
++
++ }
++ Array_to_Cbyte(NArray,ptr);
++
++ status = nc_put_var1_uchar(ncid,varid,c_start,ptr);
++ if(status != NC_NOERR) NC_RAISE(status);
++ return Qnil;
++}
++
++VALUE
++NetCDF_put_var1_sint(VALUE Var,VALUE NArray,VALUE start)
++{
++ int ncid;
++ int varid;
++ int status;
++ short *ptr;
++ int i;
++ struct NetCDFVar *Netcdf_var;
++ na_shape_t l_start;
++ size_t *c_start;
++ int ndims;
++ int *dimids;
++ size_t dimlen;
++
++ rb_secure(3);
++ Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
++ ncid=Netcdf_var->ncid;
++ varid=Netcdf_var->varid;
++ status = nc_inq_varndims(ncid,varid,&ndims);
++ if(status != NC_NOERR) NC_RAISE(status);
++
++
++ dimids = ALLOCA_N(int,ndims);
++ status = nc_inq_vardimid(ncid,varid,dimids);
++ if(status != NC_NOERR) NC_RAISE(status);
++
++ Check_Type(start,T_ARRAY);
++ if(RARRAY_LEN(start) <ndims) {
++ rb_raise(rb_eNetcdfError,"Length of 'start' is too short\n");
++ }
++
++ c_start=ALLOCA_N(size_t,ndims);
++ for(i=0;i<ndims;i++){
++ l_start=NUM2INT(RARRAY_PTR(start)[ndims-1-i]);
++
++ if(l_start < 0) {
++ status = nc_inq_dimlen(ncid,dimids[i],&dimlen);
++ if(status != NC_NOERR) NC_RAISE(status);
++ l_start += dimlen;
++ }
++ c_start[i]=l_start;
++
++ }
++ Array_to_Csint(NArray,ptr);
++
++ status = nc_put_var1_short(ncid,varid,c_start,ptr);
++ if(status != NC_NOERR) NC_RAISE(status);
++ return Qnil;
++}
++VALUE
++NetCDF_put_var1_int(VALUE Var,VALUE NArray,VALUE start)
++{
++ int ncid;
++ int varid;
++ int status;
++ int *ptr;
++ int i;
++ struct NetCDFVar *Netcdf_var;
++ na_shape_t l_start;
++ size_t *c_start;
++ int ndims;
++ int *dimids;
++ size_t dimlen;
++
++ rb_secure(3);
++ Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
++ ncid=Netcdf_var->ncid;
++ varid=Netcdf_var->varid;
++ status = nc_inq_varndims(ncid,varid,&ndims);
++ if(status != NC_NOERR) NC_RAISE(status);
++
++
++ dimids = ALLOCA_N(int,ndims);
++ status = nc_inq_vardimid(ncid,varid,dimids);
++ if(status != NC_NOERR) NC_RAISE(status);
++
++ Check_Type(start,T_ARRAY);
++ if(RARRAY_LEN(start) <ndims) {
++ rb_raise(rb_eNetcdfError,"Length of 'start' is too short\n");
++ }
++
++ c_start=ALLOCA_N(size_t,ndims);
++ for(i=0;i<ndims;i++){
++ l_start=NUM2INT(RARRAY_PTR(start)[ndims-1-i]);
++
++ if(l_start < 0) {
++ status = nc_inq_dimlen(ncid,dimids[i],&dimlen);
++ if(status != NC_NOERR) NC_RAISE(status);
++ l_start += dimlen;
++ }
++ c_start[i]=l_start;
++
++ }
++ Array_to_Clint(NArray,ptr);
++
++ status = nc_put_var1_int(ncid,varid,c_start,ptr);
++ if(status != NC_NOERR) NC_RAISE(status);
++ return Qnil;
++}
++
++VALUE
++NetCDF_put_var1_float(VALUE Var,VALUE NArray,VALUE start)
++{
++ int ncid;
++ int varid;
++ int status;
++ float *ptr;
++ int i;
++ struct NetCDFVar *Netcdf_var;
++ na_shape_t l_start;
++ size_t *c_start;
++ int ndims;
++ int *dimids;
++ size_t dimlen;
++
++ rb_secure(3);
++ Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
++ ncid=Netcdf_var->ncid;
++ varid=Netcdf_var->varid;
++ status = nc_inq_varndims(ncid,varid,&ndims);
++ if(status != NC_NOERR) NC_RAISE(status);
++
++
++ dimids = ALLOCA_N(int,ndims);
++ status = nc_inq_vardimid(ncid,varid,dimids);
++ if(status != NC_NOERR) NC_RAISE(status);
++
++ Check_Type(start,T_ARRAY);
++ if(RARRAY_LEN(start) <ndims) {
++ rb_raise(rb_eNetcdfError,"Length of 'start' is too short\n");
++ }
++
++ c_start=ALLOCA_N(size_t,ndims);
++ for(i=0;i<ndims;i++){
++ l_start=NUM2INT(RARRAY_PTR(start)[ndims-1-i]);
++
++ if(l_start < 0) {
++ status = nc_inq_dimlen(ncid,dimids[i],&dimlen);
++ if(status != NC_NOERR) NC_RAISE(status);
++ l_start += dimlen;
++ }
++ c_start[i]=l_start;
++
++ }
++ Array_to_Cfloat(NArray,ptr);
++
++ status = nc_put_var1_float(ncid,varid,c_start,ptr);
++ if(status != NC_NOERR) NC_RAISE(status);
++ return Qnil;
++}
++
++VALUE
++NetCDF_put_var1_double(VALUE Var,VALUE NArray,VALUE start)
++{
++ int ncid;
++ int varid;
++ int status;
++ double *ptr;
++ int i;
++ struct NetCDFVar *Netcdf_var;
++ na_shape_t l_start;
++ size_t *c_start;
++ int ndims;
++ int *dimids;
++ size_t dimlen;
++
++ rb_secure(3);
++ Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
++ ncid=Netcdf_var->ncid;
++ varid=Netcdf_var->varid;
++ status = nc_inq_varndims(ncid,varid,&ndims);
++ if(status != NC_NOERR) NC_RAISE(status);
++
++
++ dimids = ALLOCA_N(int,ndims);
++ status = nc_inq_vardimid(ncid,varid,dimids);
++ if(status != NC_NOERR) NC_RAISE(status);
++
++ Check_Type(start,T_ARRAY);
++ if(RARRAY_LEN(start) <ndims) {
++ rb_raise(rb_eNetcdfError,"Length of 'start' is too short\n");
++ }
++
++ c_start=ALLOCA_N(size_t,ndims);
++ for(i=0;i<ndims;i++){
++ l_start=NUM2INT(RARRAY_PTR(start)[ndims-1-i]);
++
++ if(l_start < 0) {
++ status = nc_inq_dimlen(ncid,dimids[i],&dimlen);
++ if(status != NC_NOERR) NC_RAISE(status);
++ l_start += dimlen;
++ }
++ c_start[i]=l_start;
++
++ }
++ Array_to_Cdouble(NArray,ptr);
++
++ status = nc_put_var1_double(ncid,varid,c_start,ptr);
++ if(status != NC_NOERR) NC_RAISE(status);
++ return Qnil;
++}
++
++
++VALUE
++NetCDF_put_vars_char(VALUE Var,VALUE NArray,VALUE start,VALUE end,VALUE stride)
++{
++ int ncid;
++ int varid;
++ int status;
++ unsigned char *ptr,scalar;
++ na_shape_t len;
++ int c_count_all=1;
++ struct NetCDFVar *Netcdf_var;
++ na_shape_t l_start, l_end;
++ size_t *c_start;
++ size_t *c_count;
++ ptrdiff_t *c_stride;
++ int ndims,i;
++ na_shape_t *shape;
++ int *dimids;
++ size_t dimlen;
++
++ rb_secure(3);
++ Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
++ ncid=Netcdf_var->ncid;
++ varid=Netcdf_var->varid;
++ status = nc_inq_varndims(ncid, varid, &ndims);
++ if(status != NC_NOERR) NC_RAISE(status);
++
++ dimids=ALLOCA_N(int,ndims);
++ status = nc_inq_vardimid(ncid, varid, dimids);
++ if(status != NC_NOERR) NC_RAISE(status);
++
++ Check_Type(start,T_ARRAY);
++ if(RARRAY_LEN(start) < ndims) {
++ rb_raise(rb_eNetcdfError, "Length of 'start' is too short\n");
++ }
++ c_start=ALLOCA_N(size_t,ndims);
++ for(i=0; i<ndims; i++){
++ l_start=NUM2INT(RARRAY_PTR(start)[ndims-1-i]);
++
++ if(l_start < 0) {
++ status = nc_inq_dimlen(ncid, dimids[i], &dimlen);
++ if(status != NC_NOERR) NC_RAISE(status);
++ l_start += dimlen;
++ }
++ c_start[i]=l_start;
++ }
++
++ c_stride=ALLOCA_N(ptrdiff_t,ndims);
++ switch(TYPE(stride)){
++ case T_NIL:
++ for(i=0; i<ndims; i++){
++ c_stride[i]=1;
++ }
++ break;
++ default:
++ Check_Type(stride,T_ARRAY);
++ if(RARRAY_LEN(stride) < ndims) {
++ rb_raise(rb_eNetcdfError, "Length of 'stride' is too short\n");
++ }
++ for(i=0; i<ndims; i++){
++ c_stride[i]=NUM2INT(RARRAY_PTR(stride)[ndims-1-i]);
++ if(c_stride[i]==0) {
++ rb_raise(rb_eNetcdfError, "stride cannot be zero\n");
++ }
++ }
++ }
++
++ Array_to_Cbyte_len_shape(NArray,ptr,len,shape);
++
++ c_count=ALLOCA_N(size_t,ndims);
++ switch(TYPE(end)){
++ case T_NIL:
++ for(i=0; i<ndims; i++){
++ c_count[i]=shape[i];
++ }
++ c_count_all=len;
++ break;
++ default:
++ Check_Type(end,T_ARRAY);
++ if(RARRAY_LEN(end) < ndims) {
++ rb_raise(rb_eNetcdfError, "Length of 'end' is too short\n");
++ }
++ for(i=0; i<ndims; i++){
++ l_end=NUM2INT(RARRAY_PTR(end)[ndims-1-i]);
++ if(l_end < 0) {
++ status = nc_inq_dimlen(ncid, dimids[i], &dimlen);
++ if(status != NC_NOERR) NC_RAISE(status);
++ l_end += dimlen;
++ }
++ c_count[i]=(l_end-c_start[i])/c_stride[i]+1;
++ c_count_all=c_count[i]*c_count_all;
++ }
++ if(len == 1 && len != c_count_all){
++ scalar = *ptr;
++ ptr = ALLOCA_N(unsigned char,c_count_all);
++ for(i=0;i<c_count_all;i++){ptr[i]=scalar;}
++ } else if(len != c_count_all) {
++ rb_raise(rb_eNetcdfError,
++ "lengh of the array does not agree with that of the subset\n");
++ }
++ }
++
++ status = nc_put_vars_text(ncid,varid,c_start,c_count,c_stride,(char *)ptr);
++ if(status != NC_NOERR) NC_RAISE(status);
++ return Qnil;
++}
++
++VALUE
++NetCDF_put_vars_byte(VALUE Var,VALUE NArray,VALUE start,VALUE end,VALUE stride)
++{
++ int ncid;
++ int varid;
++ int status;
++ unsigned char *ptr,scalar;
++ na_shape_t len;
++ int c_count_all=1;
++ struct NetCDFVar *Netcdf_var;
++ na_shape_t l_start, l_end;
++ size_t *c_start;
++ size_t *c_count;
++ ptrdiff_t *c_stride;
++ int ndims,i;
++ na_shape_t *shape;
++ int *dimids;
++ size_t dimlen;
++
++ rb_secure(3);
++ Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
++ ncid=Netcdf_var->ncid;
++ varid=Netcdf_var->varid;
++ status = nc_inq_varndims(ncid, varid, &ndims);
++ if(status != NC_NOERR) NC_RAISE(status);
++
++ dimids=ALLOCA_N(int,ndims);
++ status = nc_inq_vardimid(ncid, varid, dimids);
++ if(status != NC_NOERR) NC_RAISE(status);
++
++ Check_Type(start,T_ARRAY);
++ if(RARRAY_LEN(start) < ndims) {
++ rb_raise(rb_eNetcdfError, "Length of 'start' is too short\n");
++ }
++ c_start=ALLOCA_N(size_t,ndims);
++ for(i=0; i<ndims; i++){
++ l_start=NUM2INT(RARRAY_PTR(start)[ndims-1-i]);
++
++ if(l_start < 0) {
++ status = nc_inq_dimlen(ncid, dimids[i], &dimlen);
++ if(status != NC_NOERR) NC_RAISE(status);
++ l_start += dimlen;
++ }
++ c_start[i]=l_start;
++ }
++
++ c_stride=ALLOCA_N(ptrdiff_t,ndims);
++ switch(TYPE(stride)){
++ case T_NIL:
++ for(i=0; i<ndims; i++){
++ c_stride[i]=1;
++ }
++ break;
++ default:
++ Check_Type(stride,T_ARRAY);
++ if(RARRAY_LEN(stride) < ndims) {
++ rb_raise(rb_eNetcdfError, "Length of 'stride' is too short\n");
++ }
++ for(i=0; i<ndims; i++){
++ c_stride[i]=NUM2INT(RARRAY_PTR(stride)[ndims-1-i]);
++ if(c_stride[i]==0) {
++ rb_raise(rb_eNetcdfError, "stride cannot be zero\n");
++ }
++ }
++ }
++
++ Array_to_Cbyte_len_shape(NArray,ptr,len,shape);
++
++ c_count=ALLOCA_N(size_t,ndims);
++ switch(TYPE(end)){
++ case T_NIL:
++ for(i=0; i<ndims; i++){
++ c_count[i]=shape[i];
++ }
++ c_count_all=len;
++ break;
++ default:
++ Check_Type(end,T_ARRAY);
++ if(RARRAY_LEN(end) < ndims) {
++ rb_raise(rb_eNetcdfError, "Length of 'end' is too short\n");
++ }
++ for(i=0; i<ndims; i++){
++ l_end=NUM2INT(RARRAY_PTR(end)[ndims-1-i]);
++ if(l_end < 0) {
++ status = nc_inq_dimlen(ncid, dimids[i], &dimlen);
++ if(status != NC_NOERR) NC_RAISE(status);
++ l_end += dimlen;
++ }
++ c_count[i]=(l_end-c_start[i])/c_stride[i]+1;
++ c_count_all=c_count[i]*c_count_all;
++ }
++ if(len == 1 && len != c_count_all){
++ scalar = *ptr;
++ ptr = ALLOCA_N(unsigned char,c_count_all);
++ for(i=0;i<c_count_all;i++){ptr[i]=scalar;}
++ } else if(len != c_count_all) {
++ rb_raise(rb_eNetcdfError,
++ "lengh of the array does not agree with that of the subset\n");
++ }
++ }
++
++ status = nc_put_vars_uchar(ncid,varid,c_start,c_count,c_stride,ptr);
++ if(status != NC_NOERR) NC_RAISE(status);
++ return Qnil;
++}
++
++VALUE
++NetCDF_put_vars_sint(VALUE Var,VALUE NArray,VALUE start,VALUE end,VALUE stride)
++{
++ int ncid;
++ int varid;
++ int status;
++ short *ptr,scalar;
++ na_shape_t len;
++ int c_count_all=1;
++ struct NetCDFVar *Netcdf_var;
++ na_shape_t l_start, l_end;
++ size_t *c_start;
++ size_t *c_count;
++ ptrdiff_t *c_stride;
++ int ndims,i;
++ na_shape_t *shape;
++ int *dimids;
++ size_t dimlen;
++
++ rb_secure(3);
++ Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
++ ncid=Netcdf_var->ncid;
++ varid=Netcdf_var->varid;
++ status = nc_inq_varndims(ncid, varid, &ndims);
++ if(status != NC_NOERR) NC_RAISE(status);
++
++ dimids=ALLOCA_N(int,ndims);
++ status = nc_inq_vardimid(ncid, varid, dimids);
++ if(status != NC_NOERR) NC_RAISE(status);
++
++ Check_Type(start,T_ARRAY);
++ if(RARRAY_LEN(start) < ndims) {
++ rb_raise(rb_eNetcdfError, "Length of 'start' is too short\n");
++ }
++ c_start=ALLOCA_N(size_t,ndims);
++ for(i=0; i<ndims; i++){
++ l_start=NUM2INT(RARRAY_PTR(start)[ndims-1-i]);
++
++ if(l_start < 0) {
++ status = nc_inq_dimlen(ncid, dimids[i], &dimlen);
++ if(status != NC_NOERR) NC_RAISE(status);
++ l_start += dimlen;
++ }
++ c_start[i]=l_start;
++ }
++
++ c_stride=ALLOCA_N(ptrdiff_t,ndims);
++ switch(TYPE(stride)){
++ case T_NIL:
++ for(i=0; i<ndims; i++){
++ c_stride[i]=1;
++ }
++ break;
++ default:
++ Check_Type(stride,T_ARRAY);
++ if(RARRAY_LEN(stride) < ndims) {
++ rb_raise(rb_eNetcdfError, "Length of 'stride' is too short\n");
++ }
++ for(i=0; i<ndims; i++){
++ c_stride[i]=NUM2INT(RARRAY_PTR(stride)[ndims-1-i]);
++ if(c_stride[i]==0) {
++ rb_raise(rb_eNetcdfError, "stride cannot be zero\n");
++ }
++ }
++ }
++
++ Array_to_Csint_len_shape(NArray,ptr,len,shape);
++
++ c_count=ALLOCA_N(size_t,ndims);
++ switch(TYPE(end)){
++ case T_NIL:
++ for(i=0; i<ndims; i++){
++ c_count[i]=shape[i];
++ }
++ c_count_all=len;
++ break;
++ default:
++ Check_Type(end,T_ARRAY);
++ if(RARRAY_LEN(end) < ndims) {
++ rb_raise(rb_eNetcdfError, "Length of 'end' is too short\n");
++ }
++ for(i=0; i<ndims; i++){
++ l_end=NUM2INT(RARRAY_PTR(end)[ndims-1-i]);
++ if(l_end < 0) {
++ status = nc_inq_dimlen(ncid, dimids[i], &dimlen);
++ if(status != NC_NOERR) NC_RAISE(status);
++ l_end += dimlen;
++ }
++ c_count[i]=(l_end-c_start[i])/c_stride[i]+1;
++ c_count_all=c_count[i]*c_count_all;
++ }
++ if(len == 1 && len != c_count_all){
++ scalar = *ptr;
++ ptr = ALLOCA_N(short,c_count_all);
++ for(i=0;i<c_count_all;i++){ptr[i]=scalar;}
++ } else if(len != c_count_all) {
++ rb_raise(rb_eNetcdfError,
++ "lengh of the array does not agree with that of the subset\n");
++ }
++ }
++
++ status = nc_put_vars_short(ncid,varid,c_start,c_count,c_stride,ptr);
++ if(status != NC_NOERR) NC_RAISE(status);
++ return Qnil;
++}
++
++
++VALUE
++NetCDF_put_vars_int(VALUE Var,VALUE NArray,VALUE start,VALUE end,VALUE stride)
++{
++ int ncid;
++ int varid;
++ int status;
++ int *ptr,scalar;
++ na_shape_t len;
++ int c_count_all=1;
++ struct NetCDFVar *Netcdf_var;
++ na_shape_t l_start, l_end;
++ size_t *c_start;
++ size_t *c_count;
++ ptrdiff_t *c_stride;
++ int ndims,i;
++ na_shape_t *shape;
++ int *dimids;
++ size_t dimlen;
++
++ rb_secure(3);
++ Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
++ ncid=Netcdf_var->ncid;
++ varid=Netcdf_var->varid;
++ status = nc_inq_varndims(ncid, varid, &ndims);
++ if(status != NC_NOERR) NC_RAISE(status);
++
++ dimids=ALLOCA_N(int,ndims);
++ status = nc_inq_vardimid(ncid, varid, dimids);
++ if(status != NC_NOERR) NC_RAISE(status);
++
++ Check_Type(start,T_ARRAY);
++ if(RARRAY_LEN(start) < ndims) {
++ rb_raise(rb_eNetcdfError, "Length of 'start' is too short\n");
++ }
++ c_start=ALLOCA_N(size_t,ndims);
++ for(i=0; i<ndims; i++){
++ l_start=NUM2INT(RARRAY_PTR(start)[ndims-1-i]);
++
++ if(l_start < 0) {
++ status = nc_inq_dimlen(ncid, dimids[i], &dimlen);
++ if(status != NC_NOERR) NC_RAISE(status);
++ l_start += dimlen;
++ }
++ c_start[i]=l_start;
++ }
++
++ c_stride=ALLOCA_N(ptrdiff_t,ndims);
++ switch(TYPE(stride)){
++ case T_NIL:
++ for(i=0; i<ndims; i++){
++ c_stride[i]=1;
++ }
++ break;
++ default:
++ Check_Type(stride,T_ARRAY);
++ if(RARRAY_LEN(stride) < ndims) {
++ rb_raise(rb_eNetcdfError, "Length of 'stride' is too short\n");
++ }
++ for(i=0; i<ndims; i++){
++ c_stride[i]=NUM2INT(RARRAY_PTR(stride)[ndims-1-i]);
++ if(c_stride[i]==0) {
++ rb_raise(rb_eNetcdfError, "stride cannot be zero\n");
++ }
++ }
++ }
++
++ Array_to_Clint_len_shape(NArray,ptr,len,shape);
++
++ c_count=ALLOCA_N(size_t,ndims);
++ switch(TYPE(end)){
++ case T_NIL:
++ for(i=0; i<ndims; i++){
++ c_count[i]=shape[i];
++ }
++ c_count_all=len;
++ break;
++ default:
++ Check_Type(end,T_ARRAY);
++ if(RARRAY_LEN(end) < ndims) {
++ rb_raise(rb_eNetcdfError, "Length of 'end' is too short\n");
++ }
++ for(i=0; i<ndims; i++){
++ l_end=NUM2INT(RARRAY_PTR(end)[ndims-1-i]);
++ if(l_end < 0) {
++ status = nc_inq_dimlen(ncid, dimids[i], &dimlen);
++ if(status != NC_NOERR) NC_RAISE(status);
++ l_end += dimlen;
++ }
++ c_count[i]=(l_end-c_start[i])/c_stride[i]+1;
++ c_count_all=c_count[i]*c_count_all;
++ }
++ if(len == 1 && len != c_count_all){
++ scalar = *ptr;
++ ptr = ALLOCA_N(int,c_count_all);
++ for(i=0;i<c_count_all;i++){ptr[i]=scalar;}
++ } else if(len != c_count_all) {
++ rb_raise(rb_eNetcdfError,
++ "length of the array does not agree with that of the subset\n");
++ }
++ }
++
++ status = nc_put_vars_int(ncid,varid,c_start,c_count,c_stride,ptr);
++ if(status != NC_NOERR) NC_RAISE(status);
++ return Qnil;
++}
++
++
++VALUE
++NetCDF_put_vars_float(VALUE Var,VALUE NArray,VALUE start,VALUE end,VALUE stride)
++{
++ int ncid;
++ int varid;
++ int status;
++ float *ptr,scalar;
++ na_shape_t len;
++ int c_count_all=1;
++ struct NetCDFVar *Netcdf_var;
++ na_shape_t l_start, l_end;
++ size_t *c_start;
++ size_t *c_count;
++ ptrdiff_t *c_stride;
++ int ndims,i;
++ na_shape_t *shape;
++ int *dimids;
++ size_t dimlen;
++
++ rb_secure(3);
++ Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
++ ncid=Netcdf_var->ncid;
++ varid=Netcdf_var->varid;
++ status = nc_inq_varndims(ncid, varid, &ndims);
++ if(status != NC_NOERR) NC_RAISE(status);
++
++ dimids=ALLOCA_N(int,ndims);
++ status = nc_inq_vardimid(ncid, varid, dimids);
++ if(status != NC_NOERR) NC_RAISE(status);
++
++ Check_Type(start,T_ARRAY);
++ if(RARRAY_LEN(start) < ndims) {
++ rb_raise(rb_eNetcdfError, "Length of 'start' is too short\n");
++ }
++ c_start=ALLOCA_N(size_t,ndims);
++ for(i=0; i<ndims; i++){
++ l_start=NUM2INT(RARRAY_PTR(start)[ndims-1-i]);
++
++ if(l_start < 0) {
++ status = nc_inq_dimlen(ncid, dimids[i], &dimlen);
++ if(status != NC_NOERR) NC_RAISE(status);
++ l_start += dimlen;
++ }
++ c_start[i]=l_start;
++ }
++
++ c_stride=ALLOCA_N(ptrdiff_t,ndims);
++ switch(TYPE(stride)){
++ case T_NIL:
++ for(i=0; i<ndims; i++){
++ c_stride[i]=1;
++ }
++ break;
++ default:
++ Check_Type(stride,T_ARRAY);
++ if(RARRAY_LEN(stride) < ndims) {
++ rb_raise(rb_eNetcdfError, "Length of 'stride' is too short\n");
++ }
++ for(i=0; i<ndims; i++){
++ c_stride[i]=NUM2INT(RARRAY_PTR(stride)[ndims-1-i]);
++ if(c_stride[i]==0) {
++ rb_raise(rb_eNetcdfError, "stride cannot be zero\n");
++ }
++ }
++ }
++
++ Array_to_Cfloat_len_shape(NArray,ptr,len,shape);
++
++ c_count=ALLOCA_N(size_t,ndims);
++ switch(TYPE(end)){
++ case T_NIL:
++ for(i=0; i<ndims; i++){
++ c_count[i]=shape[i];
++ }
++ c_count_all=len;
++ break;
++ default:
++ Check_Type(end,T_ARRAY);
++ if(RARRAY_LEN(end) < ndims) {
++ rb_raise(rb_eNetcdfError, "Length of 'end' is too short\n");
++ }
++ for(i=0; i<ndims; i++){
++ l_end=NUM2INT(RARRAY_PTR(end)[ndims-1-i]);
++ if(l_end < 0) {
++ status = nc_inq_dimlen(ncid, dimids[i], &dimlen);
++ if(status != NC_NOERR) NC_RAISE(status);
++ l_end += dimlen;
++ }
++ c_count[i]=(l_end-c_start[i])/c_stride[i]+1;
++ c_count_all=c_count[i]*c_count_all;
++ }
++ if(len == 1 && len != c_count_all){
++ scalar = *ptr;
++ ptr = ALLOCA_N(float,c_count_all);
++ for(i=0;i<c_count_all;i++){ptr[i]=scalar;}
++ } else if(len != c_count_all) {
++ rb_raise(rb_eNetcdfError,
++ "lengh of the array does not agree with that of the subset\n");
++ }
++ }
++
++ status = nc_put_vars_float(ncid,varid,c_start,c_count,c_stride,ptr);
++ if(status != NC_NOERR) NC_RAISE(status);
++ return Qnil;
++}
++
++
++VALUE
++NetCDF_put_vars_double(VALUE Var,VALUE NArray,VALUE start,VALUE end,VALUE stride)
++{
++ int ncid;
++ int varid;
++ int status;
++ double *ptr,scalar;
++ na_shape_t len;
++ int c_count_all=1;
++ struct NetCDFVar *Netcdf_var;
++ na_shape_t l_start, l_end;
++ size_t *c_start;
++ size_t *c_count;
++ ptrdiff_t *c_stride;
++ int ndims,i;
++ na_shape_t *shape;
++ int *dimids;
++ size_t dimlen;
++
++ rb_secure(3);
++ Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
++ ncid=Netcdf_var->ncid;
++ varid=Netcdf_var->varid;
++ status = nc_inq_varndims(ncid, varid, &ndims);
++ if(status != NC_NOERR) NC_RAISE(status);
++
++ dimids=ALLOCA_N(int,ndims);
++ status = nc_inq_vardimid(ncid, varid, dimids);
++ if(status != NC_NOERR) NC_RAISE(status);
++
++ Check_Type(start,T_ARRAY);
++ if(RARRAY_LEN(start) < ndims) {
++ rb_raise(rb_eNetcdfError, "Length of 'start' is too short\n");
++ }
++ c_start=ALLOCA_N(size_t,ndims);
++ for(i=0; i<ndims; i++){
++ l_start=NUM2INT(RARRAY_PTR(start)[ndims-1-i]);
++
++ if(l_start < 0) {
++ status = nc_inq_dimlen(ncid, dimids[i], &dimlen);
++ if(status != NC_NOERR) NC_RAISE(status);
++ l_start += dimlen;
++ }
++ c_start[i]=l_start;
++ }
++
++ c_stride=ALLOCA_N(ptrdiff_t,ndims);
++ switch(TYPE(stride)){
++ case T_NIL:
++ for(i=0; i<ndims; i++){
++ c_stride[i]=1;
++ }
++ break;
++ default:
++ Check_Type(stride,T_ARRAY);
++ if(RARRAY_LEN(stride) < ndims) {
++ rb_raise(rb_eNetcdfError, "Length of 'stride' is too short\n");
++ }
++ for(i=0; i<ndims; i++){
++ c_stride[i]=NUM2INT(RARRAY_PTR(stride)[ndims-1-i]);
++ if(c_stride[i]==0) {
++ rb_raise(rb_eNetcdfError, "stride cannot be zero\n");
++ }
++ }
++ }
++
++ Array_to_Cdouble_len_shape(NArray,ptr,len,shape);
++
++ c_count=ALLOCA_N(size_t,ndims);
++ switch(TYPE(end)){
++ case T_NIL:
++ for(i=0; i<ndims; i++){
++ c_count[i]=shape[i];
++ }
++ c_count_all=len;
++ break;
++ default:
++ Check_Type(end,T_ARRAY);
++ if(RARRAY_LEN(end) < ndims) {
++ rb_raise(rb_eNetcdfError, "Length of 'end' is too short\n");
++ }
++ for(i=0; i<ndims; i++){
++ l_end=NUM2INT(RARRAY_PTR(end)[ndims-1-i]);
++ if(l_end < 0) {
++ status = nc_inq_dimlen(ncid, dimids[i], &dimlen);
++ if(status != NC_NOERR) NC_RAISE(status);
++ l_end += dimlen;
++ }
++ c_count[i]=(l_end-c_start[i])/c_stride[i]+1;
++ c_count_all=c_count[i]*c_count_all;
++ }
++ if(len == 1 && len != c_count_all){
++ scalar = *ptr;
++ ptr = ALLOCA_N(double,c_count_all);
++ for(i=0;i<c_count_all;i++){ptr[i]=scalar;}
++ } else if(len != c_count_all) {
++ rb_raise(rb_eNetcdfError,
++ "lengh of the array does not agree with that of the subset\n");
++ }
++ }
++
++ status = nc_put_vars_double(ncid,varid,c_start,c_count,c_stride,ptr);
++ if(status != NC_NOERR) NC_RAISE(status);
++ return Qnil;
++}
++
++void
++Init_netcdfraw(void)
++{
++ mNumRu = rb_define_module("NumRu");
++
++ /* Difinitions of the classes */
++ cNetCDF = rb_define_class_under(mNumRu, "NetCDF", rb_cObject);
++ cNetCDFDim = rb_define_class_under(mNumRu, "NetCDFDim", rb_cObject);
++ cNetCDFAtt = rb_define_class_under(mNumRu, "NetCDFAtt", rb_cObject);
++ cNetCDFVar = rb_define_class_under(mNumRu, "NetCDFVar", rb_cObject);
++
++ rb_eNetcdfError = rb_define_class("NetcdfError",rb_eStandardError);
++ rb_eNetcdfBadid = rb_define_class("NetcdfBadid",rb_eNetcdfError);
++ rb_eNetcdfNfile = rb_define_class("NetcdfNfile",rb_eNetcdfError);
++ rb_eNetcdfExist = rb_define_class("NetcdfExist",rb_eNetcdfError);
++ rb_eNetcdfInval = rb_define_class("NetcdfInval",rb_eNetcdfError);
++ rb_eNetcdfPerm = rb_define_class("NetcdfPerm",rb_eNetcdfError);
++ rb_eNetcdfNotindefine = rb_define_class("NetcdfNotindefine",rb_eNetcdfError);
++ rb_eNetcdfIndefine = rb_define_class("NetcdfIndefine",rb_eNetcdfError);
++ rb_eNetcdfInvalcoords = rb_define_class("NetcdfInvalcoords",rb_eNetcdfError);
++ rb_eNetcdfMaxdims = rb_define_class("NetcdfMaxdims",rb_eNetcdfError);
++ rb_eNetcdfNameinuse = rb_define_class("NetcdfNameinuse",rb_eNetcdfError);
++ rb_eNetcdfNotatt = rb_define_class("NetcdfNotatt",rb_eNetcdfError);
++ rb_eNetcdfMaxatts = rb_define_class("NetcdfMaxatts",rb_eNetcdfError);
++ rb_eNetcdfBadtype = rb_define_class("NetcdfBadtype",rb_eNetcdfError);
++ rb_eNetcdfBaddim = rb_define_class("NetcdfBaddim",rb_eNetcdfError);
++ rb_eNetcdfUnlimpos = rb_define_class("NetcdFUnlimpos",rb_eNetcdfError);
++ rb_eNetcdfMaxvars = rb_define_class("NetcdfMaxvars",rb_eNetcdfError);
++ rb_eNetcdfNotvar = rb_define_class("NetcdfNotvar",rb_eNetcdfError);
++ rb_eNetcdfGlobal = rb_define_class("NetcdfGlobal",rb_eNetcdfError);
++ rb_eNetcdfNotnc = rb_define_class("NetcdfNotnc",rb_eNetcdfError);
++ rb_eNetcdfSts = rb_define_class("NetcdfSts",rb_eNetcdfError);
++ rb_eNetcdfMaxname = rb_define_class("NetcdfMaxname",rb_eNetcdfError);
++ rb_eNetcdfUnlimit = rb_define_class("NetcdfUnlimit",rb_eNetcdfError);
++ rb_eNetcdfNorecvars = rb_define_class("NetcdfNorecvars",rb_eNetcdfError);
++ rb_eNetcdfChar = rb_define_class("NetcdfChar",rb_eNetcdfError);
++ rb_eNetcdfEdge = rb_define_class("NetcdfEdge",rb_eNetcdfError);
++ rb_eNetcdfStride = rb_define_class("NetcdfStride",rb_eNetcdfError);
++ rb_eNetcdfBadname = rb_define_class("NetcdfBadname",rb_eNetcdfError);
++ /* N.B. following must match value in ncx.h */
++ rb_eNetcdfRange = rb_define_class("NetcdfRange",rb_eNetcdfError);
++ rb_eNetcdfNomem = rb_define_class("NetcdfNomem",rb_eNetcdfError);
++ /* Global error status */
++ rb_eNetcdfEntool = rb_define_class("NetcdfEntool",rb_eNetcdfError);
++ rb_eNetcdfExdr = rb_define_class("NetcdfExdr",rb_eNetcdfError);
++ rb_eNetcdfSyserr = rb_define_class("NetcdfSyserr",rb_eNetcdfError);
++ /* Global options variable. Used to determine behavior of error handler. */
++ rb_eNetcdfFatal = rb_define_class("NetcdfFatal",rb_eNetcdfError);
++
++ /* Class Constants Definition */
++ rb_define_const(cNetCDF, "NC_NOWRITE", INT2FIX(NC_NOWRITE));
++ rb_define_const(cNetCDF, "NC_WRITE", INT2FIX(NC_WRITE));
++ rb_define_const(cNetCDF, "NC_SHARE", INT2FIX(NC_SHARE));
++ rb_define_const(cNetCDF, "NC_CLOBBER", INT2FIX(NC_CLOBBER));
++ rb_define_const(cNetCDF, "NC_NOCLOBBER", INT2FIX(NC_NOCLOBBER));
++#if NCVER >= 400
++ rb_define_const(cNetCDF, "NC_64BIT_OFFSET", INT2FIX(NC_64BIT_OFFSET));
++ /* NC_64BIT_OFFSET supports large files in the class data format */
++ rb_define_const(cNetCDF, "NC_NETCDF4", INT2FIX(NC_NETCDF4));
++ rb_define_const(cNetCDF, "NC_CLASSIC_MODEL", INT2FIX(NC_CLASSIC_MODEL));
++ /* for use as ( NC_NETCDF4 | NC_CLASSIC_MODEL ) to ensure the classic
++ data model in NetCDF4 by disabling new features like groups */
++ rb_define_const(cNetCDF, "NC_ENDIAN_NATIVE", INT2FIX(NC_ENDIAN_NATIVE));
++ rb_define_const(cNetCDF, "NC_ENDIAN_LITTLE", INT2FIX(NC_ENDIAN_LITTLE));
++ rb_define_const(cNetCDF, "NC_ENDIAN_BIG", INT2FIX(NC_ENDIAN_BIG));
++#endif
++
++#ifdef NARRAY_BIGMEM
++ rb_define_const(cNetCDF, "SUPPORT_BIGMEM", Qtrue);
++#else
++ rb_define_const(cNetCDF, "SUPPORT_BIGMEM", Qfalse);
++#endif
++
++ /* Difinitions of the ruby methods */
++ /* The methods of the NetCDF class */
++ rb_define_singleton_method(cNetCDF,"libvers",NetCDF_inq_libvers,0);
++ rb_define_singleton_method(cNetCDF,"nc_open",NetCDF_open,2);
++ rb_define_method(cNetCDF,"clone",NetCDF_clone,0);
++ rb_define_method(cNetCDF,"close",NetCDF_close,0);
++ /* rb_define_singleton_method(cNetCDF,"new",NetCDF_open,2); */
++ rb_define_singleton_method(cNetCDF,"nc_create",NetCDF_create,2);
++ rb_define_method(cNetCDF,"def_dim",NetCDF_def_dim,2);
++ rb_define_method(cNetCDF,"def_var",NetCDF_def_var,3);
++ rb_define_method(cNetCDF,"put_attraw",NetCDF_put_att,3);
++ rb_define_method(cNetCDF,"redef",NetCDF_redef,0);
++ rb_define_method(cNetCDF,"enddef",NetCDF_enddef,0);
++ rb_define_method(cNetCDF,"define_mode?",NetCDF_whether_in_define_mode,0);
++ rb_define_method(cNetCDF,"fill",NetCDF_fill,1);
++ rb_define_method(cNetCDF,"ndims",NetCDF_ndims,0);
++ rb_define_method(cNetCDF,"nvars",NetCDF_nvars,0);
++ rb_define_method(cNetCDF,"natts",NetCDF_natts,0);
++ rb_define_method(cNetCDF,"sync",NetCDF_sync,0);
++ rb_define_method(cNetCDF,"path",NetCDF_path,0);
++ rb_define_method(cNetCDF,"dim",NetCDF_dim,1);
++ rb_define_method(cNetCDF,"var",NetCDF_var,1);
++ rb_define_method(cNetCDF,"att",NetCDF_att,1);
++ rb_define_method(cNetCDF,"unlimited",NetCDF_unlimited,0);
++ rb_define_private_method(cNetCDF,"id2var",NetCDF_id2var,1);
++ rb_define_private_method(cNetCDF,"id2dim",NetCDF_id2dim,1);
++ rb_define_private_method(cNetCDF,"id2att",NetCDF_id2att,1);
++ rb_define_method(cNetCDF,"==",NetCDF_eql,1);
++ /* rb_define_method(cNetCDF,"eql?",NetCDF_eql,1); */
++
++ /* The methods of the NetCDFDim class */
++ rb_define_method(cNetCDFDim,"clone",NetCDF_dim_clone,0);
++ rb_define_method(cNetCDFDim,"length",NetCDF_dim_length,0);
++ rb_define_method(cNetCDFDim,"name=",NetCDF_dim_name,1);
++ rb_define_method(cNetCDFDim,"name",NetCDF_dim_inqname,0);
++ rb_define_method(cNetCDFDim,"unlimited?",NetCDF_dim_whether_unlimited,0);
++ rb_define_method(cNetCDFDim,"==",NetCDF_dim_eql,1);
++ /* rb_define_method(cNetCDFDim,"eql?",NetCDF_dim_eql,1); */
++
++ /* The methods of the NetCDFAtt class */
++ rb_define_method(cNetCDFAtt,"clone",NetCDF_att_clone,0);
++ rb_define_method(cNetCDFAtt,"name",NetCDF_att_inq_name,0);
++ rb_define_method(cNetCDFAtt,"name=",NetCDF_att_rename,1);
++ rb_define_method(cNetCDFAtt,"delete",NetCDF_att_delete,0);
++ rb_define_method(cNetCDFAtt,"copy",NetCDF_att_copy,1);
++ rb_define_method(cNetCDFAtt,"atttype",NetCDF_att_atttype,0);
++ rb_define_method(cNetCDFAtt,"typecode",NetCDF_att_typecode,0);
++ rb_define_method(cNetCDFAtt,"==",NetCDF_att_eql,1);
++ /* rb_define_method(cNetCDFAtt,"eql?",NetCDF_att_eql,1); */
++ rb_define_method(cNetCDFAtt,"putraw",NetCDF_att_put,2);
++ rb_define_method(cNetCDFAtt,"get",NetCDF_att_get,0);
++
++ /* The methods of the NetCDFVar class */
++#if NCVER >= 400
++ rb_define_method(cNetCDFVar,"deflate",NetCDF_var_deflate,-1);
++ rb_define_method(cNetCDFVar,"deflate_params",NetCDF_var_deflate_params,0);
++ rb_define_method(cNetCDFVar,"endian=",NetCDF_var_set_endian,1);
++ rb_define_method(cNetCDFVar,"endian",NetCDF_var_endian,0);
++#endif
++ rb_define_method(cNetCDFVar,"clone",NetCDF_var_clone,0);
++ rb_define_method(cNetCDFVar,"name",NetCDF_var_inq_name,0);
++ rb_define_method(cNetCDFVar,"ndims",NetCDF_var_ndims,0);
++ rb_define_method(cNetCDFVar,"vartype",NetCDF_var_vartype,0);
++ rb_define_method(cNetCDFVar,"typecode",NetCDF_var_typecode,0);
++ rb_define_method(cNetCDFVar,"ntype",NetCDF_var_vartype,0);
++ rb_define_method(cNetCDFVar,"natts",NetCDF_var_natts,0);
++ rb_define_method(cNetCDFVar,"file",NetCDF_var_file,0);
++ rb_define_method(cNetCDFVar,"name=",NetCDF_var_rename,1);
++ rb_define_method(cNetCDFVar,"att",NetCDF_var_att,1);
++ rb_define_method(cNetCDFVar,"put_attraw",NetCDF_put_att_var,3);
++ rb_define_method(cNetCDFVar,"dims",NetCDF_var_dims,0);
++ rb_define_method(cNetCDFVar,"dim",NetCDF_var_dim,1);
++ /*rb_define_private_method(cNetCDFVar,"id2dim",NetCDF_var_id2dim,1); */
++ rb_define_private_method(cNetCDFVar,"id2att",NetCDF_var_id2att,1);
++ rb_define_method(cNetCDFVar,"==",NetCDF_var_eql,1);
++ /* rb_define_method(cNetCDFVar,"eql?",NetCDF_var_eql,1); */
++
++ /* The "get*" or "put*" methods in the NetCDFVar class */
++ rb_define_method(cNetCDFVar,"put_var_char",NetCDF_put_var_char,1);
++ rb_define_method(cNetCDFVar,"put_var_byte",NetCDF_put_var_byte,1);
++ rb_define_method(cNetCDFVar,"put_var_sint",NetCDF_put_var_short,1);
++ rb_define_method(cNetCDFVar,"put_var_int",NetCDF_put_var_int,1);
++ rb_define_method(cNetCDFVar,"put_var_sfloat",NetCDF_put_var_float,1);
++ rb_define_method(cNetCDFVar,"put_var_float",NetCDF_put_var_double,1);
++
++ rb_define_method(cNetCDFVar,"put_vars_char",NetCDF_put_vars_char,4);
++ rb_define_method(cNetCDFVar,"put_vars_byte",NetCDF_put_vars_byte,4);
++ rb_define_method(cNetCDFVar,"put_vars_sint",NetCDF_put_vars_sint,4);
++ rb_define_method(cNetCDFVar,"put_vars_int",NetCDF_put_vars_int,4);
++ rb_define_method(cNetCDFVar,"put_vars_sfloat",NetCDF_put_vars_float,4);
++ rb_define_method(cNetCDFVar,"put_vars_float",NetCDF_put_vars_double,4);
++
++ rb_define_method(cNetCDFVar,"put_var1_char",NetCDF_put_var1_char,2);
++ rb_define_method(cNetCDFVar,"put_var1_byte",NetCDF_put_var1_byte,2);
++ rb_define_method(cNetCDFVar,"put_var1_sint",NetCDF_put_var1_sint,2);
++ rb_define_method(cNetCDFVar,"put_var1_int",NetCDF_put_var1_int,2);
++ rb_define_method(cNetCDFVar,"put_var1_sfloat",NetCDF_put_var1_float,2);
++ rb_define_method(cNetCDFVar,"put_var1_float",NetCDF_put_var1_double,2);
++
++ rb_define_method(cNetCDFVar,"get_var_char",NetCDF_get_var_char,0);
++ rb_define_method(cNetCDFVar,"get_var_byte",NetCDF_get_var_byte,0);
++ rb_define_method(cNetCDFVar,"get_var_sint",NetCDF_get_var_sint,0);
++ rb_define_method(cNetCDFVar,"get_var_int",NetCDF_get_var_int,0);
++ rb_define_method(cNetCDFVar,"get_var_sfloat",NetCDF_get_var_float,0);
++ rb_define_method(cNetCDFVar,"get_var_float",NetCDF_get_var_double,0);
++
++ rb_define_method(cNetCDFVar,"get_vars_char",NetCDF_get_vars_char,3);
++ rb_define_method(cNetCDFVar,"get_vars_byte",NetCDF_get_vars_byte,3);
++ rb_define_method(cNetCDFVar,"get_vars_sint",NetCDF_get_vars_sint,3);
++ rb_define_method(cNetCDFVar,"get_vars_int",NetCDF_get_vars_int,3);
++ rb_define_method(cNetCDFVar,"get_vars_sfloat",NetCDF_get_vars_float,3);
++ rb_define_method(cNetCDFVar,"get_vars_float",NetCDF_get_vars_double,3);
++
++ rb_define_method(cNetCDFVar,"get_var1_char",NetCDF_get_var1_char,1);
++ rb_define_method(cNetCDFVar,"get_var1_byte",NetCDF_get_var1_byte,1);
++ rb_define_method(cNetCDFVar,"get_var1_sint",NetCDF_get_var1_sint,1);
++ rb_define_method(cNetCDFVar,"get_var1_int",NetCDF_get_var1_int,1);
++ rb_define_method(cNetCDFVar,"get_var1_sfloat",NetCDF_get_var1_float,1);
++ rb_define_method(cNetCDFVar,"get_var1_float",NetCDF_get_var1_double,1);
++}
+diff --git a/extconf.rb b/extconf.rb
+deleted file mode 100644
+index 1ad8b17..0000000
+--- a/extconf.rb
++++ /dev/null
+@@ -1,173 +0,0 @@
+-require "mkmf"
+-require "rubygems" unless defined?(Gem)
+-
+-ar = ARGV.grep( /^--with-netcdf-version=/ )
+-if ar.length > 0
+- ncversion = ar[0].sub(/^--with-netcdf-version=/,"")
+-else
+- ncversion = nil
+-end
+-
+-if Gem.respond_to?(:find_files)
+- require "rbconfig"
+- so = RbConfig::CONFIG["DLEXT"]
+- narray_include = File.expand_path(File.dirname(Gem.find_files("narray.h")[0]))
+- narray_lib = File.expand_path(File.dirname(Gem.find_files("narray." + so)[0]))
+-else
+- gem_home=(`gem environment GEM_HOME`).chomp
+- narray_dir = Dir.glob("#{gem_home}/gems/narray-*").sort[-1]
+- if narray_dir
+- narray_include = narray_lib = narray_dir
+- else
+- narray_include = narray_lib = [ $sitearchdir, $vendorarchdir]
+- end
+-end
+-dir_config('narray', narray_include, narray_lib)
+-
+-dir_config('netcdf', '/usr/local')
+-
+-if ( ! ( have_header("narray.h") && have_header("narray_config.h") ) ) then
+-print <<EOS
+-** configure error **
+- Header narray.h or narray_config.h is not found. If you have these files in
+- /narraydir/include, try the following:
+-
+- % ruby extconf.rb --with-narray-include=/narraydir/include
+-
+-EOS
+- exit(-1)
+-end
+-
+-unless ncversion
+- # configure netcdf version
+- if xsystem("nc-config --version")
+- ncversion = `nc-config --version`.chomp!.sub!(/^n.* /i,"") # rm "netCDF "
+- ncversion.sub!(/^([^\.]+\.[^\.]+\.[^\.]+).+$/,'\1') # e.g. 4.2.1.1 -> 4.2.1
+- else
+- ncversion = "3.0.0" # assume version 3 (only for compilation)
+- # For compilation, there is no difference among subversions of netcdf 3
+- end
+-end
+-
+-ncver0 = ncversion[0..0] # "3" or "4"
+-ncver = ncversion.gsub(/\./,'')
+-unless /^\d\d\d$/ =~ ncver # 3 digits
+- raise("Invalid netcdf version: #{ncversion}. Use --with-netcdf-version=")
+-end
+-$CFLAGS += ' -DNCVER='+ncver
+-
+-case ncver0
+-when "4"
+- if xsystem("nc-config --libs") # for NetCDF 4
+- cflags = `nc-config --cflags`.gsub(/\n/, " ")
+- libs = `nc-config --libs`.gsub(/\n/, " ")
+- prefix_nc = `nc-config --prefix`.gsub(/\n/, "")
+-
+- dir_config("netcdf",prefix_nc)
+- $CFLAGS += ' ' + cflags
+- $LOCAL_LIBS += ' ' + libs
+- end
+-when "3"
+- # for NetCDF 3, which needs external libraries for OpenDAP
+- if xsystem("ncdap-config --libs")
+- libncdods = "nc-dap"
+- cflags = `ncdap-config --cflags`.gsub(/\n/, " ")
+- libs = `ncdap-config --libs`.gsub(/\n/, " ")
+- prefix_dods = `ncdap-config --prefix`.gsub(/\n/, "")
+- elsif xsystem("opendap-config --libs")
+- libncdods = "nc-dods"
+- cflags = `opendap-config --cflags`.gsub(/\n/, " ")
+- libs = `opendap-config --libs-nc`.gsub(/\n/, " ")
+- prefix_dods = `opendap-config --prefix`.gsub(/\n/, "")
+- end
+- if (enable_config('opendap',true) && ( xsystem("opendap-config --libs") ||
+- xsystem("ncdap-config --libs") ) )
+-
+- dir_config(libncdods,prefix_dods)
+-
+- if (!have_library(libncdods))
+- print <<-EOS
+- ** ERROR ** Library not found: nc-dods (OPeNDAP/DODS-enabled NetCDF lib)
+- Install it, or run extconf.rb with option --disable-opendap.
+- ^^^^^^^^^^^^^^^^^
+- EOS
+- exit(-1)
+- else
+- print <<-EOS
+- ** Message ** Compiling with OPeNDAP/DODS-enabled NetCDF library.
+-
+- This is because the command opendap-config is found in your system.
+- If you want to use the ordinary (non-DODS) version of NetCDF,
+- run extconf.rb with option --disable-opendap.
+- ^^^^^^^^^^^^^^^^^
+- EOS
+- end
+-
+- $CFLAGS += ' '+cflags
+- $LOCAL_LIBS += ' ' + libs
+-
+- # non portable treatments: should be improved (by Horinouchi)
+- CONFIG['LDSHARED'].sub!(/gcc/,'g++')
+- $LIBS.sub!(/-lc\s/,'') ; $LIBS.sub!(/-lc$/,'')
+- print <<-EOS
+- ** Warning ** non-portable treatments are made,
+- which was sucessfull redhat linux 9:
+- * gcc was replaced with g++ in CONFIG['LDSHARED']
+- * -lc library was removed if in $LIBS
+-
+- EOS
+- # p '@@@'
+- # ary = []
+- # CONFIG.each{|k,v| ary.push([k,v])}
+- # ary.sort.each{|x| p x}
+- else
+- if ( ! ( have_header("netcdf.h") && have_library("netcdf") ) )then
+- print <<-EOS
+- ** configure error **
+- Header netcdf.h or the compiled netcdf library is not found.
+- If you have the library installed under /netcdfdir (that is, netcdf.h is
+- in /netcdfdir/include and the library in /netcdfdir/lib/),
+- try the following:
+-
+- % ruby extconf.rb --with-netcdf-dir=/netcdfdir
+-
+- Alternatively, you can specify the two directory separately
+- with --with-netcdf-include and --with-netcdf-lib.
+- EOS
+- exit(-1)
+- end
+- end
+-else
+- raise "Netcdf version #{ncver0} is not supported"
+-end
+-
+-
+-
+-if /cygwin|mingw/ =~ RUBY_PLATFORM
+- have_library("narray") || raise("ERROR: narray library is not found")
+-end
+-
+-create_makefile "numru/netcdfraw"
+-
+-###### Modify Makefile: #######
+-File.rename("Makefile","Makefile.orig")
+-oldmkfl = File.open("Makefile.orig")
+-newmkfl = File.open("Makefile","w")
+-oldmkfl.each_line{ |line|
+- case(line)
+- when /^distclean:/
+- newmkfl.puts(line)
+- newmkfl.puts("\t\t@$(RM) *.nc demo/*.nc demo/*~ lib/*~ doc/*~ test/*.nc test/*~ Makefile.orig")
+- when /^all:/
+- newmkfl.puts(line)
+- newmkfl.puts("")
+- newmkfl.puts("test: all") # insert the "test" target
+- newmkfl.puts("\t\t at cd test && ruby test.rb && echo 'test did not fail :-p (please ignore the warnings)' && cd ..")
+-# when /lib\/netcdf/
+-# line = line.chomp! + "/"
+-# newmkfl.puts(line)
+- else
+- newmkfl.puts(line)
+- end
+-}
+-newmkfl.close
+diff --git a/lib/netcdf.rb b/lib/netcdf.rb
+index 2c6a922..dee5bd7 100644
+--- a/lib/netcdf.rb
++++ b/lib/netcdf.rb
+@@ -1,808 +1 @@
+-require 'narray'
+-require 'numru/netcdfraw'
+-
+-if NArray.const_defined?(:SUPPORT_BIGMEM) && NArray::SUPPORT_BIGMEM
+- unless NumRu::NetCDF::SUPPORT_BIGMEM
+- raise "Ruby-NetCDF was compiled with NArray with big memory supoort " +
+- "(NArray-bigmem). However the NArray loaded is not NArray-bigmem."
+- end
+-else
+- if NumRu::NetCDF::SUPPORT_BIGMEM
+- raise "Ruby-NetCDF was compiled with NArray without big memory support. " +
+- "However the NArray loaded is with the support (NArray-bigmem)."
+- end
+-end
+-
+-module NumRu
+- class NetCDF
+-
+- Max_Try = 100
+-
+- NCVERSION = NetCDF.libvers
+-
+- if NCVERSION[0..0] >= "4"
+- @@nc4 = true
+- else
+- @@nc4 = false
+- end
+- def NetCDF.nc4?
+- @@nc4
+- end
+-
+- @@cr_format = 0
+-
+- def NetCDF.creation_format=(cmode)
+- raise("This method is available only for NetCDF >= 4") unless @@nc4
+- case cmode
+- when 0, nil, NC_CLASSIC_MODEL, /^CLASSIC$/i # classic netcdf ver 3 fmt
+- @@cr_format = 0
+- when NC_64BIT_OFFSET, /^64BIT_OFFSET$/i
+- @@cr_format = NC_64BIT_OFFSET
+- when NC_NETCDF4, /^NETCDF4$/i
+- @@cr_format = NC_NETCDF4
+- when ( NC_NETCDF4 | NC_CLASSIC_MODEL), /^NETCDF4_CLASSIC$/i
+- # NetCDF4 but disabling new data models
+- @@cr_format = NC_NETCDF4 | NC_CLASSIC_MODEL
+- else
+- raise ArgumentError, "Unsupported creation mode: #{cmod.to_s}"
+- end
+- end
+-
+- def NetCDF.creation_format
+- raise("This method is available only for NetCDF >= 4") unless @@nc4
+- case @@cr_format
+- when 0
+- "TRADITIONAL"
+- when NC_64BIT_OFFSET
+- "64BIT_OFFSET"
+- when NC_NETCDF4
+- "NETCDF4"
+- when NC_NETCDF4 | NC_CLASSIC_MODEL
+- "NETCDF4_CLASSIC"
+- end
+- end
+-
+- def NetCDF.open(filename,mode="r",share=false)
+- call_create=false # false-> nc_open; true->nc_create
+- case(mode)
+- when "r","rb" # read only
+- mode=NC_NOWRITE
+- when "w","w+","wb","w+b" # overwrite if exits
+- call_create=true
+- mode=NC_CLOBBER
+- when "a","a+","r+","ab","a+b","r+b" # append if exits
+- if( File.exists?(filename) )
+- mode=NC_WRITE
+- else
+- call_create=true #(nonexsitent --> create)
+- mode=NC_CLOBBER
+- end
+- else
+- raise NetcdfError, "Mode #{mode} is not supported"
+- end
+- case(share)
+- when false
+- share=0
+- when true
+- share=NC_SHARE
+- else
+- raise NetcdfError, "We can't use the sharing mode you typed"
+- end
+- omode = mode | share
+- if(!call_create)
+- nc_open(filename,omode)
+- else
+- nc_create(filename,omode)
+- end
+- end
+-
+- class << NetCDF
+- alias new open
+- end
+-
+-
+- def NetCDF.create(filename,noclobber=false,share=false)
+- case(noclobber)
+- when false
+- noclobber=NC_CLOBBER
+- when true
+- noclobber=NC_NOCLOBBER
+- else
+- raise NetcdfError,"noclobber (2nd argument) must be true or false"
+- end
+- case(share)
+- when false
+- share=0
+- when true
+- share=NC_SHARE
+- else
+- raise NetcdfError,"share (3rd argument) must be true or false"
+- end
+-
+- cmode=noclobber | share | @@cr_format
+- nc_create(filename,cmode)
+- end
+-
+- class << NetCDF
+- def clean_tmpfile(path)
+- proc {
+- print "removing ", path, "..." if $DEBUG
+- if File.exist?(path)
+- File.unlink(path)
+- end
+- print "done\n" if $DEBUG
+- }
+- end
+- protected :clean_tmpfile
+- end
+-
+- def NetCDF.create_tmp(tmpdir=ENV['TMPDIR']||ENV['TMP']||ENV['TEMP']||'.',
+- share=false)
+- basename = 'temp'
+- if $SAFE > 0 and tmpdir.tainted?
+- tmpdir = '.'
+- end
+-
+- n = 0
+- while true
+- begin
+- tmpname = sprintf('%s/%s%d_%d.nc', tmpdir, basename, $$, n)
+- unless File.exist?(tmpname)
+- netcdf = NetCDF.create(tmpname, true, share)
+- ObjectSpace.define_finalizer(netcdf,
+- NetCDF.clean_tmpfile(tmpname))
+- break
+- end
+- rescue
+- raise NetcdfError, "cannot generate tempfile `%s'" % tmpname if n >= Max_Try
+- end
+- n += 1
+- end
+- netcdf
+- end
+-
+-
+- def put_att(attname,val,atttype=nil)
+- put_attraw(attname,val,atttype)
+- end
+-
+- def def_var_with_dim(name, vartype, shape_ul0, dimnames)
+- # Same as def_var but defines dimensions first if needed.
+- # Use zero in shape to define an unlimited dimension.
+- if (shape_ul0.length != dimnames.length ) then
+- raise ArgumentError, 'lengths of shape and dimnames do not agree'
+- end
+- dims = []
+- dimnames.each_index{ |i|
+- dim = self.dim( dimnames[i] )
+- if ( dim != nil ) then
+- # dim exists --> check the length
+- if (shape_ul0[i] != dim.length_ul0 ) then
+- raise ArgumentError, "dimension length do not agree: #{i}th dim: "+\
+- "#{shape_ul0[i]} and #{dim.length_ul0}"
+- end
+- dims.push(dim)
+- else
+- # dim does not exist --> define it
+- dims.push( def_dim( dimnames[i], shape_ul0[i] ) )
+- end
+- }
+- def_var(name, vartype, dims)
+- end
+-
+- # Iterators:
+- def each_dim
+- num_dim=ndims()
+- for dimid in 0..num_dim-1
+- obj_Dim=id2dim(dimid)
+- yield(obj_Dim)
+- end
+- end
+-
+- def each_var
+- num_var=nvars()
+- for varid in 0..num_var-1
+- obj_Var=id2var(varid)
+- yield(obj_Var)
+- end
+- end
+-
+- def each_att
+- num_att=natts()
+- for attnum in 0..num_att-1
+- obj_Att=id2att(attnum)
+- yield(obj_Att)
+- end
+- end
+-
+- def dims( names=nil ) # return all if names==nil
+- if names == nil
+- dims = (0..ndims()-1).collect{|dimid| id2dim(dimid)}
+- else
+- raise TypeError, "names is not an array" if ! names.is_a?(Array)
+- dims = names.collect{|name| dim(name)}
+- raise ArgumentError, "One or more dimensions do not exist" if dims.include?(nil)
+- end
+- dims
+- end
+-
+- def vars( names=nil ) # return all if names==nil
+- if names == nil
+- vars = (0..nvars()-1).collect{ |varid| id2var(varid) }
+- else
+- raise TypeError, "names is not an array" if ! names.is_a?(Array)
+- vars = names.collect{|name| var(name)}
+- raise ArgumentError, "One or more variables do not exist" if vars.include?(nil)
+- end
+- vars
+- end
+-
+- def dim_names
+- num_dim=ndims()
+- names=[]
+- for dimid in 0..num_dim-1
+- obj_Dim=id2dim(dimid)
+- names=names+[obj_Dim.name]
+- end
+- return names
+- end
+-
+- def var_names
+- num_var=nvars()
+- names=[]
+- for varid in 0..num_var-1
+- obj_Var=id2var(varid)
+- names=names+[obj_Var.name]
+- end
+- return names
+- end
+-
+- def att_names
+- num_att=natts()
+- names=[]
+- for attnum in 0..num_att-1
+- obj_Att=id2att(attnum)
+- names=names+[obj_Att.name]
+- end
+- return names
+- end
+-
+- def inspect
+- "NetCDF:"+path
+- end
+-
+- end
+-
+- class NetCDFVar
+-
+- class << NetCDFVar
+- def new(file,varname,mode="r",share=false)
+- if(file.is_a?(String))
+- file = NetCDF.open(file,mode,share)
+- elsif(!file.is_a?(NetCDF))
+- raise TypeError, "1st arg must be a NetCDF (file object) or a String (path)"
+- end
+- file.var(varname)
+- end
+-
+- alias open new
+- end
+-
+- alias :rank :ndims
+-
+- def each_att
+- num_att=natts()
+- for attnum in 0..num_att-1
+- obj_Att=id2att(attnum)
+- yield(obj_Att)
+- end
+- end
+-
+- def dim_names
+- ary = Array.new()
+- dims.each{|dim| ary.push(dim.name)}
+- ary
+- end
+-
+- def att_names
+- num_att=natts()
+- names=[]
+- for attnum in 0..num_att-1
+- obj_Att=id2att(attnum)
+- names=names+[obj_Att.name]
+- end
+- return names
+- end
+-
+- def put_att(attname,val,atttype=nil)
+- put_attraw(attname,val,atttype)
+- end
+-
+- def shape_ul0
+- sh = []
+- dims.each{|d|
+- if d.unlimited? then
+- sh.push(0)
+- else
+- sh.push(d.length)
+- end
+- }
+- sh
+- end
+-
+- def shape_current
+- sh = []
+- dims.each{|d|
+- sh.push(d.length)
+- }
+- sh
+- end
+-
+- # The put and get methods in the NetCDFVar class
+-
+- def pack(na)
+- sf = att('scale_factor')
+- ao = att('add_offset')
+- if ( sf == nil && ao == nil ) then
+- na
+- else
+- na = NArray.to_na(na) if na.is_a?(Array)
+- if sf
+- csf = sf.get
+- raise NetcdfError,"scale_factor is not a numeric" if csf.is_a?(String)
+- raise NetcdfError, "scale_factor is not unique" if csf.length != 1
+- raise NetcdfError, "zero scale_factor" if csf[0] == 0
+- else
+- csf = nil
+- end
+- if ao
+- cao = ao.get
+- raise NetcdfError, "add_offset is not a numeric" if cao.is_a?(String)
+- raise NetcdfError, "add_offset is not unique" if cao.length != 1
+- else
+- cao = nil
+- end
+- if csf and cao
+- packed = (na - cao) / csf
+- elsif csf
+- packed = na / csf
+- elsif cao
+- packed = na - cao
+- end
+- if self.typecode <= NArray::LINT
+- packed = packed.round
+- end
+- packed
+- end
+- end
+-
+- def scaled_put(var,hash=nil)
+- simple_put( pack(var), hash)
+- end
+-
+- @@unpack_type = nil
+- class << NetCDFVar
+- def unpack_type
+- @@unpack_type
+- end
+- def unpack_type=(na_type)
+- if [NArray::BYTE, NArray::SINT, NArray::INT,
+- NArray::SFLOAT, NArray::FLOAT, nil].include?(na_type)
+- @@unpack_type = na_type
+- else
+- raise ArgumentError, "Arg must be one of NArray::BYTE, NArray::SINT, NArray::INT, NArray::SFLOAT, NArray::FLOAT"
+- end
+- end
+-
+- end
+-
+- def unpack(na)
+- sf = att('scale_factor')
+- ao = att('add_offset')
+- if ( sf == nil && ao == nil ) then
+- na
+- else
+- if sf
+- csf = sf.get
+- raise NetcdfError,"scale_factor is not a numeric" if csf.is_a?(String)
+- raise NetcdfError, "scale_factor is not unique" if csf.length != 1
+- raise NetcdfError, "zero scale_factor" if csf[0] == 0
+- else
+- csf =nil
+- end
+- if ao
+- cao = ao.get
+- raise NetcdfError, "add_offset is not a numeric" if cao.is_a?(String)
+- raise NetcdfError, "add_offset is not unique" if cao.length != 1
+- else
+- cao = nil
+- end
+- if csf and cao
+- una = na * csf + cao # csf & cao are NArray -> coerced to their types
+- elsif csf
+- una = na * csf
+- elsif cao
+- una = na + cao
+- end
+- una = una.to_type(@@unpack_type) if @@unpack_type
+- una
+- end
+- end
+-
+- def scaled_get(hash=nil)
+- unpack( simple_get(hash) )
+- end
+-
+- def simple_put(var,hash=nil)
+- if hash==nil
+- if self.vartype == "char"
+- put_var_char(var)
+- elsif self.vartype == "byte"
+- put_var_byte(var)
+- elsif self.vartype == "sint"
+- put_var_sint(var)
+- elsif self.vartype == "int"
+- put_var_int(var)
+- elsif self.vartype == "sfloat"
+- put_var_sfloat(var)
+- elsif self.vartype == "float"
+- put_var_float(var)
+- else
+- raise NetcdfError,"variable type isn't supported in netCDF"
+- end
+- elsif hash.key?("index")==true
+- if self.vartype == "char"
+- put_var1_char(var,hash["index"])
+- elsif self.vartype=="byte"
+- put_var1_byte(var,hash["index"])
+- elsif self.vartype=="sint"
+- put_var1_sint(var,hash["index"])
+- elsif self.vartype == "int"
+- put_var1_int(var,hash["index"])
+- elsif self.vartype == "sfloat"
+- put_var1_sfloat(var,hash["index"])
+- elsif self.vartype == "float"
+- put_var1_float(var,hash["index"])
+- else
+- raise NetcdfError,"variable type isn't supported in netCDF"
+- end
+- elsif hash.key?("start")==true
+- if hash.key?("end")==false && hash.key?("stride")==false
+- if self.vartype == "char"
+- put_vars_char(var,hash["start"],nil,nil)
+- elsif self.vartype=="byte"
+- put_vars_byte(var,hash["start"],nil,nil)
+- elsif self.vartype=="sint"
+- put_vars_sint(var,hash["start"],nil,nil)
+- elsif self.vartype=="int"
+- put_vars_int(var,hash["start"],nil,nil)
+- elsif self.vartype=="sfloat"
+- put_vars_sfloat(var,hash["start"],nil,nil)
+- elsif self.vartype=="float"
+- put_vars_float(var,hash["start"],nil,nil)
+- else
+- raise NetcdfError, "variable type isn't supported in netCDF"
+- end
+- elsif hash.key?("end")==true && hash.key?("stride") == false
+- if self.vartype == "char"
+- put_vars_char(var,hash["start"],hash["end"],nil)
+- elsif self.vartype=="byte"
+- put_vars_byte(var,hash["start"],hash["end"],nil)
+- elsif self.vartype=="sint"
+- put_vars_sint(var,hash["start"],hash["end"],nil)
+- elsif self.vartype=="int"
+- put_vars_int(var,hash["start"],hash["end"],nil)
+- elsif self.vartype == "sfloat"
+- put_vars_sfloat(var,hash["start"],hash["end"],nil)
+- elsif self.vartype =="float"
+- put_vars_float(var,hash["start"],hash["end"],nil)
+- else
+- raise NetcdfError, "variable type isn't supported in netCDF"
+- end
+- elsif hash.key?("end")==false && hash.key?("stride")==true
+- if self.vartype == "char"
+- put_vars_char(var,hash["start"],nil,hash["stride"])
+- elsif self.vartype=="byte"
+- put_vars_byte(var,hash["start"],nil,hash["stride"])
+- elsif self.vartype=="sint"
+- put_vars_sint(var,hash["start"],nil,hash["stride"])
+- elsif self.vartype=="int"
+- put_vars_int(var,hash["start"],nil,hash["stride"])
+- elsif self.vartype=="sfloat"
+- put_vars_sfloat(var,hash["start"],nil,hash["stride"])
+- elsif self.vartype=="float"
+- put_vars_float(var,hash["start"],nil,hash["stride"])
+- else
+- raise NetcdfError, "variable type isn't supported in netCDF"
+- end
+- else hash.key?("end")==true && hash.key?("stride")==true
+- if self.vartype == "char"
+- put_vars_char(var,hash["start"],hash["end"],hash["stride"])
+- elsif self.vartype=="byte"
+- put_vars_byte(var,hash["start"],hash["end"],hash["stride"])
+- elsif self.vartype=="sint"
+- put_vars_sint(var,hash["start"],hash["end"],hash["stride"])
+- elsif self.vartype=="int"
+- put_vars_int(var,hash["start"],hash["end"],hash["stride"])
+- elsif self.vartype=="sfloat"
+- put_vars_sfloat(var,hash["start"],hash["end"],hash["stride"])
+- elsif self.vartype=="float"
+- put_vars_float(var,hash["start"],hash["end"],hash["stride"])
+- else
+- raise NetcdfError, "variable type isn't supported in netCDF"
+- end
+- end
+- else
+- raise ArgumentError,"{'start'}=>[ARRAY] or {'index'}=>[ARRAY] is needed"
+- end
+- end
+-
+- alias put simple_put
+-
+- def simple_get(hash=nil)
+- t_var = self.vartype
+- if hash == nil
+- if t_var == "char"
+- get_var_char
+- elsif t_var == "byte"
+- get_var_byte
+- elsif t_var == "sint"
+- get_var_sint
+- elsif t_var == "int"
+- get_var_int
+- elsif t_var == "sfloat"
+- get_var_sfloat
+- elsif t_var == "float"
+- get_var_float
+- else
+- raise NetcdfError, "variable type #{t_var} isn't supported in netCDF"
+- end
+- elsif hash.key?("index")==true
+- ind = hash["index"]
+- if t_var == "char"
+- get_var1_char(ind)
+- elsif t_var == "byte"
+- get_var1_byte(ind)
+- elsif t_var == "sint"
+- get_var1_sint(ind)
+- elsif t_var == "int"
+- get_var1_int(ind)
+- elsif t_var == "sfloat"
+- get_var1_sfloat(ind)
+- elsif t_var == "float"
+- get_var1_float(ind)
+- else
+- raise NetcdfError,"variable type #{t_var} isn't supported in netCDF"
+- end
+- elsif hash.key?("start")==true
+- h_sta = hash["start"]
+- h_end = hash["end"] # can be nill
+- h_str = hash["stride"] # can be nill
+- if NetCDF.nc4? && h_str && ((xstr=h_str[0]) != 1)
+- # Tentative treatment for the very slow netcdf-4 reading with step.
+- # Reading with step is generally slow with NetCDF 4, but it is
+- # particularly so for the first dimension.
+- # Ref: http://www.unidata.ucar.edu/mailing_lists/archives/netcdfgroup/2013/msg00311.html
+- h_str[0] = 1
+- nc4remedy = true
+- else
+- nc4remedy = false
+- end
+- if t_var == "char"
+- v = get_vars_char(h_sta,h_end,h_str)
+- elsif t_var == "byte"
+- v = get_vars_byte(h_sta,h_end,h_str)
+- elsif t_var == "sint"
+- v = get_vars_sint(h_sta,h_end,h_str)
+- elsif t_var == "int"
+- v = get_vars_int(h_sta,h_end,h_str)
+- elsif t_var == "sfloat"
+- v = get_vars_sfloat(h_sta,h_end,h_str)
+- elsif t_var == "float"
+- v = get_vars_float(h_sta,h_end,h_str)
+- else
+- raise NetcdfError, "variable type #{t_var} isn't supported in netCDF"
+- end
+- if nc4remedy
+- idx = []
+- (0...v.shape[0]).step(xstr){|k| idx.push(k)}
+- v = v[idx,false]
+- end
+- v
+- else
+- raise ArgumentError,"{'start'}=>{ARRAY} or {'index'}=>{ARRAY} is needed"
+- end
+- end
+-
+- alias get simple_get
+-
+- def __rubber_expansion( args )
+- if (id = args.index(false)) # substitution into id
+- # false is incuded
+- alen = args.length
+- if args.rindex(false) != id
+- raise ArguemntError,"only one rubber dimension is permitted"
+- elsif alen > rank+1
+- raise ArgumentError, "too many args"
+- end
+- ar = ( id!=0 ? args[0..id-1] : [] )
+- args = ar + [true]*(rank-alen+1) + args[id+1..-1]
+- elsif args.length == 0 # to support empty [], []=
+- args = [true]*rank
+- end
+- args
+- end
+- private :__rubber_expansion
+-
+- def [](*a)
+- if a.length == 0
+- return self.get
+- end
+- a = __rubber_expansion(a)
+- first = Array.new
+- last = Array.new
+- stride = Array.new
+- set_stride = false
+- a.each{|i|
+- if(i.is_a?(Fixnum))
+- first.push(i)
+- last.push(i)
+- stride.push(1)
+- elsif(i.is_a?(Range))
+- first.push(i.first)
+- last.push(i.exclude_end? ? i.last-1 : i.last)
+- stride.push(1)
+- elsif(i.is_a?(Hash))
+- r = (i.to_a[0])[0]
+- s = (i.to_a[0])[1]
+- if ( !( r.is_a?(Range) ) || ! ( s.is_a?(Integer) ) )
+- raise TypeError, "Hash argument must be {a_Range, step}"
+- end
+- first.push(r.first)
+- last.push(r.exclude_end? ? r.last-1 : r.last)
+- stride.push(s)
+- set_stride = true
+- elsif(i.is_a?(TrueClass))
+- first.push(0)
+- last.push(-1)
+- stride.push(1)
+- elsif( i.is_a?(Array) || i.is_a?(NArray))
+- a_new = a.dup
+- at = a.index(i)
+- i = NArray.to_na(i) if i.is_a?(Array)
+- for n in 0..i.length-1
+- a_new[at] = i[n]..i[n]
+- na_tmp = self[*a_new]
+- if n==0 then
+- k = at
+- if at > 0
+- a[0..at-1].each{|x| if x.is_a?(Fixnum) then k -= 1 end}
+- end
+- shape_tmp = na_tmp.shape
+- shape_tmp[k] = i.length
+- na = na_tmp.class.new(na_tmp.typecode,*shape_tmp)
+- index_tmp = Array.new(shape_tmp.length,true)
+- end
+- index_tmp[k] = n..n
+- na[*index_tmp] = na_tmp
+- end
+- return na
+- else
+- raise TypeError, "argument must be Fixnum, Range, Hash, TrueClass, Array, or NArray"
+- end
+- }
+-
+- if(set_stride)
+- na = self.get({"start"=>first, "end"=>last, "stride"=>stride})
+- else
+- na = self.get({"start"=>first, "end"=>last})
+- end
+- shape = na.shape
+- (a.length-1).downto(0){ |i|
+- shape.delete_at(i) if a[i].is_a?(Fixnum)
+- }
+- na.reshape!( *shape )
+- na
+- end
+-
+- def []=(*a)
+- val = a.pop
+- a = __rubber_expansion(a)
+- first = Array.new
+- last = Array.new
+- stride = Array.new
+- set_stride = false
+- a.each{|i|
+- if(i.is_a?(Fixnum))
+- first.push(i)
+- last.push(i)
+- stride.push(1)
+- elsif(i.is_a?(Range))
+- first.push(i.first)
+- last.push(i.exclude_end? ? i.last-1 : i.last)
+- stride.push(1)
+- elsif(i.is_a?(Hash))
+- r = (i.to_a[0])[0]
+- s = (i.to_a[0])[1]
+- if ( !( r.is_a?(Range) ) || ! ( s.is_a?(Integer) ) )
+- raise ArgumentError, "Hash argument must be {first..last, step}"
+- end
+- first.push(r.first)
+- last.push(r.exclude_end? ? r.last-1 : r.last)
+- stride.push(s)
+- set_stride = true
+- elsif(i.is_a?(TrueClass))
+- first.push(0)
+- last.push(-1)
+- stride.push(1)
+- elsif(i.is_a?(Array) || i.is_a?(NArray))
+- a_new = a.dup
+- at = a.index(i)
+- i = NArray.to_na(i) if i.is_a?(Array)
+- val = NArray.to_na(val) if val.is_a?(Array)
+- rank_of_subset = a.dup.delete_if{|v| v.is_a?(Fixnum)}.length
+- if val.rank != rank_of_subset
+- raise "rank of the rhs (#{val.rank}) is not equal to the rank "+
+- "of the subset specified by #{a.inspect} (#{rank_of_subset})"
+- end
+- k = at
+- a[0..at-1].each{|x| if x.is_a?(Fixnum) then k -= 1 end}
+- if i.length != val.shape[k]
+- raise "length of the #{k+1}-th dim of rhs is incorrect "+
+- "(#{i.length} for #{val.shape[k]})"
+- end
+- index_tmp = Array.new(val.rank,true) if !val.is_a?(Numeric) #==>Array-like
+- for n in 0..i.length-1
+- a_new[at] = i[n]..i[n]
+- if !val.is_a?(Numeric) then
+- index_tmp[k] = n..n
+- self[*a_new] = val[*index_tmp]
+- else
+- self[*a_new] = val
+- end
+- end
+- return self
+- else
+- raise TypeError, "argument must be Fixnum, Range, Hash, TrueClass, Array, or NArray"
+- end
+- }
+-
+- if(set_stride)
+- self.put(val, {"start"=>first, "end"=>last, "stride"=>stride})
+- else
+- self.put(val, {"start"=>first, "end"=>last})
+- end
+- end
+-
+- def inspect
+- 'NetCDFVar:'+file.path+'?var='+name
+- end
+-
+- end
+-
+- class NetCDFAtt
+-
+- def put(val,atttype=nil)
+- putraw(val,atttype)
+- end
+-
+- def inspect
+- 'NetCDFAtt:'+name
+- end
+- end
+-
+- class NetCDFDim
+- def inspect
+- 'NetCDFDim:'+name
+- end
+-
+- def length_ul0
+- if unlimited?
+- 0
+- else
+- length
+- end
+- end
+-
+- end
+-end
++require 'numru/netcdf'
+diff --git a/lib/netcdf_miss.rb b/lib/netcdf_miss.rb
+deleted file mode 100644
+index 4b168f0..0000000
+--- a/lib/netcdf_miss.rb
++++ /dev/null
+@@ -1,203 +0,0 @@
+-require "numru/netcdf"
+-require "narray_miss"
+-
+-module NumRu
+-
+- class NetCDFVar
+-
+- def get_with_miss(*args)
+- __interpret_missing_params if !defined?(@missval)
+- data = simple_get(*args)
+- if @vmin || @vmax
+- if @vmin
+- mask = (data >= @vmin)
+- mask = mask.and(data <= @vmax) if @vmax
+- else
+- mask = (data <= @vmax)
+- end
+- data = NArrayMiss.to_nam(data, mask)
+- elsif @missval # only missing_value is present.
+- mask = (data.ne(@missval))
+- data = NArrayMiss.to_nam(data, mask)
+- end
+- data
+- end
+-
+- def get_with_miss_and_scaling(*args)
+- __interpret_missing_params if !defined?(@missval)
+- data = simple_get(*args)
+- if @vmin || @vmax
+- if @vmin
+- mask = (data >= @vmin)
+- mask = mask.and(data <= @vmax) if @vmax
+- else
+- mask = (data <= @vmax)
+- end
+- data = NArrayMiss.to_nam(data, mask)
+- elsif @missval # only missing_value is present.
+- mask = (data.ne(@missval))
+- data = NArrayMiss.to_nam(data, mask)
+- end
+- data = unpack( data )
+- data
+- end
+-
+- def put_with_miss(data, *args)
+- if data.is_a?( NArrayMiss )
+- __interpret_missing_params if !defined?(@missval)
+- if @missval
+- simple_put(data.to_na(@missval), *args)
+- else
+- simple_put(data.to_na, *args)
+- end
+- else
+- simple_put(data, *args)
+- end
+- end
+-
+- def put_with_miss_and_scaling(data, *args)
+- if data.is_a?( NArrayMiss )
+- __interpret_missing_params if !defined?(@missval)
+- if @missval
+- data = pack( data )
+- data = data.to_na(@missval)
+- else
+- data = pack( data )
+- data = data.to_na
+- end
+- simple_put(data, *args)
+- else
+- scaled_put(data, *args)
+- end
+- end
+-
+- ######### private ##########
+-
+- def __interpret_missing_params
+- # Interprets the specification of missing data,
+- # either by valid_range, (valid_min and/or valid_max), or missing_value.
+- # (unlike the NetCDF User's guide (NUG), missing_value is interpreted,
+- # but valid_* has a higher precedence.)
+- # Always sets @missval whether missing_value is defined or not,
+- # since it will be used as a fill value for data missing.
+- #
+- @vmin = att('valid_min')
+- @vmin = @vmin.get if @vmin # kept in a NArray(size==1) to consv type
+- @vmax = att('valid_max')
+- @vmax = @vmax.get if @vmax # kept in a NArray(size==1) to consv type
+- vrange = att('valid_range')
+- vrange = vrange.get if vrange
+- if vrange
+- vrange.sort!
+- @vmin = vrange[0..0] # kept in... (same)
+- @vmax = vrange[-1..-1] # kept in... (same)
+- end
+- @missval = att('missing_value') || att('_FillValue')
+- @missval = @missval.get if @missval # kept in... (same)
+-
+- sf = att('scale_factor')
+- ao = att('add_offset')
+- if ( sf || ao )
+- ## Both NUG & CF conventions requires to specify the valid
+- ## range with respect to the external (i.e. packed) values.
+- ## However, some conventions require specification
+- ## with respect to unpacked values. The following
+- ## is to support such cases as well:
+- thres_tp = [ self.typecode, NArray::LINT ].max
+- @missval = pack(@missval) if @missval && @missval.typecode > thres_tp
+- @vmin = pack(@vmin) if @vmin && @vmin.typecode > thres_tp
+- @vmax = pack(@vmax) if @vmax && @vmax.typecode > thres_tp
+- end
+-
+- if @missval
+- if @vmin && @vmax
+- if @vmin[0] <= @missval[0] && @missval[0] <= @vmax[0]
+- warn "WARNING: missing_value #{@missval[0]} is in the valid range #{@vmin[0]}..#{@vmax[0]} --> will be ignored (#{__FILE__}:#{__LINE__})"
+- end
+- else
+- if @vmin && @missval[0] >= @vmin[0]
+- warn "WARNING: missing_value #{@missval[0]} >= valid min #{@vmin[0]} --> will be ignored (#{__FILE__}:#{__LINE__})"
+- elsif @vmax && @missval[0] <= @vmax[0]
+- warn "WARNING: missing_value #{@missval[0]} <= valid min #{@vmin[0]} --> will be ignored (#{__FILE__}:#{__LINE__})"
+- end
+- end
+- else
+- realtc = NArray::SFLOAT
+- if @vmin
+- if @vmin[0] >= 0
+- @missval = ( @vmin.typecode>=realtc ? 0.99*@vmin : @vmin-1 )
+- else
+- @missval = ( @vmin.typecode>=realtc ? 1.01*@vmin : @vmin-1 )
+- end
+- elsif @vmax
+- if @vmax[0] >= 0
+- @missval = ( @vmax.typecode>=realtc ? 1.01*@vmax : @vmax+1 )
+- else
+- @missval = ( @vmax.typecode>=realtc ? 0.99*@vmax : @vmax+1 )
+- end
+- end
+- end
+-
+- end
+-
+- private :__interpret_missing_params
+-
+- end
+-
+-end
+-
+-if $0 == __FILE__
+- include NumRu
+-
+- filename = "tmp.nc"
+- print "creating ",filename,"...\n"
+- file=NetCDF.create(filename)
+- nx = 10
+- dimx = file.def_dim("x",nx)
+- xf = file.def_var("xf","sfloat",[dimx])
+- xfn = file.def_var("xfn","sfloat",[dimx])
+- xf.put_att("valid_range",[-1e12,1e12])
+- f = 10 ** (2*NArray.sfloat(nx).indgen!)
+- xr = file.def_var("xr","sint",[dimx])
+- xr.put_att("valid_max",[0.5])
+- xr.put_att("scale_factor",1e-4)
+- xr.put_att("add_offset",0.5)
+- xr2 = file.def_var("xr2","sint",[dimx])
+- xr2.put_att("valid_max",NArray.sint(1).fill!(1000))
+- xr2.put_att("scale_factor",1e-4)
+- xr2.put_att("add_offset",0.5)
+- r = NArray.sfloat(nx).indgen!/nx
+- file.enddef
+- xf.put(f)
+- xfn.put(f)
+- xr.scaled_put(r)
+- file.close
+-
+- file = NetCDF.open(filename,'r+')
+- xf = file.var('xf')
+- xfn = file.var('xfn')
+- p "f0"
+- xf.get.each{|v| print "#{v} "} ; print "\n"
+- p( 'f1', nam = xf.get_with_miss )
+- def xf.get(*args); get_with_miss(*args); end
+- p( 'f12', xf[2..-3].to_na )
+- p( 'fn10', xfn.get_with_miss )
+- p( 'fn11', xfn.get_with_miss_and_scaling )
+- nam.invalidation([0,1])
+- p 'f2', nam
+- xf.put_with_miss(nam)
+- p( 'f3', xf.get_with_miss )
+- xr = file.var('xr')
+- p "r0"
+- xr.simple_get.each{|v| print "#{v} "} ; print "\n"
+- p( 'r1', xr.get_with_miss_and_scaling )
+- def xr.get(*args); get_with_miss_and_scaling(*args); end
+- def xr.put(*args); put_with_miss_and_scaling(*args); end
+- #xr[0..3] = xr[0..3]*10
+- p( 'r2', xr.get_with_miss_and_scaling )
+- p 'r',r
+- xr2.put_with_miss_and_scaling(r)
+- p 'xr2',xr2.get_with_miss_and_scaling
+- file.close
+- print "** ncdump tmp.nc **\n", `ncdump tmp.nc`
+-end
+diff --git a/lib/numru/netcdf.rb b/lib/numru/netcdf.rb
+new file mode 100644
+index 0000000..2c6a922
+--- /dev/null
++++ b/lib/numru/netcdf.rb
+@@ -0,0 +1,808 @@
++require 'narray'
++require 'numru/netcdfraw'
++
++if NArray.const_defined?(:SUPPORT_BIGMEM) && NArray::SUPPORT_BIGMEM
++ unless NumRu::NetCDF::SUPPORT_BIGMEM
++ raise "Ruby-NetCDF was compiled with NArray with big memory supoort " +
++ "(NArray-bigmem). However the NArray loaded is not NArray-bigmem."
++ end
++else
++ if NumRu::NetCDF::SUPPORT_BIGMEM
++ raise "Ruby-NetCDF was compiled with NArray without big memory support. " +
++ "However the NArray loaded is with the support (NArray-bigmem)."
++ end
++end
++
++module NumRu
++ class NetCDF
++
++ Max_Try = 100
++
++ NCVERSION = NetCDF.libvers
++
++ if NCVERSION[0..0] >= "4"
++ @@nc4 = true
++ else
++ @@nc4 = false
++ end
++ def NetCDF.nc4?
++ @@nc4
++ end
++
++ @@cr_format = 0
++
++ def NetCDF.creation_format=(cmode)
++ raise("This method is available only for NetCDF >= 4") unless @@nc4
++ case cmode
++ when 0, nil, NC_CLASSIC_MODEL, /^CLASSIC$/i # classic netcdf ver 3 fmt
++ @@cr_format = 0
++ when NC_64BIT_OFFSET, /^64BIT_OFFSET$/i
++ @@cr_format = NC_64BIT_OFFSET
++ when NC_NETCDF4, /^NETCDF4$/i
++ @@cr_format = NC_NETCDF4
++ when ( NC_NETCDF4 | NC_CLASSIC_MODEL), /^NETCDF4_CLASSIC$/i
++ # NetCDF4 but disabling new data models
++ @@cr_format = NC_NETCDF4 | NC_CLASSIC_MODEL
++ else
++ raise ArgumentError, "Unsupported creation mode: #{cmod.to_s}"
++ end
++ end
++
++ def NetCDF.creation_format
++ raise("This method is available only for NetCDF >= 4") unless @@nc4
++ case @@cr_format
++ when 0
++ "TRADITIONAL"
++ when NC_64BIT_OFFSET
++ "64BIT_OFFSET"
++ when NC_NETCDF4
++ "NETCDF4"
++ when NC_NETCDF4 | NC_CLASSIC_MODEL
++ "NETCDF4_CLASSIC"
++ end
++ end
++
++ def NetCDF.open(filename,mode="r",share=false)
++ call_create=false # false-> nc_open; true->nc_create
++ case(mode)
++ when "r","rb" # read only
++ mode=NC_NOWRITE
++ when "w","w+","wb","w+b" # overwrite if exits
++ call_create=true
++ mode=NC_CLOBBER
++ when "a","a+","r+","ab","a+b","r+b" # append if exits
++ if( File.exists?(filename) )
++ mode=NC_WRITE
++ else
++ call_create=true #(nonexsitent --> create)
++ mode=NC_CLOBBER
++ end
++ else
++ raise NetcdfError, "Mode #{mode} is not supported"
++ end
++ case(share)
++ when false
++ share=0
++ when true
++ share=NC_SHARE
++ else
++ raise NetcdfError, "We can't use the sharing mode you typed"
++ end
++ omode = mode | share
++ if(!call_create)
++ nc_open(filename,omode)
++ else
++ nc_create(filename,omode)
++ end
++ end
++
++ class << NetCDF
++ alias new open
++ end
++
++
++ def NetCDF.create(filename,noclobber=false,share=false)
++ case(noclobber)
++ when false
++ noclobber=NC_CLOBBER
++ when true
++ noclobber=NC_NOCLOBBER
++ else
++ raise NetcdfError,"noclobber (2nd argument) must be true or false"
++ end
++ case(share)
++ when false
++ share=0
++ when true
++ share=NC_SHARE
++ else
++ raise NetcdfError,"share (3rd argument) must be true or false"
++ end
++
++ cmode=noclobber | share | @@cr_format
++ nc_create(filename,cmode)
++ end
++
++ class << NetCDF
++ def clean_tmpfile(path)
++ proc {
++ print "removing ", path, "..." if $DEBUG
++ if File.exist?(path)
++ File.unlink(path)
++ end
++ print "done\n" if $DEBUG
++ }
++ end
++ protected :clean_tmpfile
++ end
++
++ def NetCDF.create_tmp(tmpdir=ENV['TMPDIR']||ENV['TMP']||ENV['TEMP']||'.',
++ share=false)
++ basename = 'temp'
++ if $SAFE > 0 and tmpdir.tainted?
++ tmpdir = '.'
++ end
++
++ n = 0
++ while true
++ begin
++ tmpname = sprintf('%s/%s%d_%d.nc', tmpdir, basename, $$, n)
++ unless File.exist?(tmpname)
++ netcdf = NetCDF.create(tmpname, true, share)
++ ObjectSpace.define_finalizer(netcdf,
++ NetCDF.clean_tmpfile(tmpname))
++ break
++ end
++ rescue
++ raise NetcdfError, "cannot generate tempfile `%s'" % tmpname if n >= Max_Try
++ end
++ n += 1
++ end
++ netcdf
++ end
++
++
++ def put_att(attname,val,atttype=nil)
++ put_attraw(attname,val,atttype)
++ end
++
++ def def_var_with_dim(name, vartype, shape_ul0, dimnames)
++ # Same as def_var but defines dimensions first if needed.
++ # Use zero in shape to define an unlimited dimension.
++ if (shape_ul0.length != dimnames.length ) then
++ raise ArgumentError, 'lengths of shape and dimnames do not agree'
++ end
++ dims = []
++ dimnames.each_index{ |i|
++ dim = self.dim( dimnames[i] )
++ if ( dim != nil ) then
++ # dim exists --> check the length
++ if (shape_ul0[i] != dim.length_ul0 ) then
++ raise ArgumentError, "dimension length do not agree: #{i}th dim: "+\
++ "#{shape_ul0[i]} and #{dim.length_ul0}"
++ end
++ dims.push(dim)
++ else
++ # dim does not exist --> define it
++ dims.push( def_dim( dimnames[i], shape_ul0[i] ) )
++ end
++ }
++ def_var(name, vartype, dims)
++ end
++
++ # Iterators:
++ def each_dim
++ num_dim=ndims()
++ for dimid in 0..num_dim-1
++ obj_Dim=id2dim(dimid)
++ yield(obj_Dim)
++ end
++ end
++
++ def each_var
++ num_var=nvars()
++ for varid in 0..num_var-1
++ obj_Var=id2var(varid)
++ yield(obj_Var)
++ end
++ end
++
++ def each_att
++ num_att=natts()
++ for attnum in 0..num_att-1
++ obj_Att=id2att(attnum)
++ yield(obj_Att)
++ end
++ end
++
++ def dims( names=nil ) # return all if names==nil
++ if names == nil
++ dims = (0..ndims()-1).collect{|dimid| id2dim(dimid)}
++ else
++ raise TypeError, "names is not an array" if ! names.is_a?(Array)
++ dims = names.collect{|name| dim(name)}
++ raise ArgumentError, "One or more dimensions do not exist" if dims.include?(nil)
++ end
++ dims
++ end
++
++ def vars( names=nil ) # return all if names==nil
++ if names == nil
++ vars = (0..nvars()-1).collect{ |varid| id2var(varid) }
++ else
++ raise TypeError, "names is not an array" if ! names.is_a?(Array)
++ vars = names.collect{|name| var(name)}
++ raise ArgumentError, "One or more variables do not exist" if vars.include?(nil)
++ end
++ vars
++ end
++
++ def dim_names
++ num_dim=ndims()
++ names=[]
++ for dimid in 0..num_dim-1
++ obj_Dim=id2dim(dimid)
++ names=names+[obj_Dim.name]
++ end
++ return names
++ end
++
++ def var_names
++ num_var=nvars()
++ names=[]
++ for varid in 0..num_var-1
++ obj_Var=id2var(varid)
++ names=names+[obj_Var.name]
++ end
++ return names
++ end
++
++ def att_names
++ num_att=natts()
++ names=[]
++ for attnum in 0..num_att-1
++ obj_Att=id2att(attnum)
++ names=names+[obj_Att.name]
++ end
++ return names
++ end
++
++ def inspect
++ "NetCDF:"+path
++ end
++
++ end
++
++ class NetCDFVar
++
++ class << NetCDFVar
++ def new(file,varname,mode="r",share=false)
++ if(file.is_a?(String))
++ file = NetCDF.open(file,mode,share)
++ elsif(!file.is_a?(NetCDF))
++ raise TypeError, "1st arg must be a NetCDF (file object) or a String (path)"
++ end
++ file.var(varname)
++ end
++
++ alias open new
++ end
++
++ alias :rank :ndims
++
++ def each_att
++ num_att=natts()
++ for attnum in 0..num_att-1
++ obj_Att=id2att(attnum)
++ yield(obj_Att)
++ end
++ end
++
++ def dim_names
++ ary = Array.new()
++ dims.each{|dim| ary.push(dim.name)}
++ ary
++ end
++
++ def att_names
++ num_att=natts()
++ names=[]
++ for attnum in 0..num_att-1
++ obj_Att=id2att(attnum)
++ names=names+[obj_Att.name]
++ end
++ return names
++ end
++
++ def put_att(attname,val,atttype=nil)
++ put_attraw(attname,val,atttype)
++ end
++
++ def shape_ul0
++ sh = []
++ dims.each{|d|
++ if d.unlimited? then
++ sh.push(0)
++ else
++ sh.push(d.length)
++ end
++ }
++ sh
++ end
++
++ def shape_current
++ sh = []
++ dims.each{|d|
++ sh.push(d.length)
++ }
++ sh
++ end
++
++ # The put and get methods in the NetCDFVar class
++
++ def pack(na)
++ sf = att('scale_factor')
++ ao = att('add_offset')
++ if ( sf == nil && ao == nil ) then
++ na
++ else
++ na = NArray.to_na(na) if na.is_a?(Array)
++ if sf
++ csf = sf.get
++ raise NetcdfError,"scale_factor is not a numeric" if csf.is_a?(String)
++ raise NetcdfError, "scale_factor is not unique" if csf.length != 1
++ raise NetcdfError, "zero scale_factor" if csf[0] == 0
++ else
++ csf = nil
++ end
++ if ao
++ cao = ao.get
++ raise NetcdfError, "add_offset is not a numeric" if cao.is_a?(String)
++ raise NetcdfError, "add_offset is not unique" if cao.length != 1
++ else
++ cao = nil
++ end
++ if csf and cao
++ packed = (na - cao) / csf
++ elsif csf
++ packed = na / csf
++ elsif cao
++ packed = na - cao
++ end
++ if self.typecode <= NArray::LINT
++ packed = packed.round
++ end
++ packed
++ end
++ end
++
++ def scaled_put(var,hash=nil)
++ simple_put( pack(var), hash)
++ end
++
++ @@unpack_type = nil
++ class << NetCDFVar
++ def unpack_type
++ @@unpack_type
++ end
++ def unpack_type=(na_type)
++ if [NArray::BYTE, NArray::SINT, NArray::INT,
++ NArray::SFLOAT, NArray::FLOAT, nil].include?(na_type)
++ @@unpack_type = na_type
++ else
++ raise ArgumentError, "Arg must be one of NArray::BYTE, NArray::SINT, NArray::INT, NArray::SFLOAT, NArray::FLOAT"
++ end
++ end
++
++ end
++
++ def unpack(na)
++ sf = att('scale_factor')
++ ao = att('add_offset')
++ if ( sf == nil && ao == nil ) then
++ na
++ else
++ if sf
++ csf = sf.get
++ raise NetcdfError,"scale_factor is not a numeric" if csf.is_a?(String)
++ raise NetcdfError, "scale_factor is not unique" if csf.length != 1
++ raise NetcdfError, "zero scale_factor" if csf[0] == 0
++ else
++ csf =nil
++ end
++ if ao
++ cao = ao.get
++ raise NetcdfError, "add_offset is not a numeric" if cao.is_a?(String)
++ raise NetcdfError, "add_offset is not unique" if cao.length != 1
++ else
++ cao = nil
++ end
++ if csf and cao
++ una = na * csf + cao # csf & cao are NArray -> coerced to their types
++ elsif csf
++ una = na * csf
++ elsif cao
++ una = na + cao
++ end
++ una = una.to_type(@@unpack_type) if @@unpack_type
++ una
++ end
++ end
++
++ def scaled_get(hash=nil)
++ unpack( simple_get(hash) )
++ end
++
++ def simple_put(var,hash=nil)
++ if hash==nil
++ if self.vartype == "char"
++ put_var_char(var)
++ elsif self.vartype == "byte"
++ put_var_byte(var)
++ elsif self.vartype == "sint"
++ put_var_sint(var)
++ elsif self.vartype == "int"
++ put_var_int(var)
++ elsif self.vartype == "sfloat"
++ put_var_sfloat(var)
++ elsif self.vartype == "float"
++ put_var_float(var)
++ else
++ raise NetcdfError,"variable type isn't supported in netCDF"
++ end
++ elsif hash.key?("index")==true
++ if self.vartype == "char"
++ put_var1_char(var,hash["index"])
++ elsif self.vartype=="byte"
++ put_var1_byte(var,hash["index"])
++ elsif self.vartype=="sint"
++ put_var1_sint(var,hash["index"])
++ elsif self.vartype == "int"
++ put_var1_int(var,hash["index"])
++ elsif self.vartype == "sfloat"
++ put_var1_sfloat(var,hash["index"])
++ elsif self.vartype == "float"
++ put_var1_float(var,hash["index"])
++ else
++ raise NetcdfError,"variable type isn't supported in netCDF"
++ end
++ elsif hash.key?("start")==true
++ if hash.key?("end")==false && hash.key?("stride")==false
++ if self.vartype == "char"
++ put_vars_char(var,hash["start"],nil,nil)
++ elsif self.vartype=="byte"
++ put_vars_byte(var,hash["start"],nil,nil)
++ elsif self.vartype=="sint"
++ put_vars_sint(var,hash["start"],nil,nil)
++ elsif self.vartype=="int"
++ put_vars_int(var,hash["start"],nil,nil)
++ elsif self.vartype=="sfloat"
++ put_vars_sfloat(var,hash["start"],nil,nil)
++ elsif self.vartype=="float"
++ put_vars_float(var,hash["start"],nil,nil)
++ else
++ raise NetcdfError, "variable type isn't supported in netCDF"
++ end
++ elsif hash.key?("end")==true && hash.key?("stride") == false
++ if self.vartype == "char"
++ put_vars_char(var,hash["start"],hash["end"],nil)
++ elsif self.vartype=="byte"
++ put_vars_byte(var,hash["start"],hash["end"],nil)
++ elsif self.vartype=="sint"
++ put_vars_sint(var,hash["start"],hash["end"],nil)
++ elsif self.vartype=="int"
++ put_vars_int(var,hash["start"],hash["end"],nil)
++ elsif self.vartype == "sfloat"
++ put_vars_sfloat(var,hash["start"],hash["end"],nil)
++ elsif self.vartype =="float"
++ put_vars_float(var,hash["start"],hash["end"],nil)
++ else
++ raise NetcdfError, "variable type isn't supported in netCDF"
++ end
++ elsif hash.key?("end")==false && hash.key?("stride")==true
++ if self.vartype == "char"
++ put_vars_char(var,hash["start"],nil,hash["stride"])
++ elsif self.vartype=="byte"
++ put_vars_byte(var,hash["start"],nil,hash["stride"])
++ elsif self.vartype=="sint"
++ put_vars_sint(var,hash["start"],nil,hash["stride"])
++ elsif self.vartype=="int"
++ put_vars_int(var,hash["start"],nil,hash["stride"])
++ elsif self.vartype=="sfloat"
++ put_vars_sfloat(var,hash["start"],nil,hash["stride"])
++ elsif self.vartype=="float"
++ put_vars_float(var,hash["start"],nil,hash["stride"])
++ else
++ raise NetcdfError, "variable type isn't supported in netCDF"
++ end
++ else hash.key?("end")==true && hash.key?("stride")==true
++ if self.vartype == "char"
++ put_vars_char(var,hash["start"],hash["end"],hash["stride"])
++ elsif self.vartype=="byte"
++ put_vars_byte(var,hash["start"],hash["end"],hash["stride"])
++ elsif self.vartype=="sint"
++ put_vars_sint(var,hash["start"],hash["end"],hash["stride"])
++ elsif self.vartype=="int"
++ put_vars_int(var,hash["start"],hash["end"],hash["stride"])
++ elsif self.vartype=="sfloat"
++ put_vars_sfloat(var,hash["start"],hash["end"],hash["stride"])
++ elsif self.vartype=="float"
++ put_vars_float(var,hash["start"],hash["end"],hash["stride"])
++ else
++ raise NetcdfError, "variable type isn't supported in netCDF"
++ end
++ end
++ else
++ raise ArgumentError,"{'start'}=>[ARRAY] or {'index'}=>[ARRAY] is needed"
++ end
++ end
++
++ alias put simple_put
++
++ def simple_get(hash=nil)
++ t_var = self.vartype
++ if hash == nil
++ if t_var == "char"
++ get_var_char
++ elsif t_var == "byte"
++ get_var_byte
++ elsif t_var == "sint"
++ get_var_sint
++ elsif t_var == "int"
++ get_var_int
++ elsif t_var == "sfloat"
++ get_var_sfloat
++ elsif t_var == "float"
++ get_var_float
++ else
++ raise NetcdfError, "variable type #{t_var} isn't supported in netCDF"
++ end
++ elsif hash.key?("index")==true
++ ind = hash["index"]
++ if t_var == "char"
++ get_var1_char(ind)
++ elsif t_var == "byte"
++ get_var1_byte(ind)
++ elsif t_var == "sint"
++ get_var1_sint(ind)
++ elsif t_var == "int"
++ get_var1_int(ind)
++ elsif t_var == "sfloat"
++ get_var1_sfloat(ind)
++ elsif t_var == "float"
++ get_var1_float(ind)
++ else
++ raise NetcdfError,"variable type #{t_var} isn't supported in netCDF"
++ end
++ elsif hash.key?("start")==true
++ h_sta = hash["start"]
++ h_end = hash["end"] # can be nill
++ h_str = hash["stride"] # can be nill
++ if NetCDF.nc4? && h_str && ((xstr=h_str[0]) != 1)
++ # Tentative treatment for the very slow netcdf-4 reading with step.
++ # Reading with step is generally slow with NetCDF 4, but it is
++ # particularly so for the first dimension.
++ # Ref: http://www.unidata.ucar.edu/mailing_lists/archives/netcdfgroup/2013/msg00311.html
++ h_str[0] = 1
++ nc4remedy = true
++ else
++ nc4remedy = false
++ end
++ if t_var == "char"
++ v = get_vars_char(h_sta,h_end,h_str)
++ elsif t_var == "byte"
++ v = get_vars_byte(h_sta,h_end,h_str)
++ elsif t_var == "sint"
++ v = get_vars_sint(h_sta,h_end,h_str)
++ elsif t_var == "int"
++ v = get_vars_int(h_sta,h_end,h_str)
++ elsif t_var == "sfloat"
++ v = get_vars_sfloat(h_sta,h_end,h_str)
++ elsif t_var == "float"
++ v = get_vars_float(h_sta,h_end,h_str)
++ else
++ raise NetcdfError, "variable type #{t_var} isn't supported in netCDF"
++ end
++ if nc4remedy
++ idx = []
++ (0...v.shape[0]).step(xstr){|k| idx.push(k)}
++ v = v[idx,false]
++ end
++ v
++ else
++ raise ArgumentError,"{'start'}=>{ARRAY} or {'index'}=>{ARRAY} is needed"
++ end
++ end
++
++ alias get simple_get
++
++ def __rubber_expansion( args )
++ if (id = args.index(false)) # substitution into id
++ # false is incuded
++ alen = args.length
++ if args.rindex(false) != id
++ raise ArguemntError,"only one rubber dimension is permitted"
++ elsif alen > rank+1
++ raise ArgumentError, "too many args"
++ end
++ ar = ( id!=0 ? args[0..id-1] : [] )
++ args = ar + [true]*(rank-alen+1) + args[id+1..-1]
++ elsif args.length == 0 # to support empty [], []=
++ args = [true]*rank
++ end
++ args
++ end
++ private :__rubber_expansion
++
++ def [](*a)
++ if a.length == 0
++ return self.get
++ end
++ a = __rubber_expansion(a)
++ first = Array.new
++ last = Array.new
++ stride = Array.new
++ set_stride = false
++ a.each{|i|
++ if(i.is_a?(Fixnum))
++ first.push(i)
++ last.push(i)
++ stride.push(1)
++ elsif(i.is_a?(Range))
++ first.push(i.first)
++ last.push(i.exclude_end? ? i.last-1 : i.last)
++ stride.push(1)
++ elsif(i.is_a?(Hash))
++ r = (i.to_a[0])[0]
++ s = (i.to_a[0])[1]
++ if ( !( r.is_a?(Range) ) || ! ( s.is_a?(Integer) ) )
++ raise TypeError, "Hash argument must be {a_Range, step}"
++ end
++ first.push(r.first)
++ last.push(r.exclude_end? ? r.last-1 : r.last)
++ stride.push(s)
++ set_stride = true
++ elsif(i.is_a?(TrueClass))
++ first.push(0)
++ last.push(-1)
++ stride.push(1)
++ elsif( i.is_a?(Array) || i.is_a?(NArray))
++ a_new = a.dup
++ at = a.index(i)
++ i = NArray.to_na(i) if i.is_a?(Array)
++ for n in 0..i.length-1
++ a_new[at] = i[n]..i[n]
++ na_tmp = self[*a_new]
++ if n==0 then
++ k = at
++ if at > 0
++ a[0..at-1].each{|x| if x.is_a?(Fixnum) then k -= 1 end}
++ end
++ shape_tmp = na_tmp.shape
++ shape_tmp[k] = i.length
++ na = na_tmp.class.new(na_tmp.typecode,*shape_tmp)
++ index_tmp = Array.new(shape_tmp.length,true)
++ end
++ index_tmp[k] = n..n
++ na[*index_tmp] = na_tmp
++ end
++ return na
++ else
++ raise TypeError, "argument must be Fixnum, Range, Hash, TrueClass, Array, or NArray"
++ end
++ }
++
++ if(set_stride)
++ na = self.get({"start"=>first, "end"=>last, "stride"=>stride})
++ else
++ na = self.get({"start"=>first, "end"=>last})
++ end
++ shape = na.shape
++ (a.length-1).downto(0){ |i|
++ shape.delete_at(i) if a[i].is_a?(Fixnum)
++ }
++ na.reshape!( *shape )
++ na
++ end
++
++ def []=(*a)
++ val = a.pop
++ a = __rubber_expansion(a)
++ first = Array.new
++ last = Array.new
++ stride = Array.new
++ set_stride = false
++ a.each{|i|
++ if(i.is_a?(Fixnum))
++ first.push(i)
++ last.push(i)
++ stride.push(1)
++ elsif(i.is_a?(Range))
++ first.push(i.first)
++ last.push(i.exclude_end? ? i.last-1 : i.last)
++ stride.push(1)
++ elsif(i.is_a?(Hash))
++ r = (i.to_a[0])[0]
++ s = (i.to_a[0])[1]
++ if ( !( r.is_a?(Range) ) || ! ( s.is_a?(Integer) ) )
++ raise ArgumentError, "Hash argument must be {first..last, step}"
++ end
++ first.push(r.first)
++ last.push(r.exclude_end? ? r.last-1 : r.last)
++ stride.push(s)
++ set_stride = true
++ elsif(i.is_a?(TrueClass))
++ first.push(0)
++ last.push(-1)
++ stride.push(1)
++ elsif(i.is_a?(Array) || i.is_a?(NArray))
++ a_new = a.dup
++ at = a.index(i)
++ i = NArray.to_na(i) if i.is_a?(Array)
++ val = NArray.to_na(val) if val.is_a?(Array)
++ rank_of_subset = a.dup.delete_if{|v| v.is_a?(Fixnum)}.length
++ if val.rank != rank_of_subset
++ raise "rank of the rhs (#{val.rank}) is not equal to the rank "+
++ "of the subset specified by #{a.inspect} (#{rank_of_subset})"
++ end
++ k = at
++ a[0..at-1].each{|x| if x.is_a?(Fixnum) then k -= 1 end}
++ if i.length != val.shape[k]
++ raise "length of the #{k+1}-th dim of rhs is incorrect "+
++ "(#{i.length} for #{val.shape[k]})"
++ end
++ index_tmp = Array.new(val.rank,true) if !val.is_a?(Numeric) #==>Array-like
++ for n in 0..i.length-1
++ a_new[at] = i[n]..i[n]
++ if !val.is_a?(Numeric) then
++ index_tmp[k] = n..n
++ self[*a_new] = val[*index_tmp]
++ else
++ self[*a_new] = val
++ end
++ end
++ return self
++ else
++ raise TypeError, "argument must be Fixnum, Range, Hash, TrueClass, Array, or NArray"
++ end
++ }
++
++ if(set_stride)
++ self.put(val, {"start"=>first, "end"=>last, "stride"=>stride})
++ else
++ self.put(val, {"start"=>first, "end"=>last})
++ end
++ end
++
++ def inspect
++ 'NetCDFVar:'+file.path+'?var='+name
++ end
++
++ end
++
++ class NetCDFAtt
++
++ def put(val,atttype=nil)
++ putraw(val,atttype)
++ end
++
++ def inspect
++ 'NetCDFAtt:'+name
++ end
++ end
++
++ class NetCDFDim
++ def inspect
++ 'NetCDFDim:'+name
++ end
++
++ def length_ul0
++ if unlimited?
++ 0
++ else
++ length
++ end
++ end
++
++ end
++end
+diff --git a/lib/numru/netcdf/netcdf_miss.rb b/lib/numru/netcdf/netcdf_miss.rb
+new file mode 100644
+index 0000000..4b168f0
+--- /dev/null
++++ b/lib/numru/netcdf/netcdf_miss.rb
+@@ -0,0 +1,203 @@
++require "numru/netcdf"
++require "narray_miss"
++
++module NumRu
++
++ class NetCDFVar
++
++ def get_with_miss(*args)
++ __interpret_missing_params if !defined?(@missval)
++ data = simple_get(*args)
++ if @vmin || @vmax
++ if @vmin
++ mask = (data >= @vmin)
++ mask = mask.and(data <= @vmax) if @vmax
++ else
++ mask = (data <= @vmax)
++ end
++ data = NArrayMiss.to_nam(data, mask)
++ elsif @missval # only missing_value is present.
++ mask = (data.ne(@missval))
++ data = NArrayMiss.to_nam(data, mask)
++ end
++ data
++ end
++
++ def get_with_miss_and_scaling(*args)
++ __interpret_missing_params if !defined?(@missval)
++ data = simple_get(*args)
++ if @vmin || @vmax
++ if @vmin
++ mask = (data >= @vmin)
++ mask = mask.and(data <= @vmax) if @vmax
++ else
++ mask = (data <= @vmax)
++ end
++ data = NArrayMiss.to_nam(data, mask)
++ elsif @missval # only missing_value is present.
++ mask = (data.ne(@missval))
++ data = NArrayMiss.to_nam(data, mask)
++ end
++ data = unpack( data )
++ data
++ end
++
++ def put_with_miss(data, *args)
++ if data.is_a?( NArrayMiss )
++ __interpret_missing_params if !defined?(@missval)
++ if @missval
++ simple_put(data.to_na(@missval), *args)
++ else
++ simple_put(data.to_na, *args)
++ end
++ else
++ simple_put(data, *args)
++ end
++ end
++
++ def put_with_miss_and_scaling(data, *args)
++ if data.is_a?( NArrayMiss )
++ __interpret_missing_params if !defined?(@missval)
++ if @missval
++ data = pack( data )
++ data = data.to_na(@missval)
++ else
++ data = pack( data )
++ data = data.to_na
++ end
++ simple_put(data, *args)
++ else
++ scaled_put(data, *args)
++ end
++ end
++
++ ######### private ##########
++
++ def __interpret_missing_params
++ # Interprets the specification of missing data,
++ # either by valid_range, (valid_min and/or valid_max), or missing_value.
++ # (unlike the NetCDF User's guide (NUG), missing_value is interpreted,
++ # but valid_* has a higher precedence.)
++ # Always sets @missval whether missing_value is defined or not,
++ # since it will be used as a fill value for data missing.
++ #
++ @vmin = att('valid_min')
++ @vmin = @vmin.get if @vmin # kept in a NArray(size==1) to consv type
++ @vmax = att('valid_max')
++ @vmax = @vmax.get if @vmax # kept in a NArray(size==1) to consv type
++ vrange = att('valid_range')
++ vrange = vrange.get if vrange
++ if vrange
++ vrange.sort!
++ @vmin = vrange[0..0] # kept in... (same)
++ @vmax = vrange[-1..-1] # kept in... (same)
++ end
++ @missval = att('missing_value') || att('_FillValue')
++ @missval = @missval.get if @missval # kept in... (same)
++
++ sf = att('scale_factor')
++ ao = att('add_offset')
++ if ( sf || ao )
++ ## Both NUG & CF conventions requires to specify the valid
++ ## range with respect to the external (i.e. packed) values.
++ ## However, some conventions require specification
++ ## with respect to unpacked values. The following
++ ## is to support such cases as well:
++ thres_tp = [ self.typecode, NArray::LINT ].max
++ @missval = pack(@missval) if @missval && @missval.typecode > thres_tp
++ @vmin = pack(@vmin) if @vmin && @vmin.typecode > thres_tp
++ @vmax = pack(@vmax) if @vmax && @vmax.typecode > thres_tp
++ end
++
++ if @missval
++ if @vmin && @vmax
++ if @vmin[0] <= @missval[0] && @missval[0] <= @vmax[0]
++ warn "WARNING: missing_value #{@missval[0]} is in the valid range #{@vmin[0]}..#{@vmax[0]} --> will be ignored (#{__FILE__}:#{__LINE__})"
++ end
++ else
++ if @vmin && @missval[0] >= @vmin[0]
++ warn "WARNING: missing_value #{@missval[0]} >= valid min #{@vmin[0]} --> will be ignored (#{__FILE__}:#{__LINE__})"
++ elsif @vmax && @missval[0] <= @vmax[0]
++ warn "WARNING: missing_value #{@missval[0]} <= valid min #{@vmin[0]} --> will be ignored (#{__FILE__}:#{__LINE__})"
++ end
++ end
++ else
++ realtc = NArray::SFLOAT
++ if @vmin
++ if @vmin[0] >= 0
++ @missval = ( @vmin.typecode>=realtc ? 0.99*@vmin : @vmin-1 )
++ else
++ @missval = ( @vmin.typecode>=realtc ? 1.01*@vmin : @vmin-1 )
++ end
++ elsif @vmax
++ if @vmax[0] >= 0
++ @missval = ( @vmax.typecode>=realtc ? 1.01*@vmax : @vmax+1 )
++ else
++ @missval = ( @vmax.typecode>=realtc ? 0.99*@vmax : @vmax+1 )
++ end
++ end
++ end
++
++ end
++
++ private :__interpret_missing_params
++
++ end
++
++end
++
++if $0 == __FILE__
++ include NumRu
++
++ filename = "tmp.nc"
++ print "creating ",filename,"...\n"
++ file=NetCDF.create(filename)
++ nx = 10
++ dimx = file.def_dim("x",nx)
++ xf = file.def_var("xf","sfloat",[dimx])
++ xfn = file.def_var("xfn","sfloat",[dimx])
++ xf.put_att("valid_range",[-1e12,1e12])
++ f = 10 ** (2*NArray.sfloat(nx).indgen!)
++ xr = file.def_var("xr","sint",[dimx])
++ xr.put_att("valid_max",[0.5])
++ xr.put_att("scale_factor",1e-4)
++ xr.put_att("add_offset",0.5)
++ xr2 = file.def_var("xr2","sint",[dimx])
++ xr2.put_att("valid_max",NArray.sint(1).fill!(1000))
++ xr2.put_att("scale_factor",1e-4)
++ xr2.put_att("add_offset",0.5)
++ r = NArray.sfloat(nx).indgen!/nx
++ file.enddef
++ xf.put(f)
++ xfn.put(f)
++ xr.scaled_put(r)
++ file.close
++
++ file = NetCDF.open(filename,'r+')
++ xf = file.var('xf')
++ xfn = file.var('xfn')
++ p "f0"
++ xf.get.each{|v| print "#{v} "} ; print "\n"
++ p( 'f1', nam = xf.get_with_miss )
++ def xf.get(*args); get_with_miss(*args); end
++ p( 'f12', xf[2..-3].to_na )
++ p( 'fn10', xfn.get_with_miss )
++ p( 'fn11', xfn.get_with_miss_and_scaling )
++ nam.invalidation([0,1])
++ p 'f2', nam
++ xf.put_with_miss(nam)
++ p( 'f3', xf.get_with_miss )
++ xr = file.var('xr')
++ p "r0"
++ xr.simple_get.each{|v| print "#{v} "} ; print "\n"
++ p( 'r1', xr.get_with_miss_and_scaling )
++ def xr.get(*args); get_with_miss_and_scaling(*args); end
++ def xr.put(*args); put_with_miss_and_scaling(*args); end
++ #xr[0..3] = xr[0..3]*10
++ p( 'r2', xr.get_with_miss_and_scaling )
++ p 'r',r
++ xr2.put_with_miss_and_scaling(r)
++ p 'xr2',xr2.get_with_miss_and_scaling
++ file.close
++ print "** ncdump tmp.nc **\n", `ncdump tmp.nc`
++end
+diff --git a/lib/numru/netcdf/version.rb b/lib/numru/netcdf/version.rb
+new file mode 100644
+index 0000000..7043c9e
+--- /dev/null
++++ b/lib/numru/netcdf/version.rb
+@@ -0,0 +1,5 @@
++module Ruby
++ module Netcdf
++ VERSION = "0.7.1.1"
++ end
++end
+diff --git a/lib/version.rb b/lib/version.rb
+deleted file mode 100644
+index 7043c9e..0000000
+--- a/lib/version.rb
++++ /dev/null
+@@ -1,5 +0,0 @@
+-module Ruby
+- module Netcdf
+- VERSION = "0.7.1.1"
+- end
+-end
+diff --git a/metadata.yml b/metadata.yml
+index fb30c35..25a1eda 100644
+--- a/metadata.yml
++++ b/metadata.yml
+@@ -49,7 +49,7 @@ email:
+ - eriko at gfd-dennou.org
+ executables: []
+ extensions:
+-- extconf.rb
++- ext/numru/extconf.rb
+ extra_rdoc_files: []
+ files:
+ - .gitignore
+@@ -76,11 +76,12 @@ files:
+ - doc/Ref_man_jp.html
+ - doc/Ref_man_jp.rd
+ - doc/to_html
+-- extconf.rb
++- ext/numru/extconf.rb
++- ext/numru/netcdfraw.c
+ - lib/netcdf.rb
+-- lib/netcdf_miss.rb
+-- lib/version.rb
+-- netcdfraw.c
++- lib/numru/netcdf.rb
++- lib/numru/netcdf/netcdf_miss.rb
++- lib/numru/netcdf/version.rb
+ - ruby-netcdf.gemspec
+ - test/aref_aset.rb
+ - test/char_var.rb
+diff --git a/netcdfraw.c b/netcdfraw.c
+deleted file mode 100644
+index 200e8f3..0000000
+--- a/netcdfraw.c
++++ /dev/null
+@@ -1,4721 +0,0 @@
+-#include<stdio.h>
+-#include "ruby.h"
+-#include "narray.h"
+-#include<netcdf.h>
+-#include<string.h>
+-
+-/* for compatibility with ruby 1.6 */
+-#ifndef RSTRING_PTR
+-#define RSTRING_PTR(s) (RSTRING(s)->ptr)
+-#endif
+-#ifndef RSTRING_LEN
+-#define RSTRING_LEN(s) (RSTRING(s)->len)
+-#endif
+-#ifndef RARRAY_PTR
+-#define RARRAY_PTR(a) (RARRAY(a)->ptr)
+-#endif
+-#ifndef RARRAY_LEN
+-#define RARRAY_LEN(a) (RARRAY(a)->len)
+-#endif
+-#ifndef StringValueCStr
+-#define StringValueCStr(s) STR2CSTR(s)
+-#endif
+-#ifndef SafeStringValue
+-#define SafeStringValue(s) Check_SafeStr(s)
+-#endif
+-
+-/* for compatibility for NArray and NArray with big memory patch */
+-#ifndef NARRAY_BIGMEM
+-typedef int na_shape_t;
+-#endif
+-
+-/* Data to NArray */
+-
+-/* memcpy(ary->ptr,nc_ptr,na_sizeof[NA_SINT]*ary->total); \ */
+-
+-#define Cbyte_to_NArray(v, rank, shape, up) \
+-{ \
+- struct NARRAY *ary; \
+- v = na_make_object(NA_BYTE, rank, shape, cNArray); \
+- GetNArray(v,ary); \
+- up = (unsigned char *)ary->ptr; \
+-}
+-
+-#define Csint_to_NArray(v, rank, shape, sp) \
+-{ \
+- struct NARRAY *ary; \
+- v = na_make_object(NA_SINT, rank, shape, cNArray); \
+- GetNArray(v, ary); \
+- sp = (short *)ary->ptr; \
+-}
+-
+-#define Clint_to_NArray(v, rank, shape, lp) \
+-{ \
+- struct NARRAY *ary; \
+- v = na_make_object(NA_LINT, rank, shape, cNArray); \
+- GetNArray(v, ary); \
+- lp = (int *)ary->ptr; \
+-}
+-#define Cfloat_to_NArray(v, rank, shape, fp) \
+-{ \
+- struct NARRAY *ary; \
+- v = na_make_object(NA_SFLOAT, rank, shape, cNArray); \
+- GetNArray(v, ary); \
+- fp = (float *)ary->ptr; \
+-}
+-#define Cdouble_to_NArray(v, rank, shape, dp); \
+-{ \
+- struct NARRAY *ary; \
+- v = na_make_object(NA_DFLOAT, rank, shape, cNArray); \
+- GetNArray(v, ary); \
+- dp = (double *)ary->ptr; \
+-}
+-
+-/* Array or NArray to pointer and length (with no new allocation) */
+-
+-#define Array_to_Cfloat_len(obj, ptr, len) \
+-{ \
+- struct NARRAY *na; \
+- obj = na_cast_object(obj, NA_SFLOAT); \
+- GetNArray(obj, na); \
+- ptr = (float *) NA_PTR(na,0); \
+- len = na->total; \
+-}
+-
+-#define Array_to_Cfloat_len_shape(obj, ptr, len, shape) \
+-{ \
+- struct NARRAY *na; \
+- obj = na_cast_object(obj, NA_SFLOAT); \
+- GetNArray(obj, na); \
+- ptr = (float *) NA_PTR(na,0); \
+- len = na->total; \
+- shape = na->shape; \
+-}
+-
+-#define Array_to_Cdouble_len(obj, ptr, len) \
+-{ \
+- struct NARRAY *na; \
+- obj = na_cast_object(obj, NA_DFLOAT); \
+- GetNArray(obj, na); \
+- ptr = (double *) NA_PTR(na,0); \
+- len = na->total; \
+-}
+-#define Array_to_Cdouble_len_shape(obj, ptr, len, shape) \
+-{ \
+- struct NARRAY *na; \
+- obj = na_cast_object(obj, NA_DFLOAT); \
+- GetNArray(obj, na); \
+- ptr = (double *) NA_PTR(na,0); \
+- len = na->total; \
+- shape = na->shape; \
+-}
+-
+-#define Array_to_Cbyte_len(obj, ptr, len) \
+-{ \
+- struct NARRAY *na; \
+- obj = na_cast_object(obj, NA_BYTE); \
+- GetNArray(obj, na); \
+- ptr = (u_int8_t *) NA_PTR(na,0); \
+- len = na->total; \
+-}
+-
+-#define Array_to_Cbyte_len_shape(obj, ptr, len, shape) \
+-{ \
+- struct NARRAY *na; \
+- obj = na_cast_object(obj, NA_BYTE); \
+- GetNArray(obj, na); \
+- ptr = (u_int8_t *) NA_PTR(na,0); \
+- len = na->total; \
+- shape = na->shape; \
+-}
+-
+-#define Array_to_Csint_len(obj, ptr, len) \
+-{ \
+- struct NARRAY *na; \
+- obj = na_cast_object(obj, NA_SINT); \
+- GetNArray(obj, na); \
+- ptr = (int16_t *) NA_PTR(na,0); \
+- len = na->total; \
+-}
+-
+-#define Array_to_Csint_len_shape(obj, ptr, len, shape) \
+-{ \
+- struct NARRAY *na; \
+- obj = na_cast_object(obj, NA_SINT); \
+- GetNArray(obj, na); \
+- ptr = (int16_t *) NA_PTR(na,0); \
+- len = na->total; \
+- shape = na->shape; \
+-}
+-
+-
+-#define Array_to_Clint_len(obj, ptr, len) \
+-{ \
+- struct NARRAY *na; \
+- obj = na_cast_object(obj, NA_LINT); \
+- GetNArray(obj, na); \
+- ptr = (int32_t *) NA_PTR(na,0); \
+- len = na->total; \
+-}
+-
+-#define Array_to_Clint_len_shape(obj, ptr, len, shape) \
+-{ \
+- struct NARRAY *na; \
+- obj = na_cast_object(obj, NA_LINT); \
+- GetNArray(obj, na); \
+- ptr = (int32_t *) NA_PTR(na,0); \
+- len = na->total; \
+- shape = na->shape; \
+-}
+-
+-
+-/* Array or NArray to pointer (with no new allocation) */
+-
+-#define Array_to_Cfloat(obj, ptr) \
+-{ \
+- struct NARRAY *na; \
+- obj = na_cast_object(obj, NA_SFLOAT); \
+- GetNArray(obj, na); \
+- ptr = (float *) NA_PTR(na,0); \
+-}
+-#define Array_to_Cdouble(obj, ptr) \
+-{ \
+- struct NARRAY *na; \
+- obj = na_cast_object(obj, NA_DFLOAT); \
+- GetNArray(obj, na); \
+- ptr = (double *) NA_PTR(na,0); \
+-}
+-#define Array_to_Cbyte(obj, ptr) \
+-{ \
+- struct NARRAY *na; \
+- obj = na_cast_object(obj, NA_BYTE); \
+- GetNArray(obj, na); \
+- ptr = (u_int8_t *) NA_PTR(na,0); \
+-}
+-#define Array_to_Csint(obj, ptr) \
+-{ \
+- struct NARRAY *na; \
+- obj = na_cast_object(obj, NA_SINT); \
+- GetNArray(obj, na); \
+- ptr = (int16_t *) NA_PTR(na,0); \
+-}
+-#define Array_to_Clint(obj, ptr) \
+-{ \
+- struct NARRAY *na; \
+- obj = na_cast_object(obj, NA_LINT); \
+- GetNArray(obj, na); \
+- ptr = (int32_t *) NA_PTR(na,0); \
+-}
+-
+-#define NC_RAISE(status) rb_raise(err_status2class(status),"%s",(nc_strerror(status)))
+-#define NC_RAISE2(status, str) rb_raise(err_status2class(status),"%s (%s)",nc_strerror(status),(str) )
+-
+-static VALUE mNumRu = 0;
+-static VALUE cNetCDF;
+-static VALUE cNetCDFDim;
+-static VALUE cNetCDFAtt;
+-static VALUE cNetCDFVar;
+-
+-static VALUE rb_eNetcdfError;
+-static VALUE rb_eNetcdfBadid;
+-static VALUE rb_eNetcdfNfile;
+-static VALUE rb_eNetcdfExist;
+-static VALUE rb_eNetcdfInval;
+-static VALUE rb_eNetcdfPerm;
+-static VALUE rb_eNetcdfNotindefine;
+-static VALUE rb_eNetcdfIndefine;
+-static VALUE rb_eNetcdfInvalcoords;
+-static VALUE rb_eNetcdfMaxdims;
+-static VALUE rb_eNetcdfNameinuse;
+-static VALUE rb_eNetcdfNotatt;
+-static VALUE rb_eNetcdfMaxatts;
+-static VALUE rb_eNetcdfBadtype;
+-static VALUE rb_eNetcdfBaddim;
+-static VALUE rb_eNetcdfUnlimpos;
+-static VALUE rb_eNetcdfMaxvars;
+-static VALUE rb_eNetcdfNotvar;
+-static VALUE rb_eNetcdfGlobal;
+-static VALUE rb_eNetcdfNotnc;
+-static VALUE rb_eNetcdfSts;
+-static VALUE rb_eNetcdfMaxname;
+-static VALUE rb_eNetcdfUnlimit;
+-static VALUE rb_eNetcdfNorecvars;
+-static VALUE rb_eNetcdfChar;
+-static VALUE rb_eNetcdfEdge;
+-static VALUE rb_eNetcdfStride;
+-static VALUE rb_eNetcdfBadname;
+-static VALUE rb_eNetcdfRange;
+-static VALUE rb_eNetcdfNomem;
+-
+-/* Special Error */
+-/* Global error status */
+-
+-static VALUE rb_eNetcdfFatal;
+-
+-/* Global options variable. Used to determine behavior of error handler. */
+-
+-static VALUE rb_eNetcdfEntool;
+-static VALUE rb_eNetcdfExdr;
+-static VALUE rb_eNetcdfSyserr;
+-
+-
+-struct Netcdf{
+- int ncid;
+- char *name;
+- int closed;
+-};
+-
+-struct NetCDFDim{
+- int dimid;
+- int ncid;
+-};
+-
+-struct NetCDFVar{
+- int varid;
+- int ncid;
+- VALUE file;
+-};
+-
+-struct NetCDFAtt{
+- int varid;
+- int ncid;
+- char *name;
+-};
+-
+-static struct Netcdf *
+-NetCDF_init(int ncid,char *filename)
+-{
+- struct Netcdf *Netcdffile;
+- Netcdffile=xmalloc(sizeof(struct Netcdf));
+- Netcdffile->ncid=ncid;
+- Netcdffile->closed=0;
+- Netcdffile->name=xmalloc((strlen(filename)+1)*sizeof(char));
+- strcpy(Netcdffile->name,filename);
+- return(Netcdffile);
+-}
+-
+-static struct NetCDFDim *
+-NetCDF_dim_init(int ncid,int dimid)
+-{
+- struct NetCDFDim *Netcdf_dim;
+- Netcdf_dim=xmalloc(sizeof(struct NetCDFDim));
+- Netcdf_dim->dimid=dimid;
+- Netcdf_dim->ncid=ncid;
+- return(Netcdf_dim);
+-}
+-
+-static struct NetCDFVar *
+-NetCDF_var_init(int ncid,int varid,VALUE file)
+-{
+- struct NetCDFVar *Netcdf_var;
+- Netcdf_var=xmalloc(sizeof(struct NetCDFVar));
+- Netcdf_var->varid=varid;
+- Netcdf_var->ncid=ncid;
+- Netcdf_var->file=file;
+- return(Netcdf_var);
+-}
+-static struct NetCDFAtt *
+-NetCDF_att_init(int ncid,int varid,char *attname)
+-{
+- struct NetCDFAtt *Netcdf_att;
+- Netcdf_att=xmalloc(sizeof(struct NetCDFAtt));
+- Netcdf_att->ncid=ncid;
+- Netcdf_att->varid=varid;
+- Netcdf_att->name=xmalloc((strlen(attname)+1)*sizeof(char));
+- strcpy(Netcdf_att->name,attname);
+- return(Netcdf_att);
+-}
+-
+-void
+-Netcdf_att_free(struct NetCDFAtt *Netcdf_att)
+-{
+- free(Netcdf_att->name);
+- free(Netcdf_att);
+-}
+-
+-void
+-NetCDF_var_free(struct NetCDFVar *Netcdf_var)
+-{
+- free(Netcdf_var);
+-}
+-
+-void
+-NetCDF_dim_free(struct NetCDFDim *Netcdf_dim)
+-{
+- free(Netcdf_dim);
+-}
+-
+-void
+-NetCDF_free(struct Netcdf *Netcdffile)
+-{
+- if (!Netcdffile->closed){
+- nc_close(Netcdffile->ncid); /* no error check -- not to stop during GC */
+- }
+- free(Netcdffile->name);
+- free(Netcdffile);
+-}
+-
+-static VALUE
+-err_status2class(int status)
+-{
+- if(NC_ISSYSERR(status)){
+- return(rb_eNetcdfSyserr);
+- }
+- switch(status)
+- {
+- case(NC_EBADID):
+- return(rb_eNetcdfBadid);break;
+- case(NC_ENFILE):
+- return(rb_eNetcdfNfile);break;
+- case(NC_EEXIST):
+- return(rb_eNetcdfExist);break;
+- case(NC_EINVAL):
+- return(rb_eNetcdfInval);break;
+- case(NC_EPERM):
+- return(rb_eNetcdfPerm);break;
+- case(NC_ENOTINDEFINE):
+- return(rb_eNetcdfNotindefine);break;
+- case(NC_EINDEFINE):
+- return(rb_eNetcdfIndefine);break;
+- case(NC_EINVALCOORDS):
+- return(rb_eNetcdfInvalcoords);break;
+- case(NC_EMAXDIMS):
+- return(rb_eNetcdfMaxdims);break;
+- case(NC_ENAMEINUSE):
+- return(rb_eNetcdfNameinuse);break;
+- case(NC_ENOTATT):
+- return(rb_eNetcdfNotatt);break;
+- case(NC_EMAXATTS):
+- return(rb_eNetcdfMaxatts);break;
+- case(NC_EBADTYPE):
+- return(rb_eNetcdfBadtype);break;
+- case(NC_EBADDIM):
+- return(rb_eNetcdfBaddim);break;
+- case(NC_EUNLIMPOS):
+- return(rb_eNetcdfUnlimpos);break;
+- case(NC_EMAXVARS):
+- return(rb_eNetcdfMaxvars);break;
+- case(NC_ENOTVAR):
+- return(rb_eNetcdfNotvar);break;
+- case(NC_EGLOBAL):
+- return(rb_eNetcdfGlobal);break;
+- case(NC_ENOTNC):
+- return(rb_eNetcdfNotnc);break;
+- case(NC_ESTS):
+- return(rb_eNetcdfSts);break;
+- case(NC_EMAXNAME):
+- return(rb_eNetcdfMaxname);break;
+- case(NC_EUNLIMIT):
+- return(rb_eNetcdfUnlimit);break;
+- case(NC_ENORECVARS):
+- return(rb_eNetcdfNorecvars);break;
+- case(NC_ECHAR):
+- return(rb_eNetcdfChar);break;
+- case(NC_EEDGE):
+- return(rb_eNetcdfEdge);break;
+- case(NC_ESTRIDE):
+- return(rb_eNetcdfStride);break;
+- case(NC_EBADNAME):
+- return(rb_eNetcdfBadname);break;
+- case(NC_ERANGE):
+- return(rb_eNetcdfRange);break;
+- case(NC_ENOMEM):
+- return(rb_eNetcdfNomem);break;
+- /* case(NC_ENTOOL):
+- return(rb_eNetcdfEntool);break; */
+- case(NC_EXDR):
+- return(rb_eNetcdfExdr);break;
+- case(NC_SYSERR):
+- return(rb_eNetcdfSyserr);break;
+- case(NC_FATAL):
+- return(rb_eNetcdfFatal);break;
+- }
+- return rb_eNetcdfError;
+-}
+-
+-static const char*
+-nctype2natype(int nctype){
+- switch(nctype){
+- case NC_CHAR:
+- return("char");
+- case NC_BYTE:
+- return("byte");
+- case NC_SHORT:
+- return("sint");
+- case NC_INT:
+- return("int");
+- case NC_FLOAT:
+- return("sfloat");
+- case NC_DOUBLE:
+- return("float");
+- default:
+- rb_raise(rb_eNetcdfError, "No such netcdf type number %d\n",nctype);
+- }
+-}
+-
+-static int
+-nctype2natypecode(int nctype){
+- switch(nctype){
+- case NC_CHAR:
+- return(NA_BYTE);
+- case NC_BYTE:
+- return(NA_BYTE);
+- case NC_SHORT:
+- return(NA_SINT);
+- case NC_INT:
+- return(NA_LINT);
+- case NC_FLOAT:
+- return(NA_SFLOAT);
+- case NC_DOUBLE:
+- return(NA_DFLOAT);
+- default:
+- rb_raise(rb_eNetcdfError, "No such netcdf type number %d\n",nctype);
+- }
+-}
+-
+-static int
+-natype2nctype(char *natype)
+-{
+- if(strcmp(natype,"byte")==0) return(NC_BYTE);
+- else if(strcmp(natype,"char")==0) return(NC_CHAR);
+- else if(strcmp(natype,"text")==0) return(NC_CHAR); /* alias of char */
+- else if(strcmp(natype,"string")==0) return(NC_CHAR); /* alias of char */
+- else if(strcmp(natype,"sint")==0) return(NC_SHORT);
+- else if(strcmp(natype,"int")==0) return(NC_INT);
+- else if(strcmp(natype,"sfloat")==0) return(NC_FLOAT);
+- else if(strcmp(natype,"float")==0) return(NC_DOUBLE);
+- else rb_raise(rb_eNetcdfError, "No such NArray type '%s'",natype);
+-}
+-
+-static int
+-natypecode2nctype(int natypecode)
+-{
+- if(natypecode==NA_BYTE) return(NC_BYTE);
+- else if(natypecode==NA_SINT) return(NC_SHORT);
+- else if(natypecode==NA_LINT) return(NC_INT);
+- else if(natypecode==NA_SFLOAT) return(NC_FLOAT);
+- else if(natypecode==NA_DFLOAT) return(NC_DOUBLE);
+- else rb_raise(rb_eNetcdfError, "No such NArray typecode '%d'",natypecode);
+-}
+-
+-static void
+-nc_mark_obj(struct NetCDFVar *netcdf_var)
+-{
+- VALUE ptr;
+-
+- ptr = netcdf_var->file;
+- rb_gc_mark(ptr);
+-}
+-
+-
+-VALUE
+-NetCDF_clone(VALUE file)
+-{
+- VALUE clone;
+- struct Netcdf *nc1, *nc2;
+-
+- Data_Get_Struct(file, struct Netcdf, nc1);
+- nc2 = NetCDF_init(nc1->ncid, nc1->name);
+- clone = Data_Wrap_Struct(cNetCDF, 0, NetCDF_free, nc2);
+- CLONESETUP(clone, file);
+- return clone;
+-}
+-
+-VALUE
+-NetCDF_dim_clone(VALUE dim)
+-{
+- VALUE clone;
+- struct NetCDFDim *nd1, *nd2;
+-
+- Data_Get_Struct(dim, struct NetCDFDim, nd1);
+- nd2 = NetCDF_dim_init(nd1->ncid, nd1->dimid);
+- clone = Data_Wrap_Struct(cNetCDFDim, 0, NetCDF_dim_free, nd2);
+- CLONESETUP(clone, dim);
+- return clone;
+-}
+-
+-VALUE
+-NetCDF_att_clone(VALUE att)
+-{
+- VALUE clone;
+- struct NetCDFAtt *na1, *na2;
+-
+- Data_Get_Struct(att, struct NetCDFAtt, na1);
+- na2 = NetCDF_att_init(na1->ncid, na1->varid, na1->name);
+- clone = Data_Wrap_Struct(cNetCDFAtt, 0, Netcdf_att_free, na2);
+- CLONESETUP(clone, att);
+- return clone;
+-}
+-
+-VALUE
+-NetCDF_var_clone(VALUE var)
+-{
+- VALUE clone;
+- struct NetCDFVar *nv1, *nv2;
+-
+- Data_Get_Struct(var, struct NetCDFVar, nv1);
+- nv2 = NetCDF_var_init(nv1->ncid, nv1->varid, nv1->file);
+- clone = Data_Wrap_Struct(cNetCDFVar, nc_mark_obj, NetCDF_var_free, nv2);
+- CLONESETUP(clone, var);
+- return clone;
+-}
+-
+-VALUE
+-NetCDF_inq_libvers(VALUE mod)
+-{
+- VALUE str;
+- str = rb_str_new2(nc_inq_libvers());
+- return(str);
+-}
+-
+-VALUE
+-NetCDF_close(file)
+- VALUE file;
+-{
+- int status;
+- int ncid;
+- struct Netcdf *Netcdffile;
+-
+- if (rb_safe_level() >= 3 && !OBJ_TAINTED(file)) {
+- rb_raise(rb_eSecurityError, "Insecure: can't close");
+- }
+- Data_Get_Struct(file,struct Netcdf,Netcdffile);
+- ncid=Netcdffile->ncid;
+- if(!Netcdffile->closed){
+- status = nc_close(ncid);
+- if(status != NC_NOERR) NC_RAISE(status);
+- Netcdffile->closed = 1;
+- } else {
+- rb_warn("file %s is already closed", Netcdffile->name);
+- }
+- return Qnil;
+-}
+-
+-VALUE
+-NetCDF_def_dim(VALUE file,VALUE dim_name,VALUE length)
+-{
+- char* c_dim_name;
+- size_t c_length;
+- int ncid;
+- int dimidp;
+- int status;
+- struct Netcdf *Netcdffile;
+- struct NetCDFDim *Netcdf_dim;
+- VALUE Dimension;
+-
+- rb_secure(3);
+- Data_Get_Struct(file,struct Netcdf,Netcdffile);
+-
+- Check_Type(dim_name,T_STRING);
+- c_dim_name=RSTRING_PTR(dim_name);
+- c_length=NUM2UINT(length);
+- ncid=Netcdffile->ncid;
+-
+- status = nc_def_dim(ncid,c_dim_name,c_length,&dimidp);
+- if(status !=NC_NOERR) NC_RAISE(status);
+-
+- Netcdf_dim = NetCDF_dim_init(ncid,dimidp);
+-
+- Dimension = Data_Wrap_Struct(cNetCDFDim,0,NetCDF_dim_free,Netcdf_dim);
+- return Dimension;
+-}
+-
+-
+-static VALUE
+-NetCDF_put_att_char(int ncid, char *name,VALUE value,VALUE atttype, int varid)
+-{
+- int status;
+- struct NetCDFAtt *ncatt;
+-
+- /* check atttype (not necessarily needed but it's better to do it) */
+- if (TYPE(atttype) == T_STRING){
+- if ( natype2nctype(RSTRING_PTR(atttype)) != NC_CHAR ) {
+- rb_raise(rb_eNetcdfError,
+- "attribute type must be 'char' (or nil) for a String value");
+- }
+- } else if (TYPE(atttype) != T_NIL) {
+- rb_raise(rb_eNetcdfError,
+- "type specfication must be by a string or nil");
+- }
+- /* put value */
+- Check_Type(value,T_STRING);
+- status = nc_put_att_text(ncid, varid, name,
+- RSTRING_LEN(value), RSTRING_PTR(value));
+- if(status != NC_NOERR) NC_RAISE(status);
+-
+- ncatt = NetCDF_att_init(ncid,varid,name);
+- return (Data_Wrap_Struct(cNetCDFAtt,0,Netcdf_att_free,ncatt));
+-}
+-
+-static VALUE
+-NetCDF_put_att_numeric(int ncid, char *name,VALUE value,VALUE atttype, int varid)
+-{
+- VALUE val;
+- struct NARRAY *na_val;
+- int na_typecode, status, len;
+- char *ptr;
+- struct NetCDFAtt *ncatt;
+-
+- /* check atttype and cast to an appropriate NArray if needed */
+-
+- if (TYPE(atttype) != T_NIL){
+- na_typecode = na_get_typecode(atttype);
+- GetNArray( na_cast_object(value, na_typecode), na_val );
+- } else {
+- if (TYPE(value)==T_ARRAY) {
+- val = RARRAY_PTR(value)[0]; /* to check the 1st elemnt if Array */
+- } else {
+- val = value;
+- }
+- switch(TYPE(val)){
+- case T_FIXNUM:
+- case T_BIGNUM:
+- na_typecode = NA_LINT;
+- GetNArray( na_cast_object(value, na_typecode), na_val );
+- break;
+- case T_FLOAT:
+- na_typecode = NA_DFLOAT;
+- GetNArray( na_cast_object(value, na_typecode), na_val );
+- break;
+- case T_DATA:
+- if ( IsNArray(value) ){
+- GetNArray(value,na_val);
+- na_typecode = na_val->type;
+- } else {
+- rb_raise(rb_eNetcdfError,"value has a wrong data type");
+- }
+- break;
+- default:
+- rb_raise(rb_eNetcdfError,
+- "value (or its first element) has a wrong type");
+- }
+- }
+-
+- /* put value */
+-
+- len = na_val->total;
+- ptr = na_val->ptr;
+- switch(na_typecode){
+- case NA_BYTE:
+- status = nc_put_att_uchar(ncid,varid,name,NC_BYTE,len,(unsigned char *)ptr);
+- break;
+- case NA_SINT:
+- status = nc_put_att_short(ncid,varid,name,NC_SHORT,len,(short *)ptr);
+- break;
+- case NA_LINT:
+- status = nc_put_att_int(ncid,varid,name,NC_INT,len,(int *)ptr);
+- break;
+- case NA_SFLOAT:
+- status = nc_put_att_float(ncid,varid,name,NC_FLOAT,len,(float *)ptr);
+- break;
+- case NA_DFLOAT:
+- status = nc_put_att_double(ncid,varid,name,NC_DOUBLE,len,(double*)ptr);
+- break;
+- default:
+- rb_raise(rb_eNetcdfError,
+- "unsupported type. code = %d",na_typecode);
+- }
+- if(status != NC_NOERR) NC_RAISE(status);
+-
+- ncatt = NetCDF_att_init(ncid,varid,name);
+- return (Data_Wrap_Struct(cNetCDFAtt,0,Netcdf_att_free,ncatt));
+-}
+-
+-static VALUE
+-NetCDF_put_att__(int ncid, char *name, VALUE value, VALUE atttype, int varid)
+- /*
+- * atttype: nil or a String ("string","int",etc). If nil,
+- * the type of attribute is determined from the type of value
+- */
+-{
+- switch(TYPE(value)){
+- case T_STRING:
+- return(NetCDF_put_att_char(ncid, name, value, atttype, varid));
+- default:
+- return(NetCDF_put_att_numeric(ncid, name, value, atttype, varid));
+- }
+-}
+-
+-VALUE
+-NetCDF_put_att(VALUE file,VALUE att_name,VALUE value,VALUE atttype)
+- /*
+- * atttype: nil or a String ("string","int",etc). If nil,
+- * the type of attribute is determined from the type of value
+- */
+-{
+- struct Netcdf *ncfile;
+- char *name;
+-
+- rb_secure(3);
+- Data_Get_Struct(file,struct Netcdf,ncfile);
+- Check_Type(att_name,T_STRING);
+- name = RSTRING_PTR(att_name);
+-
+- return( NetCDF_put_att__(ncfile->ncid, name, value, atttype, NC_GLOBAL) );
+-}
+-
+-VALUE
+-NetCDF_put_att_var(VALUE var,VALUE att_name,VALUE value,VALUE atttype)
+- /*
+- * atttype: nil or a String ("string","int",etc). If nil,
+- * the type of attribute is determined from the type of value
+- */
+-{
+- struct NetCDFVar *ncvar;
+- char *name;
+-
+- rb_secure(3);
+- Data_Get_Struct(var,struct NetCDFVar,ncvar);
+- Check_Type(att_name,T_STRING);
+- name = RSTRING_PTR(att_name);
+-
+- return( NetCDF_put_att__(ncvar->ncid, name, value, atttype, ncvar->varid));
+-}
+-
+-
+-VALUE
+-NetCDF_def_var(VALUE file,VALUE var_name,VALUE vartype,VALUE dimensions)
+-{
+- int ncid;
+- char *c_var_name;
+- static int xtype;
+- long c_ndims;
+- int varidp;
+- int dimidp;
+- int i=0;
+- int status;
+- char *c_dim_name;
+- int c_dimids[NC_MAX_DIMS];
+- struct Netcdf *Netcdffile;
+- struct NetCDFVar *Netcdf_var;
+- struct NetCDFDim *Netcdf_dim;
+- VALUE Var;
+-
+- rb_secure(3);
+- Check_Type(var_name,T_STRING);
+- Check_Type(dimensions,T_ARRAY);
+-
+- c_var_name=RSTRING_PTR(var_name);
+- c_ndims=RARRAY_LEN(dimensions);
+-
+- Data_Get_Struct(file,struct Netcdf,Netcdffile);
+- ncid=Netcdffile->ncid;
+-
+- if (TYPE(vartype) == T_STRING){
+- xtype = natype2nctype(RSTRING_PTR(vartype));
+- } else if (TYPE(vartype) == T_FIXNUM){
+- xtype = natypecode2nctype(NUM2INT(vartype));
+- } else {
+- rb_raise(rb_eNetcdfError,
+- "type specfication must be by a string or nil");
+- }
+-
+- for(i=0;i<c_ndims;i++){
+- switch(TYPE(RARRAY_PTR(dimensions)[c_ndims-1-i])){
+- case T_STRING:
+- Check_Type(RARRAY_PTR(dimensions)[c_ndims-1-i],T_STRING);
+- c_dim_name=StringValueCStr(RARRAY_PTR(dimensions)[c_ndims-1-i]);
+- status=nc_inq_dimid(ncid,c_dim_name,&dimidp);
+- if(status != NC_NOERR) NC_RAISE(status);
+- c_dimids[i]=dimidp;
+- break;
+- case T_DATA:
+- Data_Get_Struct(RARRAY_PTR(dimensions)[c_ndims-1-i],struct NetCDFDim,Netcdf_dim);
+- c_dimids[i]=Netcdf_dim->dimid;
+- break;
+- default:
+- rb_raise(rb_eNetcdfError, "No such object of the netCDF dimension class.");
+- }
+- }
+-
+- status = nc_def_var(ncid,c_var_name,xtype,c_ndims,c_dimids,&varidp);
+- if(status != NC_NOERR) NC_RAISE(status);
+-
+- Netcdf_var = NetCDF_var_init(ncid,varidp,file);
+-
+- Var=Data_Wrap_Struct(cNetCDFVar,nc_mark_obj,NetCDF_var_free,Netcdf_var);
+- return Var;
+-}
+-
+-VALUE
+-NetCDF_dim(VALUE file,VALUE dim_name)
+-{
+- int ncid;
+- char *c_dim_name;
+- int dimidp;
+- int status;
+- struct Netcdf *Netcdffile;
+- struct NetCDFDim *Netcdf_dim;
+- VALUE Dimension;
+-
+- Data_Get_Struct(file,struct Netcdf,Netcdffile);
+- ncid=Netcdffile->ncid;
+- Check_Type(dim_name,T_STRING);
+- c_dim_name=RSTRING_PTR(dim_name);
+-
+- status = nc_inq_dimid(ncid,c_dim_name,&dimidp);
+- if(status !=NC_NOERR){
+- if(status == NC_EBADDIM){
+- return(Qnil); /*2003/08/27 back to orig (from changes on 2003/02/03)*/
+- } else{
+- NC_RAISE(status);
+- }
+- }
+-
+- Netcdf_dim=NetCDF_dim_init(ncid,dimidp);
+-
+- Dimension = Data_Wrap_Struct(cNetCDFDim,0,NetCDF_dim_free,Netcdf_dim);
+- return Dimension;
+-}
+-
+-VALUE
+-NetCDF_var(VALUE file,VALUE var_name)
+-{
+- int ncid;
+- int status;
+- int varidp;
+- char *c_var_name;
+- struct Netcdf *Netcdffile;
+- struct NetCDFVar *Netcdf_var;
+- VALUE Variable;
+-
+- Data_Get_Struct(file,struct Netcdf,Netcdffile);
+- ncid=Netcdffile->ncid;
+- Check_Type(var_name,T_STRING);
+- c_var_name=RSTRING_PTR(var_name);
+-
+- status=nc_inq_varid(ncid,c_var_name,&varidp);
+- if(status != NC_NOERR){
+- if(status == NC_ENOTVAR){
+- return(Qnil); /*2003/08/27 back to orig (from changes on 2003/02/03)*/
+- } else{
+- NC_RAISE(status);
+- }
+- }
+-
+- Netcdf_var = NetCDF_var_init(ncid,varidp,file);
+- Variable = Data_Wrap_Struct(cNetCDFVar,nc_mark_obj,NetCDF_var_free,Netcdf_var);
+- return Variable;
+-}
+-
+-VALUE
+-NetCDF_att(VALUE file,VALUE att_name)
+-{
+- int ncid;
+- int status;
+- int attnump;
+- char *c_att_name;
+- struct Netcdf *Netcdffile;
+- struct NetCDFAtt *Netcdf_att;
+- VALUE Attribute;
+-
+- Data_Get_Struct(file,struct Netcdf,Netcdffile);
+- ncid=Netcdffile->ncid;
+- Check_Type(att_name,T_STRING);
+- c_att_name=RSTRING_PTR(att_name);
+-
+-
+- status = nc_inq_attid(ncid,NC_GLOBAL,c_att_name,&attnump);
+- if(status != NC_NOERR){
+- if(status == NC_ENOTATT){
+- return(Qnil);
+- }
+- else{
+- NC_RAISE(status);
+- }
+- }
+-
+- Netcdf_att = NetCDF_att_init(ncid,NC_GLOBAL,c_att_name);
+-
+- Attribute = Data_Wrap_Struct(cNetCDFAtt,0,Netcdf_att_free,Netcdf_att);
+-
+- return Attribute;
+-}
+-VALUE
+-NetCDF_fill(VALUE file,VALUE mode)
+-{
+- int ncid;
+- int status;
+- struct Netcdf *Netcdffile;
+- int old_modep;
+-
+- Data_Get_Struct(file,struct Netcdf,Netcdffile);
+- ncid = Netcdffile->ncid;
+- if(mode==Qfalse){
+- status = nc_set_fill(ncid,NC_NOFILL,&old_modep);
+- if(status != NC_NOERR) NC_RAISE(status);
+- }
+- else if(mode == Qtrue){
+- status = nc_set_fill(ncid,NC_FILL,&old_modep);
+- if(status != NC_NOERR) NC_RAISE(status);
+- }
+- else
+- rb_raise(rb_eNetcdfError,"Usage:self.fill(true) or self.fill(false)");
+- return Qnil;
+-}
+-
+-VALUE
+-NetCDF_redef(VALUE file)
+-{
+- int ncid;
+- int status;
+- struct Netcdf *Netcdffile;
+-
+- rb_secure(3);
+- Data_Get_Struct(file,struct Netcdf,Netcdffile);
+- ncid=Netcdffile->ncid;
+- status = nc_redef(ncid);
+- if(status !=NC_NOERR){
+- if(status == NC_EINDEFINE){
+- return Qnil;
+- }
+- else{
+- NC_RAISE(status);
+- }
+- }
+- return Qtrue;
+-}
+-
+-VALUE
+-NetCDF_enddef(VALUE file)
+-{
+- int ncid;
+- int status;
+- struct Netcdf *Netcdffile;
+-
+- rb_secure(3);
+- Data_Get_Struct(file,struct Netcdf,Netcdffile);
+- ncid=Netcdffile->ncid;
+- status = nc_enddef(ncid);
+- if(status !=NC_NOERR){
+- if(status == NC_ENOTINDEFINE){
+- return Qnil;
+- }
+- else{
+- NC_RAISE(status);
+- }
+- }
+- return Qtrue;
+-}
+-
+-VALUE
+-NetCDF_whether_in_define_mode(VALUE file)
+-{
+- /* returns true if the NetCDF object is currently in the define mode,
+- false if in the data mode, and
+- nil if else (possibly the file is read-only, or some other
+- error occurred)
+- */
+- int ncid;
+- int status;
+- struct Netcdf *Netcdffile;
+-
+- rb_secure(3);
+- Data_Get_Struct(file,struct Netcdf,Netcdffile);
+- ncid=Netcdffile->ncid;
+- status = nc_redef(ncid);
+- if(status == NC_EINDEFINE){
+- return Qtrue;
+- } else if(status == NC_NOERR) {
+- /* was in the data mode --> recover the data mode and report false */
+- status = nc_enddef(ncid);
+- if(status == NC_NOERR) {
+- return Qfalse;
+- } else {
+- return Qnil;
+- }
+- } else {
+- return Qnil;
+- }
+-}
+-
+-VALUE
+-NetCDF_open(VALUE mod,VALUE filename,VALUE omode)
+-{
+- int status;
+- int ncid;
+- char* c_filename;
+- int c_omode;
+- struct Netcdf *ncfile;
+- VALUE retval;
+-
+- Check_Type(filename,T_STRING);
+- SafeStringValue(filename);
+- c_filename=RSTRING_PTR(filename);
+- Check_Type(omode,T_FIXNUM);
+- c_omode=NUM2INT(omode);
+-
+- status = nc_open(c_filename,c_omode,&ncid);
+- if(status !=NC_NOERR){NC_RAISE2(status,c_filename);}
+-
+- ncfile = NetCDF_init(ncid,c_filename);
+- retval = Data_Wrap_Struct(cNetCDF,0,NetCDF_free,ncfile);
+- return( retval );
+-}
+-
+-VALUE
+-NetCDF_create(VALUE mod,VALUE filename,VALUE cmode)
+-{
+- int ncid;
+- int status;
+- char* c_filename;
+- int c_cmode;
+- struct Netcdf *ncfile;
+-
+- Check_Type(filename,T_STRING);
+- SafeStringValue(filename);
+- c_filename=RSTRING_PTR(filename);
+- Check_Type(cmode,T_FIXNUM);
+- c_cmode=NUM2INT(cmode);
+-
+- status = nc_create(c_filename,c_cmode,&ncid);
+- if(status != NC_NOERR) NC_RAISE2(status, c_filename);
+-
+- ncfile = NetCDF_init(ncid,c_filename);
+- return( Data_Wrap_Struct(cNetCDF,0,NetCDF_free,ncfile) );
+-}
+-
+-VALUE
+-NetCDF_ndims(VALUE file)
+-{
+- int ncid;
+- int ndimsp;
+- VALUE Integer;
+- int status;
+- struct Netcdf *ncfile;
+-
+- Data_Get_Struct(file,struct Netcdf,ncfile);
+- ncid=ncfile->ncid;
+- status = nc_inq_ndims(ncid,&ndimsp);
+- if(status != NC_NOERR) NC_RAISE (status);
+- Integer = INT2NUM(ndimsp);
+- return Integer;
+-}
+-
+-VALUE
+-NetCDF_nvars(VALUE file)
+-{
+- int ncid;
+- int nvarsp;
+- int status;
+- VALUE Integer;
+- struct Netcdf *ncfile;
+- Data_Get_Struct(file,struct Netcdf,ncfile);
+- ncid=ncfile->ncid;
+- status = nc_inq_nvars(ncid,&nvarsp);
+- if(status != NC_NOERR) NC_RAISE (status);
+- Integer = INT2NUM(nvarsp);
+- return Integer;
+-}
+-
+-VALUE
+-NetCDF_natts(VALUE file)
+-{
+- int ncid;
+- int nattsp;
+- int status;
+- VALUE Integer;
+- struct Netcdf *ncfile;
+-
+- Data_Get_Struct(file,struct Netcdf,ncfile);
+- ncid=ncfile->ncid;
+- status=nc_inq_natts(ncid,&nattsp);
+- if(status != NC_NOERR) NC_RAISE (status);
+- Integer = INT2NUM(nattsp);
+- return Integer;
+-}
+-
+-VALUE
+-NetCDF_unlimited(VALUE file)
+-{
+- int ncid;
+- int unlimdimidp;
+- int status;
+- struct Netcdf *ncfile;
+- struct NetCDFDim *Netcdf_dim;
+- VALUE Dimension;
+-
+- Data_Get_Struct(file,struct Netcdf,ncfile);
+- ncid=ncfile->ncid;
+- status=nc_inq_unlimdim(ncid,&unlimdimidp);
+- if(status !=NC_NOERR) NC_RAISE(status);
+-
+- Netcdf_dim = NetCDF_dim_init(ncid,unlimdimidp);
+-
+- /* If unlimdimidp=-1,No unlimited dimension is defined in the netCDF dataset */
+- if(unlimdimidp != -1)
+- {
+- Dimension = Data_Wrap_Struct(cNetCDFDim,0,NetCDF_dim_free,Netcdf_dim);
+- return Dimension;
+- }
+- else
+- {
+- return Qnil;
+- }
+-}
+-
+-VALUE
+-NetCDF_sync(VALUE file)
+-{
+- int ncid;
+- int status;
+- struct Netcdf *ncfile;
+-
+- rb_secure(3);
+- Data_Get_Struct(file,struct Netcdf,ncfile);
+- ncid=ncfile->ncid;
+- status = nc_sync(ncid);
+- if(status !=NC_NOERR) NC_RAISE (status);
+- return Qnil;
+-}
+-
+-VALUE
+-NetCDF_path(VALUE file)
+-{
+- char *path;
+- struct Netcdf *ncfile;
+-
+- Data_Get_Struct(file,struct Netcdf,ncfile);
+- path=ncfile->name;
+- return(rb_str_new2(path));
+-}
+-
+-VALUE
+-NetCDF_dim_length(VALUE Dim)
+-{
+- int ncid;
+- int status;
+- int dimid;
+- size_t lengthp;
+- struct NetCDFDim *Netcdf_dim;
+-
+- Data_Get_Struct(Dim,struct NetCDFDim,Netcdf_dim);
+- ncid=Netcdf_dim->ncid;
+- dimid=Netcdf_dim->dimid;
+-
+- status = nc_inq_dimlen(ncid,dimid,&lengthp);
+- if(status != NC_NOERR) NC_RAISE(status);
+-
+- return(INT2NUM(lengthp));
+-}
+-
+-VALUE
+-NetCDF_dim_name(VALUE Dim,VALUE dimension_newname)
+-{
+- int ncid;
+- int status;
+- int dimid;
+- char *c_dim_name;
+- struct NetCDFDim *Netcdf_dim;
+-
+- rb_secure(3);
+- Data_Get_Struct(Dim,struct NetCDFDim,Netcdf_dim);
+- ncid=Netcdf_dim->ncid;
+- dimid=Netcdf_dim->dimid;
+- Check_Type(dimension_newname,T_STRING);
+- c_dim_name = StringValueCStr(dimension_newname);
+-
+- status = nc_rename_dim(ncid,dimid,c_dim_name);
+- if(status !=NC_NOERR) NC_RAISE(status);
+-
+- return Qnil;
+-}
+-
+-VALUE
+-NetCDF_dim_inqname(VALUE Dim)
+-{
+- int ncid;
+- int status;
+- int dimid;
+- char c_dim_name[NC_MAX_NAME];
+- struct NetCDFDim *Netcdf_dim;
+- VALUE str;
+-
+- Data_Get_Struct(Dim,struct NetCDFDim,Netcdf_dim);
+- ncid=Netcdf_dim->ncid;
+- dimid=Netcdf_dim->dimid;
+-
+- status = nc_inq_dimname(ncid,dimid,c_dim_name);
+- if(status !=NC_NOERR) NC_RAISE(status);
+-
+- str = rb_str_new2(c_dim_name);
+- OBJ_TAINT(str);
+- return(str);
+-}
+-
+-VALUE
+-NetCDF_dim_whether_unlimited(VALUE Dim)
+-{
+- int status;
+- int uldid;
+- struct NetCDFDim *Netcdf_dim;
+-
+- Data_Get_Struct(Dim,struct NetCDFDim,Netcdf_dim);
+- status=nc_inq_unlimdim(Netcdf_dim->ncid,&uldid);
+- if(status !=NC_NOERR) NC_RAISE(status);
+- if(Netcdf_dim->dimid == uldid){
+- return(Qtrue);
+- } else {
+- return(Qfalse);
+- }
+-}
+-
+-VALUE
+-NetCDF_att_inq_name(VALUE Att)
+-{
+- char *c_att_name;
+- struct NetCDFAtt *Netcdf_att;
+- VALUE str;
+-
+- Data_Get_Struct(Att,struct NetCDFAtt,Netcdf_att);
+- c_att_name=Netcdf_att->name;
+-
+- str = rb_str_new2(c_att_name);
+- OBJ_TAINT(str);
+- return(str);
+-}
+-
+-VALUE
+-NetCDF_att_rename(VALUE Att,VALUE new_att_name)
+-{
+- int ncid;
+- int status;
+- int varid;
+- char *c_att_name;
+- char *c_new_att_name;
+- struct NetCDFAtt *Netcdf_att;
+- Data_Get_Struct(Att,struct NetCDFAtt,Netcdf_att);
+- ncid=Netcdf_att->ncid;
+- varid=Netcdf_att->varid;
+-
+- c_att_name=Netcdf_att->name;
+-
+- Check_Type(new_att_name,T_STRING);
+- SafeStringValue(new_att_name);
+- c_new_att_name=StringValueCStr(new_att_name);
+-
+- status = nc_rename_att(ncid,varid,c_att_name,c_new_att_name);
+- if(status != NC_NOERR) NC_RAISE(status);
+-
+- strcpy(Netcdf_att->name,c_new_att_name);
+- return Qnil;
+-}
+-
+-VALUE
+-NetCDF_id2dim(VALUE file,VALUE dimid)
+-{
+- int ncid;
+- int c_dimid;
+- struct Netcdf *ncfile;
+- struct NetCDFDim *Netcdf_dim;
+- VALUE Dim;
+-
+- Data_Get_Struct(file,struct Netcdf,ncfile);
+- ncid=ncfile->ncid;
+- Check_Type(dimid,T_FIXNUM);
+- c_dimid=NUM2INT(dimid);
+- Netcdf_dim = NetCDF_dim_init(ncid,c_dimid);
+- Dim=Data_Wrap_Struct(cNetCDFDim,0,NetCDF_dim_free,Netcdf_dim);
+- return(Dim);
+-}
+-
+-VALUE
+-NetCDF_id2var(VALUE file,VALUE varid)
+-{
+- int ncid;
+- int c_varid;
+- struct Netcdf *ncfile;
+- struct NetCDFVar *Netcdf_var;
+- VALUE Var;
+-
+- Data_Get_Struct(file,struct Netcdf,ncfile);
+- ncid=ncfile->ncid;
+- Check_Type(varid,T_FIXNUM);
+- c_varid=NUM2INT(varid);
+- Netcdf_var = NetCDF_var_init(ncid,c_varid,file);
+- Var=Data_Wrap_Struct(cNetCDFVar,nc_mark_obj,NetCDF_var_free,Netcdf_var);
+- return(Var);
+-}
+-
+-
+-VALUE
+-NetCDF_id2att(VALUE file,VALUE attnum)
+-{
+- int ncid;
+- int c_attnum;
+- int status;
+- struct Netcdf *ncfile;
+- struct NetCDFAtt *Netcdf_att;
+- char *c_att_name;
+- VALUE Att;
+- c_att_name=ALLOCA_N(char,NC_MAX_NAME);
+-
+- Data_Get_Struct(file,struct Netcdf,ncfile);
+- ncid=ncfile->ncid;
+-
+- Check_Type(attnum,T_FIXNUM);
+- c_attnum=NUM2INT(attnum);
+-
+- status = nc_inq_attname(ncid,NC_GLOBAL,c_attnum,c_att_name);
+- if(status != NC_NOERR) NC_RAISE(status);
+-
+- Netcdf_att=NetCDF_att_init(ncid,NC_GLOBAL,c_att_name);
+-
+- Att=Data_Wrap_Struct(cNetCDFAtt,0,Netcdf_att_free,Netcdf_att);
+- return(Att);
+-
+-}
+-
+-#if NCVER >= 400
+-/* USAGE
+- NetCDFVar#deflate(deflate_level, shuffle=false)
+- */
+-VALUE
+-NetCDF_var_deflate(int argc, VALUE *argv, VALUE Var)
+-{
+- int ncid, varid, status;
+- struct NetCDFVar *Netcdf_var;
+-
+- int shuffle;
+- /* If non-zero, turn on the shuffle filter.
+-
+- http://www.unidata.ucar.edu/software/netcdf/papers/AMS_2008.pdf :
+- The shuffle algorithm changes the byte order in the data stream;
+- when used with integers that are all close together, this
+- results in a better compression ratio. There is no benefit
+- from using the shuffle filter without also using
+- compression.
+-
+- MEMO by horinouchi: shuffling filter was also effective for float
+- variables in some test (demo5-netcdf4.rb).
+- */
+- int deflate_level;
+- int deflate=1;
+- /* Always set to non-zero:
+- See https://www.unidata.ucar.edu/software/netcdf/docs/netcdf-c/nc_005fdef_005fvar_005fdeflate.html#nc_005fdef_005fvar_005fdeflate
+- If non-zero, turn on the deflate filter at the
+- level specified by the deflate_level parameter.
+- */
+-
+- if (argc>2 || argc<1) rb_raise(rb_eArgError,
+- "wrong # of arguments (%d). It must be 1 or 2", argc);
+-
+- Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
+- ncid = Netcdf_var->ncid;
+- varid = Netcdf_var->varid;
+-
+- deflate_level = NUM2INT(argv[0]);
+-
+- if (argc==1) {
+- shuffle = 0; /* default: false */
+- } else {
+- if ( argv[1] == Qnil || argv[1] == Qfalse ) {
+- shuffle = 0;
+- } else {
+- shuffle = 1;
+- }
+- }
+-
+- status = nc_def_var_deflate(ncid, varid, shuffle, deflate, deflate_level);
+- if(status != NC_NOERR) NC_RAISE(status);
+-
+- return(Var);
+-}
+-
+-VALUE
+-NetCDF_var_deflate_params(VALUE Var)
+-{
+- int ncid, varid, status;
+- struct NetCDFVar *Netcdf_var;
+- int shufflep, deflatep, deflate_levelp;
+- VALUE sh, df, params;
+-
+- Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
+- ncid = Netcdf_var->ncid;
+- varid = Netcdf_var->varid;
+- status = nc_inq_var_deflate(ncid, varid, &shufflep, &deflatep,
+- &deflate_levelp);
+- if(status != NC_NOERR) NC_RAISE(status);
+- if (shufflep==0) {sh=Qfalse;} else {sh=Qtrue;}
+- if (deflatep==0) {df=Qfalse;} else {df=Qtrue;}
+- params = rb_ary_new3(3, sh, df, INT2NUM(deflate_levelp) );
+- return(params);
+-}
+-
+-VALUE
+-NetCDF_var_set_endian(VALUE Var, VALUE endian)
+-{
+- int ncid, varid, status;
+- struct NetCDFVar *Netcdf_var;
+-
+- Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
+- ncid = Netcdf_var->ncid;
+- varid = Netcdf_var->varid;
+- status = nc_def_var_endian(ncid, varid, NUM2INT(endian));
+- if(status != NC_NOERR) NC_RAISE(status);
+- return(Var);
+-}
+-
+-VALUE
+-NetCDF_var_endian(VALUE Var)
+-{
+- int ncid, varid, status;
+- struct NetCDFVar *Netcdf_var;
+- int endian;
+-
+- Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
+- ncid = Netcdf_var->ncid;
+- varid = Netcdf_var->varid;
+- status = nc_inq_var_endian(ncid, varid, &endian);
+- if(status != NC_NOERR) NC_RAISE(status);
+- return(INT2FIX(endian));
+-}
+-
+-#endif
+-
+-VALUE
+-NetCDF_var_id2att(VALUE Var,VALUE attnum)
+-{
+- int ncid;
+- int c_attnum;
+- int status;
+- int c_varid;
+- struct NetCDFVar *Netcdf_var;
+- struct NetCDFAtt *Netcdf_att;
+- char *c_att_name;
+- VALUE Att;
+-
+- Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
+- ncid=Netcdf_var->ncid;
+- c_varid=Netcdf_var->varid;
+-
+- Check_Type(attnum,T_FIXNUM);
+- c_attnum=NUM2INT(attnum);
+-
+- c_att_name=ALLOCA_N(char,NC_MAX_NAME);
+-
+- status = nc_inq_attname(ncid,c_varid,c_attnum,c_att_name);
+- if(status != NC_NOERR) NC_RAISE(status);
+-
+- Netcdf_att=NetCDF_att_init(ncid,c_varid,c_att_name);
+- Att=Data_Wrap_Struct(cNetCDFAtt,0,Netcdf_att_free,Netcdf_att);
+- return(Att);
+-}
+-
+-VALUE
+-NetCDF_var_dims(VALUE Var)
+-{
+- int ncid, *dimids, ndims, varid, i, status;
+- struct NetCDFVar *Netcdf_var;
+- struct NetCDFDim *Netcdf_dim;
+- VALUE Dims;
+-
+- Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
+- ncid = Netcdf_var->ncid;
+- varid = Netcdf_var->varid;
+- status = nc_inq_varndims(ncid,varid,&ndims);
+- if(status != NC_NOERR) NC_RAISE(status);
+- dimids=ALLOCA_N(int,ndims);
+- status = nc_inq_vardimid(ncid,varid,dimids);
+- if(status != NC_NOERR) NC_RAISE(status);
+- Dims = rb_ary_new();
+- for(i=0;i<ndims;i++){
+- Netcdf_dim = NetCDF_dim_init(ncid,dimids[ndims-1-i]);
+- rb_ary_push(Dims,
+- Data_Wrap_Struct(cNetCDFDim,0,NetCDF_dim_free,Netcdf_dim));
+- }
+- return(Dims);
+-}
+-
+-VALUE
+-NetCDF_var_dim(VALUE Var, VALUE ith)
+-{
+- int ncid, *dimids, ndims, varid, status, c_ith;
+- struct NetCDFVar *Netcdf_var;
+- struct NetCDFDim *Netcdf_dim;
+- VALUE Dim;
+-
+- Check_Type(ith,T_FIXNUM);
+- c_ith=NUM2INT(ith);
+- Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
+- ncid = Netcdf_var->ncid;
+- varid = Netcdf_var->varid;
+- status = nc_inq_varndims(ncid,varid,&ndims);
+- if(status != NC_NOERR) NC_RAISE(status);
+- if(c_ith < 0 || c_ith >= ndims) {
+- rb_raise(rb_eNetcdfError, "dimension count less than zero or greater than ndims-1");
+- }
+- dimids=ALLOCA_N(int,ndims);
+- status = nc_inq_vardimid(ncid,varid,dimids);
+- if(status != NC_NOERR) NC_RAISE(status);
+- Netcdf_dim = NetCDF_dim_init(ncid,dimids[ndims-1-c_ith]);
+- Dim = Data_Wrap_Struct(cNetCDFDim,0,NetCDF_dim_free,Netcdf_dim);
+- return(Dim);
+-}
+-
+-VALUE
+-NetCDF_att_copy(VALUE Att,VALUE Var_or_File)
+-{
+- int ncid_in,ncid_out;
+- int status;
+- int varid_in,varid_out;
+- char *att_name;
+- struct NetCDFAtt *Netcdf_att;
+- struct NetCDFVar *Netcdf_var;
+- struct Netcdf *ncfile;
+- struct NetCDFAtt *Netcdf_att_out;
+-
+- rb_secure(3);
+- Data_Get_Struct(Att,struct NetCDFAtt,Netcdf_att);
+- ncid_in=Netcdf_att->ncid;
+- varid_in=Netcdf_att->varid;
+- att_name=Netcdf_att->name;
+-
+- if( rb_obj_is_kind_of(Var_or_File, cNetCDFVar) ){
+- Data_Get_Struct(Var_or_File,struct NetCDFVar, Netcdf_var);
+- ncid_out=Netcdf_var->ncid;
+- varid_out=Netcdf_var->varid;
+- } else if ( rb_obj_is_kind_of(Var_or_File, cNetCDF) ){
+- Data_Get_Struct(Var_or_File,struct Netcdf, ncfile);
+- ncid_out=ncfile->ncid;
+- varid_out=NC_GLOBAL;
+- } else {
+- rb_raise(rb_eNetcdfError,"The argument must be a NetCDFVar or a NetCDF");
+- }
+-
+- status = nc_copy_att(ncid_in,varid_in,att_name,ncid_out,varid_out);
+- if(status != NC_NOERR) NC_RAISE(status);
+- Netcdf_att_out = NetCDF_att_init(ncid_out,varid_out,att_name);
+- return (Data_Wrap_Struct(cNetCDFAtt,0,Netcdf_att_free,Netcdf_att_out));
+-}
+-
+-VALUE
+-NetCDF_att_atttype(VALUE Att)
+-{
+- int ncid;
+- int varid;
+- int status;
+- char *att_name;
+- const char *Attname;
+- struct NetCDFAtt *Netcdf_att;
+- nc_type xtypep;
+-
+- Data_Get_Struct(Att,struct NetCDFAtt,Netcdf_att);
+- ncid = Netcdf_att->ncid;
+- varid = Netcdf_att->varid;
+- att_name = Netcdf_att->name;
+-
+- status = nc_inq_atttype(ncid,varid,att_name,&xtypep);
+- if(status != NC_NOERR) NC_RAISE(status);
+-
+- Attname = nctype2natype(xtypep);
+- return(rb_str_new2(Attname));
+-}
+-
+-VALUE
+-NetCDF_att_typecode(VALUE Att)
+-{
+- int ncid;
+- int varid;
+- int status;
+- char *att_name;
+- struct NetCDFAtt *Netcdf_att;
+- nc_type xtypep;
+-
+- Data_Get_Struct(Att,struct NetCDFAtt,Netcdf_att);
+- ncid = Netcdf_att->ncid;
+- varid = Netcdf_att->varid;
+- att_name = Netcdf_att->name;
+-
+- status = nc_inq_atttype(ncid,varid,att_name,&xtypep);
+- if(status != NC_NOERR) NC_RAISE(status);
+-
+- return(INT2NUM(nctype2natypecode(xtypep)));
+-}
+-
+-VALUE
+-NetCDF_att_delete(VALUE Att)
+-{
+- int ncid;
+- int status;
+- int varid;
+- char *c_att_name;
+- struct NetCDFAtt *Netcdf_att;
+-
+- rb_secure(3);
+- Data_Get_Struct(Att,struct NetCDFAtt,Netcdf_att);
+-
+- ncid=Netcdf_att->ncid;
+- varid=Netcdf_att->varid;
+- c_att_name=Netcdf_att->name;
+-
+- status = nc_del_att(ncid,varid,c_att_name);
+- if(status != NC_NOERR) NC_RAISE(status);
+-
+- return Qnil;
+-}
+-
+-VALUE
+-NetCDF_att_put(VALUE Att,VALUE value,VALUE atttype)
+- /*
+- * atttype: nil or a String ("string","int",etc). If nil,
+- * the type of attribute is determined from the type of value
+- */
+-{
+- struct NetCDFAtt *ncatt;
+-
+- rb_secure(3);
+- Data_Get_Struct(Att,struct NetCDFAtt,ncatt);
+- return( NetCDF_put_att__(ncatt->ncid, ncatt->name, value,
+- atttype, ncatt->varid) );
+-}
+-
+-VALUE
+-NetCDF_att_get(VALUE Att)
+-{
+- int ncid;
+- int varid;
+- char *c_attname;
+- int status;
+- struct NetCDFAtt *Netcdf_att;
+- nc_type xtypep;
+- size_t lenp;
+- na_shape_t attlen[1]; /* NArray uses int instead of size_t */
+- char *tp;
+- unsigned char *up;
+- short *sp;
+- int *ip;
+- float *fp;
+- double *dp;
+- VALUE NArray;
+- VALUE str;
+-
+- Data_Get_Struct(Att,struct NetCDFAtt,Netcdf_att);
+- ncid = Netcdf_att->ncid;
+- varid = Netcdf_att->varid;
+- c_attname = Netcdf_att->name;
+-
+- status = nc_inq_atttype(ncid,varid,c_attname,&xtypep);
+- if(status != NC_NOERR) NC_RAISE(status);
+-
+- switch(xtypep){
+- case NC_CHAR:
+- status = nc_inq_attlen(ncid,varid,c_attname,&lenp);
+- if(status != NC_NOERR) NC_RAISE(status);
+- tp = ALLOCA_N(char,lenp+1);
+- tp[lenp]= '\0';
+- status = nc_get_att_text(ncid,varid,c_attname,tp);
+- if(status != NC_NOERR) NC_RAISE(status);
+- str = rb_str_new2(tp);
+- OBJ_TAINT(str);
+- return(str);
+- break;
+- case NC_BYTE:
+- status = nc_inq_attlen(ncid,varid,c_attname,&lenp);
+- if(status != NC_NOERR) NC_RAISE(status);
+-
+- attlen[0]=lenp;
+- Cbyte_to_NArray(NArray,1,attlen,up);
+-
+- status = nc_get_att_uchar(ncid,varid,c_attname,up);
+- if(status != NC_NOERR) NC_RAISE(status);
+-
+- OBJ_TAINT(NArray);
+- return NArray;
+- break;
+- case NC_SHORT:
+- status = nc_inq_attlen(ncid,varid,c_attname,&lenp);
+- if(status != NC_NOERR) NC_RAISE(status);
+-
+- attlen[0]=lenp;
+- Csint_to_NArray(NArray,1,attlen,sp);
+-
+- status = nc_get_att_short(ncid,varid,c_attname,sp);
+- if(status != NC_NOERR) NC_RAISE(status);
+- OBJ_TAINT(NArray);
+- return NArray;
+- break;
+- case NC_INT:
+- status = nc_inq_attlen(ncid,varid,c_attname,&lenp);
+- if(status != NC_NOERR) NC_RAISE(status);
+-
+- attlen[0]=lenp;
+- Clint_to_NArray(NArray,1,attlen,ip);
+-
+- status = nc_get_att_int(ncid,varid,c_attname,ip);
+- if(status != NC_NOERR) NC_RAISE(status);
+-
+- OBJ_TAINT(NArray);
+- return NArray;
+- break;
+- case NC_FLOAT:
+- status = nc_inq_attlen(ncid,varid,c_attname,&lenp);
+- if(status != NC_NOERR) NC_RAISE(status);
+-
+- attlen[0]=lenp;
+- Cfloat_to_NArray(NArray,1,attlen,fp);
+-
+- status = nc_get_att_float(ncid,varid,c_attname,fp);
+- if(status != NC_NOERR) NC_RAISE(status);
+-
+- OBJ_TAINT(NArray);
+- return NArray;
+- break;
+- case NC_DOUBLE:
+- status = nc_inq_attlen(ncid,varid,c_attname,&lenp);
+- if(status != NC_NOERR) NC_RAISE(status);
+-
+- attlen[0]=lenp;
+- Cdouble_to_NArray(NArray,1,attlen,dp);
+-
+- status = nc_get_att_double(ncid,varid,c_attname,dp);
+- if(status != NC_NOERR) NC_RAISE(status);
+- OBJ_TAINT(NArray);
+- return NArray;
+- break;
+- default:
+- rb_raise(rb_eNetcdfError,"atttype isn't supported in netCDF");
+- }
+- return Qnil;
+-}
+-
+-
+-VALUE
+-NetCDF_var_inq_name(VALUE Var)
+-{
+- int ncid;
+- int status;
+- int varid;
+- char c_var_name[NC_MAX_NAME];
+- struct NetCDFVar *Netcdf_var;
+- VALUE Var_name;
+-
+- Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
+-
+- ncid=Netcdf_var->ncid;
+- varid=Netcdf_var->varid;
+- status = nc_inq_varname(ncid,varid,c_var_name);
+- if(status != NC_NOERR) NC_RAISE(status);
+-
+- Var_name=rb_str_new2(c_var_name);
+- OBJ_TAINT(Var_name);
+- return Var_name;
+-}
+-
+-VALUE
+-NetCDF_var_ndims(VALUE Var)
+-{
+- int ncid;
+- int status;
+- int varid;
+- int ndimsp;
+- struct NetCDFVar *Netcdf_var;
+- VALUE Var_ndims;
+-
+- Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
+-
+- ncid=Netcdf_var->ncid;
+- varid=Netcdf_var->varid;
+- status = nc_inq_varndims(ncid,varid,&ndimsp);
+- if(status != NC_NOERR) NC_RAISE(status);
+- Var_ndims=INT2FIX(ndimsp);
+- return Var_ndims;
+-}
+-
+-VALUE
+-NetCDF_var_vartype(VALUE Var)
+-{
+- int ncid;
+- int status;
+- int varid;
+- nc_type xtypep;
+- struct NetCDFVar *Netcdf_var;
+- const char *Vartype;
+-
+- Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
+-
+- ncid=Netcdf_var->ncid;
+- varid=Netcdf_var->varid;
+-
+- status = nc_inq_vartype(ncid,varid,&xtypep);
+- if(status != NC_NOERR) NC_RAISE(status);
+-
+- Vartype=nctype2natype(xtypep);
+- return(rb_str_new2(Vartype));
+-}
+-
+-VALUE
+-NetCDF_var_typecode(VALUE Var)
+-{
+- int ncid;
+- int status;
+- int varid;
+- nc_type xtypep;
+- struct NetCDFVar *Netcdf_var;
+-
+- Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
+-
+- ncid=Netcdf_var->ncid;
+- varid=Netcdf_var->varid;
+-
+- status = nc_inq_vartype(ncid,varid,&xtypep);
+- if(status != NC_NOERR) NC_RAISE(status);
+-
+- return(INT2NUM(nctype2natypecode(xtypep)));
+-}
+-
+-
+-VALUE
+-NetCDF_var_natts(VALUE Var)
+-{
+- int ncid;
+- int status;
+- int varid;
+- int nattsp;
+- struct NetCDFVar *Netcdf_var;
+- VALUE Var_natts;
+-
+-
+- Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
+-
+- ncid=Netcdf_var->ncid;
+- varid=Netcdf_var->varid;
+-
+- status= nc_inq_varnatts(ncid,varid,&nattsp);
+- if(status !=NC_NOERR) NC_RAISE(status);
+-
+- Var_natts=INT2FIX(nattsp);
+- return Var_natts;
+-}
+-
+-VALUE
+-NetCDF_var_file(VALUE Var)
+-{
+- struct NetCDFVar *Netcdf_var;
+- /* VALUE file; */
+- Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
+-
+- return (Netcdf_var->file);
+-}
+-
+-VALUE
+-NetCDF_var_rename(VALUE Var,VALUE var_new_name)
+-{
+- int ncid;
+- int status;
+- int varid;
+- char *c_var_new_name;
+- struct NetCDFVar *Netcdf_var;
+-
+- rb_secure(3);
+- Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
+- ncid=Netcdf_var->ncid;
+- varid=Netcdf_var->varid;
+-
+- Check_Type(var_new_name,T_STRING);
+- c_var_new_name=StringValueCStr(var_new_name);
+-
+- status = nc_rename_var(ncid,varid,c_var_new_name);
+- if(status !=NC_NOERR) NC_RAISE(status);
+-
+- return Qnil;
+-}
+-
+-VALUE
+-NetCDF_var_att(VALUE Var,VALUE att_name)
+-{
+- int ncid;
+- int status;
+- int varid;
+- char *c_att_name;
+- int c_attnump;
+- struct NetCDFVar *Netcdf_var;
+- struct NetCDFAtt *Netcdf_att;
+- VALUE Att;
+-
+- Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
+-
+- ncid=Netcdf_var->ncid;
+- varid=Netcdf_var->varid;
+-
+- Check_Type(att_name,T_STRING);
+- c_att_name=StringValueCStr(att_name);
+-
+- status = nc_inq_attid(ncid,varid,c_att_name,&c_attnump);
+- if(status == NC_NOERR){
+- Netcdf_att=NetCDF_att_init(ncid,varid,c_att_name);
+- Att=Data_Wrap_Struct(cNetCDFAtt,0,Netcdf_att_free,Netcdf_att);
+- return Att;
+- }
+- else if(status == NC_ENOTATT){
+- return Qnil;
+- }
+- else{
+- NC_RAISE(status);
+- return Qnil;
+- }
+-}
+-
+-/* Redifinition of the "==" and "eql?" methods */
+-
+-VALUE
+-NetCDF_eql(VALUE filea,VALUE fileb)
+-{
+- struct Netcdf *ncfilea;
+- struct Netcdf *ncfileb;
+-
+- if( rb_obj_is_kind_of(fileb, cNetCDF) ){
+- Data_Get_Struct(filea,struct Netcdf,ncfilea);
+- Data_Get_Struct(fileb,struct Netcdf,ncfileb);
+-
+- if(ncfilea->ncid == ncfileb->ncid &&
+- strcmp(ncfilea->name,ncfileb->name)==0){
+- return Qtrue;
+- } else {
+- return Qfalse;
+- }
+- } else {
+- return Qfalse;
+- }
+-}
+-
+-VALUE
+-NetCDF_var_eql(VALUE Vara,VALUE Varb)
+-{
+- struct NetCDFVar *Netcdf_vara;
+- struct NetCDFVar *Netcdf_varb;
+-
+- if( rb_obj_is_kind_of(Varb, cNetCDFVar) ){
+- Data_Get_Struct(Vara,struct NetCDFVar,Netcdf_vara);
+- Data_Get_Struct(Varb,struct NetCDFVar,Netcdf_varb);
+-
+- if(Netcdf_vara->ncid == Netcdf_varb->ncid &&
+- Netcdf_vara->varid == Netcdf_varb->varid){
+- return Qtrue;
+- } else {
+- return Qfalse;
+- }
+- } else {
+- return Qfalse;
+- }
+-}
+-
+-VALUE
+-NetCDF_dim_eql(VALUE Dima,VALUE Dimb)
+-{
+- struct NetCDFDim *Netcdf_dima;
+- struct NetCDFDim *Netcdf_dimb;
+-
+- if( rb_obj_is_kind_of(Dimb, cNetCDFDim) ){
+- Data_Get_Struct(Dima,struct NetCDFDim,Netcdf_dima);
+- Data_Get_Struct(Dimb,struct NetCDFDim,Netcdf_dimb);
+-
+- if(Netcdf_dima->ncid == Netcdf_dimb->ncid &&
+- Netcdf_dima->dimid == Netcdf_dimb->dimid){
+- return Qtrue;
+- } else {
+- return Qfalse;
+- }
+- } else {
+- return Qfalse;
+- }
+-}
+-
+-VALUE
+-NetCDF_att_eql(VALUE Atta,VALUE Attb)
+-{
+- struct NetCDFAtt *Netcdf_atta;
+- struct NetCDFAtt *Netcdf_attb;
+-
+- if( rb_obj_is_kind_of(Attb, cNetCDFAtt) ){
+- Data_Get_Struct(Atta,struct NetCDFAtt,Netcdf_atta);
+- Data_Get_Struct(Attb,struct NetCDFAtt,Netcdf_attb);
+-
+- if(Netcdf_atta->ncid == Netcdf_atta->ncid &&
+- Netcdf_atta->varid == Netcdf_attb->varid &&
+- strcmp(Netcdf_atta->name,Netcdf_attb->name)==0){
+- return Qtrue;
+- } else {
+- return Qfalse;
+- }
+- } else {
+- return Qfalse;
+- }
+-}
+-
+-/* Follow methods is to connect "NArray" with "Netcdf" */
+-VALUE
+-NetCDF_get_var_char(VALUE Var)
+-{
+- int ncid;
+- int varid;
+- int status;
+- unsigned char *ptr;
+- struct NetCDFVar *Netcdf_var;
+- int i=0;
+- int ndimsp;
+- int *dimids;
+- size_t lengthp;
+- na_shape_t *shape; /* NArray uses int instead of size_t */
+- VALUE NArray;
+-
+- Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
+- ncid = Netcdf_var->ncid;
+- varid = Netcdf_var->varid;
+- status = nc_inq_varndims(ncid,varid,&ndimsp);
+- if(status != NC_NOERR) NC_RAISE(status);
+- dimids = ALLOCA_N(int,ndimsp);
+- if (ndimsp != 0){
+- shape = ALLOCA_N(na_shape_t,ndimsp);
+- for(i=0;i<ndimsp;i++){
+- status = nc_inq_vardimid(ncid,varid,dimids);
+- if(status != NC_NOERR) NC_RAISE(status);
+- nc_inq_dimlen(ncid,dimids[i],&lengthp);
+- shape[ndimsp-1-i]=lengthp;
+- }
+- } else {
+- ndimsp = 1;
+- shape = ALLOCA_N(na_shape_t,1);
+- shape[0]=1;
+- }
+-
+- Cbyte_to_NArray(NArray,ndimsp,shape,ptr);
+-
+- status = nc_get_var_text(ncid,varid,(char *)ptr);
+- if(status != NC_NOERR) NC_RAISE(status);
+-
+- OBJ_TAINT(NArray);
+- return NArray;
+-}
+-
+-VALUE
+-NetCDF_get_var_byte(VALUE Var)
+-{
+- int ncid;
+- int varid;
+- int status;
+- unsigned char *ptr;
+- struct NetCDFVar *Netcdf_var;
+- int i=0;
+- int ndimsp;
+- int *dimids;
+- size_t lengthp;
+- na_shape_t *shape; /* NArray uses int instead of size_t */
+- VALUE NArray;
+-
+- Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
+- ncid = Netcdf_var->ncid;
+- varid = Netcdf_var->varid;
+- status = nc_inq_varndims(ncid,varid,&ndimsp);
+- if(status != NC_NOERR) NC_RAISE(status);
+- dimids = ALLOCA_N(int,ndimsp);
+- if (ndimsp != 0){
+- shape = ALLOCA_N(na_shape_t,ndimsp);
+- for(i=0;i<ndimsp;i++){
+- status = nc_inq_vardimid(ncid,varid,dimids);
+- if(status != NC_NOERR) NC_RAISE(status);
+- nc_inq_dimlen(ncid,dimids[i],&lengthp);
+- shape[ndimsp-1-i]=lengthp;
+- }
+- } else {
+- ndimsp = 1;
+- shape = ALLOCA_N(na_shape_t,1);
+- shape[0]=1;
+- }
+-
+- Cbyte_to_NArray(NArray,ndimsp,shape,ptr);
+-
+- status = nc_get_var_uchar(ncid,varid,ptr);
+- if(status != NC_NOERR) NC_RAISE(status);
+-
+- OBJ_TAINT(NArray);
+- return NArray;
+-}
+-
+-VALUE
+-NetCDF_get_var_sint(VALUE Var)
+-{
+- int ncid;
+- int varid;
+- int status;
+- short *ptr;
+- struct NetCDFVar *Netcdf_var;
+- int i=0;
+- int ndimsp;
+- int *dimids;
+- size_t lengthp;
+- na_shape_t *shape; /* NArray uses int instead of size_t */
+- VALUE NArray;
+-
+- Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
+- ncid = Netcdf_var->ncid;
+- varid = Netcdf_var->varid;
+- status = nc_inq_varndims(ncid,varid,&ndimsp);
+- if(status != NC_NOERR) NC_RAISE(status);
+- dimids = ALLOCA_N(int,ndimsp);
+- if (ndimsp != 0){
+- shape = ALLOCA_N(na_shape_t,ndimsp);
+- for(i=0;i<ndimsp;i++){
+- status = nc_inq_vardimid(ncid,varid,dimids);
+- if(status != NC_NOERR) NC_RAISE(status);
+- nc_inq_dimlen(ncid,dimids[i],&lengthp);
+- shape[ndimsp-1-i]=lengthp;
+- }
+- } else {
+- ndimsp = 1;
+- shape = ALLOCA_N(na_shape_t,1);
+- shape[0]=1;
+- }
+-
+- Csint_to_NArray(NArray,ndimsp,shape,ptr);
+-
+- status = nc_get_var_short(ncid,varid,ptr);
+- if(status != NC_NOERR) NC_RAISE(status);
+-
+- OBJ_TAINT(NArray);
+- return NArray;
+-}
+-
+-VALUE
+-NetCDF_get_var_int(VALUE Var)
+-{
+- int ncid;
+- int varid;
+- int status;
+- int *ptr;
+- struct NetCDFVar *Netcdf_var;
+- int i=0;
+- int ndimsp;
+- int *dimids;
+- size_t lengthp;
+- na_shape_t *shape; /* NArray uses int instead of size_t */
+- VALUE NArray;
+-
+- Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
+- ncid = Netcdf_var->ncid;
+- varid = Netcdf_var->varid;
+- status = nc_inq_varndims(ncid,varid,&ndimsp);
+- if(status != NC_NOERR) NC_RAISE(status);
+- dimids = ALLOCA_N(int,ndimsp);
+- if (ndimsp != 0){
+- shape = ALLOCA_N(na_shape_t,ndimsp);
+- for(i=0;i<ndimsp;i++){
+- status = nc_inq_vardimid(ncid,varid,dimids);
+- if(status != NC_NOERR) NC_RAISE(status);
+- nc_inq_dimlen(ncid,dimids[i],&lengthp);
+- shape[ndimsp-1-i]=lengthp;
+- }
+- } else {
+- ndimsp = 1;
+- shape = ALLOCA_N(na_shape_t,1);
+- shape[0]=1;
+- }
+-
+- Clint_to_NArray(NArray,ndimsp,shape,ptr);
+-
+- status = nc_get_var_int(ncid,varid,ptr);
+- if(status != NC_NOERR) NC_RAISE(status);
+-
+- OBJ_TAINT(NArray);
+- return NArray;
+-}
+-
+-VALUE
+-NetCDF_get_var_float(VALUE Var)
+-{
+- int ncid;
+- int varid;
+- int status;
+- float *ptr;
+- struct NetCDFVar *Netcdf_var;
+- int i=0;
+- int ndimsp;
+- int *dimids;
+- size_t lengthp;
+- na_shape_t *shape; /* NArray uses int instead of size_t */
+- VALUE NArray;
+-
+- Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
+- ncid = Netcdf_var->ncid;
+- varid = Netcdf_var->varid;
+- status = nc_inq_varndims(ncid,varid,&ndimsp);
+- if(status != NC_NOERR) NC_RAISE(status);
+- dimids = ALLOCA_N(int,ndimsp);
+- if (ndimsp != 0){
+- shape = ALLOCA_N(na_shape_t,ndimsp);
+- for(i=0;i<ndimsp;i++){
+- status = nc_inq_vardimid(ncid,varid,dimids);
+- if(status != NC_NOERR) NC_RAISE(status);
+- nc_inq_dimlen(ncid,dimids[i],&lengthp);
+- shape[ndimsp-1-i]=lengthp;
+- }
+- } else {
+- ndimsp = 1;
+- shape = ALLOCA_N(na_shape_t,1);
+- shape[0]=1;
+- }
+-
+- Cfloat_to_NArray(NArray,ndimsp,shape,ptr);
+-
+- status = nc_get_var_float(ncid,varid,ptr);
+- if(status != NC_NOERR) NC_RAISE(status);
+-
+- OBJ_TAINT(NArray);
+- return NArray;
+-}
+-
+-VALUE
+-NetCDF_get_var_double(VALUE Var)
+-{
+- int ncid;
+- int varid;
+- int status;
+- double *ptr;
+- struct NetCDFVar *Netcdf_var;
+- int i=0;
+- int ndimsp;
+- int *dimids;
+- size_t lengthp;
+- na_shape_t *shape; /* NArray uses int instead of size_t */
+- VALUE NArray;
+-
+- Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
+- ncid = Netcdf_var->ncid;
+- varid = Netcdf_var->varid;
+- status = nc_inq_varndims(ncid,varid,&ndimsp);
+- if(status != NC_NOERR) NC_RAISE(status);
+- dimids = ALLOCA_N(int,ndimsp);
+- if (ndimsp != 0){
+- shape = ALLOCA_N(na_shape_t,ndimsp);
+- for(i=0;i<ndimsp;i++){
+- status = nc_inq_vardimid(ncid,varid,dimids);
+- if(status != NC_NOERR) NC_RAISE(status);
+- nc_inq_dimlen(ncid,dimids[i],&lengthp);
+- shape[ndimsp-1-i]=lengthp;
+- }
+- } else {
+- ndimsp = 1;
+- shape = ALLOCA_N(na_shape_t,1);
+- shape[0]=1;
+- }
+-
+- Cdouble_to_NArray(NArray,ndimsp,shape,ptr);
+-
+- status = nc_get_var_double(ncid,varid,ptr);
+- if(status != NC_NOERR) NC_RAISE(status);
+-
+- OBJ_TAINT(NArray);
+- return NArray;
+-}
+-
+-VALUE
+-NetCDF_get_var1_char(VALUE Var,VALUE start)
+-{
+- int ncid;
+- int varid;
+- int status;
+- unsigned char *ptr;
+- int i;
+- struct NetCDFVar *Netcdf_var;
+- na_shape_t l_start;
+- size_t *c_start;
+- int ndims;
+- int dimids[NC_MAX_DIMS];
+- size_t dimlen;
+- na_shape_t *c_count;
+- VALUE NArray;
+-
+-
+- Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
+- ncid = Netcdf_var->ncid;
+- varid = Netcdf_var->varid;
+- status = nc_inq_varndims(ncid, varid, &ndims);
+- if(status != NC_NOERR)NC_RAISE(status);
+- if(ndims == 0) {
+- rb_raise(rb_eNetcdfError,"Cannot specify a subset of a rank-0 scalar\n");
+- }
+-
+- Check_Type(start,T_ARRAY);
+- if(RARRAY_LEN(start) < ndims) {
+- rb_raise(rb_eNetcdfError,"Length of 'start' is too short\n");
+- }
+-
+- c_start=ALLOCA_N(size_t,ndims);
+- c_count=ALLOCA_N(na_shape_t,ndims);
+- for(i=0;i<ndims;i++){
+- l_start = NUM2INT(RARRAY_PTR(start)[ndims-1-i]);
+- status = nc_inq_vardimid(ncid,varid,dimids);
+- if(status != NC_NOERR) NC_RAISE(status);
+- if(l_start < 0) {
+- status = nc_inq_dimlen(ncid,dimids[i],&dimlen);
+- if(status != NC_NOERR) NC_RAISE(status);
+- l_start += dimlen;
+- }
+- c_start[i]=l_start;
+-
+- c_count[i]=1;
+- }
+-
+-
+-
+-
+- Cbyte_to_NArray(NArray,ndims,c_count,ptr);
+- status = nc_get_var1_text(ncid,varid,c_start,(char *)ptr);
+- if(status != NC_NOERR) NC_RAISE(status);
+-
+- OBJ_TAINT(NArray);
+- return NArray;
+-
+-}
+-
+-VALUE
+-NetCDF_get_var1_byte(VALUE Var,VALUE start)
+-{
+- int ncid;
+- int varid;
+- int status;
+- unsigned char *ptr;
+- int i;
+- struct NetCDFVar *Netcdf_var;
+- na_shape_t l_start;
+- size_t *c_start;
+- int ndims;
+- int dimids[NC_MAX_DIMS];
+- size_t dimlen;
+- na_shape_t *c_count;
+- VALUE NArray;
+-
+-
+- Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
+- ncid = Netcdf_var->ncid;
+- varid = Netcdf_var->varid;
+- status = nc_inq_varndims(ncid, varid, &ndims);
+- if(status != NC_NOERR)NC_RAISE(status);
+- if(ndims == 0) {
+- rb_raise(rb_eNetcdfError,"Cannot specify a subset of a rank-0 scalar\n");
+- }
+-
+- Check_Type(start,T_ARRAY);
+- if(RARRAY_LEN(start) < ndims) {
+- rb_raise(rb_eNetcdfError,"Length of 'start' is too short\n");
+- }
+-
+- c_start=ALLOCA_N(size_t,ndims);
+- c_count=ALLOCA_N(na_shape_t,ndims);
+- for(i=0;i<ndims;i++){
+- l_start = NUM2INT(RARRAY_PTR(start)[ndims-1-i]);
+- status = nc_inq_vardimid(ncid,varid,dimids);
+- if(status != NC_NOERR) NC_RAISE(status);
+- if(l_start < 0) {
+- status = nc_inq_dimlen(ncid,dimids[i],&dimlen);
+- if(status != NC_NOERR) NC_RAISE(status);
+- l_start += dimlen;
+- }
+- c_start[i]=l_start;
+-
+- c_count[i]=1;
+- }
+-
+-
+-
+-
+- Cbyte_to_NArray(NArray,ndims,c_count,ptr);
+- status = nc_get_var1_uchar(ncid,varid,c_start,ptr);
+- if(status != NC_NOERR) NC_RAISE(status);
+-
+- OBJ_TAINT(NArray);
+- return NArray;
+-
+-}
+-
+-VALUE
+-NetCDF_get_var1_sint(VALUE Var,VALUE start)
+-{
+- int ncid;
+- int varid;
+- int status;
+- short *ptr;
+- int i;
+- struct NetCDFVar *Netcdf_var;
+- na_shape_t l_start;
+- size_t *c_start;
+- int ndims;
+- int dimids[NC_MAX_DIMS];
+- size_t dimlen;
+- na_shape_t *c_count;
+- VALUE NArray;
+-
+- Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
+- ncid = Netcdf_var->ncid;
+- varid = Netcdf_var->varid;
+- status = nc_inq_varndims(ncid, varid, &ndims);
+- if(status != NC_NOERR) NC_RAISE(status);
+- if(ndims == 0) {
+- rb_raise(rb_eNetcdfError,"Cannot specify a subset of a rank-0 scalar\n");
+- }
+-
+- Check_Type(start,T_ARRAY);
+- if(RARRAY_LEN(start) < ndims) {
+- rb_raise(rb_eNetcdfError,"Length of 'start' is too short\n");
+- }
+-
+- c_start=ALLOCA_N(size_t,ndims);
+- c_count=ALLOCA_N(na_shape_t,ndims);
+- for(i=0;i<ndims;i++){
+- l_start = NUM2INT(RARRAY_PTR(start)[ndims-1-i]);
+- status = nc_inq_vardimid(ncid,varid,dimids);
+- if(status != NC_NOERR) NC_RAISE(status);
+- if(l_start < 0) {
+- status = nc_inq_dimlen(ncid,dimids[i],&dimlen);
+- if(status != NC_NOERR) NC_RAISE(status);
+- l_start += dimlen;
+- }
+- c_start[i]=l_start;
+- c_count[i]=1;
+- }
+-
+- Csint_to_NArray(NArray,ndims,c_count,ptr);
+-
+- status = nc_get_var1_short(ncid,varid,c_start,ptr);
+- if(status != NC_NOERR) NC_RAISE(status);
+-
+- OBJ_TAINT(NArray);
+- return NArray;
+-
+-}
+-
+-VALUE
+-NetCDF_get_var1_int(VALUE Var,VALUE start)
+-{
+- int ncid;
+- int varid;
+- int status;
+- int *ptr;
+- int i;
+- struct NetCDFVar *Netcdf_var;
+- na_shape_t l_start;
+- size_t *c_start;
+- int ndims;
+- int dimids[NC_MAX_DIMS];
+- size_t dimlen;
+- na_shape_t *c_count;
+- VALUE NArray;
+-
+- Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
+- ncid = Netcdf_var->ncid;
+- varid = Netcdf_var->varid;
+- status = nc_inq_varndims(ncid, varid, &ndims);
+- if(status != NC_NOERR)NC_RAISE(status);
+- if(ndims == 0) {
+- rb_raise(rb_eNetcdfError,"Cannot specify a subset of a rank-0 scalar\n");
+- }
+-
+- Check_Type(start,T_ARRAY);
+- if(RARRAY_LEN(start) < ndims) {
+- rb_raise(rb_eNetcdfError,"Length of 'start' is too short\n");
+- }
+-
+- c_start=ALLOCA_N(size_t,ndims);
+- c_count=ALLOCA_N(na_shape_t,ndims);
+- for(i=0;i<ndims;i++){
+- l_start = NUM2INT(RARRAY_PTR(start)[ndims-1-i]);
+- status = nc_inq_vardimid(ncid,varid,dimids);
+- if(status != NC_NOERR) NC_RAISE(status);
+- if(l_start < 0) {
+- status = nc_inq_dimlen(ncid,dimids[i],&dimlen);
+- if(status != NC_NOERR) NC_RAISE(status);
+- l_start += dimlen;
+- }
+- c_start[i]=l_start;
+- c_count[i]=1;
+- }
+-
+- Clint_to_NArray(NArray,ndims,c_count,ptr);
+-
+- status = nc_get_var1_int(ncid,varid,c_start,ptr);
+- if(status != NC_NOERR) NC_RAISE(status);
+-
+- OBJ_TAINT(NArray);
+- return NArray;
+-
+-}
+-
+-VALUE
+-NetCDF_get_var1_float(VALUE Var,VALUE start)
+-{
+- int ncid;
+- int varid;
+- int status;
+- float *ptr;
+- int i;
+- struct NetCDFVar *Netcdf_var;
+- na_shape_t l_start;
+- size_t *c_start;
+- int ndims;
+- int dimids[NC_MAX_DIMS];
+- size_t dimlen;
+- na_shape_t *c_count;
+- VALUE NArray;
+-
+- Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
+- ncid = Netcdf_var->ncid;
+- varid = Netcdf_var->varid;
+- status = nc_inq_varndims(ncid, varid, &ndims);
+- if(status != NC_NOERR)NC_RAISE(status);
+- if(ndims == 0) {
+- rb_raise(rb_eNetcdfError,"Cannot specify a subset of a rank-0 scalar\n");
+- }
+-
+- Check_Type(start,T_ARRAY);
+- if(RARRAY_LEN(start) < ndims) {
+- rb_raise(rb_eNetcdfError,"Length of 'start' is too short\n");
+- }
+-
+- c_start=ALLOCA_N(size_t,ndims);
+- c_count=ALLOCA_N(na_shape_t,ndims);
+- for(i=0;i<ndims;i++){
+- l_start = NUM2INT(RARRAY_PTR(start)[ndims-1-i]);
+- status = nc_inq_vardimid(ncid, varid, dimids);
+- if(status != NC_NOERR) NC_RAISE(status);
+- if(l_start < 0) {
+- status = nc_inq_dimlen(ncid,dimids[i],&dimlen);
+- if(status != NC_NOERR) NC_RAISE(status);
+- l_start += dimlen;
+- }
+- c_start[i]=l_start;
+- c_count[i]=1;
+- }
+-
+- Cfloat_to_NArray(NArray,ndims,c_count,ptr);
+-
+- status = nc_get_var1_float(ncid,varid,c_start,ptr);
+- if(status != NC_NOERR) NC_RAISE(status);
+-
+- OBJ_TAINT(NArray);
+- return NArray;
+-
+-}
+-
+-VALUE
+-NetCDF_get_var1_double(VALUE Var,VALUE start)
+-{
+- int ncid;
+- int varid;
+- int status;
+- double *ptr;
+- int i;
+- struct NetCDFVar *Netcdf_var;
+- na_shape_t l_start;
+- size_t *c_start;
+- int ndims;
+- int dimids[NC_MAX_DIMS];
+- size_t dimlen;
+- na_shape_t *c_count;
+- VALUE NArray;
+-
+- Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
+- ncid = Netcdf_var->ncid;
+- varid = Netcdf_var->varid;
+- status = nc_inq_varndims(ncid, varid, &ndims);
+- if(status != NC_NOERR)NC_RAISE(status);
+- if(ndims == 0) {
+- rb_raise(rb_eNetcdfError,"Cannot specify a subset of a rank-0 scalar\n");
+- }
+-
+- Check_Type(start,T_ARRAY);
+- if(RARRAY_LEN(start) < ndims) {
+- rb_raise(rb_eNetcdfError,"Length of 'start' is too short\n");
+- }
+-
+- c_start=ALLOCA_N(size_t,ndims);
+- c_count=ALLOCA_N(na_shape_t,ndims);
+- for(i=0;i<ndims;i++){
+- l_start = NUM2INT(RARRAY_PTR(start)[ndims-1-i]);
+- status = nc_inq_vardimid(ncid,varid,dimids);
+- if(status !=NC_NOERR) NC_RAISE(status);
+- if(l_start < 0) {
+- status = nc_inq_dimlen(ncid,dimids[i],&dimlen);
+- if(status != NC_NOERR) NC_RAISE(status);
+- l_start += dimlen;
+- }
+- c_start[i]=l_start;
+- c_count[i]=1;
+- }
+-
+- Cdouble_to_NArray(NArray,ndims,c_count,ptr);
+-
+- status = nc_get_var1_double(ncid,varid,c_start,ptr);
+- if(status != NC_NOERR) NC_RAISE(status);
+-
+- OBJ_TAINT(NArray);
+- return NArray;
+-
+-}
+-
+-VALUE
+-NetCDF_get_vars_char(VALUE Var,VALUE start,VALUE end,VALUE stride)
+-{
+- int ncid;
+- int varid;
+- int status;
+- unsigned char *ptr;
+- int i;
+- struct NetCDFVar *Netcdf_var;
+- na_shape_t l_start, l_end;
+- size_t *c_start;
+- size_t *c_count;
+- ptrdiff_t *c_stride;
+- na_shape_t *shape; /* NArray uses int instead of size_t */
+- int ndims;
+- int *dimids;
+- size_t dimlen;
+- VALUE NArray;
+-
+- Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
+- ncid = Netcdf_var->ncid;
+- varid = Netcdf_var->varid;
+-
+- status = nc_inq_varndims(ncid,varid,&ndims);
+- if(status != NC_NOERR) NC_RAISE(status);
+- if(ndims == 0) {
+- rb_raise(rb_eNetcdfError,"Cannot specify a subset of a rank-0 scalar\n");
+- }
+-
+- dimids = ALLOCA_N(int,ndims);
+- status = nc_inq_vardimid(ncid,varid,dimids);
+- if(status != NC_NOERR) NC_RAISE(status);
+-
+- Check_Type(start,T_ARRAY);
+- if(RARRAY_LEN(start) < ndims){
+- rb_raise(rb_eNetcdfError, "Length of 'start' is too short\n");
+- }
+- c_start = ALLOCA_N(size_t,ndims);
+- for(i=0; i<ndims; i++){
+- l_start=NUM2INT(RARRAY_PTR(start)[ndims-1-i]);
+-
+- if(l_start < 0) {
+- status = nc_inq_dimlen(ncid, dimids[i], &dimlen);
+- if(status != NC_NOERR) NC_RAISE(status);
+- l_start += dimlen;
+- }
+- c_start[i]=l_start;
+- }
+-
+- c_stride=ALLOCA_N(ptrdiff_t,ndims);
+- switch(TYPE(stride)){
+- case T_NIL:
+- for(i=0; i<ndims; i++){
+- c_stride[i]=1;
+- }
+- break;
+- default:
+- Check_Type(stride,T_ARRAY);
+- if(RARRAY_LEN(stride) < ndims) {
+- rb_raise(rb_eNetcdfError, "Length of 'stride is too short\n");
+- }
+- for(i=0;i<ndims; i++){
+- c_stride[i]=NUM2INT(RARRAY_PTR(stride)[ndims-1-i]);
+- if(c_stride[i]==0){
+- rb_raise(rb_eNetcdfError,"stride cannot be zero\n");
+- }
+- }
+- }
+-
+- c_count=ALLOCA_N(size_t,ndims);
+- switch(TYPE(end)){
+- case T_NIL:
+- for(i=0; i<ndims; i++){
+- nc_inq_dimlen(ncid,dimids[i],&dimlen);
+- c_count[i]=(dimlen-c_start[i]-1)/c_stride[i]+1;
+- }
+- break;
+- default:
+- Check_Type(end,T_ARRAY);
+- if(RARRAY_LEN(end) <ndims) {
+- rb_raise(rb_eNetcdfError, "Length of 'end' is too short\n");
+- }
+- for(i=0; i<ndims; i++){
+- l_end= NUM2INT(RARRAY_PTR(end)[ndims-1-i]);
+- if(l_end < 0) {
+- status = nc_inq_dimlen(ncid,dimids[i],&dimlen);
+- if(status != NC_NOERR) NC_RAISE(status);
+- l_end +=dimlen;
+- }
+- c_count[i]=(l_end-c_start[i])/c_stride[i]+1;
+- }
+- }
+-
+-
+- shape = ALLOCA_N(na_shape_t,ndims);
+- for(i=0;i<ndims;i++){
+- shape[ndims-1-i]=c_count[i];
+- }
+-
+- Cbyte_to_NArray(NArray,ndims,shape,ptr);
+-
+- status = nc_get_vars_text(ncid,varid,c_start,c_count,c_stride,(char *)ptr);
+- if(status != NC_NOERR) NC_RAISE(status);
+-
+- OBJ_TAINT(NArray);
+- return NArray;
+-}
+-
+-VALUE
+-NetCDF_get_vars_byte(VALUE Var,VALUE start,VALUE end,VALUE stride)
+-{
+- int ncid;
+- int varid;
+- int status;
+- unsigned char *ptr;
+- int i;
+- struct NetCDFVar *Netcdf_var;
+- na_shape_t l_start, l_end;
+- size_t *c_start;
+- size_t *c_count;
+- ptrdiff_t *c_stride;
+- na_shape_t *shape; /* NArray uses int instead of size_t */
+- int ndims;
+- int *dimids;
+- size_t dimlen;
+- VALUE NArray;
+-
+- Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
+- ncid = Netcdf_var->ncid;
+- varid = Netcdf_var->varid;
+-
+- status = nc_inq_varndims(ncid,varid,&ndims);
+- if(status != NC_NOERR) NC_RAISE(status);
+- if(ndims == 0) {
+- rb_raise(rb_eNetcdfError,"Cannot specify a subset of a rank-0 scalar\n");
+- }
+-
+- dimids = ALLOCA_N(int,ndims);
+- status = nc_inq_vardimid(ncid,varid,dimids);
+- if(status != NC_NOERR) NC_RAISE(status);
+-
+- Check_Type(start,T_ARRAY);
+- if(RARRAY_LEN(start) < ndims){
+- rb_raise(rb_eNetcdfError, "Length of 'start' is too short\n");
+- }
+- c_start = ALLOCA_N(size_t,ndims);
+- for(i=0; i<ndims; i++){
+- l_start=NUM2INT(RARRAY_PTR(start)[ndims-1-i]);
+-
+- if(l_start < 0) {
+- status = nc_inq_dimlen(ncid, dimids[i], &dimlen);
+- if(status != NC_NOERR) NC_RAISE(status);
+- l_start += dimlen;
+- }
+- c_start[i]=l_start;
+- }
+-
+- c_stride=ALLOCA_N(ptrdiff_t,ndims);
+- switch(TYPE(stride)){
+- case T_NIL:
+- for(i=0; i<ndims; i++){
+- c_stride[i]=1;
+- }
+- break;
+- default:
+- Check_Type(stride,T_ARRAY);
+- if(RARRAY_LEN(stride) < ndims) {
+- rb_raise(rb_eNetcdfError, "Length of 'stride is too short\n");
+- }
+- for(i=0;i<ndims; i++){
+- c_stride[i]=NUM2INT(RARRAY_PTR(stride)[ndims-1-i]);
+- if(c_stride[i]==0){
+- rb_raise(rb_eNetcdfError,"stride cannot be zero\n");
+- }
+- }
+- }
+-
+- c_count=ALLOCA_N(size_t,ndims);
+- switch(TYPE(end)){
+- case T_NIL:
+- for(i=0; i<ndims; i++){
+- nc_inq_dimlen(ncid,dimids[i],&dimlen);
+- c_count[i]=(dimlen-c_start[i]-1)/c_stride[i]+1;
+- }
+- break;
+- default:
+- Check_Type(end,T_ARRAY);
+- if(RARRAY_LEN(end) <ndims) {
+- rb_raise(rb_eNetcdfError, "Length of 'end' is too short\n");
+- }
+- for(i=0; i<ndims; i++){
+- l_end= NUM2INT(RARRAY_PTR(end)[ndims-1-i]);
+- if(l_end < 0) {
+- status = nc_inq_dimlen(ncid,dimids[i],&dimlen);
+- if(status != NC_NOERR) NC_RAISE(status);
+- l_end +=dimlen;
+- }
+- c_count[i]=(l_end-c_start[i])/c_stride[i]+1;
+- }
+- }
+-
+-
+- shape = ALLOCA_N(na_shape_t,ndims);
+- for(i=0;i<ndims;i++){
+- shape[ndims-1-i]=c_count[i];
+- }
+-
+- Cbyte_to_NArray(NArray,ndims,shape,ptr);
+-
+- status = nc_get_vars_uchar(ncid,varid,c_start,c_count,c_stride,ptr);
+- if(status != NC_NOERR) NC_RAISE(status);
+-
+- OBJ_TAINT(NArray);
+- return NArray;
+-}
+-
+-VALUE
+-NetCDF_get_vars_sint(VALUE Var,VALUE start,VALUE end,VALUE stride)
+-{
+- int ncid;
+- int varid;
+- int status;
+- short *ptr;
+- int i;
+- struct NetCDFVar *Netcdf_var;
+- na_shape_t l_start, l_end;
+- size_t *c_start;
+- size_t *c_count;
+- ptrdiff_t *c_stride;
+- na_shape_t *shape; /* NArray uses int instead of size_t */
+- int ndims;
+- int *dimids;
+- size_t dimlen;
+- VALUE NArray;
+-
+- Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
+- ncid = Netcdf_var->ncid;
+- varid = Netcdf_var->varid;
+-
+- status = nc_inq_varndims(ncid,varid,&ndims);
+- if(status != NC_NOERR) NC_RAISE(status);
+- if(ndims == 0) {
+- rb_raise(rb_eNetcdfError,"Cannot specify a subset of a rank-0 scalar\n");
+- }
+-
+- dimids = ALLOCA_N(int,ndims);
+- status = nc_inq_vardimid(ncid,varid,dimids);
+- if(status != NC_NOERR) NC_RAISE(status);
+-
+- Check_Type(start,T_ARRAY);
+- if(RARRAY_LEN(start) < ndims){
+- rb_raise(rb_eNetcdfError, "Length of 'start' is too short\n");
+- }
+- c_start = ALLOCA_N(size_t,ndims);
+- for(i=0; i<ndims; i++){
+- l_start=NUM2INT(RARRAY_PTR(start)[ndims-1-i]);
+-
+- if(l_start < 0) {
+- status = nc_inq_dimlen(ncid, dimids[i], &dimlen);
+- if(status != NC_NOERR) NC_RAISE(status);
+- l_start += dimlen;
+- }
+- c_start[i]=l_start;
+- }
+-
+- c_stride=ALLOCA_N(ptrdiff_t,ndims);
+- switch(TYPE(stride)){
+- case T_NIL:
+- for(i=0; i<ndims; i++){
+- c_stride[i]=1;
+- }
+- break;
+- default:
+- Check_Type(stride,T_ARRAY);
+- if(RARRAY_LEN(stride) < ndims) {
+- rb_raise(rb_eNetcdfError, "Length of 'stride is too short\n");
+- }
+- for(i=0;i<ndims; i++){
+- c_stride[i]=NUM2INT(RARRAY_PTR(stride)[ndims-1-i]);
+- if(c_stride[i]==0){
+- rb_raise(rb_eNetcdfError,"stride cannot be zero\n");
+- }
+- }
+- }
+-
+- c_count=ALLOCA_N(size_t,ndims);
+- switch(TYPE(end)){
+- case T_NIL:
+- for(i=0; i<ndims; i++){
+- nc_inq_dimlen(ncid,dimids[i],&dimlen);
+- c_count[i]=(dimlen-c_start[i]-1)/c_stride[i]+1;
+- }
+- break;
+- default:
+- Check_Type(end,T_ARRAY);
+- if(RARRAY_LEN(end) <ndims) {
+- rb_raise(rb_eNetcdfError, "Length of 'end' is too short\n");
+- }
+- for(i=0; i<ndims; i++){
+- l_end= NUM2INT(RARRAY_PTR(end)[ndims-1-i]);
+- if(l_end < 0) {
+- status = nc_inq_dimlen(ncid,dimids[i],&dimlen);
+- if(status != NC_NOERR) NC_RAISE(status);
+- l_end +=dimlen;
+- }
+- c_count[i]=(l_end-c_start[i])/c_stride[i]+1;
+- }
+- }
+-
+-
+- shape = ALLOCA_N(na_shape_t,ndims);
+- for(i=0;i<ndims;i++){
+- shape[ndims-1-i]=c_count[i];
+- }
+-
+- Csint_to_NArray(NArray,ndims,shape,ptr);
+-
+-
+- status = nc_get_vars_short(ncid,varid,c_start,c_count,c_stride,ptr);
+- if(status != NC_NOERR) NC_RAISE(status);
+-
+- OBJ_TAINT(NArray);
+- return NArray;
+-}
+-
+-VALUE
+-NetCDF_get_vars_int(VALUE Var,VALUE start,VALUE end,VALUE stride)
+-{
+- int ncid;
+- int varid;
+- int status;
+- int *ptr;
+- int i;
+- struct NetCDFVar *Netcdf_var;
+- na_shape_t l_start, l_end;
+- size_t *c_start;
+- size_t *c_count;
+- ptrdiff_t *c_stride;
+- na_shape_t *shape; /* NArray uses int instead of size_t */
+- int ndims;
+- int *dimids;
+- size_t dimlen;
+- VALUE NArray;
+-
+- Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
+- ncid = Netcdf_var->ncid;
+- varid = Netcdf_var->varid;
+-
+- status = nc_inq_varndims(ncid,varid,&ndims);
+- if(status != NC_NOERR) NC_RAISE(status);
+- if(ndims == 0) {
+- rb_raise(rb_eNetcdfError,"Cannot specify a subset of a rank-0 scalar\n");
+- }
+-
+- dimids = ALLOCA_N(int,ndims);
+- status = nc_inq_vardimid(ncid,varid,dimids);
+- if(status != NC_NOERR) NC_RAISE(status);
+-
+- Check_Type(start,T_ARRAY);
+- if(RARRAY_LEN(start) < ndims){
+- rb_raise(rb_eNetcdfError, "Length of 'start' is too short\n");
+- }
+- c_start = ALLOCA_N(size_t,ndims);
+- for(i=0; i<ndims; i++){
+- l_start=NUM2INT(RARRAY_PTR(start)[ndims-1-i]);
+-
+- if(l_start < 0) {
+- status = nc_inq_dimlen(ncid, dimids[i], &dimlen);
+- if(status != NC_NOERR) NC_RAISE(status);
+- l_start += dimlen;
+- }
+- c_start[i]=l_start;
+- }
+-
+- c_stride=ALLOCA_N(ptrdiff_t,ndims);
+- switch(TYPE(stride)){
+- case T_NIL:
+- for(i=0; i<ndims; i++){
+- c_stride[i]=1;
+- }
+- break;
+- default:
+- Check_Type(stride,T_ARRAY);
+- if(RARRAY_LEN(stride) < ndims) {
+- rb_raise(rb_eNetcdfError, "Length of 'stride is too short\n");
+- }
+- for(i=0;i<ndims; i++){
+- c_stride[i]=NUM2INT(RARRAY_PTR(stride)[ndims-1-i]);
+- if(c_stride[i]==0){
+- rb_raise(rb_eNetcdfError,"stride cannot be zero\n");
+- }
+- }
+- }
+-
+- c_count=ALLOCA_N(size_t,ndims);
+- switch(TYPE(end)){
+- case T_NIL:
+- for(i=0; i<ndims; i++){
+- nc_inq_dimlen(ncid,dimids[i],&dimlen);
+- c_count[i]=(dimlen-c_start[i]-1)/c_stride[i]+1;
+- }
+- break;
+- default:
+- Check_Type(end,T_ARRAY);
+- if(RARRAY_LEN(end) <ndims) {
+- rb_raise(rb_eNetcdfError, "Length of 'end' is too short\n");
+- }
+- for(i=0; i<ndims; i++){
+- l_end= NUM2INT(RARRAY_PTR(end)[ndims-1-i]);
+- if(l_end < 0) {
+- status = nc_inq_dimlen(ncid,dimids[i],&dimlen);
+- if(status != NC_NOERR) NC_RAISE(status);
+- l_end +=dimlen;
+- }
+- c_count[i]=(l_end-c_start[i])/c_stride[i]+1;
+- }
+- }
+-
+-
+- shape = ALLOCA_N(na_shape_t,ndims);
+- for(i=0;i<ndims;i++){
+- shape[ndims-1-i]=c_count[i];
+- }
+-
+- Clint_to_NArray(NArray,ndims,shape,ptr);
+-
+-
+- status = nc_get_vars_int(ncid,varid,c_start,c_count,c_stride,ptr);
+- if(status != NC_NOERR) NC_RAISE(status);
+-
+- OBJ_TAINT(NArray);
+- return NArray;
+-}
+-
+-VALUE
+-NetCDF_get_vars_float(VALUE Var,VALUE start,VALUE end,VALUE stride)
+-{
+- int ncid;
+- int varid;
+- int status;
+- float *ptr;
+- int i;
+- struct NetCDFVar *Netcdf_var;
+- na_shape_t l_start, l_end;
+- size_t *c_start;
+- size_t *c_count;
+- ptrdiff_t *c_stride;
+- na_shape_t *shape; /* NArray uses int instead of size_t */
+- int ndims;
+- int *dimids;
+- size_t dimlen;
+- VALUE NArray;
+-
+- Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
+- ncid = Netcdf_var->ncid;
+- varid = Netcdf_var->varid;
+-
+- status = nc_inq_varndims(ncid,varid,&ndims);
+- if(status != NC_NOERR) NC_RAISE(status);
+- if(ndims == 0) {
+- rb_raise(rb_eNetcdfError,"Cannot specify a subset of a rank-0 scalar\n");
+- }
+-
+- dimids = ALLOCA_N(int,ndims);
+- status = nc_inq_vardimid(ncid,varid,dimids);
+- if(status != NC_NOERR) NC_RAISE(status);
+-
+- Check_Type(start,T_ARRAY);
+- if(RARRAY_LEN(start) < ndims){
+- rb_raise(rb_eNetcdfError, "Length of 'start' is too short\n");
+- }
+- c_start = ALLOCA_N(size_t,ndims);
+- for(i=0; i<ndims; i++){
+- l_start=NUM2INT(RARRAY_PTR(start)[ndims-1-i]);
+-
+- if(l_start < 0) {
+- status = nc_inq_dimlen(ncid, dimids[i], &dimlen);
+- if(status != NC_NOERR) NC_RAISE(status);
+- l_start += dimlen;
+- }
+- c_start[i]=l_start;
+- }
+-
+- c_stride=ALLOCA_N(ptrdiff_t,ndims);
+- switch(TYPE(stride)){
+- case T_NIL:
+- for(i=0; i<ndims; i++){
+- c_stride[i]=1;
+- }
+- break;
+- default:
+- Check_Type(stride,T_ARRAY);
+- if(RARRAY_LEN(stride) < ndims) {
+- rb_raise(rb_eNetcdfError, "Length of 'stride is too short\n");
+- }
+- for(i=0;i<ndims; i++){
+- c_stride[i]=NUM2INT(RARRAY_PTR(stride)[ndims-1-i]);
+- if(c_stride[i]==0){
+- rb_raise(rb_eNetcdfError,"stride cannot be zero\n");
+- }
+- }
+- }
+-
+- c_count=ALLOCA_N(size_t,ndims);
+- switch(TYPE(end)){
+- case T_NIL:
+- for(i=0; i<ndims; i++){
+- nc_inq_dimlen(ncid,dimids[i],&dimlen);
+- c_count[i]=(dimlen-c_start[i]-1)/c_stride[i]+1;
+- }
+- break;
+- default:
+- Check_Type(end,T_ARRAY);
+- if(RARRAY_LEN(end) <ndims) {
+- rb_raise(rb_eNetcdfError, "Length of 'end' is too short\n");
+- }
+- for(i=0; i<ndims; i++){
+- l_end= NUM2INT(RARRAY_PTR(end)[ndims-1-i]);
+- if(l_end < 0) {
+- status = nc_inq_dimlen(ncid,dimids[i],&dimlen);
+- if(status != NC_NOERR) NC_RAISE(status);
+- l_end +=dimlen;
+- }
+- c_count[i]=(l_end-c_start[i])/c_stride[i]+1;
+- }
+- }
+-
+-
+- shape = ALLOCA_N(na_shape_t,ndims);
+- for(i=0;i<ndims;i++){
+- shape[ndims-1-i]=c_count[i];
+- }
+-
+- Cfloat_to_NArray(NArray,ndims,shape,ptr);
+-
+-
+- status = nc_get_vars_float(ncid,varid,c_start,c_count,c_stride,ptr);
+- if(status != NC_NOERR) NC_RAISE(status);
+-
+- OBJ_TAINT(NArray);
+- return NArray;
+-}
+-
+-VALUE
+-NetCDF_get_vars_double(VALUE Var,VALUE start,VALUE end,VALUE stride)
+-{
+- int ncid;
+- int varid;
+- int status;
+- double *ptr;
+- int i;
+- struct NetCDFVar *Netcdf_var;
+- na_shape_t l_start, l_end;
+- size_t *c_start;
+- size_t *c_count;
+- ptrdiff_t *c_stride;
+- na_shape_t *shape; /* NArray uses int instead of size_t */
+- int ndims;
+- int *dimids;
+- size_t dimlen;
+- VALUE NArray;
+-
+- Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
+- ncid = Netcdf_var->ncid;
+- varid = Netcdf_var->varid;
+-
+- status = nc_inq_varndims(ncid,varid,&ndims);
+- if(status != NC_NOERR) NC_RAISE(status);
+- if(ndims == 0) {
+- rb_raise(rb_eNetcdfError,"Cannot specify a subset of a rank-0 scalar\n");
+- }
+-
+- dimids = ALLOCA_N(int,ndims);
+- status = nc_inq_vardimid(ncid,varid,dimids);
+- if(status != NC_NOERR) NC_RAISE(status);
+-
+- Check_Type(start,T_ARRAY);
+- if(RARRAY_LEN(start) < ndims){
+- rb_raise(rb_eNetcdfError, "Length of 'start' is too short\n");
+- }
+- c_start = ALLOCA_N(size_t,ndims);
+- for(i=0; i<ndims; i++){
+- l_start=NUM2INT(RARRAY_PTR(start)[ndims-1-i]);
+-
+- if(l_start < 0) {
+- status = nc_inq_dimlen(ncid, dimids[i], &dimlen);
+- if(status != NC_NOERR) NC_RAISE(status);
+- l_start += dimlen;
+- }
+- c_start[i]=l_start;
+- }
+-
+- c_stride=ALLOCA_N(ptrdiff_t,ndims);
+- switch(TYPE(stride)){
+- case T_NIL:
+- for(i=0; i<ndims; i++){
+- c_stride[i]=1;
+- }
+- break;
+- default:
+- Check_Type(stride,T_ARRAY);
+- if(RARRAY_LEN(stride) < ndims) {
+- rb_raise(rb_eNetcdfError, "Length of 'stride is too short\n");
+- }
+- for(i=0;i<ndims; i++){
+- c_stride[i]=NUM2INT(RARRAY_PTR(stride)[ndims-1-i]);
+- if(c_stride[i]==0){
+- rb_raise(rb_eNetcdfError,"stride cannot be zero\n");
+- }
+- }
+- }
+-
+- c_count=ALLOCA_N(size_t,ndims);
+- switch(TYPE(end)){
+- case T_NIL:
+- for(i=0; i<ndims; i++){
+- nc_inq_dimlen(ncid,dimids[i],&dimlen);
+- c_count[i]=(dimlen-c_start[i]-1)/c_stride[i]+1;
+- }
+- break;
+- default:
+- Check_Type(end,T_ARRAY);
+- if(RARRAY_LEN(end) <ndims) {
+- rb_raise(rb_eNetcdfError, "Length of 'end' is too short\n");
+- }
+- for(i=0; i<ndims; i++){
+- l_end= NUM2INT(RARRAY_PTR(end)[ndims-1-i]);
+- if(l_end < 0) {
+- status = nc_inq_dimlen(ncid,dimids[i],&dimlen);
+- if(status != NC_NOERR) NC_RAISE(status);
+- l_end +=dimlen;
+- }
+- c_count[i]=(l_end-c_start[i])/c_stride[i]+1;
+- }
+- }
+-
+-
+- shape = ALLOCA_N(na_shape_t,ndims);
+- for(i=0;i<ndims;i++){
+- shape[ndims-1-i]=c_count[i];
+- }
+-
+- Cdouble_to_NArray(NArray,ndims,shape,ptr);
+-
+- status = nc_get_vars_double(ncid,varid,c_start,c_count,c_stride,ptr);
+- if(status != NC_NOERR) NC_RAISE(status);
+-
+- OBJ_TAINT(NArray);
+- return NArray;
+-}
+-
+-
+-VALUE
+-NetCDF_put_var_char(VALUE Var,VALUE NArray)
+-{
+- int ncid;
+- int varid;
+- int status;
+- unsigned char *ptr,scalar;
+- na_shape_t len,i=0;
+- struct NetCDFVar *Netcdf_var;
+- na_shape_t nc_tlen=1;
+- int ndimsp;
+- int dimids[NC_MAX_DIMS];
+- size_t lengthp;
+- char *var_name;
+-
+- rb_secure(3);
+- Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
+- ncid=Netcdf_var->ncid;
+- varid=Netcdf_var->varid;
+-
+- Array_to_Cbyte_len(NArray,ptr,len);
+-
+- status = nc_inq_varndims(ncid,varid,&ndimsp);
+- if(status != NC_NOERR) NC_RAISE(status);
+- for(i=0;i<ndimsp;i++){
+- status = nc_inq_vardimid(ncid,varid,dimids);
+- if(status != NC_NOERR) NC_RAISE(status);
+- nc_inq_dimlen(ncid,dimids[i],&lengthp);
+- nc_tlen=lengthp*nc_tlen;
+- }
+- if(len == 1 && len != nc_tlen){
+- scalar = *ptr;
+- ptr = ALLOCA_N(unsigned char,nc_tlen);
+- for(i=0;i<nc_tlen;i++){ptr[i]=scalar;}
+- } else if(len != nc_tlen){
+- var_name=ALLOCA_N(char,NC_MAX_NAME);
+- status = nc_inq_varname(ncid,varid,var_name);
+- if(status != NC_NOERR) NC_RAISE(status );
+- rb_raise(rb_eNetcdfError,"Length of NArray don't equal to length of total array in the '%s'\n",var_name);
+- }
+- status = nc_put_var_text(ncid,varid,(char *)ptr);
+- if(status !=NC_NOERR) NC_RAISE(status);
+- return Qnil;
+-}
+-
+-VALUE
+-NetCDF_put_var_byte(VALUE Var,VALUE NArray)
+-{
+- int ncid;
+- int varid;
+- int status;
+- unsigned char *ptr,scalar;
+- na_shape_t len,i=0;
+- struct NetCDFVar *Netcdf_var;
+- na_shape_t nc_tlen=1;
+- int ndimsp;
+- int dimids[NC_MAX_DIMS];
+- size_t lengthp;
+- char *var_name;
+-
+- rb_secure(3);
+- Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
+- ncid=Netcdf_var->ncid;
+- varid=Netcdf_var->varid;
+-
+- Array_to_Cbyte_len(NArray,ptr,len);
+-
+- status = nc_inq_varndims(ncid,varid,&ndimsp);
+- if(status != NC_NOERR) NC_RAISE(status);
+- for(i=0;i<ndimsp;i++){
+- status = nc_inq_vardimid(ncid,varid,dimids);
+- if(status != NC_NOERR) NC_RAISE(status);
+- nc_inq_dimlen(ncid,dimids[i],&lengthp);
+- nc_tlen=lengthp*nc_tlen;
+- }
+- if(len == 1 && len != nc_tlen){
+- scalar = *ptr;
+- ptr = ALLOCA_N(unsigned char,nc_tlen);
+- for(i=0;i<nc_tlen;i++){ptr[i]=scalar;}
+- } else if(len != nc_tlen){
+- var_name=ALLOCA_N(char,NC_MAX_NAME);
+- status = nc_inq_varname(ncid,varid,var_name);
+- if(status != NC_NOERR) NC_RAISE(status );
+- rb_raise(rb_eNetcdfError,"Length of NArray don't equal to length of total array in the '%s'\n",var_name);
+- }
+- status = nc_put_var_uchar(ncid,varid,ptr);
+- if(status !=NC_NOERR) NC_RAISE(status);
+- return Qnil;
+-}
+-
+-VALUE
+-NetCDF_put_var_short(VALUE Var,VALUE NArray)
+-{
+- int ncid;
+- int varid;
+- int status;
+- short *ptr,scalar;
+- na_shape_t len,i=0;
+- struct NetCDFVar *Netcdf_var;
+- na_shape_t nc_tlen=1;
+- int ndimsp;
+- int dimids[NC_MAX_DIMS];
+- size_t lengthp;
+- char *var_name;
+-
+- rb_secure(3);
+- Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
+- ncid=Netcdf_var->ncid;
+- varid=Netcdf_var->varid;
+- Array_to_Csint_len(NArray,ptr,len);
+-
+- status = nc_inq_varndims(ncid,varid,&ndimsp);
+- if(status != NC_NOERR) NC_RAISE(status);
+- for(i=0;i<ndimsp;i++){
+- status = nc_inq_vardimid(ncid,varid,dimids);
+- if(status != NC_NOERR) NC_RAISE(status);
+- nc_inq_dimlen(ncid,dimids[i],&lengthp);
+- nc_tlen=lengthp*nc_tlen;
+- }
+- if(len == 1 && len != nc_tlen){
+- scalar = *ptr;
+- ptr = ALLOCA_N(short,nc_tlen);
+- for(i=0;i<nc_tlen;i++){ptr[i]=scalar;}
+- } else if(len != nc_tlen){
+- var_name=ALLOCA_N(char,NC_MAX_NAME);
+- status = nc_inq_varname(ncid,varid,var_name);
+- if(status != NC_NOERR) NC_RAISE(status);
+- rb_raise(rb_eNetcdfError,"Length of NArray don't equal to length of total array length in the '%s'\n",var_name);
+- }
+-
+- status = nc_put_var_short(ncid,varid,ptr);
+- if(status !=NC_NOERR) NC_RAISE(status);
+- return Qnil;
+-}
+-
+-VALUE
+-NetCDF_put_var_int(VALUE Var,VALUE NArray)
+-{
+- int ncid;
+- int varid;
+- int status;
+- int *ptr,scalar;
+- na_shape_t len,i=0;
+- struct NetCDFVar *Netcdf_var;
+- na_shape_t nc_tlen=1;
+- int ndimsp;
+- int dimids[NC_MAX_DIMS];
+- size_t lengthp;
+- char *var_name;
+-
+- rb_secure(3);
+- Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
+- ncid=Netcdf_var->ncid;
+- varid=Netcdf_var->varid;
+-
+- Array_to_Clint_len(NArray,ptr,len);
+-
+- status = nc_inq_varndims(ncid,varid,&ndimsp);
+- if(status != NC_NOERR) NC_RAISE(status);
+- for(i=0;i<ndimsp;i++){
+- status = nc_inq_vardimid(ncid,varid,dimids);
+- if(status != NC_NOERR) NC_RAISE(status);
+- nc_inq_dimlen(ncid,dimids[i],&lengthp);
+- nc_tlen=lengthp*nc_tlen;
+- }
+- if(len == 1 && len != nc_tlen){
+- scalar = *ptr;
+- ptr = ALLOCA_N(int,nc_tlen);
+- for(i=0;i<nc_tlen;i++){ptr[i]=scalar;}
+- } else if(len != nc_tlen){
+- var_name=ALLOCA_N(char,NC_MAX_NAME);
+- status = nc_inq_varname(ncid,varid,var_name);
+- if(status != NC_NOERR) NC_RAISE(status);
+- rb_raise(rb_eNetcdfError,"Length of NArray don't equal to length of total array length in the '%s'\n",var_name);
+- }
+-
+-
+- status = nc_put_var_int(ncid,varid,ptr);
+- if(status !=NC_NOERR) NC_RAISE(status);
+- return Qnil;
+-}
+-
+-
+-VALUE
+-NetCDF_put_var_float(VALUE Var,VALUE NArray)
+-{
+- int ncid;
+- int varid;
+- int status;
+- float *ptr,scalar;
+- na_shape_t len,i=0;
+- struct NetCDFVar *Netcdf_var;
+- na_shape_t nc_tlen=1;
+- int ndimsp;
+- int dimids[NC_MAX_DIMS];
+- size_t lengthp;
+- char *var_name;
+-
+-
+- rb_secure(3);
+- Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
+- ncid=Netcdf_var->ncid;
+- varid=Netcdf_var->varid;
+-
+- Array_to_Cfloat_len(NArray,ptr,len);
+-
+- status = nc_inq_varndims(ncid,varid,&ndimsp);
+- if(status != NC_NOERR) NC_RAISE(status);
+- for(i=0;i<ndimsp;i++){
+- status = nc_inq_vardimid(ncid,varid,dimids);
+- if(status != NC_NOERR) NC_RAISE(status);
+- nc_inq_dimlen(ncid,dimids[i],&lengthp);
+- nc_tlen=lengthp*nc_tlen;
+- }
+- if(len == 1 && len != nc_tlen){
+- scalar = *ptr;
+- ptr = ALLOCA_N(float,nc_tlen);
+- for(i=0;i<nc_tlen;i++){ptr[i]=scalar;}
+- } else if(len != nc_tlen){
+- var_name=ALLOCA_N(char,NC_MAX_NAME);
+- status = nc_inq_varname(ncid,varid,var_name);
+- if(status != NC_NOERR) NC_RAISE(status);
+- rb_raise(rb_eNetcdfError,"Length of NArray don't equal to length of total array length in the '%s'\n",var_name);
+- }
+-
+- status = nc_put_var_float(ncid,varid,ptr);
+- if(status !=NC_NOERR) NC_RAISE(status);
+- return Qnil;
+-}
+-
+-VALUE
+-NetCDF_put_var_double(VALUE Var,VALUE NArray)
+-{
+- int ncid;
+- int varid;
+- int status;
+- double *ptr,scalar;
+- na_shape_t len,i=0;
+- struct NetCDFVar *Netcdf_var;
+- na_shape_t nc_tlen=1;
+- int ndimsp;
+- int dimids[NC_MAX_DIMS];
+- size_t lengthp;
+- char *var_name;
+-
+-
+- rb_secure(3);
+- Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
+- ncid=Netcdf_var->ncid;
+- varid=Netcdf_var->varid;
+-
+- Array_to_Cdouble_len(NArray,ptr,len);
+-
+- status = nc_inq_varndims(ncid,varid,&ndimsp);
+- if(status != NC_NOERR) NC_RAISE(status);
+- for(i=0;i<ndimsp;i++){
+- status = nc_inq_vardimid(ncid,varid,dimids);
+- if(status != NC_NOERR) NC_RAISE(status);
+- nc_inq_dimlen(ncid,dimids[i],&lengthp);
+- nc_tlen=lengthp*nc_tlen;
+- }
+- if(len == 1 && len != nc_tlen){
+- scalar = *ptr;
+- ptr = ALLOCA_N(double,nc_tlen);
+- for(i=0;i<nc_tlen;i++){ptr[i]=scalar;}
+- } else if(len != nc_tlen){
+- var_name=ALLOCA_N(char,NC_MAX_NAME);
+- status = nc_inq_varname(ncid,varid,var_name);
+- if(status != NC_NOERR) NC_RAISE(status);
+- rb_raise(rb_eNetcdfError,"Length of NArray don't equal to length of total array length in the '%s'\n",var_name);
+- }
+-
+- status = nc_put_var_double(ncid,varid,ptr);
+- if(status !=NC_NOERR) NC_RAISE(status);
+- return Qnil;
+-}
+-
+-VALUE
+-NetCDF_put_var1_char(VALUE Var,VALUE NArray,VALUE start)
+-{
+- int ncid;
+- int varid;
+- int status;
+- unsigned char *ptr;
+- int i;
+- struct NetCDFVar *Netcdf_var;
+- na_shape_t l_start;
+- size_t *c_start;
+- int ndims;
+- int *dimids;
+- size_t dimlen;
+-
+- rb_secure(3);
+- Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
+- ncid=Netcdf_var->ncid;
+- varid=Netcdf_var->varid;
+- status = nc_inq_varndims(ncid,varid,&ndims);
+- if(status != NC_NOERR) NC_RAISE(status);
+-
+-
+- dimids = ALLOCA_N(int,ndims);
+- status = nc_inq_vardimid(ncid,varid,dimids);
+- if(status != NC_NOERR) NC_RAISE(status);
+-
+- Check_Type(start,T_ARRAY);
+- if(RARRAY_LEN(start) <ndims) {
+- rb_raise(rb_eNetcdfError,"Length of 'start' is too short\n");
+- }
+-
+- c_start=ALLOCA_N(size_t,ndims);
+- for(i=0;i<ndims;i++){
+- l_start=NUM2INT(RARRAY_PTR(start)[ndims-1-i]);
+-
+- if(l_start < 0) {
+- status = nc_inq_dimlen(ncid,dimids[i],&dimlen);
+- if(status != NC_NOERR) NC_RAISE(status);
+- l_start += dimlen;
+- }
+- c_start[i]=l_start;
+-
+- }
+- Array_to_Cbyte(NArray,ptr);
+-
+- status = nc_put_var1_text(ncid,varid,c_start,(char *)ptr);
+- if(status != NC_NOERR) NC_RAISE(status);
+- return Qnil;
+-}
+-
+-VALUE
+-NetCDF_put_var1_byte(VALUE Var,VALUE NArray,VALUE start)
+-{
+- int ncid;
+- int varid;
+- int status;
+- unsigned char *ptr;
+- int i;
+- struct NetCDFVar *Netcdf_var;
+- na_shape_t l_start;
+- size_t *c_start;
+- int ndims;
+- int *dimids;
+- size_t dimlen;
+-
+- rb_secure(3);
+- Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
+- ncid=Netcdf_var->ncid;
+- varid=Netcdf_var->varid;
+- status = nc_inq_varndims(ncid,varid,&ndims);
+- if(status != NC_NOERR) NC_RAISE(status);
+-
+-
+- dimids = ALLOCA_N(int,ndims);
+- status = nc_inq_vardimid(ncid,varid,dimids);
+- if(status != NC_NOERR) NC_RAISE(status);
+-
+- Check_Type(start,T_ARRAY);
+- if(RARRAY_LEN(start) <ndims) {
+- rb_raise(rb_eNetcdfError,"Length of 'start' is too short\n");
+- }
+-
+- c_start=ALLOCA_N(size_t,ndims);
+- for(i=0;i<ndims;i++){
+- l_start=NUM2INT(RARRAY_PTR(start)[ndims-1-i]);
+-
+- if(l_start < 0) {
+- status = nc_inq_dimlen(ncid,dimids[i],&dimlen);
+- if(status != NC_NOERR) NC_RAISE(status);
+- l_start += dimlen;
+- }
+- c_start[i]=l_start;
+-
+- }
+- Array_to_Cbyte(NArray,ptr);
+-
+- status = nc_put_var1_uchar(ncid,varid,c_start,ptr);
+- if(status != NC_NOERR) NC_RAISE(status);
+- return Qnil;
+-}
+-
+-VALUE
+-NetCDF_put_var1_sint(VALUE Var,VALUE NArray,VALUE start)
+-{
+- int ncid;
+- int varid;
+- int status;
+- short *ptr;
+- int i;
+- struct NetCDFVar *Netcdf_var;
+- na_shape_t l_start;
+- size_t *c_start;
+- int ndims;
+- int *dimids;
+- size_t dimlen;
+-
+- rb_secure(3);
+- Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
+- ncid=Netcdf_var->ncid;
+- varid=Netcdf_var->varid;
+- status = nc_inq_varndims(ncid,varid,&ndims);
+- if(status != NC_NOERR) NC_RAISE(status);
+-
+-
+- dimids = ALLOCA_N(int,ndims);
+- status = nc_inq_vardimid(ncid,varid,dimids);
+- if(status != NC_NOERR) NC_RAISE(status);
+-
+- Check_Type(start,T_ARRAY);
+- if(RARRAY_LEN(start) <ndims) {
+- rb_raise(rb_eNetcdfError,"Length of 'start' is too short\n");
+- }
+-
+- c_start=ALLOCA_N(size_t,ndims);
+- for(i=0;i<ndims;i++){
+- l_start=NUM2INT(RARRAY_PTR(start)[ndims-1-i]);
+-
+- if(l_start < 0) {
+- status = nc_inq_dimlen(ncid,dimids[i],&dimlen);
+- if(status != NC_NOERR) NC_RAISE(status);
+- l_start += dimlen;
+- }
+- c_start[i]=l_start;
+-
+- }
+- Array_to_Csint(NArray,ptr);
+-
+- status = nc_put_var1_short(ncid,varid,c_start,ptr);
+- if(status != NC_NOERR) NC_RAISE(status);
+- return Qnil;
+-}
+-VALUE
+-NetCDF_put_var1_int(VALUE Var,VALUE NArray,VALUE start)
+-{
+- int ncid;
+- int varid;
+- int status;
+- int *ptr;
+- int i;
+- struct NetCDFVar *Netcdf_var;
+- na_shape_t l_start;
+- size_t *c_start;
+- int ndims;
+- int *dimids;
+- size_t dimlen;
+-
+- rb_secure(3);
+- Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
+- ncid=Netcdf_var->ncid;
+- varid=Netcdf_var->varid;
+- status = nc_inq_varndims(ncid,varid,&ndims);
+- if(status != NC_NOERR) NC_RAISE(status);
+-
+-
+- dimids = ALLOCA_N(int,ndims);
+- status = nc_inq_vardimid(ncid,varid,dimids);
+- if(status != NC_NOERR) NC_RAISE(status);
+-
+- Check_Type(start,T_ARRAY);
+- if(RARRAY_LEN(start) <ndims) {
+- rb_raise(rb_eNetcdfError,"Length of 'start' is too short\n");
+- }
+-
+- c_start=ALLOCA_N(size_t,ndims);
+- for(i=0;i<ndims;i++){
+- l_start=NUM2INT(RARRAY_PTR(start)[ndims-1-i]);
+-
+- if(l_start < 0) {
+- status = nc_inq_dimlen(ncid,dimids[i],&dimlen);
+- if(status != NC_NOERR) NC_RAISE(status);
+- l_start += dimlen;
+- }
+- c_start[i]=l_start;
+-
+- }
+- Array_to_Clint(NArray,ptr);
+-
+- status = nc_put_var1_int(ncid,varid,c_start,ptr);
+- if(status != NC_NOERR) NC_RAISE(status);
+- return Qnil;
+-}
+-
+-VALUE
+-NetCDF_put_var1_float(VALUE Var,VALUE NArray,VALUE start)
+-{
+- int ncid;
+- int varid;
+- int status;
+- float *ptr;
+- int i;
+- struct NetCDFVar *Netcdf_var;
+- na_shape_t l_start;
+- size_t *c_start;
+- int ndims;
+- int *dimids;
+- size_t dimlen;
+-
+- rb_secure(3);
+- Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
+- ncid=Netcdf_var->ncid;
+- varid=Netcdf_var->varid;
+- status = nc_inq_varndims(ncid,varid,&ndims);
+- if(status != NC_NOERR) NC_RAISE(status);
+-
+-
+- dimids = ALLOCA_N(int,ndims);
+- status = nc_inq_vardimid(ncid,varid,dimids);
+- if(status != NC_NOERR) NC_RAISE(status);
+-
+- Check_Type(start,T_ARRAY);
+- if(RARRAY_LEN(start) <ndims) {
+- rb_raise(rb_eNetcdfError,"Length of 'start' is too short\n");
+- }
+-
+- c_start=ALLOCA_N(size_t,ndims);
+- for(i=0;i<ndims;i++){
+- l_start=NUM2INT(RARRAY_PTR(start)[ndims-1-i]);
+-
+- if(l_start < 0) {
+- status = nc_inq_dimlen(ncid,dimids[i],&dimlen);
+- if(status != NC_NOERR) NC_RAISE(status);
+- l_start += dimlen;
+- }
+- c_start[i]=l_start;
+-
+- }
+- Array_to_Cfloat(NArray,ptr);
+-
+- status = nc_put_var1_float(ncid,varid,c_start,ptr);
+- if(status != NC_NOERR) NC_RAISE(status);
+- return Qnil;
+-}
+-
+-VALUE
+-NetCDF_put_var1_double(VALUE Var,VALUE NArray,VALUE start)
+-{
+- int ncid;
+- int varid;
+- int status;
+- double *ptr;
+- int i;
+- struct NetCDFVar *Netcdf_var;
+- na_shape_t l_start;
+- size_t *c_start;
+- int ndims;
+- int *dimids;
+- size_t dimlen;
+-
+- rb_secure(3);
+- Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
+- ncid=Netcdf_var->ncid;
+- varid=Netcdf_var->varid;
+- status = nc_inq_varndims(ncid,varid,&ndims);
+- if(status != NC_NOERR) NC_RAISE(status);
+-
+-
+- dimids = ALLOCA_N(int,ndims);
+- status = nc_inq_vardimid(ncid,varid,dimids);
+- if(status != NC_NOERR) NC_RAISE(status);
+-
+- Check_Type(start,T_ARRAY);
+- if(RARRAY_LEN(start) <ndims) {
+- rb_raise(rb_eNetcdfError,"Length of 'start' is too short\n");
+- }
+-
+- c_start=ALLOCA_N(size_t,ndims);
+- for(i=0;i<ndims;i++){
+- l_start=NUM2INT(RARRAY_PTR(start)[ndims-1-i]);
+-
+- if(l_start < 0) {
+- status = nc_inq_dimlen(ncid,dimids[i],&dimlen);
+- if(status != NC_NOERR) NC_RAISE(status);
+- l_start += dimlen;
+- }
+- c_start[i]=l_start;
+-
+- }
+- Array_to_Cdouble(NArray,ptr);
+-
+- status = nc_put_var1_double(ncid,varid,c_start,ptr);
+- if(status != NC_NOERR) NC_RAISE(status);
+- return Qnil;
+-}
+-
+-
+-VALUE
+-NetCDF_put_vars_char(VALUE Var,VALUE NArray,VALUE start,VALUE end,VALUE stride)
+-{
+- int ncid;
+- int varid;
+- int status;
+- unsigned char *ptr,scalar;
+- na_shape_t len;
+- int c_count_all=1;
+- struct NetCDFVar *Netcdf_var;
+- na_shape_t l_start, l_end;
+- size_t *c_start;
+- size_t *c_count;
+- ptrdiff_t *c_stride;
+- int ndims,i;
+- na_shape_t *shape;
+- int *dimids;
+- size_t dimlen;
+-
+- rb_secure(3);
+- Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
+- ncid=Netcdf_var->ncid;
+- varid=Netcdf_var->varid;
+- status = nc_inq_varndims(ncid, varid, &ndims);
+- if(status != NC_NOERR) NC_RAISE(status);
+-
+- dimids=ALLOCA_N(int,ndims);
+- status = nc_inq_vardimid(ncid, varid, dimids);
+- if(status != NC_NOERR) NC_RAISE(status);
+-
+- Check_Type(start,T_ARRAY);
+- if(RARRAY_LEN(start) < ndims) {
+- rb_raise(rb_eNetcdfError, "Length of 'start' is too short\n");
+- }
+- c_start=ALLOCA_N(size_t,ndims);
+- for(i=0; i<ndims; i++){
+- l_start=NUM2INT(RARRAY_PTR(start)[ndims-1-i]);
+-
+- if(l_start < 0) {
+- status = nc_inq_dimlen(ncid, dimids[i], &dimlen);
+- if(status != NC_NOERR) NC_RAISE(status);
+- l_start += dimlen;
+- }
+- c_start[i]=l_start;
+- }
+-
+- c_stride=ALLOCA_N(ptrdiff_t,ndims);
+- switch(TYPE(stride)){
+- case T_NIL:
+- for(i=0; i<ndims; i++){
+- c_stride[i]=1;
+- }
+- break;
+- default:
+- Check_Type(stride,T_ARRAY);
+- if(RARRAY_LEN(stride) < ndims) {
+- rb_raise(rb_eNetcdfError, "Length of 'stride' is too short\n");
+- }
+- for(i=0; i<ndims; i++){
+- c_stride[i]=NUM2INT(RARRAY_PTR(stride)[ndims-1-i]);
+- if(c_stride[i]==0) {
+- rb_raise(rb_eNetcdfError, "stride cannot be zero\n");
+- }
+- }
+- }
+-
+- Array_to_Cbyte_len_shape(NArray,ptr,len,shape);
+-
+- c_count=ALLOCA_N(size_t,ndims);
+- switch(TYPE(end)){
+- case T_NIL:
+- for(i=0; i<ndims; i++){
+- c_count[i]=shape[i];
+- }
+- c_count_all=len;
+- break;
+- default:
+- Check_Type(end,T_ARRAY);
+- if(RARRAY_LEN(end) < ndims) {
+- rb_raise(rb_eNetcdfError, "Length of 'end' is too short\n");
+- }
+- for(i=0; i<ndims; i++){
+- l_end=NUM2INT(RARRAY_PTR(end)[ndims-1-i]);
+- if(l_end < 0) {
+- status = nc_inq_dimlen(ncid, dimids[i], &dimlen);
+- if(status != NC_NOERR) NC_RAISE(status);
+- l_end += dimlen;
+- }
+- c_count[i]=(l_end-c_start[i])/c_stride[i]+1;
+- c_count_all=c_count[i]*c_count_all;
+- }
+- if(len == 1 && len != c_count_all){
+- scalar = *ptr;
+- ptr = ALLOCA_N(unsigned char,c_count_all);
+- for(i=0;i<c_count_all;i++){ptr[i]=scalar;}
+- } else if(len != c_count_all) {
+- rb_raise(rb_eNetcdfError,
+- "lengh of the array does not agree with that of the subset\n");
+- }
+- }
+-
+- status = nc_put_vars_text(ncid,varid,c_start,c_count,c_stride,(char *)ptr);
+- if(status != NC_NOERR) NC_RAISE(status);
+- return Qnil;
+-}
+-
+-VALUE
+-NetCDF_put_vars_byte(VALUE Var,VALUE NArray,VALUE start,VALUE end,VALUE stride)
+-{
+- int ncid;
+- int varid;
+- int status;
+- unsigned char *ptr,scalar;
+- na_shape_t len;
+- int c_count_all=1;
+- struct NetCDFVar *Netcdf_var;
+- na_shape_t l_start, l_end;
+- size_t *c_start;
+- size_t *c_count;
+- ptrdiff_t *c_stride;
+- int ndims,i;
+- na_shape_t *shape;
+- int *dimids;
+- size_t dimlen;
+-
+- rb_secure(3);
+- Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
+- ncid=Netcdf_var->ncid;
+- varid=Netcdf_var->varid;
+- status = nc_inq_varndims(ncid, varid, &ndims);
+- if(status != NC_NOERR) NC_RAISE(status);
+-
+- dimids=ALLOCA_N(int,ndims);
+- status = nc_inq_vardimid(ncid, varid, dimids);
+- if(status != NC_NOERR) NC_RAISE(status);
+-
+- Check_Type(start,T_ARRAY);
+- if(RARRAY_LEN(start) < ndims) {
+- rb_raise(rb_eNetcdfError, "Length of 'start' is too short\n");
+- }
+- c_start=ALLOCA_N(size_t,ndims);
+- for(i=0; i<ndims; i++){
+- l_start=NUM2INT(RARRAY_PTR(start)[ndims-1-i]);
+-
+- if(l_start < 0) {
+- status = nc_inq_dimlen(ncid, dimids[i], &dimlen);
+- if(status != NC_NOERR) NC_RAISE(status);
+- l_start += dimlen;
+- }
+- c_start[i]=l_start;
+- }
+-
+- c_stride=ALLOCA_N(ptrdiff_t,ndims);
+- switch(TYPE(stride)){
+- case T_NIL:
+- for(i=0; i<ndims; i++){
+- c_stride[i]=1;
+- }
+- break;
+- default:
+- Check_Type(stride,T_ARRAY);
+- if(RARRAY_LEN(stride) < ndims) {
+- rb_raise(rb_eNetcdfError, "Length of 'stride' is too short\n");
+- }
+- for(i=0; i<ndims; i++){
+- c_stride[i]=NUM2INT(RARRAY_PTR(stride)[ndims-1-i]);
+- if(c_stride[i]==0) {
+- rb_raise(rb_eNetcdfError, "stride cannot be zero\n");
+- }
+- }
+- }
+-
+- Array_to_Cbyte_len_shape(NArray,ptr,len,shape);
+-
+- c_count=ALLOCA_N(size_t,ndims);
+- switch(TYPE(end)){
+- case T_NIL:
+- for(i=0; i<ndims; i++){
+- c_count[i]=shape[i];
+- }
+- c_count_all=len;
+- break;
+- default:
+- Check_Type(end,T_ARRAY);
+- if(RARRAY_LEN(end) < ndims) {
+- rb_raise(rb_eNetcdfError, "Length of 'end' is too short\n");
+- }
+- for(i=0; i<ndims; i++){
+- l_end=NUM2INT(RARRAY_PTR(end)[ndims-1-i]);
+- if(l_end < 0) {
+- status = nc_inq_dimlen(ncid, dimids[i], &dimlen);
+- if(status != NC_NOERR) NC_RAISE(status);
+- l_end += dimlen;
+- }
+- c_count[i]=(l_end-c_start[i])/c_stride[i]+1;
+- c_count_all=c_count[i]*c_count_all;
+- }
+- if(len == 1 && len != c_count_all){
+- scalar = *ptr;
+- ptr = ALLOCA_N(unsigned char,c_count_all);
+- for(i=0;i<c_count_all;i++){ptr[i]=scalar;}
+- } else if(len != c_count_all) {
+- rb_raise(rb_eNetcdfError,
+- "lengh of the array does not agree with that of the subset\n");
+- }
+- }
+-
+- status = nc_put_vars_uchar(ncid,varid,c_start,c_count,c_stride,ptr);
+- if(status != NC_NOERR) NC_RAISE(status);
+- return Qnil;
+-}
+-
+-VALUE
+-NetCDF_put_vars_sint(VALUE Var,VALUE NArray,VALUE start,VALUE end,VALUE stride)
+-{
+- int ncid;
+- int varid;
+- int status;
+- short *ptr,scalar;
+- na_shape_t len;
+- int c_count_all=1;
+- struct NetCDFVar *Netcdf_var;
+- na_shape_t l_start, l_end;
+- size_t *c_start;
+- size_t *c_count;
+- ptrdiff_t *c_stride;
+- int ndims,i;
+- na_shape_t *shape;
+- int *dimids;
+- size_t dimlen;
+-
+- rb_secure(3);
+- Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
+- ncid=Netcdf_var->ncid;
+- varid=Netcdf_var->varid;
+- status = nc_inq_varndims(ncid, varid, &ndims);
+- if(status != NC_NOERR) NC_RAISE(status);
+-
+- dimids=ALLOCA_N(int,ndims);
+- status = nc_inq_vardimid(ncid, varid, dimids);
+- if(status != NC_NOERR) NC_RAISE(status);
+-
+- Check_Type(start,T_ARRAY);
+- if(RARRAY_LEN(start) < ndims) {
+- rb_raise(rb_eNetcdfError, "Length of 'start' is too short\n");
+- }
+- c_start=ALLOCA_N(size_t,ndims);
+- for(i=0; i<ndims; i++){
+- l_start=NUM2INT(RARRAY_PTR(start)[ndims-1-i]);
+-
+- if(l_start < 0) {
+- status = nc_inq_dimlen(ncid, dimids[i], &dimlen);
+- if(status != NC_NOERR) NC_RAISE(status);
+- l_start += dimlen;
+- }
+- c_start[i]=l_start;
+- }
+-
+- c_stride=ALLOCA_N(ptrdiff_t,ndims);
+- switch(TYPE(stride)){
+- case T_NIL:
+- for(i=0; i<ndims; i++){
+- c_stride[i]=1;
+- }
+- break;
+- default:
+- Check_Type(stride,T_ARRAY);
+- if(RARRAY_LEN(stride) < ndims) {
+- rb_raise(rb_eNetcdfError, "Length of 'stride' is too short\n");
+- }
+- for(i=0; i<ndims; i++){
+- c_stride[i]=NUM2INT(RARRAY_PTR(stride)[ndims-1-i]);
+- if(c_stride[i]==0) {
+- rb_raise(rb_eNetcdfError, "stride cannot be zero\n");
+- }
+- }
+- }
+-
+- Array_to_Csint_len_shape(NArray,ptr,len,shape);
+-
+- c_count=ALLOCA_N(size_t,ndims);
+- switch(TYPE(end)){
+- case T_NIL:
+- for(i=0; i<ndims; i++){
+- c_count[i]=shape[i];
+- }
+- c_count_all=len;
+- break;
+- default:
+- Check_Type(end,T_ARRAY);
+- if(RARRAY_LEN(end) < ndims) {
+- rb_raise(rb_eNetcdfError, "Length of 'end' is too short\n");
+- }
+- for(i=0; i<ndims; i++){
+- l_end=NUM2INT(RARRAY_PTR(end)[ndims-1-i]);
+- if(l_end < 0) {
+- status = nc_inq_dimlen(ncid, dimids[i], &dimlen);
+- if(status != NC_NOERR) NC_RAISE(status);
+- l_end += dimlen;
+- }
+- c_count[i]=(l_end-c_start[i])/c_stride[i]+1;
+- c_count_all=c_count[i]*c_count_all;
+- }
+- if(len == 1 && len != c_count_all){
+- scalar = *ptr;
+- ptr = ALLOCA_N(short,c_count_all);
+- for(i=0;i<c_count_all;i++){ptr[i]=scalar;}
+- } else if(len != c_count_all) {
+- rb_raise(rb_eNetcdfError,
+- "lengh of the array does not agree with that of the subset\n");
+- }
+- }
+-
+- status = nc_put_vars_short(ncid,varid,c_start,c_count,c_stride,ptr);
+- if(status != NC_NOERR) NC_RAISE(status);
+- return Qnil;
+-}
+-
+-
+-VALUE
+-NetCDF_put_vars_int(VALUE Var,VALUE NArray,VALUE start,VALUE end,VALUE stride)
+-{
+- int ncid;
+- int varid;
+- int status;
+- int *ptr,scalar;
+- na_shape_t len;
+- int c_count_all=1;
+- struct NetCDFVar *Netcdf_var;
+- na_shape_t l_start, l_end;
+- size_t *c_start;
+- size_t *c_count;
+- ptrdiff_t *c_stride;
+- int ndims,i;
+- na_shape_t *shape;
+- int *dimids;
+- size_t dimlen;
+-
+- rb_secure(3);
+- Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
+- ncid=Netcdf_var->ncid;
+- varid=Netcdf_var->varid;
+- status = nc_inq_varndims(ncid, varid, &ndims);
+- if(status != NC_NOERR) NC_RAISE(status);
+-
+- dimids=ALLOCA_N(int,ndims);
+- status = nc_inq_vardimid(ncid, varid, dimids);
+- if(status != NC_NOERR) NC_RAISE(status);
+-
+- Check_Type(start,T_ARRAY);
+- if(RARRAY_LEN(start) < ndims) {
+- rb_raise(rb_eNetcdfError, "Length of 'start' is too short\n");
+- }
+- c_start=ALLOCA_N(size_t,ndims);
+- for(i=0; i<ndims; i++){
+- l_start=NUM2INT(RARRAY_PTR(start)[ndims-1-i]);
+-
+- if(l_start < 0) {
+- status = nc_inq_dimlen(ncid, dimids[i], &dimlen);
+- if(status != NC_NOERR) NC_RAISE(status);
+- l_start += dimlen;
+- }
+- c_start[i]=l_start;
+- }
+-
+- c_stride=ALLOCA_N(ptrdiff_t,ndims);
+- switch(TYPE(stride)){
+- case T_NIL:
+- for(i=0; i<ndims; i++){
+- c_stride[i]=1;
+- }
+- break;
+- default:
+- Check_Type(stride,T_ARRAY);
+- if(RARRAY_LEN(stride) < ndims) {
+- rb_raise(rb_eNetcdfError, "Length of 'stride' is too short\n");
+- }
+- for(i=0; i<ndims; i++){
+- c_stride[i]=NUM2INT(RARRAY_PTR(stride)[ndims-1-i]);
+- if(c_stride[i]==0) {
+- rb_raise(rb_eNetcdfError, "stride cannot be zero\n");
+- }
+- }
+- }
+-
+- Array_to_Clint_len_shape(NArray,ptr,len,shape);
+-
+- c_count=ALLOCA_N(size_t,ndims);
+- switch(TYPE(end)){
+- case T_NIL:
+- for(i=0; i<ndims; i++){
+- c_count[i]=shape[i];
+- }
+- c_count_all=len;
+- break;
+- default:
+- Check_Type(end,T_ARRAY);
+- if(RARRAY_LEN(end) < ndims) {
+- rb_raise(rb_eNetcdfError, "Length of 'end' is too short\n");
+- }
+- for(i=0; i<ndims; i++){
+- l_end=NUM2INT(RARRAY_PTR(end)[ndims-1-i]);
+- if(l_end < 0) {
+- status = nc_inq_dimlen(ncid, dimids[i], &dimlen);
+- if(status != NC_NOERR) NC_RAISE(status);
+- l_end += dimlen;
+- }
+- c_count[i]=(l_end-c_start[i])/c_stride[i]+1;
+- c_count_all=c_count[i]*c_count_all;
+- }
+- if(len == 1 && len != c_count_all){
+- scalar = *ptr;
+- ptr = ALLOCA_N(int,c_count_all);
+- for(i=0;i<c_count_all;i++){ptr[i]=scalar;}
+- } else if(len != c_count_all) {
+- rb_raise(rb_eNetcdfError,
+- "length of the array does not agree with that of the subset\n");
+- }
+- }
+-
+- status = nc_put_vars_int(ncid,varid,c_start,c_count,c_stride,ptr);
+- if(status != NC_NOERR) NC_RAISE(status);
+- return Qnil;
+-}
+-
+-
+-VALUE
+-NetCDF_put_vars_float(VALUE Var,VALUE NArray,VALUE start,VALUE end,VALUE stride)
+-{
+- int ncid;
+- int varid;
+- int status;
+- float *ptr,scalar;
+- na_shape_t len;
+- int c_count_all=1;
+- struct NetCDFVar *Netcdf_var;
+- na_shape_t l_start, l_end;
+- size_t *c_start;
+- size_t *c_count;
+- ptrdiff_t *c_stride;
+- int ndims,i;
+- na_shape_t *shape;
+- int *dimids;
+- size_t dimlen;
+-
+- rb_secure(3);
+- Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
+- ncid=Netcdf_var->ncid;
+- varid=Netcdf_var->varid;
+- status = nc_inq_varndims(ncid, varid, &ndims);
+- if(status != NC_NOERR) NC_RAISE(status);
+-
+- dimids=ALLOCA_N(int,ndims);
+- status = nc_inq_vardimid(ncid, varid, dimids);
+- if(status != NC_NOERR) NC_RAISE(status);
+-
+- Check_Type(start,T_ARRAY);
+- if(RARRAY_LEN(start) < ndims) {
+- rb_raise(rb_eNetcdfError, "Length of 'start' is too short\n");
+- }
+- c_start=ALLOCA_N(size_t,ndims);
+- for(i=0; i<ndims; i++){
+- l_start=NUM2INT(RARRAY_PTR(start)[ndims-1-i]);
+-
+- if(l_start < 0) {
+- status = nc_inq_dimlen(ncid, dimids[i], &dimlen);
+- if(status != NC_NOERR) NC_RAISE(status);
+- l_start += dimlen;
+- }
+- c_start[i]=l_start;
+- }
+-
+- c_stride=ALLOCA_N(ptrdiff_t,ndims);
+- switch(TYPE(stride)){
+- case T_NIL:
+- for(i=0; i<ndims; i++){
+- c_stride[i]=1;
+- }
+- break;
+- default:
+- Check_Type(stride,T_ARRAY);
+- if(RARRAY_LEN(stride) < ndims) {
+- rb_raise(rb_eNetcdfError, "Length of 'stride' is too short\n");
+- }
+- for(i=0; i<ndims; i++){
+- c_stride[i]=NUM2INT(RARRAY_PTR(stride)[ndims-1-i]);
+- if(c_stride[i]==0) {
+- rb_raise(rb_eNetcdfError, "stride cannot be zero\n");
+- }
+- }
+- }
+-
+- Array_to_Cfloat_len_shape(NArray,ptr,len,shape);
+-
+- c_count=ALLOCA_N(size_t,ndims);
+- switch(TYPE(end)){
+- case T_NIL:
+- for(i=0; i<ndims; i++){
+- c_count[i]=shape[i];
+- }
+- c_count_all=len;
+- break;
+- default:
+- Check_Type(end,T_ARRAY);
+- if(RARRAY_LEN(end) < ndims) {
+- rb_raise(rb_eNetcdfError, "Length of 'end' is too short\n");
+- }
+- for(i=0; i<ndims; i++){
+- l_end=NUM2INT(RARRAY_PTR(end)[ndims-1-i]);
+- if(l_end < 0) {
+- status = nc_inq_dimlen(ncid, dimids[i], &dimlen);
+- if(status != NC_NOERR) NC_RAISE(status);
+- l_end += dimlen;
+- }
+- c_count[i]=(l_end-c_start[i])/c_stride[i]+1;
+- c_count_all=c_count[i]*c_count_all;
+- }
+- if(len == 1 && len != c_count_all){
+- scalar = *ptr;
+- ptr = ALLOCA_N(float,c_count_all);
+- for(i=0;i<c_count_all;i++){ptr[i]=scalar;}
+- } else if(len != c_count_all) {
+- rb_raise(rb_eNetcdfError,
+- "lengh of the array does not agree with that of the subset\n");
+- }
+- }
+-
+- status = nc_put_vars_float(ncid,varid,c_start,c_count,c_stride,ptr);
+- if(status != NC_NOERR) NC_RAISE(status);
+- return Qnil;
+-}
+-
+-
+-VALUE
+-NetCDF_put_vars_double(VALUE Var,VALUE NArray,VALUE start,VALUE end,VALUE stride)
+-{
+- int ncid;
+- int varid;
+- int status;
+- double *ptr,scalar;
+- na_shape_t len;
+- int c_count_all=1;
+- struct NetCDFVar *Netcdf_var;
+- na_shape_t l_start, l_end;
+- size_t *c_start;
+- size_t *c_count;
+- ptrdiff_t *c_stride;
+- int ndims,i;
+- na_shape_t *shape;
+- int *dimids;
+- size_t dimlen;
+-
+- rb_secure(3);
+- Data_Get_Struct(Var,struct NetCDFVar,Netcdf_var);
+- ncid=Netcdf_var->ncid;
+- varid=Netcdf_var->varid;
+- status = nc_inq_varndims(ncid, varid, &ndims);
+- if(status != NC_NOERR) NC_RAISE(status);
+-
+- dimids=ALLOCA_N(int,ndims);
+- status = nc_inq_vardimid(ncid, varid, dimids);
+- if(status != NC_NOERR) NC_RAISE(status);
+-
+- Check_Type(start,T_ARRAY);
+- if(RARRAY_LEN(start) < ndims) {
+- rb_raise(rb_eNetcdfError, "Length of 'start' is too short\n");
+- }
+- c_start=ALLOCA_N(size_t,ndims);
+- for(i=0; i<ndims; i++){
+- l_start=NUM2INT(RARRAY_PTR(start)[ndims-1-i]);
+-
+- if(l_start < 0) {
+- status = nc_inq_dimlen(ncid, dimids[i], &dimlen);
+- if(status != NC_NOERR) NC_RAISE(status);
+- l_start += dimlen;
+- }
+- c_start[i]=l_start;
+- }
+-
+- c_stride=ALLOCA_N(ptrdiff_t,ndims);
+- switch(TYPE(stride)){
+- case T_NIL:
+- for(i=0; i<ndims; i++){
+- c_stride[i]=1;
+- }
+- break;
+- default:
+- Check_Type(stride,T_ARRAY);
+- if(RARRAY_LEN(stride) < ndims) {
+- rb_raise(rb_eNetcdfError, "Length of 'stride' is too short\n");
+- }
+- for(i=0; i<ndims; i++){
+- c_stride[i]=NUM2INT(RARRAY_PTR(stride)[ndims-1-i]);
+- if(c_stride[i]==0) {
+- rb_raise(rb_eNetcdfError, "stride cannot be zero\n");
+- }
+- }
+- }
+-
+- Array_to_Cdouble_len_shape(NArray,ptr,len,shape);
+-
+- c_count=ALLOCA_N(size_t,ndims);
+- switch(TYPE(end)){
+- case T_NIL:
+- for(i=0; i<ndims; i++){
+- c_count[i]=shape[i];
+- }
+- c_count_all=len;
+- break;
+- default:
+- Check_Type(end,T_ARRAY);
+- if(RARRAY_LEN(end) < ndims) {
+- rb_raise(rb_eNetcdfError, "Length of 'end' is too short\n");
+- }
+- for(i=0; i<ndims; i++){
+- l_end=NUM2INT(RARRAY_PTR(end)[ndims-1-i]);
+- if(l_end < 0) {
+- status = nc_inq_dimlen(ncid, dimids[i], &dimlen);
+- if(status != NC_NOERR) NC_RAISE(status);
+- l_end += dimlen;
+- }
+- c_count[i]=(l_end-c_start[i])/c_stride[i]+1;
+- c_count_all=c_count[i]*c_count_all;
+- }
+- if(len == 1 && len != c_count_all){
+- scalar = *ptr;
+- ptr = ALLOCA_N(double,c_count_all);
+- for(i=0;i<c_count_all;i++){ptr[i]=scalar;}
+- } else if(len != c_count_all) {
+- rb_raise(rb_eNetcdfError,
+- "lengh of the array does not agree with that of the subset\n");
+- }
+- }
+-
+- status = nc_put_vars_double(ncid,varid,c_start,c_count,c_stride,ptr);
+- if(status != NC_NOERR) NC_RAISE(status);
+- return Qnil;
+-}
+-
+-void
+-Init_netcdfraw(void)
+-{
+- mNumRu = rb_define_module("NumRu");
+-
+- /* Difinitions of the classes */
+- cNetCDF = rb_define_class_under(mNumRu, "NetCDF", rb_cObject);
+- cNetCDFDim = rb_define_class_under(mNumRu, "NetCDFDim", rb_cObject);
+- cNetCDFAtt = rb_define_class_under(mNumRu, "NetCDFAtt", rb_cObject);
+- cNetCDFVar = rb_define_class_under(mNumRu, "NetCDFVar", rb_cObject);
+-
+- rb_eNetcdfError = rb_define_class("NetcdfError",rb_eStandardError);
+- rb_eNetcdfBadid = rb_define_class("NetcdfBadid",rb_eNetcdfError);
+- rb_eNetcdfNfile = rb_define_class("NetcdfNfile",rb_eNetcdfError);
+- rb_eNetcdfExist = rb_define_class("NetcdfExist",rb_eNetcdfError);
+- rb_eNetcdfInval = rb_define_class("NetcdfInval",rb_eNetcdfError);
+- rb_eNetcdfPerm = rb_define_class("NetcdfPerm",rb_eNetcdfError);
+- rb_eNetcdfNotindefine = rb_define_class("NetcdfNotindefine",rb_eNetcdfError);
+- rb_eNetcdfIndefine = rb_define_class("NetcdfIndefine",rb_eNetcdfError);
+- rb_eNetcdfInvalcoords = rb_define_class("NetcdfInvalcoords",rb_eNetcdfError);
+- rb_eNetcdfMaxdims = rb_define_class("NetcdfMaxdims",rb_eNetcdfError);
+- rb_eNetcdfNameinuse = rb_define_class("NetcdfNameinuse",rb_eNetcdfError);
+- rb_eNetcdfNotatt = rb_define_class("NetcdfNotatt",rb_eNetcdfError);
+- rb_eNetcdfMaxatts = rb_define_class("NetcdfMaxatts",rb_eNetcdfError);
+- rb_eNetcdfBadtype = rb_define_class("NetcdfBadtype",rb_eNetcdfError);
+- rb_eNetcdfBaddim = rb_define_class("NetcdfBaddim",rb_eNetcdfError);
+- rb_eNetcdfUnlimpos = rb_define_class("NetcdFUnlimpos",rb_eNetcdfError);
+- rb_eNetcdfMaxvars = rb_define_class("NetcdfMaxvars",rb_eNetcdfError);
+- rb_eNetcdfNotvar = rb_define_class("NetcdfNotvar",rb_eNetcdfError);
+- rb_eNetcdfGlobal = rb_define_class("NetcdfGlobal",rb_eNetcdfError);
+- rb_eNetcdfNotnc = rb_define_class("NetcdfNotnc",rb_eNetcdfError);
+- rb_eNetcdfSts = rb_define_class("NetcdfSts",rb_eNetcdfError);
+- rb_eNetcdfMaxname = rb_define_class("NetcdfMaxname",rb_eNetcdfError);
+- rb_eNetcdfUnlimit = rb_define_class("NetcdfUnlimit",rb_eNetcdfError);
+- rb_eNetcdfNorecvars = rb_define_class("NetcdfNorecvars",rb_eNetcdfError);
+- rb_eNetcdfChar = rb_define_class("NetcdfChar",rb_eNetcdfError);
+- rb_eNetcdfEdge = rb_define_class("NetcdfEdge",rb_eNetcdfError);
+- rb_eNetcdfStride = rb_define_class("NetcdfStride",rb_eNetcdfError);
+- rb_eNetcdfBadname = rb_define_class("NetcdfBadname",rb_eNetcdfError);
+- /* N.B. following must match value in ncx.h */
+- rb_eNetcdfRange = rb_define_class("NetcdfRange",rb_eNetcdfError);
+- rb_eNetcdfNomem = rb_define_class("NetcdfNomem",rb_eNetcdfError);
+- /* Global error status */
+- rb_eNetcdfEntool = rb_define_class("NetcdfEntool",rb_eNetcdfError);
+- rb_eNetcdfExdr = rb_define_class("NetcdfExdr",rb_eNetcdfError);
+- rb_eNetcdfSyserr = rb_define_class("NetcdfSyserr",rb_eNetcdfError);
+- /* Global options variable. Used to determine behavior of error handler. */
+- rb_eNetcdfFatal = rb_define_class("NetcdfFatal",rb_eNetcdfError);
+-
+- /* Class Constants Definition */
+- rb_define_const(cNetCDF, "NC_NOWRITE", INT2FIX(NC_NOWRITE));
+- rb_define_const(cNetCDF, "NC_WRITE", INT2FIX(NC_WRITE));
+- rb_define_const(cNetCDF, "NC_SHARE", INT2FIX(NC_SHARE));
+- rb_define_const(cNetCDF, "NC_CLOBBER", INT2FIX(NC_CLOBBER));
+- rb_define_const(cNetCDF, "NC_NOCLOBBER", INT2FIX(NC_NOCLOBBER));
+-#if NCVER >= 400
+- rb_define_const(cNetCDF, "NC_64BIT_OFFSET", INT2FIX(NC_64BIT_OFFSET));
+- /* NC_64BIT_OFFSET supports large files in the class data format */
+- rb_define_const(cNetCDF, "NC_NETCDF4", INT2FIX(NC_NETCDF4));
+- rb_define_const(cNetCDF, "NC_CLASSIC_MODEL", INT2FIX(NC_CLASSIC_MODEL));
+- /* for use as ( NC_NETCDF4 | NC_CLASSIC_MODEL ) to ensure the classic
+- data model in NetCDF4 by disabling new features like groups */
+- rb_define_const(cNetCDF, "NC_ENDIAN_NATIVE", INT2FIX(NC_ENDIAN_NATIVE));
+- rb_define_const(cNetCDF, "NC_ENDIAN_LITTLE", INT2FIX(NC_ENDIAN_LITTLE));
+- rb_define_const(cNetCDF, "NC_ENDIAN_BIG", INT2FIX(NC_ENDIAN_BIG));
+-#endif
+-
+-#ifdef NARRAY_BIGMEM
+- rb_define_const(cNetCDF, "SUPPORT_BIGMEM", Qtrue);
+-#else
+- rb_define_const(cNetCDF, "SUPPORT_BIGMEM", Qfalse);
+-#endif
+-
+- /* Difinitions of the ruby methods */
+- /* The methods of the NetCDF class */
+- rb_define_singleton_method(cNetCDF,"libvers",NetCDF_inq_libvers,0);
+- rb_define_singleton_method(cNetCDF,"nc_open",NetCDF_open,2);
+- rb_define_method(cNetCDF,"clone",NetCDF_clone,0);
+- rb_define_method(cNetCDF,"close",NetCDF_close,0);
+- /* rb_define_singleton_method(cNetCDF,"new",NetCDF_open,2); */
+- rb_define_singleton_method(cNetCDF,"nc_create",NetCDF_create,2);
+- rb_define_method(cNetCDF,"def_dim",NetCDF_def_dim,2);
+- rb_define_method(cNetCDF,"def_var",NetCDF_def_var,3);
+- rb_define_method(cNetCDF,"put_attraw",NetCDF_put_att,3);
+- rb_define_method(cNetCDF,"redef",NetCDF_redef,0);
+- rb_define_method(cNetCDF,"enddef",NetCDF_enddef,0);
+- rb_define_method(cNetCDF,"define_mode?",NetCDF_whether_in_define_mode,0);
+- rb_define_method(cNetCDF,"fill",NetCDF_fill,1);
+- rb_define_method(cNetCDF,"ndims",NetCDF_ndims,0);
+- rb_define_method(cNetCDF,"nvars",NetCDF_nvars,0);
+- rb_define_method(cNetCDF,"natts",NetCDF_natts,0);
+- rb_define_method(cNetCDF,"sync",NetCDF_sync,0);
+- rb_define_method(cNetCDF,"path",NetCDF_path,0);
+- rb_define_method(cNetCDF,"dim",NetCDF_dim,1);
+- rb_define_method(cNetCDF,"var",NetCDF_var,1);
+- rb_define_method(cNetCDF,"att",NetCDF_att,1);
+- rb_define_method(cNetCDF,"unlimited",NetCDF_unlimited,0);
+- rb_define_private_method(cNetCDF,"id2var",NetCDF_id2var,1);
+- rb_define_private_method(cNetCDF,"id2dim",NetCDF_id2dim,1);
+- rb_define_private_method(cNetCDF,"id2att",NetCDF_id2att,1);
+- rb_define_method(cNetCDF,"==",NetCDF_eql,1);
+- /* rb_define_method(cNetCDF,"eql?",NetCDF_eql,1); */
+-
+- /* The methods of the NetCDFDim class */
+- rb_define_method(cNetCDFDim,"clone",NetCDF_dim_clone,0);
+- rb_define_method(cNetCDFDim,"length",NetCDF_dim_length,0);
+- rb_define_method(cNetCDFDim,"name=",NetCDF_dim_name,1);
+- rb_define_method(cNetCDFDim,"name",NetCDF_dim_inqname,0);
+- rb_define_method(cNetCDFDim,"unlimited?",NetCDF_dim_whether_unlimited,0);
+- rb_define_method(cNetCDFDim,"==",NetCDF_dim_eql,1);
+- /* rb_define_method(cNetCDFDim,"eql?",NetCDF_dim_eql,1); */
+-
+- /* The methods of the NetCDFAtt class */
+- rb_define_method(cNetCDFAtt,"clone",NetCDF_att_clone,0);
+- rb_define_method(cNetCDFAtt,"name",NetCDF_att_inq_name,0);
+- rb_define_method(cNetCDFAtt,"name=",NetCDF_att_rename,1);
+- rb_define_method(cNetCDFAtt,"delete",NetCDF_att_delete,0);
+- rb_define_method(cNetCDFAtt,"copy",NetCDF_att_copy,1);
+- rb_define_method(cNetCDFAtt,"atttype",NetCDF_att_atttype,0);
+- rb_define_method(cNetCDFAtt,"typecode",NetCDF_att_typecode,0);
+- rb_define_method(cNetCDFAtt,"==",NetCDF_att_eql,1);
+- /* rb_define_method(cNetCDFAtt,"eql?",NetCDF_att_eql,1); */
+- rb_define_method(cNetCDFAtt,"putraw",NetCDF_att_put,2);
+- rb_define_method(cNetCDFAtt,"get",NetCDF_att_get,0);
+-
+- /* The methods of the NetCDFVar class */
+-#if NCVER >= 400
+- rb_define_method(cNetCDFVar,"deflate",NetCDF_var_deflate,-1);
+- rb_define_method(cNetCDFVar,"deflate_params",NetCDF_var_deflate_params,0);
+- rb_define_method(cNetCDFVar,"endian=",NetCDF_var_set_endian,1);
+- rb_define_method(cNetCDFVar,"endian",NetCDF_var_endian,0);
+-#endif
+- rb_define_method(cNetCDFVar,"clone",NetCDF_var_clone,0);
+- rb_define_method(cNetCDFVar,"name",NetCDF_var_inq_name,0);
+- rb_define_method(cNetCDFVar,"ndims",NetCDF_var_ndims,0);
+- rb_define_method(cNetCDFVar,"vartype",NetCDF_var_vartype,0);
+- rb_define_method(cNetCDFVar,"typecode",NetCDF_var_typecode,0);
+- rb_define_method(cNetCDFVar,"ntype",NetCDF_var_vartype,0);
+- rb_define_method(cNetCDFVar,"natts",NetCDF_var_natts,0);
+- rb_define_method(cNetCDFVar,"file",NetCDF_var_file,0);
+- rb_define_method(cNetCDFVar,"name=",NetCDF_var_rename,1);
+- rb_define_method(cNetCDFVar,"att",NetCDF_var_att,1);
+- rb_define_method(cNetCDFVar,"put_attraw",NetCDF_put_att_var,3);
+- rb_define_method(cNetCDFVar,"dims",NetCDF_var_dims,0);
+- rb_define_method(cNetCDFVar,"dim",NetCDF_var_dim,1);
+- /*rb_define_private_method(cNetCDFVar,"id2dim",NetCDF_var_id2dim,1); */
+- rb_define_private_method(cNetCDFVar,"id2att",NetCDF_var_id2att,1);
+- rb_define_method(cNetCDFVar,"==",NetCDF_var_eql,1);
+- /* rb_define_method(cNetCDFVar,"eql?",NetCDF_var_eql,1); */
+-
+- /* The "get*" or "put*" methods in the NetCDFVar class */
+- rb_define_method(cNetCDFVar,"put_var_char",NetCDF_put_var_char,1);
+- rb_define_method(cNetCDFVar,"put_var_byte",NetCDF_put_var_byte,1);
+- rb_define_method(cNetCDFVar,"put_var_sint",NetCDF_put_var_short,1);
+- rb_define_method(cNetCDFVar,"put_var_int",NetCDF_put_var_int,1);
+- rb_define_method(cNetCDFVar,"put_var_sfloat",NetCDF_put_var_float,1);
+- rb_define_method(cNetCDFVar,"put_var_float",NetCDF_put_var_double,1);
+-
+- rb_define_method(cNetCDFVar,"put_vars_char",NetCDF_put_vars_char,4);
+- rb_define_method(cNetCDFVar,"put_vars_byte",NetCDF_put_vars_byte,4);
+- rb_define_method(cNetCDFVar,"put_vars_sint",NetCDF_put_vars_sint,4);
+- rb_define_method(cNetCDFVar,"put_vars_int",NetCDF_put_vars_int,4);
+- rb_define_method(cNetCDFVar,"put_vars_sfloat",NetCDF_put_vars_float,4);
+- rb_define_method(cNetCDFVar,"put_vars_float",NetCDF_put_vars_double,4);
+-
+- rb_define_method(cNetCDFVar,"put_var1_char",NetCDF_put_var1_char,2);
+- rb_define_method(cNetCDFVar,"put_var1_byte",NetCDF_put_var1_byte,2);
+- rb_define_method(cNetCDFVar,"put_var1_sint",NetCDF_put_var1_sint,2);
+- rb_define_method(cNetCDFVar,"put_var1_int",NetCDF_put_var1_int,2);
+- rb_define_method(cNetCDFVar,"put_var1_sfloat",NetCDF_put_var1_float,2);
+- rb_define_method(cNetCDFVar,"put_var1_float",NetCDF_put_var1_double,2);
+-
+- rb_define_method(cNetCDFVar,"get_var_char",NetCDF_get_var_char,0);
+- rb_define_method(cNetCDFVar,"get_var_byte",NetCDF_get_var_byte,0);
+- rb_define_method(cNetCDFVar,"get_var_sint",NetCDF_get_var_sint,0);
+- rb_define_method(cNetCDFVar,"get_var_int",NetCDF_get_var_int,0);
+- rb_define_method(cNetCDFVar,"get_var_sfloat",NetCDF_get_var_float,0);
+- rb_define_method(cNetCDFVar,"get_var_float",NetCDF_get_var_double,0);
+-
+- rb_define_method(cNetCDFVar,"get_vars_char",NetCDF_get_vars_char,3);
+- rb_define_method(cNetCDFVar,"get_vars_byte",NetCDF_get_vars_byte,3);
+- rb_define_method(cNetCDFVar,"get_vars_sint",NetCDF_get_vars_sint,3);
+- rb_define_method(cNetCDFVar,"get_vars_int",NetCDF_get_vars_int,3);
+- rb_define_method(cNetCDFVar,"get_vars_sfloat",NetCDF_get_vars_float,3);
+- rb_define_method(cNetCDFVar,"get_vars_float",NetCDF_get_vars_double,3);
+-
+- rb_define_method(cNetCDFVar,"get_var1_char",NetCDF_get_var1_char,1);
+- rb_define_method(cNetCDFVar,"get_var1_byte",NetCDF_get_var1_byte,1);
+- rb_define_method(cNetCDFVar,"get_var1_sint",NetCDF_get_var1_sint,1);
+- rb_define_method(cNetCDFVar,"get_var1_int",NetCDF_get_var1_int,1);
+- rb_define_method(cNetCDFVar,"get_var1_sfloat",NetCDF_get_var1_float,1);
+- rb_define_method(cNetCDFVar,"get_var1_float",NetCDF_get_var1_double,1);
+-}
+diff --git a/ruby-netcdf.gemspec b/ruby-netcdf.gemspec
+index a6025bc..3886c35 100644
+--- a/ruby-netcdf.gemspec
++++ b/ruby-netcdf.gemspec
+@@ -30,5 +30,5 @@ Gem::Specification.new do |spec|
+ spec.add_runtime_dependency(%q<narray>, [">= 0"])
+ spec.add_runtime_dependency(%q<narray_miss>, [">= 0"])
+
+- spec.extensions << "extconf.rb"
++ spec.extensions << "ext/numru/extconf.rb"
+ end
+diff --git a/test/test.rb b/test/test.rb
+index 7ec59c6..b125a69 100644
+--- a/test/test.rb
++++ b/test/test.rb
+@@ -1,9 +1,4 @@
+-##require 'numru/netcdf'
+-## // to test before make install -->
+-require 'narray'
+-require '../netcdfraw'
+-require '../lib/netcdf'
+-## <-- to test before make install //
++require 'numru/netcdf'
+
+ include NumRu
+
diff --git a/debian/ruby-netcdf.examples b/debian/ruby-netcdf.examples
new file mode 100644
index 0000000..d8284bb
--- /dev/null
+++ b/debian/ruby-netcdf.examples
@@ -0,0 +1,3 @@
+bin/console
+bin/setup
+demo
diff --git a/debian/ruby-test-files.yaml b/debian/ruby-test-files.yaml
new file mode 100644
index 0000000..9fe6e2b
--- /dev/null
+++ b/debian/ruby-test-files.yaml
@@ -0,0 +1,10 @@
+---
+- test/aref_aset.rb
+- test/char_var.rb
+- test/clone.rb
+- test/create_tmp.rb
+- test/def_var_with_dim.rb
+- test/factor_offset.rb
+- test/putatt.rb
+- test/test.rb
+- test/type.rb
diff --git a/debian/ruby-tests.rake b/debian/ruby-tests.rake
deleted file mode 100644
index 9075465..0000000
--- a/debian/ruby-tests.rake
+++ /dev/null
@@ -1,8 +0,0 @@
-# -*- mode: ruby; coding: utf-8 -*-
-require 'gem2deb/rake/testtask'
-
-task :default => :test
-
-Rake::TestTask.new do |t|
- t.pattern = 'test/test.rb'
-end
diff --git a/debian/rules b/debian/rules
index 0bfd81e..387bdec 100755
--- a/debian/rules
+++ b/debian/rules
@@ -15,4 +15,8 @@ override_dh_installchangelogs:
override_dh_auto_clean:
dh_auto_clean
- rm -f $(CURDIR)/test.nc
+ rm -f $(CURDIR)/ext/numru/Makefile
+ rm -f $(CURDIR)/ext/numru/netcdfraw.o
+ rm -f $(CURDIR)/ext/numru/netcdfraw.so
+ rm -f $(CURDIR)/ext/numru/.RUBY*
+ rm -f $(CURDIR)/*.nc
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-grass/ruby-netcdf.git
More information about the Pkg-grass-devel
mailing list