]> git.sesse.net Git - bcachefs-tools-debian/blob - include/linux/seq_buf.h
rust: bump rpassword to v7.x
[bcachefs-tools-debian] / include / linux / seq_buf.h
1 /* SPDX-License-Identifier: GPL-2.0 */
2 #ifndef _LINUX_SEQ_BUF_H
3 #define _LINUX_SEQ_BUF_H
4
5 #include <linux/kernel.h>
6 #include <stdarg.h>
7 #include <string.h>
8
9 /*
10  * Trace sequences are used to allow a function to call several other functions
11  * to create a string of data to use.
12  */
13
14 /**
15  * seq_buf - seq buffer structure
16  * @buffer:     pointer to the buffer
17  * @size:       size of the buffer
18  * @len:        the amount of data inside the buffer
19  * @readpos:    The next position to read in the buffer.
20  */
21 struct seq_buf {
22         char                    *buffer;
23         size_t                  size;
24         size_t                  len;
25         loff_t                  readpos;
26 };
27
28 static inline void seq_buf_clear(struct seq_buf *s)
29 {
30         s->len = 0;
31         s->readpos = 0;
32 }
33
34 static inline void
35 seq_buf_init(struct seq_buf *s, char *buf, unsigned int size)
36 {
37         s->buffer = buf;
38         s->size = size;
39         seq_buf_clear(s);
40 }
41
42 /*
43  * seq_buf have a buffer that might overflow. When this happens
44  * the len and size are set to be equal.
45  */
46 static inline bool
47 seq_buf_has_overflowed(struct seq_buf *s)
48 {
49         return s->len > s->size;
50 }
51
52 static inline void
53 seq_buf_set_overflow(struct seq_buf *s)
54 {
55         s->len = s->size + 1;
56 }
57
58 /*
59  * How much buffer is left on the seq_buf?
60  */
61 static inline unsigned int
62 seq_buf_buffer_left(struct seq_buf *s)
63 {
64         if (seq_buf_has_overflowed(s))
65                 return 0;
66
67         return s->size - s->len;
68 }
69
70 /* How much buffer was written? */
71 static inline unsigned int seq_buf_used(struct seq_buf *s)
72 {
73         return min(s->len, s->size);
74 }
75
76 /**
77  * seq_buf_terminate - Make sure buffer is nul terminated
78  * @s: the seq_buf descriptor to terminate.
79  *
80  * This makes sure that the buffer in @s is nul terminated and
81  * safe to read as a string.
82  *
83  * Note, if this is called when the buffer has overflowed, then
84  * the last byte of the buffer is zeroed, and the len will still
85  * point passed it.
86  *
87  * After this function is called, s->buffer is safe to use
88  * in string operations.
89  */
90 static inline void seq_buf_terminate(struct seq_buf *s)
91 {
92         if (WARN_ON(s->size == 0))
93                 return;
94
95         if (seq_buf_buffer_left(s))
96                 s->buffer[s->len] = 0;
97         else
98                 s->buffer[s->size - 1] = 0;
99 }
100
101 /**
102  * seq_buf_get_buf - get buffer to write arbitrary data to
103  * @s: the seq_buf handle
104  * @bufp: the beginning of the buffer is stored here
105  *
106  * Return the number of bytes available in the buffer, or zero if
107  * there's no space.
108  */
109 static inline size_t seq_buf_get_buf(struct seq_buf *s, char **bufp)
110 {
111         WARN_ON(s->len > s->size + 1);
112
113         if (s->len < s->size) {
114                 *bufp = s->buffer + s->len;
115                 return s->size - s->len;
116         }
117
118         *bufp = NULL;
119         return 0;
120 }
121
122 /**
123  * seq_buf_commit - commit data to the buffer
124  * @s: the seq_buf handle
125  * @num: the number of bytes to commit
126  *
127  * Commit @num bytes of data written to a buffer previously acquired
128  * by seq_buf_get.  To signal an error condition, or that the data
129  * didn't fit in the available space, pass a negative @num value.
130  */
131 static inline void seq_buf_commit(struct seq_buf *s, int num)
132 {
133         if (num < 0) {
134                 seq_buf_set_overflow(s);
135         } else {
136                 /* num must be negative on overflow */
137                 BUG_ON(s->len + num > s->size);
138                 s->len += num;
139         }
140 }
141
142 extern __printf(2, 3)
143 int seq_buf_printf(struct seq_buf *s, const char *fmt, ...);
144 extern __printf(2, 0)
145 int seq_buf_vprintf(struct seq_buf *s, const char *fmt, va_list args);
146 extern int seq_buf_to_user(struct seq_buf *s, char __user *ubuf,
147                            int cnt);
148 extern int seq_buf_puts(struct seq_buf *s, const char *str);
149 extern int seq_buf_putc(struct seq_buf *s, unsigned char c);
150
151 void seq_buf_human_readable_u64(struct seq_buf *, u64);
152
153 #endif /* _LINUX_SEQ_BUF_H */