if (len == 0) {
return;
}
final AttributeIterator dataAttrs = findAttributesByTypeAndName(NTFSAttribute.Types.DATA, streamName);
NTFSAttribute attr = dataAttrs.next();
if (attr == null) {
throw new IOException("Data attribute not found, file record = " + this);
}
if (attr.isResident()) {
if (dataAttrs.next() != null) {
throw new IOException("Resident attribute should be by itself, file record = " + this);
}
final NTFSResidentAttribute resData = (NTFSResidentAttribute) attr;
final int attrLength = resData.getAttributeLength();
if (attrLength < len) {
throw new IOException("File data(" + attrLength + "b) is not large enough to read:" + len + "b");
}
resData.getData(resData.getAttributeOffset() + (int) fileOffset, dest, off, len);
if (log.isDebugEnabled()) {
log.debug("readData: read from resident data");
}
return;
}
// At this point we know that at least the first attribute is non-resident.
// calculate start and end cluster
final int clusterSize = getVolume().getClusterSize();
final long startCluster = fileOffset / clusterSize;
final long endCluster = (fileOffset + len - 1) / clusterSize;
final int nrClusters = (int) (endCluster - startCluster + 1);
final byte[] tmp = new byte[nrClusters * clusterSize];
long clusterWithinNresData = startCluster;
int readClusters = 0;
do {
if (attr.isResident()) {
throw new IOException("Resident attribute should be by itself, file record = " + this);
}
final NTFSNonResidentAttribute nresData = (NTFSNonResidentAttribute) attr;