示例#1
0
        private object ReadCollection(Stream s)
        {
            object returnValue;
            char   listItemTypeAsChar = Convert.ToChar(s.ReadByte());
            int    numOfItemsInList   = SerDe.ReadInt32(s);

            switch (listItemTypeAsChar)
            {
            case 'c':
                var strArray = new string[numOfItemsInList];
                for (int itemIndex = 0; itemIndex < numOfItemsInList; ++itemIndex)
                {
                    strArray[itemIndex] = SerDe.ReadString(s);
                }
                returnValue = strArray;
                break;

            case 'i':
                var intArray = new int[numOfItemsInList];
                for (int itemIndex = 0; itemIndex < numOfItemsInList; ++itemIndex)
                {
                    intArray[itemIndex] = SerDe.ReadInt32(s);
                }
                returnValue = intArray;
                break;

            case 'g':
                var longArray = new long[numOfItemsInList];
                for (int itemIndex = 0; itemIndex < numOfItemsInList; ++itemIndex)
                {
                    longArray[itemIndex] = SerDe.ReadInt64(s);
                }
                returnValue = longArray;
                break;

            case 'd':
                var doubleArray = new double[numOfItemsInList];
                for (int itemIndex = 0; itemIndex < numOfItemsInList; ++itemIndex)
                {
                    doubleArray[itemIndex] = SerDe.ReadDouble(s);
                }
                returnValue = doubleArray;
                break;

            case 'A':
                var doubleArrayArray = new double[numOfItemsInList][];
                for (int itemIndex = 0; itemIndex < numOfItemsInList; ++itemIndex)
                {
                    doubleArrayArray[itemIndex] = ReadCollection(s) as double[];
                }
                returnValue = doubleArrayArray;
                break;

            case 'b':
                var boolArray = new bool[numOfItemsInList];
                for (int itemIndex = 0; itemIndex < numOfItemsInList; ++itemIndex)
                {
                    boolArray[itemIndex] = Convert.ToBoolean(s.ReadByte());
                }
                returnValue = boolArray;
                break;

            case 'r':
                var byteArrayArray = new byte[numOfItemsInList][];
                for (int itemIndex = 0; itemIndex < numOfItemsInList; ++itemIndex)
                {
                    int byteArrayLen = SerDe.ReadInt32(s);
                    byteArrayArray[itemIndex] = SerDe.ReadBytes(s, byteArrayLen);
                }
                returnValue = byteArrayArray;
                break;

            case 'j':
                var jvmObjectReferenceArray = new JvmObjectReference[numOfItemsInList];
                for (int itemIndex = 0; itemIndex < numOfItemsInList; ++itemIndex)
                {
                    string itemIdentifier = SerDe.ReadString(s);
                    jvmObjectReferenceArray[itemIndex] =
                        new JvmObjectReference(itemIdentifier, this);
                }
                returnValue = jvmObjectReferenceArray;
                break;

            default:
                // convert listItemTypeAsChar to UInt32 because the char may be non-printable
                throw new NotSupportedException(
                          string.Format("Identifier for list item type 0x{0:X} not supported",
                                        Convert.ToUInt32(listItemTypeAsChar)));
            }
            return(returnValue);
        }
示例#2
0
        /// <summary>
        /// Process the input and output streams.
        /// </summary>
        /// <param name="inputStream">The input stream.</param>
        /// <param name="outputStream">The output stream.</param>
        /// <param name="readComplete">True if stream is read completely, false otherwise.</param>
        /// <returns>The connection status.</returns>
        private ConnectionStatus ProcessStream(
            Stream inputStream,
            Stream outputStream,
            out bool readComplete)
        {
            readComplete = false;

            try
            {
                byte[] requestFlagBytes = SerDe.ReadBytes(inputStream, sizeof(int));
                // For socket stream, read on the stream returns 0, which
                // SerDe.ReadBytes() returns as null to denote the stream is closed.
                if (requestFlagBytes == null)
                {
                    return(ConnectionStatus.SOCKET_CLOSED);
                }

                // Check value of the initial request. Expected values are:
                // - CallbackFlags.CLOSE
                // - CallbackFlags.CALLBACK
                int requestFlag = BinaryPrimitives.ReadInt32BigEndian(requestFlagBytes);
                if (requestFlag == (int)CallbackFlags.CLOSE)
                {
                    return(ConnectionStatus.REQUEST_CLOSE);
                }
                else if (requestFlag != (int)CallbackFlags.CALLBACK)
                {
                    throw new Exception(
                              string.Format(
                                  "Unexpected callback flag received. Expected: {0}, Received: {1}.",
                                  CallbackFlags.CALLBACK,
                                  requestFlag));
                }

                // Use callback id to get the registered handler.
                int callbackId = SerDe.ReadInt32(inputStream);
                if (!_callbackHandlers.TryGetValue(
                        callbackId,
                        out ICallbackHandler callbackHandler))
                {
                    throw new Exception($"Unregistered callback id: {callbackId}");
                }

                s_logger.LogInfo(
                    string.Format(
                        "[{0}] Received request for callback id: {1}, callback handler: {2}",
                        ConnectionId,
                        callbackId,
                        callbackHandler));

                // Save contents of callback handler data to be used later.
                using var callbackDataStream =
                          new MemoryStream(SerDe.ReadBytes(inputStream, SerDe.ReadInt32(inputStream)));

                // Check the end of stream.
                int endOfStream = SerDe.ReadInt32(inputStream);
                if (endOfStream == (int)CallbackFlags.END_OF_STREAM)
                {
                    s_logger.LogDebug($"[{ConnectionId}] Received END_OF_STREAM signal.");

                    // Run callback handler.
                    callbackHandler.Run(callbackDataStream);

                    SerDe.Write(outputStream, (int)CallbackFlags.END_OF_STREAM);
                    readComplete = true;
                }
                else
                {
                    // This may happen when the input data is not read completely.
                    s_logger.LogWarn(
                        $"[{ConnectionId}] Unexpected end of stream: {endOfStream}.");

                    // Write flag to indicate the connection should be closed.
                    SerDe.Write(outputStream, (int)CallbackFlags.CLOSE);
                }

                return(ConnectionStatus.OK);
            }
            catch (Exception e)
            {
                s_logger.LogError($"[{ConnectionId}] ProcessStream() failed with exception: {e}");

                try
                {
                    SerDe.Write(outputStream, (int)CallbackFlags.DOTNET_EXCEPTION_THROWN);
                    SerDe.Write(outputStream, e.ToString());
                }
                catch (IOException)
                {
                    // JVM closed the socket.
                }
                catch (Exception ex)
                {
                    s_logger.LogError(
                        $"[{ConnectionId}] Writing exception to stream failed with exception: {ex}");
                }

                throw;
            }
        }