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