Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
stenzek
GitHub Repository: stenzek/duckstation
Path: blob/master/dep/zydis/src/FormatterBuffer.c
4211 views
1
/***************************************************************************************************
2
3
Zyan Disassembler Library (Zydis)
4
5
Original Author : Florian Bernd
6
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:
13
*
14
* The above copyright notice and this permission notice shall be included in all
15
* copies or substantial portions of the Software.
16
*
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
23
* SOFTWARE.
24
25
***************************************************************************************************/
26
27
#include <Zydis/Internal/String.h>
28
#include <Zydis/FormatterBuffer.h>
29
30
/* ============================================================================================== */
31
/* Exported functions */
32
/* ============================================================================================== */
33
34
/* ---------------------------------------------------------------------------------------------- */
35
/* Token */
36
/* ---------------------------------------------------------------------------------------------- */
37
38
ZyanStatus ZydisFormatterTokenGetValue(const ZydisFormatterToken* token,
39
ZydisTokenType* type, ZyanConstCharPointer* value)
40
{
41
if (!token || !type || !value)
42
{
43
return ZYAN_STATUS_INVALID_ARGUMENT;
44
}
45
46
*type = token->type;
47
*value = (ZyanConstCharPointer)((ZyanU8*)token + sizeof(ZydisFormatterToken));
48
49
return ZYAN_STATUS_SUCCESS;
50
}
51
52
ZyanStatus ZydisFormatterTokenNext(ZydisFormatterTokenConst** token)
53
{
54
if (!token || !*token)
55
{
56
return ZYAN_STATUS_INVALID_ARGUMENT;
57
}
58
59
const ZyanU8 next = (*token)->next;
60
if (!next)
61
{
62
return ZYAN_STATUS_OUT_OF_RANGE;
63
}
64
*token = (ZydisFormatterTokenConst*)((ZyanU8*)*token + sizeof(ZydisFormatterToken) + next);
65
66
return ZYAN_STATUS_SUCCESS;
67
}
68
69
/* ---------------------------------------------------------------------------------------------- */
70
/* Buffer */
71
/* ---------------------------------------------------------------------------------------------- */
72
73
ZyanStatus ZydisFormatterBufferGetToken(const ZydisFormatterBuffer* buffer,
74
ZydisFormatterTokenConst** token)
75
{
76
if (!buffer || !token)
77
{
78
return ZYAN_STATUS_INVALID_ARGUMENT;
79
}
80
81
*token = ((ZydisFormatterTokenConst*)buffer->string.vector.data - 1);
82
if ((*token)->type == ZYDIS_TOKEN_INVALID)
83
{
84
return ZYAN_STATUS_INVALID_OPERATION;
85
}
86
87
return ZYAN_STATUS_SUCCESS;
88
}
89
90
ZyanStatus ZydisFormatterBufferGetString(ZydisFormatterBuffer* buffer, ZyanString** string)
91
{
92
if (!buffer || !string)
93
{
94
return ZYAN_STATUS_INVALID_ARGUMENT;
95
}
96
97
if (buffer->is_token_list &&
98
((ZydisFormatterTokenConst*)buffer->string.vector.data - 1)->type == ZYDIS_TOKEN_INVALID)
99
{
100
return ZYAN_STATUS_INVALID_OPERATION;
101
}
102
103
ZYAN_ASSERT(buffer->string.vector.data);
104
ZYAN_ASSERT(buffer->string.vector.size);
105
106
*string = &buffer->string;
107
108
return ZYAN_STATUS_SUCCESS;
109
}
110
111
ZyanStatus ZydisFormatterBufferAppend(ZydisFormatterBuffer* buffer, ZydisTokenType type)
112
{
113
if (!buffer)
114
{
115
return ZYAN_STATUS_INVALID_ARGUMENT;
116
}
117
118
if (!buffer->is_token_list)
119
{
120
return ZYAN_STATUS_SUCCESS;
121
}
122
123
const ZyanUSize len = buffer->string.vector.size;
124
ZYAN_ASSERT((len > 0) && (len < 256));
125
if (buffer->capacity <= len + sizeof(ZydisFormatterToken))
126
{
127
return ZYAN_STATUS_INSUFFICIENT_BUFFER_SIZE;
128
}
129
130
ZydisFormatterToken* const last = (ZydisFormatterToken*)buffer->string.vector.data - 1;
131
last->next = (ZyanU8)len;
132
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';
139
140
ZydisFormatterToken* const token = (ZydisFormatterToken*)buffer->string.vector.data - 1;
141
token->type = type;
142
token->next = 0;
143
144
return ZYAN_STATUS_SUCCESS;
145
}
146
147
ZyanStatus ZydisFormatterBufferRemember(const ZydisFormatterBuffer* buffer, ZyanUPointer* state)
148
{
149
if (!buffer || !state)
150
{
151
return ZYAN_STATUS_INVALID_ARGUMENT;
152
}
153
154
if (buffer->is_token_list)
155
{
156
*state = (ZyanUPointer)buffer->string.vector.data;
157
} else
158
{
159
*state = (ZyanUPointer)buffer->string.vector.size;
160
}
161
162
return ZYAN_STATUS_SUCCESS;
163
}
164
165
ZyanStatus ZydisFormatterBufferRestore(ZydisFormatterBuffer* buffer, ZyanUPointer state)
166
{
167
if (!buffer)
168
{
169
return ZYAN_STATUS_INVALID_ARGUMENT;
170
}
171
172
if (buffer->is_token_list)
173
{
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';
180
} else
181
{
182
buffer->string.vector.size = (ZyanUSize)state;
183
ZYDIS_STRING_NULLTERMINATE(&buffer->string);
184
}
185
186
return ZYAN_STATUS_SUCCESS;
187
}
188
189
/* ---------------------------------------------------------------------------------------------- */
190
191
/* ============================================================================================== */
192
193