raf = diskSpaceCheckingRAFFactory.createNewRAF(storageFile, totalLength, random);
Logger.normal(this, "Creating splitfile storage file for complete-via-truncation: "+storageFile);
} else {
raf = rafFactory.makeRAF(totalLength);
}
RAFLock lock = raf.lockOpen();
try {
for(int i=0;i<segments.length;i++) {
SplitFileFetcherSegmentStorage segment = segments[i];
segment.writeKeysWithChecksum(segmentKeys[i]);
}
if(persistent) {
for(SplitFileFetcherSegmentStorage segment : segments)
segment.writeMetadata();
raf.pwrite(offsetGeneralProgress, generalProgress, 0, generalProgress.length);
keyListener.innerWriteMainBloomFilter(offsetMainBloomFilter);
keyListener.initialWriteSegmentBloomFilters(offsetSegmentBloomFilters);
BucketTools.copyTo(metadataTemp, raf, offsetOriginalMetadata, -1);
metadataTemp.free();
raf.pwrite(offsetOriginalDetails, encodedURI, 0, encodedURI.length);
raf.pwrite(offsetBasicSettings, encodedBasicSettings, 0, encodedBasicSettings.length);
// This bit tricky because version is included in the checksum.
// When the RAF is encrypted, we use HMAC's and this is important.
// FIXME is Fields.bytesToInt etc compatible with DataOutputStream.*?
// FIXME if not, we need something that is ...
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(baos);
dos.writeInt(encodedBasicSettings.length - checksumLength);
byte[] bufToWrite = baos.toByteArray();
baos = new ByteArrayOutputStream();
dos = new DataOutputStream(baos);
dos.writeInt(0); // flags
dos.writeShort(checksumChecker.getChecksumTypeID());
dos.writeInt(VERSION);
byte[] version = baos.toByteArray();
byte[] bufToChecksum = Arrays.copyOf(bufToWrite, bufToWrite.length+version.length);
System.arraycopy(version, 0, bufToChecksum, bufToWrite.length, version.length);
byte[] checksum =
checksumChecker.generateChecksum(bufToChecksum);
// Pointers.
raf.pwrite(offsetBasicSettings + encodedBasicSettings.length, bufToWrite, 0,
bufToWrite.length);
// Checksum.
raf.pwrite(offsetBasicSettings + encodedBasicSettings.length + bufToWrite.length,
checksum, 0, checksum.length);
// Version.
raf.pwrite(offsetBasicSettings + encodedBasicSettings.length + bufToWrite.length +
checksum.length, version, 0, version.length);
// Write magic last.
baos = new ByteArrayOutputStream();
dos = new DataOutputStream(baos);
dos.writeLong(END_MAGIC);
byte[] buf = baos.toByteArray();
raf.pwrite(totalLength - 8, buf, 0, 8);
}
} finally {
lock.unlock();
}
if(logMINOR) Logger.minor(this, "Fetching "+thisKey+" on "+this+" for "+fetcher);
}