Results 1 to 32 of 32

Thread: Extremely difficult - Serialize a UDT

  1. #1

    Thread Starter
    Addicted Member Martin Wilson's Avatar
    Join Date
    Mar 2002
    Location
    :)
    Posts
    236

    Extremely difficult - Serialize a UDT

    How can I serialize a UDT into a byte array...I tried CopyMemory, but that also copies the padding bytes. I need universal code so that I supply any UDT and a byte array is returned...any ideas...thanks.
    Last edited by Martin Wilson; May 31st, 2002 at 11:25 AM.
    What is the answer to this question?

  2. #2
    DerFarm
    Guest
    What's a UDT?

  3. #3
    Fanatic Member skald2k's Avatar
    Join Date
    Feb 2002
    Location
    Sydney, Australia
    Posts
    535
    User Definite Type.
    - If at first you dont succeed, then give up, cause you will never will!

  4. #4
    Fanatic Member Slaine's Avatar
    Join Date
    Jul 2002
    Posts
    641
    Originally posted by skald2k
    User Definite Type.
    User Defined Type
    Martin J Wallace (Slaine)

  5. #5
    DerFarm
    Guest
    Ah! so you have a User Defined Type something on the order of:

    Code:
    Define Person
       Name as Text
       Dbay as Date
       SSN   as Text
    ....
    and you want to run it through a function to return a binary string
    suitable for saving and then re-loading at a future time.

    Is this the gist of the question?

    And you want it to work with ANY UDT that you can come up with
    in the future?

  6. #6

    Thread Starter
    Addicted Member Martin Wilson's Avatar
    Join Date
    Mar 2002
    Location
    :)
    Posts
    236
    You've sort of got it...basically I want to send graphics headers through winsock.
    What is the answer to this question?

  7. #7

    Thread Starter
    Addicted Member Martin Wilson's Avatar
    Join Date
    Mar 2002
    Location
    :)
    Posts
    236
    Everything I have found suggests saving the udt to a file and then loading it into a byte array...which is what I was doing before. Are there any other methods?
    What is the answer to this question?

  8. #8
    Frenzied Member
    Join Date
    Aug 2000
    Location
    O!
    Posts
    1,177

    Re: Serialize a UDT.

    Originally posted by Martin Wilson
    How can I serialize a UDT into a byte array...I tried CopyMemory, but that also copies the padding bytes. I need universal code so that I supply any UDT and a byte array is returned...any ideas...thanks.
    What does your UDT look like? I send large (6000+ bytes) UDTs to C and COBOL servers with no problems.

    We do a lot of inter-program communication and the programs are written in various languages (C, COBOL, TAL, VC++, VB) so we generally standardize the interprocess messages to look like COBOL records. Also, because different platforms allocate different sizes for certain data types, we stick to Integers, Longs and fixed length Strings.

    When I want a UDT within a UDT, I use a fixed length String as a place holder and CopyMemory the internal UDT into the String.

    For example:
    VB Code:
    1. Public Type dclStdHeader                          ' current length = 52
    2.             ttl_len               As Long         ' long  ttl_len;
    3.             msgtype               As Long         ' long  msgtype;
    4.             orig_id               As Long         ' long  orig_id;
    5.             seq_num               As Long         ' long  seq_num;
    6.             tran_type             As Long         ' long  tran_type;
    7.             curr_wndw             As Long         ' long  curr_wndw;
    8.             curr_req              As Integer      ' short curr_req
    9.             user_def              As String * 26  ' char  user_def[26];
    10.        End Type
    11. Public Type dclTypeStatus                         ' current length = 124
    12.             name                  As String * 8   ' char  pname[8];
    13.             custid                As String * 8   ' char  cust[8];
    14.             svrclass              As String * 16  ' char  svrclass[16];
    15.             pthway                As String * 16  ' char  pthway[16];
    16.             errtime               As String * 20  ' char  errdate[20];
    17.             state                 As String * 12  ' char  state[12];
    18.             lasterr               As String * 6   ' char  lasterr[6];
    19.             proctype              As String * 6   ' short proctype[6];
    20.             restarts              As String * 4   ' char  restarts[4];
    21.             monitorname           As String * 8   ' char  monitorname[8];
    22.             errordesc             As String * 20  ' char  errordesc[20];
    23.        End Type
    24. Public Type dclStatusRep
    25.             rep_hdr               As String * 52  ' holder for dclStdHeader
    26.             repid                 As Integer      ' short rtncode;
    27.             system                As Integer      ' short system;
    28.             index                 As Integer      ' short index;
    29.             lines                 As Integer      ' short linecnt;
    30.             statline(giMaxLines)  As String * 124 ' holders for dclTypeStatus
    31.        End Type
    Records of type dclStatusRep are returned from a C program - the equivalent C struct fields are listed in the comments to the right.

    rep_hdr is a holder for the header UDT and statline is an array of (50) holders for the status record UDTs.

    HTH

  9. #9

    Thread Starter
    Addicted Member Martin Wilson's Avatar
    Join Date
    Mar 2002
    Location
    :)
    Posts
    236
    This file demonstrate the problem...compare the 2 files produced.

    The problems occurs because in memory, longs need to start on a 4 byte boundary, but as the UDT starts with an integer, 2 padding bytes need to be added. Instead of IILLLL, you get IIPPLLLL.
    Attached Files Attached Files
    Last edited by Martin Wilson; May 31st, 2002 at 10:33 AM.
    What is the answer to this question?

  10. #10
    Frenzied Member KayJay's Avatar
    Join Date
    Jul 2001
    Location
    Chennai
    Posts
    1,849
    Use LSET.

    [Highlight=VB]
    Private Type Person
    Name As String * 30
    Age As Integer
    Sex As String * 1
    MaritalStatus As String * 10
    End Type
    Private Type Car
    Make As String * 30
    Model As String * 30
    Color As String * 10
    End Type
    Private Type Marks
    Math As Integer
    English As Integer
    Physics As Integer
    Geography As Integer
    Biology As Integer
    Chemistry As Integer
    History As Integer
    End Type

    Private Type CarSummaryType
    Buffer As String * 70
    End Type

    Private Type PersonSummaryType
    Buffer As String * 42
    End Type

    Private Type MarksSummaryType
    Buffer As String * 7
    End Type


    Dim MySelf As Person
    Dim MyCar As Car
    Dim MyMarks As Marks
    Dim MyCarSummary As CarSummaryType
    Dim MySelfSummary As PersonSummaryType
    Dim MyMarksSummary As MarksSummaryType


    Private Sub Command1_Click()
    MySelf.Age = 24
    MySelf.MaritalStatus = "Single"
    MySelf.Name = "KayJay"
    MySelf.Sex = "M"

    MyCar.Make = "Mercedez Benz"
    MyCar.Model = "C-Class Saloon"
    MyCar.Color = "Raven"

    MyMarks.Biology = 80
    MyMarks.Chemistry = 90
    MyMarks.English = 70
    MyMarks.Geography = 85
    MyMarks.History = 75
    MyMarks.Math = 95
    MyMarks.Physics = 80


    LSet MyCarSummary = MyCar
    LSet MySelfSummary = MySelf
    LSet MyMarksSummary = MyMarks

    MsgBox MyCarSummary.Buffer
    MsgBox MySelfSummary.Buffer
    GetValuesForMarks MyMarksSummary.Buffer


    End Sub

    Private Sub GetValuesForMarks(Buffer As String)
    Dim udtDetails As Marks
    Dim udtSummary As MarksSummaryType
    udtSummary.Buffer = Buffer
    LSet udtDetails = udtSummary
    With udtDetails
    Debug.Print .Biology
    Debug.Print .Chemistry
    End With
    End Sub
    [Highlight=VB]

    with the above u could pass the "BUFFER" as string over winsock and then use something like the "GETVALUES....." sub-routine to reconctruct the data at the other end.

    "Brothers, you asked for it."
    ...Francisco Domingo Carlos Andres Sebastian D'Anconia

  11. #11

    Thread Starter
    Addicted Member Martin Wilson's Avatar
    Join Date
    Mar 2002
    Location
    :)
    Posts
    236
    The other end is a webbrowser so I can't control how it does it unfortunately.
    What is the answer to this question?

  12. #12
    Frenzied Member KayJay's Avatar
    Join Date
    Jul 2001
    Location
    Chennai
    Posts
    1,849
    Does this help?
    Attached Files Attached Files

    "Brothers, you asked for it."
    ...Francisco Domingo Carlos Andres Sebastian D'Anconia

  13. #13

    Thread Starter
    Addicted Member Martin Wilson's Avatar
    Join Date
    Mar 2002
    Location
    :)
    Posts
    236
    No You are just re-declaring the UDT...the data needs to be sent by winsock...which doesn't accept UDTs.
    What is the answer to this question?

  14. #14
    Frenzied Member KayJay's Avatar
    Join Date
    Jul 2001
    Location
    Chennai
    Posts
    1,849
    Since LEN and LENB are giving problems

    The attachment?
    Attached Files Attached Files

    "Brothers, you asked for it."
    ...Francisco Domingo Carlos Andres Sebastian D'Anconia

  15. #15

    Thread Starter
    Addicted Member Martin Wilson's Avatar
    Join Date
    Mar 2002
    Location
    :)
    Posts
    236
    That is what I was doing before and it does work...but I want to get rid of the file access and send the UDT more directly. The file access seems pointless and slows the code down.
    What is the answer to this question?

  16. #16
    PowerPoster
    Join Date
    Mar 2002
    Location
    UK
    Posts
    4,780
    You cannot (that I know of) serialize a UDT without creating a compress/expand routine.

    In .net and java you can as you can base your class on the serialization object.


    Heres my sugesstion, turn then UDT into a class.
    Create a function inside that serialises it, and also that expands it. And just call the functions, you can also make it return a byte array etc, or exactly how you want it formated.

    i.e

    VB Code:
    1. 'MyClass
    2. Private strString as String
    3. Private intInteger as Integer
    4.  
    5. Public funcCompressMe() as String
    6.  
    7.    funcCompressMe = strstring & "MY$PLIT"  & intInteger  & "MY$PLIT"
    8.  
    9. End Function
    10.  
    11. Public Sub procExpandMe(Data as String)
    12.  
    13. dim strData() as String
    14.  
    15. strData = Split(Data,"MY$PLIT")
    16. strString = strData(0)
    17. intInteger = Int(Val(strData(1))
    18.  
    19. End Sub

    Its just a quick demo, but I use something similar for my project atm. But more advanced version.

  17. #17

    Thread Starter
    Addicted Member Martin Wilson's Avatar
    Join Date
    Mar 2002
    Location
    :)
    Posts
    236
    Then I would need a seperate class for each UDT. There must be a way as the udt is stored correctly when saved to a file...does anyone know where I can the source to vb functions?
    What is the answer to this question?

  18. #18
    PowerPoster
    Join Date
    Mar 2002
    Location
    UK
    Posts
    4,780
    How do you store it now ? Give some example code.

  19. #19
    Hyperactive Member
    Join Date
    Mar 2000
    Location
    Pittsburgh, PA
    Posts
    329
    what does Serialize mean?
    ______________

  20. #20
    Frenzied Member KayJay's Avatar
    Join Date
    Jul 2001
    Location
    Chennai
    Posts
    1,849
    JAT.

    If we use property bags, would it take the same amount of effort as for creating a Class?

    Say something like : -

    VB Code:
    1. Private Type BITMAPFILEHEADER
    2.         bfType As Integer
    3.         bfSize As Long
    4.         bfReserved1 As Integer
    5.         bfReserved2 As Integer
    6.         bfOffBits As Long
    7. End Type
    8. Private Sub Command1_Click()
    9.     Dim FileHeader As BITMAPFILEHEADER
    10.     FileHeader.bfType = &H4D42
    11.     FileHeader.bfOffBits = Len(FileHeader) + CLng(40)
    12.     FileHeader.bfSize = Len(FileHeader) + CLng(40 + 100)
    13.     Open "C:\windows.000\desktop\UDT.txt" For Binary As #1
    14.         Put #1, , FileHeader
    15.     Close #1
    16.  
    17.  
    18.  
    19.  
    20.  
    21. Dim propbag As New PropertyBag
    22. Dim propArray() As Byte
    23. Dim thearray() As Byte
    24. propbag.WriteProperty "bfType", &H4D42
    25. propbag.WriteProperty "bfOffBits", Len(FileHeader) + CLng(40)
    26. propbag.WriteProperty "bfSize", Len(FileHeader) + CLng(40 + 100)
    27.  
    28. propArray() = propbag.Contents
    29. End
    30.  
    31. End Sub

    You could then parse the resultant Byte array and strip them off the inherent PropBag data which should be fixed in lengths. JAT

    "Brothers, you asked for it."
    ...Francisco Domingo Carlos Andres Sebastian D'Anconia

  21. #21
    PowerPoster
    Join Date
    Mar 2002
    Location
    UK
    Posts
    4,780
    Well, there a few terms for serialization, but heres the one thats being discussed.


    You have a data structure, which holds certain data.
    When you serialize the structure, you convert the data into a stream. You can then send / save the data, and then later on un-serialize it back into its original form.

    A very good use is saving EXACTLY all the variables and there states in a class, and as such you can load them back up again with no problem. Imagin if you save serialized data to disk every 5 seconds, and then your PC crashes. You can just load up the last set of data back into the class, and it will act exactly how you left it.

    In this case, the strucuture is a picture, and the struture wants to be serialized so it can be sent across IP to another computer, that can then expand it back out.

  22. #22

    Thread Starter
    Addicted Member Martin Wilson's Avatar
    Join Date
    Mar 2002
    Location
    :)
    Posts
    236
    All I want to send are image headers to a web browser followed by the image data.
    What is the answer to this question?

  23. #23
    Hyperactive Member
    Join Date
    Feb 2001
    Location
    LoCal
    Posts
    280
    Not sure if this would work but I used this to move stuff among COM servers...

    Try using LSet and defining a second UDT that has the same byte length as the UDT you're trying to pass.

    Code:
    Public udtMyType
         Name as string * 30
         City as string * 20
    End Type
    
    Public udtMyTypeSerialized
         Buffer as string *50
    End Type
    
    Public udtData as udtMyType
    Public udtBuffer as udtMyTypeSerialized
    
    With udtData
         .Name = "Achichincle"
         .City = "San Diego"
    End with
    
    LSet udtBuffer = udtData
    Now udtBuffer is essentially a byte-array in memory of all your data so you should be able to CopyMemory it as needed.

    When you get it to where you want it just do the LSet in reverse...

    It was in a book I read...
    Achichincle

    VB6 (VSEE SP5, W2KPro)
    ASP
    HTML

  24. #24
    Frenzied Member KayJay's Avatar
    Join Date
    Jul 2001
    Location
    Chennai
    Posts
    1,849
    Achichincle, thats been suggested before and he does not want to do that, since he has no conrol over the client App.

    The closest I could manage to serialize a UDT is, as I mentioned using PropertyBags.

    I picked some really cool stuff on the net, forget where. Its great.

    You could (see attachment) do a "FOR EACH...NEXT" with UDT's as properties of a PropertyBag. Thats the closest.

    Check it out Martin and see if it could of any use to u.
    Attached Files Attached Files

    "Brothers, you asked for it."
    ...Francisco Domingo Carlos Andres Sebastian D'Anconia

  25. #25

    Thread Starter
    Addicted Member Martin Wilson's Avatar
    Join Date
    Mar 2002
    Location
    :)
    Posts
    236
    That still requires me to know the elements of the UDT...it would be easier to just add the elements individually. It looks like I gonna have to give up on solving this.
    What is the answer to this question?

  26. #26
    Frenzied Member KayJay's Avatar
    Join Date
    Jul 2001
    Location
    Chennai
    Posts
    1,849
    Good Luck.

    Just asking... If the purpose is to send an image file to a webrowser, why not just use HTTP command? "HTTP /GET...." or what ever the syntax is.

    Are you building the images from code?

    "Brothers, you asked for it."
    ...Francisco Domingo Carlos Andres Sebastian D'Anconia

  27. #27

    Thread Starter
    Addicted Member Martin Wilson's Avatar
    Join Date
    Mar 2002
    Location
    :)
    Posts
    236
    It is sort of an HTTP server, it generates an image depending on the url it recieves and sends it to the browser. That works fine.
    What is the answer to this question?

  28. #28
    Frenzied Member KayJay's Avatar
    Join Date
    Jul 2001
    Location
    Chennai
    Posts
    1,849
    PHEW!!!!!!!

    That was a tough one to crack!! Played with CopyMem, CopyMemByPtr, VarPtr, PropBags. Nah! stumped me.

    Here it goes. VB 6 Not Possible!!!!. VB.Net Possible

    Workaround for VB 6. Get yourself the "VBHLP32.DLL" from http://www.softcircuits.com and then use the attachment. Your Byte Array is as required! You still have to add another parmeter(s) apart from the UDT though.

    Had fun though! 2 days with nothing to do, I was getting mad
    Attached Files Attached Files

    "Brothers, you asked for it."
    ...Francisco Domingo Carlos Andres Sebastian D'Anconia

  29. #29
    Hyperactive Member
    Join Date
    Feb 2001
    Location
    LoCal
    Posts
    280
    KayJay - sorry, I don't know how I missed your post. Gotta start drinking coffe again...
    Achichincle

    VB6 (VSEE SP5, W2KPro)
    ASP
    HTML

  30. #30

    Thread Starter
    Addicted Member Martin Wilson's Avatar
    Join Date
    Mar 2002
    Location
    :)
    Posts
    236
    Thanks a lot KayJay That is great...I still need to provide pszFields but I can cope with that. How did you find it...just searched google?
    Thanks a lot
    What is the answer to this question?

  31. #31
    Frenzied Member KayJay's Avatar
    Join Date
    Jul 2001
    Location
    Chennai
    Posts
    1,849
    Yeah!! Google and Google and Google and Google.......

    Umpteen searches with various keywords and finally

    But learnt a helluva a lot in the process. Especially the undocumented function VartPtr and its derivatives.

    Can u belive that CopyMemByPtr returned only three results from Google & Yahoo & only ONE from Teoma.

    And more, all those point to the same enumeration example of AllAPI Guide. No help at all

    Stumbled somehow on that site.

    Well anyway Good Luck with your app.

    Achichincle, Coffee sounds good. I'll have some myself

    "Brothers, you asked for it."
    ...Francisco Domingo Carlos Andres Sebastian D'Anconia

  32. #32
    PowerPoster
    Join Date
    Mar 2002
    Location
    UK
    Posts
    4,780
    well solved

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width