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{ 031 private static final long serialVersionUID = 5399364372073889764L; 032 033 private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(NC2Datatype.class); 034 035 /** the native datatype */ 036 private DataType nativeType = null; 037 038 /** 039 * Create an Datatype with specified class, size, byte order and sign. The 040 * following list a few example of how to create a Datatype. 041 * <ol> 042 * <li>to create unsigned native integer<br> 043 * NC2Datatype type = new NC2Datatype(Datatype.CLASS_INTEGER, Datatype.NATIVE, Datatype.NATIVE, Datatype.SIGN_NONE);</li> 044 * <li>to create 16-bit signed integer with big endian<br> 045 * NC2Datatype type = new NC2Datatype(Datatype.CLASS_INTEGER, 2, Datatype.ORDER_BE, Datatype.NATIVE);</li> 046 * <li>to create native float<br> 047 * NC2Datatype type = new NC2Datatype(Datatype.CLASS_FLOAT, Datatype.NATIVE, Datatype.NATIVE, Datatype.NATIVE);</li> 048 * <li>to create 64-bit double<br> 049 * NC2Datatype type = new NC2Datatype(Datatype.CLASS_FLOAT, 8, Datatype.NATIVE, Datatype.NATIVE);</li> 050 * </ol> 051 * 052 * @param tclass 053 * the class of the datatype, e.g. CLASS_INTEGER, CLASS_FLOAT and etc. 054 * @param tsize 055 * the size of the datatype in bytes, e.g. for a 32-bit integer, the size is 4. 056 * Valid values are NATIVE or a positive value. 057 * @param torder 058 * the byte order of the datatype. Valid values are ORDER_LE, ORDER_BE, ORDER_VAX, 059 * ORDER_NONE and NATIVE. 060 * @param tsign 061 * the sign of the datatype. Valid values are SIGN_NONE, SIGN_2 and NATIVE. 062 * 063 * @throws Exception 064 * if there is an error 065 */ 066 public NC2Datatype(int tclass, int tsize, int torder, int tsign) throws Exception { 067 super(tclass, tsize, torder, tsign); 068 datatypeDescription = getDescription(); 069 } 070 071 /** 072 * Constructs a NC2Datatype with a given NetCDF3 native datatype object. 073 * 074 * @param theType 075 * the netcdf native datatype. 076 * 077 * @throws Exception 078 * if there is an error 079 */ 080 public NC2Datatype(DataType theType) throws Exception { 081 super(null, -1); 082 log.trace("NC2Datatype: start nc2 type = {}", theType); 083 nativeType = theType; 084 fromNative(0); 085 datatypeDescription = getDescription(); 086 } 087 088 /* 089 * (non-Javadoc) 090 * 091 * @see hdf.object.Datatype#fromNative(long) 092 */ 093 /** 094 * Translate NetCDF3 datatype object into NC2Datatype. 095 * 096 * @param tid the native ID 097 * UNUSED. 098 */ 099 @Override 100 public void fromNative(long tid) { 101 if (nativeType == null) 102 return; 103 104 datatypeOrder = NATIVE; 105 if (nativeType.equals(DataType.CHAR)) { 106 datatypeClass = CLASS_CHAR; 107 datatypeSize = 1; 108 } 109 else if (nativeType.equals(DataType.BYTE)) { 110 datatypeClass = CLASS_INTEGER; 111 datatypeSize = 1; 112 } 113 else if (nativeType.equals(DataType.SHORT)) { 114 datatypeClass = CLASS_INTEGER; 115 datatypeSize = 2; 116 } 117 else if (nativeType.equals(DataType.INT)) { 118 datatypeClass = CLASS_INTEGER; 119 datatypeSize = 4; 120 } 121 else if (nativeType.equals(DataType.LONG)) { 122 datatypeClass = CLASS_INTEGER; 123 datatypeSize = 8; 124 } 125 else if (nativeType.equals(DataType.FLOAT)) { 126 datatypeClass = CLASS_FLOAT; 127 datatypeSize = 4; 128 } 129 else if (nativeType.equals(DataType.DOUBLE)) { 130 datatypeClass = CLASS_FLOAT; 131 datatypeSize = 8; 132 } 133 else if (nativeType.equals(DataType.STRING)) { 134 datatypeClass = CLASS_STRING; 135 datatypeSize = 80; // default length. need to figure out the actual length 136 } 137 else if (nativeType.equals(DataType.OPAQUE)) { 138 datatypeClass = CLASS_OPAQUE; 139 datatypeSize = 1; 140 } 141 142 log.trace("Datatype class={} size={}", datatypeClass, datatypeSize); 143 } 144 145 /** 146 * Allocate an one-dimensional array of byte, short, int, long, float, 147 * double, or String to store data retrieved from an NetCDF3 file based on 148 * the given NetCDF3 datatype and dimension sizes. 149 * 150 * @param dtype 151 * the NetCDF3 datatype object. 152 * @param datasize 153 * the size of the data array 154 * 155 * @return an array of 'datasize' numbers of datatype. 156 * 157 * @throws OutOfMemoryError 158 * if the array cannot be allocated 159 */ 160 public static final Object allocateArray(DataType dtype, int datasize) throws OutOfMemoryError { 161 if ((datasize <= 0) || (dtype == null)) { 162 log.debug("datasize <= 0"); 163 return null; 164 } 165 166 Object data = null; 167 168 if (dtype.equals(DataType.BYTE)) 169 data = new byte[datasize]; 170 else if (dtype.equals(DataType.SHORT)) 171 data = new short[datasize]; 172 else if (dtype.equals(DataType.INT)) 173 data = new int[datasize]; 174 else if (dtype.equals(DataType.LONG)) 175 data = new long[datasize]; 176 else if (dtype.equals(DataType.FLOAT)) 177 data = new float[datasize]; 178 else if (dtype.equals(DataType.DOUBLE)) 179 data = new double[datasize]; 180 else if (dtype.equals(DataType.STRING)) 181 data = new String[datasize]; 182 183 return data; 184 } 185 186 /* 187 * (non-Javadoc) 188 * 189 * @see hdf.object.Datatype#getDatatypeDescription() 190 */ 191 @Override 192 public String getDescription() { 193 if (datatypeDescription != null) 194 return datatypeDescription; 195 196 String description = null; 197 198 if (nativeType == null) 199 description = "Unknown data type."; 200 201 description = nativeType.toString(); 202 203 return description; 204 } 205 206 /* 207 * (non-Javadoc) 208 * 209 * @see hdf.object.Datatype#isUnsigned() 210 */ 211 @Override 212 public boolean isUnsigned() { 213 if (nativeType.isNumeric()) 214 return false; 215 else 216 return false; 217 } 218 219 @Override 220 public boolean isText() { 221 return (nativeType == DataType.CHAR); 222 } 223 224 /* 225 * (non-Javadoc) 226 * @see hdf.object.Datatype#createNative() 227 */ 228 @Override 229 public long createNative() { 230 if (datatypeClass == CLASS_INTEGER) { 231 if (datatypeSize == 1) 232 nativeType = DataType.BYTE; 233 else if (datatypeSize == 2) 234 nativeType = DataType.SHORT; 235 else if (datatypeSize == 4) 236 nativeType = DataType.INT; 237 else if (datatypeSize == 8) 238 nativeType = DataType.LONG; 239 } 240 else if (datatypeClass == CLASS_FLOAT) { 241 if (datatypeSize == 4) 242 nativeType = DataType.FLOAT; 243 else if (datatypeSize == 8) 244 nativeType = DataType.DOUBLE; 245 } 246 else if (datatypeClass == CLASS_STRING) { 247 nativeType = DataType.STRING; 248 } 249 else { 250 log.debug("createNative(): unknown datatype class {}", datatypeClass); 251 } 252 253 return -1; 254 } 255 256 /* 257 * (non-Javadoc) 258 * 259 * @see hdf.object.Datatype#close(int) 260 */ 261 @Override 262 public void close(long id) { 263 // No implementation 264 } 265 266 // Implementing MetaDataContainer 267 /** 268 * Retrieves the object's metadata, such as attributes, from the file. 269 * 270 * Metadata, such as attributes, is stored in a List. 271 * 272 * @param attrPropList 273 * the list of properties to get 274 * 275 * @return the list of metadata objects. 276 * 277 * @throws Exception 278 * if the metadata can not be retrieved 279 */ 280 @SuppressWarnings("rawtypes") 281 public List getMetadata(int... attrPropList) throws Exception { 282 throw new UnsupportedOperationException("getMetadata(int... attrPropList) is not supported"); 283 } 284 285 /** 286 * Check if the object has any attributes attached. 287 * 288 * @return true if it has any attributes, false otherwise. 289 */ 290 @Override 291 public boolean hasAttribute() { 292 return false; 293 } 294}