mirror of
				https://codeberg.org/1414codeforge/ubgpsuite.git
				synced 2025-06-05 21:29:11 +02:00 
			
		
		
		
	[lonetic/bufio,lonetix/bgp,tools/bgpgrep,tools/peerindex] Add support for buffered input
This commit is contained in:
		| @@ -159,7 +159,7 @@ static void NormalizeExtendedTimestamp(Dumpfmtctx *ctx) | |||||||
| 	ctx->microsecs %= 1000000; | 	ctx->microsecs %= 1000000; | ||||||
| } | } | ||||||
|  |  | ||||||
| static void DumpUnknown(Stmbuf *sb, BgpType type) | static void DumpUnknown(Stmwrbuf *sb, BgpType type) | ||||||
| { | { | ||||||
| 	Bufio_Putc(sb, UNKNOWN_MARKER); | 	Bufio_Putc(sb, UNKNOWN_MARKER); | ||||||
| 	Bufio_Putc(sb, SEP_CHAR); | 	Bufio_Putc(sb, SEP_CHAR); | ||||||
| @@ -167,7 +167,7 @@ static void DumpUnknown(Stmbuf *sb, BgpType type) | |||||||
| 	Bufio_Putsn(sb, SEPS_BUF, 8); | 	Bufio_Putsn(sb, SEPS_BUF, 8); | ||||||
| } | } | ||||||
|  |  | ||||||
| static Sint32 DumpCaps(Stmbuf *sb, Bgpcapiter *caps, const Dumpfmtctx *ctx) | static Sint32 DumpCaps(Stmwrbuf *sb, Bgpcapiter *caps, const Dumpfmtctx *ctx) | ||||||
| { | { | ||||||
| 	const char *s; | 	const char *s; | ||||||
| 	Bgpcap     *cap; | 	Bgpcap     *cap; | ||||||
| @@ -193,7 +193,7 @@ static Sint32 DumpCaps(Stmbuf *sb, Bgpcapiter *caps, const Dumpfmtctx *ctx) | |||||||
| 	return ncaps; | 	return ncaps; | ||||||
| } | } | ||||||
|  |  | ||||||
| static Judgement DumpAttributes(Stmbuf           *sb, | static Judgement DumpAttributes(Stmwrbuf         *sb, | ||||||
|                                 const Bgpattrseg *tpa, |                                 const Bgpattrseg *tpa, | ||||||
|                                 Bgpattrtab        table, |                                 Bgpattrtab        table, | ||||||
|                                 const Dumpfmtctx *ctx) |                                 const Dumpfmtctx *ctx) | ||||||
| @@ -402,7 +402,7 @@ static Judgement DumpAttributes(Stmbuf           *sb, | |||||||
| 	return OK; | 	return OK; | ||||||
| } | } | ||||||
|  |  | ||||||
| static void DumpMrtInfoTrailer(Stmbuf *sb, const Dumpfmtctx *ctx) | static void DumpMrtInfoTrailer(Stmwrbuf *sb, const Dumpfmtctx *ctx) | ||||||
| { | { | ||||||
| 	char buf[128]; | 	char buf[128]; | ||||||
|  |  | ||||||
| @@ -440,7 +440,7 @@ static void DumpMrtInfoTrailer(Stmbuf *sb, const Dumpfmtctx *ctx) | |||||||
| 	Bufio_Puts(sb, EOLN); | 	Bufio_Puts(sb, EOLN); | ||||||
| } | } | ||||||
|  |  | ||||||
| static void WarnCorrupted(Stmbuf *sb, const Dumpfmtctx *ctx) | static void WarnCorrupted(Stmwrbuf *sb, const Dumpfmtctx *ctx) | ||||||
| { | { | ||||||
| 	Bufio_Putc(sb, SEP_CHAR_BAD); | 	Bufio_Putc(sb, SEP_CHAR_BAD); | ||||||
| 	if (ctx->withColors) | 	if (ctx->withColors) | ||||||
| @@ -452,7 +452,7 @@ static void WarnCorrupted(Stmbuf *sb, const Dumpfmtctx *ctx) | |||||||
| } | } | ||||||
|  |  | ||||||
| static Sint32 DumpRoutesFast(char              marker, | static Sint32 DumpRoutesFast(char              marker, | ||||||
|                              Stmbuf           *sb, |                              Stmwrbuf           *sb, | ||||||
|                              Bgpmpiter        *prefixes, |                              Bgpmpiter        *prefixes, | ||||||
|                              const Bgpattrseg *tpa, |                              const Bgpattrseg *tpa, | ||||||
|                              Bgpattrtab        table, |                              Bgpattrtab        table, | ||||||
| @@ -519,7 +519,7 @@ static unsigned InsertRoute(Prefixtree **pr, Prefixtree *n) | |||||||
| } | } | ||||||
|  |  | ||||||
| static Sint32 DumpRouteWithPathId(char              marker, | static Sint32 DumpRouteWithPathId(char              marker, | ||||||
|                                   Stmbuf           *sb, |                                   Stmwrbuf         *sb, | ||||||
|                                   const Prefixtree *n, |                                   const Prefixtree *n, | ||||||
|                                   const Bgpattrseg *tpa, |                                   const Bgpattrseg *tpa, | ||||||
|                                   Bgpattrtab        table, |                                   Bgpattrtab        table, | ||||||
| @@ -558,7 +558,7 @@ static Sint32 DumpRouteWithPathId(char              marker, | |||||||
| } | } | ||||||
|  |  | ||||||
| static Sint32 DumpRoutes(char              marker, | static Sint32 DumpRoutes(char              marker, | ||||||
|                          Stmbuf           *sb, |                          Stmwrbuf         *sb, | ||||||
|                          Bgpmpiter        *prefixes, |                          Bgpmpiter        *prefixes, | ||||||
|                          const Bgpattrseg *tpa, |                          const Bgpattrseg *tpa, | ||||||
|                          Bgpattrtab        table, |                          Bgpattrtab        table, | ||||||
| @@ -614,7 +614,7 @@ static Sint32 DumpRoutes(char              marker, | |||||||
| 	return nprefixes; | 	return nprefixes; | ||||||
| } | } | ||||||
|  |  | ||||||
| static Judgement DumpBgp(Stmbuf        *sb, | static Judgement DumpBgp(Stmwrbuf      *sb, | ||||||
|                          BgpType        type, |                          BgpType        type, | ||||||
|                          const void    *data, |                          const void    *data, | ||||||
|                          size_t         nbytes, |                          size_t         nbytes, | ||||||
| @@ -720,7 +720,7 @@ static Sint64 Isolario_DumpMsg(const Bgphdr *hdr, | |||||||
|                                const StmOps *ops, |                                const StmOps *ops, | ||||||
|                                Bgpattrtab    table) |                                Bgpattrtab    table) | ||||||
| { | { | ||||||
| 	Stmbuf sb; | 	Stmwrbuf sb; | ||||||
|  |  | ||||||
| 	size_t nbytes = beswap16(hdr->len); | 	size_t nbytes = beswap16(hdr->len); | ||||||
| 	assert(nbytes >= BGP_HDRSIZ); | 	assert(nbytes >= BGP_HDRSIZ); | ||||||
| @@ -731,7 +731,7 @@ static Sint64 Isolario_DumpMsg(const Bgphdr *hdr, | |||||||
| 	ctx.isAsn32bit = BGP_ISASN32BIT(flags); | 	ctx.isAsn32bit = BGP_ISASN32BIT(flags); | ||||||
| 	ctx.isAddPath  = BGP_ISADDPATH(flags); | 	ctx.isAddPath  = BGP_ISADDPATH(flags); | ||||||
|  |  | ||||||
| 	Bufio_Init(&sb, streamp, ops); | 	Bufio_WrInit(&sb, streamp, ops); | ||||||
| 	DumpBgp(&sb, hdr->type, hdr + 1, nbytes, table, &ctx); | 	DumpBgp(&sb, hdr->type, hdr + 1, nbytes, table, &ctx); | ||||||
| 	return Bufio_Flush(&sb); | 	return Bufio_Flush(&sb); | ||||||
| } | } | ||||||
| @@ -742,7 +742,7 @@ static Sint64 Isolario_DumpMsgWc(const Bgphdr *hdr, | |||||||
|                                  const StmOps *ops, |                                  const StmOps *ops, | ||||||
|                                  Bgpattrtab    table) |                                  Bgpattrtab    table) | ||||||
| { | { | ||||||
| 	Stmbuf sb; | 	Stmwrbuf sb; | ||||||
|  |  | ||||||
| 	size_t nbytes = beswap16(hdr->len); | 	size_t nbytes = beswap16(hdr->len); | ||||||
| 	assert(nbytes >= BGP_HDRSIZ); | 	assert(nbytes >= BGP_HDRSIZ); | ||||||
| @@ -754,7 +754,7 @@ static Sint64 Isolario_DumpMsgWc(const Bgphdr *hdr, | |||||||
| 	ctx.isAddPath  = BGP_ISADDPATH(flags); | 	ctx.isAddPath  = BGP_ISADDPATH(flags); | ||||||
| 	ctx.withColors = TRUE; | 	ctx.withColors = TRUE; | ||||||
|  |  | ||||||
| 	Bufio_Init(&sb, streamp, ops); | 	Bufio_WrInit(&sb, streamp, ops); | ||||||
| 	DumpBgp(&sb, hdr->type, hdr + 1, nbytes, table, &ctx); | 	DumpBgp(&sb, hdr->type, hdr + 1, nbytes, table, &ctx); | ||||||
|  |  | ||||||
| 	return Bufio_Flush(&sb); | 	return Bufio_Flush(&sb); | ||||||
| @@ -770,12 +770,12 @@ static Sint64 Isolario_DumpRibv2(const Mrthdr       *hdr, | |||||||
| 	assert(hdr->type == MRT_TABLE_DUMPV2); | 	assert(hdr->type == MRT_TABLE_DUMPV2); | ||||||
| 	assert(TABLE_DUMPV2_ISRIB(hdr->subtype)); | 	assert(TABLE_DUMPV2_ISRIB(hdr->subtype)); | ||||||
|  |  | ||||||
| 	Stmbuf     sb; | 	Stmwrbuf   sb; | ||||||
| 	Dumpfmtctx ctx; | 	Dumpfmtctx ctx; | ||||||
| 	char       buf[APPFX_STRLEN + 1]; | 	char       buf[APPFX_STRLEN + 1]; | ||||||
| 	char      *ep; | 	char      *ep; | ||||||
|  |  | ||||||
| 	Bufio_Init(&sb, streamp, ops); | 	Bufio_WrInit(&sb, streamp, ops); | ||||||
|  |  | ||||||
| 	memset(&ctx, 0, sizeof(ctx)); | 	memset(&ctx, 0, sizeof(ctx)); | ||||||
| 	ctx.hasPeer      = TRUE; | 	ctx.hasPeer      = TRUE; | ||||||
| @@ -865,13 +865,13 @@ static Sint64 Isolario_DumpRib(const Mrthdr    *hdr, | |||||||
| { | { | ||||||
| 	assert(hdr->type == MRT_TABLE_DUMP); | 	assert(hdr->type == MRT_TABLE_DUMP); | ||||||
|  |  | ||||||
| 	Stmbuf     sb; | 	Stmwrbuf   sb; | ||||||
| 	Dumpfmtctx ctx; | 	Dumpfmtctx ctx; | ||||||
| 	RawPrefix  pfx; | 	RawPrefix  pfx; | ||||||
| 	char       buf[APPFX_STRLEN + 1]; | 	char       buf[APPFX_STRLEN + 1]; | ||||||
| 	char      *ep; | 	char      *ep; | ||||||
|  |  | ||||||
| 	Bufio_Init(&sb, streamp, ops); | 	Bufio_WrInit(&sb, streamp, ops); | ||||||
|  |  | ||||||
| 	memset(&ctx, 0, sizeof(ctx)); | 	memset(&ctx, 0, sizeof(ctx)); | ||||||
| 	ctx.hasPeer      = TRUE; | 	ctx.hasPeer      = TRUE; | ||||||
| @@ -930,14 +930,14 @@ static Sint64 Isolario_DumpBgp4mp(const Mrthdr    *hdr, | |||||||
| { | { | ||||||
| 	assert(hdr->type == MRT_BGP4MP || hdr->type == MRT_BGP4MP_ET); | 	assert(hdr->type == MRT_BGP4MP || hdr->type == MRT_BGP4MP_ET); | ||||||
|  |  | ||||||
| 	Stmbuf     sb; | 	Stmwrbuf   sb; | ||||||
| 	Dumpfmtctx ctx; | 	Dumpfmtctx ctx; | ||||||
| 	size_t     offset;  // offset to BGP4MP payload | 	size_t     offset;  // offset to BGP4MP payload | ||||||
| 	size_t     len; | 	size_t     len; | ||||||
|  |  | ||||||
| 	const Bgp4mphdr *bgp4mp = BGP4MP_HDR(hdr); | 	const Bgp4mphdr *bgp4mp = BGP4MP_HDR(hdr); | ||||||
|  |  | ||||||
| 	Bufio_Init(&sb, streamp, ops); | 	Bufio_WrInit(&sb, streamp, ops); | ||||||
|  |  | ||||||
| 	len = beswap32(hdr->len); | 	len = beswap32(hdr->len); | ||||||
|  |  | ||||||
| @@ -1058,12 +1058,12 @@ static Sint64 Isolario_DumpZebra(const Mrthdr   *hdr, | |||||||
| { | { | ||||||
| 	assert(hdr->type == MRT_BGP); | 	assert(hdr->type == MRT_BGP); | ||||||
|  |  | ||||||
| 	Stmbuf     sb; | 	Stmwrbuf   sb; | ||||||
| 	Dumpfmtctx ctx; | 	Dumpfmtctx ctx; | ||||||
|  |  | ||||||
| 	const Zebrahdr *zebra = ZEBRA_HDR(hdr); | 	const Zebrahdr *zebra = ZEBRA_HDR(hdr); | ||||||
|  |  | ||||||
| 	Bufio_Init(&sb, streamp, ops); | 	Bufio_WrInit(&sb, streamp, ops); | ||||||
|  |  | ||||||
| 	memset(&ctx, 0, sizeof(ctx)); | 	memset(&ctx, 0, sizeof(ctx)); | ||||||
| 	ctx.hasPeer         = TRUE; | 	ctx.hasPeer         = TRUE; | ||||||
|   | |||||||
							
								
								
									
										127
									
								
								lonetix/bufio.c
									
									
									
									
									
								
							
							
						
						
									
										127
									
								
								lonetix/bufio.c
									
									
									
									
									
								
							| @@ -18,36 +18,91 @@ | |||||||
| #include <stdio.h> | #include <stdio.h> | ||||||
| #include <string.h> | #include <string.h> | ||||||
|  |  | ||||||
| Sint64 Bufio_Flush(Stmbuf *sb) | static Judgement Bufio_FillRdBuf(Stmrdbuf *sb) | ||||||
|  | { | ||||||
|  | 	assert(sb->pos == sb->availIn); | ||||||
|  |  | ||||||
|  | 	Sint64 n = sb->ops->Read(sb->streamp, sb->buf, sizeof(sb->buf)); | ||||||
|  | 	if (n < 0) { | ||||||
|  | 		sb->hasError = TRUE; | ||||||
|  | 		return NG; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	sb->isEof = (n == 0); | ||||||
|  |  | ||||||
|  | 	sb->availIn  = n; | ||||||
|  | 	sb->totalIn += n; | ||||||
|  | 	sb->pos      = 0; | ||||||
|  | 	return OK; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | Sint64 Bufio_Read(Stmrdbuf *sb, void *buf, size_t nbytes) | ||||||
|  | { | ||||||
|  | 	assert(sb->ops->Read); | ||||||
|  |  | ||||||
|  | 	if (sb->hasError) | ||||||
|  | 		return -1;  // refuse unless somebody clears error | ||||||
|  |  | ||||||
|  | 	Uint8 *dest = (Uint8 *) buf; | ||||||
|  | 	while (nbytes > 0) { | ||||||
|  | 		if (sb->pos >= sb->availIn) { | ||||||
|  | 			if (Bufio_FillRdBuf(sb) != OK) { | ||||||
|  | 				if (dest > (Uint8 *) buf) | ||||||
|  | 					break; // delay error to next read | ||||||
|  |  | ||||||
|  | 				return -1; | ||||||
|  | 			} | ||||||
|  | 			if (sb->isEof) | ||||||
|  | 				break;  // end of file | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		size_t size = MIN((size_t) (sb->availIn - sb->pos), nbytes); | ||||||
|  |  | ||||||
|  | 		memcpy(dest, sb->buf + sb->pos, size); | ||||||
|  | 		sb->pos += size; | ||||||
|  |  | ||||||
|  | 		nbytes -= size; | ||||||
|  | 		dest   += size; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return dest - (Uint8 *) buf; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Bufio_Close(Stmrdbuf *sb) | ||||||
|  | { | ||||||
|  | 	if (sb->ops->Close) sb->ops->Close(sb->streamp); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | Sint64 Bufio_Flush(Stmwrbuf *sb) | ||||||
| { | { | ||||||
| 	assert(sb->ops->Write); | 	assert(sb->ops->Write); | ||||||
|  |  | ||||||
| 	while (sb->len > 0) { | 	while (sb->availOut > 0) { | ||||||
| 		Sint64 n = sb->ops->Write(sb->streamp, sb->buf, sb->len); | 		Sint64 n = sb->ops->Write(sb->streamp, sb->buf, sb->availOut); | ||||||
| 		if (n < 0) | 		if (n < 0) | ||||||
| 			return NG; | 			return -1; | ||||||
|  |  | ||||||
| 		memmove(sb->buf, sb->buf + n, sb->len - n); | 		memmove(sb->buf, sb->buf + n, sb->availOut - n); | ||||||
| 		sb->len   -= n; | 		sb->availOut -= n; | ||||||
| 		sb->total += n; | 		sb->totalOut += n; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return sb->total; | 	return sb->totalOut; | ||||||
| } | } | ||||||
|  |  | ||||||
| Sint64 _Bufio_Putsn(Stmbuf *sb, const char *s, size_t nbytes) | Sint64 _Bufio_Putsn(Stmwrbuf *sb, const char *s, size_t nbytes) | ||||||
| { | { | ||||||
| 	if (sb->len + nbytes > sizeof(sb->buf) && Bufio_Flush(sb) == -1) | 	if (sb->availOut + nbytes > sizeof(sb->buf) && Bufio_Flush(sb) == -1) | ||||||
| 		return -1; | 		return -1; | ||||||
| 	if (nbytes > sizeof(sb->buf)) | 	if (nbytes > sizeof(sb->buf)) | ||||||
| 		return sb->ops->Write(sb->streamp, sb, nbytes); | 		return sb->ops->Write(sb->streamp, sb, nbytes); | ||||||
|  |  | ||||||
| 	memcpy(sb->buf + sb->len, s, nbytes); | 	memcpy(sb->buf + sb->availOut, s, nbytes); | ||||||
| 	sb->len += nbytes; | 	sb->availOut += nbytes; | ||||||
| 	return nbytes; | 	return nbytes; | ||||||
| } | } | ||||||
|  |  | ||||||
| Sint64 Bufio_Putu(Stmbuf *sb, unsigned long long val) | Sint64 Bufio_Putu(Stmwrbuf *sb, unsigned long long val) | ||||||
| { | { | ||||||
| 	char buf[DIGS(val) + 1]; | 	char buf[DIGS(val) + 1]; | ||||||
|  |  | ||||||
| @@ -55,7 +110,7 @@ Sint64 Bufio_Putu(Stmbuf *sb, unsigned long long val) | |||||||
| 	return Bufio_Putsn(sb, buf, eptr - buf); | 	return Bufio_Putsn(sb, buf, eptr - buf); | ||||||
| } | } | ||||||
|  |  | ||||||
| Sint64 Bufio_Putx(Stmbuf *sb, unsigned long long val) | Sint64 Bufio_Putx(Stmwrbuf *sb, unsigned long long val) | ||||||
| { | { | ||||||
| 	char buf[XDIGS(val) + 1]; | 	char buf[XDIGS(val) + 1]; | ||||||
|  |  | ||||||
| @@ -63,7 +118,7 @@ Sint64 Bufio_Putx(Stmbuf *sb, unsigned long long val) | |||||||
| 	return Bufio_Putsn(sb, buf, eptr - buf); | 	return Bufio_Putsn(sb, buf, eptr - buf); | ||||||
| } | } | ||||||
|  |  | ||||||
| Sint64 Bufio_Puti(Stmbuf *sb, long long val) | Sint64 Bufio_Puti(Stmwrbuf *sb, long long val) | ||||||
| { | { | ||||||
| 	char buf[1 + DIGS(val) + 1]; | 	char buf[1 + DIGS(val) + 1]; | ||||||
|  |  | ||||||
| @@ -71,7 +126,7 @@ Sint64 Bufio_Puti(Stmbuf *sb, long long val) | |||||||
| 	return Bufio_Putsn(sb, buf, eptr - buf); | 	return Bufio_Putsn(sb, buf, eptr - buf); | ||||||
| } | } | ||||||
|  |  | ||||||
| Sint64 Bufio_Putf(Stmbuf *sb, double val) | Sint64 Bufio_Putf(Stmwrbuf *sb, double val) | ||||||
| { | { | ||||||
| 	char buf[DOUBLE_STRLEN + 1]; | 	char buf[DOUBLE_STRLEN + 1]; | ||||||
|  |  | ||||||
| @@ -79,7 +134,7 @@ Sint64 Bufio_Putf(Stmbuf *sb, double val) | |||||||
| 	return Bufio_Putsn(sb, buf, eptr - buf); | 	return Bufio_Putsn(sb, buf, eptr - buf); | ||||||
| } | } | ||||||
|  |  | ||||||
| Sint64 Bufio_Printf(Stmbuf *sb, const char *fmt, ...) | Sint64 Bufio_Printf(Stmwrbuf *sb, const char *fmt, ...) | ||||||
| { | { | ||||||
| 	va_list va; | 	va_list va; | ||||||
| 	Sint64  n; | 	Sint64  n; | ||||||
| @@ -91,7 +146,7 @@ Sint64 Bufio_Printf(Stmbuf *sb, const char *fmt, ...) | |||||||
| 	return n; | 	return n; | ||||||
| } | } | ||||||
|  |  | ||||||
| Sint64 Bufio_Vprintf(Stmbuf *sb, const char *fmt, va_list va) | Sint64 Bufio_Vprintf(Stmwrbuf *sb, const char *fmt, va_list va) | ||||||
| { | { | ||||||
| 	va_list vc; | 	va_list vc; | ||||||
| 	char   *buf; | 	char   *buf; | ||||||
| @@ -117,3 +172,39 @@ Sint64 Bufio_Vprintf(Stmbuf *sb, const char *fmt, va_list va) | |||||||
| 	return Bufio_Putsn(sb, buf, n2); | 	return Bufio_Putsn(sb, buf, n2); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | static Sint64 Bufio_StmRead(void *streamp, void *buf, size_t nbytes) | ||||||
|  | { | ||||||
|  | 	return Bufio_Read((Stmrdbuf *) streamp, buf, nbytes); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static Sint64 Bufio_StmTell(void *streamp) | ||||||
|  | { | ||||||
|  | 	Stmrdbuf *sb = (Stmrdbuf *) streamp; | ||||||
|  |  | ||||||
|  | 	return (sb->hasError) ? -1 : sb->totalIn + (Sint64) sb->pos; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void Bufio_StmClose(void *streamp) | ||||||
|  | { | ||||||
|  | 	Bufio_Close((Stmrdbuf *) streamp); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static const StmOps _Stm_RdBufOps = { | ||||||
|  | 	Bufio_StmRead, | ||||||
|  | 	NULL, | ||||||
|  | 	NULL, | ||||||
|  | 	Bufio_StmTell, | ||||||
|  | 	NULL, | ||||||
|  | 	Bufio_StmClose | ||||||
|  | }; | ||||||
|  | static const StmOps _Stm_NcRdBufOps = { | ||||||
|  | 	Bufio_StmRead, | ||||||
|  | 	NULL, | ||||||
|  | 	NULL, | ||||||
|  | 	Bufio_StmTell, | ||||||
|  | 	NULL, | ||||||
|  | 	NULL | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | const StmOps *const Stm_RdBufOps   = &_Stm_RdBufOps; | ||||||
|  | const StmOps *const Stm_NcRdBufOps = &_Stm_NcRdBufOps; | ||||||
|   | |||||||
| @@ -3,7 +3,7 @@ | |||||||
| /** | /** | ||||||
|  * \file      bufio.h |  * \file      bufio.h | ||||||
|  * |  * | ||||||
|  * Buffered stream writing utilities. |  * Buffered stream input/output utilities. | ||||||
|  * |  * | ||||||
|  * \copyright The DoubleFourteen Code Forge (C) All Rights Reserved |  * \copyright The DoubleFourteen Code Forge (C) All Rights Reserved | ||||||
|  * \author    Lorenzo Cogotti |  * \author    Lorenzo Cogotti | ||||||
| @@ -26,27 +26,81 @@ | |||||||
|  * and reduce calls to a stream's `Write()` operation. |  * and reduce calls to a stream's `Write()` operation. | ||||||
|  */ |  */ | ||||||
| typedef struct { | typedef struct { | ||||||
| 	Sint64        total;            ///< Total bytes flushed to output | 	Sint64        totalOut;         ///< Total bytes flushed to output | ||||||
| 	Uint32        len;              ///< Bytes currently buffered | 	Uint32        availOut;         ///< Bytes currently buffered | ||||||
| 	char          buf[STM_BUFSIZ];  ///< Output buffer | 	char          buf[STM_BUFSIZ];  ///< Output buffer | ||||||
| 	void         *streamp;          ///< Output stream pointer | 	void         *streamp;          ///< Output stream pointer | ||||||
| 	const StmOps *ops;              ///< Output stream operations | 	const StmOps *ops;              ///< Output stream operations | ||||||
| } Stmbuf; | } Stmwrbuf; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Buffered input helper structure. | ||||||
|  |  * | ||||||
|  |  * A small `struct` holding an input buffer. | ||||||
|  |  * Reading variant of the `Stmwrbuf` structure. | ||||||
|  |  * | ||||||
|  |  * In contrast with `Stmwrbuf`, this struct may be used | ||||||
|  |  * as a stream with `Stm_RdBufOps` and `Stm_NcRdBufOps`. | ||||||
|  |  */ | ||||||
|  | typedef struct { | ||||||
|  | 	Sint64        totalIn;          ///< Total bytes read from input. | ||||||
|  | 	Uint16        availIn;          ///< Bytes currently buffered. | ||||||
|  | 	Uint16        pos;              ///< Offset inside buffer to next byte to be returned. | ||||||
|  | 	Boolean8      hasError;         ///< Whether a read error was encountered | ||||||
|  | 	Boolean8      isEof;            ///< Whether last Read() from input returned 0 | ||||||
|  | 	char          buf[STM_BUFSIZ];  ///< Input buffer | ||||||
|  | 	void         *streamp;          ///< Input stream pointer | ||||||
|  | 	const StmOps *ops;              ///< Input stream operations | ||||||
|  | } Stmrdbuf; | ||||||
|  |  | ||||||
|  | /// Clear `Stmrdbuf` error flag, if set. | ||||||
|  | FORCE_INLINE void BUFIO_CLRERROR(Stmrdbuf *sb) | ||||||
|  | { | ||||||
|  | 	sb->hasError = FALSE; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /// Clear `Stmrdbuf` EOF flag, if set. | ||||||
|  | FORCE_INLINE void BUFIO_CLREOF(Stmrdbuf *sb) | ||||||
|  | { | ||||||
|  | 	sb->isEof = FALSE; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Initialize the buffer for reading from `streamp` using the | ||||||
|  |  * `ops` stream operations. | ||||||
|  |  * | ||||||
|  |  * \param [out] sb      Buffer to be initialized, must not be `NULL` | ||||||
|  |  * \param [in]  streamp Output stream pointer | ||||||
|  |  * \param [in]  ops     Output stream operations, must not be `NULL` | ||||||
|  |  *                      and must provide a `Read()` operation | ||||||
|  |  */ | ||||||
|  | FORCE_INLINE void Bufio_RdInit(Stmrdbuf *sb, void *streamp, const StmOps *ops) | ||||||
|  | { | ||||||
|  | 	sb->totalIn  = 0; | ||||||
|  | 	sb->availIn  = 0; | ||||||
|  | 	sb->hasError = FALSE; | ||||||
|  | 	sb->isEof    = FALSE; | ||||||
|  | 	sb->streamp  = streamp; | ||||||
|  | 	sb->ops      = ops; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | Sint64 Bufio_Read(Stmrdbuf *sb, void *buf, size_t nbytes); | ||||||
|  | void Bufio_Close(Stmrdbuf *sb); | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Flush the buffer to output stream. |  * Flush the buffer to output stream. | ||||||
|  * |  * | ||||||
|  * \return On success returns the **total** bytes written to output |  * \return On success returns the **total** bytes written to output | ||||||
|  *         stream since last call to `Bufio_Init()`, |  *         stream since last call to `Bufio_WrInit()`, | ||||||
|  *         that is the value stored inside `sb->total` field after the flush |  *         that is the value stored inside `sb->totalOut` field after the flush | ||||||
|  *         operations. Otherwise returns -1. |  *         operations. Otherwise returns -1. | ||||||
|  * |  * | ||||||
|  * \note Partial flushes are possible on partial writes, in which case |  * \note Partial flushes are possible on partial writes, in which case | ||||||
|  *       some amount of data will remain buffered in `sb` and may be |  *       some amount of data will remain buffered in `sb` and may be | ||||||
|  *       flushed later on; `sb->total` and `sb->len` will still be updated |  *       flushed later on; `sb->totalOut` and `sb->len` will still be updated | ||||||
|  *       consistently. |  *       consistently. | ||||||
|  */ |  */ | ||||||
| Sint64 Bufio_Flush(Stmbuf *sb); | Sint64 Bufio_Flush(Stmwrbuf *sb); | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Initialize the buffer for writing to `streamp` using the |  * Initialize the buffer for writing to `streamp` using the | ||||||
| @@ -57,12 +111,12 @@ Sint64 Bufio_Flush(Stmbuf *sb); | |||||||
|  * \param [in]  ops     Output stream operations, must not be `NULL` |  * \param [in]  ops     Output stream operations, must not be `NULL` | ||||||
|  *                      and must provide a `Write()` operation |  *                      and must provide a `Write()` operation | ||||||
|  */ |  */ | ||||||
| FORCE_INLINE void Bufio_Init(Stmbuf       *sb, | FORCE_INLINE void Bufio_WrInit(Stmwrbuf     *sb, | ||||||
|                                void         *streamp, |                                void         *streamp, | ||||||
|                                const StmOps *ops) |                                const StmOps *ops) | ||||||
| { | { | ||||||
| 	sb->total   = 0; | 	sb->totalOut = 0; | ||||||
| 	sb->len     = 0; | 	sb->availOut = 0; | ||||||
| 	sb->streamp  = streamp; | 	sb->streamp  = streamp; | ||||||
| 	sb->ops      = ops; | 	sb->ops      = ops; | ||||||
| } | } | ||||||
| @@ -77,16 +131,16 @@ FORCE_INLINE void Bufio_Init(Stmbuf       *sb, | |||||||
|  *         -1 on error. |  *         -1 on error. | ||||||
|  * |  * | ||||||
|  * @{ |  * @{ | ||||||
|  *   \fn Sint64 Bufio_Putu(Stmbuf *, unsigned long long) |  *   \fn Sint64 Bufio_Putu(Stmwrbuf *, unsigned long long) | ||||||
|  *   \fn Sint64 Bufio_Putx(Stmbuf *, unsigned long long) |  *   \fn Sint64 Bufio_Putx(Stmwrbuf *, unsigned long long) | ||||||
|  *   \fn Sint64 Bufio_Puti(Stmbuf *, long long) |  *   \fn Sint64 Bufio_Puti(Stmwrbuf *, long long) | ||||||
|  *   \fn Sint64 Bufio_Putf(Stmbuf *, double) |  *   \fn Sint64 Bufio_Putf(Stmwrbuf *, double) | ||||||
|  * @} |  * @} | ||||||
|  */ |  */ | ||||||
| Sint64 Bufio_Putu(Stmbuf *sb, unsigned long long val); | Sint64 Bufio_Putu(Stmwrbuf *sb, unsigned long long val); | ||||||
| Sint64 Bufio_Putx(Stmbuf *sb, unsigned long long val); | Sint64 Bufio_Putx(Stmwrbuf *sb, unsigned long long val); | ||||||
| Sint64 Bufio_Puti(Stmbuf *sb, long long val); | Sint64 Bufio_Puti(Stmwrbuf *sb, long long val); | ||||||
| Sint64 Bufio_Putf(Stmbuf *sb, double val); | Sint64 Bufio_Putf(Stmwrbuf *sb, double val); | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Write a single character to `sb`. |  * Write a single character to `sb`. | ||||||
| @@ -96,12 +150,12 @@ Sint64 Bufio_Putf(Stmbuf *sb, double val); | |||||||
|  * |  * | ||||||
|  * \note `\0` may be written and buffered like any other `char`. |  * \note `\0` may be written and buffered like any other `char`. | ||||||
|  */ |  */ | ||||||
| FORCE_INLINE Sint64 Bufio_Putc(Stmbuf *sb, char c) | FORCE_INLINE Sint64 Bufio_Putc(Stmwrbuf *sb, char c) | ||||||
| { | { | ||||||
| 	if (sb->len == sizeof(sb->buf) && Bufio_Flush(sb) == -1) | 	if (sb->availOut == sizeof(sb->buf) && Bufio_Flush(sb) == -1) | ||||||
| 		return -1; | 		return -1; | ||||||
|  |  | ||||||
| 	sb->buf[sb->len++] = c; | 	sb->buf[sb->availOut++] = c; | ||||||
| 	return 1; | 	return 1; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -117,7 +171,7 @@ FORCE_INLINE Sint64 Bufio_Putc(Stmbuf *sb, char c) | |||||||
|  * \return Number of bytes written to `sb` on success (equal to |  * \return Number of bytes written to `sb` on success (equal to | ||||||
|  *         `nbytes`), -1 on error. |  *         `nbytes`), -1 on error. | ||||||
|  */ |  */ | ||||||
| Sint64 _Bufio_Putsn(Stmbuf *, const char *, size_t); | Sint64 _Bufio_Putsn(Stmwrbuf *, const char *, size_t); | ||||||
|  |  | ||||||
| #ifdef __GNUC__ | #ifdef __GNUC__ | ||||||
| // Optimize to call Bufio_Putc() if 'nbytes' is statically known to be 1 | // Optimize to call Bufio_Putc() if 'nbytes' is statically known to be 1 | ||||||
| @@ -137,7 +191,7 @@ Sint64 _Bufio_Putsn(Stmbuf *, const char *, size_t); | |||||||
|  * \return Number of bytes written to `sb` on success (equal |  * \return Number of bytes written to `sb` on success (equal | ||||||
|  *         to string length), -1 on error. |  *         to string length), -1 on error. | ||||||
|  */ |  */ | ||||||
| FORCE_INLINE Sint64 Bufio_Puts(Stmbuf *sb, const char *s) | FORCE_INLINE Sint64 Bufio_Puts(Stmwrbuf *sb, const char *s) | ||||||
| { | { | ||||||
| 	EXTERNC size_t strlen(const char *); // avoids #include | 	EXTERNC size_t strlen(const char *); // avoids #include | ||||||
|  |  | ||||||
| @@ -152,11 +206,14 @@ FORCE_INLINE Sint64 Bufio_Puts(Stmbuf *sb, const char *s) | |||||||
|  * \return Number of bytes written to `sb` on success, -1 on error. |  * \return Number of bytes written to `sb` on success, -1 on error. | ||||||
|  * |  * | ||||||
|  * @{ |  * @{ | ||||||
|  *   \fn Sint64 Bufio_Printf(Stmbuf *, const char *, ...) |  *   \fn Sint64 Bufio_Printf(Stmwrbuf *, const char *, ...) | ||||||
|  *   \fn Sint64 Bufio_Vprintf(Stmbuf *, const char *, va_list) |  *   \fn Sint64 Bufio_Vprintf(Stmwrbuf *, const char *, va_list) | ||||||
|  * @} |  * @} | ||||||
|  */ |  */ | ||||||
| CHECK_PRINTF(2, 3) Sint64 Bufio_Printf(Stmbuf *, const char *, ...); | CHECK_PRINTF(2, 3) Sint64 Bufio_Printf(Stmwrbuf *, const char *, ...); | ||||||
| CHECK_PRINTF(2, 0) Sint64 Bufio_Vprintf(Stmbuf *, const char *, va_list); | CHECK_PRINTF(2, 0) Sint64 Bufio_Vprintf(Stmwrbuf *, const char *, va_list); | ||||||
|  |  | ||||||
|  | extern const StmOps *const Stm_RdBufOps; | ||||||
|  | extern const StmOps *const Stm_NcRdBufOps; | ||||||
|  |  | ||||||
| #endif | #endif | ||||||
|   | |||||||
| @@ -316,8 +316,10 @@ static void Bgpgrep_OpenMrtDump(const char *filename) | |||||||
| 	S.filename = filename; | 	S.filename = filename; | ||||||
| 	if (strcmp(S.filename, "-") == 0) { | 	if (strcmp(S.filename, "-") == 0) { | ||||||
| 		// Direct read from stdin - assume uncompressed. | 		// Direct read from stdin - assume uncompressed. | ||||||
| 		S.inf    = STM_FILDES(CON_FILDES(STDIN)); | 		Bufio_RdInit(&S.infBuf, STM_FILDES(CON_FILDES(STDIN)), Stm_NcFildesOps); | ||||||
| 		S.infOps = Stm_NcFildesOps; |  | ||||||
|  | 		S.inf    = &S.infBuf; | ||||||
|  | 		S.infOps = Stm_NcRdBufOps; | ||||||
| 		return; | 		return; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -352,8 +354,10 @@ static void Bgpgrep_OpenMrtDump(const char *filename) | |||||||
|  |  | ||||||
| 	} else { | 	} else { | ||||||
| 		// Assume uncompressed file | 		// Assume uncompressed file | ||||||
| 		S.inf    = STM_FILDES(fh); | 		Bufio_RdInit(&S.infBuf, STM_FILDES(fh), Stm_FildesOps); | ||||||
| 		S.infOps = Stm_FildesOps; |  | ||||||
|  | 		S.inf    = &S.infBuf; | ||||||
|  | 		S.infOps = Stm_RdBufOps; | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -16,6 +16,7 @@ | |||||||
| #include "bgp/mrt.h" | #include "bgp/mrt.h" | ||||||
| #include "bgp/patricia.h" | #include "bgp/patricia.h" | ||||||
| #include "bgp/vm.h" | #include "bgp/vm.h" | ||||||
|  | #include "bufio.h" | ||||||
|  |  | ||||||
| #include <setjmp.h> | #include <setjmp.h> | ||||||
|  |  | ||||||
| @@ -113,6 +114,7 @@ struct BgpgrepState { | |||||||
| 	const char   *filename;  // current file being processed | 	const char   *filename;  // current file being processed | ||||||
| 	void         *inf;       // NOTE: may be NULL even in a file is open | 	void         *inf;       // NOTE: may be NULL even in a file is open | ||||||
| 	const StmOps *infOps;    // if NULL no file is open | 	const StmOps *infOps;    // if NULL no file is open | ||||||
|  | 	Stmrdbuf      infBuf;    // input buffer in case we're reading from uncompressed source | ||||||
|  |  | ||||||
| 	// Miscellaneous global flags and data | 	// Miscellaneous global flags and data | ||||||
| 	Boolean8  noColor; | 	Boolean8  noColor; | ||||||
|   | |||||||
| @@ -226,8 +226,10 @@ static void Peerindex_OpenMrtDump(const char *filename) | |||||||
| 	S.filename = filename; | 	S.filename = filename; | ||||||
| 	if (strcmp(S.filename, "-") == 0) { | 	if (strcmp(S.filename, "-") == 0) { | ||||||
| 		// Direct read from stdin, assume uncompressed | 		// Direct read from stdin, assume uncompressed | ||||||
| 		S.inf    = STM_FILDES(CON_FILDES(STDIN)); | 		Bufio_RdInit(&S.infBuf, STM_FILDES(CON_FILDES(STDIN)), Stm_NcFildesOps); | ||||||
| 		S.infOps = Stm_NcFildesOps; |  | ||||||
|  | 		S.inf    = &S.infBuf; | ||||||
|  | 		S.infOps = Stm_NcRdBufOps; | ||||||
| 		return; | 		return; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -262,8 +264,10 @@ static void Peerindex_OpenMrtDump(const char *filename) | |||||||
|  |  | ||||||
| 	} else { | 	} else { | ||||||
| 		// Assume uncompressed file | 		// Assume uncompressed file | ||||||
| 		S.inf    = STM_FILDES(fh); | 		Bufio_RdInit(&S.infBuf, STM_FILDES(fh), Stm_FildesOps); | ||||||
| 		S.infOps = Stm_FildesOps; |  | ||||||
|  | 		S.inf    = &S.infBuf; | ||||||
|  | 		S.infOps = Stm_RdBufOps; | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -288,7 +292,7 @@ static void Peerindex_MarkPeerRefs(void) | |||||||
| static void Peerindex_FlushPeerIndexTable(void) | static void Peerindex_FlushPeerIndexTable(void) | ||||||
| { | { | ||||||
| 	char buf[IPV6_STRLEN + 1]; | 	char buf[IPV6_STRLEN + 1]; | ||||||
| 	Stmbuf sb; | 	Stmwrbuf sb; | ||||||
|  |  | ||||||
| 	Ipadr adr; | 	Ipadr adr; | ||||||
|  |  | ||||||
| @@ -300,7 +304,7 @@ static void Peerindex_FlushPeerIndexTable(void) | |||||||
|  |  | ||||||
| 	Uint16 idx = 0; | 	Uint16 idx = 0; | ||||||
|  |  | ||||||
| 	Bufio_Init(&sb, S.outf, S.outfOps); | 	Bufio_WrInit(&sb, S.outf, S.outfOps); | ||||||
|  |  | ||||||
| 	Bgp_StartMrtPeersv2(&it, &S.peerIndex); | 	Bgp_StartMrtPeersv2(&it, &S.peerIndex); | ||||||
| 	while ((peer = Bgp_NextMrtPeerv2(&it)) != NULL) { | 	while ((peer = Bgp_NextMrtPeerv2(&it)) != NULL) { | ||||||
|   | |||||||
| @@ -13,6 +13,7 @@ | |||||||
| #define DF_PEERINDEX_LOCAL_H_ | #define DF_PEERINDEX_LOCAL_H_ | ||||||
|  |  | ||||||
| #include "bgp/mrt.h" | #include "bgp/mrt.h" | ||||||
|  | #include "bufio.h" | ||||||
|  |  | ||||||
| #include <setjmp.h> | #include <setjmp.h> | ||||||
|  |  | ||||||
| @@ -39,6 +40,7 @@ typedef struct { | |||||||
| 	const char   *filename; | 	const char   *filename; | ||||||
| 	void         *inf; | 	void         *inf; | ||||||
| 	const StmOps *infOps; | 	const StmOps *infOps; | ||||||
|  | 	Stmrdbuf      infBuf; | ||||||
|  |  | ||||||
| 	// Miscellaneous global flags and data | 	// Miscellaneous global flags and data | ||||||
| 	Boolean8    hasPeerIndex; | 	Boolean8    hasPeerIndex; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user