ReactOS 0.4.16-dev-334-g4d9f67c
exconcat.c File Reference
#include "acpi.h"
#include "accommon.h"
#include "acinterp.h"
#include "amlresrc.h"
Include dependency graph for exconcat.c:

Go to the source code of this file.

Macros

#define _COMPONENT   ACPI_EXECUTER
 

Functions

static ACPI_STATUS AcpiExConvertToObjectTypeString (ACPI_OPERAND_OBJECT *ObjDesc, ACPI_OPERAND_OBJECT **ResultDesc)
 
ACPI_STATUS AcpiExDoConcatenate (ACPI_OPERAND_OBJECT *Operand0, ACPI_OPERAND_OBJECT *Operand1, ACPI_OPERAND_OBJECT **ActualReturnDesc, ACPI_WALK_STATE *WalkState)
 
ACPI_STATUS AcpiExConcatTemplate (ACPI_OPERAND_OBJECT *Operand0, ACPI_OPERAND_OBJECT *Operand1, ACPI_OPERAND_OBJECT **ActualReturnDesc, ACPI_WALK_STATE *WalkState)
 

Macro Definition Documentation

◆ _COMPONENT

#define _COMPONENT   ACPI_EXECUTER

Definition at line 50 of file exconcat.c.

Function Documentation

◆ AcpiExConcatTemplate()

ACPI_STATUS AcpiExConcatTemplate ( ACPI_OPERAND_OBJECT Operand0,
ACPI_OPERAND_OBJECT Operand1,
ACPI_OPERAND_OBJECT **  ActualReturnDesc,
ACPI_WALK_STATE WalkState 
)

Definition at line 388 of file exconcat.c.

393{
395 ACPI_OPERAND_OBJECT *ReturnDesc;
396 UINT8 *NewBuf;
397 UINT8 *EndTag;
398 ACPI_SIZE Length0;
399 ACPI_SIZE Length1;
400 ACPI_SIZE NewLength;
401
402
403 ACPI_FUNCTION_TRACE (ExConcatTemplate);
404
405
406 /*
407 * Find the EndTag descriptor in each resource template.
408 * Note1: returned pointers point TO the EndTag, not past it.
409 * Note2: zero-length buffers are allowed; treated like one EndTag
410 */
411
412 /* Get the length of the first resource template */
413
414 Status = AcpiUtGetResourceEndTag (Operand0, &EndTag);
415 if (ACPI_FAILURE (Status))
416 {
418 }
419
420 Length0 = ACPI_PTR_DIFF (EndTag, Operand0->Buffer.Pointer);
421
422 /* Get the length of the second resource template */
423
424 Status = AcpiUtGetResourceEndTag (Operand1, &EndTag);
425 if (ACPI_FAILURE (Status))
426 {
428 }
429
430 Length1 = ACPI_PTR_DIFF (EndTag, Operand1->Buffer.Pointer);
431
432 /* Combine both lengths, minimum size will be 2 for EndTag */
433
434 NewLength = Length0 + Length1 + sizeof (AML_RESOURCE_END_TAG);
435
436 /* Create a new buffer object for the result (with one EndTag) */
437
438 ReturnDesc = AcpiUtCreateBufferObject (NewLength);
439 if (!ReturnDesc)
440 {
442 }
443
444 /*
445 * Copy the templates to the new buffer, 0 first, then 1 follows. One
446 * EndTag descriptor is copied from Operand1.
447 */
448 NewBuf = ReturnDesc->Buffer.Pointer;
449 memcpy (NewBuf, Operand0->Buffer.Pointer, Length0);
450 memcpy (NewBuf + Length0, Operand1->Buffer.Pointer, Length1);
451
452 /* Insert EndTag and set the checksum to zero, means "ignore checksum" */
453
454 NewBuf[NewLength - 1] = 0;
455 NewBuf[NewLength - 2] = ACPI_RESOURCE_NAME_END_TAG | 1;
456
457 /* Return the completed resource template */
458
459 *ActualReturnDesc = ReturnDesc;
461}
INT Length1
Definition: FsRtlDissect.c:15
static USHORT USHORT * NewLength
unsigned char UINT8
#define ACPI_FAILURE(a)
Definition: acexcep.h:95
#define AE_NO_MEMORY
Definition: acexcep.h:112
#define AE_OK
Definition: acexcep.h:97
#define ACPI_RESOURCE_NAME_END_TAG
Definition: aclocal.h:1323
#define return_ACPI_STATUS(s)
Definition: acoutput.h:496
#define ACPI_FUNCTION_TRACE(a)
Definition: acoutput.h:480
UINT32 ACPI_STATUS
Definition: actypes.h:460
#define ACPI_PTR_DIFF(a, b)
Definition: actypes.h:548
ACPI_STATUS AcpiUtGetResourceEndTag(ACPI_OPERAND_OBJECT *ObjDesc, UINT8 **EndTag)
Definition: utresrc.c:636
ACPI_OPERAND_OBJECT * AcpiUtCreateBufferObject(ACPI_SIZE BufferSize)
Definition: utobject.c:258
struct aml_resource_end_tag AML_RESOURCE_END_TAG
Status
Definition: gdiplustypes.h:25
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
ACPI_OBJECT_BUFFER Buffer
Definition: acobject.h:522

Referenced by AcpiExOpcode_2A_1T_1R().

◆ AcpiExConvertToObjectTypeString()

static ACPI_STATUS AcpiExConvertToObjectTypeString ( ACPI_OPERAND_OBJECT ObjDesc,
ACPI_OPERAND_OBJECT **  ResultDesc 
)
static

Definition at line 346 of file exconcat.c.

349{
350 ACPI_OPERAND_OBJECT *ReturnDesc;
351 const char *TypeString;
352
353
354 TypeString = AcpiUtGetTypeName (ObjDesc->Common.Type);
355
356 ReturnDesc = AcpiUtCreateStringObject (
357 ((ACPI_SIZE) strlen (TypeString) + 9)); /* 9 For "[ Object]" */
358 if (!ReturnDesc)
359 {
360 return (AE_NO_MEMORY);
361 }
362
363 strcpy (ReturnDesc->String.Pointer, "[");
364 strcat (ReturnDesc->String.Pointer, TypeString);
365 strcat (ReturnDesc->String.Pointer, " Object]");
366
367 *ResultDesc = ReturnDesc;
368 return (AE_OK);
369}
char * strcat(char *DstString, const char *SrcString)
Definition: utclib.c:568
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
const char * AcpiUtGetTypeName(ACPI_OBJECT_TYPE Type)
Definition: utdecode.c:250
ACPI_OPERAND_OBJECT * AcpiUtCreateStringObject(ACPI_SIZE StringSize)
Definition: utobject.c:320
ACPI_OBJECT_COMMON Common
Definition: acobject.h:519
ACPI_OBJECT_STRING String
Definition: acobject.h:521

Referenced by AcpiExDoConcatenate().

◆ AcpiExDoConcatenate()

ACPI_STATUS AcpiExDoConcatenate ( ACPI_OPERAND_OBJECT Operand0,
ACPI_OPERAND_OBJECT Operand1,
ACPI_OPERAND_OBJECT **  ActualReturnDesc,
ACPI_WALK_STATE WalkState 
)

Definition at line 85 of file exconcat.c.

90{
91 ACPI_OPERAND_OBJECT *LocalOperand0 = Operand0;
92 ACPI_OPERAND_OBJECT *LocalOperand1 = Operand1;
93 ACPI_OPERAND_OBJECT *TempOperand1 = NULL;
94 ACPI_OPERAND_OBJECT *ReturnDesc;
95 char *Buffer;
96 ACPI_OBJECT_TYPE Operand0Type;
97 ACPI_OBJECT_TYPE Operand1Type;
99
100
101 ACPI_FUNCTION_TRACE (ExDoConcatenate);
102
103
104 /* Operand 0 preprocessing */
105
106 switch (Operand0->Common.Type)
107 {
109 case ACPI_TYPE_STRING:
110 case ACPI_TYPE_BUFFER:
111
112 Operand0Type = Operand0->Common.Type;
113 break;
114
115 default:
116
117 /* For all other types, get the "object type" string */
118
120 Operand0, &LocalOperand0);
121 if (ACPI_FAILURE (Status))
122 {
123 goto Cleanup;
124 }
125
126 Operand0Type = ACPI_TYPE_STRING;
127 break;
128 }
129
130 /* Operand 1 preprocessing */
131
132 switch (Operand1->Common.Type)
133 {
135 case ACPI_TYPE_STRING:
136 case ACPI_TYPE_BUFFER:
137
138 Operand1Type = Operand1->Common.Type;
139 break;
140
141 default:
142
143 /* For all other types, get the "object type" string */
144
146 Operand1, &LocalOperand1);
147 if (ACPI_FAILURE (Status))
148 {
149 goto Cleanup;
150 }
151
152 Operand1Type = ACPI_TYPE_STRING;
153 break;
154 }
155
156 /*
157 * Convert the second operand if necessary. The first operand (0)
158 * determines the type of the second operand (1) (See the Data Types
159 * section of the ACPI specification). Both object types are
160 * guaranteed to be either Integer/String/Buffer by the operand
161 * resolution mechanism.
162 */
163 switch (Operand0Type)
164 {
166
167 Status = AcpiExConvertToInteger (LocalOperand1, &TempOperand1,
169 break;
170
171 case ACPI_TYPE_BUFFER:
172
173 Status = AcpiExConvertToBuffer (LocalOperand1, &TempOperand1);
174 break;
175
176 case ACPI_TYPE_STRING:
177
178 switch (Operand1Type)
179 {
181 case ACPI_TYPE_STRING:
182 case ACPI_TYPE_BUFFER:
183
184 /* Other types have already been converted to string */
185
187 LocalOperand1, &TempOperand1, ACPI_IMPLICIT_CONVERT_HEX);
188 break;
189
190 default:
191
192 Status = AE_OK;
193 break;
194 }
195 break;
196
197 default:
198
199 ACPI_ERROR ((AE_INFO, "Invalid object type: 0x%X",
200 Operand0->Common.Type));
202 }
203
204 if (ACPI_FAILURE (Status))
205 {
206 goto Cleanup;
207 }
208
209 /* Take care with any newly created operand objects */
210
211 if ((LocalOperand1 != Operand1) &&
212 (LocalOperand1 != TempOperand1))
213 {
214 AcpiUtRemoveReference (LocalOperand1);
215 }
216
217 LocalOperand1 = TempOperand1;
218
219 /*
220 * Both operands are now known to be the same object type
221 * (Both are Integer, String, or Buffer), and we can now perform
222 * the concatenation.
223 *
224 * There are three cases to handle, as per the ACPI spec:
225 *
226 * 1) Two Integers concatenated to produce a new Buffer
227 * 2) Two Strings concatenated to produce a new String
228 * 3) Two Buffers concatenated to produce a new Buffer
229 */
230 switch (Operand0Type)
231 {
233
234 /* Result of two Integers is a Buffer */
235 /* Need enough buffer space for two integers */
236
237 ReturnDesc = AcpiUtCreateBufferObject (
238 (ACPI_SIZE) ACPI_MUL_2 (AcpiGbl_IntegerByteWidth));
239 if (!ReturnDesc)
240 {
242 goto Cleanup;
243 }
244
245 Buffer = (char *) ReturnDesc->Buffer.Pointer;
246
247 /* Copy the first integer, LSB first */
248
249 memcpy (Buffer, &Operand0->Integer.Value,
250 AcpiGbl_IntegerByteWidth);
251
252 /* Copy the second integer (LSB first) after the first */
253
254 memcpy (Buffer + AcpiGbl_IntegerByteWidth,
255 &LocalOperand1->Integer.Value, AcpiGbl_IntegerByteWidth);
256 break;
257
258 case ACPI_TYPE_STRING:
259
260 /* Result of two Strings is a String */
261
262 ReturnDesc = AcpiUtCreateStringObject (
263 ((ACPI_SIZE) LocalOperand0->String.Length +
264 LocalOperand1->String.Length));
265 if (!ReturnDesc)
266 {
268 goto Cleanup;
269 }
270
271 Buffer = ReturnDesc->String.Pointer;
272
273 /* Concatenate the strings */
274
275 strcpy (Buffer, LocalOperand0->String.Pointer);
276 strcat (Buffer, LocalOperand1->String.Pointer);
277 break;
278
279 case ACPI_TYPE_BUFFER:
280
281 /* Result of two Buffers is a Buffer */
282
283 ReturnDesc = AcpiUtCreateBufferObject (
284 ((ACPI_SIZE) Operand0->Buffer.Length +
285 LocalOperand1->Buffer.Length));
286 if (!ReturnDesc)
287 {
289 goto Cleanup;
290 }
291
292 Buffer = (char *) ReturnDesc->Buffer.Pointer;
293
294 /* Concatenate the buffers */
295
296 memcpy (Buffer, Operand0->Buffer.Pointer,
297 Operand0->Buffer.Length);
298 memcpy (Buffer + Operand0->Buffer.Length,
299 LocalOperand1->Buffer.Pointer,
300 LocalOperand1->Buffer.Length);
301 break;
302
303 default:
304
305 /* Invalid object type, should not happen here */
306
307 ACPI_ERROR ((AE_INFO, "Invalid object type: 0x%X",
308 Operand0->Common.Type));
310 goto Cleanup;
311 }
312
313 *ActualReturnDesc = ReturnDesc;
314
315Cleanup:
316 if (LocalOperand0 != Operand0)
317 {
318 AcpiUtRemoveReference (LocalOperand0);
319 }
320
321 if (LocalOperand1 != Operand1)
322 {
323 AcpiUtRemoveReference (LocalOperand1);
324 }
325
327}
#define AE_AML_INTERNAL
Definition: acexcep.h:194
#define ACPI_IMPLICIT_CONVERT_HEX
Definition: acinterp.h:126
#define ACPI_MUL_2(a)
Definition: acmacros.h:207
#define ACPI_ERROR(plist)
Definition: acoutput.h:240
#define AE_INFO
Definition: acoutput.h:230
#define ACPI_TYPE_STRING
Definition: actypes.h:689
UINT32 ACPI_OBJECT_TYPE
Definition: actypes.h:685
#define ACPI_TYPE_BUFFER
Definition: actypes.h:690
#define ACPI_TYPE_INTEGER
Definition: actypes.h:688
void AcpiUtRemoveReference(ACPI_OPERAND_OBJECT *Object)
Definition: utdelete.c:790
#define ACPI_IMPLICIT_CONVERSION
Definition: acutils.h:145
Definition: bufpool.h:45
#define NULL
Definition: types.h:112
static const WCHAR Cleanup[]
Definition: register.c:80
static ACPI_STATUS AcpiExConvertToObjectTypeString(ACPI_OPERAND_OBJECT *ObjDesc, ACPI_OPERAND_OBJECT **ResultDesc)
Definition: exconcat.c:346
ACPI_STATUS AcpiExConvertToBuffer(ACPI_OPERAND_OBJECT *ObjDesc, ACPI_OPERAND_OBJECT **ResultDesc)
Definition: exconvrt.c:224
ACPI_STATUS AcpiExConvertToInteger(ACPI_OPERAND_OBJECT *ObjDesc, ACPI_OPERAND_OBJECT **ResultDesc, UINT32 ImplicitConversion)
Definition: exconvrt.c:79
ACPI_STATUS AcpiExConvertToString(ACPI_OPERAND_OBJECT *ObjDesc, ACPI_OPERAND_OBJECT **ResultDesc, UINT32 Type)
Definition: exconvrt.c:440
ACPI_OBJECT_INTEGER Integer
Definition: acobject.h:520

Referenced by AcpiExOpcode_2A_1T_1R().