Transfer complex data over network

Posted on 1998-11-14
Last Modified: 2013-11-13
I need a way to transfer data of a complex user defined type via network.

My data type includes collections, objects, arrays of variable bounds ...

(The winsock control can only be used with upd-protocoll as this is already used to raise actions on remote workstations; one action could be SendRefreshedData wich makes the remote workstation, that receives this, to send me the described datatype)
Question by:tstrob

Expert Comment

ID: 1444886
The easiest way will be to convert the data into a string, or byte array. Make the first 4 bytes to specify the type of the data. Then just copy the data after the header, adding details as nesseasery, like array size, or size of every element. The receiving procedure will accept it, and translate according to the first 4 bytes
LVL 13

Accepted Solution

Mirkwood earned 330 total points
ID: 1444887
Here are some function that convert a variant (including arrays) to a byte array or string.
Now you can send the complex data as a simple byte array and convert is back at the receiver again.
Objects and Collection cannot be based as raw data (by definition) since they contain pointers.

Function ByteArray2Variant(bytearray As Variant) As Variant
    Dim i As Integer
    Dim tmpStr As String
    For i = LBound(bytearray) To UBound(bytearray)
        tmpStr = tmpStr & Chr(bytearray(i))
    ByteArray2Variant = String2Variant(tmpStr)
End Function

Function Variant2ByteArray(var As Variant) As Variant
    Dim i As Long
    Dim str As String
    Dim bytearray() As Byte
    str = Variant2String(var)
    Dim Length As Long
    Length = Len(str)
    ReDim bytearray(Length)
    For i = 0 To (Length - 1)
        bytearray(i) = AscB(Mid(str, i + 1, 1))
    Variant2ByteArray = bytearray
End Function

Public Function Variant2String(ByVal var As Variant) As String
' Convert a variant to a String (use String2Variant) to retreive the variant
   Dim tmpString As String
   If (IsArray(var)) Then
      tmpString = MakeHeader(var)
      Dim subvar As Variant
      Dim i As Integer
      For i = LBound(var) To UBound(var)
         tmpString = tmpString & Variant2String(var(i))
      Dim strValue As String
      If varType(var) = vbString Then
        strValue = var
        strValue = LTrim(str(var))
      End If
      tmpString = MakeHeader(var, Len(strValue)) & strValue
   End If
   Variant2String = tmpString
End Function

Public Function String2Variant(ByVal str As String, Optional ByRef index As Integer = 1) As Variant
' Retreive variant from the String build by Variant2String
    Dim tmpVariant As Variant
    Dim varType As Integer
    index = GetType(str, index, varType)
    If ((varType And vbArray) = vbArray) Then
        Dim vlbound As Integer
        Dim vubound As Integer
        index = GetBounds(str, index, vlbound, vubound)
        Dim i As Integer
        ReDim tmpVariant(vlbound To vubound)
        For i = vlbound To vubound
            tmpVariant(i) = String2Variant(str, index)
        Dim valLength As Integer
        index = GetLength(str, index, valLength)
        tmpVariant = GetValue(str, index, varType, valLength)
        index = index + valLength
    End If
    String2Variant = tmpVariant
End Function
Private Function GetValue(ByVal str As String, ByVal index As Integer, _
                            ByVal varType As Integer, ByVal varLen As Integer) As Variant
    Dim tmpString As String
    Dim tmpVariant As Variant
    tmpString = Mid(str, index, varLen)
    Select Case varType
       Case vbEmpty
             'To nothing
       Case vbNull
             Debug.Assert 0
       Case vbInteger
             Dim tmpInt As Integer
             tmpInt = Val(tmpString)
             tmpVariant = tmpInt
       Case vbLong
             Dim tmpLong As Long
             tmpLong = Val(tmpString)
             tmpVariant = tmpLong
       Case vbSingle
             Dim tmpSingle As Single
             tmpSingle = Val(tmpString)
             tmpVariant = tmpSingle
       Case vbDouble
             Dim tmpDouble As Double
             tmpDouble = Val(tmpString)
             tmpVariant = tmpDouble
       Case vbCurrency
             Dim tmpCurrency As Currency
             tmpCurrency = tmpString
             tmpVariant = tmpCurrency
       Case vbDate
             Dim tmpDate As Date
             tmpDate = tmpString
             tmpVariant = tmpDate
       Case vbString
             tmpVariant = tmpString
       Case vbObject
             Debug.Assert 0
       Case vbError
             Debug.Assert 0
       Case vbBoolean
             Dim tmpbool As Boolean
             tmpbool = tmpString
             tmpVariant = tmpbool
       Case vbVariant
             Debug.Assert 0
       Case vbDataObject
             Debug.Assert 0
       Case vbDecimal
             Debug.Assert 0
       Case vbByte
             Dim tmpByte As Byte
             tmpVariant = tmpByte
    End Select
    GetValue = tmpVariant
End Function

Private Function GetLength(ByVal str As String, ByVal index As Integer, _
                           ByRef varLength As Integer) As Integer
' retrieve type and length of a value
   Dim possemicolon As Integer
   possemicolon = InStr(index, str, ";")
   varLength = Val(Mid(str, index, possemicolon - index))
   GetLength = possemicolon + 1
End Function
Private Function GetBounds(ByVal str As String, ByVal index As Integer, _
                           ByRef varLBound As Integer, _
                           ByRef varUBound As Integer) As Integer
' retrieve UBound and LBound of an array
   Dim possemicolon As Integer
   Dim posdots As Integer
   posdots = InStr(index, str, ":")
   possemicolon = InStr(index, str, ";")
   varLBound = Val(Mid(str, index, posdots - index))
   varUBound = Val(Mid(str, posdots + 1, possemicolon - posdots - 1))
   GetBounds = possemicolon + 1
End Function
Private Function GetType(ByVal str As String, ByVal index As Integer, _
                         ByRef varType As Integer) As Integer
' retrieve varianttype
   Dim poscomma As Integer
   poscomma = InStr(index, str, ",")
   varType = Val(Mid(str, index, poscomma - index))
   GetType = poscomma + 1
End Function

Private Function MakeHeader(ByVal value As Variant, _
                            Optional ByVal Lenght As Integer = 0) As String
    Dim strType As String
    Dim strLen As String
    Dim strLBound, strUBound As String
    If (IsArray(value)) Then
        ' Type,LBound:LBound;
        strType = LTrim(str(varType(value)))
        strLBound = LTrim(str(LBound(value)))
        strUBound = LTrim(str(UBound(value)))
        MakeHeader = strType & "," & strLBound & ":" & strUBound & ";"
        ' Type,Len;
        strType = LTrim(str(varType(value)))
        strLen = LTrim(str(Lenght))
        MakeHeader = strType & "," & strLen & ";"
    End If
End Function


Featured Post

Windows Server 2016: All you need to know

Learn about Hyper-V features that increase functionality and usability of Microsoft Windows Server 2016. Also, throughout this eBook, you’ll find some basic PowerShell examples that will help you leverage the scripts in your environments!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Enums (shorthand for ‘enumerations’) are not often used by programmers but they can be quite valuable when they are.  What are they? An Enum is just a type of variable like a string or an Integer, but in this case one that you create that contains…
If you need to start windows update installation remotely or as a scheduled task you will find this very helpful.
This tutorial covers a step-by-step guide to install VisualVM launcher in eclipse.
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…

832 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question