Ejemplo n.º 1
0
// ------------------------------------------------------------------------------------
        public void Expand_WS_buf()
        {
            m_rem_ui16 += (WS_Buf_Pool.Expand_MemBlk(ref m_ary_buf) >> 1);
            if (m_idx_byte + (m_rem_ui16 << 1) != m_ary_buf.Length) //// エラー顕在化
            {
                throw new Exception("Write_WS_Buffer.Expand_WS_buf() : m_idx_byte + (m_rem_ui16 << 1) != m_ary_buf.Length");
            }
        }
Ejemplo n.º 2
0
// ------------------------------------------------------------------------------------
        public void Copy_bytes_from(byte[] ary_buf_src)
        {
            if ((ary_buf_src.Length & 1) == 1)
            {
                // idx_byte が奇数である場合はエラーとする
                throw new Exception("Write_WS_Buffer.Set_idx_byte() : ary_buf_src.Length が奇数となっています。");
            }

            int len_src_u16 = (ary_buf_src.Length >> 1);

            while (m_rem_ui16 < len_src_u16) // ここでは、大きなサイズのコピーが発生しても大丈夫なようにしている
            {
                // Expand_MemBlk の戻り値は、増加された「バイト数」
                m_rem_ui16 += (WS_Buf_Pool.Expand_MemBlk(ref m_ary_buf) >> 1);
                if (m_idx_byte + (m_rem_ui16 << 1) != m_ary_buf.Length)  //// エラー顕在化
                {
                    throw new Exception("Write_WS_Buffer.Copy_bytes_from() : m_idx_byte + m_rem_ui16 != m_ary_buf.Length");
                }
            }

            // m_rem_ui16 の値は先に決定しておく
            m_rem_ui16 -= len_src_u16;

            unsafe
            {
                fixed(byte *pdst_byte_top = m_ary_buf)
                fixed(byte *psrc_byte_top = ary_buf_src)
                {
                    ushort *pdst_u16 = (ushort *)(pdst_byte_top + m_idx_byte);
                    ushort *psrc_u16 = (ushort *)psrc_byte_top;

                    for (; len_src_u16 > 0; --len_src_u16)
                    {
                        *pdst_u16++ = *psrc_u16++;
                    }

                    m_idx_byte = (int)(((byte *)pdst_u16) - pdst_byte_top);
                }
            }
        }
Ejemplo n.º 3
0
// ------------------------------------------------------------------------------------
// 1行分の文字数をカウントして、バッファを確保する。
// 必要となる最大バッファサイズは、
// 文字数+3(先頭の ID_Text or ID_TR, ID_TD, ID_Text)+1(` の未ペアがあった場合)
// +2*「| の個数(TD、ID_Text)」+(Chr.PCS_Tab - 1)*TABの個数
        public unsafe void SecureBuf_for1Line(ushort *psrc)
        {
            ushort *psrc_top = psrc;
            int     pcs_add  = 0;

            while (true)
            {
                switch (*psrc)
                {
                case Chr.CR:
                case Chr.LF:
                    goto LOOP_OUT;

                case Chr.TAB:
                    pcs_add += (Chr.PCS_Tab - 1);
                    break;

                case '|':
                    pcs_add += 2;
                    break;
                }
                psrc++;
            }
LOOP_OUT:
            // 本当は +4 でいいが、余裕をみて +10 としている
            int pcs_to_need = (int)(psrc - psrc_top) + 10 + pcs_add;

            if (m_rem_ui16 < pcs_to_need)
            {
                m_rem_ui16 += (WS_Buf_Pool.Expand_MemBlk(ref m_ary_buf) >> 1);
                if (m_idx_byte + (m_rem_ui16 << 1) != m_ary_buf.Length)  //// エラー顕在化
                {
                    throw new Exception("Write_WS_Buffer.SecureBuf_for1Line() : m_idx_byte + m_rem_ui16 != m_ary_buf.Length");
                }
            }
        }
Ejemplo n.º 4
0
// m_ary_buf に書き込まれる内容
// ID_ERR_Report -> ID_Div -> ID_Text -> err_msg -> ID_Div -> ID_Text -> psrc からの EN_MAX_ERR_Text 文字数分の内容
// err_msg は、クライアントと、サーバー側の StdOut に送られるメッセージ
// psrc は MD ファイル側のポインタで fixed されている

// 注意: バッファの拡張をする場合があるため、m_ary_buf は fixed されていてはならない
        public unsafe void CrtErrReport_to_WrtBuf_and_ThrowErr(ushort *psrc, string err_msg)
        {
            // +10 は念のためのマージン
            int max_len_u16_to_wrt_buf = 1 + 1 + 2 + err_msg.Length + 1 + 2 + EN_MAX_ERR_Text + 10;

            if (m_rem_ui16 < max_len_u16_to_wrt_buf)
            {
                // Expand_MemBlk の戻り値は、増加された「バイト数」
                m_rem_ui16 += (WS_Buf_Pool.Expand_MemBlk(ref m_ary_buf) >> 1);
                if (m_idx_byte + (m_rem_ui16 << 1) != m_ary_buf.Length)  //// エラー顕在化
                {
                    throw new Exception(
                              "Write_WS_Buffer.CrtErrReport_to_WrtBuf_and_ThrowErr() : m_idx_byte + m_rem_ui16 != m_ary_buf.Length");
                }
            }

            unsafe
            {
                fixed(byte *pdst_top = m_ary_buf)
                {
                    ushort *pdst = (ushort *)(pdst_top + m_idx_byte);

                    // err_msg の埋め込み
                    {
                        int len_err_msg = err_msg.Length;

                        *pdst = (ushort)ID.ERR_Report;          // このブロックで8バイト
                        *(pdst + 1) = (ushort)ID.Div;
                        *(pdst + 2) = (ushort)ID.Text;
                        *(pdst + 3) = (ushort)len_err_msg;
                        pdst       += 4;

                        fixed(char *pmsg_top = err_msg)
                        {
                            ushort *pmsg = (ushort *)pmsg_top;

                            for (; len_err_msg > 0; --len_err_msg)
                            {
                                *pdst++ = *pmsg++;
                            }
                        }
                    }

                    // エラーを特定しやすいように、クライアントに psrc からの文字列を送出する
                    // psrc は '\0' で終了していることに留意する
                    ushort *pTmnt_dst = pdst + EN_MAX_ERR_Text;

                    *pdst = (ushort)ID.Div;
                    *(pdst + 1) = (ushort)ID.Text;
                    ushort *ptr_at_pos_text_len = pdst + 2;

                    pdst += 3;

                    while (true)
                    {
                        ushort chr = *psrc++;
                        if (pdst == pTmnt_dst || chr == 0)
                        {
                            break;
                        }

/*
 *                              if (chr == Chr.CR) { *pdst++ = (ushort)ID.BR;  psrc++;  continue; }
 *                              if (chr == Chr.LF) { *pdst++ = (ushort)ID.BR;  continue; }
 */
                        *pdst++ = chr;
                    }

                    *ptr_at_pos_text_len = (ushort)((pdst - ptr_at_pos_text_len) - 1);      // 文字数の書き込み

                    m_idx_byte = (int)(((byte *)pdst) - pdst_top);
                    m_rem_ui16 = (m_ary_buf.Length - m_idx_byte) >> 1;
                }
            }

            this.Wrt_ID_End();
            throw new Exception(err_msg);
        }
Ejemplo n.º 5
0
// ------------------------------------------------------------------------------------
        public async Task Spawn_Context(HttpListenerContext context, uint idx_context)
        {
            // AcceptWebSocketAsync() は、キャンセルトークンをサポートしていない
            // 引数: サポートされている WebSocket サブプロトコル
            HttpListenerWebSocketContext wsc = await context.AcceptWebSocketAsync(null);

            MainForm.StdOut("--- WebSocket 接続完了\r\n");

            using (m_WS = wsc.WebSocket)
                using (WS_Buf_Pool.MemBlock mem_blk = WS_Buf_Pool.Lease_MemBlock())
                {
                    m_read_WS_buf  = new Read_WS_Buf(mem_blk.m_ary_buf);
                    m_write_WS_buf = new Write_WS_Buffer(mem_blk.m_ary_buf);

                    try
                    {
                        // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
#if CREATE_TEST_LEXED_CODE
                        // Test Lexed Code を送信する
                        Write_WS_Buffer write_ws_buf = MainForm.ms_DBG_write_WS_buf;
                        await m_WS.SendAsync(
                            new ArraySegment <byte>(write_ws_buf.Get_buf(), 0, write_ws_buf.Get_idx_byte_cur())
                            , WebSocketMessageType.Binary, true, ms_cts_shutdown.Token);
#else
                        // まずはルートフォルダのファイル情報を送信しておく
                        FileLister.Set_DirFileNames(m_write_WS_buf, "./");
                        await m_write_WS_buf.SendAsync(m_WS, ms_cts_shutdown);
#endif

                        while (true)
                        {
                            WebSocketReceiveResult rslt = await m_WS.ReceiveAsync(
                                new ArraySegment <byte>(mem_blk.m_ary_buf), ms_cts_shutdown.Token);

                            if (rslt.EndOfMessage == false)
                            {
                                MainForm.StdOut("--- 不正な大きさのデータを受信しました。クライアントを切断します\r\n");
                                break;
                            }
                            if (m_WS.State == WebSocketState.CloseReceived)
                            {
                                MainForm.StdOut("--- クライアントが接続を Close しました\r\n");
                                break;
                            }

                            m_read_WS_buf.Renew(rslt.Count);
                            switch (m_read_WS_buf.Read_ID())
                            {
                            case ID.DirFileList: {
                                ID id = m_read_WS_buf.Read_ID();
                                if (id != ID.Text)
                                {
                                    throw new Exception($"不正なパラメータを受信 DirFileList / id -> {((byte)id).ToString()}");
                                }

                                FileLister.Set_DirFileNames(m_write_WS_buf, m_read_WS_buf.Get_text_cur());
                                await m_write_WS_buf.SendAsync(m_WS, ms_cts_shutdown);
                            } continue;

                            case ID.Files_inDir: {
                                ID id = m_read_WS_buf.Read_ID();
                                if (id != ID.Text)
                                {
                                    throw new Exception($"不正なパラメータを受信 Files_inDir / id -> {((byte)id).ToString()}");
                                }

                                string str_path_dir = m_read_WS_buf.Get_text_cur();

                                id = m_read_WS_buf.Read_ID();
                                if (id != ID.Num_int)
                                {
                                    throw new Exception($"不正なパラメータを受信 Files_inDir / id -> {((byte)id).ToString()}");
                                }

                                int SEC_Updated_recv = m_read_WS_buf.Get_Num_int();

                                FileLister.OnFiles_inDir(m_write_WS_buf, str_path_dir, SEC_Updated_recv);
                                await m_write_WS_buf.SendAsync(m_WS, ms_cts_shutdown);
                            } continue;

                            case ID.MD_file: {
                                var(path_md_file, SEC_Updated, idx_byte_SEC_updated) = m_read_WS_buf.Read_Req_MD();
                                MainForm.StdOut($"path_md_file : {path_md_file} / SEC_Updated : {SEC_Updated.ToString()}\r\n");

                                // ID.MD_file -> ID_Text (path_dir) -> ID_Text (file name) は Receive時の値を流用
                                m_write_WS_buf.Set_idx_byte(idx_byte_SEC_updated);
                                m_write_WS_buf.Wrt_Num_int(1000);          // 1000 は試験値

                                Lexer.LexFile(m_write_WS_buf, path_md_file);
                                MainForm.StdOut("--- Lexing 処理完了\r\n");

                                m_write_WS_buf.Simplify_Buf();
                                MainForm.StdOut("--- Simplify_Buf 処理完了\r\n");

                                await m_write_WS_buf.SendAsync(m_WS, ms_cts_shutdown);
                            } continue;
                            }



                            MainForm.StdOut($"--- ReceiveAsync() : 受信バイト数 -> {rslt.Count}\r\n");
                            MainForm.HexDump(mem_blk.m_ary_buf, 0, 20);
                            DBG_WS_Buffer.Show_WS_buf(MainForm.ms_RBox_stdout, mem_blk.m_ary_buf, rslt.Count);



                            // 今は、index.md のみを解析するようにしている
//				string ret_str = Lexer.LexFile(m_write_WS_buf, "md_root/index.md");

//				string str_recv = ms_utf16_encoding.GetString(mem_blk.m_ary_buf, 0, rslt.Count);
//				MainForm.StdOut(str_recv);
                        }

                        await m_WS.CloseOutputAsync(WebSocketCloseStatus.NormalClosure, "接続を終了します", ms_cts_shutdown.Token);
                    }
                    catch (OperationCanceledException)
                    {
                        MainForm.StdOut("--- サーバーシャットダウンのシグナルを受信しました\r\n");
                    }
                    catch (WebSocketException ex)
                    {
                        MainForm.StdOut($"!!! 例外発を補足しました WebSoketErrorCode : {ex.WebSocketErrorCode.ToString()}\r\n");
                        MainForm.StdOut($"    {ex.ToString()}\r\n");
                    }
                    catch (Exception ex)
                    {
                        MainForm.StdOut($"!!! 例外を補足しました : {ex.ToString()}\r\n");
                    }
                }

            MdSvr.Remove_task_context(idx_context);
            MainForm.StdOut("--- WebSocket 切断完了\r\n");
        }