forked from muralivijay/kernel_xiaomi_sm6225
-
Notifications
You must be signed in to change notification settings - Fork 0
/
buffer.h
239 lines (212 loc) · 6.35 KB
/
buffer.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
/*
* include/vservices/buffer.h
*
* Copyright (c) 2012-2018 General Dynamics
* Copyright (c) 2014 Open Kernel Labs, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This file defines simple wrapper types for strings and variable-size buffers
* that are stored inside Virtual Services message buffers.
*/
#ifndef _VSERVICES_BUFFER_H_
#define _VSERVICES_BUFFER_H_
#include <linux/types.h>
#include <linux/string.h>
#include <linux/slab.h>
struct vs_mbuf;
/**
* struct vs_string - Virtual Services fixed sized string type
* @ptr: String pointer
* @max_size: Maximum length of the string in bytes
*
* A handle to a possibly NUL-terminated string stored in a message buffer. If
* the size of the string equals to max_size, the string is not NUL-terminated.
* If the protocol does not specify an encoding, the encoding is assumed to be
* UTF-8. Wide character encodings are not supported by this type; use struct
* vs_pbuf for wide character strings.
*/
struct vs_string {
char *ptr;
size_t max_size;
};
/**
* vs_string_copyout - Copy a Virtual Services string to a C string buffer.
* @dest: C string to copy to
* @src: Virtual Services string to copy from
* @max_size: Size of the destination buffer, including the NUL terminator.
*
* The behaviour is similar to strlcpy(): that is, the copied string
* is guaranteed not to exceed the specified size (including the NUL
* terminator byte), and is guaranteed to be NUL-terminated as long as
* the size is nonzero (unlike strncpy()).
*
* The return value is the size of the input string (even if the output was
* truncated); this is to make truncation easy to detect.
*/
static inline size_t
vs_string_copyout(char *dest, const struct vs_string *src, size_t max_size)
{
size_t src_len = strnlen(src->ptr, src->max_size);
if (max_size) {
size_t dest_len = min(src_len, max_size - 1);
memcpy(dest, src->ptr, dest_len);
dest[dest_len] = '\0';
}
return src_len;
}
/**
* vs_string_copyin_len - Copy a C string, up to a given length, into a Virtual
* Services string.
* @dest: Virtual Services string to copy to
* @src: C string to copy from
* @max_size: Maximum number of bytes to copy
*
* Returns the number of bytes copied, which may be less than the input
* string's length.
*/
static inline size_t
vs_string_copyin_len(struct vs_string *dest, const char *src, size_t max_size)
{
strncpy(dest->ptr, src, min(max_size, dest->max_size));
return strnlen(dest->ptr, dest->max_size);
}
/**
* vs_string_copyin - Copy a C string into a Virtual Services string.
* @dest: Virtual Services string to copy to
* @src: C string to copy from
*
* Returns the number of bytes copied, which may be less than the input
* string's length.
*/
static inline size_t
vs_string_copyin(struct vs_string *dest, const char *src)
{
return vs_string_copyin_len(dest, src, dest->max_size);
}
/**
* vs_string_length - Return the size of the string stored in a Virtual Services
* string.
* @str: Virtual Service string to get the length of
*/
static inline size_t
vs_string_length(struct vs_string *str)
{
return strnlen(str->ptr, str->max_size);
}
/**
* vs_string_dup - Allocate a C string buffer and copy a Virtual Services string
* into it.
* @str: Virtual Services string to duplicate
*/
static inline char *
vs_string_dup(struct vs_string *str, gfp_t gfp)
{
size_t len;
char *ret;
len = strnlen(str->ptr, str->max_size) + 1;
ret = kmalloc(len, gfp);
if (ret)
vs_string_copyout(ret, str, len);
return ret;
}
/**
* vs_string_max_size - Return the maximum size of a Virtual Services string,
* not including the NUL terminator if the lenght of the
* string is equal to max_size.
*
* @str Virtual Services string to return the maximum size of.
*
* @return The maximum size of the string.
*/
static inline size_t
vs_string_max_size(struct vs_string *str)
{
return str->max_size;
}
/**
* struct vs_pbuf - Handle to a variable-size buffered payload.
* @data: Data buffer
* @size: Current size of the buffer
* @max_size: Maximum size of the buffer
*
* This is similar to struct vs_string, except that has an explicitly
* stored size rather than being null-terminated. The functions that
* return ssize_t all return the new size of the modified buffer, and
* will return a negative size if the buffer overflows.
*/
struct vs_pbuf {
void *data;
size_t size, max_size;
};
/**
* vs_pbuf_size - Get the size of a pbuf
* @pbuf: pbuf to get the size of
*/
static inline size_t vs_pbuf_size(const struct vs_pbuf *pbuf)
{
return pbuf->size;
}
/**
* vs_pbuf_data - Get the data pointer for a a pbuf
* @pbuf: pbuf to get the data pointer for
*/
static inline const void *vs_pbuf_data(const struct vs_pbuf *pbuf)
{
return pbuf->data;
}
/**
* vs_pbuf_resize - Resize a pbuf
* @pbuf: pbuf to resize
* @size: New size
*/
static inline ssize_t vs_pbuf_resize(struct vs_pbuf *pbuf, size_t size)
{
if (size > pbuf->max_size)
return -EOVERFLOW;
pbuf->size = size;
return size;
}
/**
* vs_pbuf_copyin - Copy data into a pbuf
* @pbuf: pbuf to copy data into
* @offset: Offset to copy data to
* @data: Pointer to data to copy into the pbuf
* @nbytes: Number of bytes to copy into the pbuf
*/
static inline ssize_t vs_pbuf_copyin(struct vs_pbuf *pbuf, off_t offset,
const void *data, size_t nbytes)
{
if (offset + nbytes > pbuf->size)
return -EOVERFLOW;
memcpy(pbuf->data + offset, data, nbytes);
return nbytes;
}
/**
* vs_pbuf_append - Append data to a pbuf
* @pbuf: pbuf to append to
* @data: Pointer to data to append to the pbuf
* @nbytes: Number of bytes to append
*/
static inline ssize_t vs_pbuf_append(struct vs_pbuf *pbuf,
const void *data, size_t nbytes)
{
if (pbuf->size + nbytes > pbuf->max_size)
return -EOVERFLOW;
memcpy(pbuf->data + pbuf->size, data, nbytes);
pbuf->size += nbytes;
return pbuf->size;
}
/**
* vs_pbuf_dup_string - Duplicate the contents of a pbuf as a C string. The
* string is allocated and must be freed using kfree.
* @pbuf: pbuf to convert
* @gfp_flags: GFP flags for the string allocation
*/
static inline char *vs_pbuf_dup_string(struct vs_pbuf *pbuf, gfp_t gfp_flags)
{
return kstrndup(pbuf->data, pbuf->size, gfp_flags);
}
#endif /* _VSERVICES_BUFFER_H_ */