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