]> Git Repo - J-u-boot.git/blame - lib/abuf.c
Merge tag 'u-boot-imx-master-20250127' of https://gitlab.denx.de/u-boot/custodians...
[J-u-boot.git] / lib / abuf.c
CommitLineData
67bc59df
SG
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
90ad4e28 9#ifndef USE_HOSTCC
67bc59df
SG
10#include <malloc.h>
11#include <mapmem.h>
12#include <string.h>
90ad4e28
SG
13#endif
14
15#include <abuf.h>
67bc59df
SG
16
17void 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
90ad4e28 24#ifndef USE_HOSTCC
67bc59df
SG
25void abuf_map_sysmem(struct abuf *abuf, ulong addr, size_t size)
26{
27 abuf_set(abuf, map_sysmem(addr, size), size);
28}
c487381d
SG
29
30ulong abuf_addr(const struct abuf *abuf)
31{
32 return map_to_sysmem(abuf->data);
33}
34
90ad4e28
SG
35#else
36/* copied from lib/string.c for convenience */
37static char *memdup(const void *src, size_t len)
38{
39 char *p;
40
41 p = malloc(len);
42 if (!p)
43 return NULL;
44
45 memcpy(p, src, len);
46
47 return p;
48}
49#endif
67bc59df
SG
50
51bool abuf_realloc(struct abuf *abuf, size_t new_size)
52{
53 void *ptr;
54
55 if (!new_size) {
56 /* easy case, just need to uninit, freeing any allocation */
57 abuf_uninit(abuf);
58 return true;
59 } else if (abuf->alloced) {
60 /* currently allocated, so need to reallocate */
61 ptr = realloc(abuf->data, new_size);
62 if (!ptr)
63 return false;
64 abuf->data = ptr;
65 abuf->size = new_size;
66 return true;
67 } else if (new_size <= abuf->size) {
68 /*
69 * not currently alloced and new size is no larger. Just update
70 * it. Data is lost off the end if new_size < abuf->size
71 */
72 abuf->size = new_size;
73 return true;
74 } else {
75 /* not currently allocated and new size is larger. Alloc and
76 * copy in data. The new space is not inited.
77 */
99aca9ef 78 ptr = malloc(new_size);
67bc59df
SG
79 if (!ptr)
80 return false;
99aca9ef
SG
81 if (abuf->size)
82 memcpy(ptr, abuf->data, abuf->size);
67bc59df
SG
83 abuf->data = ptr;
84 abuf->size = new_size;
85 abuf->alloced = true;
86 return true;
87 }
88}
89
34ecba1f
SG
90bool abuf_realloc_inc(struct abuf *abuf, size_t inc)
91{
92 return abuf_realloc(abuf, abuf->size + inc);
93}
94
67bc59df
SG
95void *abuf_uninit_move(struct abuf *abuf, size_t *sizep)
96{
97 void *ptr;
98
99 if (sizep)
100 *sizep = abuf->size;
101 if (!abuf->size)
102 return NULL;
103 if (abuf->alloced) {
104 ptr = abuf->data;
105 } else {
106 ptr = memdup(abuf->data, abuf->size);
107 if (!ptr)
108 return NULL;
109 }
110 /* Clear everything out so there is no record of the data */
111 abuf_init(abuf);
112
113 return ptr;
114}
115
116void abuf_init_set(struct abuf *abuf, void *data, size_t size)
117{
118 abuf_init(abuf);
119 abuf_set(abuf, data, size);
120}
121
7ba7c1dd
SG
122void abuf_init_const(struct abuf *abuf, const void *data, size_t size)
123{
124 /* for now there is no flag indicating that the abuf data is constant */
125 abuf_init_set(abuf, (void *)data, size);
126}
127
67bc59df
SG
128void abuf_init_move(struct abuf *abuf, void *data, size_t size)
129{
130 abuf_init_set(abuf, data, size);
131 abuf->alloced = true;
132}
133
134void abuf_uninit(struct abuf *abuf)
135{
136 if (abuf->alloced)
137 free(abuf->data);
138 abuf_init(abuf);
139}
140
141void abuf_init(struct abuf *abuf)
142{
143 abuf->data = NULL;
144 abuf->size = 0;
145 abuf->alloced = false;
146}
This page took 0.128518 seconds and 4 git commands to generate.