PeerCastStation.FLV.RTMP.RTMPConnection.RecvMessage C# (CSharp) Method

RecvMessage() private method

private RecvMessage ( MessageQueue messages, CancellationToken cancel_token ) : Task
messages MessageQueue
cancel_token System.Threading.CancellationToken
return Task
    private async Task<bool> RecvMessage(MessageQueue<QueuedMessage> messages, CancellationToken cancel_token)
    {
      var basic_header = (await RecvStream(1, cancel_token))[0];
      var chunk_stream_id = basic_header & 0x3F;
      if (chunk_stream_id==0) {
        chunk_stream_id = (await RecvStream(1, cancel_token))[0] + 64;
      }
      else if (chunk_stream_id==1) {
        var buf = await RecvStream(2, cancel_token);
        chunk_stream_id = (buf[1]*256 | buf[0]) + 64;
      }

      RTMPMessageBuilder msg = null;
      RTMPMessageBuilder last_msg = null;
      if (!lastMessages.TryGetValue(chunk_stream_id, out last_msg)) {
        last_msg = RTMPMessageBuilder.NullPacket;
      }
      switch ((basic_header & 0xC0)>>6) {
      case 0:
        using (var reader=new RTMPBinaryReader(await RecvStream(11, cancel_token))) {
          long timestamp  = reader.ReadUInt24();
          var body_length = reader.ReadUInt24();
          var type_id     = reader.ReadByte();
          var stream_id   = reader.ReadUInt32LE();
          if (timestamp==0xFFFFFF) {
            using (var ext_reader=new RTMPBinaryReader(await RecvStream(4, cancel_token))) {
              timestamp = ext_reader.ReadUInt32();
            }
          }
          msg = new RTMPMessageBuilder(
            last_msg,
            timestamp,
            type_id,
            stream_id,
            body_length);
          lastMessages[chunk_stream_id] = msg;
        }
        break;
      case 1:
        using (var reader=new RTMPBinaryReader(await RecvStream(7, cancel_token))) {
          long timestamp_delta = reader.ReadUInt24();
          var body_length      = reader.ReadUInt24();
          var type_id          = reader.ReadByte();
          if (timestamp_delta==0xFFFFFF) {
            using (var ext_reader=new RTMPBinaryReader(await RecvStream(4, cancel_token))) {
              timestamp_delta = ext_reader.ReadUInt32();
            }
          }
          msg = new RTMPMessageBuilder(
            last_msg,
            timestamp_delta,
            type_id,
            body_length);
          lastMessages[chunk_stream_id] = msg;
        }
        break;
      case 2:
        using (var reader=new RTMPBinaryReader(await RecvStream(3, cancel_token))) {
          long timestamp_delta = reader.ReadUInt24();
          if (timestamp_delta==0xFFFFFF) {
            using (var ext_reader=new RTMPBinaryReader(await RecvStream(4, cancel_token))) {
              timestamp_delta = ext_reader.ReadUInt32();
            }
          }
          msg = new RTMPMessageBuilder(last_msg, timestamp_delta);
          lastMessages[chunk_stream_id] = msg;
        }
        break;
      case 3:
        msg = last_msg;
        if (msg.ReceivedLength>=msg.BodyLength) {
          msg = new RTMPMessageBuilder(last_msg);
          lastMessages[chunk_stream_id] = msg;
        }
        break;
      }

      msg.ReceivedLength += await RecvStream(
        msg.Body,
        msg.ReceivedLength,
        Math.Min(recvChunkSize, msg.BodyLength-msg.ReceivedLength),
        cancel_token);
      if (msg.ReceivedLength>=msg.BodyLength) {
        messages.Enqueue(new QueuedMessage(QueuedMessage.MessageDirection.In, chunk_stream_id, msg.ToMessage()));
      }
      return true; //TODO:接続エラー時はfalseを返す
    }