/*
* Copyright 2008 CoreMedia AG, Hamburg
*
* Licensed under the Apache License, Version 2.0 (the License);
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.coremedia.iso.boxes.odf;
import com.coremedia.iso.BoxParser;
import com.coremedia.iso.IsoBufferWrapper;
import com.coremedia.iso.IsoFile;
import com.coremedia.iso.IsoOutputStream;
import com.coremedia.iso.boxes.AbstractBox;
import com.coremedia.iso.boxes.AbstractFullBox;
import com.coremedia.iso.boxes.Box;
import com.coremedia.iso.boxes.ContainerBox;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
/**
* The Common Headers Box defines a structure for required headers in a DCF file.
* See OMA-TS-DRM-DCF-V2_0-* specification for details.
*/
public class OmaDrmCommonHeadersBox extends AbstractFullBox implements ContainerBox {
public static final String TYPE = "ohdr";
private List<Box> extendedHeaders;
private int encryptionMethod;
private int paddingScheme;
private long plaintextLength;
private String contentId;
private String rightsIssuerUrl;
private String textualHeaders;
public <T extends Box> List<T> getBoxes(Class<T> clazz) {
return getBoxes(clazz, false);
}
@SuppressWarnings("unchecked")
public <T extends Box> List<T> getBoxes(Class<T> clazz, boolean recursive) {
//todo recursive?
ArrayList<T> boxesToBeReturned = new ArrayList<T>();
for (Box boxe : extendedHeaders) {
if (clazz.isInstance(boxe)) {
boxesToBeReturned.add(clazz.cast(boxe));
}
}
return boxesToBeReturned;
}
public OmaDrmCommonHeadersBox() {
super(IsoFile.fourCCtoBytes(TYPE));
contentId = "";
rightsIssuerUrl = "";
textualHeaders = "";
extendedHeaders = new LinkedList<Box>();
}
public List<Box> getBoxes() {
return extendedHeaders;
}
public void setTextualHeaders(Map<String, String> m) {
textualHeaders = "";
if (m != null) {
for (String key : m.keySet()) {
String value = m.get(key);
textualHeaders += key + ":";
textualHeaders += value + "\0";
}
}
}
public void setRightsIssuerUrl(String rightsIssuerUrl) {
assert rightsIssuerUrl != null;
this.rightsIssuerUrl = rightsIssuerUrl;
}
public void setContentId(String contentId) {
assert contentId != null;
this.contentId = contentId;
}
public void setPlaintextLength(long plaintextLength) {
this.plaintextLength = plaintextLength;
}
public void setPaddingScheme(int paddingScheme) {
assert paddingScheme == 0 || paddingScheme == 1;
this.paddingScheme = paddingScheme;
}
public void setEncryptionMethod(int encryptionMethod) {
assert encryptionMethod == 0 || encryptionMethod == 1 || encryptionMethod == 2;
this.encryptionMethod = encryptionMethod;
}
public int getEncryptionMethod() {
return encryptionMethod;
}
public int getPaddingScheme() {
return paddingScheme;
}
public long getPlaintextLength() {
return plaintextLength;
}
public String getContentId() {
return contentId;
}
public String getRightsIssuerUrl() {
return rightsIssuerUrl;
}
public String getTextualHeaders() {
return textualHeaders;
}
protected long getContentSize() {
long contentLength;
try {
contentLength = 16 +
contentId.getBytes("UTF-8").length + (rightsIssuerUrl != null ? rightsIssuerUrl.getBytes("UTF-8").length : 0) +
(textualHeaders != null ? textualHeaders.getBytes("UTF-8").length : 0);
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
for (Box boxe : extendedHeaders) {
contentLength += boxe.getSize();
}
return contentLength;
}
public void parse(IsoBufferWrapper in, long size, BoxParser boxParser, Box lastMovieFragmentBox) throws IOException {
super.parse(in, size, boxParser, lastMovieFragmentBox);
encryptionMethod = in.readUInt8();
paddingScheme = in.readUInt8();
plaintextLength = in.readUInt64();
int contentIdLength = in.readUInt16();
int rightsIssuerUrlLength = in.readUInt16();
int textualHeadersLength = in.readUInt16();
contentId = new String(in.read(contentIdLength), "UTF-8");
rightsIssuerUrl = new String(in.read(rightsIssuerUrlLength), "UTF-8");
textualHeaders = new String(in.read(textualHeadersLength), "UTF-8");
long remainingContentSize = size;
remainingContentSize -= 4 + 1 + 1 + 8 + 2 + 2 + 2;
remainingContentSize -= contentIdLength + rightsIssuerUrlLength + textualHeadersLength;
while (remainingContentSize > 0) {
Box box = boxParser.parseBox(in, this, lastMovieFragmentBox);
remainingContentSize -= box.getSize();
extendedHeaders.add((AbstractBox) box);
}
assert remainingContentSize == 0;
}
protected void getContent(IsoOutputStream isos) throws IOException {
isos.writeUInt8(encryptionMethod);
isos.writeUInt8(paddingScheme);
isos.writeUInt64(plaintextLength);
isos.writeUInt16(utf8StringLengthInBytes(contentId));
isos.writeUInt16(rightsIssuerUrl != null ? utf8StringLengthInBytes(rightsIssuerUrl) : 0);
isos.writeUInt16(textualHeaders != null ? utf8StringLengthInBytes(textualHeaders) : 0);
isos.writeStringNoTerm(contentId);
isos.writeStringNoTerm(rightsIssuerUrl);
isos.writeStringNoTerm(textualHeaders);
for (Box boxe : extendedHeaders) {
boxe.getBox(isos);
}
}
public String toString() {
StringBuffer buffer = new StringBuffer();
buffer.append("OmaDrmCommonHeadersBox[");
buffer.append("encryptionMethod=").append(getEncryptionMethod()).append(";");
buffer.append("paddingScheme=").append(getPaddingScheme()).append(";");
buffer.append("plaintextLength=").append(getPlaintextLength()).append(";");
buffer.append("contentId=").append(getContentId()).append(";");
buffer.append("rightsIssuerUrl=").append(getRightsIssuerUrl()).append(";");
buffer.append("textualHeaders=").append(getTextualHeaders());
for (Box box : getBoxes()) {
buffer.append(";");
buffer.append(box.toString());
}
buffer.append("]");
return buffer.toString();
}
public void setBoxes(List<Box> extendedHeaders) {
this.extendedHeaders = extendedHeaders;
}
public long getNumOfBytesToFirstChild() {
long sizeOfChildren = 0;
for (Box extendedHeader : extendedHeaders) {
sizeOfChildren += extendedHeader.getSize();
}
return getSize() - sizeOfChildren;
}
}