/* * Copyright 1998-2014 University Corporation for Atmospheric Research/Unidata * * Portions of this software were developed by the Unidata Program at the * University Corporation for Atmospheric Research. * * Access and use of this software shall impose the following obligations * and understandings on the user. The user is granted the right, without * any fee or cost, to use, copy, modify, alter, enhance and distribute * this software, and any derivative works thereof, and its supporting * documentation for any purpose whatsoever, provided that this entire * notice appears in all copies of the software, derivative works and * supporting documentation. Further, UCAR requests that the user credit * UCAR/Unidata in any publications that result from the use of this * software or in any product that includes this software. The names UCAR * and/or Unidata, however, may not be used in any advertising or publicity * to endorse or promote any products or commercial entity unless specific * written permission is obtained from UCAR/Unidata. The user also * understands that UCAR/Unidata is not obligated to provide the user with * any support, consulting, training or assistance of any kind with regard * to the use, operation and performance of this software nor to provide * the user with any updates, revisions, new versions or "bug fixes." * * THIS SOFTWARE IS PROVIDED BY UCAR/UNIDATA "AS IS" AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL UCAR/UNIDATA BE LIABLE FOR ANY SPECIAL, * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE ACCESS, USE OR PERFORMANCE OF THIS SOFTWARE. */ // $Id: NcSDCharArray.java 51 2006-07-12 17:13:13Z caron $ package thredds.server.opendap; import ucar.ma2.*; import ucar.nc2.*; import opendap.dap.*; import opendap.servers.*; import java.io.IOException; import java.io.EOFException; import java.io.DataOutputStream; import java.util.*; /** * Wraps a netcdf char variable with rank > 1 as an SDArray. * * @author jcaron */ public class NcSDCharArray extends SDArray implements HasNetcdfVariable { static private org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(NcSDCharArray.class); private static final boolean debugRead = false, debugReadDetail = false; private Variable ncVar = null; private int strLen = 1; /** * Constructor: Wraps a netcdf char variable (rank > 1) in a DODS SDArray. * * @param v : netcdf Variable */ NcSDCharArray(Variable v) { super(Variable.getDAPName(v)); this.ncVar = v; if (v.getRank() < 1) throw new IllegalArgumentException("NcSDCharArray: rank must be > 1, var = " + v.getFullName()); // set dimensions, eliminate last one List dims = v.getDimensions(); for (int i = 0; i < dims.size(); i++) { Dimension dim = (Dimension) dims.get(i); if (i < dims.size() - 1) appendDim(dim.getLength(), dim.getShortName()); else strLen = dim.getLength(); } // set String type addVariable(new NcSDString(Variable.getDAPName(v), null)); } public Variable getVariable() { return ncVar; } /** * Read the data values (parameters are ignored). * Use the start, stop and stride values that were set by the constraint evaluator. * * @param datasetName not used * @param specialO not used * @return false (no more data to be read) * @throws IOException * @throws EOFException */ public boolean read(String datasetName, Object specialO) throws IOException { boolean hasStride = false; Array a; try { if (debugRead) { System.out.println("NcSDCharArray read " + ncVar.getFullName()); for (int i = 0; i < numDimensions(); i++) { DArrayDimension d = getDimension(i); System.out.println(" " + d.getEncodedName() + " " + getStart(i) + " " + getStop(i) + " " + getStride(i)); } } // set up the netcdf read int n = numDimensions(); int[] origin = new int[n + 1]; int[] shape = new int[n + 1]; for (int i = 0; i < n; i++) { origin[i] = getStart(i); shape[i] = getStop(i) - getStart(i) + 1; hasStride = hasStride || (getStride(i) > 1); } origin[n] = 0; shape[n] = strLen; a = ncVar.read(origin, shape); if (debugRead) System.out.println(" Read = " + a.getSize() + " elems of type = " + a.getElementType()); // deal with strides using a section if (hasStride) { List<Range> ranges = new ArrayList<>(); for (int i = 0; i < n; i++) { int s = getStride(i); if (s > 1) { // otherwise null, means "take all elements" ranges.add(new Range(0, shape[i], s)); if (debugRead) System.out.println(" Section dim " + i + " stride = " + s); } } ranges.add(null); // get all a = a.section(ranges); if (debugRead) System.out.println(" section size " + a.getSize()); } } catch (InvalidDimensionException e) { log.error("read char array", e); throw new IllegalStateException("NcSDCharArray InvalidDimensionException"); } catch (InvalidRangeException e) { log.error("read char array", e); throw new IllegalStateException("NcSDCharArray InvalidRangeException"); } setData(a); return (false); } public void setData(Array data) { PrimitiveVector pv = getPrimitiveVector(); if (debugRead) System.out.println(" PrimitiveVector type = " + pv.getTemplate() + " pv type = " + pv.getClass().getName()); // this is the case of netcdf char arrays with rank > 1; // these become DODS Arrays of Strings ArrayChar ca = (ArrayChar) data; ArrayChar.StringIterator siter = ca.getStringIterator(); int nelems = siter.getNumElems(); if (debugRead) System.out.println(" set Strings = " + nelems); BaseTypePrimitiveVector btpv = (BaseTypePrimitiveVector) pv; btpv.setLength(nelems); for (int i = 0; i < nelems; i++) { String val = siter.next(); NcSDString ds = new NcSDString("", val); btpv.setValue(i, ds); if (debugReadDetail) System.out.println(" s = " + val + " == " + ds.getValue()); } if (debugRead) System.out.println(" PrimitiveVector len = " + pv.getLength() + " type = " + pv.getTemplate()); setRead(true); } public void serialize(DataOutputStream sink, StructureData sdata, StructureMembers.Member m) throws IOException { setData( sdata.getArray( m)); externalize( sink); } }