duckstation

duckstation, but archived from the revision just before upstream changed it to a proprietary software project, this version is the libre one
git clone https://git.neptards.moe/u3shit/duckstation.git
Log | Files | Refs | README | LICENSE

FormatterBuffer.c (6463B)


      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 /* ============================================================================================== */