1 /***************************************************************************************************
3 Zyan Disassembler Library (Zydis)
5 Original Author : Florian Bernd
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal
9 * in the Software without restriction, including without limitation the rights
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 * copies of the Software, and to permit persons to whom the Software is
12 * furnished to do so, subject to the following conditions:
14 * The above copyright notice and this permission notice shall be included in all
15 * copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 ***************************************************************************************************/
27 #include <Zydis/Internal/String.h>
28 #include <Zydis/FormatterBuffer.h>
30 /* ============================================================================================== */
31 /* Exported functions */
32 /* ============================================================================================== */
34 /* ---------------------------------------------------------------------------------------------- */
36 /* ---------------------------------------------------------------------------------------------- */
38 ZyanStatus
ZydisFormatterTokenGetValue(const ZydisFormatterToken
* token
,
39 ZydisTokenType
* type
, ZyanConstCharPointer
* value
)
41 if (!token
|| !type
|| !value
)
43 return ZYAN_STATUS_INVALID_ARGUMENT
;
47 *value
= (ZyanConstCharPointer
)((ZyanU8
*)token
+ sizeof(ZydisFormatterToken
));
49 return ZYAN_STATUS_SUCCESS
;
52 ZyanStatus
ZydisFormatterTokenNext(ZydisFormatterTokenConst
** token
)
54 if (!token
|| !*token
)
56 return ZYAN_STATUS_INVALID_ARGUMENT
;
59 const ZyanU8 next
= (*token
)->next
;
62 return ZYAN_STATUS_OUT_OF_RANGE
;
64 *token
= (ZydisFormatterTokenConst
*)((ZyanU8
*)*token
+ sizeof(ZydisFormatterToken
) + next
);
66 return ZYAN_STATUS_SUCCESS
;
69 /* ---------------------------------------------------------------------------------------------- */
71 /* ---------------------------------------------------------------------------------------------- */
73 ZyanStatus
ZydisFormatterBufferGetToken(const ZydisFormatterBuffer
* buffer
,
74 ZydisFormatterTokenConst
** token
)
76 if (!buffer
|| !token
)
78 return ZYAN_STATUS_INVALID_ARGUMENT
;
81 *token
= ((ZydisFormatterTokenConst
*)buffer
->string
.vector
.data
- 1);
82 if ((*token
)->type
== ZYDIS_TOKEN_INVALID
)
84 return ZYAN_STATUS_INVALID_OPERATION
;
87 return ZYAN_STATUS_SUCCESS
;
90 ZyanStatus
ZydisFormatterBufferGetString(ZydisFormatterBuffer
* buffer
, ZyanString
** string
)
92 if (!buffer
|| !string
)
94 return ZYAN_STATUS_INVALID_ARGUMENT
;
97 if (buffer
->is_token_list
&&
98 ((ZydisFormatterTokenConst
*)buffer
->string
.vector
.data
- 1)->type
== ZYDIS_TOKEN_INVALID
)
100 return ZYAN_STATUS_INVALID_OPERATION
;
103 ZYAN_ASSERT(buffer
->string
.vector
.data
);
104 ZYAN_ASSERT(buffer
->string
.vector
.size
);
106 *string
= &buffer
->string
;
108 return ZYAN_STATUS_SUCCESS
;
111 ZyanStatus
ZydisFormatterBufferAppend(ZydisFormatterBuffer
* buffer
, ZydisTokenType type
)
115 return ZYAN_STATUS_INVALID_ARGUMENT
;
118 if (!buffer
->is_token_list
)
120 return ZYAN_STATUS_SUCCESS
;
123 const ZyanUSize len
= buffer
->string
.vector
.size
;
124 ZYAN_ASSERT((len
> 0) && (len
< 256));
125 if (buffer
->capacity
<= len
+ sizeof(ZydisFormatterToken
))
127 return ZYAN_STATUS_INSUFFICIENT_BUFFER_SIZE
;
130 ZydisFormatterToken
* const last
= (ZydisFormatterToken
*)buffer
->string
.vector
.data
- 1;
131 last
->next
= (ZyanU8
)len
;
133 const ZyanUSize delta
= len
+ sizeof(ZydisFormatterToken
);
134 buffer
->capacity
-= delta
;
135 buffer
->string
.vector
.data
= (ZyanU8
*)buffer
->string
.vector
.data
+ delta
;
136 buffer
->string
.vector
.size
= 1;
137 buffer
->string
.vector
.capacity
= ZYAN_MIN(buffer
->capacity
, 255);
138 *(char*)buffer
->string
.vector
.data
= '\0';
140 ZydisFormatterToken
* const token
= (ZydisFormatterToken
*)buffer
->string
.vector
.data
- 1;
144 return ZYAN_STATUS_SUCCESS
;
147 ZyanStatus
ZydisFormatterBufferRemember(const ZydisFormatterBuffer
* buffer
, ZyanUPointer
* state
)
149 if (!buffer
|| !state
)
151 return ZYAN_STATUS_INVALID_ARGUMENT
;
154 if (buffer
->is_token_list
)
156 *state
= (ZyanUPointer
)buffer
->string
.vector
.data
;
159 *state
= (ZyanUPointer
)buffer
->string
.vector
.size
;
162 return ZYAN_STATUS_SUCCESS
;
165 ZyanStatus
ZydisFormatterBufferRestore(ZydisFormatterBuffer
* buffer
, ZyanUPointer state
)
169 return ZYAN_STATUS_INVALID_ARGUMENT
;
172 if (buffer
->is_token_list
)
174 const ZyanUSize delta
= (ZyanUPointer
)buffer
->string
.vector
.data
- state
;
175 buffer
->capacity
+= delta
;
176 buffer
->string
.vector
.data
= (void*)state
;
177 buffer
->string
.vector
.size
= 1; // TODO: Restore size?
178 buffer
->string
.vector
.capacity
= ZYAN_MIN(buffer
->capacity
, 255);
179 *(char*)buffer
->string
.vector
.data
= '\0';
182 buffer
->string
.vector
.size
= (ZyanUSize
)state
;
183 ZYDIS_STRING_NULLTERMINATE(&buffer
->string
);
186 return ZYAN_STATUS_SUCCESS
;
189 /* ---------------------------------------------------------------------------------------------- */
191 /* ============================================================================================== */