mirror of
https://github.com/aziascreations/PB-MessagePack.git
synced 2026-11-03 17:01:24 +01:00
Added Finalize function, Added basic example
This commit is contained in:
@@ -110,6 +110,13 @@ PureBasic include for creating/reading MessagePack data.
|
||||
Frees a given internal structure `*MsgPackData` and its associated buffer if `FreeDataBuffer` is `#True`.
|
||||
Returns `#True` if freed properly, `#False` otherwise.
|
||||
|
||||
* `MsgPackFinalize.i(*MsgPackData.MsgPackData)` \
|
||||
Frees a given internal structure `*MsgPackData` and returns its buffer, shrunk to the number of bytes written. \
|
||||
The caller takes ownership of the buffer, gets its size with `MemorySize()` and frees it with `FreeMemory()`. \
|
||||
Fails if the buffer is owned by the caller or nothing was written. \
|
||||
Returns `#Null` on errors and leaves `*MsgPackData` untouched. \
|
||||
See: `MsgPackLastError`
|
||||
|
||||
|
||||
### Literals
|
||||
* `MsgPackReadBoolean.b(*MsgPackData.MsgPackData)`
|
||||
|
||||
@@ -0,0 +1,119 @@
|
||||
; ------------------------------------------------------------------------------
|
||||
;- Notes
|
||||
|
||||
; This example show you how to write, export and read a MessagePack buffer
|
||||
; with implicitely typed variables whose format code is automatically
|
||||
; resolved based on the given data.
|
||||
|
||||
|
||||
; ------------------------------------------------------------------------------
|
||||
;- Example
|
||||
|
||||
EnableExplicit
|
||||
|
||||
XIncludeFile "../../Includes/MessagePack.pbi"
|
||||
|
||||
Structure MyDataPacket
|
||||
Id.q
|
||||
UserName.s
|
||||
EndStructure
|
||||
|
||||
Procedure.b EncodeMyDataPacket(*MsgPackData, *Input.MyDataPacket)
|
||||
If MsgPackWriteInteger(*MsgPackData, *Input\Id) <> #MsgPack_Error_Success
|
||||
ProcedureReturn #False
|
||||
EndIf
|
||||
|
||||
If MsgPackWriteString(*MsgPackData, *Input\UserName) <> #MsgPack_Error_Success
|
||||
ProcedureReturn #False
|
||||
EndIf
|
||||
|
||||
ProcedureReturn #True
|
||||
EndProcedure
|
||||
|
||||
Procedure.b DecodeMyDataPacket(*MsgPackData, *Output.MyDataPacket)
|
||||
*Output\Id = MsgPackReadInteger(*MsgPackData)
|
||||
If MsgPackLastError(*MsgPackData) <> #MsgPack_Error_Success
|
||||
ProcedureReturn #False
|
||||
EndIf
|
||||
|
||||
*Output\UserName = MsgPackReadString(*MsgPackData)
|
||||
If MsgPackLastError(*MsgPackData) <> #MsgPack_Error_Success
|
||||
ProcedureReturn #False
|
||||
EndIf
|
||||
|
||||
ProcedureReturn #True
|
||||
EndProcedure
|
||||
|
||||
|
||||
|
||||
; Obscure structures that hold info about the MsgPack data
|
||||
Define *Writer, *Reader
|
||||
|
||||
; MsgPack-encoded buffer that will get exported midway in this example.
|
||||
Define *Buffer
|
||||
|
||||
; Structure that will hold the data to encode and the decoded one.
|
||||
; You could replace this with whatever you want in your use cases.
|
||||
Define InputStruct.MyDataPacket, OutputStruct.MyDataPacket
|
||||
|
||||
|
||||
|
||||
; Preparing the input structure.
|
||||
With InputStruct
|
||||
\Id = 67
|
||||
\UserName = "Herwin"
|
||||
EndWith
|
||||
|
||||
|
||||
; Writing the data into the buffer.
|
||||
; Leaving out the `GrowthIncrement` parameter causes reallocations of the required size on every write.
|
||||
; Setting it to any value higher than 1 would force the library to allocate memory in blocks of X bytes.
|
||||
*Writer = MsgPackCreate(64)
|
||||
If Not *Writer
|
||||
Debug "Failed to create the writer !"
|
||||
End 1
|
||||
EndIf
|
||||
|
||||
If Not EncodeMyDataPacket(*Writer, @InputStruct)
|
||||
Debug "Failed to encode the packet !"
|
||||
End 2
|
||||
EndIf
|
||||
|
||||
|
||||
; Exporting the data.
|
||||
; Doing this frees the obscure structure in `*Writer`.
|
||||
; It also resizes the final buffer to the appropriate size.
|
||||
*Buffer = MsgPackFinalize(*Writer)
|
||||
If Not *Buffer
|
||||
Debug "Failed to finalize the writer !"
|
||||
End 3
|
||||
EndIf
|
||||
|
||||
Debug "Encoded size: " + Str(MemorySize(*Buffer))
|
||||
|
||||
|
||||
; It also gives ownership of the buffer to the obscure structure.
|
||||
; And it is marked internally as read-only.
|
||||
*Reader = MsgPackWrapMsgBuffer(*Buffer, MemorySize(*Buffer), #True)
|
||||
If Not *Reader
|
||||
Debug "Failed to wrap the buffer !"
|
||||
End 4
|
||||
EndIf
|
||||
|
||||
|
||||
; Getting data out of the MsgPack buffer.
|
||||
OutputStruct.MyDataPacket
|
||||
If Not DecodeMyDataPacket(*Reader, @OutputStruct)
|
||||
Debug "Failed to decode the packet !"
|
||||
End 5
|
||||
EndIf
|
||||
|
||||
Debug "Id: " + Str(OutputStruct\Id)
|
||||
Debug "UserName: " + OutputStruct\UserName
|
||||
|
||||
|
||||
; Freeing the obscure structure.
|
||||
; Since it owns the buffer, it will also free it.
|
||||
MsgPackFree(*Reader, #True)
|
||||
|
||||
End 0
|
||||
@@ -113,6 +113,42 @@ Procedure.b MsgPackFree(*MsgPackData.MsgPackData, FreeDataBuffer.b = #False)
|
||||
ProcedureReturn #True
|
||||
EndProcedure
|
||||
|
||||
; Frees a given internal structure and returns its buffer, shrunk to the number of bytes
|
||||
; written so far (`BufferOffset`), whose size can be obtained with `MemorySize()`.
|
||||
; The caller takes ownership of the returned buffer and must free it with `FreeMemory()`.
|
||||
; Returns `#Null` on errors, in which case `*MsgPackData` and its buffer are left untouched.
|
||||
Procedure.i MsgPackFinalize(*MsgPackData.MsgPackData)
|
||||
Protected *FinalBuffer
|
||||
|
||||
If Not *MsgPackData
|
||||
DebuggerError("A #Null MsgPackData pointer was passed !")
|
||||
ProcedureReturn #Null
|
||||
EndIf
|
||||
|
||||
If _MsgPackHasFlag(*MsgPackData, #MsgPack_DataFlags_NoBufferFree)
|
||||
DebuggerError("Cannot finalize a buffer that is still owned by the caller !")
|
||||
*MsgPackData\LastError = #MsgPack_Error_InvalidValue
|
||||
ProcedureReturn #Null
|
||||
EndIf
|
||||
|
||||
If *MsgPackData\BufferOffset <= 0
|
||||
DebuggerError("Cannot finalize an empty buffer !")
|
||||
*MsgPackData\LastError = #MsgPack_Error_InvalidValue
|
||||
ProcedureReturn #Null
|
||||
EndIf
|
||||
|
||||
*FinalBuffer = ReAllocateMemory(*MsgPackData\Buffer, *MsgPackData\BufferOffset, #PB_Memory_NoClear)
|
||||
If Not *FinalBuffer
|
||||
Debug("Failed to shrink memory for buffer !")
|
||||
*MsgPackData\LastError = #MsgPack_Error_FailedToGrowBuffer
|
||||
ProcedureReturn #Null
|
||||
EndIf
|
||||
|
||||
FreeStructure(*MsgPackData)
|
||||
|
||||
ProcedureReturn *FinalBuffer
|
||||
EndProcedure
|
||||
|
||||
|
||||
; TODO: Add callback in the structure, maybe ?
|
||||
; FIXME: Use a .q for the size !!!!
|
||||
|
||||
@@ -66,6 +66,8 @@ 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))
|
||||
* [Louis Somers](https://github.com/mlsomers)
|
||||
* LsMsgPack windows utility ([GitHub repository](https://github.com/mlsomers/LsMsgPack))
|
||||
|
||||
|
||||
## License
|
||||
|
||||
Reference in New Issue
Block a user