public void write(Tag tag, RandomAccessFile raf, RandomAccessFile rafTemp) throws CannotReadException, CannotWriteException, IOException {
//logger.info("Starting to write file:");
//1st Page:Identification Header
//logger.fine("Read 1st Page:identificationHeader:");
OggPageHeader pageHeader = OggPageHeader.read(raf);
raf.seek(0);
//Write 1st page (unchanged) and place writer pointer at end of data
rafTemp.getChannel().transferFrom(raf.getChannel(), 0, pageHeader.getPageLength() + OggPageHeader.OGG_PAGE_HEADER_FIXED_LENGTH + pageHeader.getSegmentTable().length);
rafTemp.skipBytes(pageHeader.getPageLength() + OggPageHeader.OGG_PAGE_HEADER_FIXED_LENGTH + pageHeader.getSegmentTable().length);
//logger.fine("Written identificationHeader:");
//2nd page:Comment and Setup if there is enough room, may also (although not normally) contain audio frames
OggPageHeader secondPageHeader = OggPageHeader.read(raf);
//2nd Page:Store the end of Header
long secondPageHeaderEndPos = raf.getFilePointer();
//logger.fine("Read 2nd Page:comment and setup and possibly audio:Header finishes at file position:" + secondPageHeaderEndPos);
//Get header sizes
raf.seek(0);
OggVorbisTagReader.OggVorbisHeaderSizes vorbisHeaderSizes = reader.readOggVorbisHeaderSizes(raf);
//Convert the OggVorbisComment header to raw packet data
ByteBuffer newComment = tc.convert(tag);
//Compute new comment length(this may need to be spread over multiple pages)
int newCommentLength = newComment.capacity();
//Calculate new size of new 2nd page
int newSecondPageDataLength = vorbisHeaderSizes.getSetupHeaderSize() + newCommentLength + vorbisHeaderSizes.getExtraPacketDataSize();
//logger.fine("Old 2nd Page no of packets: " + secondPageHeader.getPacketList().size());
//logger.fine("Old 2nd Page size: " + secondPageHeader.getPageLength());
// logger.fine("Old last packet incomplete: " + secondPageHeader.isLastPacketIncomplete());
//logger.fine("Setup Header Size: " + vorbisHeaderSizes.getSetupHeaderSize());
// logger.fine("Extra Packets: " + vorbisHeaderSizes.getExtraPacketList().size());
//logger.fine("Extra Packet Size: " + vorbisHeaderSizes.getExtraPacketDataSize());
//logger.fine("Old comment: " + vorbisHeaderSizes.getCommentHeaderSize());
//logger.fine("New comment: " + newCommentLength);
//logger.fine("New Page Data Size: " + newSecondPageDataLength);
//Second Page containing new vorbis, setup and possibly some extra packets can fit on one page
if (isCommentAndSetupHeaderFitsOnASinglePage(newCommentLength, vorbisHeaderSizes.getSetupHeaderSize(), vorbisHeaderSizes.getExtraPacketList())) {
//And if comment and setup header originally fitted on both, the length of the 2nd
//page must be less than maximum size allowed
//AND
//there must be two packets with last being complete because they may have
//elected to split the setup over multiple pages instead of using up whole page - (as long
//as the last lacing value is 255 they can do this)
// OR
//There are more than the packets in which case have complete setup header and some audio packets
//we dont care if the last audio packet is split on next page as long as we preserve it
if ((secondPageHeader.getPageLength() < OggPageHeader.MAXIMUM_PAGE_DATA_SIZE) && (((secondPageHeader.getPacketList().size() == 2) && (!secondPageHeader.isLastPacketIncomplete())) || (secondPageHeader.getPacketList().size() > 2))) {
//logger.info("Header and Setup remain on single page:");
replaceSecondPageOnly(vorbisHeaderSizes, newCommentLength, newSecondPageDataLength, secondPageHeader, newComment, secondPageHeaderEndPos, raf, rafTemp);
}
//Original 2nd page spanned multiple pages so more work to do
else {