📄 ddfsubfielddefinition.java
字号:
/****************************************************************************** * Copyright (c) 1999, Frank Warmerdam * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ******************************************************************************/package com.bbn.openmap.dataAccess.iso8211;import com.bbn.openmap.MoreMath;import com.bbn.openmap.layer.vpf.MutableInt;import com.bbn.openmap.util.Debug;/** * Information from the DDR record describing one subfield of a * DDFFieldDefn. All subfields of a field will occur in each occurance * of that field (as a DDFField) in a DDFRecord. Subfield's actually * contain formatted data (as instances within a record). */public class DDFSubfieldDefinition implements DDFConstants { protected String pszName; // a.k.a. subfield mnemonic protected String pszFormatString; protected DDFDataType eType; protected int eBinaryFormat; /** * bIsVariable determines whether we using the chFormatDelimeter * (true), or the fixed width (false). */ protected boolean bIsVariable; protected char chFormatDelimeter; protected int nFormatWidth; public interface DDFBinaryFormat { public final static int NotBinary = 0; public final static int UInt = 1; public final static int SInt = 2; public final static int FPReal = 3; public final static int FloatReal = 4; public final static int FloatComplex = 5; } public int getWidth() { return nFormatWidth; } /** Get pointer to subfield name. */ public String getName() { return pszName; } /** Get pointer to subfield format string */ public String getFormat() { return pszFormatString; } /** * Get the general type of the subfield. This can be used to * determine which of ExtractFloatData(), ExtractIntData() or * ExtractStringData() should be used. * * @return The subfield type. One of DDFInt, DDFFloat, DDFString * or DDFBinaryString. */ public DDFDataType getType() { return eType; } public DDFSubfieldDefinition() { pszName = null; bIsVariable = true; nFormatWidth = 0; chFormatDelimeter = DDF_UNIT_TERMINATOR; eBinaryFormat = DDFBinaryFormat.NotBinary; eType = DDFDataType.DDFString; pszFormatString = new String(""); } /** * Set the name of the subfield. */ public void setName(String pszNewName) { pszName = pszNewName.trim(); } /** * While interpreting the format string we don't support: * <UL> * <LI>Passing an explicit terminator for variable length field. * <LI>'X' for unused data ... this should really be filtered * <LI>out by DDFFieldDefinition.applyFormats(), but isn't. * <LI>'B' bitstrings that aren't a multiple of eight. * </UL> */ public boolean setFormat(String pszFormat) { pszFormatString = pszFormat; if (Debug.debugging("iso8211")) { Debug.output("DDFSubfieldDefinition.setFormat(" + pszFormat + ")"); } /* -------------------------------------------------------------------- */ /* These values will likely be used. */ /* -------------------------------------------------------------------- */ if (pszFormatString.length() > 1 && pszFormatString.charAt(1) == '(') { // Need to loop through characters to grab digits, and // then get integer version. If we look a the atoi code, // it checks for non-digit characters and then stops. int i = 3; for (; i < pszFormat.length() && Character.isDigit(pszFormat.charAt(i)); i++) { } nFormatWidth = Integer.parseInt(pszFormat.substring(2, i)); bIsVariable = (nFormatWidth == 0); } else { bIsVariable = true; } /* -------------------------------------------------------------------- */ /* Interpret the format string. */ /* -------------------------------------------------------------------- */ switch (pszFormatString.charAt(0)) { case 'A': case 'C': // It isn't clear to me how this is different than // 'A' eType = DDFDataType.DDFString; break; case 'R': eType = DDFDataType.DDFFloat; break; case 'I': case 'S': eType = DDFDataType.DDFInt; break; case 'B': case 'b': // Is the width expressed in bits? (is it a bitstring) bIsVariable = false; if (pszFormatString.charAt(1) == '(') { int numEndIndex = 2; for (; numEndIndex < pszFormatString.length() && Character.isDigit(pszFormatString.charAt(numEndIndex)); numEndIndex++) { } String numberString = pszFormatString.substring(2, numEndIndex); nFormatWidth = Integer.valueOf(numberString).intValue(); if (nFormatWidth % 8 != 0) { Debug.error("DDFSubfieldDefinition.setFormat() problem with " + pszFormatString.charAt(0) + " not being modded with 8 evenly"); return false; } nFormatWidth = Integer.parseInt(numberString) / 8; eBinaryFormat = DDFBinaryFormat.SInt; // good // default, // works for // SDTS. if (nFormatWidth < 5) { eType = DDFDataType.DDFInt; } else { eType = DDFDataType.DDFBinaryString; } } else { // or do we have a binary type indicator? (is it binary) eBinaryFormat = (int) (pszFormatString.charAt(1) - '0'); int numEndIndex = 2; for (; numEndIndex < pszFormatString.length() && Character.isDigit(pszFormatString.charAt(numEndIndex)); numEndIndex++) { } nFormatWidth = Integer.valueOf(pszFormatString.substring(2, numEndIndex)).intValue(); if (eBinaryFormat == DDFBinaryFormat.SInt || eBinaryFormat == DDFBinaryFormat.UInt) { eType = DDFDataType.DDFInt; } else { eType = DDFDataType.DDFFloat; } } break; case 'X': // 'X' is extra space, and shouldn't be directly assigned // to a // subfield ... I haven't encountered it in use yet // though. Debug.error("DDFSubfieldDefinition: Format type of " + pszFormatString.charAt(0) + " not supported."); return false; default: Debug.error("DDFSubfieldDefinition: Format type of " + pszFormatString.charAt(0) + " not recognised."); return false; } return true; } /** * Write out subfield definition info. A variety of information * about this field definition is written to the give debugging * file handle. */ public String toString() { StringBuffer buf = new StringBuffer(" DDFSubfieldDefn:\n"); buf.append(" Label = " + pszName + "\n"); buf.append(" FormatString = " + pszFormatString + "\n"); return buf.toString(); } /** * Scan for the end of variable length data. Given a pointer to * the data for this subfield (from within a DDFRecord) this * method will return the number of bytes which are data for this * subfield. The number of bytes consumed as part of this field * can also be fetched. This number may be one longer than the * length if there is a terminator character used. * <p> * * This method is mainly for internal use, or for applications * which want the raw binary data to interpret themselves. * Otherwise use one of ExtractStringData(), ExtractIntData() or * ExtractFloatData(). * * @param pachSourceData The pointer to the raw data for this * field. This may have come from DDFRecord::GetData(), * taking into account skip factors over previous subfields * data. * @param nMaxBytes The maximum number of bytes that are * accessable after pachSourceData. * @param pnConsumedBytes the number of bytes used. * * @return The number of bytes at pachSourceData which are actual * data for this record (not including unit, or field * terminator). */ public int getDataLength(byte[] pachSourceData, int nMaxBytes, MutableInt pnConsumedBytes) { if (!bIsVariable) { if (nFormatWidth > nMaxBytes) { Debug.error("DDFSubfieldDefinition: Only " + nMaxBytes + " bytes available for subfield " + pszName + " with format string " + pszFormatString + " ... returning shortened data."); if (pnConsumedBytes != null) { pnConsumedBytes.value = nMaxBytes; } return nMaxBytes; } else { if (pnConsumedBytes != null) { pnConsumedBytes.value = nFormatWidth; } return nFormatWidth; } } else { int nLength = 0; boolean bCheckFieldTerminator = true; /* * We only check for the field terminator because of some * buggy datasets with missing format terminators. * However, we have found the field terminator is a legal * character within the fields of some extended datasets * (such as JP34NC94.000). So we don't check for the field * terminator if the field appears to be multi-byte which * we established by the first character being out of the * ASCII printable range (32-127). */ if (pachSourceData[0] < 32 || pachSourceData[0] >= 127) { bCheckFieldTerminator = false; } while (nLength < nMaxBytes && pachSourceData[nLength] != chFormatDelimeter) { if (bCheckFieldTerminator && pachSourceData[nLength] == DDF_FIELD_TERMINATOR) break; nLength++; } if (pnConsumedBytes != null) { if (nMaxBytes == 0) { pnConsumedBytes.value = nLength; } else { pnConsumedBytes.value = nLength + 1; } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -