AsfExtHeaderModifierpublic class AsfExtHeaderModifier extends Object implements ChunkModifierThis modifier manipulates an ASF header extension object. |
Fields Summary |
---|
private final List | modifierListList of modifiers which are to be applied to contained chunks. |
Constructors Summary |
---|
public AsfExtHeaderModifier(List modifiers)Creates an instance.
assert modifiers != null;
this.modifierList = new ArrayList<ChunkModifier>(modifiers);
|
Methods Summary |
---|
private void | copyChunk(org.jaudiotagger.audio.asf.data.GUID guid, java.io.InputStream source, java.io.OutputStream destination)Simply copies a chunk from source to
destination .
The method assumes, that the GUID has already been read and will write
the provided one to the destination.
The chunk length however will be read and used to determine the amount of
bytes to copy.
final long chunkSize = Utils.readUINT64(source);
destination.write(guid.getBytes());
Utils.writeUINT64(chunkSize, destination);
Utils.copy(source, destination, chunkSize - 24);
| public boolean | isApplicable(org.jaudiotagger.audio.asf.data.GUID guid){@inheritDoc}
return GUID.GUID_HEADER_EXTENSION.equals(guid);
| public ModificationResult | modify(org.jaudiotagger.audio.asf.data.GUID guid, java.io.InputStream source, java.io.OutputStream destination){@inheritDoc}
assert GUID.GUID_HEADER_EXTENSION.equals(guid);
long difference = 0;
final List<ChunkModifier> modders = new ArrayList<ChunkModifier>(
this.modifierList);
final Set<GUID> occuredGuids = new HashSet<GUID>();
occuredGuids.add(guid);
final BigInteger chunkLen = Utils.readBig64(source);
final GUID reserved1 = Utils.readGUID(source);
final int reserved2 = Utils.readUINT16(source);
final long dataSize = Utils.readUINT32(source);
assert dataSize == 0 || dataSize >= 24;
assert chunkLen.subtract(BigInteger.valueOf(46)).longValue() == dataSize;
/*
* Stream buffer for the chunk list
*/
final ByteArrayOutputStream bos = new ByteArrayOutputStream();
/*
* Stream which counts read bytes. Dirty but quick way of implementing
* this.
*/
final CountingInputStream cis = new CountingInputStream(source);
while (cis.getReadCount() < dataSize) {
// read GUID
final GUID curr = Utils.readGUID(cis);
boolean handled = false;
for (int i = 0; i < modders.size() && !handled; i++) {
if (modders.get(i).isApplicable(curr)) {
final ModificationResult modRes = modders.get(i).modify(
curr, cis, bos);
difference += modRes.getByteDifference();
occuredGuids.addAll(modRes.getOccuredGUIDs());
modders.remove(i);
handled = true;
}
}
if (!handled) {
occuredGuids.add(curr);
copyChunk(curr, cis, bos);
}
}
// Now apply the left modifiers.
for (final ChunkModifier curr : modders) {
// chunks, which were not in the source file, will be added to the
// destination
final ModificationResult result = curr.modify(null, null, bos);
difference += result.getByteDifference();
occuredGuids.addAll(result.getOccuredGUIDs());
}
destination.write(GUID.GUID_HEADER_EXTENSION.getBytes());
Utils.writeUINT64(chunkLen.add(BigInteger.valueOf(difference))
.longValue(), destination);
destination.write(reserved1.getBytes());
Utils.writeUINT16(reserved2, destination);
Utils.writeUINT32(dataSize + difference, destination);
destination.write(bos.toByteArray());
return new ModificationResult(0, difference, occuredGuids);
|
|