[Red5commits] [1596] added experimental AMF3 support
jbauch
luke at codegent.com
Wed Jan 24 11:02:25 EST 2007
added experimental AMF3 support
Timestamp: 12/20/06 20:35:22 EST (1 month ago)
Change: 1596
Author: jbauch
Files (see diff or trac for details):
java/server/trunk/src/org/red5/io/amf/AMF.java
java/server/trunk/src/org/red5/io/amf/Input.java
java/server/trunk/src/org/red5/io/amf/Output.java
java/server/trunk/src/org/red5/io/amf3/Input.java
java/server/trunk/src/org/red5/io/amf3/Output.java
java/server/trunk/src/org/red5/io/mock/Input.java
java/server/trunk/src/org/red5/io/mock/Output.java
java/server/trunk/src/org/red5/io/object/BaseInput.java
java/server/trunk/src/org/red5/io/object/Input.java
java/server/trunk/src/org/red5/io/object/Output.java
java/server/trunk/src/org/red5/io/object/Serializer.java
java/server/trunk/src/org/red5/server/BaseConnection.java
java/server/trunk/src/org/red5/server/api/IConnection.java
java/server/trunk/src/org/red5/server/net/rtmp/BaseRTMPHandler.java
java/server/trunk/src/org/red5/server/net/rtmp/Channel.java
java/server/trunk/src/org/red5/server/net/rtmp/RTMPConnection.java
java/server/trunk/src/org/red5/server/net/rtmp/RTMPHandler.java
java/server/trunk/src/org/red5/server/net/rtmp/codec/IEventDecoder.java
java/server/trunk/src/org/red5/server/net/rtmp/codec/RTMPMinaProtocolDecoder.java
java/server/trunk/src/org/red5/server/net/rtmp/codec/RTMPProtocolDecoder.java
java/server/trunk/src/org/red5/server/net/rtmp/codec/RTMPProtocolEncoder.java
java/server/trunk/src/org/red5/server/net/rtmp/event/FlexMessage.java
java/server/trunk/src/org/red5/server/net/rtmp/message/Constants.java
java/server/trunk/src/org/red5/server/net/servlet/ServletConnection.java
java/server/trunk/test/org/red5/server/api/test/TestConnection.java
Trac: http://mirror1.cvsdude.com/trac/osflash/red5/changeset/1596
Index: /java/server/trunk/test/org/red5/server/api/test/TestConnection.java
===================================================================
--- /java/server/trunk/test/org/red5/server/api/test/TestConnection.java (revision 1406)
+++ /java/server/trunk/test/org/red5/server/api/test/TestConnection.java (revision 1596)
@@ -9,4 +9,8 @@
}
+ public Encoding getEncoding() {
+ return Encoding.AMF0;
+ }
+
@Override
public long getReadBytes() {
Index: /java/server/trunk/src/org/red5/server/net/rtmp/RTMPHandler.java
===================================================================
--- /java/server/trunk/src/org/red5/server/net/rtmp/RTMPHandler.java (revision 1582)
+++ /java/server/trunk/src/org/red5/server/net/rtmp/RTMPHandler.java (revision 1596)
@@ -221,6 +221,15 @@
call.setStatus(Call.STATUS_SUCCESS_RESULT);
if (call instanceof IPendingServiceCall) {
- ((IPendingServiceCall) call)
- .setResult(getStatus(NC_CONNECT_SUCCESS));
+ IPendingServiceCall pc = (IPendingServiceCall) call;
+ Map<String, Object> result = new HashMap<String, Object>();
+ StatusObject status = getStatus(NC_CONNECT_SUCCESS);
+ result.put("code", status.getCode());
+ result.put("description", status.getDescription());
+ result.put("application", status.getApplication());
+ result.put("level", status.getLevel());
+ if (params.get("objectEncoding") == Integer.valueOf(3))
+ // Client wants to use AMF3 encoding
+ result.put("objectEncoding", 3);
+ pc.setResult(result);
}
// Measure initial roundtrip time after connecting
@@ -325,5 +334,5 @@
}
- public Object getStatus(String code) {
+ public StatusObject getStatus(String code) {
return statusObjectService.getStatusObject(code);
}
Index: /java/server/trunk/src/org/red5/server/net/rtmp/event/FlexMessage.java
===================================================================
--- /java/server/trunk/src/org/red5/server/net/rtmp/event/FlexMessage.java (revision 1596)
+++ /java/server/trunk/src/org/red5/server/net/rtmp/event/FlexMessage.java (revision 1596)
@@ -0,0 +1,15 @@
+package org.red5.server.net.rtmp.event;
+
+public class FlexMessage extends Invoke {
+
+ public FlexMessage() {
+ super();
+ }
+
+ @Override
+ public byte getDataType() {
+ // TODO Auto-generated method stub
+ return TYPE_FLEX_MESSAGE;
+ }
+
+}
Index: /java/server/trunk/src/org/red5/server/net/rtmp/RTMPConnection.java
===================================================================
--- /java/server/trunk/src/org/red5/server/net/rtmp/RTMPConnection.java (revision 1582)
+++ /java/server/trunk/src/org/red5/server/net/rtmp/RTMPConnection.java (revision 1596)
@@ -101,4 +101,5 @@
private int usedStreams;
+ protected Encoding encoding = Encoding.AMF0;
public RTMPConnection(String type) {
@@ -110,11 +111,17 @@
public void setup(String host, String path, String sessionId,
- Map<String, String> params) {
+ Map<String, Object> params) {
this.host = host;
this.path = path;
this.sessionId = sessionId;
this.params = params;
- }
-
+ if (params.get("objectEncoding") == Integer.valueOf(3))
+ encoding = Encoding.AMF3;
+ }
+
+ public Encoding getEncoding() {
+ return encoding;
+ }
+
public int getNextAvailableChannelId() {
int result = -1;
Index: /java/server/trunk/src/org/red5/server/net/rtmp/message/Constants.java
===================================================================
--- /java/server/trunk/src/org/red5/server/net/rtmp/message/Constants.java (revision 1406)
+++ /java/server/trunk/src/org/red5/server/net/rtmp/message/Constants.java (revision 1596)
@@ -40,5 +40,7 @@
public static final byte TYPE_VIDEO_DATA = 0x09;
- // Unknown: 0x0A ... 0x11
+ // Unknown: 0x0A ... 0x10
+ public static final byte TYPE_FLEX_MESSAGE = 0x11;
+
public static final byte TYPE_NOTIFY = 0x12;
Index: /java/server/trunk/src/org/red5/server/net/rtmp/Channel.java
===================================================================
--- /java/server/trunk/src/org/red5/server/net/rtmp/Channel.java (revision 1572)
+++ /java/server/trunk/src/org/red5/server/net/rtmp/Channel.java (revision 1596)
@@ -22,5 +22,7 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.red5.server.api.IConnection.Encoding;
import org.red5.server.api.stream.IClientStream;
+import org.red5.server.net.rtmp.event.FlexMessage;
import org.red5.server.net.rtmp.event.IRTMPEvent;
import org.red5.server.net.rtmp.event.Invoke;
@@ -97,5 +99,8 @@
final PendingCall call = new PendingCall(null, "onStatus",
new Object[] { status });
- invoke = new Invoke();
+ if (connection.getEncoding() == Encoding.AMF3)
+ invoke = new FlexMessage();
+ else
+ invoke = new Invoke();
invoke.setInvokeId(1);
invoke.setCall(call);
Index: /java/server/trunk/src/org/red5/server/net/rtmp/BaseRTMPHandler.java
===================================================================
--- /java/server/trunk/src/org/red5/server/net/rtmp/BaseRTMPHandler.java (revision 1574)
+++ /java/server/trunk/src/org/red5/server/net/rtmp/BaseRTMPHandler.java (revision 1596)
@@ -112,4 +112,5 @@
case TYPE_INVOKE:
+ case TYPE_FLEX_MESSAGE:
onInvoke(conn, channel, header, (Invoke) message);
if(message.getHeader().getStreamId()!=0
Index: /java/server/trunk/src/org/red5/server/net/rtmp/codec/RTMPMinaProtocolDecoder.java
===================================================================
--- /java/server/trunk/src/org/red5/server/net/rtmp/codec/RTMPMinaProtocolDecoder.java (revision 1406)
+++ /java/server/trunk/src/org/red5/server/net/rtmp/codec/RTMPMinaProtocolDecoder.java (revision 1596)
@@ -28,4 +28,6 @@
import org.apache.mina.filter.codec.ProtocolDecoder;
import org.apache.mina.filter.codec.ProtocolDecoderOutput;
+import org.red5.server.api.IConnection;
+import org.red5.server.api.Red5;
import org.red5.server.net.protocol.ProtocolState;
@@ -38,4 +40,9 @@
final ProtocolState state = (ProtocolState) session
.getAttribute(ProtocolState.SESSION_KEY);
+
+ IConnection conn = (IConnection) session.getAttachment();
+
+ // Set thread local here so we have the connection during decoding of packets
+ Red5.setConnectionLocal(conn);
ByteBuffer buf = (ByteBuffer) session.getAttribute("buffer");
Index: /java/server/trunk/src/org/red5/server/net/rtmp/codec/IEventDecoder.java
===================================================================
--- /java/server/trunk/src/org/red5/server/net/rtmp/codec/IEventDecoder.java (revision 1400)
+++ /java/server/trunk/src/org/red5/server/net/rtmp/codec/IEventDecoder.java (revision 1596)
@@ -24,4 +24,5 @@
import org.red5.server.net.rtmp.event.BytesRead;
import org.red5.server.net.rtmp.event.ChunkSize;
+import org.red5.server.net.rtmp.event.FlexMessage;
import org.red5.server.net.rtmp.event.Invoke;
import org.red5.server.net.rtmp.event.Notify;
@@ -51,3 +52,4 @@
public abstract VideoData decodeVideoData(ByteBuffer in);
+ public abstract FlexMessage decodeFlexMessage(ByteBuffer in);
}
Index: /java/server/trunk/src/org/red5/server/net/rtmp/codec/RTMPProtocolEncoder.java
===================================================================
--- /java/server/trunk/src/org/red5/server/net/rtmp/codec/RTMPProtocolEncoder.java (revision 1574)
+++ /java/server/trunk/src/org/red5/server/net/rtmp/codec/RTMPProtocolEncoder.java (revision 1596)
@@ -27,7 +27,10 @@
import org.apache.commons.logging.LogFactory;
import org.apache.mina.common.ByteBuffer;
-import org.red5.io.amf.Output;
+import org.red5.io.object.Output;
import org.red5.io.object.Serializer;
import org.red5.io.utils.BufferUtils;
+import org.red5.server.api.IConnection;
+import org.red5.server.api.Red5;
+import org.red5.server.api.IConnection.Encoding;
import org.red5.server.api.service.IPendingServiceCall;
import org.red5.server.api.service.IServiceCall;
@@ -39,4 +42,5 @@
import org.red5.server.net.rtmp.event.ChunkSize;
import org.red5.server.net.rtmp.event.ClientBW;
+import org.red5.server.net.rtmp.event.FlexMessage;
import org.red5.server.net.rtmp.event.IRTMPEvent;
import org.red5.server.net.rtmp.event.Invoke;
@@ -65,4 +69,13 @@
private Serializer serializer;
+
+ private Output getOutput(ByteBuffer buffer) {
+ IConnection conn = Red5.getConnectionLocal();
+ if (conn.getEncoding() == Encoding.AMF3) {
+ return new org.red5.io.amf3.Output(buffer);
+ } else {
+ return new org.red5.io.amf.Output(buffer);
+ }
+ }
public ByteBuffer encode(ProtocolState state, Object message)
@@ -216,4 +229,6 @@
case TYPE_CLIENT_BANDWIDTH:
return encodeClientBW((ClientBW) message);
+ case TYPE_FLEX_MESSAGE:
+ return encodeFlexMessage((FlexMessage) message);
default:
return null;
@@ -244,6 +259,7 @@
final ByteBuffer out = ByteBuffer.allocate(128);
out.setAutoExpand(true);
-
- Output.putString(out, so.getName());
+ final Output output = getOutput(out);
+
+ output.putString(so.getName());
// SO version
out.putInt(so.getVersion());
@@ -275,5 +291,5 @@
mark = out.position();
out.skip(4); // we will be back
- Output.putString(out, event.getKey());
+ output.putString(event.getKey());
len = out.position() - mark - 4;
out.putInt(mark, len);
@@ -294,6 +310,5 @@
String key = (String) keys.next();
- Output.putString(out, key);
- final Output output = new Output(out);
+ output.putString(key);
serializer.serialize(output, initialData.get(key));
@@ -306,6 +321,5 @@
out.skip(4); // we will be back
- Output.putString(out, event.getKey());
- final Output output = new Output(out);
+ output.putString(event.getKey());
serializer.serialize(output, event.getValue());
@@ -322,5 +336,4 @@
out.skip(4);
// Serialize name of the handler to call...
- final Output output = new Output(out);
serializer.serialize(output, event.getKey());
// ...and the arguments
@@ -338,6 +351,6 @@
mark = out.position();
out.skip(4); // we will be back
- Output.putString(out, event.getKey());
- Output.putString(out, (String) event.getValue());
+ output.putString(event.getKey());
+ output.putString((String) event.getValue());
len = out.position() - mark - 4;
out.putInt(mark, len);
@@ -353,7 +366,6 @@
//out.putInt(0);
out.skip(4); // we will be back
- Output.putString(out, event.getKey());
- final Output output2 = new Output(out);
- serializer.serialize(output2, event.getValue());
+ output.putString(event.getKey());
+ serializer.serialize(output, event.getValue());
len = out.position() - mark - 4;
out.putInt(mark, len);
@@ -384,11 +396,14 @@
protected ByteBuffer encodeNotifyOrInvoke(Notify invoke) {
+ ByteBuffer out = ByteBuffer.allocate(1024);
+ out.setAutoExpand(true);
+ encodeNotifyOrInvoke(out, invoke);
+ return out;
+ }
+
+ protected void encodeNotifyOrInvoke(ByteBuffer out, Notify invoke) {
// TODO: tidy up here
// log.debug("Encode invoke");
-
- ByteBuffer out = ByteBuffer.allocate(1024);
- out.setAutoExpand(true);
- Output output = new Output(out);
-
+ Output output = new org.red5.io.amf.Output(out);
final IServiceCall call = invoke.getCall();
final boolean isPending = (call.getStatus() == Call.STATUS_PENDING);
@@ -412,4 +427,12 @@
serializer.serialize(output, invoke.getConnectionParams());
}
+
+ if (call.getServiceName() == null && "connect".equals(call.getServiceMethodName())) {
+ // Response to initial connect, always use AMF0
+ output = new org.red5.io.amf.Output(out);
+ } else {
+ output = getOutput(out);
+ }
+
if (!isPending && (invoke instanceof Invoke)) {
IPendingServiceCall pendingCall = (IPendingServiceCall) call;
@@ -429,5 +452,4 @@
}
}
- return out;
}
@@ -498,3 +520,12 @@
}
+ public ByteBuffer encodeFlexMessage(FlexMessage msg) {
+ ByteBuffer out = ByteBuffer.allocate(1024);
+ out.setAutoExpand(true);
+ // Unknown byte, always 0?
+ out.put((byte) 0);
+ encodeNotifyOrInvoke(out, msg);
+ return out;
+ }
+
}
Index: /java/server/trunk/src/org/red5/server/net/rtmp/codec/RTMPProtocolDecoder.java
===================================================================
--- /java/server/trunk/src/org/red5/server/net/rtmp/codec/RTMPProtocolDecoder.java (revision 1574)
+++ /java/server/trunk/src/org/red5/server/net/rtmp/codec/RTMPProtocolDecoder.java (revision 1596)
@@ -29,7 +29,11 @@
import org.apache.commons.logging.LogFactory;
import org.apache.mina.common.ByteBuffer;
-import org.red5.io.amf.Input;
+import org.red5.io.amf.AMF;
import org.red5.io.object.Deserializer;
+import org.red5.io.object.Input;
import org.red5.io.utils.BufferUtils;
+import org.red5.server.api.IConnection;
+import org.red5.server.api.Red5;
+import org.red5.server.api.IConnection.Encoding;
import org.red5.server.net.protocol.ProtocolException;
import org.red5.server.net.protocol.ProtocolState;
@@ -40,4 +44,5 @@
import org.red5.server.net.rtmp.event.ChunkSize;
import org.red5.server.net.rtmp.event.ClientBW;
+import org.red5.server.net.rtmp.event.FlexMessage;
import org.red5.server.net.rtmp.event.IRTMPEvent;
import org.red5.server.net.rtmp.event.Invoke;
@@ -73,4 +78,13 @@
}
+ private Input getInput(ByteBuffer buffer) {
+ IConnection conn = Red5.getConnectionLocal();
+ if (conn != null && conn.getEncoding() == Encoding.AMF3) {
+ return new org.red5.io.amf3.Input(buffer);
+ } else {
+ return new org.red5.io.amf.Input(buffer);
+ }
+ }
+
public void setDeserializer(Deserializer deserializer) {
this.deserializer = deserializer;
@@ -379,4 +393,7 @@
message = decodeClientBW(in);
break;
+ case TYPE_FLEX_MESSAGE:
+ message = decodeFlexMessage(in);
+ break;
default:
message = decodeUnknown(header.getDataType(), in);
@@ -421,6 +438,6 @@
public ISharedObjectMessage decodeSharedObject(ByteBuffer in) {
- final Input input = new Input(in);
- String name = Input.getString(in);
+ final Input input = getInput(in);
+ String name = input.getString();
// Read version of SO to modify
int version = in.getInt();
@@ -448,7 +465,7 @@
if (type == ISharedObjectEvent.Type.CLIENT_STATUS) {
// Status code
- key = Input.getString(in);
+ key = input.getString();
// Status level
- value = Input.getString(in);
+ value = input.getString();
} else if (type == ISharedObjectEvent.Type.CLIENT_UPDATE_DATA) {
key = null;
@@ -457,5 +474,5 @@
final int start = in.position();
while (in.position() - start < length) {
- String tmp = Input.getString(in);
+ String tmp = input.getString();
map.put(tmp, deserializer.deserialize(input));
}
@@ -464,5 +481,5 @@
&& type != ISharedObjectEvent.Type.CLIENT_SEND_MESSAGE) {
if (length > 0) {
- key = Input.getString(in);
+ key = input.getString();
if (length > key.length() + 2) {
value = deserializer.deserialize(input);
@@ -530,5 +547,5 @@
// TODO: we should use different code depending on server or client mode
int start = in.position();
- Input input = new Input(in);
+ Input input = getInput(in);
String action = (String) deserializer.deserialize(input);
@@ -647,3 +664,53 @@
}
+ public FlexMessage decodeFlexMessage(ByteBuffer in) {
+ // Unknown byte, always 0?
+ in.skip(1);
+ Input input = new org.red5.io.amf.Input(in);
+ String action = (String) deserializer.deserialize(input);
+ int invokeId = ((Number) deserializer.deserialize(input)).intValue();
+ FlexMessage msg = new FlexMessage();
+ msg.setInvokeId(invokeId);
+ Object[] params = new Object[] {};
+
+ if (in.hasRemaining()) {
+ ArrayList paramList = new ArrayList();
+
+ final Object obj = deserializer.deserialize(input);
+ if (obj != null) {
+ paramList.add(obj);
+ }
+
+ if (in.hasRemaining()) {
+ // Check for AMF3 encoding of parameters
+ byte tmp = in.get();
+ in.position(in.position()-1);
+ if (tmp == AMF.TYPE_AMF3_OBJECT) {
+ // All further parameters are encoded using AMF3
+ input = new org.red5.io.amf3.Input(in);
+ }
+ while (in.hasRemaining()) {
+ paramList.add(deserializer.deserialize(input));
+ }
+ }
+ params = paramList.toArray();
+ if (log.isDebugEnabled()) {
+ log.debug("Num params: " + paramList.size());
+ for (int i = 0; i < params.length; i++) {
+ log.debug(" > " + i + ": " + params[i]);
+ }
+ }
+ }
+
+ final int dotIndex = action.lastIndexOf('.');
+ String serviceName = (dotIndex == -1) ? null : action.substring(0,
+ dotIndex);
+ String serviceMethod = (dotIndex == -1) ? action : action.substring(
+ dotIndex + 1, action.length());
+
+ PendingCall call = new PendingCall(serviceName, serviceMethod, params);
+ msg.setCall(call);
+ return msg;
+ }
+
}
Index: /java/server/trunk/src/org/red5/server/net/servlet/ServletConnection.java
===================================================================
--- /java/server/trunk/src/org/red5/server/net/servlet/ServletConnection.java (revision 1519)
+++ /java/server/trunk/src/org/red5/server/net/servlet/ServletConnection.java (revision 1596)
@@ -55,4 +55,8 @@
}
+ public Encoding getEncoding() {
+ return Encoding.AMF0;
+ }
+
public String getType() {
return IConnection.TRANSIENT;
@@ -81,6 +85,6 @@
}
- public Map<String, String> getConnectParams() {
- return new HashMap<String, String>();
+ public Map<String, Object> getConnectParams() {
+ return new HashMap<String, Object>();
}
Index: /java/server/trunk/src/org/red5/server/api/IConnection.java
===================================================================
--- /java/server/trunk/src/org/red5/server/api/IConnection.java (revision 1590)
+++ /java/server/trunk/src/org/red5/server/api/IConnection.java (revision 1596)
@@ -39,4 +39,12 @@
/**
+ * Encoding types.
+ */
+ public static enum Encoding {
+ AMF0,
+ AMF3
+ };
+
+ /**
* Persistent connection type, eg RTMP.
*/
@@ -60,4 +68,11 @@
public String getType(); // PERSISTENT | POLLING | TRANSIENT
+ /**
+ * Get the object encoding for this connection.
+ *
+ * @return the used encoding.
+ */
+ public Encoding getEncoding();
+
/**
* Initialize the connection.
@@ -100,5 +115,5 @@
* @return
*/
- public Map<String, String> getConnectParams();
+ public Map<String, Object> getConnectParams();
/**
Index: /java/server/trunk/src/org/red5/server/BaseConnection.java
===================================================================
--- /java/server/trunk/src/org/red5/server/BaseConnection.java (revision 1590)
+++ /java/server/trunk/src/org/red5/server/BaseConnection.java (revision 1596)
@@ -87,5 +87,5 @@
*/
@SuppressWarnings({"JavadocReference"})
- protected Map<String, String> params = null;
+ protected Map<String, Object> params = null;
/**
* Client bound to connection
@@ -113,5 +113,5 @@
public BaseConnection(String type, String host, String remoteAddress,
int remotePort, String path, String sessionId,
- Map<String, String> params) {
+ Map<String, Object> params) {
this.type = type;
this.host = host;
@@ -192,5 +192,5 @@
* @return
*/
- public Map<String, String> getConnectParams() {
+ public Map<String, Object> getConnectParams() {
return Collections.unmodifiableMap(params);
}
Index: /java/server/trunk/src/org/red5/io/amf3/Input.java
===================================================================
--- /java/server/trunk/src/org/red5/io/amf3/Input.java (revision 1406)
+++ /java/server/trunk/src/org/red5/io/amf3/Input.java (revision 1596)
@@ -29,4 +29,5 @@
import org.apache.commons.logging.LogFactory;
import org.apache.mina.common.ByteBuffer;
+import org.red5.io.amf.AMF;
import org.red5.io.object.BaseInput;
import org.red5.io.object.DataTypes;
@@ -37,13 +38,10 @@
* @author The Red5 Project (red5 at osflash.org)
* @author Luke Hubbard, Codegent Ltd (luke at codegent.com)
+ * @author Joachim Bauch (jojo at struktur.de)
*/
-public class Input extends BaseInput implements org.red5.io.object.Input {
+public class Input extends org.red5.io.amf.Input implements org.red5.io.object.Input {
protected static Log log = LogFactory.getLog(Input.class.getName());
- protected ByteBuffer buf;
-
- protected byte currentDataType;
-
/**
* Input Constructor
@@ -52,6 +50,5 @@
*/
public Input(ByteBuffer buf) {
- super();
- this.buf = buf;
+ super(buf);
}
@@ -70,6 +67,12 @@
byte coreType;
+ if (currentDataType == AMF.TYPE_AMF3_OBJECT) {
+ currentDataType = buf.get();
+ } else {
+ // AMF0 object
+ return readDataType(currentDataType);
+ }
+
switch (currentDataType) {
-
case AMF3.TYPE_NULL:
coreType = DataTypes.CORE_NULL;
@@ -158,7 +161,13 @@
*/
public String readString() {
- int len = buf.getInt();
- // shift by one bit ?
- // is it a reference ? if not continue
+ int len = readAMF3Integer();
+ if (len == 0)
+ return "";
+
+ if ((len & 1) == 0) {
+ // Reference
+ return (String) getReference(len >> 1);
+ }
+ len >>= 1;
int limit = buf.limit();
final java.nio.ByteBuffer strBuf = buf.buf();
@@ -166,5 +175,5 @@
final String string = AMF3.CHARSET.decode(strBuf).toString();
buf.limit(limit); // Reset the limit
- // save a reference
+ storeReference(string);
return string;
}
@@ -203,4 +212,5 @@
*/
public int readStartArray() {
+ System.err.println("MISSING: readStartArray");
return buf.getInt();
}
@@ -228,4 +238,5 @@
*/
public int readStartMap() {
+ System.err.println("MISSING: readStartMap");
return buf.getInt();
}
@@ -246,5 +257,5 @@
*/
public String readItemKey() {
- return "";
+ return readString();
}
@@ -271,4 +282,5 @@
*/
public String readStartObject() {
+ System.err.println("MISSING: readStartObject");
return null;
}
@@ -280,5 +292,7 @@
*/
public boolean hasMoreProperties() {
- return false;
+ boolean isEnd = (buf.get() == 0);
+ buf.position(buf.position()-1);
+ return isEnd;
}
@@ -289,5 +303,5 @@
*/
public String readPropertyName() {
- return null;
+ return readString();
}
@@ -303,8 +317,5 @@
*/
public void skipEndObject() {
- // skip two marker bytes
- // then end of object byte
- buf.skip(3);
- // byte nextType = buf.get();
+ buf.skip(1);
}
@@ -328,13 +339,4 @@
// Return null for now
return null;
- }
-
- /**
- * Reads Reference
- *
- * @return Object
- */
- public Object readReference() {
- return getReference(buf.getShort());
}
Index: /java/server/trunk/src/org/red5/io/amf3/Output.java
===================================================================
--- /java/server/trunk/src/org/red5/io/amf3/Output.java (revision 1400)
+++ /java/server/trunk/src/org/red5/io/amf3/Output.java (revision 1596)
@@ -25,4 +25,6 @@
import org.apache.commons.logging.LogFactory;
import org.apache.mina.common.ByteBuffer;
+import org.red5.io.amf.AMF;
+import org.red5.io.amf3.AMF3;
/**
@@ -32,10 +34,9 @@
* @see org.red5.io.amf3.Input
* @author The Red5 Project (red5 at osflash.org)
+ * @author Joachim Bauch (jojo at struktur.de)
*/
-public class Output implements org.red5.io.object.Output {
+public class Output extends org.red5.io.amf.Output implements org.red5.io.object.Output {
protected static Log log = LogFactory.getLog(Output.class.getName());
-
- protected ByteBuffer buffer;
/**
@@ -46,102 +47,148 @@
* @see ByteBuffer
*/
- public Output(ByteBuffer buffer) {
- this.buffer = buffer;
+ public Output(ByteBuffer buf) {
+ super(buf);
}
public boolean supportsDataType(byte type) {
- return false;
+ return true;
}// Basic Data Types
- public void writeNumber(Number num) {
-
+ public void writeBoolean(Boolean bol) {
+ buf.put(AMF.TYPE_AMF3_OBJECT);
+ buf.put(bol.booleanValue() ? AMF3.TYPE_BOOLEAN_TRUE : AMF3.TYPE_BOOLEAN_FALSE);
}
- public void writeBoolean(Boolean bol) {
+ public void writeNull() {
+ buf.put(AMF.TYPE_AMF3_OBJECT);
+ buf.put(AMF3.TYPE_NULL);
+ }
+ protected void putInteger(long value) {
+ if (value < 0) {
+ System.err.println("MISSING: negative integer");
+ return;
+ }
+
+
Note:
Diffs are chopped if more than 25k.
This is to get past the limit on the mailing list.
More information about the Red5commits
mailing list