linux/include/linux/seq_buf.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0 */
   2#ifndef _LINUX_SEQ_BUF_H
   3#define _LINUX_SEQ_BUF_H
   4
   5#include <linux/fs.h>
   6
   7/*
   8 * Trace sequences are used to allow a function to call several other functions
   9 * to create a string of data to use.
  10 */
  11
  12/**
  13 * seq_buf - seq buffer structure
  14 * @buffer:     pointer to the buffer
  15 * @size:       size of the buffer
  16 * @len:        the amount of data inside the buffer
  17 * @readpos:    The next position to read in the buffer.
  18 */
  19struct seq_buf {
  20        char                    *buffer;
  21        size_t                  size;
  22        size_t                  len;
  23        loff_t                  readpos;
  24};
  25
  26static inline void seq_buf_clear(struct seq_buf *s)
  27{
  28        s->len = 0;
  29        s->readpos = 0;
  30}
  31
  32static inline void
  33seq_buf_init(struct seq_buf *s, unsigned char *buf, unsigned int size)
  34{
  35        s->buffer = buf;
  36        s->size = size;
  37        seq_buf_clear(s);
  38}
  39
  40/*
  41 * seq_buf have a buffer that might overflow. When this happens
  42 * the len and size are set to be equal.
  43 */
  44static inline bool
  45seq_buf_has_overflowed(struct seq_buf *s)
  46{
  47        return s->len > s->size;
  48}
  49
  50static inline void
  51seq_buf_set_overflow(struct seq_buf *s)
  52{
  53        s->len = s->size + 1;
  54}
  55
  56/*
  57 * How much buffer is left on the seq_buf?
  58 */
  59static inline unsigned int
  60seq_buf_buffer_left(struct seq_buf *s)
  61{
  62        if (seq_buf_has_overflowed(s))
  63                return 0;
  64
  65        return s->size - s->len;
  66}
  67
  68/* How much buffer was written? */
  69static inline unsigned int seq_buf_used(struct seq_buf *s)
  70{
  71        return min(s->len, s->size);
  72}
  73
  74/**
  75 * seq_buf_get_buf - get buffer to write arbitrary data to
  76 * @s: the seq_buf handle
  77 * @bufp: the beginning of the buffer is stored here
  78 *
  79 * Return the number of bytes available in the buffer, or zero if
  80 * there's no space.
  81 */
  82static inline size_t seq_buf_get_buf(struct seq_buf *s, char **bufp)
  83{
  84        WARN_ON(s->len > s->size + 1);
  85
  86        if (s->len < s->size) {
  87                *bufp = s->buffer + s->len;
  88                return s->size - s->len;
  89        }
  90
  91        *bufp = NULL;
  92        return 0;
  93}
  94
  95/**
  96 * seq_buf_commit - commit data to the buffer
  97 * @s: the seq_buf handle
  98 * @num: the number of bytes to commit
  99 *
 100 * Commit @num bytes of data written to a buffer previously acquired
 101 * by seq_buf_get.  To signal an error condition, or that the data
 102 * didn't fit in the available space, pass a negative @num value.
 103 */
 104static inline void seq_buf_commit(struct seq_buf *s, int num)
 105{
 106        if (num < 0) {
 107                seq_buf_set_overflow(s);
 108        } else {
 109                /* num must be negative on overflow */
 110                BUG_ON(s->len + num > s->size);
 111                s->len += num;
 112        }
 113}
 114
 115extern __printf(2, 3)
 116int seq_buf_printf(struct seq_buf *s, const char *fmt, ...);
 117extern __printf(2, 0)
 118int seq_buf_vprintf(struct seq_buf *s, const char *fmt, va_list args);
 119extern int seq_buf_print_seq(struct seq_file *m, struct seq_buf *s);
 120extern int seq_buf_to_user(struct seq_buf *s, char __user *ubuf,
 121                           int cnt);
 122extern int seq_buf_puts(struct seq_buf *s, const char *str);
 123extern int seq_buf_putc(struct seq_buf *s, unsigned char c);
 124extern int seq_buf_putmem(struct seq_buf *s, const void *mem, unsigned int len);
 125extern int seq_buf_putmem_hex(struct seq_buf *s, const void *mem,
 126                              unsigned int len);
 127extern int seq_buf_path(struct seq_buf *s, const struct path *path, const char *esc);
 128extern int seq_buf_hex_dump(struct seq_buf *s, const char *prefix_str,
 129                            int prefix_type, int rowsize, int groupsize,
 130                            const void *buf, size_t len, bool ascii);
 131
 132#ifdef CONFIG_BINARY_PRINTF
 133extern int
 134seq_buf_bprintf(struct seq_buf *s, const char *fmt, const u32 *binary);
 135#endif
 136
 137#endif /* _LINUX_SEQ_BUF_H */
 138