bzip2
Cアプリケーション内のストリームからデータをプルしています。データのチャンクがデコンプレッサから出てくるので、それらは以下に書き込むことができますstdout
:
fwrite(buffer, 1, length, stdout);
これはうまくいきます。に送信されると、すべてのデータを取得しstdout
ます。
に書き込む代わりにstdout
、このステートメントからの出力を1行のチャンクで内部的に処理したいと思います。改行文字で終了する文字列です\n
。
デコンプレッサストリームの出力を、改行に達するまで一度に1文字ずつ別のバッファに書き込んでから、行ごとの処理関数を呼び出しますか?これは遅いですか、よりスマートなアプローチがありますか?アドバイスありがとうございます。
編集
あなたの提案をありがとう。最終的に、出力バッファーに相当するデータを通過するたびに、短い行バッファーの先頭に残り(出力バッファーの最後にある「スタブ」)を格納するバッファーのペアを作成しました。
出力バッファを1文字ずつループし、改行に相当するデータを一度に処理します。改行のない余りが割り当てられて割り当てられ、次のストリームのラインバッファにコピーされます。繰り返されるステートメントrealloc
よりも安価なようです。malloc-free
これが私が思いついたコードです:
char bzBuf[BZBUFMAXLEN];
BZFILE *bzFp;
int bzError, bzNBuf;
char bzLineBuf[BZLINEBUFMAXLEN];
char *bzBufRemainder = NULL;
int bzBufPosition, bzLineBufPosition;
bzFp = BZ2_bzReadOpen(&bzError, *fp, 0, 0, NULL, 0); /* http://www.bzip.org/1.0.5/bzip2-manual-1.0.5.html#bzcompress-init */
if (bzError != BZ_OK) {
BZ2_bzReadClose(&bzError, bzFp);
fprintf(stderr, "\n\t[gchr2] - Error: Bzip2 data could not be retrieved\n\n");
return -1;
}
bzError = BZ_OK;
bzLineBufPosition = 0;
while (bzError == BZ_OK) {
bzNBuf = BZ2_bzRead(&bzError, bzFp, bzBuf, sizeof(bzBuf));
if (bzError == BZ_OK || bzError == BZ_STREAM_END) {
if (bzBufRemainder != NULL) {
/* fprintf(stderr, "copying bzBufRemainder to bzLineBuf...\n"); */
strncpy(bzLineBuf, bzBufRemainder, strlen(bzBufRemainder)); /* leave out \0 */
bzLineBufPosition = strlen(bzBufRemainder);
}
for (bzBufPosition = 0; bzBufPosition < bzNBuf; bzBufPosition++) {
bzLineBuf[bzLineBufPosition++] = bzBuf[bzBufPosition];
if (bzBuf[bzBufPosition] == '\n') {
bzLineBuf[bzLineBufPosition] = '\0'; /* terminate bzLineBuf */
/* process the line buffer, e.g. print it out or transform it, etc. */
fprintf(stdout, "%s", bzLineBuf);
bzLineBufPosition = 0; /* reset line buffer position */
}
else if (bzBufPosition == (bzNBuf - 1)) {
bzLineBuf[bzLineBufPosition] = '\0';
if (bzBufRemainder != NULL)
bzBufRemainder = (char *)realloc(bzBufRemainder, bzLineBufPosition);
else
bzBufRemainder = (char *)malloc(bzLineBufPosition);
strncpy(bzBufRemainder, bzLineBuf, bzLineBufPosition);
}
}
}
}
if (bzError != BZ_STREAM_END) {
BZ2_bzReadClose(&bzError, bzFp);
fprintf(stderr, "\n\t[gchr2] - Error: Bzip2 data could not be uncompressed\n\n");
return -1;
} else {
BZ2_bzReadGetUnused(&bzError, bzFp, 0, 0);
BZ2_bzReadClose(&bzError, bzFp);
}
free(bzBufRemainder);
bzBufRemainder = NULL;
皆様のご協力に心より感謝申し上げます。これはうまく機能しています。