Fields Summary |
---|
protected static final String | TYPE_CRCDATA |
protected static final String | TYPE_EXPERIMENTAL |
protected static final String | TYPE_EXTENDED |
protected static final String | TYPE_PADDINGSIZE |
protected static final String | TYPE_UNSYNCHRONISATION |
protected static int | TAG_EXT_HEADER_LENGTH |
protected static int | TAG_EXT_HEADER_CRC_LENGTH |
protected static int | FIELD_TAG_EXT_SIZE_LENGTH |
protected static int | TAG_EXT_HEADER_DATA_LENGTH |
public static final int | MASK_V23_UNSYNCHRONIZATIONID3v2.3 Header bit mask |
public static final int | MASK_V23_EXTENDED_HEADERID3v2.3 Header bit mask |
public static final int | MASK_V23_EXPERIMENTALID3v2.3 Header bit mask |
public static final int | MASK_V23_CRC_DATA_PRESENTID3v2.3 Extended Header bit mask |
public static final int | MASK_V23_EMBEDDED_INFO_FLAGID3v2.3 RBUF frame bit mask |
protected boolean | crcDataFlagCRC Checksum calculated |
protected boolean | experimentalExperiemntal tag |
protected boolean | extendedContains extended header |
private int | crc32Crcdata Checksum in extended header |
private int | paddingSizeTag padding |
protected boolean | unsynchronizationAll frames in the tag uses unsynchronisation |
protected boolean | compressionThe tag is compressed |
public static final byte | RELEASE |
public static final byte | MAJOR_VERSION |
public static final byte | REVISION |
Methods Summary |
---|
protected void | addFrame(AbstractID3v2Frame frame)
try
{
//Special case to handle TDRC frame from V24 that needs breaking up into separate frame in V23
if ((frame.getIdentifier().equals(ID3v24Frames.FRAME_ID_YEAR)) && (frame.getBody() instanceof FrameBodyTDRC))
{
translateFrame(frame);
}
else if (frame instanceof ID3v23Frame)
{
copyFrameIntoMap(frame.getIdentifier(),frame);
}
else
{
ID3v23Frame newFrame = new ID3v23Frame(frame);
copyFrameIntoMap(newFrame.getIdentifier(), newFrame);
}
}
catch (InvalidFrameException ife)
{
logger.log(Level.SEVERE, "Unable to convert frame:" + frame.getIdentifier());
}
|
protected void | copyPrimitives(AbstractID3v2Tag copyObj)Copy primitives applicable to v2.3
logger.config("Copying primitives");
super.copyPrimitives(copyObj);
if (copyObj instanceof ID3v23Tag)
{
ID3v23Tag copyObject = (ID3v23Tag) copyObj;
this.crcDataFlag = copyObject.crcDataFlag;
this.experimental = copyObject.experimental;
this.extended = copyObject.extended;
this.crc32 = copyObject.crc32;
this.paddingSize = copyObject.paddingSize;
}
|
public TagField | createArtworkField(byte[] data, java.lang.String mimeType)Create Artwork
AbstractID3v2Frame frame = createFrame(getFrameAndSubIdFromGenericKey(FieldKey.COVER_ART).getFrameId());
FrameBodyAPIC body = (FrameBodyAPIC) frame.getBody();
body.setObjectValue(DataTypes.OBJ_PICTURE_DATA, data);
body.setObjectValue(DataTypes.OBJ_PICTURE_TYPE, PictureTypes.DEFAULT_ID);
body.setObjectValue(DataTypes.OBJ_MIME_TYPE, mimeType);
body.setObjectValue(DataTypes.OBJ_DESCRIPTION, "");
return frame;
|
public TagField | createField(ID3v23FieldKey id3Key, java.lang.String value)Create Frame for Id3 Key
Only textual data supported at the moment, should only be used with frames that
support a simple string argument.
if (id3Key == null)
{
throw new KeyNotFoundException();
}
return super.doCreateTagField(new FrameAndSubId(id3Key.getFrameId(), id3Key.getSubId()), value);
|
public TagField | createField(org.jaudiotagger.tag.images.Artwork artwork){@inheritDoc}
AbstractID3v2Frame frame = createFrame(getFrameAndSubIdFromGenericKey(FieldKey.COVER_ART).getFrameId());
FrameBodyAPIC body = (FrameBodyAPIC) frame.getBody();
if(!artwork.isLinked())
{
body.setObjectValue(DataTypes.OBJ_PICTURE_DATA, artwork.getBinaryData());
body.setObjectValue(DataTypes.OBJ_PICTURE_TYPE, artwork.getPictureType());
body.setObjectValue(DataTypes.OBJ_MIME_TYPE, artwork.getMimeType());
body.setObjectValue(DataTypes.OBJ_DESCRIPTION, "");
return frame;
}
else
{
try
{
body.setObjectValue(DataTypes.OBJ_PICTURE_DATA,artwork.getImageUrl().getBytes("ISO-8859-1"));
}
catch(UnsupportedEncodingException uoe)
{
throw new RuntimeException(uoe.getMessage());
}
body.setObjectValue(DataTypes.OBJ_PICTURE_TYPE, artwork.getPictureType());
body.setObjectValue(DataTypes.OBJ_MIME_TYPE, FrameBodyAPIC.IMAGE_IS_URL);
body.setObjectValue(DataTypes.OBJ_DESCRIPTION, "");
return frame;
}
|
public ID3v23Frame | createFrame(java.lang.String id)
return new ID3v23Frame(id);
|
public void | createStructure()For representing the MP3File in an XML Format
MP3File.getStructureFormatter().openHeadingElement(TYPE_TAG, getIdentifier());
super.createStructureHeader();
//Header
MP3File.getStructureFormatter().openHeadingElement(TYPE_HEADER, "");
MP3File.getStructureFormatter().addElement(TYPE_UNSYNCHRONISATION, this.isUnsynchronization());
MP3File.getStructureFormatter().addElement(TYPE_EXTENDED, this.extended);
MP3File.getStructureFormatter().addElement(TYPE_EXPERIMENTAL, this.experimental);
MP3File.getStructureFormatter().addElement(TYPE_CRCDATA, this.crc32);
MP3File.getStructureFormatter().addElement(TYPE_PADDINGSIZE, this.paddingSize);
MP3File.getStructureFormatter().closeHeadingElement(TYPE_HEADER);
//Body
super.createStructureBody();
MP3File.getStructureFormatter().closeHeadingElement(TYPE_TAG);
|
public void | deleteField(ID3v23FieldKey id3v23FieldKey)Delete fields with this id3v23FieldKey
if (id3v23FieldKey == null)
{
throw new KeyNotFoundException();
}
super.doDeleteTagField(new FrameAndSubId(id3v23FieldKey.getFrameId(), id3v23FieldKey.getSubId()));
|
public void | deleteField(java.lang.String id)Delete fields with this (frame) id
super.doDeleteTagField(new FrameAndSubId(id,null));
|
public boolean | equals(java.lang.Object obj)Is Tag Equivalent to another tag
if (!(obj instanceof ID3v23Tag))
{
return false;
}
ID3v23Tag object = (ID3v23Tag) obj;
if (this.crc32 != object.crc32)
{
return false;
}
if (this.crcDataFlag != object.crcDataFlag)
{
return false;
}
if (this.experimental != object.experimental)
{
return false;
}
if (this.extended != object.extended)
{
return false;
}
return this.paddingSize == object.paddingSize && super.equals(obj);
|
public java.util.List | getArtworkList(){@inheritDoc}
List<TagField> coverartList = getFields(FieldKey.COVER_ART);
List<Artwork> artworkList = new ArrayList<Artwork>(coverartList.size());
for (TagField next : coverartList)
{
FrameBodyAPIC coverArt = (FrameBodyAPIC) ((AbstractID3v2Frame) next).getBody();
Artwork artwork = ArtworkFactory.getNew();
artwork.setMimeType(coverArt.getMimeType());
artwork.setPictureType(coverArt.getPictureType());
if (coverArt.isImageUrl())
{
artwork.setLinked(true);
artwork.setImageUrl(coverArt.getImageUrl());
}
else
{
artwork.setBinaryData(coverArt.getImageData());
}
artworkList.add(artwork);
}
return artworkList;
|
public int | getCrc32()
return crc32;
|
public java.lang.String | getFirst(ID3v23FieldKey id3v23FieldKey)Retrieve the first value that exists for this id3v23key
if (id3v23FieldKey == null)
{
throw new KeyNotFoundException();
}
FrameAndSubId frameAndSubId = new FrameAndSubId(id3v23FieldKey.getFrameId(), id3v23FieldKey.getSubId());
if (id3v23FieldKey == ID3v23FieldKey.TRACK)
{
AbstractID3v2Frame frame = getFirstField(frameAndSubId.getFrameId());
return String.valueOf(((FrameBodyTRCK)frame.getBody()).getTrackNo());
}
else if (id3v23FieldKey == ID3v23FieldKey.TRACK_TOTAL)
{
AbstractID3v2Frame frame = getFirstField(frameAndSubId.getFrameId());
return String.valueOf(((FrameBodyTRCK)frame.getBody()).getTrackTotal());
}
else if (id3v23FieldKey == ID3v23FieldKey.DISC_NO)
{
AbstractID3v2Frame frame = getFirstField(frameAndSubId.getFrameId());
return String.valueOf(((FrameBodyTPOS)frame.getBody()).getDiscNo());
}
else if (id3v23FieldKey == ID3v23FieldKey.DISC_TOTAL)
{
AbstractID3v2Frame frame = getFirstField(frameAndSubId.getFrameId());
return String.valueOf(((FrameBodyTPOS)frame.getBody()).getDiscTotal());
}
else
{
return super.doGetValueAtIndex(frameAndSubId, 0);
}
|
protected FrameAndSubId | getFrameAndSubIdFromGenericKey(FieldKey genericKey)
ID3v23FieldKey id3v23FieldKey = ID3v23Frames.getInstanceOf().getId3KeyFromGenericKey(genericKey);
if (id3v23FieldKey == null)
{
throw new KeyNotFoundException();
}
return new FrameAndSubId(id3v23FieldKey.getFrameId(), id3v23FieldKey.getSubId());
|
protected ID3Frames | getID3Frames()
return ID3v23Frames.getInstanceOf();
|
public java.lang.String | getIdentifier()
return "ID3v2.30";
|
public byte | getMajorVersion()Retrieve the Major Version
return MAJOR_VERSION;
|
public int | getPaddingSize()
return paddingSize;
|
public java.util.Comparator | getPreferredFrameOrderComparator()
return ID3v23PreferredFrameOrderComparator.getInstanceof();
|
public byte | getRelease()Retrieve the Release
return RELEASE;
|
public byte | getRevision()Retrieve the Revision
return REVISION;
|
public int | getSize()Return frame size based upon the sizes of the tags rather than the physical
no of bytes between start of ID3Tag and start of Audio Data.
TODO this is incorrect, because of subclasses
int size = TAG_HEADER_LENGTH;
if (extended)
{
size += TAG_EXT_HEADER_LENGTH;
if (crcDataFlag)
{
size += TAG_EXT_HEADER_CRC_LENGTH;
}
}
size += super.getSize();
return size;
|
public boolean | isUnsynchronization()
return unsynchronization;
|
public void | read(java.nio.ByteBuffer buffer){@inheritDoc}
int size;
if (!seek(buffer))
{
throw new TagNotFoundException(getIdentifier() + " tag not found");
}
logger.config(getLoggingFilename() + ":" + "Reading ID3v23 tag");
readHeaderFlags(buffer);
// Read the size, this is size of tag not including the tag header
size = ID3SyncSafeInteger.bufferToValue(buffer);
logger.config(ErrorMessage.ID_TAG_SIZE.getMsg(getLoggingFilename(),size));
//Extended Header
if (extended)
{
readExtendedHeader(buffer, size);
}
//Slice Buffer, so position markers tally with size (i.e do not include tagHeader)
ByteBuffer bufferWithoutHeader = buffer.slice();
//We need to synchronize the buffer
if (isUnsynchronization())
{
bufferWithoutHeader = ID3Unsynchronization.synchronize(bufferWithoutHeader);
}
readFrames(bufferWithoutHeader, size);
logger.config(getLoggingFilename() + ":Loaded Frames,there are:" + frameMap.keySet().size());
|
private void | readExtendedHeader(java.nio.ByteBuffer buffer, int size)Read the optional extended header
// Int is 4 bytes.
int extendedHeaderSize = buffer.getInt();
// Extended header without CRC Data
if (extendedHeaderSize == TAG_EXT_HEADER_DATA_LENGTH)
{
//Flag should not be setField , if is log a warning
byte extFlag = buffer.get();
crcDataFlag = (extFlag & MASK_V23_CRC_DATA_PRESENT) != 0;
if (crcDataFlag)
{
logger.warning(ErrorMessage.ID3_TAG_CRC_FLAG_SET_INCORRECTLY.getMsg(getLoggingFilename()));
}
//2nd Flag Byte (not used)
buffer.get();
//Take padding and ext header size off the size to be read
paddingSize=buffer.getInt();
if(paddingSize>0)
{
logger.config(ErrorMessage.ID3_TAG_PADDING_SIZE.getMsg(getLoggingFilename(),paddingSize));
}
size = size - ( paddingSize + TAG_EXT_HEADER_LENGTH);
}
else if (extendedHeaderSize == TAG_EXT_HEADER_DATA_LENGTH + TAG_EXT_HEADER_CRC_LENGTH)
{
logger.config(ErrorMessage.ID3_TAG_CRC.getMsg(getLoggingFilename()));
//Flag should be setField, if nor just act as if it is
byte extFlag = buffer.get();
crcDataFlag = (extFlag & MASK_V23_CRC_DATA_PRESENT) != 0;
if (!crcDataFlag)
{
logger.warning(ErrorMessage.ID3_TAG_CRC_FLAG_SET_INCORRECTLY.getMsg(getLoggingFilename()));
}
//2nd Flag Byte (not used)
buffer.get();
//Take padding size of size to be read
paddingSize = buffer.getInt();
if(paddingSize>0)
{
logger.config(ErrorMessage.ID3_TAG_PADDING_SIZE.getMsg(getLoggingFilename(),paddingSize));
}
size = size - (paddingSize + TAG_EXT_HEADER_LENGTH + TAG_EXT_HEADER_CRC_LENGTH);
//CRC Data
crc32 = buffer.getInt();
logger.config(ErrorMessage.ID3_TAG_CRC_SIZE.getMsg(getLoggingFilename(),crc32));
}
//Extended header size is only allowed to be six or ten bytes so this is invalid but instead
//of giving up lets guess its six bytes and carry on and see if we can read file ok
else
{
logger.warning(ErrorMessage.ID3_EXTENDED_HEADER_SIZE_INVALID.getMsg(getLoggingFilename(), extendedHeaderSize));
buffer.position(buffer.position() - FIELD_TAG_EXT_SIZE_LENGTH);
}
|
protected void | readFrames(java.nio.ByteBuffer byteBuffer, int size)Read the frames
Read from byteBuffer upto size
//Now start looking for frames
ID3v23Frame next;
frameMap = new LinkedHashMap();
encryptedFrameMap = new LinkedHashMap();
//Read the size from the Tag Header
this.fileReadSize = size;
logger.finest(getLoggingFilename() + ":Start of frame body at:" + byteBuffer.position() + ",frames data size is:" + size);
// Read the frames until got to up to the size as specified in header or until
// we hit an invalid frame identifier or padding
while (byteBuffer.position() < size)
{
String id;
try
{
//Read Frame
logger.finest(getLoggingFilename() + ":Looking for next frame at:" + byteBuffer.position());
next = new ID3v23Frame(byteBuffer, getLoggingFilename());
id = next.getIdentifier();
loadFrameIntoMap(id, next);
}
//Found Padding, no more frames
catch (PaddingException ex)
{
logger.config(getLoggingFilename() + ":Found padding starting at:" + byteBuffer.position());
break;
}
//Found Empty Frame, log it - empty frames should not exist
catch (EmptyFrameException ex)
{
logger.warning(getLoggingFilename() + ":Empty Frame:" + ex.getMessage());
this.emptyFrameBytes += ID3v23Frame.FRAME_HEADER_SIZE;
}
catch (InvalidFrameIdentifierException ifie)
{
logger.warning(getLoggingFilename() + ":Invalid Frame Identifier:" + ifie.getMessage());
this.invalidFrames++;
//Don't try and find any more frames
break;
}
//Problem trying to find frame, often just occurs because frameHeader includes padding
//and we have reached padding
catch (InvalidFrameException ife)
{
logger.warning(getLoggingFilename() + ":Invalid Frame:" + ife.getMessage());
this.invalidFrames++;
//Don't try and find any more frames
break;
}
//Failed reading frame but may just have invalid data but correct length so lets carry on
//in case we can read the next frame
catch(InvalidDataTypeException idete)
{
logger.warning(getLoggingFilename() + ":Corrupt Frame:" + idete.getMessage());
this.invalidFrames++;
continue;
}
}
|
private void | readHeaderFlags(java.nio.ByteBuffer buffer)Read header flags
Log info messages for flags that have been set and log warnings when bits have been set for unknown flags
//Allowable Flags
byte flags = buffer.get();
unsynchronization = (flags & MASK_V23_UNSYNCHRONIZATION) != 0;
extended = (flags & MASK_V23_EXTENDED_HEADER) != 0;
experimental = (flags & MASK_V23_EXPERIMENTAL) != 0;
//Not allowable/Unknown Flags
if ((flags & FileConstants.BIT4) != 0)
{
logger.warning(ErrorMessage.ID3_INVALID_OR_UNKNOWN_FLAG_SET.getMsg(getLoggingFilename(), FileConstants.BIT4));
}
if ((flags & FileConstants.BIT3) != 0)
{
logger.warning(ErrorMessage.ID3_INVALID_OR_UNKNOWN_FLAG_SET.getMsg(getLoggingFilename(), FileConstants.BIT3));
}
if ((flags & FileConstants.BIT2) != 0)
{
logger.warning(ErrorMessage.ID3_INVALID_OR_UNKNOWN_FLAG_SET.getMsg(getLoggingFilename(), FileConstants.BIT2));
}
if ((flags & FileConstants.BIT1) != 0)
{
logger.warning(ErrorMessage.ID3_INVALID_OR_UNKNOWN_FLAG_SET.getMsg(getLoggingFilename(), FileConstants.BIT1));
}
if ((flags & FileConstants.BIT0) != 0)
{
logger.warning(ErrorMessage.ID3_INVALID_OR_UNKNOWN_FLAG_SET.getMsg(getLoggingFilename(), FileConstants.BIT0));
}
if (isUnsynchronization())
{
logger.config(ErrorMessage.ID3_TAG_UNSYNCHRONIZED.getMsg(getLoggingFilename()));
}
if (extended)
{
logger.config(ErrorMessage.ID3_TAG_EXTENDED.getMsg(getLoggingFilename()));
}
if (experimental)
{
logger.config(ErrorMessage.ID3_TAG_EXPERIMENTAL.getMsg(getLoggingFilename()));
}
|
protected void | translateFrame(AbstractID3v2Frame frame)This is used when we need to translate a single frame into multiple frames,
currently required for v24 TDRC frames.
FrameBodyTDRC tmpBody = (FrameBodyTDRC) frame.getBody();
ID3v23Frame newFrame;
if (!tmpBody.getYear().equals(""))
{
newFrame = new ID3v23Frame(ID3v23Frames.FRAME_ID_V3_TYER);
((FrameBodyTYER) newFrame.getBody()).setText(tmpBody.getYear());
logger.config("Adding Frame:" + newFrame.getIdentifier());
frameMap.put(newFrame.getIdentifier(), newFrame);
}
if (!tmpBody.getDate().equals(""))
{
newFrame = new ID3v23Frame(ID3v23Frames.FRAME_ID_V3_TDAT);
((FrameBodyTDAT) newFrame.getBody()).setText(tmpBody.getDate());
((FrameBodyTDAT) newFrame.getBody()).setMonthOnly(tmpBody.isMonthOnly());
logger.config("Adding Frame:" + newFrame.getIdentifier());
frameMap.put(newFrame.getIdentifier(), newFrame);
}
if (!tmpBody.getTime().equals(""))
{
newFrame = new ID3v23Frame(ID3v23Frames.FRAME_ID_V3_TIME);
((FrameBodyTIME) newFrame.getBody()).setText(tmpBody.getTime());
((FrameBodyTIME) newFrame.getBody()).setHoursOnly(tmpBody.isHoursOnly());
logger.config("Adding Frame:" + newFrame.getIdentifier());
frameMap.put(newFrame.getIdentifier(), newFrame);
}
|
public void | write(java.io.File file, long audioStartLocation)Write tag to file
TODO:we currently never write the Extended header , but if we did the size calculation in this
method would be slightly incorrect
setLoggingFilename(file.getName());
logger.config("Writing tag to file:"+getLoggingFilename());
//Write Body Buffer
byte[] bodyByteBuffer = writeFramesToBuffer().toByteArray();
logger.config(getLoggingFilename() + ":bodybytebuffer:sizebeforeunsynchronisation:" + bodyByteBuffer.length);
// Unsynchronize if option enabled and unsync required
unsynchronization = TagOptionSingleton.getInstance().isUnsyncTags() && ID3Unsynchronization.requiresUnsynchronization(bodyByteBuffer);
if (isUnsynchronization())
{
bodyByteBuffer = ID3Unsynchronization.unsynchronize(bodyByteBuffer);
logger.config(getLoggingFilename() + ":bodybytebuffer:sizeafterunsynchronisation:" + bodyByteBuffer.length);
}
int sizeIncPadding = calculateTagSize(bodyByteBuffer.length + TAG_HEADER_LENGTH, (int) audioStartLocation);
int padding = sizeIncPadding - (bodyByteBuffer.length + TAG_HEADER_LENGTH);
logger.config(getLoggingFilename() + ":Current audiostart:" + audioStartLocation);
logger.config(getLoggingFilename() + ":Size including padding:" + sizeIncPadding);
logger.config(getLoggingFilename() + ":Padding:" + padding);
ByteBuffer headerBuffer = writeHeaderToBuffer(padding, bodyByteBuffer.length);
writeBufferToFile(file, headerBuffer, bodyByteBuffer, padding, sizeIncPadding, audioStartLocation);
|
public void | write(java.nio.channels.WritableByteChannel channel){@inheritDoc}
logger.config(getLoggingFilename() + ":Writing tag to channel");
byte[] bodyByteBuffer = writeFramesToBuffer().toByteArray();
logger.config(getLoggingFilename() + ":bodybytebuffer:sizebeforeunsynchronisation:" + bodyByteBuffer.length);
// Unsynchronize if option enabled and unsync required
unsynchronization = TagOptionSingleton.getInstance().isUnsyncTags() && ID3Unsynchronization.requiresUnsynchronization(bodyByteBuffer);
if (isUnsynchronization())
{
bodyByteBuffer = ID3Unsynchronization.unsynchronize(bodyByteBuffer);
logger.config(getLoggingFilename() + ":bodybytebuffer:sizeafterunsynchronisation:" + bodyByteBuffer.length);
}
ByteBuffer headerBuffer = writeHeaderToBuffer(0, bodyByteBuffer.length);
channel.write(headerBuffer);
channel.write(ByteBuffer.wrap(bodyByteBuffer));
|
private java.nio.ByteBuffer | writeHeaderToBuffer(int padding, int size)Write the ID3 header to the ByteBuffer.
TODO Calculate the CYC Data Check
TODO Reintroduce Extended Header
// Flags,currently we never calculate the CRC
// and if we dont calculate them cant keep orig values. Tags are not
// experimental and we never createField extended header to keep things simple.
extended = false;
experimental = false;
crcDataFlag = false;
// Create Header Buffer,allocate maximum possible size for the header
ByteBuffer headerBuffer = ByteBuffer.
allocate(TAG_HEADER_LENGTH + TAG_EXT_HEADER_LENGTH + TAG_EXT_HEADER_CRC_LENGTH);
//TAGID
headerBuffer.put(TAG_ID);
//Major Version
headerBuffer.put(getMajorVersion());
//Minor Version
headerBuffer.put(getRevision());
//Flags
byte flagsByte = 0;
if (isUnsynchronization())
{
flagsByte |= MASK_V23_UNSYNCHRONIZATION;
}
if (extended)
{
flagsByte |= MASK_V23_EXTENDED_HEADER;
}
if (experimental)
{
flagsByte |= MASK_V23_EXPERIMENTAL;
}
headerBuffer.put(flagsByte);
//Additional Header Size,(for completeness we never actually write the extended header)
int additionalHeaderSize = 0;
if (extended)
{
additionalHeaderSize += TAG_EXT_HEADER_LENGTH;
if (crcDataFlag)
{
additionalHeaderSize += TAG_EXT_HEADER_CRC_LENGTH;
}
}
//Size As Recorded in Header, don't include the main header length
headerBuffer.put(ID3SyncSafeInteger.valueToBuffer(padding + size + additionalHeaderSize));
//Write Extended Header
if (extended)
{
byte extFlagsByte1 = 0;
byte extFlagsByte2 = 0;
//Contains CRCData
if (crcDataFlag)
{
headerBuffer.putInt(TAG_EXT_HEADER_DATA_LENGTH + TAG_EXT_HEADER_CRC_LENGTH);
extFlagsByte1 |= MASK_V23_CRC_DATA_PRESENT;
headerBuffer.put(extFlagsByte1);
headerBuffer.put(extFlagsByte2);
headerBuffer.putInt(paddingSize);
headerBuffer.putInt(crc32);
}
//Just extended Header
else
{
headerBuffer.putInt(TAG_EXT_HEADER_DATA_LENGTH);
headerBuffer.put(extFlagsByte1);
headerBuffer.put(extFlagsByte2);
//Newly Calculated Padding As Recorded in Extended Header
headerBuffer.putInt(padding);
}
}
headerBuffer.flip();
return headerBuffer;
|