001/***************************************************************************** 002 * Copyright by The HDF Group. * 003 * Copyright by the Board of Trustees of the University of Illinois. * 004 * All rights reserved. * 005 * * 006 * This file is part of the HDF Java Products distribution. * 007 * The full copyright notice, including terms governing use, modification, * 008 * and redistribution, is contained in the files COPYING and Copyright.html. * 009 * COPYING can be found at the root of the source code distribution tree. * 010 * Or, see https://support.hdfgroup.org/products/licenses.html * 011 * If you do not have access to either file, you may request a copy from * 012 * help@hdfgroup.org. * 013 ****************************************************************************/ 014 015package hdf.object.nc2; 016 017import java.util.List; 018 019import hdf.object.Datatype; 020import ucar.ma2.DataType; 021 022/** 023 * Datatype encapsulates information of a datatype. Information includes the 024 * class, size, endian of a datatype. 025 * 026 * @version 1.1 9/4/2007 027 * @author Peter X. Cao 028 */ 029public class NC2Datatype extends Datatype { 030 private static final long serialVersionUID = 5399364372073889764L; 031 032 private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(NC2Datatype.class); 033 034 DataType nativeType = null; 035 036 /** 037 * Create an Datatype with specified class, size, byte order and sign. The 038 * following list a few example of how to create a Datatype. 039 * <ol> 040 * <li>to create unsigned native integer<br> 041 * NC2Datatype type = new NC2Datatype(Datatype.CLASS_INTEGER, Datatype.NATIVE, Datatype.NATIVE, Datatype.SIGN_NONE);</li> 042 * <li>to create 16-bit signed integer with big endian<br> 043 * NC2Datatype type = new NC2Datatype(Datatype.CLASS_INTEGER, 2, Datatype.ORDER_BE, Datatype.NATIVE);</li> 044 * <li>to create native float<br> 045 * NC2Datatype type = new NC2Datatype(Datatype.CLASS_FLOAT, Datatype.NATIVE, Datatype.NATIVE, Datatype.NATIVE);</li> 046 * <li>to create 64-bit double<br> 047 * NC2Datatype type = new NC2Datatype(Datatype.CLASS_FLOAT, 8, Datatype.NATIVE, Datatype.NATIVE);</li> 048 * </ol> 049 * 050 * @param tclass 051 * the class of the datatype, e.g. CLASS_INTEGER, CLASS_FLOAT and etc. 052 * @param tsize 053 * the size of the datatype in bytes, e.g. for a 32-bit integer, the size is 4. 054 * Valid values are NATIVE or a positive value. 055 * @param torder 056 * the byte order of the datatype. Valid values are ORDER_LE, ORDER_BE, ORDER_VAX, 057 * ORDER_NONE and NATIVE. 058 * @param tsign 059 * the sign of the datatype. Valid values are SIGN_NONE, SIGN_2 and NATIVE. 060 * 061 * @throws Exception 062 * if there is an error 063 */ 064 public NC2Datatype(int tclass, int tsize, int torder, int tsign) throws Exception { 065 super(tclass, tsize, torder, tsign); 066 datatypeDescription = getDescription(); 067 } 068 069 /** 070 * Constructs a NC2Datatype with a given NetCDF3 native datatype object. 071 * 072 * @param theType 073 * the netcdf native datatype. 074 * 075 * @throws Exception 076 * if there is an error 077 */ 078 public NC2Datatype(DataType theType) throws Exception { 079 super(null, -1); 080 log.trace("NC2Datatype: start nc2 type = {}", theType); 081 nativeType = theType; 082 fromNative(0); 083 datatypeDescription = getDescription(); 084 } 085 086 /* 087 * (non-Javadoc) 088 * 089 * @see hdf.object.DataFormat#hasAttribute() 090 */ 091 @Override 092 public boolean hasAttribute() { 093 return false; 094 } 095 096 /* 097 * (non-Javadoc) 098 * 099 * @see hdf.object.Datatype#fromNative(long) 100 */ 101 /** 102 * Translate NetCDF3 datatype object into NC2Datatype. 103 * 104 * @param tid the native ID 105 * UNUSED. 106 */ 107 @Override 108 public void fromNative(long tid) 109 { 110 if (nativeType == null) { 111 return; 112 } 113 114 datatypeOrder = NATIVE; 115 if (nativeType.equals(DataType.CHAR)) { 116 datatypeClass = CLASS_CHAR; 117 datatypeSize = 1; 118 } 119 else if (nativeType.equals(DataType.BYTE)) { 120 datatypeClass = CLASS_INTEGER; 121 datatypeSize = 1; 122 } 123 else if (nativeType.equals(DataType.SHORT)) { 124 datatypeClass = CLASS_INTEGER; 125 datatypeSize = 2; 126 } 127 else if (nativeType.equals(DataType.INT)) { 128 datatypeClass = CLASS_INTEGER; 129 datatypeSize = 4; 130 } 131 else if (nativeType.equals(DataType.LONG)) { 132 datatypeClass = CLASS_INTEGER; 133 datatypeSize = 8; 134 } 135 else if (nativeType.equals(DataType.FLOAT)) { 136 datatypeClass = CLASS_FLOAT; 137 datatypeSize = 4; 138 } 139 else if (nativeType.equals(DataType.DOUBLE)) { 140 datatypeClass = CLASS_FLOAT; 141 datatypeSize = 8; 142 } 143 else if (nativeType.equals(DataType.STRING)) { 144 datatypeClass = CLASS_STRING; 145 datatypeSize = 80; // default length. need to figure out the actual length 146 } 147 else if (nativeType.equals(DataType.OPAQUE)) { 148 datatypeClass = CLASS_OPAQUE; 149 datatypeSize = 1; 150 } 151 152 log.trace("Datatype class={} size={}", datatypeClass, datatypeSize); 153 } 154 155 /** 156 * Allocate an one-dimensional array of byte, short, int, long, float, 157 * double, or String to store data retrieved from an NetCDF3 file based on 158 * the given NetCDF3 datatype and dimension sizes. 159 * 160 * @param dtype 161 * the NetCDF3 datatype object. 162 * @param datasize 163 * the size of the data array 164 * 165 * @return an array of 'datasize' numbers of datatype. 166 * 167 * @throws OutOfMemoryError 168 * if the array cannot be allocated 169 */ 170 public static final Object allocateArray(DataType dtype, int datasize) 171 throws OutOfMemoryError { 172 if ((datasize <= 0) || (dtype == null)) { 173 log.debug("datasize <= 0"); 174 return null; 175 } 176 177 Object data = null; 178 179 if (dtype.equals(DataType.BYTE)) { 180 data = new byte[datasize]; 181 } 182 else if (dtype.equals(DataType.SHORT)) { 183 data = new short[datasize]; 184 } 185 else if (dtype.equals(DataType.INT)) { 186 data = new int[datasize]; 187 } 188 else if (dtype.equals(DataType.LONG)) { 189 data = new long[datasize]; 190 } 191 else if (dtype.equals(DataType.FLOAT)) { 192 data = new float[datasize]; 193 } 194 else if (dtype.equals(DataType.DOUBLE)) { 195 data = new double[datasize]; 196 } 197 else if (dtype.equals(DataType.STRING)) { 198 data = new String[datasize]; 199 } 200 201 return data; 202 } 203 204 /* 205 * (non-Javadoc) 206 * 207 * @see hdf.object.Datatype#getDatatypeDescription() 208 */ 209 @Override 210 public String getDescription() { 211 if (datatypeDescription != null) { 212 return datatypeDescription; 213 } 214 215 String description = null; 216 217 if (nativeType == null) { 218 description = "Unknown data type."; 219 } 220 221 description = nativeType.toString(); 222 223 return description; 224 } 225 226 /* 227 * (non-Javadoc) 228 * 229 * @see hdf.object.Datatype#isUnsigned() 230 */ 231 @Override 232 public boolean isUnsigned() { 233 if (nativeType.isNumeric()) 234 return false; 235 else 236 return false; 237 } 238 239 @Override 240 public boolean isText() { 241 return (nativeType == DataType.CHAR); 242 } 243 244 /* 245 * (non-Javadoc) 246 * @see hdf.object.Datatype#createNative() 247 */ 248 @Override 249 public long createNative() 250 { 251 if (datatypeClass == CLASS_INTEGER) { 252 if (datatypeSize == 1) { 253 nativeType = DataType.BYTE; 254 } 255 else if (datatypeSize == 2) { 256 nativeType = DataType.SHORT; 257 } 258 else if (datatypeSize == 4) { 259 nativeType = DataType.INT; 260 } 261 else if (datatypeSize == 8) { 262 nativeType = DataType.LONG; 263 } 264 } 265 else if (datatypeClass == CLASS_FLOAT) { 266 if (datatypeSize == 4) { 267 nativeType = DataType.FLOAT; 268 } 269 else if (datatypeSize == 8) { 270 nativeType = DataType.DOUBLE; 271 } 272 } 273 else if (datatypeClass == CLASS_STRING) { 274 nativeType = DataType.STRING; 275 } 276 else { 277 log.debug("createNative(): unknown datatype class {}", datatypeClass); 278 } 279 280 return -1; 281 } 282 283 /* 284 * (non-Javadoc) 285 * 286 * @see hdf.object.Datatype#close(int) 287 */ 288 @Override 289 public void close(long id) { 290 // No implementation 291 } 292 293 // Implementing DataFormat 294 @SuppressWarnings("rawtypes") 295 public List getMetadata(int... attrPropList) throws Exception { 296 throw new UnsupportedOperationException("getMetadata(int... attrPropList) is not supported"); 297 } 298}