/** * Decode calls. * * @param in Input data as byte buffer * @return List of pending calls */ protected List<RemotingCall> decodeCalls(IoBuffer in) { log.debug("Decode calls"); // in.getInt(); List<RemotingCall> calls = new LinkedList<RemotingCall>(); org.red5.io.amf.Input input; int count = in.getUnsignedShort(); log.debug("Calls: {}", count); int limit = in.limit(); // Loop over all the body elements for (int i = 0; i < count; i++) { in.limit(limit); String serviceString = org.red5.io.amf.Input.getString(in); String clientCallback = org.red5.io.amf.Input.getString(in); log.debug("callback: {}", clientCallback); Object[] args = null; boolean isAMF3 = false; @SuppressWarnings("unused") int length = in.getInt(); // Set the limit and deserialize // NOTE: disabled because the FP sends wrong values here /* * if (length != -1) in.limit(in.position()+length); */ byte type = in.get(); if (type == AMF.TYPE_ARRAY) { int elements = in.getInt(); List<Object> values = new ArrayList<Object>(); RefStorage refStorage = null; for (int j = 0; j < elements; j++) { byte amf3Check = in.get(); in.position(in.position() - 1); isAMF3 = (amf3Check == AMF.TYPE_AMF3_OBJECT); if (isAMF3) { if (refStorage == null) { input = new org.red5.io.amf3.Input(in); } else { input = new org.red5.io.amf3.Input(in, refStorage); } } else { input = new org.red5.io.amf.Input(in); } // prepare remoting mode input.reset(); // add deserialized object to the value list values.add(Deserializer.deserialize(input, Object.class)); if (isAMF3) { refStorage = ((org.red5.io.amf3.Input) input).getRefStorage(); } } args = values.toArray(new Object[values.size()]); if (log.isDebugEnabled()) { for (Object element : args) { log.debug("> " + element); } } } else if (type == AMF.TYPE_NULL) { log.debug("Got null amf type"); } else if (type != AMF.TYPE_ARRAY) { throw new RuntimeException("AMF0 array type expected but found " + type); } String serviceName; String serviceMethod; int dotPos = serviceString.lastIndexOf('.'); if (dotPos != -1) { serviceName = serviceString.substring(0, dotPos); serviceMethod = serviceString.substring(dotPos + 1, serviceString.length()); } else { serviceName = ""; serviceMethod = serviceString; } boolean isMessaging = false; if ("".equals(serviceName) && "null".equals(serviceMethod)) { // Use fixed service and method name for Flex messaging requests, // this probably will change in the future. serviceName = FlexMessagingService.SERVICE_NAME; serviceMethod = "handleRequest"; isMessaging = true; } log.debug("Service: {} Method: {}", serviceName, serviceMethod); // Add the call to the list calls.add( new RemotingCall(serviceName, serviceMethod, args, clientCallback, isAMF3, isMessaging)); } return calls; }
/** Resets map */ @Override public void reset() { super.reset(); // input must keep the String references for all parameters // refStorage.stringReferences.clear(); }