## f_forward

ファイルからデータを読み出し、送信ストリームに直接転送します。

    FRESULT f_forward (
      FIL* fp,                         /* [IN] ファイル オブジェクト構造体 */
      UINT (*func)(const BYTE*,UINT),  /* [IN] データ転送関数 */
      UINT btf,                        /* [IN] 転送するバイト数 */
      UINT* bf                         /* [OUT] 転送されたバイト数 */
    );

#### 引数

fp
  ファイル オブジェクト構造体へのポインタを指定します。
func
  データを渡すユーザ定義関数へのポインタを指定します。この関数の仕様はサンプルを参照してください。
btf
  転送するバイト数(0～UINTの最大値)を指定します。
bf
  実際に転送されたバイト数を格納する変数を指すポインタを指定します。

#### 戻り値

FR_OK, FR_DISK_ERR, FR_INT_ERR, FR_DENIED, FR_INVALID_OBJECT, FR_TIMEOUT

#### 解説

ファイルのデータをバッファに読み出さずに送信ストリームに直接転送します。アプリケーション側でデータ バッファを必要としないので、メモリの限られた環境で有効です。リード/ライト ポインタは転送されたバイト数だけ進みます。指定されたバイト数の転送中にファイルの終端に達した場合や送信ストリームがビジーになった場合、`*bf`は`btf`よりも小さくなります。

#### 対応情報

`_USE_FORWARD == 1`のときに使用可能です。

#### 使用例（オーディオ再生）

    /*-----------------------------------------------------------------------*/
    /* f_forward関数から呼ばれるデータ送信関数の例                           */
    /*-----------------------------------------------------------------------*/

    UINT out_stream (   /* 戻り値: 転送されたバイト数またはストリームの状態 */
        const BYTE *p,  /* 転送するデータを指すポインタ */
        UINT btf        /* >0: 転送を行う(バイト数). 0: ストリームの状態を調べる */
    )
    {
        UINT cnt = 0;

        if (btf == 0) {     /* センス要求 */
            /* ストリームの状態を返す (0: ビジー, 1: レディ) */
            /* 一旦、レディを返したら、続く転送要求で少なくとも1バイトは */
            /* 転送されないと f_forward関数は FR_INT_ERR となる。 */
            if (FIFO_READY) cnt = 1;
        }
        else {              /* 転送要求 */
            do {    /* 全てのバイトを転送するか、ストリームがビジーになるまで繰り返す */
                FIFO_PORT = *p++;
                cnt++;
            } while (cnt < btf && FIFO_READY);
        }

        return cnt;
    }

    /*-----------------------------------------------------------------------*/
    /* f_forward関数の使用例                                                 */
    /*-----------------------------------------------------------------------*/

    FRESULT play_file (
        char *fn        /* 再生するオーディオ ファイル名を指すポインタ */
    )
    {
        FRESULT rc;
        FIL fil;
        UINT dmy;

        /* ファイルを読み出しモードで開く */
        rc = f_open(&fil, fn, FA_READ);
        if (rc) return rc;

        /* 全てのデータが転送されるかエラーが発生するまで続ける */
        while (rc == FR_OK && !f_eof(&fil)) {

            /* ほかの処理... */

            /* 定期的または要求に応じてデータをストリームに送出する */
            rc = f_forward(&fil, out_stream, 1000, &dmy);
        }

        /* ファイルを閉じて戻る */
        f_close(&fil);
        return rc;
    }

#### 参照

`f_open, fgets, f_write, f_close, FIL`

戻る