From 4662e5286aa259e158f314157d0d8f2ad213a321 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 18 Mar 2025 16:20:42 +0100 Subject: membuff: Rename functions to have membuf_ prefix The double 'f' is not necessary and is a bit annoying as elsewhere in U-Boot we use 'buf'. Rename all the functions before it is used more widely. Signed-off-by: Simon Glass --- boot/bootmeth_extlinux.c | 6 +-- common/console.c | 32 ++++++++-------- drivers/serial/sandbox.c | 10 ++--- drivers/usb/emul/sandbox_keyb.c | 6 +-- include/membuff.h | 82 ++++++++++++++++++++--------------------- lib/membuff.c | 66 ++++++++++++++++----------------- 6 files changed, 101 insertions(+), 101 deletions(-) diff --git a/boot/bootmeth_extlinux.c b/boot/bootmeth_extlinux.c index 17c6cebd2f4..f3a81715080 100644 --- a/boot/bootmeth_extlinux.c +++ b/boot/bootmeth_extlinux.c @@ -114,9 +114,9 @@ static int extlinux_fill_info(struct bootflow *bflow) int len; log_debug("parsing bflow file size %x\n", bflow->size); - membuff_init(&mb, bflow->buf, bflow->size); - membuff_putraw(&mb, bflow->size, true, &data); - while (len = membuff_readline(&mb, line, sizeof(line) - 1, ' ', true), len) { + membuf_init(&mb, bflow->buf, bflow->size); + membuf_putraw(&mb, bflow->size, true, &data); + while (len = membuf_readline(&mb, line, sizeof(line) - 1, ' ', true), len) { char *tok, *p = line; tok = strsep(&p, " "); diff --git a/common/console.c b/common/console.c index 26812b2ccbe..ffd0cc1807d 100644 --- a/common/console.c +++ b/common/console.c @@ -101,7 +101,7 @@ static void console_record_putc(const char c) if (!(gd->flags & GD_FLG_RECORD)) return; if (gd->console_out.start && - !membuff_putbyte((struct membuff *)&gd->console_out, c)) + !membuf_putbyte((struct membuff *)&gd->console_out, c)) gd->flags |= GD_FLG_RECORD_OVF; } @@ -112,7 +112,7 @@ static void console_record_puts(const char *s) if (gd->console_out.start) { int len = strlen(s); - if (membuff_put((struct membuff *)&gd->console_out, s, len) != + if (membuf_put((struct membuff *)&gd->console_out, s, len) != len) gd->flags |= GD_FLG_RECORD_OVF; } @@ -125,7 +125,7 @@ static int console_record_getc(void) if (!gd->console_in.start) return -1; - return membuff_getbyte((struct membuff *)&gd->console_in); + return membuf_getbyte((struct membuff *)&gd->console_in); } static int console_record_tstc(void) @@ -133,7 +133,7 @@ static int console_record_tstc(void) if (!(gd->flags & GD_FLG_RECORD)) return 0; if (gd->console_in.start) { - if (membuff_peekbyte((struct membuff *)&gd->console_in) != -1) + if (membuf_peekbyte((struct membuff *)&gd->console_in) != -1) return 1; } return 0; @@ -810,14 +810,14 @@ int console_record_init(void) { int ret; - ret = membuff_new((struct membuff *)&gd->console_out, - gd->flags & GD_FLG_RELOC ? - CONFIG_CONSOLE_RECORD_OUT_SIZE : - CONFIG_CONSOLE_RECORD_OUT_SIZE_F); + ret = membuf_new((struct membuff *)&gd->console_out, + gd->flags & GD_FLG_RELOC ? + CONFIG_CONSOLE_RECORD_OUT_SIZE : + CONFIG_CONSOLE_RECORD_OUT_SIZE_F); if (ret) return ret; - ret = membuff_new((struct membuff *)&gd->console_in, - CONFIG_CONSOLE_RECORD_IN_SIZE); + ret = membuf_new((struct membuff *)&gd->console_in, + CONFIG_CONSOLE_RECORD_IN_SIZE); /* Start recording from the beginning */ gd->flags |= GD_FLG_RECORD; @@ -827,8 +827,8 @@ int console_record_init(void) void console_record_reset(void) { - membuff_purge((struct membuff *)&gd->console_out); - membuff_purge((struct membuff *)&gd->console_in); + membuf_purge((struct membuff *)&gd->console_out); + membuf_purge((struct membuff *)&gd->console_in); gd->flags &= ~GD_FLG_RECORD_OVF; } @@ -847,23 +847,23 @@ int console_record_readline(char *str, int maxlen) if (console_record_isempty()) return -ENOENT; - return membuff_readline((struct membuff *)&gd->console_out, str, + return membuf_readline((struct membuff *)&gd->console_out, str, maxlen, '\0', false); } int console_record_avail(void) { - return membuff_avail((struct membuff *)&gd->console_out); + return membuf_avail((struct membuff *)&gd->console_out); } bool console_record_isempty(void) { - return membuff_isempty((struct membuff *)&gd->console_out); + return membuf_isempty((struct membuff *)&gd->console_out); } int console_in_puts(const char *str) { - return membuff_put((struct membuff *)&gd->console_in, str, strlen(str)); + return membuf_put((struct membuff *)&gd->console_in, str, strlen(str)); } #endif diff --git a/drivers/serial/sandbox.c b/drivers/serial/sandbox.c index 77a1558db68..cc0491bc3c8 100644 --- a/drivers/serial/sandbox.c +++ b/drivers/serial/sandbox.c @@ -63,7 +63,7 @@ static int sandbox_serial_probe(struct udevice *dev) if (state->term_raw != STATE_TERM_RAW) disable_ctrlc(1); - membuff_init(&priv->buf, priv->serial_buf, sizeof(priv->serial_buf)); + membuf_init(&priv->buf, priv->serial_buf, sizeof(priv->serial_buf)); return 0; } @@ -138,15 +138,15 @@ static int sandbox_serial_pending(struct udevice *dev, bool input) return 0; os_usleep(100); - avail = membuff_putraw(&priv->buf, 100, false, &data); + avail = membuf_putraw(&priv->buf, 100, false, &data); if (!avail) return 1; /* buffer full */ count = os_read(0, data, avail); if (count > 0) - membuff_putraw(&priv->buf, count, true, &data); + membuf_putraw(&priv->buf, count, true, &data); - return membuff_avail(&priv->buf); + return membuf_avail(&priv->buf); } static int sandbox_serial_getc(struct udevice *dev) @@ -156,7 +156,7 @@ static int sandbox_serial_getc(struct udevice *dev) if (!sandbox_serial_pending(dev, true)) return -EAGAIN; /* buffer empty */ - return membuff_getbyte(&priv->buf); + return membuf_getbyte(&priv->buf); } #ifdef CONFIG_DEBUG_UART_SANDBOX diff --git a/drivers/usb/emul/sandbox_keyb.c b/drivers/usb/emul/sandbox_keyb.c index db769883ba3..756fef64a36 100644 --- a/drivers/usb/emul/sandbox_keyb.c +++ b/drivers/usb/emul/sandbox_keyb.c @@ -167,7 +167,7 @@ int sandbox_usb_keyb_add_string(struct udevice *dev, struct sandbox_keyb_priv *priv = dev_get_priv(dev); int ret; - ret = membuff_put(&priv->in, scancode, USB_KBD_BOOT_REPORT_SIZE); + ret = membuf_put(&priv->in, scancode, USB_KBD_BOOT_REPORT_SIZE); if (ret != USB_KBD_BOOT_REPORT_SIZE) return -ENOSPC; @@ -194,7 +194,7 @@ static int sandbox_keyb_interrupt(struct udevice *dev, struct usb_device *udev, if (length < USB_KBD_BOOT_REPORT_SIZE) return 0; - membuff_get(&priv->in, buffer, USB_KBD_BOOT_REPORT_SIZE); + membuf_get(&priv->in, buffer, USB_KBD_BOOT_REPORT_SIZE); return 0; } @@ -220,7 +220,7 @@ static int sandbox_keyb_probe(struct udevice *dev) struct sandbox_keyb_priv *priv = dev_get_priv(dev); /* Provide an 80 character keyboard buffer */ - return membuff_new(&priv->in, 80 * USB_KBD_BOOT_REPORT_SIZE); + return membuf_new(&priv->in, 80 * USB_KBD_BOOT_REPORT_SIZE); } static const struct dm_usb_ops sandbox_usb_keyb_ops = { diff --git a/include/membuff.h b/include/membuff.h index 4eba626ce1c..c7370e1c072 100644 --- a/include/membuff.h +++ b/include/membuff.h @@ -6,8 +6,8 @@ * Copyright (c) 1992 Simon Glass */ -#ifndef _MEMBUFF_H -#define _MEMBUFF_H +#ifndef _membuf_H +#define _membuf_H /** * @struct membuff: holds the state of a membuff - it is used for input and @@ -37,16 +37,16 @@ struct membuff { }; /** - * membuff_purge() - reset a membuff to the empty state + * membuf_purge() - reset a membuff to the empty state * * Initialise head and tail pointers so that the membuff becomes empty. * * @mb: membuff to purge */ -void membuff_purge(struct membuff *mb); +void membuf_purge(struct membuff *mb); /** - * membuff_putraw() - find out where bytes can be written + * membuf_putraw() - find out where bytes can be written * * Work out where in the membuff some data could be written. Return a pointer * to the address and the number of bytes which can be written there. If @@ -64,10 +64,10 @@ void membuff_purge(struct membuff *mb); * @data: the address data can be written to * Return: number of bytes which can be written */ -int membuff_putraw(struct membuff *mb, int maxlen, bool update, char **data); +int membuf_putraw(struct membuff *mb, int maxlen, bool update, char **data); /** - * membuff_getraw() - find and return a pointer to available bytes + * membuf_getraw() - find and return a pointer to available bytes * * Returns a pointer to any valid input data in the given membuff and * optionally marks it as read. Note that not all input data may not be @@ -82,37 +82,37 @@ int membuff_putraw(struct membuff *mb, int maxlen, bool update, char **data); * @data: returns address of data in input membuff * Return: the number of bytes available at *@data */ -int membuff_getraw(struct membuff *mb, int maxlen, bool update, char **data); +int membuf_getraw(struct membuff *mb, int maxlen, bool update, char **data); /** - * membuff_putbyte() - Writes a byte to a membuff + * membuf_putbyte() - Writes a byte to a membuff * * @mb: membuff to adjust * @ch: byte to write * Return: true on success, false if membuff is full */ -bool membuff_putbyte(struct membuff *mb, int ch); +bool membuf_putbyte(struct membuff *mb, int ch); /** * @mb: membuff to adjust - * membuff_getbyte() - Read a byte from the membuff + * membuf_getbyte() - Read a byte from the membuff * Return: the byte read, or -1 if the membuff is empty */ -int membuff_getbyte(struct membuff *mb); +int membuf_getbyte(struct membuff *mb); /** - * membuff_peekbyte() - check the next available byte + * membuf_peekbyte() - check the next available byte * - * Return the next byte which membuff_getbyte() would return, without + * Return the next byte which membuf_getbyte() would return, without * removing it from the membuff. * * @mb: membuff to adjust * Return: the byte peeked, or -1 if the membuff is empty */ -int membuff_peekbyte(struct membuff *mb); +int membuf_peekbyte(struct membuff *mb); /** - * membuff_get() - get data from a membuff + * membuf_get() - get data from a membuff * * Copies any available data (up to @maxlen bytes) to @buff and removes it * from the membuff. @@ -122,10 +122,10 @@ int membuff_peekbyte(struct membuff *mb); * @maxlen: maximum number of bytes to read * Return: the number of bytes read */ -int membuff_get(struct membuff *mb, char *buff, int maxlen); +int membuf_get(struct membuff *mb, char *buff, int maxlen); /** - * membuff_put() - write data to a membuff + * membuf_put() - write data to a membuff * * Writes some data to a membuff. Returns the number of bytes added. If this * is less than @lnehgt, then the membuff got full @@ -135,36 +135,36 @@ int membuff_get(struct membuff *mb, char *buff, int maxlen); * @length: number of bytes to write from 'data' * Return: the number of bytes added */ -int membuff_put(struct membuff *mb, const char *buff, int length); +int membuf_put(struct membuff *mb, const char *buff, int length); /** - * membuff_isempty() - check if a membuff is empty + * membuf_isempty() - check if a membuff is empty * * @mb: membuff to check * Return: true if empty, else false */ -bool membuff_isempty(struct membuff *mb); +bool membuf_isempty(struct membuff *mb); /** - * membuff_avail() - check available data in a membuff + * membuf_avail() - check available data in a membuff * * @mb: membuff to check * Return: number of bytes of data available */ -int membuff_avail(struct membuff *mb); +int membuf_avail(struct membuff *mb); /** - * membuff_size() - get the size of a membuff + * membuf_size() - get the size of a membuff * * Note that a membuff can only old data up to one byte less than its size. * * @mb: membuff to check * Return: total size */ -int membuff_size(struct membuff *mb); +int membuf_size(struct membuff *mb); /** - * membuff_makecontig() - adjust all membuff data to be contiguous + * membuf_makecontig() - adjust all membuff data to be contiguous * * This places all data in a membuff into a single contiguous lump, if * possible @@ -172,18 +172,18 @@ int membuff_size(struct membuff *mb); * @mb: membuff to adjust * Return: true on success */ -bool membuff_makecontig(struct membuff *mb); +bool membuf_makecontig(struct membuff *mb); /** - * membuff_free() - find the number of bytes that can be written to a membuff + * membuf_free() - find the number of bytes that can be written to a membuff * * @mb: membuff to check * Return: returns the number of bytes free in a membuff */ -int membuff_free(struct membuff *mb); +int membuf_free(struct membuff *mb); /** - * membuff_readline() - read a line of text from a membuff + * membuf_readline() - read a line of text from a membuff * * Reads a line of text of up to 'maxlen' characters from a membuff and puts * it in @str. Any character less than @minch is assumed to be the end of @@ -196,10 +196,10 @@ int membuff_free(struct membuff *mb); * Return: number of bytes read (including terminator) if a line has been * read, 0 if nothing was there or line didn't fit when must_fit is set */ -int membuff_readline(struct membuff *mb, char *str, int maxlen, int minch, bool must_fit); +int membuf_readline(struct membuff *mb, char *str, int maxlen, int minch, bool must_fit); /** - * membuff_extend_by() - expand a membuff + * membuf_extend_by() - expand a membuff * * Extends a membuff by the given number of bytes * @@ -209,38 +209,38 @@ int membuff_readline(struct membuff *mb, char *str, int maxlen, int minch, bool * Return: 0 if the expand succeeded, -ENOMEM if not enough memory, -E2BIG * if the the size would exceed @max */ -int membuff_extend_by(struct membuff *mb, int by, int max); +int membuf_extend_by(struct membuff *mb, int by, int max); /** - * membuff_init() - set up a new membuff using an existing membuff + * membuf_init() - set up a new membuff using an existing membuff * * @mb: membuff to set up * @buff: Address of buffer * @size: Size of buffer */ -void membuff_init(struct membuff *mb, char *buff, int size); +void membuf_init(struct membuff *mb, char *buff, int size); /** - * membuff_uninit() - clear a membuff so it can no longer be used + * membuf_uninit() - clear a membuff so it can no longer be used * * @mb: membuff to uninit */ -void membuff_uninit(struct membuff *mb); +void membuf_uninit(struct membuff *mb); /** - * membuff_new() - create a new membuff + * membuf_new() - create a new membuff * * @mb: membuff to init * @size: size of membuff to create * Return: 0 if OK, -ENOMEM if out of memory */ -int membuff_new(struct membuff *mb, int size); +int membuf_new(struct membuff *mb, int size); /** - * membuff_dispose() - free memory allocated to a membuff and uninit it + * membuf_dispose() - free memory allocated to a membuff and uninit it * * @mb: membuff to dispose */ -void membuff_dispose(struct membuff *mb); +void membuf_dispose(struct membuff *mb); #endif diff --git a/lib/membuff.c b/lib/membuff.c index b242a38ff1c..435d12b8a3c 100644 --- a/lib/membuff.c +++ b/lib/membuff.c @@ -11,15 +11,15 @@ #include #include "membuff.h" -void membuff_purge(struct membuff *mb) +void membuf_purge(struct membuff *mb) { /* set mb->head and mb->tail so the buffers look empty */ mb->head = mb->start; mb->tail = mb->start; } -static int membuff_putrawflex(struct membuff *mb, int maxlen, bool update, - char ***data, int *offsetp) +static int membuf_putrawflex(struct membuff *mb, int maxlen, bool update, + char ***data, int *offsetp) { int len; @@ -72,30 +72,30 @@ static int membuff_putrawflex(struct membuff *mb, int maxlen, bool update, return len; } -int membuff_putraw(struct membuff *mb, int maxlen, bool update, char **data) +int membuf_putraw(struct membuff *mb, int maxlen, bool update, char **data) { char **datap; int offset; int size; - size = membuff_putrawflex(mb, maxlen, update, &datap, &offset); + size = membuf_putrawflex(mb, maxlen, update, &datap, &offset); *data = *datap + offset; return size; } -bool membuff_putbyte(struct membuff *mb, int ch) +bool membuf_putbyte(struct membuff *mb, int ch) { char *data; - if (membuff_putraw(mb, 1, true, &data) != 1) + if (membuf_putraw(mb, 1, true, &data) != 1) return false; *data = ch; return true; } -int membuff_getraw(struct membuff *mb, int maxlen, bool update, char **data) +int membuf_getraw(struct membuff *mb, int maxlen, bool update, char **data) { int len; @@ -146,21 +146,21 @@ int membuff_getraw(struct membuff *mb, int maxlen, bool update, char **data) return len; } -int membuff_getbyte(struct membuff *mb) +int membuf_getbyte(struct membuff *mb) { char *data = 0; - return membuff_getraw(mb, 1, true, &data) != 1 ? -1 : *(uint8_t *)data; + return membuf_getraw(mb, 1, true, &data) != 1 ? -1 : *(uint8_t *)data; } -int membuff_peekbyte(struct membuff *mb) +int membuf_peekbyte(struct membuff *mb) { char *data = 0; - return membuff_getraw(mb, 1, false, &data) != 1 ? -1 : *(uint8_t *)data; + return membuf_getraw(mb, 1, false, &data) != 1 ? -1 : *(uint8_t *)data; } -int membuff_get(struct membuff *mb, char *buff, int maxlen) +int membuf_get(struct membuff *mb, char *buff, int maxlen) { char *data = 0, *buffptr = buff; int len = 1, i; @@ -171,7 +171,7 @@ int membuff_get(struct membuff *mb, char *buff, int maxlen) */ for (i = 0; len && i < 2; i++) { /* get a pointer to the data available */ - len = membuff_getraw(mb, maxlen, true, &data); + len = membuf_getraw(mb, maxlen, true, &data); /* copy it into the buffer */ memcpy(buffptr, data, len); @@ -183,14 +183,14 @@ int membuff_get(struct membuff *mb, char *buff, int maxlen) return buffptr - buff; } -int membuff_put(struct membuff *mb, const char *buff, int length) +int membuf_put(struct membuff *mb, const char *buff, int length) { char *data; int towrite, i, written; for (i = written = 0; i < 2; i++) { /* ask where some data can be written */ - towrite = membuff_putraw(mb, length, true, &data); + towrite = membuf_putraw(mb, length, true, &data); /* and write it, updating the bytes length */ memcpy(data, buff, towrite); @@ -203,12 +203,12 @@ int membuff_put(struct membuff *mb, const char *buff, int length) return written; } -bool membuff_isempty(struct membuff *mb) +bool membuf_isempty(struct membuff *mb) { return mb->head == mb->tail; } -int membuff_avail(struct membuff *mb) +int membuf_avail(struct membuff *mb) { struct membuff copy; int i, avail; @@ -219,18 +219,18 @@ int membuff_avail(struct membuff *mb) /* now read everything out of the copied buffer */ for (i = avail = 0; i < 2; i++) - avail += membuff_getraw(©, -1, true, &data); + avail += membuf_getraw(©, -1, true, &data); /* and return how much we read */ return avail; } -int membuff_size(struct membuff *mb) +int membuf_size(struct membuff *mb) { return mb->end - mb->start; } -bool membuff_makecontig(struct membuff *mb) +bool membuf_makecontig(struct membuff *mb) { int topsize, botsize; @@ -281,13 +281,13 @@ bool membuff_makecontig(struct membuff *mb) return true; } -int membuff_free(struct membuff *mb) +int membuf_free(struct membuff *mb) { return mb->end == mb->start ? 0 : - (mb->end - mb->start) - 1 - membuff_avail(mb); + (mb->end - mb->start) - 1 - membuf_avail(mb); } -int membuff_readline(struct membuff *mb, char *str, int maxlen, int minch, bool must_fit) +int membuf_readline(struct membuff *mb, char *str, int maxlen, int minch, bool must_fit) { int len; /* number of bytes read (!= string length) */ char *s, *end; @@ -322,7 +322,7 @@ int membuff_readline(struct membuff *mb, char *str, int maxlen, int minch, bool return len; } -int membuff_extend_by(struct membuff *mb, int by, int max) +int membuf_extend_by(struct membuff *mb, int by, int max) { int oldhead, oldtail; int size, orig; @@ -358,32 +358,32 @@ int membuff_extend_by(struct membuff *mb, int by, int max) return 0; } -void membuff_init(struct membuff *mb, char *buff, int size) +void membuf_init(struct membuff *mb, char *buff, int size) { mb->start = buff; mb->end = mb->start + size; - membuff_purge(mb); + membuf_purge(mb); } -int membuff_new(struct membuff *mb, int size) +int membuf_new(struct membuff *mb, int size) { mb->start = malloc(size); if (!mb->start) return -ENOMEM; - membuff_init(mb, mb->start, size); + membuf_init(mb, mb->start, size); return 0; } -void membuff_uninit(struct membuff *mb) +void membuf_uninit(struct membuff *mb) { mb->end = NULL; mb->start = NULL; - membuff_purge(mb); + membuf_purge(mb); } -void membuff_dispose(struct membuff *mb) +void membuf_dispose(struct membuff *mb) { free(&mb->start); - membuff_uninit(mb); + membuf_uninit(mb); } -- cgit v1.2.3 From 9ca1789ff099a364c6e16dcb6f6ad2e8677f32f1 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 18 Mar 2025 16:20:43 +0100 Subject: membuff: Rename the files to membuf Rename the C and header files to use the membuf basename, to match the functions. Add a MAINTAINERS entry while we are here. Signed-off-by: Simon Glass --- MAINTAINERS | 7 + include/asm-generic/global_data.h | 2 +- include/membuf.h | 246 ++++++++++++++++++++++++ include/membuff.h | 246 ------------------------ lib/Makefile | 2 +- lib/membuf.c | 389 ++++++++++++++++++++++++++++++++++++++ lib/membuff.c | 389 -------------------------------------- 7 files changed, 644 insertions(+), 637 deletions(-) create mode 100644 include/membuf.h delete mode 100644 include/membuff.h create mode 100644 lib/membuf.c delete mode 100644 lib/membuff.c diff --git a/MAINTAINERS b/MAINTAINERS index 92d4a158fd0..fac9ce81d70 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1281,6 +1281,13 @@ T: git git://github.com/ARM-software/u-boot.git F: drivers/video/mali_dp.c F: drivers/i2c/i2c-versatile.c +MEMBUF +M: Simon Glass +S: Maintained +T: git https://source.denx.de/u-boot/u-boot.git +F: include/membuf.h +F: lib/membuf.c + MICROBLAZE M: Michal Simek S: Maintained diff --git a/include/asm-generic/global_data.h b/include/asm-generic/global_data.h index 789adf2c3f9..18d94592b03 100644 --- a/include/asm-generic/global_data.h +++ b/include/asm-generic/global_data.h @@ -23,7 +23,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/include/membuf.h b/include/membuf.h new file mode 100644 index 00000000000..c7370e1c072 --- /dev/null +++ b/include/membuf.h @@ -0,0 +1,246 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (c) 2015 Google, Inc + * Written by Simon Glass + * + * Copyright (c) 1992 Simon Glass + */ + +#ifndef _membuf_H +#define _membuf_H + +/** + * @struct membuff: holds the state of a membuff - it is used for input and + * output buffers. The buffer extends from @start to (@start + @size - 1). + * Data in the buffer extends from @tail to @head: it is written in at + * @head and read out from @tail. The membuff is empty when @head == @tail + * and full when adding another character would make @head == @tail. We + * therefore waste one character in the membuff to avoid having an extra flag + * to determine whether (when @head == @tail) the membuff is empty or full. + * + * xxxxxx data + * ...... empty + * + * .............xxxxxxxxxxxxxxxx......................... + * ^ ^ + * tail head + * + * xxxxxxxxxxxxx................xxxxxxxxxxxxxxxxxxxxxxxxx + * ^ ^ + * head tail + */ +struct membuff { + char *start; /** the start of the buffer */ + char *end; /** the end of the buffer (start + length) */ + char *head; /** current buffer head */ + char *tail; /** current buffer tail */ +}; + +/** + * membuf_purge() - reset a membuff to the empty state + * + * Initialise head and tail pointers so that the membuff becomes empty. + * + * @mb: membuff to purge + */ +void membuf_purge(struct membuff *mb); + +/** + * membuf_putraw() - find out where bytes can be written + * + * Work out where in the membuff some data could be written. Return a pointer + * to the address and the number of bytes which can be written there. If + * @update is true, the caller must then write the data immediately, since + * the membuff is updated as if the write has been done, + * + * Note that because the spare space in a membuff may not be contiguous, this + * function may not return @maxlen even if there is enough space in the + * membuff. However, by calling this function twice (with @update == true), + * you will get access to all the spare space. + * + * @mb: membuff to adjust + * @maxlen: the number of bytes we want to write + * @update: true to update the membuff as if the write happened, false to not + * @data: the address data can be written to + * Return: number of bytes which can be written + */ +int membuf_putraw(struct membuff *mb, int maxlen, bool update, char **data); + +/** + * membuf_getraw() - find and return a pointer to available bytes + * + * Returns a pointer to any valid input data in the given membuff and + * optionally marks it as read. Note that not all input data may not be + * returned, since data is not necessarily contiguous in the membuff. However, + * if you call this function twice (with @update == true) you are guaranteed + * to get all available data, in at most two installments. + * + * @mb: membuff to adjust + * @maxlen: maximum number of bytes to get + * @update: true to update the membuff as if the bytes have been read (use + * false to check bytes without reading them) + * @data: returns address of data in input membuff + * Return: the number of bytes available at *@data + */ +int membuf_getraw(struct membuff *mb, int maxlen, bool update, char **data); + +/** + * membuf_putbyte() - Writes a byte to a membuff + * + * @mb: membuff to adjust + * @ch: byte to write + * Return: true on success, false if membuff is full + */ +bool membuf_putbyte(struct membuff *mb, int ch); + +/** + * @mb: membuff to adjust + * membuf_getbyte() - Read a byte from the membuff + * Return: the byte read, or -1 if the membuff is empty + */ +int membuf_getbyte(struct membuff *mb); + +/** + * membuf_peekbyte() - check the next available byte + * + * Return the next byte which membuf_getbyte() would return, without + * removing it from the membuff. + * + * @mb: membuff to adjust + * Return: the byte peeked, or -1 if the membuff is empty + */ +int membuf_peekbyte(struct membuff *mb); + +/** + * membuf_get() - get data from a membuff + * + * Copies any available data (up to @maxlen bytes) to @buff and removes it + * from the membuff. + * + * @mb: membuff to adjust + * @Buff: address of membuff to transfer bytes to + * @maxlen: maximum number of bytes to read + * Return: the number of bytes read + */ +int membuf_get(struct membuff *mb, char *buff, int maxlen); + +/** + * membuf_put() - write data to a membuff + * + * Writes some data to a membuff. Returns the number of bytes added. If this + * is less than @lnehgt, then the membuff got full + * + * @mb: membuff to adjust + * @data: the data to write + * @length: number of bytes to write from 'data' + * Return: the number of bytes added + */ +int membuf_put(struct membuff *mb, const char *buff, int length); + +/** + * membuf_isempty() - check if a membuff is empty + * + * @mb: membuff to check + * Return: true if empty, else false + */ +bool membuf_isempty(struct membuff *mb); + +/** + * membuf_avail() - check available data in a membuff + * + * @mb: membuff to check + * Return: number of bytes of data available + */ +int membuf_avail(struct membuff *mb); + +/** + * membuf_size() - get the size of a membuff + * + * Note that a membuff can only old data up to one byte less than its size. + * + * @mb: membuff to check + * Return: total size + */ +int membuf_size(struct membuff *mb); + +/** + * membuf_makecontig() - adjust all membuff data to be contiguous + * + * This places all data in a membuff into a single contiguous lump, if + * possible + * + * @mb: membuff to adjust + * Return: true on success + */ +bool membuf_makecontig(struct membuff *mb); + +/** + * membuf_free() - find the number of bytes that can be written to a membuff + * + * @mb: membuff to check + * Return: returns the number of bytes free in a membuff + */ +int membuf_free(struct membuff *mb); + +/** + * membuf_readline() - read a line of text from a membuff + * + * Reads a line of text of up to 'maxlen' characters from a membuff and puts + * it in @str. Any character less than @minch is assumed to be the end of + * line character + * + * @mb: membuff to adjust + * @str: Place to put the line + * @maxlen: Maximum line length (excluding terminator) + * @must_fit: If true then str is empty if line doesn't fit + * Return: number of bytes read (including terminator) if a line has been + * read, 0 if nothing was there or line didn't fit when must_fit is set + */ +int membuf_readline(struct membuff *mb, char *str, int maxlen, int minch, bool must_fit); + +/** + * membuf_extend_by() - expand a membuff + * + * Extends a membuff by the given number of bytes + * + * @mb: membuff to adjust + * @by: Number of bytes to increase the size by + * @max: Maximum size to allow + * Return: 0 if the expand succeeded, -ENOMEM if not enough memory, -E2BIG + * if the the size would exceed @max + */ +int membuf_extend_by(struct membuff *mb, int by, int max); + +/** + * membuf_init() - set up a new membuff using an existing membuff + * + * @mb: membuff to set up + * @buff: Address of buffer + * @size: Size of buffer + */ +void membuf_init(struct membuff *mb, char *buff, int size); + +/** + * membuf_uninit() - clear a membuff so it can no longer be used + * + * @mb: membuff to uninit + */ +void membuf_uninit(struct membuff *mb); + +/** + * membuf_new() - create a new membuff + * + * @mb: membuff to init + * @size: size of membuff to create + * Return: 0 if OK, -ENOMEM if out of memory + */ +int membuf_new(struct membuff *mb, int size); + +/** + * membuf_dispose() - free memory allocated to a membuff and uninit it + * + * @mb: membuff to dispose + */ +void membuf_dispose(struct membuff *mb); + +#endif diff --git a/include/membuff.h b/include/membuff.h deleted file mode 100644 index c7370e1c072..00000000000 --- a/include/membuff.h +++ /dev/null @@ -1,246 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * Copyright (c) 2015 Google, Inc - * Written by Simon Glass - * - * Copyright (c) 1992 Simon Glass - */ - -#ifndef _membuf_H -#define _membuf_H - -/** - * @struct membuff: holds the state of a membuff - it is used for input and - * output buffers. The buffer extends from @start to (@start + @size - 1). - * Data in the buffer extends from @tail to @head: it is written in at - * @head and read out from @tail. The membuff is empty when @head == @tail - * and full when adding another character would make @head == @tail. We - * therefore waste one character in the membuff to avoid having an extra flag - * to determine whether (when @head == @tail) the membuff is empty or full. - * - * xxxxxx data - * ...... empty - * - * .............xxxxxxxxxxxxxxxx......................... - * ^ ^ - * tail head - * - * xxxxxxxxxxxxx................xxxxxxxxxxxxxxxxxxxxxxxxx - * ^ ^ - * head tail - */ -struct membuff { - char *start; /** the start of the buffer */ - char *end; /** the end of the buffer (start + length) */ - char *head; /** current buffer head */ - char *tail; /** current buffer tail */ -}; - -/** - * membuf_purge() - reset a membuff to the empty state - * - * Initialise head and tail pointers so that the membuff becomes empty. - * - * @mb: membuff to purge - */ -void membuf_purge(struct membuff *mb); - -/** - * membuf_putraw() - find out where bytes can be written - * - * Work out where in the membuff some data could be written. Return a pointer - * to the address and the number of bytes which can be written there. If - * @update is true, the caller must then write the data immediately, since - * the membuff is updated as if the write has been done, - * - * Note that because the spare space in a membuff may not be contiguous, this - * function may not return @maxlen even if there is enough space in the - * membuff. However, by calling this function twice (with @update == true), - * you will get access to all the spare space. - * - * @mb: membuff to adjust - * @maxlen: the number of bytes we want to write - * @update: true to update the membuff as if the write happened, false to not - * @data: the address data can be written to - * Return: number of bytes which can be written - */ -int membuf_putraw(struct membuff *mb, int maxlen, bool update, char **data); - -/** - * membuf_getraw() - find and return a pointer to available bytes - * - * Returns a pointer to any valid input data in the given membuff and - * optionally marks it as read. Note that not all input data may not be - * returned, since data is not necessarily contiguous in the membuff. However, - * if you call this function twice (with @update == true) you are guaranteed - * to get all available data, in at most two installments. - * - * @mb: membuff to adjust - * @maxlen: maximum number of bytes to get - * @update: true to update the membuff as if the bytes have been read (use - * false to check bytes without reading them) - * @data: returns address of data in input membuff - * Return: the number of bytes available at *@data - */ -int membuf_getraw(struct membuff *mb, int maxlen, bool update, char **data); - -/** - * membuf_putbyte() - Writes a byte to a membuff - * - * @mb: membuff to adjust - * @ch: byte to write - * Return: true on success, false if membuff is full - */ -bool membuf_putbyte(struct membuff *mb, int ch); - -/** - * @mb: membuff to adjust - * membuf_getbyte() - Read a byte from the membuff - * Return: the byte read, or -1 if the membuff is empty - */ -int membuf_getbyte(struct membuff *mb); - -/** - * membuf_peekbyte() - check the next available byte - * - * Return the next byte which membuf_getbyte() would return, without - * removing it from the membuff. - * - * @mb: membuff to adjust - * Return: the byte peeked, or -1 if the membuff is empty - */ -int membuf_peekbyte(struct membuff *mb); - -/** - * membuf_get() - get data from a membuff - * - * Copies any available data (up to @maxlen bytes) to @buff and removes it - * from the membuff. - * - * @mb: membuff to adjust - * @Buff: address of membuff to transfer bytes to - * @maxlen: maximum number of bytes to read - * Return: the number of bytes read - */ -int membuf_get(struct membuff *mb, char *buff, int maxlen); - -/** - * membuf_put() - write data to a membuff - * - * Writes some data to a membuff. Returns the number of bytes added. If this - * is less than @lnehgt, then the membuff got full - * - * @mb: membuff to adjust - * @data: the data to write - * @length: number of bytes to write from 'data' - * Return: the number of bytes added - */ -int membuf_put(struct membuff *mb, const char *buff, int length); - -/** - * membuf_isempty() - check if a membuff is empty - * - * @mb: membuff to check - * Return: true if empty, else false - */ -bool membuf_isempty(struct membuff *mb); - -/** - * membuf_avail() - check available data in a membuff - * - * @mb: membuff to check - * Return: number of bytes of data available - */ -int membuf_avail(struct membuff *mb); - -/** - * membuf_size() - get the size of a membuff - * - * Note that a membuff can only old data up to one byte less than its size. - * - * @mb: membuff to check - * Return: total size - */ -int membuf_size(struct membuff *mb); - -/** - * membuf_makecontig() - adjust all membuff data to be contiguous - * - * This places all data in a membuff into a single contiguous lump, if - * possible - * - * @mb: membuff to adjust - * Return: true on success - */ -bool membuf_makecontig(struct membuff *mb); - -/** - * membuf_free() - find the number of bytes that can be written to a membuff - * - * @mb: membuff to check - * Return: returns the number of bytes free in a membuff - */ -int membuf_free(struct membuff *mb); - -/** - * membuf_readline() - read a line of text from a membuff - * - * Reads a line of text of up to 'maxlen' characters from a membuff and puts - * it in @str. Any character less than @minch is assumed to be the end of - * line character - * - * @mb: membuff to adjust - * @str: Place to put the line - * @maxlen: Maximum line length (excluding terminator) - * @must_fit: If true then str is empty if line doesn't fit - * Return: number of bytes read (including terminator) if a line has been - * read, 0 if nothing was there or line didn't fit when must_fit is set - */ -int membuf_readline(struct membuff *mb, char *str, int maxlen, int minch, bool must_fit); - -/** - * membuf_extend_by() - expand a membuff - * - * Extends a membuff by the given number of bytes - * - * @mb: membuff to adjust - * @by: Number of bytes to increase the size by - * @max: Maximum size to allow - * Return: 0 if the expand succeeded, -ENOMEM if not enough memory, -E2BIG - * if the the size would exceed @max - */ -int membuf_extend_by(struct membuff *mb, int by, int max); - -/** - * membuf_init() - set up a new membuff using an existing membuff - * - * @mb: membuff to set up - * @buff: Address of buffer - * @size: Size of buffer - */ -void membuf_init(struct membuff *mb, char *buff, int size); - -/** - * membuf_uninit() - clear a membuff so it can no longer be used - * - * @mb: membuff to uninit - */ -void membuf_uninit(struct membuff *mb); - -/** - * membuf_new() - create a new membuff - * - * @mb: membuff to init - * @size: size of membuff to create - * Return: 0 if OK, -ENOMEM if out of memory - */ -int membuf_new(struct membuff *mb, int size); - -/** - * membuf_dispose() - free memory allocated to a membuff and uninit it - * - * @mb: membuff to dispose - */ -void membuf_dispose(struct membuff *mb); - -#endif diff --git a/lib/Makefile b/lib/Makefile index a30ce1595d5..41de2671cc6 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -125,7 +125,7 @@ obj-y += hang.o obj-y += linux_compat.o obj-y += linux_string.o obj-$(CONFIG_$(PHASE_)LMB) += lmb.o -obj-y += membuff.o +obj-y += membuf.o obj-$(CONFIG_REGEX) += slre.o obj-y += string.o obj-y += tables_csum.o diff --git a/lib/membuf.c b/lib/membuf.c new file mode 100644 index 00000000000..5473efa98ca --- /dev/null +++ b/lib/membuf.c @@ -0,0 +1,389 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) 2015 Google, Inc + * Written by Simon Glass + * + * Copyright (c) 1992 Simon Glass + */ + +#include +#include +#include +#include "membuf.h" + +void membuf_purge(struct membuff *mb) +{ + /* set mb->head and mb->tail so the buffers look empty */ + mb->head = mb->start; + mb->tail = mb->start; +} + +static int membuf_putrawflex(struct membuff *mb, int maxlen, bool update, + char ***data, int *offsetp) +{ + int len; + + /* always write to 'mb->head' */ + assert(data && offsetp); + *data = &mb->start; + *offsetp = mb->head - mb->start; + + /* if there is no buffer, we can do nothing */ + if (!mb->start) + return 0; + + /* + * if head is ahead of tail, we can write from head until the end of + * the buffer + */ + if (mb->head >= mb->tail) { + /* work out how many bytes can fit here */ + len = mb->end - mb->head - 1; + if (maxlen >= 0 && len > maxlen) + len = maxlen; + + /* update the head pointer to mark these bytes as written */ + if (update) + mb->head += len; + + /* + * if the tail isn't at start of the buffer, then we can + * write one more byte right at the end + */ + if ((maxlen < 0 || len < maxlen) && mb->tail != mb->start) { + len++; + if (update) + mb->head = mb->start; + } + + /* otherwise now we can write until head almost reaches tail */ + } else { + /* work out how many bytes can fit here */ + len = mb->tail - mb->head - 1; + if (maxlen >= 0 && len > maxlen) + len = maxlen; + + /* update the head pointer to mark these bytes as written */ + if (update) + mb->head += len; + } + + /* return the number of bytes which can be/must be written */ + return len; +} + +int membuf_putraw(struct membuff *mb, int maxlen, bool update, char **data) +{ + char **datap; + int offset; + int size; + + size = membuf_putrawflex(mb, maxlen, update, &datap, &offset); + *data = *datap + offset; + + return size; +} + +bool membuf_putbyte(struct membuff *mb, int ch) +{ + char *data; + + if (membuf_putraw(mb, 1, true, &data) != 1) + return false; + *data = ch; + + return true; +} + +int membuf_getraw(struct membuff *mb, int maxlen, bool update, char **data) +{ + int len; + + /* assume for now there is no data to get */ + len = 0; + + /* + * in this case head is ahead of tail, so we must return data between + *'tail' and 'head' + */ + if (mb->head > mb->tail) { + /* work out the amount of data */ + *data = mb->tail; + len = mb->head - mb->tail; + + /* check it isn't too much */ + if (maxlen >= 0 && len > maxlen) + len = maxlen; + + /* & mark it as read from the buffer */ + if (update) + mb->tail += len; + } + + /* + * if head is before tail, then we have data between 'tail' and 'end' + * and some more data between 'start' and 'head'(which we can't + * return this time + */ + else if (mb->head < mb->tail) { + /* work out the amount of data */ + *data = mb->tail; + len = mb->end - mb->tail; + if (maxlen >= 0 && len > maxlen) + len = maxlen; + if (update) { + mb->tail += len; + if (mb->tail == mb->end) + mb->tail = mb->start; + } + } + + debug("getraw: maxlen=%d, update=%d, head=%d, tail=%d, data=%d, len=%d", + maxlen, update, (int)(mb->head - mb->start), + (int)(mb->tail - mb->start), (int)(*data - mb->start), len); + + /* return the number of bytes we found */ + return len; +} + +int membuf_getbyte(struct membuff *mb) +{ + char *data = 0; + + return membuf_getraw(mb, 1, true, &data) != 1 ? -1 : *(uint8_t *)data; +} + +int membuf_peekbyte(struct membuff *mb) +{ + char *data = 0; + + return membuf_getraw(mb, 1, false, &data) != 1 ? -1 : *(uint8_t *)data; +} + +int membuf_get(struct membuff *mb, char *buff, int maxlen) +{ + char *data = 0, *buffptr = buff; + int len = 1, i; + + /* + * do this in up to two lots(see GetRaw for why) stopping when there + * is no more data + */ + for (i = 0; len && i < 2; i++) { + /* get a pointer to the data available */ + len = membuf_getraw(mb, maxlen, true, &data); + + /* copy it into the buffer */ + memcpy(buffptr, data, len); + buffptr += len; + maxlen -= len; + } + + /* return the number of bytes read */ + return buffptr - buff; +} + +int membuf_put(struct membuff *mb, const char *buff, int length) +{ + char *data; + int towrite, i, written; + + for (i = written = 0; i < 2; i++) { + /* ask where some data can be written */ + towrite = membuf_putraw(mb, length, true, &data); + + /* and write it, updating the bytes length */ + memcpy(data, buff, towrite); + written += towrite; + buff += towrite; + length -= towrite; + } + + /* return the number of bytes written */ + return written; +} + +bool membuf_isempty(struct membuff *mb) +{ + return mb->head == mb->tail; +} + +int membuf_avail(struct membuff *mb) +{ + struct membuff copy; + int i, avail; + char *data = 0; + + /* make a copy of this buffer's control data */ + copy = *mb; + + /* now read everything out of the copied buffer */ + for (i = avail = 0; i < 2; i++) + avail += membuf_getraw(©, -1, true, &data); + + /* and return how much we read */ + return avail; +} + +int membuf_size(struct membuff *mb) +{ + return mb->end - mb->start; +} + +bool membuf_makecontig(struct membuff *mb) +{ + int topsize, botsize; + + debug("makecontig: head=%d, tail=%d, size=%d", + (int)(mb->head - mb->start), (int)(mb->tail - mb->start), + (int)(mb->end - mb->start)); + + /* + * first we move anything at the start of the buffer into the correct + * place some way along + */ + if (mb->tail > mb->head) { + /* + * the data is split into two parts, from 0 to ->head and + * from ->tail to ->end. We move the stuff from 0 to ->head + * up to make space for the other data before it + */ + topsize = mb->end - mb->tail; + botsize = mb->head - mb->start; + + /* + * must move data at bottom up by 'topsize' bytes - check if + * there's room + */ + if (mb->head + topsize >= mb->tail) + return false; + memmove(mb->start + topsize, mb->start, botsize); + debug(" - memmove(%d, %d, %d)", topsize, 0, botsize); + + /* nothing at the start, so skip that step */ + } else { + topsize = mb->head - mb->tail; + botsize = 0; + } + + /* now move data at top down to the bottom */ + memcpy(mb->start, mb->tail, topsize); + debug(" - memcpy(%d, %d, %d)", 0, (int)(mb->tail - mb->start), topsize); + + /* adjust pointers */ + mb->tail = mb->start; + mb->head = mb->start + topsize + botsize; + + debug(" - head=%d, tail=%d", (int)(mb->head - mb->start), + (int)(mb->tail - mb->start)); + + /* all ok */ + return true; +} + +int membuf_free(struct membuff *mb) +{ + return mb->end == mb->start ? 0 : + (mb->end - mb->start) - 1 - membuf_avail(mb); +} + +int membuf_readline(struct membuff *mb, char *str, int maxlen, int minch, bool must_fit) +{ + int len; /* number of bytes read (!= string length) */ + char *s, *end; + bool ok = false; + char *orig = str; + + end = mb->head >= mb->tail ? mb->head : mb->end; + for (len = 0, s = mb->tail; s < end && len < maxlen - 1; str++) { + *str = *s++; + len++; + if (*str == '\n' || *str < minch) { + ok = true; + break; + } + if (s == end && mb->tail > mb->head) { + s = mb->start; + end = mb->head; + } + } + + /* couldn't get the whole string */ + if (!ok && must_fit) { + if (maxlen) + *orig = '\0'; + return 0; + } + + /* terminate the string, update the membuff and return success */ + *str = '\0'; + mb->tail = s == mb->end ? mb->start : s; + + return len; +} + +int membuf_extend_by(struct membuff *mb, int by, int max) +{ + int oldhead, oldtail; + int size, orig; + char *ptr; + + /* double the buffer size until it is big enough */ + assert(by >= 0); + for (orig = mb->end - mb->start, size = orig; size < orig + by;) + size *= 2; + if (max != -1) + size = min(size, max); + by = size - orig; + + /* if we're already at maximum, give up */ + if (by <= 0) + return -E2BIG; + + oldhead = mb->head - mb->start; + oldtail = mb->tail - mb->start; + ptr = realloc(mb->start, size); + if (!ptr) + return -ENOMEM; + mb->start = ptr; + mb->head = mb->start + oldhead; + mb->tail = mb->start + oldtail; + + if (mb->head < mb->tail) { + memmove(mb->tail + by, mb->tail, orig - oldtail); + mb->tail += by; + } + mb->end = mb->start + size; + + return 0; +} + +void membuf_init(struct membuff *mb, char *buff, int size) +{ + mb->start = buff; + mb->end = mb->start + size; + membuf_purge(mb); +} + +int membuf_new(struct membuff *mb, int size) +{ + mb->start = malloc(size); + if (!mb->start) + return -ENOMEM; + + membuf_init(mb, mb->start, size); + return 0; +} + +void membuf_uninit(struct membuff *mb) +{ + mb->end = NULL; + mb->start = NULL; + membuf_purge(mb); +} + +void membuf_dispose(struct membuff *mb) +{ + free(&mb->start); + membuf_uninit(mb); +} diff --git a/lib/membuff.c b/lib/membuff.c deleted file mode 100644 index 435d12b8a3c..00000000000 --- a/lib/membuff.c +++ /dev/null @@ -1,389 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Copyright (c) 2015 Google, Inc - * Written by Simon Glass - * - * Copyright (c) 1992 Simon Glass - */ - -#include -#include -#include -#include "membuff.h" - -void membuf_purge(struct membuff *mb) -{ - /* set mb->head and mb->tail so the buffers look empty */ - mb->head = mb->start; - mb->tail = mb->start; -} - -static int membuf_putrawflex(struct membuff *mb, int maxlen, bool update, - char ***data, int *offsetp) -{ - int len; - - /* always write to 'mb->head' */ - assert(data && offsetp); - *data = &mb->start; - *offsetp = mb->head - mb->start; - - /* if there is no buffer, we can do nothing */ - if (!mb->start) - return 0; - - /* - * if head is ahead of tail, we can write from head until the end of - * the buffer - */ - if (mb->head >= mb->tail) { - /* work out how many bytes can fit here */ - len = mb->end - mb->head - 1; - if (maxlen >= 0 && len > maxlen) - len = maxlen; - - /* update the head pointer to mark these bytes as written */ - if (update) - mb->head += len; - - /* - * if the tail isn't at start of the buffer, then we can - * write one more byte right at the end - */ - if ((maxlen < 0 || len < maxlen) && mb->tail != mb->start) { - len++; - if (update) - mb->head = mb->start; - } - - /* otherwise now we can write until head almost reaches tail */ - } else { - /* work out how many bytes can fit here */ - len = mb->tail - mb->head - 1; - if (maxlen >= 0 && len > maxlen) - len = maxlen; - - /* update the head pointer to mark these bytes as written */ - if (update) - mb->head += len; - } - - /* return the number of bytes which can be/must be written */ - return len; -} - -int membuf_putraw(struct membuff *mb, int maxlen, bool update, char **data) -{ - char **datap; - int offset; - int size; - - size = membuf_putrawflex(mb, maxlen, update, &datap, &offset); - *data = *datap + offset; - - return size; -} - -bool membuf_putbyte(struct membuff *mb, int ch) -{ - char *data; - - if (membuf_putraw(mb, 1, true, &data) != 1) - return false; - *data = ch; - - return true; -} - -int membuf_getraw(struct membuff *mb, int maxlen, bool update, char **data) -{ - int len; - - /* assume for now there is no data to get */ - len = 0; - - /* - * in this case head is ahead of tail, so we must return data between - *'tail' and 'head' - */ - if (mb->head > mb->tail) { - /* work out the amount of data */ - *data = mb->tail; - len = mb->head - mb->tail; - - /* check it isn't too much */ - if (maxlen >= 0 && len > maxlen) - len = maxlen; - - /* & mark it as read from the buffer */ - if (update) - mb->tail += len; - } - - /* - * if head is before tail, then we have data between 'tail' and 'end' - * and some more data between 'start' and 'head'(which we can't - * return this time - */ - else if (mb->head < mb->tail) { - /* work out the amount of data */ - *data = mb->tail; - len = mb->end - mb->tail; - if (maxlen >= 0 && len > maxlen) - len = maxlen; - if (update) { - mb->tail += len; - if (mb->tail == mb->end) - mb->tail = mb->start; - } - } - - debug("getraw: maxlen=%d, update=%d, head=%d, tail=%d, data=%d, len=%d", - maxlen, update, (int)(mb->head - mb->start), - (int)(mb->tail - mb->start), (int)(*data - mb->start), len); - - /* return the number of bytes we found */ - return len; -} - -int membuf_getbyte(struct membuff *mb) -{ - char *data = 0; - - return membuf_getraw(mb, 1, true, &data) != 1 ? -1 : *(uint8_t *)data; -} - -int membuf_peekbyte(struct membuff *mb) -{ - char *data = 0; - - return membuf_getraw(mb, 1, false, &data) != 1 ? -1 : *(uint8_t *)data; -} - -int membuf_get(struct membuff *mb, char *buff, int maxlen) -{ - char *data = 0, *buffptr = buff; - int len = 1, i; - - /* - * do this in up to two lots(see GetRaw for why) stopping when there - * is no more data - */ - for (i = 0; len && i < 2; i++) { - /* get a pointer to the data available */ - len = membuf_getraw(mb, maxlen, true, &data); - - /* copy it into the buffer */ - memcpy(buffptr, data, len); - buffptr += len; - maxlen -= len; - } - - /* return the number of bytes read */ - return buffptr - buff; -} - -int membuf_put(struct membuff *mb, const char *buff, int length) -{ - char *data; - int towrite, i, written; - - for (i = written = 0; i < 2; i++) { - /* ask where some data can be written */ - towrite = membuf_putraw(mb, length, true, &data); - - /* and write it, updating the bytes length */ - memcpy(data, buff, towrite); - written += towrite; - buff += towrite; - length -= towrite; - } - - /* return the number of bytes written */ - return written; -} - -bool membuf_isempty(struct membuff *mb) -{ - return mb->head == mb->tail; -} - -int membuf_avail(struct membuff *mb) -{ - struct membuff copy; - int i, avail; - char *data = 0; - - /* make a copy of this buffer's control data */ - copy = *mb; - - /* now read everything out of the copied buffer */ - for (i = avail = 0; i < 2; i++) - avail += membuf_getraw(©, -1, true, &data); - - /* and return how much we read */ - return avail; -} - -int membuf_size(struct membuff *mb) -{ - return mb->end - mb->start; -} - -bool membuf_makecontig(struct membuff *mb) -{ - int topsize, botsize; - - debug("makecontig: head=%d, tail=%d, size=%d", - (int)(mb->head - mb->start), (int)(mb->tail - mb->start), - (int)(mb->end - mb->start)); - - /* - * first we move anything at the start of the buffer into the correct - * place some way along - */ - if (mb->tail > mb->head) { - /* - * the data is split into two parts, from 0 to ->head and - * from ->tail to ->end. We move the stuff from 0 to ->head - * up to make space for the other data before it - */ - topsize = mb->end - mb->tail; - botsize = mb->head - mb->start; - - /* - * must move data at bottom up by 'topsize' bytes - check if - * there's room - */ - if (mb->head + topsize >= mb->tail) - return false; - memmove(mb->start + topsize, mb->start, botsize); - debug(" - memmove(%d, %d, %d)", topsize, 0, botsize); - - /* nothing at the start, so skip that step */ - } else { - topsize = mb->head - mb->tail; - botsize = 0; - } - - /* now move data at top down to the bottom */ - memcpy(mb->start, mb->tail, topsize); - debug(" - memcpy(%d, %d, %d)", 0, (int)(mb->tail - mb->start), topsize); - - /* adjust pointers */ - mb->tail = mb->start; - mb->head = mb->start + topsize + botsize; - - debug(" - head=%d, tail=%d", (int)(mb->head - mb->start), - (int)(mb->tail - mb->start)); - - /* all ok */ - return true; -} - -int membuf_free(struct membuff *mb) -{ - return mb->end == mb->start ? 0 : - (mb->end - mb->start) - 1 - membuf_avail(mb); -} - -int membuf_readline(struct membuff *mb, char *str, int maxlen, int minch, bool must_fit) -{ - int len; /* number of bytes read (!= string length) */ - char *s, *end; - bool ok = false; - char *orig = str; - - end = mb->head >= mb->tail ? mb->head : mb->end; - for (len = 0, s = mb->tail; s < end && len < maxlen - 1; str++) { - *str = *s++; - len++; - if (*str == '\n' || *str < minch) { - ok = true; - break; - } - if (s == end && mb->tail > mb->head) { - s = mb->start; - end = mb->head; - } - } - - /* couldn't get the whole string */ - if (!ok && must_fit) { - if (maxlen) - *orig = '\0'; - return 0; - } - - /* terminate the string, update the membuff and return success */ - *str = '\0'; - mb->tail = s == mb->end ? mb->start : s; - - return len; -} - -int membuf_extend_by(struct membuff *mb, int by, int max) -{ - int oldhead, oldtail; - int size, orig; - char *ptr; - - /* double the buffer size until it is big enough */ - assert(by >= 0); - for (orig = mb->end - mb->start, size = orig; size < orig + by;) - size *= 2; - if (max != -1) - size = min(size, max); - by = size - orig; - - /* if we're already at maximum, give up */ - if (by <= 0) - return -E2BIG; - - oldhead = mb->head - mb->start; - oldtail = mb->tail - mb->start; - ptr = realloc(mb->start, size); - if (!ptr) - return -ENOMEM; - mb->start = ptr; - mb->head = mb->start + oldhead; - mb->tail = mb->start + oldtail; - - if (mb->head < mb->tail) { - memmove(mb->tail + by, mb->tail, orig - oldtail); - mb->tail += by; - } - mb->end = mb->start + size; - - return 0; -} - -void membuf_init(struct membuff *mb, char *buff, int size) -{ - mb->start = buff; - mb->end = mb->start + size; - membuf_purge(mb); -} - -int membuf_new(struct membuff *mb, int size) -{ - mb->start = malloc(size); - if (!mb->start) - return -ENOMEM; - - membuf_init(mb, mb->start, size); - return 0; -} - -void membuf_uninit(struct membuff *mb) -{ - mb->end = NULL; - mb->start = NULL; - membuf_purge(mb); -} - -void membuf_dispose(struct membuff *mb) -{ - free(&mb->start); - membuf_uninit(mb); -} -- cgit v1.2.3 From 68b0af2127dbd7b304f897f4796c6eb86fd74402 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 18 Mar 2025 16:20:44 +0100 Subject: membuf: Rename struct Rename the struct to match the function prefix and filenames. Signed-off-by: Simon Glass --- arch/sandbox/include/asm/serial.h | 2 +- boot/bootmeth_extlinux.c | 2 +- common/console.c | 24 +++++++++++----------- drivers/usb/emul/sandbox_keyb.c | 2 +- include/asm-generic/global_data.h | 4 ++-- include/membuf.h | 42 +++++++++++++++++++-------------------- lib/membuf.c | 42 +++++++++++++++++++-------------------- 7 files changed, 59 insertions(+), 59 deletions(-) diff --git a/arch/sandbox/include/asm/serial.h b/arch/sandbox/include/asm/serial.h index 16589a1b219..41506341816 100644 --- a/arch/sandbox/include/asm/serial.h +++ b/arch/sandbox/include/asm/serial.h @@ -44,7 +44,7 @@ void sandbox_serial_endisable(bool enabled); * @buf: holds input characters available to be read by this driver */ struct sandbox_serial_priv { - struct membuff buf; + struct membuf buf; char serial_buf[16]; bool start_of_line; }; diff --git a/boot/bootmeth_extlinux.c b/boot/bootmeth_extlinux.c index f3a81715080..921d721a27b 100644 --- a/boot/bootmeth_extlinux.c +++ b/boot/bootmeth_extlinux.c @@ -108,7 +108,7 @@ static int extlinux_check(struct udevice *dev, struct bootflow_iter *iter) */ static int extlinux_fill_info(struct bootflow *bflow) { - struct membuff mb; + struct membuf mb; char line[200]; char *data; int len; diff --git a/common/console.c b/common/console.c index ffd0cc1807d..b69bb189639 100644 --- a/common/console.c +++ b/common/console.c @@ -101,7 +101,7 @@ static void console_record_putc(const char c) if (!(gd->flags & GD_FLG_RECORD)) return; if (gd->console_out.start && - !membuf_putbyte((struct membuff *)&gd->console_out, c)) + !membuf_putbyte((struct membuf *)&gd->console_out, c)) gd->flags |= GD_FLG_RECORD_OVF; } @@ -112,7 +112,7 @@ static void console_record_puts(const char *s) if (gd->console_out.start) { int len = strlen(s); - if (membuf_put((struct membuff *)&gd->console_out, s, len) != + if (membuf_put((struct membuf *)&gd->console_out, s, len) != len) gd->flags |= GD_FLG_RECORD_OVF; } @@ -125,7 +125,7 @@ static int console_record_getc(void) if (!gd->console_in.start) return -1; - return membuf_getbyte((struct membuff *)&gd->console_in); + return membuf_getbyte((struct membuf *)&gd->console_in); } static int console_record_tstc(void) @@ -133,7 +133,7 @@ static int console_record_tstc(void) if (!(gd->flags & GD_FLG_RECORD)) return 0; if (gd->console_in.start) { - if (membuf_peekbyte((struct membuff *)&gd->console_in) != -1) + if (membuf_peekbyte((struct membuf *)&gd->console_in) != -1) return 1; } return 0; @@ -810,13 +810,13 @@ int console_record_init(void) { int ret; - ret = membuf_new((struct membuff *)&gd->console_out, + ret = membuf_new((struct membuf *)&gd->console_out, gd->flags & GD_FLG_RELOC ? CONFIG_CONSOLE_RECORD_OUT_SIZE : CONFIG_CONSOLE_RECORD_OUT_SIZE_F); if (ret) return ret; - ret = membuf_new((struct membuff *)&gd->console_in, + ret = membuf_new((struct membuf *)&gd->console_in, CONFIG_CONSOLE_RECORD_IN_SIZE); /* Start recording from the beginning */ @@ -827,8 +827,8 @@ int console_record_init(void) void console_record_reset(void) { - membuf_purge((struct membuff *)&gd->console_out); - membuf_purge((struct membuff *)&gd->console_in); + membuf_purge((struct membuf *)&gd->console_out); + membuf_purge((struct membuf *)&gd->console_in); gd->flags &= ~GD_FLG_RECORD_OVF; } @@ -847,23 +847,23 @@ int console_record_readline(char *str, int maxlen) if (console_record_isempty()) return -ENOENT; - return membuf_readline((struct membuff *)&gd->console_out, str, + return membuf_readline((struct membuf *)&gd->console_out, str, maxlen, '\0', false); } int console_record_avail(void) { - return membuf_avail((struct membuff *)&gd->console_out); + return membuf_avail((struct membuf *)&gd->console_out); } bool console_record_isempty(void) { - return membuf_isempty((struct membuff *)&gd->console_out); + return membuf_isempty((struct membuf *)&gd->console_out); } int console_in_puts(const char *str) { - return membuf_put((struct membuff *)&gd->console_in, str, strlen(str)); + return membuf_put((struct membuf *)&gd->console_in, str, strlen(str)); } #endif diff --git a/drivers/usb/emul/sandbox_keyb.c b/drivers/usb/emul/sandbox_keyb.c index 756fef64a36..5ed8c2c799a 100644 --- a/drivers/usb/emul/sandbox_keyb.c +++ b/drivers/usb/emul/sandbox_keyb.c @@ -38,7 +38,7 @@ enum { * */ struct sandbox_keyb_priv { - struct membuff in; + struct membuf in; }; struct sandbox_keyb_plat { diff --git a/include/asm-generic/global_data.h b/include/asm-generic/global_data.h index 18d94592b03..506ee51cdb0 100644 --- a/include/asm-generic/global_data.h +++ b/include/asm-generic/global_data.h @@ -316,14 +316,14 @@ struct global_data { * * This buffer is used to collect output during console recording. */ - struct membuff console_out; + struct membuf console_out; /** * @console_in: input buffer for console recording * * If console recording is activated, this buffer can be used to * emulate input. */ - struct membuff console_in; + struct membuf console_in; #endif #if CONFIG_IS_ENABLED(VIDEO) /** diff --git a/include/membuf.h b/include/membuf.h index c7370e1c072..17616d5577e 100644 --- a/include/membuf.h +++ b/include/membuf.h @@ -10,7 +10,7 @@ #define _membuf_H /** - * @struct membuff: holds the state of a membuff - it is used for input and + * @struct membuf: holds the state of a membuff - it is used for input and * output buffers. The buffer extends from @start to (@start + @size - 1). * Data in the buffer extends from @tail to @head: it is written in at * @head and read out from @tail. The membuff is empty when @head == @tail @@ -29,7 +29,7 @@ * ^ ^ * head tail */ -struct membuff { +struct membuf { char *start; /** the start of the buffer */ char *end; /** the end of the buffer (start + length) */ char *head; /** current buffer head */ @@ -43,7 +43,7 @@ struct membuff { * * @mb: membuff to purge */ -void membuf_purge(struct membuff *mb); +void membuf_purge(struct membuf *mb); /** * membuf_putraw() - find out where bytes can be written @@ -64,7 +64,7 @@ void membuf_purge(struct membuff *mb); * @data: the address data can be written to * Return: number of bytes which can be written */ -int membuf_putraw(struct membuff *mb, int maxlen, bool update, char **data); +int membuf_putraw(struct membuf *mb, int maxlen, bool update, char **data); /** * membuf_getraw() - find and return a pointer to available bytes @@ -82,7 +82,7 @@ int membuf_putraw(struct membuff *mb, int maxlen, bool update, char **data); * @data: returns address of data in input membuff * Return: the number of bytes available at *@data */ -int membuf_getraw(struct membuff *mb, int maxlen, bool update, char **data); +int membuf_getraw(struct membuf *mb, int maxlen, bool update, char **data); /** * membuf_putbyte() - Writes a byte to a membuff @@ -91,14 +91,14 @@ int membuf_getraw(struct membuff *mb, int maxlen, bool update, char **data); * @ch: byte to write * Return: true on success, false if membuff is full */ -bool membuf_putbyte(struct membuff *mb, int ch); +bool membuf_putbyte(struct membuf *mb, int ch); /** * @mb: membuff to adjust * membuf_getbyte() - Read a byte from the membuff * Return: the byte read, or -1 if the membuff is empty */ -int membuf_getbyte(struct membuff *mb); +int membuf_getbyte(struct membuf *mb); /** * membuf_peekbyte() - check the next available byte @@ -109,7 +109,7 @@ int membuf_getbyte(struct membuff *mb); * @mb: membuff to adjust * Return: the byte peeked, or -1 if the membuff is empty */ -int membuf_peekbyte(struct membuff *mb); +int membuf_peekbyte(struct membuf *mb); /** * membuf_get() - get data from a membuff @@ -122,7 +122,7 @@ int membuf_peekbyte(struct membuff *mb); * @maxlen: maximum number of bytes to read * Return: the number of bytes read */ -int membuf_get(struct membuff *mb, char *buff, int maxlen); +int membuf_get(struct membuf *mb, char *buff, int maxlen); /** * membuf_put() - write data to a membuff @@ -135,7 +135,7 @@ int membuf_get(struct membuff *mb, char *buff, int maxlen); * @length: number of bytes to write from 'data' * Return: the number of bytes added */ -int membuf_put(struct membuff *mb, const char *buff, int length); +int membuf_put(struct membuf *mb, const char *buff, int length); /** * membuf_isempty() - check if a membuff is empty @@ -143,7 +143,7 @@ int membuf_put(struct membuff *mb, const char *buff, int length); * @mb: membuff to check * Return: true if empty, else false */ -bool membuf_isempty(struct membuff *mb); +bool membuf_isempty(struct membuf *mb); /** * membuf_avail() - check available data in a membuff @@ -151,7 +151,7 @@ bool membuf_isempty(struct membuff *mb); * @mb: membuff to check * Return: number of bytes of data available */ -int membuf_avail(struct membuff *mb); +int membuf_avail(struct membuf *mb); /** * membuf_size() - get the size of a membuff @@ -161,7 +161,7 @@ int membuf_avail(struct membuff *mb); * @mb: membuff to check * Return: total size */ -int membuf_size(struct membuff *mb); +int membuf_size(struct membuf *mb); /** * membuf_makecontig() - adjust all membuff data to be contiguous @@ -172,7 +172,7 @@ int membuf_size(struct membuff *mb); * @mb: membuff to adjust * Return: true on success */ -bool membuf_makecontig(struct membuff *mb); +bool membuf_makecontig(struct membuf *mb); /** * membuf_free() - find the number of bytes that can be written to a membuff @@ -180,7 +180,7 @@ bool membuf_makecontig(struct membuff *mb); * @mb: membuff to check * Return: returns the number of bytes free in a membuff */ -int membuf_free(struct membuff *mb); +int membuf_free(struct membuf *mb); /** * membuf_readline() - read a line of text from a membuff @@ -196,7 +196,7 @@ int membuf_free(struct membuff *mb); * Return: number of bytes read (including terminator) if a line has been * read, 0 if nothing was there or line didn't fit when must_fit is set */ -int membuf_readline(struct membuff *mb, char *str, int maxlen, int minch, bool must_fit); +int membuf_readline(struct membuf *mb, char *str, int maxlen, int minch, bool must_fit); /** * membuf_extend_by() - expand a membuff @@ -209,7 +209,7 @@ int membuf_readline(struct membuff *mb, char *str, int maxlen, int minch, bool m * Return: 0 if the expand succeeded, -ENOMEM if not enough memory, -E2BIG * if the the size would exceed @max */ -int membuf_extend_by(struct membuff *mb, int by, int max); +int membuf_extend_by(struct membuf *mb, int by, int max); /** * membuf_init() - set up a new membuff using an existing membuff @@ -218,14 +218,14 @@ int membuf_extend_by(struct membuff *mb, int by, int max); * @buff: Address of buffer * @size: Size of buffer */ -void membuf_init(struct membuff *mb, char *buff, int size); +void membuf_init(struct membuf *mb, char *buff, int size); /** * membuf_uninit() - clear a membuff so it can no longer be used * * @mb: membuff to uninit */ -void membuf_uninit(struct membuff *mb); +void membuf_uninit(struct membuf *mb); /** * membuf_new() - create a new membuff @@ -234,13 +234,13 @@ void membuf_uninit(struct membuff *mb); * @size: size of membuff to create * Return: 0 if OK, -ENOMEM if out of memory */ -int membuf_new(struct membuff *mb, int size); +int membuf_new(struct membuf *mb, int size); /** * membuf_dispose() - free memory allocated to a membuff and uninit it * * @mb: membuff to dispose */ -void membuf_dispose(struct membuff *mb); +void membuf_dispose(struct membuf *mb); #endif diff --git a/lib/membuf.c b/lib/membuf.c index 5473efa98ca..b13998ccdbd 100644 --- a/lib/membuf.c +++ b/lib/membuf.c @@ -11,14 +11,14 @@ #include #include "membuf.h" -void membuf_purge(struct membuff *mb) +void membuf_purge(struct membuf *mb) { /* set mb->head and mb->tail so the buffers look empty */ mb->head = mb->start; mb->tail = mb->start; } -static int membuf_putrawflex(struct membuff *mb, int maxlen, bool update, +static int membuf_putrawflex(struct membuf *mb, int maxlen, bool update, char ***data, int *offsetp) { int len; @@ -72,7 +72,7 @@ static int membuf_putrawflex(struct membuff *mb, int maxlen, bool update, return len; } -int membuf_putraw(struct membuff *mb, int maxlen, bool update, char **data) +int membuf_putraw(struct membuf *mb, int maxlen, bool update, char **data) { char **datap; int offset; @@ -84,7 +84,7 @@ int membuf_putraw(struct membuff *mb, int maxlen, bool update, char **data) return size; } -bool membuf_putbyte(struct membuff *mb, int ch) +bool membuf_putbyte(struct membuf *mb, int ch) { char *data; @@ -95,7 +95,7 @@ bool membuf_putbyte(struct membuff *mb, int ch) return true; } -int membuf_getraw(struct membuff *mb, int maxlen, bool update, char **data) +int membuf_getraw(struct membuf *mb, int maxlen, bool update, char **data) { int len; @@ -146,21 +146,21 @@ int membuf_getraw(struct membuff *mb, int maxlen, bool update, char **data) return len; } -int membuf_getbyte(struct membuff *mb) +int membuf_getbyte(struct membuf *mb) { char *data = 0; return membuf_getraw(mb, 1, true, &data) != 1 ? -1 : *(uint8_t *)data; } -int membuf_peekbyte(struct membuff *mb) +int membuf_peekbyte(struct membuf *mb) { char *data = 0; return membuf_getraw(mb, 1, false, &data) != 1 ? -1 : *(uint8_t *)data; } -int membuf_get(struct membuff *mb, char *buff, int maxlen) +int membuf_get(struct membuf *mb, char *buff, int maxlen) { char *data = 0, *buffptr = buff; int len = 1, i; @@ -183,7 +183,7 @@ int membuf_get(struct membuff *mb, char *buff, int maxlen) return buffptr - buff; } -int membuf_put(struct membuff *mb, const char *buff, int length) +int membuf_put(struct membuf *mb, const char *buff, int length) { char *data; int towrite, i, written; @@ -203,14 +203,14 @@ int membuf_put(struct membuff *mb, const char *buff, int length) return written; } -bool membuf_isempty(struct membuff *mb) +bool membuf_isempty(struct membuf *mb) { return mb->head == mb->tail; } -int membuf_avail(struct membuff *mb) +int membuf_avail(struct membuf *mb) { - struct membuff copy; + struct membuf copy; int i, avail; char *data = 0; @@ -225,12 +225,12 @@ int membuf_avail(struct membuff *mb) return avail; } -int membuf_size(struct membuff *mb) +int membuf_size(struct membuf *mb) { return mb->end - mb->start; } -bool membuf_makecontig(struct membuff *mb) +bool membuf_makecontig(struct membuf *mb) { int topsize, botsize; @@ -281,13 +281,13 @@ bool membuf_makecontig(struct membuff *mb) return true; } -int membuf_free(struct membuff *mb) +int membuf_free(struct membuf *mb) { return mb->end == mb->start ? 0 : (mb->end - mb->start) - 1 - membuf_avail(mb); } -int membuf_readline(struct membuff *mb, char *str, int maxlen, int minch, bool must_fit) +int membuf_readline(struct membuf *mb, char *str, int maxlen, int minch, bool must_fit) { int len; /* number of bytes read (!= string length) */ char *s, *end; @@ -322,7 +322,7 @@ int membuf_readline(struct membuff *mb, char *str, int maxlen, int minch, bool m return len; } -int membuf_extend_by(struct membuff *mb, int by, int max) +int membuf_extend_by(struct membuf *mb, int by, int max) { int oldhead, oldtail; int size, orig; @@ -358,14 +358,14 @@ int membuf_extend_by(struct membuff *mb, int by, int max) return 0; } -void membuf_init(struct membuff *mb, char *buff, int size) +void membuf_init(struct membuf *mb, char *buff, int size) { mb->start = buff; mb->end = mb->start + size; membuf_purge(mb); } -int membuf_new(struct membuff *mb, int size) +int membuf_new(struct membuf *mb, int size) { mb->start = malloc(size); if (!mb->start) @@ -375,14 +375,14 @@ int membuf_new(struct membuff *mb, int size) return 0; } -void membuf_uninit(struct membuff *mb) +void membuf_uninit(struct membuf *mb) { mb->end = NULL; mb->start = NULL; membuf_purge(mb); } -void membuf_dispose(struct membuff *mb) +void membuf_dispose(struct membuf *mb) { free(&mb->start); membuf_uninit(mb); -- cgit v1.2.3 From f48f1705c357605f05f5a47b84c1c89dc33bec35 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 18 Mar 2025 16:20:45 +0100 Subject: membuf: Include stdbool This uses a bool type so include the required header. Signed-off-by: Simon Glass --- include/membuf.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/membuf.h b/include/membuf.h index 17616d5577e..636ed703ee7 100644 --- a/include/membuf.h +++ b/include/membuf.h @@ -9,6 +9,8 @@ #ifndef _membuf_H #define _membuf_H +#include + /** * @struct membuf: holds the state of a membuff - it is used for input and * output buffers. The buffer extends from @start to (@start + @size - 1). -- cgit v1.2.3 From 44e763bd6624f23fe6d94340efb43c627b5ce4a7 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 18 Mar 2025 16:20:46 +0100 Subject: membuf: Correct implementation of membuf_dispose() This should free the pointer, not the address of the pointer. Fix it. Signed-off-by: Simon Glass --- lib/membuf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/membuf.c b/lib/membuf.c index b13998ccdbd..695d16d051e 100644 --- a/lib/membuf.c +++ b/lib/membuf.c @@ -384,6 +384,6 @@ void membuf_uninit(struct membuf *mb) void membuf_dispose(struct membuf *mb) { - free(&mb->start); + free(mb->start); membuf_uninit(mb); } -- cgit v1.2.3 From 142a3cb63c81602ae4f48266a190ebceb483e536 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 18 Mar 2025 16:20:47 +0100 Subject: membuf: Add some tests Add tests for the membuf implementation. Signed-off-by: Simon Glass --- test/lib/Makefile | 1 + test/lib/membuf.c | 239 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 240 insertions(+) create mode 100644 test/lib/membuf.c diff --git a/test/lib/Makefile b/test/lib/Makefile index 0e4cb8e3dfd..aa89923f786 100644 --- a/test/lib/Makefile +++ b/test/lib/Makefile @@ -14,6 +14,7 @@ obj-y += hexdump.o obj-$(CONFIG_SANDBOX) += kconfig.o obj-y += lmb.o obj-$(CONFIG_HAVE_SETJMP) += longjmp.o +obj-$(CONFIG_SANDBOX) += membuf.o obj-$(CONFIG_CONSOLE_RECORD) += test_print.o obj-$(CONFIG_SSCANF) += sscanf.o obj-$(CONFIG_$(PHASE_)STRTO) += str.o diff --git a/test/lib/membuf.c b/test/lib/membuf.c new file mode 100644 index 00000000000..3f268a422d5 --- /dev/null +++ b/test/lib/membuf.c @@ -0,0 +1,239 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2024 Google LLC + * Written by Simon Glass + */ + +#include +#include +#include +#include +#include +#include +#include + +#define TEST_SIZE 16 +#define TEST_COUNT 10000 + +static void membuf_zero(struct membuf *mb) +{ + memset(mb->start, '\0', mb->end - mb->start); +} + +static int membuf_check(struct unit_test_state *uts, struct membuf *mb, + int value) +{ + /* head is out of range */ + ut_assert(!(mb->head < mb->start || mb->head >= mb->end)); + + /* tail is out of range */ + ut_assert(!(mb->tail < mb->start || mb->tail >= mb->end)); + + return 0; +} + +/* write from 1 to test_size bytes, and check they come back OK */ +static int lib_test_membuf_one(struct unit_test_state *uts) +{ + char in[TEST_SIZE * 2], out[TEST_SIZE * 2]; + struct membuf mb; + int size, ret, test_size, i; + + ut_assertok(membuf_new(&mb, TEST_SIZE)); + + /* setup in test */ + for (i = 0; i < TEST_SIZE; i++) { + in[i] = (i & 63) + '0'; + in[i + TEST_SIZE] = in[i]; + } + + test_size = TEST_SIZE; + + for (i = 1; i < TEST_COUNT; i++) { + membuf_zero(&mb); + size = rand() % test_size; + + // now write patterns and check they come back OK + ret = membuf_put(&mb, in, 0); + ret = membuf_put(&mb, in, size); + ut_asserteq(size, ret); + + ret = membuf_put(&mb, in, 0); + ut_assertok(membuf_check(uts, &mb, i)); + + ret = membuf_get(&mb, out, 0); + ret = membuf_get(&mb, out, size); + ut_asserteq(size, ret); + + ret = membuf_get(&mb, out, 0); + ut_assertok(membuf_check(uts, &mb, i)); + + ut_asserteq_mem(in, out, size); + } + + return 0; +} +LIB_TEST(lib_test_membuf_one, 0); + +/* write random number of bytes, and check they come back OK */ +static int lib_test_membuf_random(struct unit_test_state *uts) +{ + char in[TEST_SIZE * 2]; + char buf[TEST_SIZE * 2]; + struct membuf mb; + int size, ret, test_size, i; + char *inptr, *outptr; + int max_avail, min_free; + + ut_assertok(membuf_new(&mb, TEST_SIZE)); + + for (i = 0; i < TEST_SIZE; i++) { + in[i] = (i & 63) + '0'; + in[i + TEST_SIZE] = in[i]; + } + + test_size = TEST_SIZE; + + inptr = in; + outptr = in; + min_free = TEST_COUNT; + max_avail = 0; + membuf_zero(&mb); + for (i = 0; i < TEST_COUNT; i++) { + size = rand() % test_size; + + if (membuf_free(&mb) < min_free) + min_free = membuf_free(&mb); + + ret = membuf_put(&mb, inptr, size); + ut_assertok(membuf_check(uts, &mb, i)); + inptr += ret; + if (inptr >= in + TEST_SIZE) + inptr -= TEST_SIZE; + + size = rand() % (test_size - 1); + + if (membuf_avail(&mb) > max_avail) + max_avail = membuf_avail(&mb); + + ret = membuf_get(&mb, buf, size); + ut_assertok(membuf_check(uts, &mb, i)); + ut_asserteq_mem(buf, outptr, ret); + + outptr += ret; + if (outptr >= in + TEST_SIZE) + outptr -= TEST_SIZE; + } + + return 0; +} +LIB_TEST(lib_test_membuf_random, 0); + +/* test membuf_extend() with split segments */ +static int lib_test_membuf_extend(struct unit_test_state *uts) +{ + char in[TEST_SIZE * 2]; + char buf[TEST_SIZE * 2]; + struct membuf mb; + int ret, test_size, i, cur; + char *data; + + ut_assertok(membuf_new(&mb, TEST_SIZE)); + + for (i = 0; i < TEST_SIZE; i++) { + in[i] = (i & 63) + '0'; + in[i + TEST_SIZE] = in[i]; + } + + test_size = TEST_SIZE - 1; + + for (cur = 0; cur <= test_size; cur++) { + ut_assertok(membuf_new(&mb, TEST_SIZE)); + + membuf_zero(&mb); + + /* + * add some bytes, then remove them - this will force the membuf + * to have data split into two segments when we fill it + */ + ret = membuf_putraw(&mb, TEST_SIZE / 2, true, &data); + membuf_getraw(&mb, ret, true, &data); + ut_asserteq(TEST_SIZE / 2, ret); + + /* fill it */ + ret = membuf_put(&mb, in, cur); + ut_assertok(membuf_check(uts, &mb, cur)); + ut_asserteq(cur, ret); + + /* extend the buffer */ + ut_assertok(membuf_extend_by(&mb, TEST_SIZE, -1)); + ut_assertok(membuf_check(uts, &mb, cur)); + + /* check our data is still there */ + ret = membuf_get(&mb, buf, TEST_SIZE * 2); + ut_assertok(membuf_check(uts, &mb, cur)); + ut_asserteq(cur, ret); + ut_asserteq_mem(in, buf, cur); + membuf_uninit(&mb); + } + + return 0; +} +LIB_TEST(lib_test_membuf_extend, 0); + +/* test membuf_readline() with generated data */ +static int lib_test_membuf_readline(struct unit_test_state *uts) +{ + char *buf; + int size, cur, i, ret, readptr, cmpptr; + struct membuf mb; + char *data; + char str[256]; + char *s; + + ut_assertok(membuf_new(&mb, 1024)); + membuf_zero(&mb); + + /* Use the README as test data */ + ut_assertok(os_read_file("README", (void **)&buf, &size)); + + cur = 0; + readptr = 0; + cmpptr = 0; + for (i = 0; i < 100000; i++, cur += 1) { + /* fill the buffer with up to 'cur' bytes */ + ret = membuf_putraw(&mb, cur, false, &data); + + if (ret > 0) { + int can_read = min(ret, size - readptr); + + memcpy(data, &buf[readptr], can_read); + readptr += can_read; + + membuf_putraw(&mb, can_read, true, &data); + ut_assertok(membuf_check(uts, &mb, i)); + } + + /* read a line and compare */ + ret = membuf_readline(&mb, str, 256, 0, true); + ut_assertok(membuf_check(uts, &mb, i)); + if (ret) { + char *ptr; + + s = &buf[cmpptr]; + ptr = strchr(s, '\n'); + *ptr = '\0'; + + ut_asserteq_str(s, str); + cmpptr += strlen(s) + 1; + *ptr = '\n'; + } else { + ut_assert(membuf_free(&mb)); + } + } + membuf_dispose(&mb); + os_free(buf); + + return 0; +} +LIB_TEST(lib_test_membuf_readline, 0); -- cgit v1.2.3 From da8694a7d2cc9fdfd67e8a039ba1e70bdd543d0b Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 18 Mar 2025 16:20:48 +0100 Subject: membuf: Minor code-style improvements Show the start in end in the comment. Comment a missing variable in membuf_readline() and fix its line length. Signed-off-by: Simon Glass --- include/membuf.h | 6 ++++-- lib/membuf.c | 3 ++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/include/membuf.h b/include/membuf.h index 636ed703ee7..46764690f53 100644 --- a/include/membuf.h +++ b/include/membuf.h @@ -25,7 +25,7 @@ * * .............xxxxxxxxxxxxxxxx......................... * ^ ^ - * tail head + * ^start tail head ^end * * xxxxxxxxxxxxx................xxxxxxxxxxxxxxxxxxxxxxxxx * ^ ^ @@ -194,11 +194,13 @@ int membuf_free(struct membuf *mb); * @mb: membuff to adjust * @str: Place to put the line * @maxlen: Maximum line length (excluding terminator) + * @minch: Minimum ASCII character to permit as part of the line (e.g. ' ') * @must_fit: If true then str is empty if line doesn't fit * Return: number of bytes read (including terminator) if a line has been * read, 0 if nothing was there or line didn't fit when must_fit is set */ -int membuf_readline(struct membuf *mb, char *str, int maxlen, int minch, bool must_fit); +int membuf_readline(struct membuf *mb, char *str, int maxlen, int minch, + bool must_fit); /** * membuf_extend_by() - expand a membuff diff --git a/lib/membuf.c b/lib/membuf.c index 695d16d051e..f38ff36cb0b 100644 --- a/lib/membuf.c +++ b/lib/membuf.c @@ -287,7 +287,8 @@ int membuf_free(struct membuf *mb) (mb->end - mb->start) - 1 - membuf_avail(mb); } -int membuf_readline(struct membuf *mb, char *str, int maxlen, int minch, bool must_fit) +int membuf_readline(struct membuf *mb, char *str, int maxlen, int minch, + bool must_fit) { int len; /* number of bytes read (!= string length) */ char *s, *end; -- cgit v1.2.3