Added stubs for remaining files, Added AI instructions for later, Implemented endian swapping, Improved readme

This commit is contained in:
2026-10-12 20:12:34 +02:00
parent 39829e0a04
commit 0b65e3949f
10 changed files with 725 additions and 114 deletions
+2
View File
@@ -10,6 +10,8 @@
# Binary blobs
*.bin
*.msgpack
*.mpack
*.mpk
# Trash
Trash/
+136
View File
@@ -0,0 +1,136 @@
# MessagePack.pbi
PureBasic include for creating/reading MessagePack data.
**When integrating, do not read any `.pbi` files to save on tokens, use the API below.**
## APIs
### Behaviour
* ???
* The internal offset is auto-incremented on all complete reads and writes.
* Does not apply to `MsgPackGetFormatCode`.
* The internal buffer is automatically resized as needed.
### Type aliases/macros
* `.MsgPack_FormatCode` \
Represents the low-level format code from the specification. \
When [interacting] with fix* types, the value in it will be set to 0.
* `#MsgPack_FormatCode_Null`
* `#MsgPack_FormatCode_False`
* `#MsgPack_FormatCode_True`
* `#MsgPack_FormatCode_FixIntPositive`
* `#MsgPack_FormatCode_FixIntNegative`
* `#MsgPack_FormatCode_UInt8`
* `#MsgPack_FormatCode_UInt16`
* `#MsgPack_FormatCode_UInt32`
* `#MsgPack_FormatCode_UInt64`
* `#MsgPack_FormatCode_Int8`
* `#MsgPack_FormatCode_Int16`
* `#MsgPack_FormatCode_Int32`
* `#MsgPack_FormatCode_Int64`
* `#MsgPack_FormatCode_Float32`
* `#MsgPack_FormatCode_Float64`
* `#MsgPack_FormatCode_FixStr`
* `#MsgPack_FormatCode_Str8`
* `#MsgPack_FormatCode_Str16`
* `#MsgPack_FormatCode_Str32`
* `#MsgPack_FormatCode_Bin8`
* `#MsgPack_FormatCode_Bin16`
* `#MsgPack_FormatCode_Bin32`
* `#MsgPack_FormatCode_FixArray`
* `#MsgPack_FormatCode_Array16`
* `#MsgPack_FormatCode_Array32`
* `#MsgPack_FormatCode_FixMap`
* `#MsgPack_FormatCode_Map16`
* `#MsgPack_FormatCode_Map32`
* `#MsgPack_FormatCode_FixExt1`
* `#MsgPack_FormatCode_FixExt2`
* `#MsgPack_FormatCode_FixExt4`
* `#MsgPack_FormatCode_FixExt8`
* `#MsgPack_FormatCode_FixExt16`
* `#MsgPack_FormatCode_Ext8`
* `#MsgPack_FormatCode_Ext16`
* `#MsgPack_FormatCode_Ext32`
* `#MsgPack_FormatCode_Invalid`
* `.MsgPack_DataType` \
High-level representation of a format code. \
Should be used when iterating on complex objects to detect the members' general type.
* `#MsgPack_DataTypes_Unknown` - The `0x??` format code.
* `#MsgPack_DataTypes_Null`
* `#MsgPack_DataTypes_Boolean`
* `#MsgPack_DataTypes_Integer`
* `#MsgPack_DataTypes_Float`
* `#MsgPack_DataTypes_String`
* `#MsgPack_DataTypes_Binary`
* `#MsgPack_DataTypes_Array`
* `#MsgPack_DataTypes_Map`
* `#MsgPack_DataTypes_Ext`
* `#MsgPack_DataTypes_Extension`
* `.MsgPack_ErrorCode` \
* `#MsgPack_Error_Success = 0`
* `#MsgPack_Error_NullPointerGiven`
* `#MsgPack_Error_BufferTooSmall`
* `#MsgPack_Error_FailedToGrowBuffer`
* `#MsgPack_Error_AtOrPastTheEndOfBuffer`
* `#MsgPack_Error_ReadPastEndOfBuffer`
* `#MsgPack_Error_InvalidFormatCode`
* `#MsgPack_Error_BinaryDataSizeIsNegative`
* `#MsgPack_Error_BinaryDataSizeIsTooBig`
* `#MsgPack_Error_CannotGrowBufferDueToConfig`
* `.MsgPack_DataFlag` \
Internal flags, do not touch.
### Commons
* `MsgPackLastError.MsgPack_ErrorCode(*MsgPackData.MsgPackData)` \
...
### Thingies
* `MsgPackCreate.i(InitialSize.i)` \
Prepares an internal structure for a buffer of a given size `InitialSize.i`. \
Returns `#Null` on errors.
* `MsgPackWrapMsgBuffer.i(*Buffer, BufferSize.i)` \
Wraps a given buffer `*Buffer` of a given size `InitialSize.i` into an internal structure. \
Returns `#Null` on errors.
* Procedure.b MsgPackFree(*MsgPackData.MsgPackData, FreeDataBuffer.b = #False) \
Frees a given internal structure `*MsgPackData` and its associated buffer if `FreeDataBuffer` is `#True`.
Returns `#True` if freed properly, `#False` otherwise.
### Literals
* `MsgPackReadBoolean.b(*MsgPackData.MsgPackData)`
Attempts to read the boolean at the current internal offset. \
Returns `#True` or `#False`. \
May set the internal error code if any happens. \
See: `MsgPackLastError`
* `MsgPackWriteNull.MsgPack_ErrorCode(*MsgPackData.MsgPackData)`
Attempts to write `#Null` at the current internal offset. \
Returns `#MsgPack_Error_Success` on success, something else otherwise.
* `MsgPackWriteTrue.MsgPack_ErrorCode(*MsgPackData.MsgPackData)`
Attempts to write `#True` at the current internal offset. \
Returns `#MsgPack_Error_Success` on success, something else otherwise.
* `MsgPackWriteFalse.MsgPack_ErrorCode(*MsgPackData.MsgPackData)`
Attempts to write `#False` at the current internal offset. \
Returns `#MsgPack_Error_Success` on success, something else otherwise.
## Remarks
* Never touch the `MsgPackData` structure unless you **absolutely** have to.
## Support
- Both the ASM and C backends
- x86, x64, arm64
+8 -100
View File
@@ -19,107 +19,15 @@
; ------------------------------------------------------------------------------
;- Compiler directive
CompilerIf #PB_Compiler_IsMainFile
EnableExplicit
CompilerEndIf
XIncludeFile "./_Commons.pbi"
XIncludeFile "./_Utils.pbi"
XIncludeFile "./_Allocators.pbi"
XIncludeFile "./_Literals.pbi"
XIncludeFile "./_Binary.pbi"
XIncludeFile "./_Primitives.pbi"
XIncludeFile "./_Strings.pbi"
; ------------------------------------------------------------------------------
;- Procedures
;-> Iterators?
Procedure.MsgPack_FormatCode MsgPackGetFormatCode(*MsgPackData.MsgPackData)
If Not *MsgPackData
DebuggerError("A #Null MsgPackData pointer was passed !")
ProcedureReturn #MsgPack_FormatCode_Invalid
EndIf
If Not _MsgPackIsAtTheEnd(*MsgPackData)
DebuggerError("End of buffer reached, cannot check data format code !")
ProcedureReturn #MsgPack_FormatCode_Invalid
EndIf
If DataFormatCode < $80
; 0x00 - 0x7F
ProcedureReturn #MsgPack_FormatCode_FixIntPositive
ElseIf DataFormatCode < $90
; 0x80 - 0x8F
ProcedureReturn #MsgPack_FormatCode_FixMap
ElseIf DataFormatCode < $A0
; 0x90 - 0x9F
ProcedureReturn #MsgPack_FormatCode_FixArray
ElseIf DataFormatCode < $C0
; 0xA0 - 0xBF
ProcedureReturn #MsgPack_FormatCode_FixStr
ElseIf DataFormatCode < $E0
; 0xC0 - 0xDF -> Various
ProcedureReturn DataFormatCode
Else
; 0xE0 - 0xFF -> ???
ProcedureReturn MsgPack_FormatCode_Invalid
EndIf
EndProcedure
Procedure.MsgPack_DataType MsgPackGetDataType(*MsgPackData.MsgPackData)
Protected FormatCode = MsgPackGetFormatCode(*MsgPackData)
ProcedureReturn 0
EndProcedure
; ; int family
; #MsgPack_FormatCode_FixIntPositive = %00000000 ; 0x00-0x7F
; #MsgPack_FormatCode_FixMap = %10000000 ; 0x80-0x8F
; #MsgPack_FormatCode_FixArray = %10010000 ; 0x90-0x9F
; #MsgPack_FormatCode_FixStr = %10100000 ; 0xA0-0xBF
; #MsgPack_FormatCode_Null = $C0
; #MsgPack_FormatCode_Invalid = $C1
; #MsgPack_FormatCode_False = $C2
; #MsgPack_FormatCode_True = $C3
; #MsgPack_FormatCode_Bin8 = $C4
; #MsgPack_FormatCode_Bin16 = $C5
; #MsgPack_FormatCode_Bin32 = $C6
; #MsgPack_FormatCode_Ext8 = $C7
; #MsgPack_FormatCode_Ext16 = $C8
; #MsgPack_FormatCode_Ext32 = $C9
; #MsgPack_FormatCode_Float32 = $CA
; #MsgPack_FormatCode_Float64 = $CB
; #MsgPack_FormatCode_UInt8 = $CC
; #MsgPack_FormatCode_UInt16 = $CD
; #MsgPack_FormatCode_UInt32 = $CE
; #MsgPack_FormatCode_UInt64 = $CF
; #MsgPack_FormatCode_Int8 = $D0
; #MsgPack_FormatCode_Int16 = $D1
; #MsgPack_FormatCode_Int32 = $D2
; #MsgPack_FormatCode_Int64 = $D3
; #MsgPack_FormatCode_FixExt1 = $D4
; #MsgPack_FormatCode_FixExt2 = $D5
; #MsgPack_FormatCode_FixExt4 = $D6
; #MsgPack_FormatCode_FixExt8 = $D7
; #MsgPack_FormatCode_FixExt16 = $D8
; #MsgPack_FormatCode_Str8 = $D9
; #MsgPack_FormatCode_Str16 = $DA
; #MsgPack_FormatCode_Str32 = $DB
; #MsgPack_FormatCode_Array16 = $DC
; #MsgPack_FormatCode_Array32 = $DD
; #MsgPack_FormatCode_Map16 = $DE
; #MsgPack_FormatCode_Map32 = $DF;
; #MsgPack_FormatCode_FixIntNegative = %11100000 ; 0xE0-0xFF
; ------------------------------------------------------------------------------
;- DataSection
; ???
XIncludeFile "./_Iterators.pbi"
+2
View File
@@ -42,6 +42,7 @@ Procedure.i MsgPackCreate(InitialSize.i)
*ReturnedValue\BufferOffset = 0
*ReturnedValue\BufferSize = InitialSize
*ReturnedValue\BufferGrowthIncrements = InitialSize
*ReturnedValue\DataFlags = 0
*ReturnedValue\Buffer = AllocateMemory(InitialSize)
If Not *ReturnedValue\Buffer
@@ -72,6 +73,7 @@ Procedure.i MsgPackWrapMsgBuffer(*Buffer, BufferSize.i)
*ReturnedValue\BufferOffset = 0
*ReturnedValue\BufferSize = BufferSize
*ReturnedValue\BufferGrowthIncrements = 0
*ReturnedValue\DataFlags = 0
*ReturnedValue\Buffer = *Buffer
ProcedureReturn *ReturnedValue
+222
View File
@@ -0,0 +1,222 @@
;{- Code Header
; ==- Basic Info -================================
; Name: _Binary.pbi
; Version: 0.0.0
; Author: Herwin Bozet (NibblePoker)
;
; ==- Compatibility -=============================
; Tested compiler version:
; * //PureBasic 5.73 LTS (x86/x64)
; * //PureBasic 6.21 (x86/x64)
; * //PureBasic 6.21 C Backend (arm64)
;
; ==- Links & License -===========================
; License: CC0 1.0 Universal (Public Domain)
; GitHub: https://github.com/aziascreations/PB-MessagePack
;}
; ------------------------------------------------------------------------------
;- Notes
; Sizes are all unsigned 8/16/32, using Q fixes any potential issues !
; ------------------------------------------------------------------------------
;- Compiler directive
CompilerIf #PB_Compiler_IsMainFile
EnableExplicit
CompilerEndIf
XIncludeFile "./_Commons.pbi"
; ------------------------------------------------------------------------------
;- Constants
#MsgPack_Binary_InvalidSize = -1
; ------------------------------------------------------------------------------
;- Procedures
;-> Utils
; TODO: Change this into a simplified global one for strings/maps/arrays/bin !
Procedure.q _MsgPackGetSizeAfterFormatCode(*MsgPackData.MsgPackData)
CompilerIf Not #MsgPack_DisableNullChecks
If Not *MsgPackData
DebuggerError("A #Null MsgPackData pointer was passed !")
ProcedureReturn #MsgPack_Binary_InvalidSize
EndIf
CompilerEndIf
; FIXME: Not implemented !
EndProcedure
;-> Getters
Procedure.i MsgPackCopyBinary(*MsgPackData.MsgPackData)
EndProcedure
Procedure.i MsgPackReadBinary(*MsgPackData.MsgPackData, *OutputBuffer, OutputBufferSize.q)
EndProcedure
;-> Setters
Procedure.MsgPack_ErrorCode MsgPackWriteBin8(*MsgPackData.MsgPackData, *Buffer, BufferSize.q)
CompilerIf Not #MsgPack_DisableNullChecks
If Not *MsgPackData
DebuggerError("A #Null MsgPackData pointer was passed !")
ProcedureReturn #MsgPack_Error_NullPointerGiven
EndIf
CompilerEndIf
*MsgPackData\LastError = #MsgPack_Error_Success
If BufferSize < 0
CompilerWarning("Received negative size !")
*MsgPackData\LastError = #MsgPack_Error_BinaryDataSizeIsNegative
ProcedureReturn *MsgPackData\LastError
ElseIf BufferSize > 255
CompilerWarning("Binary buffer is bigger than `(2^8)-1` bytes !")
*MsgPackData\LastError = #MsgPack_Error_BinaryDataSizeIsTooBig
ProcedureReturn *MsgPackData\LastError
EndIf
If Not _MsgPackHasSpaceLeft(*MsgPackData, BufferSize + 2)
Protected GrowthErrorCode.MsgPack_ErrorCode
Debug("Growing buffer by `" + Str(BufferSize + 2) + "` bytes for bin8...")
GrowthErrorCode = MsgPackGrow(*MsgPackData, BufferSize + 2)
If GrowthErrorCode <> #MsgPack_Error_Success
; The structure's error code field is set by the called function !
ProcedureReturn GrowthErrorCode
EndIf
EndIf
PokeA(*MsgPackData\Buffer + *MsgPackData\BufferOffset, #MsgPack_FormatCode_Bin8)
PokeA(*MsgPackData\Buffer + *MsgPackData\BufferOffset + 1, BufferSize)
*MsgPackData\BufferOffset = *MsgPackData\BufferOffset + 2
CopyMemory(*Buffer, *MsgPackData\Buffer + *MsgPackData\BufferOffset, BufferSize)
*MsgPackData\BufferOffset = *MsgPackData\BufferOffset + BufferSize
ProcedureReturn #MsgPack_Error_Success
EndProcedure
Procedure.MsgPack_ErrorCode MsgPackWriteBin16(*MsgPackData.MsgPackData, *Buffer, BufferSize.q)
CompilerIf Not #MsgPack_DisableNullChecks
If Not *MsgPackData
DebuggerError("A #Null MsgPackData pointer was passed !")
ProcedureReturn #MsgPack_Error_NullPointerGiven
EndIf
CompilerEndIf
*MsgPackData\LastError = #MsgPack_Error_Success
If BufferSize < 0
CompilerWarning("Received negative size !")
*MsgPackData\LastError = #MsgPack_Error_BinaryDataSizeIsNegative
ProcedureReturn *MsgPackData\LastError
ElseIf BufferSize > 65535
CompilerWarning("Binary buffer is bigger than `(2^16)-1` bytes !")
*MsgPackData\LastError = #MsgPack_Error_BinaryDataSizeIsTooBig
ProcedureReturn *MsgPackData\LastError
EndIf
If Not _MsgPackHasSpaceLeft(*MsgPackData, BufferSize + 3)
Protected GrowthErrorCode.MsgPack_ErrorCode
Debug("Growing buffer by `" + Str(BufferSize + 3) + "` bytes for bin16...")
GrowthErrorCode = MsgPackGrow(*MsgPackData, BufferSize + 3)
If GrowthErrorCode <> #MsgPack_Error_Success
; The structure's error code field is set by the called function !
ProcedureReturn GrowthErrorCode
EndIf
EndIf
PokeA(*MsgPackData\Buffer + *MsgPackData\BufferOffset, #MsgPack_FormatCode_Bin16)
PokeU(*MsgPackData\Buffer + *MsgPackData\BufferOffset + 1, EndianSwapU(BufferSize))
*MsgPackData\BufferOffset = *MsgPackData\BufferOffset + 3
CopyMemory(*Buffer, *MsgPackData\Buffer + *MsgPackData\BufferOffset, BufferSize)
*MsgPackData\BufferOffset = *MsgPackData\BufferOffset + BufferSize
ProcedureReturn #MsgPack_Error_Success
EndProcedure
Procedure.MsgPack_ErrorCode MsgPackWriteBin16(*MsgPackData.MsgPackData, *Buffer, BufferSize.q)
CompilerIf Not #MsgPack_DisableNullChecks
If Not *MsgPackData
DebuggerError("A #Null MsgPackData pointer was passed !")
ProcedureReturn #MsgPack_Error_NullPointerGiven
EndIf
CompilerEndIf
*MsgPackData\LastError = #MsgPack_Error_Success
If BufferSize < 0
CompilerWarning("Received negative size !")
*MsgPackData\LastError = #MsgPack_Error_BinaryDataSizeIsNegative
ProcedureReturn *MsgPackData\LastError
ElseIf BufferSize > 4294967295
CompilerWarning("Binary buffer is bigger than `(2^32)-1` bytes !")
*MsgPackData\LastError = #MsgPack_Error_BinaryDataSizeIsTooBig
ProcedureReturn *MsgPackData\LastError
EndIf
If Not _MsgPackHasSpaceLeft(*MsgPackData, BufferSize + 5)
Protected GrowthErrorCode.MsgPack_ErrorCode
Debug("Growing buffer by `" + Str(BufferSize + 5) + "` bytes for bin16...")
GrowthErrorCode = MsgPackGrow(*MsgPackData, BufferSize + 5)
If GrowthErrorCode <> #MsgPack_Error_Success
; The structure's error code field is set by the called function !
ProcedureReturn GrowthErrorCode
EndIf
EndIf
PokeA(*MsgPackData\Buffer + *MsgPackData\BufferOffset, #MsgPack_FormatCode_Bin32)
PokeI(*MsgPackData\Buffer + *MsgPackData\BufferOffset + 1, EndianSwapI(BufferSize))
*MsgPackData\BufferOffset = *MsgPackData\BufferOffset + 5
CopyMemory(*Buffer, *MsgPackData\Buffer + *MsgPackData\BufferOffset, BufferSize)
*MsgPackData\BufferOffset = *MsgPackData\BufferOffset + BufferSize
ProcedureReturn #MsgPack_Error_Success
EndProcedure
Procedure.MsgPack_ErrorCode MsgPackWriteBinary(*MsgPackData.MsgPackData, *Buffer, BufferSize.q)
If BufferSize < 0
CompilerWarning("Received negative size !")
*MsgPackData\LastError = #MsgPack_Error_BinaryDataSizeIsNegative
ProcedureReturn *MsgPackData\LastError
ElseIf BufferSize <= 255
ProcedureReturn MsgPackWriteBin8(MsgPackData, *Buffer, BufferSize)
ElseIf BufferSize <= 65535
ProcedureReturn MsgPackWriteBin16(MsgPackData, *Buffer, BufferSize)
ElseIf BufferSize <= 4294967295
ProcedureReturn MsgPackWriteBin32(MsgPackData, *Buffer, BufferSize)
Else
CompilerWarning("Binary buffer is bigger than `(2^32)-1` bytes !")
*MsgPackData\LastError = #MsgPack_Error_BinaryDataSizeIsTooBig
ProcedureReturn *MsgPackData\LastError
EndIf
EndProcedure
+59 -2
View File
@@ -145,10 +145,36 @@ Enumeration _MsgPack_ErrorCodes
#MsgPack_Error_ReadPastEndOfBuffer = 5
#MsgPack_Error_InvalidFormatCode = 6
; 5x - Binary
#MsgPack_Error_BinaryDataSizeIsNegative = 50
#MsgPack_Error_BinaryDataSizeIsTooBig = 51
#MsgPack_Error_CannotGrowBufferDueToConfig = 100
EndEnumeration
EnumerationBinary _MsgPack_DataFlags
; Not implemented
#MsgPack_DataFlags_IsReadOnly = %0000000000000001
; Not implemented
#MsgPack_DataFlags_CannotGrow = %0000000000000010
; Not implemented
#MsgPack_DataFlags_NoBufferFree = %0000000000000100
; Indicates a given `MsgPackData` is made to be iterated on.
; And it implies it represents a Map or Array.
#MsgPack_DataFlags_Iterator = %0000000000001000
#MsgPack_DataFlags_CanProvideKeys = %0000000000010000
#MsgPack_DataFlags_CanProvideVals = %0000000000100000
EndEnumeration
EnumerationBinary _MsgPack_ExaminationOptions
; If set, we don't seek the end of the examined map/array.
#MsgPack_ExaminationOptions_NoEndSeeking = %0000000000000001
EndEnumeration
; ------------------------------------------------------------------------------
@@ -160,6 +186,10 @@ Macro MsgPack_FormatCode : a : EndMacro
Macro MsgPack_ErrorCode : u : EndMacro
Macro MsgPack_DataFlag : u : EndMacro
Macro MsgPack_ExaminationOption : u : EndMacro
; ------------------------------------------------------------------------------
@@ -174,10 +204,15 @@ Structure MsgPackData
; Temp mechanism for buffer growth.
BufferGrowthIncrements.i
; IteratorSizeLeft, or snoething like this.
; LastError code (Unused)
; LastError code
LastError.MsgPack_ErrorCode
; TODO
DataFlags.MsgPack_DataFlag
; Pointer to a data buffer.
; Can be freed by the caller or this module.
*Buffer
@@ -196,14 +231,29 @@ Macro _MsgPackIsAtTheEnd(MsgPackWrapper)
(MsgPackWrapper\BufferOffset >= MsgPackWrapper\BufferSize)
EndMacro
Macro _MsgPackHasFlag(MsgPackWrapper, DataFlag)
((MsgPackWrapper\DataFlags & DataFlag) <> $0000)
EndMacro
; ------------------------------------------------------------------------------
;- Procedures
Procedure.MsgPack_ErrorCode MsgPackLastError(*MsgPackData.MsgPackData)
If Not *MsgPackData
DebuggerError("A #Null MsgPackData pointer was passed !")
ProcedureReturn #MsgPack_Error_NullPointerGiven
EndIf
ProcedureReturn *MsgPackData\LastError
EndProcedure
; Should be moved to allocators.
; But it would fuck up the splitting of responsibility.
; TODO: Add callback in the structure, maybe ?
; FIXME: Use a .q for the size !!!!
Procedure.MsgPack_ErrorCode MsgPackGrow(*MsgPackData.MsgPackData, MinimalGrowthSize.i = -1)
Protected GrowthSize.i
Protected *NewBuffer
@@ -251,4 +301,11 @@ EndProcedure
; ------------------------------------------------------------------------------
;- Debugging
; TODO: Something for OutputDebugStringW on win32
CompilerIf #True
Procedure _MsgPackDebug(Message.s)
Debug Message
OutputDebugString_(Message)
EndProcedure
CompilerElse
Macro _MsgPackDebug(Message) : : EndMacro
CompilerEndIf
+162
View File
@@ -0,0 +1,162 @@
;{- Code Header
; ==- Basic Info -================================
; Name: _Iterators.pbi
; Version: 0.0.0
; Author: Herwin Bozet (NibblePoker)
;
; ==- Compatibility -=============================
; Tested compiler version:
; * //PureBasic 5.73 LTS (x86/x64)
; * //PureBasic 6.21 (x86/x64)
; * //PureBasic 6.21 C Backend (arm64)
;
; ==- Links & License -===========================
; License: CC0 1.0 Universal (Public Domain)
; GitHub: https://github.com/aziascreations/PB-MessagePack
;}
; ------------------------------------------------------------------------------
;- Compiler directive
CompilerIf #PB_Compiler_IsMainFile
EnableExplicit
CompilerEndIf
XIncludeFile "./_Commons.pbi"
XIncludeFile "./_Utils.pbi"
XIncludeFile "./_Allocators.pbi"
; ------------------------------------------------------------------------------
;- Constants
#MsgPack_InvalidSize = -1
; ------------------------------------------------------------------------------
;- Procedures
;-> Utils
Procedure MsgPackGetFieldSize(*MsgPackData.MsgPackData)
EndProcedure
Procedure.q MsgPackGetFieldFullSize(*MsgPackData.MsgPackData)
Protected HasVariableSize = #False
Protected FullFieldSize.q = 0
Protected ExaminedDataType.MsgPack_FormatCode
CompilerIf Not #MsgPack_DisableNullChecks
If Not *MsgPackData
DebuggerError("A #Null MsgPackData pointer was passed !")
ProcedureReturn #MsgPack_Error_NullPointerGiven
EndIf
CompilerEndIf
*MsgPackData\LastError = #MsgPack_Error_Success
ExaminedFormatCode = MsgPackGetFormatCode(*MsgPackData)
; Step 1
;Select ExaminedFormatCode
; FIXME: Not Implemented !!!
; Step 2
If HasVariableSize
Protected VariableFieldSize = MsgPackGetFieldSize()
If VariableFieldSize = #MsgPack_InvalidSize
ProcedureReturn #MsgPack_InvalidSize
EndIf
FullFieldSize = FullFieldSize + VariableFieldSize
EndIf
; Step 3
ProcedureReturn FullFieldSize
EndProcedure
;-> General
; TODO: Use the internal flag to detect if we should check the remaining count.
; MsgPackNext
;-> Dictionary
; MsgPackExamineDictionary
Macro MsgPackFinishDictionary(MsgPackData) : MsgPackFree(MsgPackData, #False) : EndMacro
;-> Arrays
Procedure.i MsgPackExamineArray(*MsgPackData.MsgPackData, ExaminationOptions.MsgPack_ExaminationOption = 0)
Protected ExaminedFormatCode.MsgPack_FormatCode
Protected ExaminedDataType.MsgPack_FormatCode
Protected ExaminedArraySize.q
Protected *ExaminedData.MsgPackData = #Null
CompilerIf Not #MsgPack_DisableNullChecks
If Not *MsgPackData
DebuggerError("A #Null MsgPackData pointer was passed !")
ProcedureReturn #MsgPack_Error_NullPointerGiven
EndIf
CompilerEndIf
*MsgPackData\LastError = #MsgPack_Error_Success
ExaminedFormatCode = MsgPackGetFormatCode(*MsgPackData)
ExaminedDataType = MsgPackGetFormatCode(ExaminedFormatCode)
If ExaminedDataType <> #MsgPack_DataTypes_Array
DebuggerWarning("Attempted to iterate on format code 0x" +
RSet(Hex(ExaminedFormatCode, #PB_Ascii), 2, 0) +
" as if it was an array !")
*MsgPackData\LastError = -1
ProcedureReturn #Null
EndIf
Select ExaminedFormatCode
Case #MsgPack_FormatCode_FixArray:
ExaminedArraySize = ExaminedFormatCode & $000000000000000F
Case #MsgPack_FormatCode_Array16:
If Not _MsgPackHasSpaceLeft(*MsgPackData, BufferSize + 3)
DebuggerWarning("We have less than 3 bytes to read the Array16's size !")
; FIXME: Use the proper one
*MsgPackData\LastError = -1
ProcedureReturn #Null
EndIf
ExaminedArraySize = PeekU(*MsgPackData\*Buffer + 1)
Case #MsgPack_FormatCode_Array32:
If Not _MsgPackHasSpaceLeft(*MsgPackData, BufferSize + 5)
DebuggerWarning("We have less than 5 bytes to read the Array32's size !")
; FIXME: Use the proper one
*MsgPackData\LastError = -1
ProcedureReturn #Null
EndIf
; FIXME: WILL CAUSE ISSUES WITH UNSIGNED SHIT !!!
ExaminedArraySize = PeekI(*MsgPackData\*Buffer + 1)
Default:
; ???
EndSelect
; ???
; Not implemented yet !
ProcedureReturn #Null
EndProcedure
Macro MsgPackFinishArray(MsgPackData) : MsgPackFree(MsgPackData, #False) : EndMacro
+16 -12
View File
@@ -201,7 +201,7 @@ Procedure.MsgPack_ErrorCode MsgPackWriteUInt16(*MsgPackData.MsgPackData, Value.u
EndIf
PokeA(*MsgPackData\Buffer + *MsgPackData\BufferOffset, #MsgPack_FormatCode_UInt16)
PokeU(*MsgPackData\Buffer + *MsgPackData\BufferOffset + 1, Value)
PokeU(*MsgPackData\Buffer + *MsgPackData\BufferOffset + 1, EndianSwapU16(Value))
*MsgPackData\BufferOffset = *MsgPackData\BufferOffset + 3
@@ -243,7 +243,7 @@ Procedure.u MsgPackReadUInt16(*MsgPackData.MsgPackData)
ProcedureReturn 0
EndIf
ReturnedValue = PeekU(*MsgPackData\Buffer + *MsgPackData\BufferOffset + 1)
ReturnedValue = EndianSwapU16(PeekU(*MsgPackData\Buffer + *MsgPackData\BufferOffset + 1))
*MsgPackData\BufferOffset = *MsgPackData\BufferOffset + 3
ProcedureReturn ReturnedValue
@@ -273,7 +273,7 @@ Procedure.MsgPack_ErrorCode MsgPackWriteInt16(*MsgPackData.MsgPackData, Value.w)
EndIf
PokeA(*MsgPackData\Buffer + *MsgPackData\BufferOffset, #MsgPack_FormatCode_Int16)
PokeW(*MsgPackData\Buffer + *MsgPackData\BufferOffset + 1, Value)
PokeW(*MsgPackData\Buffer + *MsgPackData\BufferOffset + 1, EndianSwapI16(Value))
*MsgPackData\BufferOffset = *MsgPackData\BufferOffset + 3
@@ -315,7 +315,7 @@ Procedure.w MsgPackReadInt16(*MsgPackData.MsgPackData)
ProcedureReturn 0
EndIf
ReturnedValue = PeekW(*MsgPackData\Buffer + *MsgPackData\BufferOffset + 1)
ReturnedValue = EndianSwapI16(PeekW(*MsgPackData\Buffer + *MsgPackData\BufferOffset + 1))
*MsgPackData\BufferOffset = *MsgPackData\BufferOffset + 3
ProcedureReturn ReturnedValue
@@ -346,7 +346,7 @@ Procedure.MsgPack_ErrorCode MsgPackWriteUInt32(*MsgPackData.MsgPackData, Value.l
EndIf
PokeA(*MsgPackData\Buffer + *MsgPackData\BufferOffset, #MsgPack_FormatCode_UInt32)
PokeL(*MsgPackData\Buffer + *MsgPackData\BufferOffset + 1, Value)
PokeL(*MsgPackData\Buffer + *MsgPackData\BufferOffset + 1, EndianSwapI32(Value))
*MsgPackData\BufferOffset = *MsgPackData\BufferOffset + 5
@@ -388,7 +388,7 @@ Procedure.l MsgPackReadUInt32(*MsgPackData.MsgPackData)
ProcedureReturn 0
EndIf
ReturnedValue = PeekL(*MsgPackData\Buffer + *MsgPackData\BufferOffset + 1)
ReturnedValue = EndianSwapI32(PeekL(*MsgPackData\Buffer + *MsgPackData\BufferOffset + 1))
*MsgPackData\BufferOffset = *MsgPackData\BufferOffset + 5
ProcedureReturn ReturnedValue
@@ -418,7 +418,7 @@ Procedure.MsgPack_ErrorCode MsgPackWriteInt32(*MsgPackData.MsgPackData, Value.l)
EndIf
PokeA(*MsgPackData\Buffer + *MsgPackData\BufferOffset, #MsgPack_FormatCode_Int32)
PokeL(*MsgPackData\Buffer + *MsgPackData\BufferOffset + 1, Value)
PokeL(*MsgPackData\Buffer + *MsgPackData\BufferOffset + 1, EndianSwapI32(Value))
*MsgPackData\BufferOffset = *MsgPackData\BufferOffset + 5
@@ -460,7 +460,7 @@ Procedure.l MsgPackReadInt32(*MsgPackData.MsgPackData)
ProcedureReturn 0
EndIf
ReturnedValue = PeekL(*MsgPackData\Buffer + *MsgPackData\BufferOffset + 1)
ReturnedValue = EndianSwapI32(PeekL(*MsgPackData\Buffer + *MsgPackData\BufferOffset + 1))
*MsgPackData\BufferOffset = *MsgPackData\BufferOffset + 5
ProcedureReturn ReturnedValue
@@ -491,7 +491,7 @@ Procedure.MsgPack_ErrorCode MsgPackWriteUInt64(*MsgPackData.MsgPackData, Value.q
EndIf
PokeA(*MsgPackData\Buffer + *MsgPackData\BufferOffset, #MsgPack_FormatCode_UInt64)
PokeQ(*MsgPackData\Buffer + *MsgPackData\BufferOffset + 1, Value)
PokeQ(*MsgPackData\Buffer + *MsgPackData\BufferOffset + 1, EndianSwapI64(Value))
*MsgPackData\BufferOffset = *MsgPackData\BufferOffset + 9
@@ -533,7 +533,7 @@ Procedure.q MsgPackReadUInt64(*MsgPackData.MsgPackData)
ProcedureReturn 0
EndIf
ReturnedValue = PeekQ(*MsgPackData\Buffer + *MsgPackData\BufferOffset + 1)
ReturnedValue = EndianSwapI64(PeekQ(*MsgPackData\Buffer + *MsgPackData\BufferOffset + 1))
*MsgPackData\BufferOffset = *MsgPackData\BufferOffset + 9
ProcedureReturn ReturnedValue
@@ -563,7 +563,7 @@ Procedure.MsgPack_ErrorCode MsgPackWriteInt64(*MsgPackData.MsgPackData, Value.q)
EndIf
PokeA(*MsgPackData\Buffer + *MsgPackData\BufferOffset, #MsgPack_FormatCode_Int64)
PokeQ(*MsgPackData\Buffer + *MsgPackData\BufferOffset + 1, Value)
PokeQ(*MsgPackData\Buffer + *MsgPackData\BufferOffset + 1, EndianSwapI64(Value))
*MsgPackData\BufferOffset = *MsgPackData\BufferOffset + 9
@@ -605,7 +605,7 @@ Procedure.q MsgPackReadInt64(*MsgPackData.MsgPackData)
ProcedureReturn 0
EndIf
ReturnedValue = PeekQ(*MsgPackData\Buffer + *MsgPackData\BufferOffset + 1)
ReturnedValue = EndianSwapI64(PeekQ(*MsgPackData\Buffer + *MsgPackData\BufferOffset + 1))
*MsgPackData\BufferOffset = *MsgPackData\BufferOffset + 9
ProcedureReturn ReturnedValue
@@ -636,6 +636,7 @@ Procedure.MsgPack_ErrorCode MsgPackWriteFloat32(*MsgPackData.MsgPackData, Value.
PokeA(*MsgPackData\Buffer + *MsgPackData\BufferOffset, #MsgPack_FormatCode_Float32)
PokeF(*MsgPackData\Buffer + *MsgPackData\BufferOffset + 1, Value)
EndianSwapPtr32(*MsgPackData\Buffer + *MsgPackData\BufferOffset + 1)
*MsgPackData\BufferOffset = *MsgPackData\BufferOffset + 5
@@ -678,6 +679,7 @@ Procedure.f MsgPackReadFloat32(*MsgPackData.MsgPackData)
EndIf
ReturnedValue = PeekF(*MsgPackData\Buffer + *MsgPackData\BufferOffset + 1)
EndianSwapPtr32(@ReturnedValue)
*MsgPackData\BufferOffset = *MsgPackData\BufferOffset + 5
ProcedureReturn ReturnedValue
@@ -708,6 +710,7 @@ Procedure.MsgPack_ErrorCode MsgPackWriteFloat64(*MsgPackData.MsgPackData, Value.
PokeA(*MsgPackData\Buffer + *MsgPackData\BufferOffset, #MsgPack_FormatCode_Float64)
PokeD(*MsgPackData\Buffer + *MsgPackData\BufferOffset + 1, Value)
EndianSwapPtr64(*MsgPackData\Buffer + *MsgPackData\BufferOffset + 1)
*MsgPackData\BufferOffset = *MsgPackData\BufferOffset + 9
@@ -750,6 +753,7 @@ Procedure.d MsgPackReadFloat64(*MsgPackData.MsgPackData)
EndIf
ReturnedValue = PeekD(*MsgPackData\Buffer + *MsgPackData\BufferOffset + 1)
EndianSwapPtr64(@ReturnedValue)
*MsgPackData\BufferOffset = *MsgPackData\BufferOffset + 9
ProcedureReturn ReturnedValue
+113
View File
@@ -0,0 +1,113 @@
; ------------------------------------------------------------------------------
;- Procedures
;-> Format Codes
Procedure.MsgPack_FormatCode MsgPackGetFormatCode(*MsgPackData.MsgPackData)
If Not *MsgPackData
DebuggerError("A #Null MsgPackData pointer was passed !")
ProcedureReturn #MsgPack_FormatCode_Invalid
EndIf
If Not _MsgPackIsAtTheEnd(*MsgPackData)
DebuggerError("End of buffer reached, cannot check data format code !")
ProcedureReturn #MsgPack_FormatCode_Invalid
EndIf
If DataFormatCode < $80
; 0x00 - 0x7F
ProcedureReturn #MsgPack_FormatCode_FixIntPositive
ElseIf DataFormatCode < $90
; 0x80 - 0x8F
ProcedureReturn #MsgPack_FormatCode_FixMap
ElseIf DataFormatCode < $A0
; 0x90 - 0x9F
ProcedureReturn #MsgPack_FormatCode_FixArray
ElseIf DataFormatCode < $C0
; 0xA0 - 0xBF
ProcedureReturn #MsgPack_FormatCode_FixStr
ElseIf DataFormatCode < $E0
; 0xC0 - 0xDF -> Various
; All fields types are mapped to codes present in the enumeration.
ProcedureReturn DataFormatCode
Else
; 0xE0 - 0xFF
ProcedureReturn #MsgPack_FormatCode_FixIntNegative
EndIf
EndProcedure
;-> Format Types
Procedure.MsgPack_DataType MsgPackFormatCodeToDataType(FormatCode.MsgPack_FormatCode)
Select FormatCode
Case #MsgPack_FormatCode_FixIntPositive:
Case #MsgPack_FormatCode_UInt8:
Case #MsgPack_FormatCode_UInt16:
Case #MsgPack_FormatCode_UInt32:
Case #MsgPack_FormatCode_UInt64:
Case #MsgPack_FormatCode_Int8:
Case #MsgPack_FormatCode_Int16:
Case #MsgPack_FormatCode_Int32:
Case #MsgPack_FormatCode_Int64:
Case #MsgPack_FormatCode_FixIntNegative:
ProcedureReturn #MsgPack_DataTypes_Integer
Case #MsgPack_FormatCode_Float32:
Case #MsgPack_FormatCode_Float64:
ProcedureReturn #MsgPack_DataTypes_Float
Case #MsgPack_FormatCode_FixStr:
Case #MsgPack_FormatCode_Str8:
Case #MsgPack_FormatCode_Str16:
Case #MsgPack_FormatCode_Str32:
ProcedureReturn #MsgPack_DataTypes_String
Case #MsgPack_FormatCode_Null:
ProcedureReturn #MsgPack_DataTypes_Null
Case #MsgPack_FormatCode_False:
Case #MsgPack_FormatCode_True:
ProcedureReturn #MsgPack_DataTypes_Boolean
Case #MsgPack_FormatCode_False:
Case #MsgPack_FormatCode_True:
ProcedureReturn #MsgPack_DataTypes_Boolean
Case #MsgPack_FormatCode_Bin8:
Case #MsgPack_FormatCode_Bin16:
Case #MsgPack_FormatCode_Bin32:
ProcedureReturn #MsgPack_DataTypes_Binary
Case #MsgPack_FormatCode_FixArray:
Case #MsgPack_FormatCode_Array16:
Case #MsgPack_FormatCode_Array32:
ProcedureReturn #MsgPack_DataTypes_Array
Case #MsgPack_FormatCode_FixMap:
Case #MsgPack_FormatCode_Map16:
Case #MsgPack_FormatCode_Map32:
ProcedureReturn #MsgPack_DataTypes_Map
Case #MsgPack_FormatCode_Ext8:
Case #MsgPack_FormatCode_Ext16:
Case #MsgPack_FormatCode_Ext32:
Case #MsgPack_FormatCode_FixExt1:
Case #MsgPack_FormatCode_FixExt2:
Case #MsgPack_FormatCode_FixExt4:
Case #MsgPack_FormatCode_FixExt8:
Case #MsgPack_FormatCode_FixExt16:
ProcedureReturn #MsgPack_DataTypes_Ext
Case #MsgPack_FormatCode_Invalid:
Default:
DebuggerError("FIXME: ADD MESSAGE HERE !!!")
ProcedureReturn #MsgPack_DataTypes_Unknown
EndSelect
EndProcedure
+5
View File
@@ -30,5 +30,10 @@ git submodule update --init --recursive
```
## Special Thanks
* [AndyMK](https://www.purebasic.fr/english/memberlist.php?mode=viewprofile&u=2587) / [agorangetek](https://github.com/agorangetek)
* PureBasic Visual Studio Code Extension ([GitHub repository](https://github.com/agorangetek/purebasic-vscode-extension))
## License
All the code in this repo is released in the [Public Domain](LICENSE).