/** * How many times do the subfields of this record repeat? This will always be one for * non-repeating fields. * * @return The number of times that the subfields of this record occur in this record. This will * be one for non-repeating fields. */ public int getRepeatCount() { if (!poDefn.isRepeating()) { return 1; } /* -------------------------------------------------------------------- */ /* The occurrence count depends on how many copies of this */ /* field's list of subfields can fit into the data space. */ /* -------------------------------------------------------------------- */ if (poDefn.getFixedWidth() != 0) { return pachData.length / poDefn.getFixedWidth(); } /* -------------------------------------------------------------------- */ /* Note that it may be legal to have repeating variable width */ /* subfields, but I don't have any samples, so I ignore it for */ /* now. */ /* */ /* * The file data/cape_royal_AZ_DEM/1183XREF.DDF has a * repeating */ /* variable length field, but the count is one, so it isn't */ /* much value for testing. */ /* -------------------------------------------------------------------- */ int iOffset = 0; int iRepeatCount = 1; MutableInt nBytesConsumed = new MutableInt(0); while (true) { for (int iSF = 0; iSF < poDefn.getSubfieldCount(); iSF++) { DDFSubfieldDefinition poThisSFDefn = poDefn.getSubfieldDefn(iSF); if (poThisSFDefn.getWidth() > pachData.length - iOffset) { nBytesConsumed.value = poThisSFDefn.getWidth(); } else { byte[] tempData = new byte[pachData.length - iOffset]; System.arraycopy(pachData, iOffset, tempData, 0, tempData.length); poThisSFDefn.getDataLength(tempData, tempData.length, nBytesConsumed); } iOffset += nBytesConsumed.value; if (iOffset > pachData.length) { return iRepeatCount - 1; } } if (iOffset > pachData.length - 2) return iRepeatCount; iRepeatCount++; } }
/** * Fetch raw data pointer for a particular subfield of this field. * * <p>The passed DDFSubfieldDefn (poSFDefn) should be acquired from the DDFFieldDefn corresponding * with this field. This is normally done once before reading any records. This method involves a * series of calls to DDFSubfield::GetDataLength() in order to track through the DDFField data to * that belonging to the requested subfield. This can be relatively expensive. * * <p> * * @param poSFDefn The definition of the subfield for which the raw data pointer is desired. * @param pnMaxBytes The maximum number of bytes that can be accessed from the returned data * pointer is placed in this int, unless it is null. * @param iSubfieldIndex The instance of this subfield to fetch. Use zero (the default) for the * first instance. * @return A pointer into the DDFField's data that belongs to the subfield. This returned pointer * is invalidated by the next record read (DDFRecord::ReadRecord()) and the returned pointer * should not be freed by the application. */ public byte[] getSubfieldData( DDFSubfieldDefinition poSFDefn, MutableInt pnMaxBytes, int iSubfieldIndex) { int iOffset = 0; if (poSFDefn == null) return null; if (iSubfieldIndex > 0 && poDefn.getFixedWidth() > 0) { iOffset = poDefn.getFixedWidth() * iSubfieldIndex; iSubfieldIndex = 0; } MutableInt nBytesConsumed = new MutableInt(0); while (iSubfieldIndex >= 0) { for (int iSF = 0; iSF < poDefn.getSubfieldCount(); iSF++) { DDFSubfieldDefinition poThisSFDefn = poDefn.getSubfieldDefn(iSF); byte[] subPachData = new byte[pachData.length - iOffset]; System.arraycopy(pachData, iOffset, subPachData, 0, subPachData.length); if (poThisSFDefn == poSFDefn && iSubfieldIndex == 0) { if (pnMaxBytes != null) { pnMaxBytes.value = pachData.length - iOffset; } return subPachData; } poThisSFDefn.getDataLength(subPachData, subPachData.length, nBytesConsumed); iOffset += nBytesConsumed.value; } iSubfieldIndex--; } // We didn't find our target subfield or instance! return null; }