Co-Authored-By: Claude <noreply@anthropic.com>
15 KiB
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. - Can be disabled with the internal
#MsgPack_DataFlags_MoveOffsetAfterRead/Writeflags, honored by every read and write.
- Does not apply to
- The internal buffer is automatically resized as needed.
- Invalid or truncated data never raises a
DebuggerError, only programming errors do. (e.g.:#Nullpointers) - Views from
MsgPackExamineare read-only, writes return#MsgPack_Error_BufferIsReadOnly.
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- The0x??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_FailedToAllocateBuffer#MsgPack_Error_BinaryDataSizeIsNegative#MsgPack_Error_BinaryDataSizeIsTooBig#MsgPack_Error_OutputBufferTooSmall#MsgPack_Error_UnsupportedStringEncoding#MsgPack_Error_InvalidStringSize#MsgPack_Error_TooManyEntries#MsgPack_Error_OddMapFieldCount#MsgPack_Error_CannotGrowBufferDueToConfig#MsgPack_Error_BufferIsReadOnly
-
.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 sizeInitialSize.i.
Returns#Nullon errors. -
MsgPackWrapMsgBuffer.i(*Buffer, BufferSize.i)
Wraps a given buffer*Bufferof a given sizeInitialSize.iinto an internal structure.
Returns#Nullon errors. -
MsgPackFree.b(*MsgPackData.MsgPackData, FreeDataBuffer.b)
Frees a given internal structure*MsgPackDataand its associated buffer ifFreeDataBufferis#True.
FreeDataBufferis mandatory, use#Falsefor buffers wrapped withMsgPackWrapMsgBufferthat the caller still owns.
Returns#Trueif freed properly,#Falseotherwise. -
MsgPackFinalize.i(*MsgPackData.MsgPackData)
Frees a given internal structure*MsgPackDataand returns its buffer, shrunk to the number of bytes written.
The caller takes ownership of the buffer, gets its size withMemorySize()and frees it withFreeMemory().
Fails if the buffer is owned by the caller or nothing was written.
Returns#Nullon errors and leaves*MsgPackDatauntouched.
See:MsgPackLastError
Literals
-
MsgPackReadBoolean.b(*MsgPackData.MsgPackData)Attempts to read the boolean at the current internal offset.
Returns#Trueor#False.
May set the internal error code if any happens.
See:MsgPackLastError -
MsgPackWriteNull.MsgPack_ErrorCode(*MsgPackData.MsgPackData)Attempts to write#Nullat the current internal offset.
Returns#MsgPack_Error_Successon success, something else otherwise. -
MsgPackWriteTrue.MsgPack_ErrorCode(*MsgPackData.MsgPackData)Attempts to write#Trueat the current internal offset.
Returns#MsgPack_Error_Successon success, something else otherwise. -
MsgPackWriteFalse.MsgPack_ErrorCode(*MsgPackData.MsgPackData)Attempts to write#Falseat the current internal offset.
Returns#MsgPack_Error_Successon success, something else otherwise. -
MsgPackWriteBoolean.MsgPack_ErrorCode(*MsgPackData.MsgPackData, Boolean.b)Writes#Trueor#Falsedepending onBoolean.
Returns#MsgPack_Error_Successon success, something else otherwise. -
MsgPackReadNull.MsgPack_ErrorCode(*MsgPackData.MsgPackData)Attempts to read a nil at the current internal offset.
Returns#MsgPack_Error_Successon success, something else otherwise, in which case the offset isn't moved.
Integers & Floats
-
MsgPackWriteInteger.MsgPack_ErrorCode(*MsgPackData.MsgPackData, Value.q)
WritesValueusing the smallest int format code that fits, fixints included.
Positive values always use the unsigned format codes.
UInt64 values above(2^63)-1must be written withMsgPackWriteUInt64. -
MsgPackWriteFixInt.MsgPack_ErrorCode(*MsgPackData.MsgPackData, Value.q)
WritesValueas a fixint, from-32to127.
Returns#MsgPack_Error_ValueOverflowif it doesn't fit. -
MsgPackWrite/Read[U]Int8/16/32/64,MsgPackWrite/ReadFloat32/64
Force the given format code. Aliases:MsgPackWrite/ReadU8,I8, ...,F64.
UInt32andUInt64use.land.q, so their values above the signed max come back negative. -
MsgPackReadInteger.q(*MsgPackData.MsgPackData)
Reads any int field at the current internal offset, fixints included.
Returns0on errors and sets the internal error code.
UInt64 values above(2^63)-1fail with#MsgPack_Error_ValueOverflowwithout moving the offset, so they can be read withMsgPackReadUInt64.
See:MsgPackLastError -
MsgPackReadFloat.d(*MsgPackData.MsgPackData)
Reads any float field at the current internal offset.
Returns0on errors and sets the internal error code.
See:MsgPackLastError
Binary
-
MsgPackWriteBinary.MsgPack_ErrorCode(*MsgPackData.MsgPackData, *Buffer, BufferSize.q)
WritesBufferSizebytes from*Bufferusing the smallest bin format code that fits.
Returns#MsgPack_Error_Successon success, something else otherwise. -
MsgPackWriteBin8/16/32.MsgPack_ErrorCode(*MsgPackData.MsgPackData, *Buffer, BufferSize.q)
Same asMsgPackWriteBinary, but forces the given format code, even if a smaller one fits. -
MsgPackReadBinary.q(*MsgPackData.MsgPackData, *OutputBuffer, OutputBufferSize.q)
Copies the bin field at the current internal offset into*OutputBuffer.
Returns the number of bytes copied, or#MsgPack_InvalidSizeon errors.
The offset isn't moved on errors, so it can be retried with a bigger buffer.
See:MsgPackLastError -
MsgPackCopyBinary.i(*MsgPackData.MsgPackData)
Copies the bin field at the current internal offset into a new buffer that must be freed withFreeMemory().
Returns#Nullon errors, or for empty bin fields with#MsgPack_Error_Successas the last error.
See:MsgPackLastError
Strings
Supported encodings: #PB_UTF8 (default, per spec), #PB_Ascii, #PB_Unicode (UTF-16 LE).
-
MsgPackWriteString.MsgPack_ErrorCode(*MsgPackData.MsgPackData, String.s, Encoding.i = #PB_UTF8)
WritesStringusing the smallest str format code that fits its encoded byte size.
Returns#MsgPack_Error_Successon success, something else otherwise. -
MsgPackWriteFixStr/Str8/Str16/Str32.MsgPack_ErrorCode(*MsgPackData.MsgPackData, String.s, Encoding.i = #PB_UTF8)
Same asMsgPackWriteString, but forces the given format code. -
MsgPackReadString.s(*MsgPackData.MsgPackData, Encoding.i = #PB_UTF8)
Reads any str field at the current internal offset.
Returns""on errors and sets the internal error code.
See:MsgPackLastError
Extensions
ExtType.b is the signed ext type, -128 to -1 being reserved by the spec but not rejected.
Size errors reuse the #MsgPack_Error_BinaryDataSize* codes.
-
MsgPackWriteExtension.MsgPack_ErrorCode(*MsgPackData.MsgPackData, ExtType.b, *Buffer, BufferSize.q)
WritesBufferSizebytes from*Bufferusing fixext for 1/2/4/8/16 bytes, or the smallest ext format code otherwise.
Returns#MsgPack_Error_Successon success, something else otherwise. -
MsgPackWriteExt8/16/32.MsgPack_ErrorCode(*MsgPackData.MsgPackData, ExtType.b, *Buffer, BufferSize.q)
Same asMsgPackWriteExtension, but forces the given format code, even if a smaller one fits. -
MsgPackWriteFixExt1/2/4/8/16.MsgPack_ErrorCode(*MsgPackData.MsgPackData, ExtType.b, *Buffer)
Writes the 1/2/4/8/16 bytes at*Bufferas the given fixext. -
MsgPackGetExtensionType.b(*MsgPackData.MsgPackData)
Returns the type of the ext field at the current internal offset, without moving it.
Returns0on errors and sets the internal error code.
See:MsgPackLastError -
MsgPackReadExtension.q(*MsgPackData.MsgPackData, *OutputBuffer, OutputBufferSize.q)
Same asMsgPackReadBinary, for the data of ext fields. -
MsgPackCopyExtension.i(*MsgPackData.MsgPackData)
Same asMsgPackCopyBinary, for the data of ext fields.
Navigation
Arrays and maps are handled iteratively, so deep nesting can't overflow the stack.
-
MsgPackGetFieldFullSize.q(*MsgPackData.MsgPackData)
Returns the full size in bytes of the field at the current internal offset, without moving it.
Arrays and maps include all of their contained fields, recursively.
Returns#MsgPack_InvalidSizeon errors and sets the internal error code.
See:MsgPackLastError -
MsgPackGetEntryCount.q(*MsgPackData.MsgPackData)
Returns the number of entries in the array or map at the current internal offset, without moving it.
A map entry is a key and a value, and counts as one.
Returns#MsgPack_InvalidSizeon errors and sets the internal error code. -
MsgPackSkip.MsgPack_ErrorCode(*MsgPackData.MsgPackData, FieldCount.q = 1)
Moves the internal offset past the nextFieldCountfields, the ones contained in arrays and maps included.
Map keys and values count as separate fields.
Returns#MsgPack_Error_Successon success, something else otherwise, in which case the offset isn't moved.
Arrays & Maps
-
MsgPackExamine.i(*MsgPackData.MsgPackData, ExaminationOptions.MsgPack_ExaminationOption = 0)
Returns a view over the array or map at the current internal offset, to iterate on withMsgPackNextEntry.
The view is a regularMsgPackDatalimited to the array/map's content, so all the regular read functions work on it, and can't read past it.
It reads straight from*MsgPackData's buffer, which must not be grown or freed while the view is used.
The whole array/map is checked beforehand, and the offset of*MsgPackDatais moved past it.
Returns#Nullon errors and sets the internal error code.
See:MsgPackLastError#MsgPack_ExaminationOptions_Unsafe- Not recommended !
Skips the content check, which is also what finds the array/map's end.
The view can read past the array/map untilMsgPackNextEntryreaches its end, invalid content is only detected while iterating, and the offset of*MsgPackDataisn't moved, useMsgPackSkipafterward.
-
MsgPackNextEntry.b(*Iterator.MsgPackData)
Moves the view's offset to its next entry, the first one on the first call.
Whatever wasn't read from the current entry is skipped, nested arrays/maps included.
Map entries are read key first, then value.
Returns#Trueif an entry is available,#Falseat the end or on errors, with the internal error code set accordingly. -
MsgPackFinish(*Iterator.MsgPackData)
Frees a view fromMsgPackExamine, without touching the underlying buffer.
Define *Iterator.MsgPackData = MsgPackExamine(*MsgPack)
If *Iterator
While MsgPackNextEntry(*Iterator)
Key.s = MsgPackReadString(*Iterator)
If MsgPackFormatCodeToDataType(MsgPackGetFormatCode(*Iterator)) = #MsgPack_DataTypes_Map
*Nested = MsgPackExamine(*Iterator) ; Or leave it, it'll be skipped
; ...
MsgPackFinish(*Nested)
EndIf
Wend
MsgPackFinish(*Iterator)
EndIf
-
MsgPackWriteArray.MsgPack_ErrorCode(*MsgPackData.MsgPackData, *Buffer, BufferSize.q)
Writes an array whose entries are the fields in theBufferSizebytes of MessagePack data at*Buffer, using the smallest array format code that fits.
The data is fully checked and its fields are counted, nested arrays/maps counting as one.
*Buffercan come fromMsgPackFinalize, withMemorySize()as its size, but not from*MsgPackData's own buffer.
Returns#MsgPack_Error_Successon success, something else otherwise, with nothing written. -
MsgPackWriteMap.MsgPack_ErrorCode(*MsgPackData.MsgPackData, *Buffer, BufferSize.q)
Same asMsgPackWriteArray, for maps.
The data must hold an even number of fields, alternating keys and values, or#MsgPack_Error_OddMapFieldCountis returned. -
MsgPackWriteArrayFrom/MapFrom.MsgPack_ErrorCode(*MsgPackData.MsgPackData, *Source.MsgPackData)
Same asMsgPackWriteArray/Map, with the data written so far in*Source, which is left untouched. -
MsgPackWriteFixArray/Array16/Array32/FixMap/Map16/Map32.MsgPack_ErrorCode(*MsgPackData.MsgPackData, *Buffer, BufferSize.q)
Same asMsgPackWriteArray/Map, but forces the given format code.
Returns#MsgPack_Error_TooManyEntriesif the entries don't fit in it.
Remarks
- Never touch the
MsgPackDatastructure unless you absolutely have to.
Support
- Both the ASM and C backends
- x86, x64, arm64