PatchworkOS
Loading...
Searching...
No Matches
concat.c
Go to the documentation of this file.
2
4#include <kernel/log/log.h>
5
6#include <errno.h>
7
9{
10 if (source->type == AML_INTEGER)
11 {
12 *out = source->integer.value;
13 return 0;
14 }
15 else if (source->type == AML_STRING || source->type == AML_BUFFER)
16 {
17 aml_object_t* temp = NULL;
18 if (aml_convert_source(state, source, &temp, AML_INTEGER) == ERR)
19 {
20 return ERR;
21 }
22
23 *out = temp->integer.value;
24 DEREF(temp);
25 return 0;
26 }
27 else
28 {
29 errno = EINVAL;
30 return ERR;
31 }
32}
33
34static uint64_t aml_concat_resolve_to_string(aml_state_t* state, aml_object_t* source, const char** outStr,
35 aml_object_t** outTemp)
36{
37 if (source->type == AML_STRING)
38 {
39 *outStr = source->string.content;
40 *outTemp = NULL;
41 return 0;
42 }
43 else if (source->type == AML_INTEGER || source->type == AML_BUFFER)
44 {
45 aml_object_t* temp = NULL;
46 if (aml_convert_source(state, source, &temp, AML_STRING) == ERR)
47 {
48 return ERR;
49 }
50
51 *outStr = temp->string.content;
52 *outTemp = temp; // Caller must deref
53 return 0;
54 }
55 else if (source->type == AML_UNINITIALIZED)
56 {
57 *outStr = "Uninitialized Object";
58 *outTemp = NULL;
59 return 0;
60 }
61 else if (source->type == AML_PACKAGE)
62 {
63 *outStr = "Package";
64 *outTemp = NULL;
65 return 0;
66 }
67 else if (source->type == AML_FIELD_UNIT)
68 {
69 *outStr = "Field Unit";
70 *outTemp = NULL;
71 return 0;
72 }
73 else if (source->type == AML_DEVICE)
74 {
75 *outStr = "Device";
76 *outTemp = NULL;
77 return 0;
78 }
79 else if (source->type == AML_EVENT)
80 {
81 *outStr = "Event";
82 *outTemp = NULL;
83 return 0;
84 }
85 else if (source->type == AML_METHOD)
86 {
87 *outStr = "Control Method";
88 *outTemp = NULL;
89 return 0;
90 }
91 else if (source->type == AML_MUTEX)
92 {
93 *outStr = "Mutex";
94 *outTemp = NULL;
95 return 0;
96 }
97 else if (source->type == AML_OPERATION_REGION)
98 {
99 *outStr = "Operation Region";
100 *outTemp = NULL;
101 return 0;
102 }
103 else if (source->type == AML_POWER_RESOURCE)
104 {
105 *outStr = "Power Resource";
106 *outTemp = NULL;
107 return 0;
108 }
109 else if (source->type == AML_PROCESSOR)
110 {
111 *outStr = "Processor";
112 *outTemp = NULL;
113 return 0;
114 }
115 else if (source->type == AML_THERMAL_ZONE)
116 {
117 *outStr = "Thermal Zone";
118 *outTemp = NULL;
119 return 0;
120 }
121 else if (source->type == AML_BUFFER_FIELD)
122 {
123 *outStr = "Buffer Field";
124 *outTemp = NULL;
125 return 0;
126 }
127 else if (source->type == AML_DEBUG_OBJECT)
128 {
129 *outStr = "Debug Object";
130 *outTemp = NULL;
131 return 0;
132 }
133 else
134 {
135 errno = EINVAL;
136 return ERR;
137 }
138}
139
141 uint64_t* outLen, aml_object_t** outTemp)
142{
143 if (source->type == AML_BUFFER)
144 {
145 *outBuf = source->buffer.content;
146 *outLen = source->buffer.length;
147 *outTemp = NULL;
148 return 0;
149 }
150 else if (source->type == AML_INTEGER || source->type == AML_STRING)
151 {
152 aml_object_t* temp = NULL;
153 if (aml_convert_source(state, source, &temp, AML_BUFFER) == ERR)
154 {
155 return ERR;
156 }
157
158 *outBuf = temp->buffer.content;
159 *outLen = temp->buffer.length;
160 *outTemp = temp; // Caller must deref
161 return 0;
162 }
163 else
164 {
165 // The spec seems a bit vague on this. But my assumption is that when resolving other types to a buffer,
166 // we first convert them to a string, then take the string's bytes as the buffer content.
167 const char* str;
168 if (aml_concat_resolve_to_string(state, source, &str, outTemp) == ERR)
169 {
170 return ERR;
171 }
172
173 *outBuf = (uint8_t*)str;
174 *outLen = strlen(str);
175 return 0;
176 }
177}
178
180 aml_object_t* result)
181{
182 assert(source1->type == AML_INTEGER);
183 aml_integer_t value1 = source1->integer.value;
184 aml_integer_t value2;
185 if (aml_concat_resolve_to_integer(state, source2, &value2) == ERR)
186 {
187 return ERR;
188 }
189
190 if (aml_buffer_set_empty(result, aml_integer_byte_size() * 2) == ERR)
191 {
192 return ERR;
193 }
194 memcpy(result->buffer.content, &value1, aml_integer_byte_size());
196
197 return 0;
198}
199
201 aml_object_t* result)
202{
203 assert(source1->type == AML_STRING);
204 const char* str1 = source1->string.content;
205 const char* str2;
206 aml_object_t* temp2 = NULL;
207 if (aml_concat_resolve_to_string(state, source2, &str2, &temp2) == ERR)
208 {
209 return ERR;
210 }
211 DEREF_DEFER(temp2);
212
213 size_t len1 = strlen(str1);
214 size_t len2 = strlen(str2);
215
216 if (aml_string_set_empty(result, len1 + len2) == ERR)
217 {
218 return ERR;
219 }
220 memcpy(result->string.content, str1, len1);
221 memcpy(result->string.content + len1, str2, len2);
222
223 return 0;
224}
225
227 aml_object_t* result)
228{
229 assert(source1->type == AML_BUFFER);
230 uint8_t* buf1 = source1->buffer.content;
231 uint64_t len1 = source1->buffer.length;
232 uint8_t* buf2;
233 uint64_t len2;
234 aml_object_t* temp2 = NULL;
235 if (aml_concat_resolve_to_buffer(state, source2, &buf2, &len2, &temp2) == ERR)
236 {
237 return ERR;
238 }
239 DEREF_DEFER(temp2);
240
241 if (aml_buffer_set_empty(result, len1 + len2) == ERR)
242 {
243 return ERR;
244 }
245 memcpy(result->buffer.content, buf1, len1);
246 memcpy(result->buffer.content + len1, buf2, len2);
247
248 return 0;
249}
250
252 aml_object_t* result)
253{
254 const char* str1;
255 aml_object_t* temp1 = NULL;
256 if (aml_concat_resolve_to_string(state, source1, &str1, &temp1) == ERR)
257 {
258 return ERR;
259 }
260 DEREF_DEFER(temp1);
261
262 const char* str2;
263 aml_object_t* temp2 = NULL;
264 if (aml_concat_resolve_to_string(state, source2, &str2, &temp2) == ERR)
265 {
266 return ERR;
267 }
268 DEREF_DEFER(temp2);
269
270 size_t len1 = strlen(str1);
271 size_t len2 = strlen(str2);
272
273 if (aml_string_set_empty(result, len1 + len2) == ERR)
274 {
275 return ERR;
276 }
277 memcpy(result->string.content, str1, len1);
278 memcpy(result->string.content + len1, str2, len2);
279
280 return 0;
281}
282
284{
285 if (source1 == NULL || source2 == NULL || result == NULL)
286 {
287 errno = EINVAL;
288 return ERR;
289 }
290
291 if (source1->type == AML_UNINITIALIZED || source2->type == AML_UNINITIALIZED)
292 {
293 errno = EINVAL;
294 return ERR;
295 }
296
297 switch (source1->type)
298 {
299 case AML_INTEGER:
300 return aml_concat_integer(state, source1, source2, result);
301 case AML_STRING:
302 return aml_concat_string(state, source1, source2, result);
303 case AML_BUFFER:
304 return aml_concat_buffer(state, source1, source2, result);
305 default:
306 return aml_concat_other_types(state, source1, source2, result);
307 }
308}
#define assert(expression)
Definition assert.h:29
static uint64_t aml_concat_buffer(aml_state_t *state, aml_object_t *source1, aml_object_t *source2, aml_object_t *result)
Definition concat.c:226
static uint64_t aml_concat_integer(aml_state_t *state, aml_object_t *source1, aml_object_t *source2, aml_object_t *result)
Definition concat.c:179
static uint64_t aml_concat_string(aml_state_t *state, aml_object_t *source1, aml_object_t *source2, aml_object_t *result)
Definition concat.c:200
static uint64_t aml_concat_resolve_to_buffer(aml_state_t *state, aml_object_t *source, uint8_t **outBuf, uint64_t *outLen, aml_object_t **outTemp)
Definition concat.c:140
static uint64_t aml_concat_resolve_to_integer(aml_state_t *state, aml_object_t *source, aml_integer_t *out)
Definition concat.c:8
uint64_t aml_concat(aml_state_t *state, aml_object_t *source1, aml_object_t *source2, aml_object_t *result)
Concatenates two objects according to the rules in section 19.6.12 of the ACPI specification.
Definition concat.c:283
static uint64_t aml_concat_other_types(aml_state_t *state, aml_object_t *source1, aml_object_t *source2, aml_object_t *result)
Definition concat.c:251
static uint64_t aml_concat_resolve_to_string(aml_state_t *state, aml_object_t *source, const char **outStr, aml_object_t **outTemp)
Definition concat.c:34
uint64_t aml_convert_source(aml_state_t *state, aml_object_t *src, aml_object_t **dest, aml_type_t allowedTypes)
Performs a "Implicit Source Operand Conversion" acording to the rules in section 19....
Definition convert.c:541
uint64_t aml_integer_t
AML Integer type.
Definition integer.h:20
uint8_t aml_integer_byte_size(void) PURE_FUNC
Get the byte size of an AML integer.
Definition integer.c:22
uint64_t aml_buffer_set_empty(aml_object_t *object, uint64_t length)
Set a object as an empty buffer with the given length.
Definition object.c:487
uint64_t aml_string_set_empty(aml_object_t *object, uint64_t length)
Set a object as an empty string with the given length.
Definition object.c:955
@ AML_METHOD
Definition object.h:75
@ AML_BUFFER_FIELD
Definition object.h:60
@ AML_PROCESSOR
Definition object.h:81
@ AML_PACKAGE
Definition object.h:79
@ AML_OPERATION_REGION
Definition object.h:78
@ AML_DEBUG_OBJECT
Definition object.h:61
@ AML_STRING
Definition object.h:83
@ AML_THERMAL_ZONE
Definition object.h:84
@ AML_FIELD_UNIT
Definition object.h:64
@ AML_POWER_RESOURCE
Definition object.h:80
@ AML_EVENT
Definition object.h:63
@ AML_DEVICE
Definition object.h:62
@ AML_MUTEX
Definition object.h:76
@ AML_INTEGER
Definition object.h:65
@ AML_UNINITIALIZED
Definition object.h:58
@ AML_BUFFER
Definition object.h:59
#define DEREF_DEFER(ptr)
RAII-style cleanup for scoped references.
Definition ref.h:54
#define DEREF(ptr)
Decrement reference count.
Definition ref.h:80
#define EINVAL
Invalid argument.
Definition errno.h:142
#define errno
Error number variable.
Definition errno.h:27
#define NULL
Pointer error value.
Definition NULL.h:23
#define ERR
Integer error value.
Definition ERR.h:17
__UINT64_TYPE__ uint64_t
Definition stdint.h:17
__UINT8_TYPE__ uint8_t
Definition stdint.h:11
_PUBLIC void * memcpy(void *_RESTRICT s1, const void *_RESTRICT s2, size_t n)
Definition memcpy.c:4
_PUBLIC size_t strlen(const char *s)
Definition strlen.c:3
uint64_t length
Definition object.h:214
uint8_t * content
Definition object.h:213
aml_integer_t value
Definition object.h:266
ACPI object.
Definition object.h:425
aml_buffer_obj_t buffer
Definition object.h:431
aml_integer_obj_t integer
Definition object.h:435
aml_string_obj_t string
Definition object.h:444
AML State.
Definition state.h:25
char * content
Definition object.h:370