/*
* myLib - https://github.com/taktod/myLib
* Copyright (c) 2014 ttProject. All rights reserved.
*
* Licensed under The MIT license.
*/
package com.ttProject.container.mkv;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
import org.apache.log4j.Logger;
import com.ttProject.container.IContainer;
import com.ttProject.nio.channels.IReadChannel;
import com.ttProject.unit.extra.BitConnector;
import com.ttProject.unit.extra.EbmlValue;
/**
* mkvMasterTag
* this tag have some tag inside.
* @author taktod
*/
public abstract class MkvMasterTag extends MkvTag {
/** logger */
@SuppressWarnings("unused")
private Logger logger = Logger.getLogger(MkvMasterTag.class);
/** holding tags. */
private List<MkvTag> childTags = new ArrayList<MkvTag>();
/**
* constructor
* @param tag
* @param size
*/
public MkvMasterTag(Type id, EbmlValue size) {
super(id, size);
}
/**
* {@inheritDoc}
*/
@Override
public void load(IReadChannel channel) throws Exception {
int targetSize = getMkvSize();
IContainer container = null;
while(targetSize > 0 && (container = getMkvTagReader().read(channel)) != null) {
targetSize -= container.getSize();
if(container instanceof MkvTag) {
childTags.add((MkvTag)container);
}
}
super.load(channel);
}
/**
* add child tag
*/
public void addChild(MkvTag tag) {
childTags.add(tag);
super.update();
}
/**
* rev child tag.
* @param i
* @return
*/
public MkvTag removeChild(int i) {
MkvTag removedTag = childTags.remove(i);
super.update();
return removedTag;
}
/**
* ref child tags.
* @return
*/
public List<MkvTag> getChildList() {
return new ArrayList<MkvTag>(childTags);
}
/**
* set the size infinite(for live streaming)
* @param set true:infinite false:not-infinite.
*/
public void setInfinite(boolean set) {
if(set) {
getTagSize().setLong(0xFFFFFFFFFFFFFFL);
}
else {
getTagSize().set(0);
}
super.update();
}
/**
* {@inheritDoc}
* note only reply ebml header and ebml size. child tags will report recursively.
*/
@Override
protected void requestUpdate() throws Exception {
if(getTagSize().getLong() == 0xFFFFFFFFFFFFFFL) {
// reply only for ebml header and ebml size.(this is for segment only.)
// TODO same as getHeaderBuffer()?
BitConnector connector = new BitConnector();
super.setData(connector.connect(getTagId(), getTagSize()));
return;
}
int size = 0;
for(MkvTag tag : childTags) {
tag.getData();
size += tag.getSize();
}
getTagSize().set(size);
BitConnector connector = new BitConnector();
ByteBuffer data = connector.connect(getTagId(), getTagSize());
setSize(data.remaining() + size);
super.setData(data);
}
/**
* {@inheritDoc}
*/
@Override
public String toString(String space) {
StringBuilder data = new StringBuilder();
data.append(super.toString(space));
data.append("*");
return data.toString();
}
}