[Gambas-user] File Format Help

bb adamnt42 at gmail.com
Thu Jun 17 20:02:33 CEST 2021


On Thu, 2021-06-17 at 12:51 -0500, John Dovey wrote:
> Replying to myself again.
> I've now progressed this far. Am I on the right track?
> 
> Sub Main()
>     '' FidoMsg
> 
>     Dim FM_fromUserName As String '36
>     Dim FM_toUserName As String '36
>     Dim FM_subject As String '72
>     Dim FM_DateTime As String ' 20
>     Dim FM_timesRead As Short
>     Dim FM_destNode As Short
>     Dim FM_origNode As Short
>     Dim FM_cost As Short
>     Dim FM_origNet As Short
>     Dim FM_destNet As Short
>     Dim FM_destZone As Short
>     Dim FM_origZone As Short
>     Dim FM_destPoint As Short
>     Dim FM_origPoint As Short
>     Dim FM_replyTo As Short
>     Dim FM_Attribute As Short
>     Dim FM_nextReply As Short
>     Dim FM_text As String 'null terminated
>     ' 1) Numeric elements (bytes, byte-arrays, shorts, integers,
> longs) can be Read directly From the stream.ie(4 byte Integer) = Read
> #Stream As Integer. Gambas can handle little endian / big endian
> issues.
>     ' 2)Fixed length strings must be handled In a two stage process.
>     ' First, the required string length number Of bytes Is Read Into
> a byte array. This byte array Is Then converted To a string.
>     'Sample code:
> 
>     Dim hfile As File
> 
>     hfile = Open "test.msg" For Read 'Write Create
>     ''Test
>     Dim Bytes As New Byte[36]
>     Bytes.Read(hfile)
>     FM_fromUserName = Bytes.ToString()
>     Bytes.Read(hfile)
>     FM_toUserName = bytes.ToString()
>     Dim Bytes2 As New Byte[72]
>     Bytes2.Read(hfile)
>     FM_subject = Bytes2.ToString()
>     Dim Bytes3 As New Byte[20]
>     Bytes3.Read(hfile)
>     FM_DateTime = Bytes3.ToString()
>     FM_timesRead = Read #hfile As Short
>     FM_destNode = Read #hfile As Short
>     FM_origNode = Read #hfile As Short
>     FM_cost = Read #hfile As Short
>     FM_origNet = Read #hfile As Short
>     FM_destNet = Read #hfile As Short
>     FM_destZone = Read #hfile As Short
>     FM_origZone = Read #hfile As Short
>     FM_destPoint = Read #hfile As Short
>     FM_origPoint = Read #hfile As Short
>     FM_replyTo = Read #hfile As Short
>     FM_Attribute = Read #hfile As Short
>     FM_nextReply = Read #hfile As Short
>     FM_text = Read #hfile As String
>     '' End Test
>     'FidoMsg = Read #hfile As MyFidoMsg
>     'Write #hfile, FidoMsg As MyFidoMsg
>     Close #hfile
> End Sub
> 
> On Thu, 17 Jun 2021 at 11:09, John Dovey <dovey.john at gmail.com>
> wrote:
> > As a followup to my own message, this is what I've gotten to so
> > far. I KNOW my struct is incorrect, but I'm not sure what it should
> > be. For those interested, I've included a test.msg file that is
> > maybe a better example.
> > 
> > Public Struct myFidoMsg 'Datatype
> >     fromUserName As Byte[] '36
> >     toUserName As Byte[] '36
> >     subject As Byte[] '72
> >     DateTime As Byte[] ' 20
> >     timesRead As Integer
> >     destNode As Integer
> >     origNode As Integer
> >     cost As Integer
> >     origNet As Integer
> >     destNet As Integer
> >     destZone As Integer
> >     origZone As Integer
> >     destPoint As Integer
> >     origPoint As Integer
> >     replyTo As Integer
> >     Attribute As Integer
> >     nextReply As Integer
> >     text As String 'null terminated
> > End Struct
> > 
> > Sub Main()
> > 
> >     Dim hfile As File
> >     Dim FidoMsg As MyFidoMsg
> > 
> >     hfile = Open "test.msg" For Read 'Write Create
> >     FidoMsg = Read #hfile As MyFidoMsg
> >     'Read
> >     'Write #hfile, FidoMsg As MyFidoMsg
> >     Close #hfile
> > end sub
> > 
> > On Thu, 17 Jun 2021 at 09:46, John Dovey <dovey.john at gmail.com>
> > wrote:
> > > I hope no-one minds if I ask this here. I'm just really unsure
> > > how to do this best in Gambas. 
> > > I want to read and write files that have a (very old)
> > > specification
> > > Essentially, it looks like this:
> > >  1. Application Layer Data Definition : a Stored Message
> > > 
> > >                                Stored Message
> > > 
> > >        Offset
> > >       dec hex
> > >               .-----------------------------------------------.
> > >         0   0 |                                               |
> > >               ~                 fromUserName                  ~
> > >               |                   36 bytes                    |
> > >               +-----------------------+-----------------------+
> > >        36  24 |                                               |
> > >               ~                  toUserName                   ~
> > >               |                   36 bytes                    |
> > >               +-----------------------+-----------------------+
> > >        72  48 |                                               |
> > >               ~                    subject                    ~
> > >               |                   72  bytes                   |
> > >               +-----------------------+-----------------------+
> > >       144  90 |                                               |
> > >               ~                    DateTime                   ~
> > >               |                    20 bytes                   |
> > >               +-----------------------+-----------------------+
> > >       164  A4 | timesRead (low order) | timesRead (high order)|
> > >               +-----------------------+-----------------------+
> > >       166  A6 | destNode (low order)  | destNode (high order) |
> > >               +-----------------------+-----------------------+
> > >       168  A8 | origNode (low order)  | origNode (high order) |
> > >               +-----------------------+-----------------------+
> > >       170  AA |   cost (low order)    |   cost (high order)   |
> > >               +-----------------------+-----------------------+
> > >       172  AC | origNet (low order)   | origNet (high order)  |
> > >               +-----------------------+-----------------------+
> > >       174  AE | destNet (low order)   | destNet (high order)  |
> > >               +-----------------------+-----------------------+
> > >       176  B0 | destZone (optional)   | destZone (optional)   |
> > >               +-----------------------+-----------------------+
> > >       178  B2 | origZone (optional)   | origZone (optional)   |
> > >               +-----------------------+-----------------------+
> > >       180  B4 | destPoint(optional)   | destPoint(optional)   |
> > >               +-----------------------+-----------------------+
> > >       182  B6 | origPoint(optional)   | origPoint(optional)   |
> > >               +-----------------------+-----------------------+
> > >       184  B8 |  replyTo (low order)  |  replyTo (high order) |
> > >               +-----------------------+-----------------------+
> > >       186  BA | Attribute (low order) | Attribute (high order)|
> > >               +-----------------------+-----------------------+
> > >       188  BC | nextReply (low order) | nextReply (high order)|
> > >               +-----------------------+-----------------------+
> > >       190  BE |                      text                     |
> > >               ~                    unbounded                  ~
> > >               |                 null terminated               |
> > >               `-----------------------------------------------'
> > > 
> > >       Message    = fromUserName(36)  (* Null terminated *)
> > >                    toUserName(36)    (* Null terminated *)
> > >                    subject(72)       (* see FileList below *)
> > >                    DateTime          (* message body was last
> > > edited *)
> > >                    timesRead         (* number of times msg has
> > > been read *)
> > >                    destNode          (* of message *)
> > >                    origNode          (* of message *)
> > >                    cost              (* in lowest unit of
> > > originator's
> > >                                         currency *)
> > >                    origNet           (* of message *)
> > >                    destNet           (* of message *)
> > >                    destZone          (* of message *)
> > >                    origZone          (* of message *)
> > >                    destPoint         (* of message *)
> > >                    origPoint         (* of message *)
> > >                    replyTo           (* msg to which this replies
> > > *)
> > >                    AttributeWord
> > >                    nextReply         (* msg which replies to this
> > > *)
> > >                    text(unbounded)   (* Null terminated *)
> > > There is a sample packet you can look at if you really want to
> > > see what it looks like, but this should give you an idea:
> > > 
> > > 
> > > I'm guessing a "Struct" of some sort? 
> > > Any advice would be appreciated.
> > > 
> > > John
> > > 
Compartmentalize! Compartmentalize! Compartmentalize!
After quickly scanning through that spec, if it were I I'd be
immediately looking to build a set of classes that implement each
structure as a separate class exposing the data as properties and
containing at least methods to read and parse the object.
Some inheritance looks possible e.g. message & compressed message (but
I haven't read it too closely.
These types of parser classes and structures (concepts not "structs"!)
we use very commonly for data scraping applications. At least you have
a well-formed data specification! :-)

b




More information about the User mailing list