picox  0.1
Xstream

入出力を抽象化するストリーム機能を提供します [詳解]

Xstream 連携図

データ構造

struct  XMemStream
 メモリに対して入出力を行うストリーム型です [詳解]
 
struct  XStream
 ストリームを表す抽象型です [詳解]
 

マクロ定義

#define X_MEMSTREAM_TAG   (X_MAKE_TAG('X', 'M', 'M', 'S'))
 XMemStreamのタグです
 
#define X_STREAM_TAG   (X_MAKE_TAG('X', 'S', 'T', 'R'))
 ストリームタグの初期値です
 

関数

static XMemStreamx_memstream_cast (XStream *stream)
 tagがXMemStreamと一致していなければNULLを返します
 
void xmemstream_init (XMemStream *self, void *mem, size_t size, size_t capacity)
 メモリストリームを初期化します [詳解]
 
int xstream_close (XStream *self)
 ストリームの終了処理を行います [詳解]
 
int xstream_error (const XStream *self)
 最後のエラー値を返します
 
const char * xstream_error_string (const XStream *self, int errcode)
 エラー値の文字列表現を返します
 
int xstream_flush (XStream *self)
 ストリームの終了処理を行います [詳解]
 
int xstream_getc (XStream *self)
 ストリームから1バイトを読みだし、intにキャストして返します [詳解]
 
int xstream_gets (XStream *self, char *dst, size_t size, char **result, bool *overflow)
 ストリームから1行を取り出します [詳解]
 
void xstream_init (XStream *self)
 ストリームの初期化を行います
 
int xstream_printf (XStream *self, const char *fmt,...)
 ストリームにvprintf形式の出力を行います [詳解]
 
int xstream_putc (XStream *self, int c)
 cをunsigned charにキャストしてストリームに書き込みます [詳解]
 
int xstream_read (XStream *self, void *dst, size_t size, size_t *nread)
 ストリームからdstにsizeバイトの読み出しを試みます [詳解]
 
int xstream_seek (XStream *self, XOffset offset, XSeekMode mode)
 ストリームの現在位置を移動します [詳解]
 
int xstream_tell (XStream *self, XSize *pos)
 ストリームの現在位置をposに格納します [詳解]
 
int xstream_vprintf (XStream *self, const char *fmt, va_list args)
 ストリームにvprintf形式の出力を行います [詳解]
 
int xstream_write (XStream *self, const void *src, size_t size, size_t *nwritten)
 ストリームにsrcからsizeバイトの書き込みを試みます [詳解]
 

stream_function_pointers

ストリームにセットする関数ポインタ型のグループです

戻り値のint型はエラーステータスを返し、0は正常終了、0以外はエラーを表します 。

typedef int(* XStreamReadFunc) (void *driver, void *dst, size_t size, size_t *nread)
 ストリームからの読み出し関数ポインタ型です [詳解]
 
typedef int(* XStreamWriteFunc) (void *driver, const void *src, size_t size, size_t *nwritten)
 ストリームへの書き込み関数ポインタ型です [詳解]
 
typedef int(* XStreamSeekFunc) (void *driver, XOffset offset, XSeekMode mode)
 ストリームの現在位置を移動する関数ポインタ型です [詳解]
 
typedef int(* XStreamTellFunc) (void *driver, XSize *pos)
 ストリームの現在位置を取得する関数ポインタ型です
 
typedef int(* XStreamSizeFunc) (void *driver, XSize *size)
 ストリームのバイト数を取得する関数ポインタ型です
 
typedef int(* XStreamFlushFunc) (void *driver)
 ストリームのバッファリングをフラッシュする関数ポインタ型です
 
typedef int(* XStreamCloseFunc) (void *driver)
 ストリームのフラッシュと、リソースの開放を行う関数ポインタ型です
 
typedef const char *(* XStreamErrorStringFunc) (int errcode)
 ストリームが返したエラーステータスに対応する文字列を返す関数ポインタ型です
 

詳解

入出力を抽象化するストリーム機能を提供します

プログラムの目的とは、どこかから入力を受け取り、処理をし、どこかへ出力をする ことで、C言語ではそれを関数で実現します。

例えば組込みプログラムでの入出力先は、メモリ、ファイル、UART、シリアルフラッ シュ等です。(ファイルという概念が既に入出力を抽象化したものであることにも注 目)

入出力先が異なるだけで、内部処理が同じ関数を全て用意することは困難で、ライブ ラリ実装者としては、精々メモリとファイル用位までしかインターフェースを限定で きません。

そこで、ストリームという抽象型に対して入出力を行うことでこの問題を解決する ことができます。

標準CではFILEがストリームの役割を担いますが、FILEストリームは基本的にファイ ルシステムや実行環境依存の前提条件が多いため、組込み環境では扱いにくいもので す。

picoxが提供する簡易的なストリームを入出力に使用することで、入出力先に依存し ない関数を実装できます。

基本的なストリームはpicoxが提供しますが、独自のストリームを定義したい場合は 、まずはXMemStreamの実装を参考にしてみてください。

型定義詳解

typedef int(* XStreamReadFunc) (void *driver, void *dst, size_t size, size_t *nread)

ストリームからの読み出し関数ポインタ型です

dstにストリームからsizeバイトの読み出しを試み、nreadには実際に読み出せたバイ ト数を格納してください。

typedef int(* XStreamSeekFunc) (void *driver, XOffset offset, XSeekMode mode)

ストリームの現在位置を移動する関数ポインタ型です

modeに応じて、offsetバイトの移動を行ってください。

typedef int(* XStreamWriteFunc) (void *driver, const void *src, size_t size, size_t *nwritten)

ストリームへの書き込み関数ポインタ型です

srcからストリームにsizeバイトの書き込みを試み、nwrittenには実際に書き込めた バイト数を格納してください。

関数詳解

void xmemstream_init ( XMemStream self,
void *  mem,
size_t  size,
size_t  capacity 
)

メモリストリームを初期化します

引数
memストリーム対象のメモリ先頭アドレス
size初期有効バイト数
capacitywriteやseekで拡張可能なバイト数

例えば、sizeが10でcapacityが20の時、readは10バイトまでしか行えませんが、 writeで5バイト追記した場合は、sizeが拡張され、15バイトまでreadできるようにな ります。さらに6バイトを追記しようとすると、capacityは20なので、最後の1バイト は捨てられ、sizeは20となり、capacity以上の拡張を行うことはできません。

int xstream_close ( XStream self)

ストリームの終了処理を行います

戻り値
==0 正常終了
!=0 エラー
int xstream_flush ( XStream self)

ストリームの終了処理を行います

戻り値
==0 正常終了
!=0 エラー
int xstream_getc ( XStream self)

ストリームから1バイトを読みだし、intにキャストして返します

エラー or ストリーム終端に達していた場合はEOFを返します。

int xstream_gets ( XStream self,
char *  dst,
size_t  size,
char **  result,
bool *  overflow 
)

ストリームから1行を取り出します

streamから最大でsize - 1バイトの文字をdstに格納します。読み込みはEOFまたは改 行文字('
')まで行われます。

std::fgetsとは異なり、改行文字はバッファに含まれません。また、CR('')は読み 捨てするので、Mac形式の改行コードには対応していません。

  • resultはEOFの時はNULLが、それ以外の時はdstがセットされます。
  • overflowは1行がsizeを超えた時にtrueがセットされます。

result, overflowのセットが不要な場合はNULLを渡してください。

真面目に処理をする場合、以下の4つのパターンを適切に判定する必要があります。

  • 正常終了 ((戻り値 0) && (result != NULL))
  • EOF ((戻り値 0) && (result == NULL))
  • オーバーフロー ((戻り値 0) && (overflow == true))
  • IOエラー (戻り値 非0)
// サンプルコード
for (;;)
{
err = xstream_gets(stream, buf, sizeof(buf), result, overflow);
X_BREAK_IF(err);
X_BREAK_IF(!result); // EOF
if (overflow)
{
do
{
// オーバーフローした行を読み捨てる。
err = xstream_gets(st, buf, sizeof(buf), result, overflow);
X_BREAK_IF(err);
} while (overflow);
}
X_BREAK_IF(err);
}
int xstream_printf ( XStream self,
const char *  fmt,
  ... 
)

ストリームにvprintf形式の出力を行います

戻り値
>=0 書き込んだバイト数
<0 エラー
int xstream_putc ( XStream self,
int  c 
)

cをunsigned charにキャストしてストリームに書き込みます

エラー or ストリーム終端に達していた場合はEOFを返し、正常終了ならc自身を返し ます。

int xstream_read ( XStream self,
void *  dst,
size_t  size,
size_t *  nread 
)

ストリームからdstにsizeバイトの読み出しを試みます

nreadには読み出しに成功したバイト数がセットされます。

戻り値
==0 正常終了
!=0 エラー
int xstream_seek ( XStream self,
XOffset  offset,
XSeekMode  mode 
)

ストリームの現在位置を移動します

戻り値
==0 正常終了
!=0 エラー
int xstream_tell ( XStream self,
XSize pos 
)

ストリームの現在位置をposに格納します

戻り値
==0 正常終了
!=0 エラー
int xstream_vprintf ( XStream self,
const char *  fmt,
va_list  args 
)

ストリームにvprintf形式の出力を行います

戻り値
>=0 書き込んだバイト数
<0 エラー
int xstream_write ( XStream self,
const void *  src,
size_t  size,
size_t *  nwritten 
)

ストリームにsrcからsizeバイトの書き込みを試みます

nwrittenには書き込みに成功したバイト数がセットされます。

戻り値
==0 正常終了
!=0 エラー