// ------------------------------------------------------------------------------------ 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"); } }
// ------------------------------------------------------------------------------------ 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); } } }
// ------------------------------------------------------------------------------------ // 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"); } } }
// 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); }