# IParser

パーサーオブジェクトに１バイトずつ電文を投入することで、電文系列を解釈する状態遷移マシンです。

## メソッド

### Parse(), operator << ()

```cpp
IParser& Parse(uint8_t u8b)
IParser& operator << (char_t c)
```

パーサーに１バイト入力します。入力のたびにパーサーの状態が変化し、パーサーの解釈が完了すると`state()`が`E_TWESERCMD_COMPLETE`に変化し解釈完了状態となります。

### state()

```cpp
uint8_t state()
```

パーサーの状態を取得します。

### operator bool(), is\_complete()

```cpp
operator bool()
bool is_complete()
```

パーサーの状態が`E_TWESERCMD_COMPLETE`の場合`true`になります。

### length()

```cpp
uint16_t length()
```

パーサーで解釈済みのバイト列のデータ長を返します。

### operator\[]\()

```cpp
uint8_t operator[](int i)
```

パーサーの解釈済みのバイト列にアクセスします。

### get\_payload()

```cpp
SmplBuf_Byte& get_payload()
```

パーサーの解釈済みのバイト列を格納した配列クラス`SmplBuf_Byte`を参照します。

### set\_payload()

```cpp
template <typename T>
inline void set_payload(T& bobj)

inline void set_payload(uint8_t *b, uint8_t *e)

//例: buffに出力書式を格納する
AsciiParser format_ascii; // パーサー（出力用）
SmplBuf_ByteSL<256> buff; // 出力バッファ
uint8_t buff_raw[] = "ABCDE"; // データ列

format_ascii.set_payload(buff_raw, buff_raw + sizeof(buff_raw));

buff << format_ascii;
for(auto x : buff) putchar(x);

```

パーサーオブジェクトを用いて出力を構築する際に、データ列をコピーします。コピー元は`SmplBuf_Byte`データ構造または`uint8_t*`型の先頭と終端+1ポインタの組み合わせです。

### reinit()

```cpp
virtual void reinit()
```

パーサーの解釈途中の内容を破棄し、新たな解釈を始めます。

### operator << ()

```cpp
IStreamOut& operator << (TWE::IStreamOut& lhs, IParser& rhs)
IStreamOut& operator << (TWETERM::ITerm& lhs, IParser& rhs)
```

IStreamOutをベースクラスにもつストリームオブジェクトに、書式出力します。

## メソッド

### \_u8Parse()

```cpp
virtual uint8_t _u8Parse(char_t u8b) = 0
```

１バイト入力して解釈を進める仮想関数です。派生クラスにより実装されます。

### \_vOutput()

```cpp
virtual inline void _vOutput(SmplBuf_Byte& bobj, IStreamOut& p) = 0
```

バイト配列`bobj`に格納されるバイト列に対応する書式をストリーム`p`に出力する仮想関数です。派生クラスにより実装されます。

## 状態

| 状態名                          |    値    | 状態                     |
| ---------------------------- | :-----: | ---------------------- |
| `E_TWESERCMD_EMPTY`          |    0    | 解釈前で、まだ系列のヘッダも認識できていない |
|                              | 1..0x7F | 解釈中                    |
| `E_TWESERCMD_COMPLETE`       |   0x80  | 系列が正しく解釈できた            |
| `E_TWESERCMD_ERROR`          |   0x81  | 系列の解釈にエラーがあった          |
| `E_TWESERCMD_CHECKSUM_ERROR` |   0x82  | 系列は得られたがチェックサムエラーだった   |
