Italian Come convertire serializator.ConvertObjectToBytes("comando da inviare") in vba?

amorosik

Expert
Licensed User
Dispongo di una routine in B4J che invia dei messaggi ad un broker mqtt, nel mio caso Mosquitto, indirizzati a dei telefoni
Sto usando a bordo dei telefoni le classiche routine descritte negli esempi di Erel, che usano la serializzazione delle stringhe da inviare e quando ricevute la de-serializzazione
Vorrei mantenere il meccanismo dell'invio messaggio 'serializzato' anche inviando messaggi al broker mqtt da programmi tipo Excel/Access che usano il vba
Ambiente nel quale la funzione di serializzazione degli oggetti, come realizzata negli ambienti B4X, non e' disponibile
La domanda e': come replicare in vba le funzioni di serializzazione presenti in B4X?
In sostanza, come fare per convertire queste poche righe in vba (ottenendo un file col contenuto uguale):

B4X:
Dim serializator As B4XSerializator
Dim byte_array as byte()=serializator.ConvertObjectToBytes("comando da inviare")
Dim out As OutputStream=File.OpenOutput(File.DirApp,"aaa_test_serializzazione.txt",False)
out.WriteBytes(byte_array,0,byte_array.Length)
out.Close
 
Last edited:

sirjo66

Well-Known Member
Licensed User
Longtime User
il B4XSerializator utilizza un formato tutto suo oppure un formato standard, quale ad esempio il JSON ???
Dopo la riga Dim byte_array as byte()=serializator.ConvertObjectToBytes("comando da inviare"), cosa ti trovi sull'array byte_array ?
 

amorosik

Expert
Licensed User
Veramente e' la domanda che ho fatto io 🤣
Comunque, usando questo codice

B4X:
Dim ser As B4XSerializator
Dim byte_array() As Byte
byte_array=ser.ConvertObjectToBytes("Esempio di comando")
Dim out As OutputStream=File.OpenOutput(File.DirApp,"aaa_test_serializzazione.txt",False)
out.WriteBytes(byte_array,0,byte_array.Length)
out.Close

il contenuto del file di testo, da 31 byte, e' questo

1680444770020.png


Sembra essere un formato proprietario
 
Last edited:

sirjo66

Well-Known Member
Licensed User
Longtime User
si, sembra proprio un formato proprietario, per cui credo proprio non riuscirai a gestirlo.
Ma il broker mqtt accetta solo questo tipo di formato ??
 

amorosik

Expert
Licensed User
si, sembra proprio un formato proprietario, per cui credo proprio non riuscirai a gestirlo.
Ma il broker mqtt accetta solo questo tipo di formato ??

No, accetta anche il testo in chiaro
Ma avendo dal lato ricevitore del messaggio la sezione di codice che riceve gia' ora dal formato serializzato, volevo evitare di cambiare quella parte la'
Mi sa che dovro' duplicare la sezione lato ricevitore, una per il formato serializzato, una seconda per il formato in chiaro
Che era quel che volevo evitare
Adesso chiedo a chatgpt 😇
 

amorosik

Expert
Licensed User
Ringrazio per il consiglio
Si avevo gia' visto, ma non cambia la sostanza
Dovrei fare un programma dot net al quale mandare il mio messaggio in chiaro, sempre di due pezzi avrei bisogno
Tanto vale fare programma B4J
Il mio obiettivo era comprendere cosa faccia la ConvertObjectToBytes per riprodurne il funzionamento dentro Excel in modo da avere tutto dentro unico sistema
 

Victorh2877

Member
Licensed User
c'è tutto il necessario per fare quello che hai chiesto.

Leggi tutto il post e c'è la soluzione.
https://www.b4x.com/android/forum/t...lementation-of-b4xserializator.73080/#content

Devi prendere il codice di c# e convertirlo in VBA o in qualsiasi altro linguaggio hai necessità.
per il VBA al post #3 c'è il convertitore di codice http://converter.telerik.com/


Code:
Public Class B4XSerializator
    Private Const T_NULL As Byte = 0, T_STRING As Byte = 1, T_SHORT As Byte = 2, T_INT As Byte = 3, T_LONG As Byte = 4, T_FLOAT As Byte = 5, T_DOUBLE As Byte = 6, T_BOOLEAN As Byte = 7, T_BYTE As Byte = 10, T_CHAR As Byte = 14, T_MAP As Byte = 20, T_LIST As Byte = 21, T_NSARRAY As Byte = 22, T_NSDATA As Byte = 23, T_TYPE As Byte = 24
    Private br As BinaryReader
    Private bw As BinaryWriter
    Private ReadOnly utf8 As UTF8Encoding

    Public Sub New()
        utf8 = New UTF8Encoding(False)
    End Sub

    Public Function ConvertBytesToObject(ByVal Bytes As Byte()) As Object
        Using inf As InflaterInputStream = New InflaterInputStream(New MemoryStream(Bytes))
            br = New BinaryReader(inf)
            Dim ret As Object = readObject()
            Return ret
        End Using
    End Function

    Public Function ConvertObjectToBytes(ByVal Object As Object) As Byte()
        Dim ms As MemoryStream = New MemoryStream()

        Using def As DeflaterOutputStream = New DeflaterOutputStream(ms)
            bw = New BinaryWriter(def)
            writeObject(Object)
        End Using

        Return ms.ToArray()
    End Function

    Private Sub writeObject(ByVal o As Object)
        If o Is Nothing Then
            writeByte(T_NULL)
        ElseIf TypeOf o Is Integer Then
            writeByte(T_INT)
            writeInt(CInt(o))
        ElseIf TypeOf o Is Double Then
            writeByte(T_DOUBLE)
            bw.Write(CDbl(o))
        ElseIf TypeOf o Is Single Then
            writeByte(T_FLOAT)
            bw.Write(CSng(o))
        ElseIf TypeOf o Is Long Then
            writeByte(T_LONG)
            bw.Write(CLng(o))
        ElseIf TypeOf o Is Byte Then
            writeByte(T_BYTE)
            bw.Write(CByte(o))
        ElseIf TypeOf o Is Short Then
            writeByte(T_SHORT)
            bw.Write(CShort(o))
        ElseIf TypeOf o Is Char Then
            writeByte(T_CHAR)
            bw.Write(CShort(CChar(o)))
        ElseIf TypeOf o Is Boolean Then
            writeByte(T_BOOLEAN)
            writeByte(CByte((If(CBool(o), 1, 0))))
        ElseIf TypeOf o Is String Then
            Dim temp As Byte() = utf8.GetBytes(CStr(o))
            writeByte(T_STRING)
            writeInt(temp.Length)
            bw.Write(temp, 0, temp.Length)
        ElseIf TypeOf o Is List(Of Object) Then
            writeByte(T_LIST)
            writeList(CType(o, List(Of Object)))
        ElseIf TypeOf o Is Dictionary(Of Object, Object) Then
            writeByte(T_MAP)
            writeMap(CType(o, Dictionary(Of Object, Object)))
        ElseIf o.[GetType]().IsArray Then

            If TypeOf o Is Byte() Then
                writeByte(T_NSDATA)
                Dim b As Byte() = CType(o, Byte())
                writeInt(b.Length)
                bw.Write(b, 0, b.Length)
            ElseIf TypeOf o Is Object() Then
                writeByte(T_NSARRAY)
                writeList(New List(Of Object)(CType(o, Object())))
            Else
                Throw New Exception("Only arrays of bytes or objects are supported.")
            End If
        ElseIf TypeOf o Is B4XType Then
            writeByte(T_TYPE)
            writeType(CType(o, B4XType))
        Else
            Throw New Exception("Type not supported: " & o.[GetType]())
        End If
    End Sub

    Private Sub writeMap(ByVal m As Dictionary(Of Object, Object))
        writeInt(m.Count)

        For Each kvp As KeyValuePair(Of Object, Object) In m
            writeObject(kvp.Key)
            writeObject(kvp.Value)
        Next
    End Sub

    Private Sub writeList(ByVal list As List(Of Object))
        writeInt(list.Count)

        For Each o As Object In list
            writeObject(o)
        Next
    End Sub

    Private Function readObject() As Object
        Dim t As Byte = br.ReadByte()
        Dim len As Integer
        Dim b As Byte()

        Select Case t
            Case T_NULL
                Return Nothing
            Case T_INT
                Return readInt()
            Case T_SHORT
                Return readShort()
            Case T_LONG
                Return br.ReadInt64()
            Case T_FLOAT
                Return br.ReadSingle()
            Case T_DOUBLE
                Return br.ReadDouble()
            Case T_BOOLEAN
                Return br.ReadByte() = 1
            Case T_BYTE
                Return br.ReadByte()
            Case T_STRING
                len = readInt()
                b = br.ReadBytes(len)
                Return utf8.GetString(b)
            Case T_CHAR
                Return ChrW(readShort())
            Case T_LIST
                Return readList()
            Case T_MAP
                Return readMap()
            Case T_NSDATA
                len = readInt()
                Return br.ReadBytes(len)
            Case T_NSARRAY
                Dim list As List(Of Object) = readList()
                Return list.ToArray()
            Case T_TYPE
                Return readType()
            Case Else
                Throw New Exception("Unsupported type: " & t)
        End Select
    End Function

    Private Sub writeByte(ByVal b As Byte)
        bw.Write(b)
    End Sub

    Private Sub writeInt(ByVal i As Integer)
        bw.Write(i)
    End Sub

    Private Function readList() As List(Of Object)
        Dim len As Integer = readInt()
        Dim arr As List(Of Object) = New List(Of Object)(len)

        For i As Integer = 0 To len - 1
            arr.Add(readObject())
        Next

        Return arr
    End Function

    Private Function readMap() As Dictionary(Of Object, Object)
        Dim len As Integer = readInt()
        Dim mm As Dictionary(Of Object, Object) = New Dictionary(Of Object, Object)()

        For i As Integer = 0 To len - 1
            mm(readObject()) = readObject()
        Next

        Return mm
    End Function

    Private Function readInt() As Integer
        Return br.ReadInt32()
    End Function

    Private Function readShort() As Short
        Return br.ReadInt16()
    End Function

    Private Function readType() As Object
        Dim cls As String = CStr(readObject())
        Dim data = readMap()
        Return New B4XType(cls, data)
    End Function

    Private Sub writeType(ByVal t As B4XType)
        writeObject("_" & t.ClassName)
        writeMap(t.Fields)
    End Sub
End Class
 

amorosik

Expert
Licensed User
Certo che c'e' tutto il necessario, ma racchiuso dentro una libreria
Prima di postare ho letto l'articolo consigliato, che tra l'altro gia' conoscevo
E se apri il file di esempio vedrai che una delle prime righe e'

using ICSharpCode.SharpZipLib.Zip.Compression.Streams;

dalla quale vengono prese dele funzioni essenziali per lo svolgimento del lavoro
Cercando in rete si trova pure la SharpZipLib ma e' un cincinin troppo complicato (per le mie conoscenze) andare ad indagare cosa faccia la libreria e replicarne il funzionamento in vba

Il convertitore telerik ti converte da c# a vbnet e viceversa, col vba c'ha poco a che fare
Pure ChatGpt ha iniziato "..e basta e basta co ste domande..." 🤣
 
Last edited:
Top