
org.red5.io.amf3.Output Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of android-rmtp-client Show documentation
Show all versions of android-rmtp-client Show documentation
A standalone RTMP client library ported from the Red5 project
The newest version!
package org.red5.io.amf3;
/*
* RED5 Open Source Flash Server - http://code.google.com/p/red5/
*
* Copyright (c) 2006-2010 by respective authors (see below). All rights reserved.
*
* This library is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 2.1 of the License, or (at your option) any later
* version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with this library; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
import java.lang.reflect.Array;
import java.lang.reflect.Field;
//import java.lang.reflect.Method;
import java.nio.ByteBuffer;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
//import java.util.Set;
//import net.sf.ehcache.Element;
//import org.apache.commons.beanutils.BeanMap;
import org.apache.mina.core.buffer.IoBuffer;
import org.red5.annotations.Anonymous;
//import org.red5.compatibility.flex.ObjectProxy;
import org.red5.io.amf.AMF;
import org.red5.io.object.RecordSet;
import org.red5.io.object.Serializer;
import org.red5.io.utils.XMLUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
/**
* AMF3 output writer
*
* @see org.red5.io.amf3.AMF3
* @see org.red5.io.amf3.Input
* @author The Red5 Project ([email protected])
* @author Joachim Bauch ([email protected])
* @author Harald Radi ([email protected])
*/
public class Output extends org.red5.io.amf.Output implements org.red5.io.object.Output {
protected static Logger log = LoggerFactory.getLogger(Output.class);
/**
* Set to a value above 0 to disable writing of the AMF3 object tag.
*/
private int amf3_mode;
/**
* List of strings already written.
* */
private Map stringReferences;
/**
* Constructor of AMF3 output.
*
* @param buf instance of IoBuffer
* @see IoBuffer
*/
public Output(IoBuffer buf) {
super(buf);
amf3_mode = 0;
stringReferences = new HashMap();
}
/**
* Force using AMF3 everywhere
*/
public void enforceAMF3() {
amf3_mode++;
}
/**
* Provide access to raw data.
*
* @return IoBuffer
*/
protected IoBuffer getBuffer() {
return buf;
}
/** {@inheritDoc} */
@Override
public boolean supportsDataType(byte type) {
return true;
}
// Basic Data Types
protected void writeAMF3() {
if (amf3_mode == 0) {
buf.put(AMF.TYPE_AMF3_OBJECT);
}
}
/** {@inheritDoc} */
@Override
public void writeBoolean(Boolean bol) {
writeAMF3();
buf.put(bol ? AMF3.TYPE_BOOLEAN_TRUE : AMF3.TYPE_BOOLEAN_FALSE);
}
/** {@inheritDoc} */
@Override
public void writeNull() {
writeAMF3();
buf.put(AMF3.TYPE_NULL);
}
protected void putInteger(long value) {
if ((value >= -268435456) && (value <= 268435455)) {
value &= 536870911;
}
if (value < 128) {
buf.put((byte) value);
} else if (value < 16384) {
buf.put((byte) (((value >> 7) & 0x7F) | 0x80));
buf.put((byte) (value & 0x7F));
} else if (value < 2097152) {
buf.put((byte) (((value >> 14) & 0x7F) | 0x80));
buf.put((byte) (((value >> 7) & 0x7F) | 0x80));
buf.put((byte) (value & 0x7F));
} else if (value < 1073741824) {
buf.put((byte) (((value >> 22) & 0x7F) | 0x80));
buf.put((byte) (((value >> 15) & 0x7F) | 0x80));
buf.put((byte) (((value >> 8) & 0x7F) | 0x80));
buf.put((byte) (value & 0xFF));
} else {
log.error("Integer out of range: {}", value);
}
}
protected static byte[] encodeString(String string) {
//Element element = getStringCache().get(string);
//byte[] encoded = (element == null ? null : (byte[]) element.getObjectValue());
byte[] encoded = null;
if (encoded == null) {
ByteBuffer buf = AMF3.CHARSET.encode(string);
encoded = new byte[buf.limit()];
buf.get(encoded);
//getStringCache().put(new Element(string, encoded));
}
return encoded;
}
protected void putString(String str, byte[] encoded) {
final int len = encoded.length;
Integer pos = stringReferences.get(str);
if (pos != null) {
// Reference to existing string
putInteger(pos << 1);
return;
}
putInteger(len << 1 | 1);
buf.put(encoded);
stringReferences.put(str, stringReferences.size());
}
/** {@inheritDoc} */
@Override
public void putString(String string) {
if ("".equals(string)) {
// Empty string;
putInteger(1);
return;
}
final byte[] encoded = encodeString(string);
putString(string, encoded);
}
/** {@inheritDoc} */
@Override
public void writeNumber(Number num) {
writeAMF3();
if (num.longValue() < AMF3.MIN_INTEGER_VALUE || num.longValue() > AMF3.MAX_INTEGER_VALUE) {
// Out of range for integer encoding
buf.put(AMF3.TYPE_NUMBER);
buf.putDouble(num.doubleValue());
} else if (num instanceof Long || num instanceof Integer || num instanceof Short || num instanceof Byte) {
buf.put(AMF3.TYPE_INTEGER);
putInteger(num.longValue());
} else {
buf.put(AMF3.TYPE_NUMBER);
buf.putDouble(num.doubleValue());
}
}
/** {@inheritDoc} */
@Override
public void writeString(String string) {
writeAMF3();
buf.put(AMF3.TYPE_STRING);
if ("".equals(string)) {
putInteger(1);
} else {
final byte[] encoded = encodeString(string);
putString(string, encoded);
}
}
/** {@inheritDoc} */
@Override
public void writeDate(Date date) {
writeAMF3();
buf.put(AMF3.TYPE_DATE);
if (hasReference(date)) {
putInteger(getReferenceId(date) << 1);
return;
}
storeReference(date);
putInteger(1);
buf.putDouble(date.getTime());
}
/** {@inheritDoc} */
public void writeArray(Collection> array, Serializer serializer) {
writeAMF3();
buf.put(AMF3.TYPE_ARRAY);
if (hasReference(array)) {
putInteger(getReferenceId(array) << 1);
return;
}
storeReference(array);
amf3_mode += 1;
int count = array.size();
putInteger(count << 1 | 1);
putString("");
for (Object item : array) {
serializer.serialize(this, item);
}
amf3_mode -= 1;
}
/** {@inheritDoc} */
public void writeArray(Object[] array, Serializer serializer) {
writeAMF3();
buf.put(AMF3.TYPE_ARRAY);
if (hasReference(array)) {
putInteger(getReferenceId(array) << 1);
return;
}
storeReference(array);
amf3_mode += 1;
int count = array.length;
putInteger(count << 1 | 1);
putString("");
for (Object item : array) {
serializer.serialize(this, item);
}
amf3_mode -= 1;
}
/** {@inheritDoc} */
public void writeArray(Object array, Serializer serializer) {
writeAMF3();
buf.put(AMF3.TYPE_ARRAY);
if (hasReference(array)) {
putInteger(getReferenceId(array) << 1);
return;
}
storeReference(array);
amf3_mode += 1;
int count = Array.getLength(array);
putInteger(count << 1 | 1);
putString("");
for (int i = 0; i < count; i++) {
serializer.serialize(this, Array.get(array, i));
}
amf3_mode -= 1;
}
/** {@inheritDoc} */
public void writeMap(Map
© 2015 - 2025 Weber Informatics LLC | Privacy Policy