public static void writeChId(NaiveMultiplexing m, BytesView bv, int id, ref int cur) { int idLen = m.sendChannelIdLength; if (idLen == 1) { var i = id == ReservedId ? (sbyte.MinValue) : (sbyte)id; bv[cur++] = (byte)i; } else if (idLen == 2) { var i = id == ReservedId ? (short.MinValue) : (short)id; bv[cur++] = (byte)(i >> 8); bv[cur++] = (byte)(i); } else if (idLen == 4) { for (int i = 4 - 1; i >= 0; i--) { bv[cur++] = (byte)(id >> (i * 8)); } } else { string message = $"BUG?: unexpected recvChannelIdLength ({m.recvChannelIdLength})"; Logging.error($"{m}: " + message); throw new Exception(message); } }
public async Task <int> ReadAsync(BytesSegment bs) { var pos = 0; var curnode = latestMsg; if (curnode == null || curnode.tlen == 0) { curnode = (await MsgStream.RecvMsgR(null)).Data; if (curnode == null) { return(0); } } do { if (curnode.len > 0) { var size = Math.Min(bs.Len, curnode.len); Buffer.BlockCopy(curnode.bytes, curnode.offset, bs.Bytes, bs.Offset + pos, size); curnode.SubSelf(size); pos += size; } } while (pos < bs.Len && (curnode = curnode.nextNode) != null); if (curnode == null || curnode.tlen == 0) { latestMsg = null; } else { latestMsg = curnode; } return(pos); }
private async Task SendImpl(Msg msg, byte flags) { var header = BufferPool.GlobalGetBs(4); int hPos = 0; int len = msg.Data.len; if (len > 0x00ffffff) { throw new ArgumentOutOfRangeException("msg", "msg is too long!"); } for (int i = 3 - 1; i >= 0; i--) { header[hPos++] = (byte)((len >> (i * 8)) & (0xff)); } header[hPos++] = flags; var bv = new BytesView(header.Bytes, header.Offset, header.Len); Filters.OnWrite(bv); if (bv.len != hPos) { throw new Exception("filters are not allowed to change data size"); } Filters.OnWrite(msg.Data); if (msg.Data.len != len) { throw new Exception("filters are not allowed to change data size"); } bv.nextNode = msg.Data; await BaseStream.WriteMultipleAsyncR(bv); }
public AwaitableWrapper <Msg> RecvMsgR(BytesView buf) { if (readEOF) { ThrowInvalidOperation(); } raR.Reset(); raR_deq = recvQueue.DequeueAsync(out raR_noWaiting); if (raR_continuation == null) { raR_continuation = () => { Msg m; var tmp = raR_deq; raR_deq = null; if (!tmp.TryGetResult(out m, out var ex)) { raR.SetException(ex); } else { try { m = rar_continuation2(m); } catch (Exception e) { raR.SetException(e); return; } raR.SetResult(m); } };
private Task WriteMultipleAsyncImpl(BytesView bv) { if (bv.nextNode == null) { return(WriteAsync(new BytesSegment(bv))); } var e = writeArgPool.GetValue(); int count = 0; foreach (var cur in bv) { if (cur.len > 0) { count++; } } var bufList = new ArraySegment <byte> [count]; var index = 0; foreach (var cur in bv) { if (cur.len > 0) { bufList[index++] = new ArraySegment <byte>(cur.bytes, cur.offset, cur.len); } } e.BufferList = bufList; return(SendAsync(e)); }
public static Frame unpack(NaiveMultiplexing m, BytesView bv) { var cur = 0; int id = getChId(m, bv, ref cur); bv.SubSelf(cur); return(new Frame { Id = id, Data = bv }); }
public AwaitableWrapper WriteMultipleAsyncR(BytesView bv) { if (raWm == null) { raWm = new ReusableAwaiter <VoidType> .BeginEndStateMachine <SocketStream1>(this, WriteMultipleEnd); } raWm.Reset(); ArraySegment <byte>[] bufList = PrepareWriteMultiple(bv); WriteMultipleBegin(this, bufList, raWm.ArgCallback, raWm.ArgState); return(new AwaitableWrapper(raWm)); }
public static byte[] EncryptOrDecryptBytes(bool isEncrypting, byte[] key, byte[] buf) { var bv = new BytesView(buf); if (key.Length > 16) { key = key.Take(16).ToArray(); } WebSocket.GetAesFilter2(isEncrypting, key)(bv); return(bv.GetBytes()); }
internal async Task SendOpcode(Channel ch, byte opcode) { BytesView bv = new BytesView(new byte[4 + 1]); Task task = null; lock (_sendLock) { int cur = 0; Frame.writeChId(this, bv, ch.Id, ref cur); bv[cur++] = opcode; task = this.SendMsg_NoLock(ReservedChannel, bv); } await task.CAF(); }
public BytesView pack(NaiveMultiplexing m, BytesView headerBv = null) { Debug.Assert(Id <= m.currentMaxId, $"Id > currentMaxId ({m})"); if (headerBv == null) { headerBv = new BytesView(new byte[getSendChIdLen(m)]); } var cur = 0; writeChId(m, headerBv, Id, ref cur); headerBv.len = cur; headerBv.nextNode = Data; return(headerBv); }
public static uint Append(BytesView bv, uint initial) { uint crc = initial; while (bv != null) { if (bv.len > 0) { crc = Crc32CAlgorithm.Append(crc, bv.bytes, bv.offset, bv.len); } bv = bv.nextNode; } return(crc); }
public async Task <Msg> RecvMsg(BytesView buf) { while (true) { Msg msg = Msg.EOF; await WaitBaseStream(); try { msg = await BaseStream.RecvMsg(buf); } catch (Exception) { } if (msg.IsEOF) { OnBaseStreamFailed(); continue; } var data = msg.Data; var opcode = (Opcode)data[0]; if (opcode == Opcode.Data) { ReceivedPacketsCount++; SendAck(); return(msg); } else if (opcode == Opcode.AckOneMessage) { AckedPacketsCount++; var acked = unackedPackets.Dequeue(); SendingWindowAdd(acked.Len); } else if (opcode == Opcode.AckMessages) { int seq = BitConverter.ToInt32(data.bytes, data.offset + 1); int totalLen = 0; while (unackedPackets.Peek().Seq <= seq) { AckedPacketsCount++; var acked = unackedPackets.Dequeue(); totalLen += acked.Len; } SendingWindowAdd(totalLen); } else { throw new Exception("unknown opcode: " + opcode); } } }
public Task <Msg> RecvMsg(BytesView buf) { lock (_syncRoot) { if (MState.HasRemoteShutdown) { throw new InvalidOperationException("remote shutdown"); } if (lastRecv?.IsCompleted == false) { throw new Exception("another RecvMsg() task is running"); } var t = _RecvMsg(buf); lastRecv = t; return(t); } }
public async Task <Msg> _RecvMsg(BytesView buf) { if (!_conn.ivReceived) { _conn.ivReceived = true; var recvEnc = _conn.enc(false); recvEnc.IV = (await ws.ReadAsync()).payload; ws.AddReadFilter(FilterBase.GetStreamFilterFromIVEncryptor(false, recvEnc, true)); } var frame = await ws.ReadAsync(); if (frame.opcode == 0x01) { OnFinReceived(); return(Msg.EOF); } return(frame.payload); }
public static AwaitableWrapper WriteMultipleAsyncR(this IMyStream myStream, BytesView bv) { if (myStream is IMyStreamMultiBuffer bvs) { return(bvs.WriteMultipleAsyncR(bv)); } else { return(new AwaitableWrapper(NaiveUtils.RunAsyncTask(async() => { foreach (var item in bv) { if (item.len > 0) { await myStream.WriteAsync(new BytesSegment(item)); } } }))); } }
private static ArraySegment <byte>[] PrepareWriteMultiple(BytesView bv) { int count = 0; foreach (var cur in bv) { if (cur.len > 0) { count++; } } var bufList = new ArraySegment <byte> [count]; var index = 0; foreach (var cur in bv) { if (cur.len > 0) { bufList[index++] = new ArraySegment <byte>(cur.bytes, cur.offset, cur.len); } } return(bufList); }
public static int getChId(NaiveMultiplexing m, BytesView bv, ref int cur) { int id = 0; int idLen = m.recvChannelIdLength; if (idLen == 1) { id = (sbyte)bv[cur++]; if (id == sbyte.MinValue) { id = ReservedId; } } else if (idLen == 2) { id = (short)(bv[cur++] << 8 | bv[cur++]); if (id == short.MinValue) { id = ReservedId; } } else if (idLen == 4) { for (int i = 4 - 1; i >= 0; i--) { id |= (bv[cur++] << (i * 8)); } } else { string message = $"BUG?: unexpected recvChannelIdLength ({idLen})"; Logging.error($"{m}: " + message); throw new Exception(message); } return(id); }
public Task <Msg> RecvMsg(BytesView buf) { if (PreReadEnabled && recvTasks == null) { recvTasks = new Task <Msg> [recvStreams.Length]; for (int i = 0; i < recvStreams.Length; i++) { var i2 = i; recvTasks[i] = Task.Run(() => recvStreams[i2].RecvMsg(null)); } } if (nextRecv == recvStreams.Length) { nextRecv = 0; } var curRecv2 = nextRecv++; if (recvTasks != null) { var task = recvTasks[curRecv2]; recvTasks[curRecv2] = (!task.IsCompleted) ? NaiveUtils.RunAsyncTask(async(s) => { await s.prevTask; return(await s.curStream.RecvMsg(null)); }, new recvArgs { prevTask = task, curStream = recvStreams[curRecv2] }) //? task.ContinueWith((t, s) => s.CastTo<IMsgStream>().RecvMsg(null), recvStreams[curRecv2], TaskContinuationOptions.ExecuteSynchronously).Unwrap() : recvStreams[curRecv2].RecvMsg(null); return(task); } else { return(recvStreams[curRecv2].RecvMsg(buf)); } }
public AwaitableWrapper WriteMultipleAsyncR(BytesView bv) { return(new AwaitableWrapper(MsgStream.SendMsg(new Msg(bv)))); }
public static uint Compute(BytesView bv) { return(Append(bv, 0)); }
public Task WriteMultipleAsync(BytesView bv) { ArraySegment <byte>[] bufList = PrepareWriteMultiple(bv); return(TaskHelper.FromAsyncTrim(this, bufList, WriteMultipleBegin, WriteMultipleEnd)); }
public async Task <Msg> RecvMsg(BytesView buf) { return(await RecvMsgR(buf)); }
public async Task <Msg> RecvMsg(BytesView buf) { var frame = await RecvImpl(); return(new Msg(frame.Payload)); }
public AwaitableWrapper WriteMultipleAsyncR(BytesView bv) { return(new AwaitableWrapper(WriteMultipleAsyncImpl(bv))); }
public Frame(int id, BytesView data) { Id = id; Data = data; }