]> Git Repo - u-boot.git/blob - lib/abuf.c
Merge patch series "board: siemens: clean up subfolders"
[u-boot.git] / lib / abuf.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Handles a buffer that can be allocated and freed
4  *
5  * Copyright 2021 Google LLC
6  * Written by Simon Glass <[email protected]>
7  */
8
9 #ifndef USE_HOSTCC
10 #include <malloc.h>
11 #include <mapmem.h>
12 #include <string.h>
13 #endif
14
15 #include <abuf.h>
16
17 void abuf_set(struct abuf *abuf, void *data, size_t size)
18 {
19         abuf_uninit(abuf);
20         abuf->data = data;
21         abuf->size = size;
22 }
23
24 #ifndef USE_HOSTCC
25 void abuf_map_sysmem(struct abuf *abuf, ulong addr, size_t size)
26 {
27         abuf_set(abuf, map_sysmem(addr, size), size);
28 }
29 #else
30 /* copied from lib/string.c for convenience */
31 static char *memdup(const void *src, size_t len)
32 {
33         char *p;
34
35         p = malloc(len);
36         if (!p)
37                 return NULL;
38
39         memcpy(p, src, len);
40
41         return p;
42 }
43 #endif
44
45 bool abuf_realloc(struct abuf *abuf, size_t new_size)
46 {
47         void *ptr;
48
49         if (!new_size) {
50                 /* easy case, just need to uninit, freeing any allocation */
51                 abuf_uninit(abuf);
52                 return true;
53         } else if (abuf->alloced) {
54                 /* currently allocated, so need to reallocate */
55                 ptr = realloc(abuf->data, new_size);
56                 if (!ptr)
57                         return false;
58                 abuf->data = ptr;
59                 abuf->size = new_size;
60                 return true;
61         } else if (new_size <= abuf->size) {
62                 /*
63                  * not currently alloced and new size is no larger. Just update
64                  * it. Data is lost off the end if new_size < abuf->size
65                  */
66                 abuf->size = new_size;
67                 return true;
68         } else {
69                 /* not currently allocated and new size is larger. Alloc and
70                  * copy in data. The new space is not inited.
71                  */
72                 ptr = malloc(new_size);
73                 if (!ptr)
74                         return false;
75                 if (abuf->size)
76                         memcpy(ptr, abuf->data, abuf->size);
77                 abuf->data = ptr;
78                 abuf->size = new_size;
79                 abuf->alloced = true;
80                 return true;
81         }
82 }
83
84 bool abuf_realloc_inc(struct abuf *abuf, size_t inc)
85 {
86         return abuf_realloc(abuf, abuf->size + inc);
87 }
88
89 void *abuf_uninit_move(struct abuf *abuf, size_t *sizep)
90 {
91         void *ptr;
92
93         if (sizep)
94                 *sizep = abuf->size;
95         if (!abuf->size)
96                 return NULL;
97         if (abuf->alloced) {
98                 ptr = abuf->data;
99         } else {
100                 ptr = memdup(abuf->data, abuf->size);
101                 if (!ptr)
102                         return NULL;
103         }
104         /* Clear everything out so there is no record of the data */
105         abuf_init(abuf);
106
107         return ptr;
108 }
109
110 void abuf_init_set(struct abuf *abuf, void *data, size_t size)
111 {
112         abuf_init(abuf);
113         abuf_set(abuf, data, size);
114 }
115
116 void abuf_init_move(struct abuf *abuf, void *data, size_t size)
117 {
118         abuf_init_set(abuf, data, size);
119         abuf->alloced = true;
120 }
121
122 void abuf_uninit(struct abuf *abuf)
123 {
124         if (abuf->alloced)
125                 free(abuf->data);
126         abuf_init(abuf);
127 }
128
129 void abuf_init(struct abuf *abuf)
130 {
131         abuf->data = NULL;
132         abuf->size = 0;
133         abuf->alloced = false;
134 }
This page took 0.035216 seconds and 4 git commands to generate.