package org.jcodec.containers.mp4.boxes;
import static org.jcodec.common.JCodecUtil2.asciiString;
import org.jcodec.common.io.NIOUtils;
import org.jcodec.platform.Platform;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* This class is part of JCodec ( www.jcodec.org ) This software is distributed
* under FreeBSD License
*
* @author The JCodec project
*
*/
public class AliasBox extends FullBox {
public final static int DirectoryName = 0;
public final static int DirectoryIDs = 1; // parent & higher directory ids
// '/' is not counted, one
// unsigned32 for each dir
public final static int AbsolutePath = 2;
public final static int AppleShareZoneName = 3;
public final static int AppleShareServerName = 4;
public final static int AppleShareUserName = 5;
public final static int DriverName = 6;
public final static int RevisedAppleShare = 9;
public final static int AppleRemoteAccessDialup = 10;
public final static int UNIXAbsolutePath = 18;
public final static int UTF16AbsolutePath = 14;
public final static int UFT16VolumeName = 15; // 26
public final static int VolumeMountPoint = 19; // 1
private String type;
private short recordSize;
private short version;
private short kind;
private String volumeName;
private int volumeCreateDate;
private short volumeSignature;
private short volumeType;
private int parentDirId;
private String fileName;
private int fileNumber;
private int createdLocalDate;
private String fileTypeName;
private String creatorName;
private short nlvlFrom;
private short nlvlTo;
private int volumeAttributes;
private short fsId;
private List<ExtraField> extra;
public static String fourcc() {
return "alis";
}
private static Set<Integer> utf16 = new HashSet<Integer>();
static {
utf16.add(14);
utf16.add(15);
}
public static class ExtraField {
short type;
int len;
byte[] data;
public ExtraField(short type, int len, byte[] bs) {
this.type = type;
this.len = len;
this.data = bs;
}
public String toString() {
return Platform.stringFromCharset4(data, 0, len, utf16.contains(type) ? Charset.forName("UTF-16") : Charset.forName("UTF-8"));
}
}
public AliasBox(Header atom) {
super(atom);
}
public void parse(ByteBuffer is) {
super.parse(is);
if ((flags & 0x1) != 0) // self ref
return;
type = NIOUtils.readString(is, 4);
recordSize = is.getShort();
version = is.getShort();
kind = is.getShort();
volumeName = NIOUtils.readPascalStringL(is, 27);
volumeCreateDate = is.getInt();
volumeSignature = is.getShort();
volumeType = is.getShort();
parentDirId = is.getInt();
fileName = NIOUtils.readPascalStringL(is, 63);
fileNumber = is.getInt();
createdLocalDate = is.getInt();
fileTypeName = NIOUtils.readString(is, 4);
creatorName = NIOUtils.readString(is, 4);
nlvlFrom = is.getShort();
nlvlTo = is.getShort();
volumeAttributes = is.getInt();
fsId = is.getShort();
NIOUtils.skip(is, 10);
extra = new ArrayList<ExtraField>();
while (true) {
short type = is.getShort();
if (type == -1)
break;
int len = is.getShort();
byte[] bs = NIOUtils.toArray(NIOUtils.read(is, (len + 1) & 0xfffffffe));
if (bs == null)
break;
extra.add(new ExtraField(type, len, bs));
}
}
protected void doWrite(ByteBuffer out) {
super.doWrite(out);
if ((flags & 0x1) != 0) // self ref
return;
out.put(asciiString(type), 0, 4);
out.putShort(recordSize);
out.putShort(version);
out.putShort(kind);
NIOUtils.writePascalStringL(out, volumeName, 27);
out.putInt(volumeCreateDate);
out.putShort(volumeSignature);
out.putShort(volumeType);
out.putInt(parentDirId);
NIOUtils.writePascalStringL(out, fileName, 63);
out.putInt(fileNumber);
out.putInt(createdLocalDate);
out.put(asciiString(fileTypeName), 0, 4);
out.put(asciiString(creatorName), 0, 4);
out.putShort(nlvlFrom);
out.putShort(nlvlTo);
out.putInt(volumeAttributes);
out.putShort(fsId);
out.put(new byte[10]);
for (ExtraField extraField : extra) {
out.putShort(extraField.type);
out.putShort((short) extraField.len);
out.put(extraField.data);
}
out.putShort((short) -1);
out.putShort((short) 0);
}
public int getRecordSize() {
return recordSize;
}
public String getFileName() {
return fileName;
}
public List<ExtraField> getExtras() {
return extra;
}
public ExtraField getExtra(int type) {
for (ExtraField extraField : extra) {
if (extraField.type == type)
return extraField;
}
return null;
}
public boolean isSelfRef() {
return (flags & 0x1) != 0;
}
public static AliasBox createSelfRef() {
AliasBox alis = new AliasBox(new Header(fourcc()));
alis.setFlags(1);
return alis;
}
public String getUnixPath() {
ExtraField extraField = getExtra(AliasBox.UNIXAbsolutePath);
return extraField == null ? null : "/" + extraField.toString();
}
}