Read and Write Binary String

Share your advanced PureBasic knowledge/code with the community.
User avatar
Guimauve
Enthusiast
Enthusiast
Posts: 742
Joined: Wed Oct 22, 2003 2:51 am
Location: Canada

Read and Write Binary String

Post by Guimauve »

Code updated For 5.20+

A small exemple to show how to Write and read Structure with all type of variable inside.

Regards
Guimauve

Code: Select all

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Déclaration de la Structure >>>>>

Structure StructTest
  
  Byte.b
  Word.w
  Long.l
  Float.f
  String.s
  
EndStructure

; <<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Les mutateurs >>>>>

Procedure SetStructTestByte(*ObjetA.StructTest, Byte.b)
  
  *ObjetA\Byte = Byte
  
EndProcedure

Procedure SetStructTestWord(*ObjetA.StructTest, Word.w)
  
  *ObjetA\Word = Word
  
EndProcedure

Procedure SetStructTestLong(*ObjetA.StructTest, Long.l)
  
  *ObjetA\Long = Long
  
EndProcedure

Procedure SetStructTestFloat(*ObjetA.StructTest, Float.f)
  
  *ObjetA\Float = Float
  
EndProcedure

Procedure SetStructTestString(*ObjetA.StructTest, String.s)
  
  *ObjetA\String = String
  
EndProcedure

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Les observateurs >>>>>

Procedure.b GetStructTestByte(*ObjetA.StructTest)
  
  ProcedureReturn *ObjetA\Byte
  
EndProcedure

Procedure.w GetStructTestWord(*ObjetA.StructTest)
  
  ProcedureReturn *ObjetA\Word
  
EndProcedure

Procedure.l GetStructTestLong(*ObjetA.StructTest)
  
  ProcedureReturn *ObjetA\Long
  
EndProcedure

Procedure.f GetStructTestFloat(*ObjetA.StructTest)
  
  ProcedureReturn *ObjetA\Float
  
EndProcedure

Procedure.s GetStructTestString(*ObjetA.StructTest)
  
  ProcedureReturn *ObjetA\String
  
EndProcedure

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< L'opérateur Update >>>>>

Procedure UpdateStructTest(*ObjetA.StructTest, Byte.b, Word.w, Long.l, Float.f, String.s)
  
  SetStructTestByte(*ObjetA, Byte)
  SetStructTestWord(*ObjetA, Word)
  SetStructTestLong(*ObjetA, Long)
  SetStructTestFloat(*ObjetA, Float)
  SetStructTestString(*ObjetA, String)
  
EndProcedure

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

Procedure WriteBinaryString(String$)
  
  WriteLong(0,Len(String$))
  WriteData(0,@String$, Len(String$))
  
EndProcedure

Procedure.s ReadBinaryString()
  
  Length = ReadLong(0)
  String$ = Space(Length)
  ReadData(0,@String$, Length)
  
  ProcedureReturn String$
EndProcedure


; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

NewList Liste.StructTest()

String.s = "Good Morning !"

For Compteur = 0 To 5
  
  AddElement(Liste())
  UpdateStructTest(@Liste(), Byte.b, Word.w, Long.l, Float.f, String.s)
  
  Byte = Byte + 1 + Compteur
  Word = Word + 5 + Compteur
  Long = Long + 10000 + Compteur
  Float = 3.141592 + Compteur
  String = "Hello World no. " + Str(Compteur) + "!"
  
Next

Debug "We put some stuff into the linked list"

ForEach Liste()
  
  Debug GetStructTestByte(@Liste())
  Debug GetStructTestWord(@Liste())
  Debug GetStructTestLong(@Liste())
  Debug GetStructTestFloat(@Liste())
  Debug GetStructTestString(@Liste())
  
Next


Debug "We create the Binary file"

If CreateFile(0, "Test.bin")
  
  ForEach Liste()
    WriteByte(0,GetStructTestByte(@Liste()))
    WriteWord(0,GetStructTestWord(@Liste()))
    WriteLong(0,GetStructTestLong(@Liste()))
    WriteFloat(0,GetStructTestFloat(@Liste()))
    WriteBinaryString(GetStructTestString(@Liste()))
  Next
  
  CloseFile(0)
  
EndIf

ClearList(Liste())

Debug "Test to check if the linked list is Empty : "
Debug "Number of element = " +  Str(ListSize(Liste()))

Debug "We load the file"

If OpenFile(0,"Test.bin")
  
  Repeat
    
    AddElement(Liste())
    SetStructTestByte(@Liste(),ReadByte(0))
    SetStructTestWord(@Liste(),ReadWord(0))
    SetStructTestLong(@Liste(),ReadLong(0))
    SetStructTestFloat(@Liste(),ReadFloat(0))
    SetStructTestString(@Liste(),ReadBinaryString())
    
  Until Eof(0)
  
EndIf

Debug "We show content loaded from the file."

ForEach Liste()
  
  Debug GetStructTestByte(@Liste())
  Debug GetStructTestWord(@Liste())
  Debug GetStructTestLong(@Liste())
  Debug GetStructTestFloat(@Liste())
  Debug GetStructTestString(@Liste())
  
Next
User avatar
Guimauve
Enthusiast
Enthusiast
Posts: 742
Joined: Wed Oct 22, 2003 2:51 am
Location: Canada

Post by Guimauve »

One more with a Static array inside the structure. Sorry the Debug message are in french.

Regards
Guimauve

Code: Select all

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Déclaration de la Structure >>>>>

Structure TestStruc
  
  Array.s[10]
  Maths.f
  Var.l
  
EndStructure

; <<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Les mutateurs >>>>>

Procedure SetTestStrucArray(*ObjetA.TestStruc, Index.b, Valeur.s)
  
  *ObjetA\Array[Index] = Valeur
  
EndProcedure

Procedure SetTestStrucMaths(*ObjetA.TestStruc, Maths.f)
  
  *ObjetA\Maths = Maths
  
EndProcedure

Procedure SetTestStrucVar(*ObjetA.TestStruc, Var.l)
  
  *ObjetA\Var = Var
  
EndProcedure

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Les observateurs >>>>>

Procedure.s GetTestStrucArray(*ObjetA.TestStruc, Index.b)
  
  ProcedureReturn *ObjetA\Array[Index]
  
EndProcedure

Procedure.f GetTestStrucMaths(*ObjetA.TestStruc)
  
  ProcedureReturn *ObjetA\Maths
  
EndProcedure

Procedure.l GetTestStrucVar(*ObjetA.TestStruc)
  
  ProcedureReturn *ObjetA\Var
  
EndProcedure

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< L'opérateur Update >>>>>

Procedure UpdateTestStruc(*ObjetA.TestStruc, Maths.f, Var.l)
  
  SetTestStrucMaths(*ObjetA, Maths)
  SetTestStrucVar(*ObjetA, Var)
  
EndProcedure


; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

Procedure WriteBinaryString(String$)
  
  WriteLong(Len(String$)) 
  WriteData(String$, Len(String$)) 
  
EndProcedure 

Procedure.s ReadBinaryString()
  
  Length = ReadLong()
  String$ = Space(Length)
  ReadData(String$, Length) 
  
  ProcedureReturn String$
EndProcedure 

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<


NewList SuperList.TestStruc()
Maths.f = 3.125
Var.l = 5

For Compteur = 0 To 20
  
  AddElement(SuperList())
  
  For Index = 0 To 9
    SetTestStrucArray(@SuperList(), Index, "Allo " + Str(Compteur * 5 + Index)) 
  Next 
  
  UpdateTestStruc(@SuperList(), Maths.f, Var.l)
  Maths = Maths + Compteur * 5
  Var = Var + Compteur * 3
  
Next


Debug "On montre le contenu"

ForEach SuperList()
  
  For Index = 0 To 9
    Debug GetTestStrucArray(@SuperList(), Index) 
  Next 
  Debug GetTestStrucMaths(@SuperList())
  Debug GetTestStrucVar(@SuperList())
  
Next


Debug "On créer un fichier"

If CreateFile(0, "SuperTest.bin")
  
  ForEach SuperList()
    
    For Index = 0 To 9
      WriteBinaryString(GetTestStrucArray(@SuperList(), Index))
    Next 
    WriteFloat(GetTestStrucMaths(@SuperList()))
    WriteLong(GetTestStrucVar(@SuperList()))
    
  Next
  
  CloseFile(0)
  
EndIf 


ClearList(SuperList())

Debug "On test si la liste est vide : "
Debug "Nombre d'élément = " +  Str(CountList(SuperList()))

Debug "On ouvre le fichier"

If OpenFile(0, "SuperTest.bin")
  
  Repeat
    AddElement(SuperList())
    For Index = 0 To 9
      SetTestStrucArray(@SuperList(), Index, ReadBinaryString())
    Next 
    SetTestStrucMaths(@SuperList(),ReadFloat())
    SetTestStrucVar(@SuperList(),ReadLong())
    
  Until Eof(0)
  
  CloseFile(0)
  
EndIf 


Debug "On montre le contenu après le chargement"

ForEach SuperList()
  
  For Index = 0 To 9
    Debug GetTestStrucArray(@SuperList(), Index) 
  Next 
  Debug GetTestStrucMaths(@SuperList())
  Debug GetTestStrucVar(@SuperList())
  
Next
Daffodil the Duck
User
User
Posts: 14
Joined: Mon Aug 15, 2005 10:14 pm
Location: Canada

Binary write and read

Post by Daffodil the Duck »

Guimauve
This is fantastic. It solves one half of something I have been stuck on for a while now. The other half I am stuck on is similar. Is there any way to adapt it so that instead of saving the contents of a linked list in binary form to a file and restoring, it could save the contents of a tree gadget to a file in binary and restore. I have a program that uses a tree gadget with 19872 rows and it takes a while to load up when inserting row by row. This looks like a quick way to load and restore the tree gadget once the initial row by row load is saved in binary. Thanks in advance
User avatar
Guimauve
Enthusiast
Enthusiast
Posts: 742
Joined: Wed Oct 22, 2003 2:51 am
Location: Canada

Post by Guimauve »

Sorry for the Delay.

For your question Yes It's possible but it's not very easy. You need to verify each node for sub item and Write and Read all information from your TreeGadget on the file you would like to create.

If you acces to the TreeGadget internal Structure by a Pointers you can Code a small procedures like these one.

Code: Select all

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Structure declaration >>>>>

Structure Point3D

   x.f
   y.f
   z.f

EndStructure

; <<<<<<<<<<<<<<<<<<<<
; <<<<< Mutators >>>>>

Procedure SetPoint3Dx(*PointA.Point3D, x.f)

   *PointA\x = x

EndProcedure

Procedure SetPoint3Dy(*PointA.Point3D, y.f)

   *PointA\y = y

EndProcedure

Procedure SetPoint3Dz(*PointA.Point3D, z.f)

   *PointA\z = z

EndProcedure

; <<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Observators >>>>>

Procedure.f GetPoint3Dx(*PointA.Point3D)

   ProcedureReturn *PointA\x

EndProcedure

Procedure.f GetPoint3Dy(*PointA.Point3D)

   ProcedureReturn *PointA\y

EndProcedure

Procedure.f GetPoint3Dz(*PointA.Point3D)

   ProcedureReturn *PointA\z

EndProcedure

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Read Binary file >>>>>

Procedure ReadPoint3D(*PointA.Point3D)

   SetPoint3Dx(*PointA, ReadFloat())
   SetPoint3Dy(*PointA, ReadFloat())
   SetPoint3Dz(*PointA, ReadFloat())

EndProcedure

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Write Binary file >>>>>

Procedure WritePoint3D(*PointA.Point3D)

   WriteFloat(GetPoint3Dx(*PointA))
   WriteFloat(GetPoint3Dy(*PointA))
   WriteFloat(GetPoint3Dz(*PointA))

EndProcedure

But Instead to set the data in a 3D point Structure you set the TreeGadget Structure directly.

The only problems I don't know the shape of the Structure used to create this gadget. Also I don't know how to acces this Structure.

Regards

Guimauve
Post Reply