package org.mobicents.media; import java.io.Serializable; /** * Standard JMF class -- see <a href="http://java.sun.com/products/java-media/jmf/2.1.1/apidocs/javax/media/Format.html" target="_blank">this class in the JMF Javadoc</a>. * Coding complete. * @author Ken Larson * */ public class Format implements Cloneable, Serializable { public static final int NOT_SPECIFIED = -1; public static final int TRUE = 1; public static final int FALSE = 0; protected String encoding; // allowed to be null // we don't declare the types inline here, because the eclipse compiler // adds anonymous fields of type Class which affect serialization. public static final Class byteArray = FormatUtils.byteArray; public static final Class shortArray = FormatUtils.shortArray; public static final Class intArray = FormatUtils.intArray; public static final Class formatArray = FormatUtils.formatArray; protected Class dataType; protected Class clz; // TODO: what is this for? - present in JMF javadoc but not clear it is needed. // perhaps it is needed for serialization, or for faster code than getClass(). private long encodingCode; // This is set during equals/matches comparisons via isSameEncoding. Allows for fast string comparisons. private int hash; public final static Format ANY = new Format("ANY"); public Format(String encoding) { this.encoding = encoding; hash = encoding.hashCode(); this.dataType = byteArray; clz = getClass(); } public static final int FORMAT_HASHMAP_DEFAULT_INITIAL_CAPACITY = 8; public static final float FORMAT_HASHMAP_DEFAULT_LOAD_FACTOR = 1f; public Format(String encoding, Class dataType) { this.encoding = encoding; this.dataType = dataType; clz = getClass(); hash = encoding.hashCode(); } public String getEncoding() { return encoding; } public Class getDataType() { return dataType; } @Override public boolean equals(Object format) { /* if (!(format instanceof Format)) { return false; // if we are a format is a subclass this, let the subclass do the comparison: } if (FormatUtils.isSubclass(format.getClass(), getClass())) { return format.equals(this); } final Format oCast = (Format) format; return FormatUtils.nullSafeEquals(oCast.getDataType(), this.getDataType()) && (this.encoding == oCast.encoding || isSameEncoding(oCast)); */ return format.hashCode() == hash; } @Override public int hashCode() { return hash; } public boolean matches(Format format) { if (format == null) { return false; } if (this == ANY) { return true; } if (format == ANY) { return true; } if (!FormatUtils.isOneAssignableFromTheOther(getClass(), format.getClass())) { return false; } return (this.encoding == format.encoding || this.encoding == null || format.encoding == null || isSameEncoding(format)) && FormatUtils.matches(format.dataType, this.dataType); } public Format intersects(Format other) { // the JMF JavaDoc states: // " If both objects have specified values then the value in this object will be used." // however, testing reveals that the value in the passed-in object will be used. final Format result; if (getClass().isAssignableFrom(other.getClass())) { result = (Format) other.clone(); if (!FormatUtils.specified(result.encoding)) { result.encoding = this.encoding; } if (!FormatUtils.specified(result.dataType)) { result.dataType = this.dataType; } } else if (other.getClass().isAssignableFrom(getClass())) { result = (Format) clone(); if (!FormatUtils.specified(result.encoding)) { result.encoding = other.encoding; } if (!FormatUtils.specified(result.dataType)) { result.dataType = other.dataType; } } else { result = null; // subclasses in different branches } return result; } public boolean isSameEncoding(Format other) { if (other == null) { return false; } if (other.encoding == null) { return false; } if (this.encoding == null) { return false; } if (other.encoding.equalsIgnoreCase(this.encoding)) { return true; } if (this.encodingCode == 0) { this.encodingCode = getEncodingCode(this.encoding); } if (other.encodingCode == 0) { other.encodingCode = getEncodingCode(other.encoding); } return encodingCode == other.encodingCode; } public boolean isSameEncoding(String encoding) { if (encoding == null) { return false; } if (this.encoding == null) { return false; } if (encoding == this.encoding) { return true; } if (this.encodingCode == 0) { this.encodingCode = getEncodingCode(this.encoding); } return this.encodingCode == getEncodingCode(encoding); } private long getEncodingCode(String enc) { if (enc == null) { return 0; } return FormatUtils.stringEncodingCodeVal(enc); } public Format relax() { return (Format) clone(); } public Object clone() { return new Format(encoding, dataType); } protected void copy(Format f) { // do not copy encoding. this.dataType = f.dataType; } public String toString() { return getEncoding(); } static { // TODO: what to do here? } }