Link to home
Create AccountLog in
Avatar of BASit Bulbulia
BASit BulbuliaFlag for South Africa

asked on

Using .Net Random Access Files be able to Read,Write and Edit Legacy Data written with QBASIC - data stored with MKi$ MKs$ Mkd$

I am using .Net VB Express 2005.

I need to know how I can open a Random Access file to read and write back my legacy data written with QBASIC(Microsoft)

I managed to use FileGet and was able to view only the normal string data - how do i read / edit and re-write the data from one record when the data is stored with :-

 MKi$ (2 bit) Mks$(4 bit) and Mkd$(8 bit) and normal strings

In Qbasic you used the cvi, cvs and cvd functions to read the data.  How can these be implemented with .Net Vb

Please supply code snippets of how the file is open and records read /edited and written back in the same format.
Assume in your eaxmpales that the record size length is 20  with the fields  2 is mki$, 4 is mks$, 8 is mkd$ and 6 is a normal string.

Thanks in Advance.

BASit
www.compubyte.co.za 
Avatar of Sancler
Sancler

There's quite a bit of code out there replicating the old MK?$ and CV? functions.  None of it's expensive, but this one's free

    http://www.adit.co.uk/html/numbers.html

or, similar, on here

    https://www.experts-exchange.com/questions/20451431/4-byte-string-that-represents-a-Single-precision-number.html

Roger
Avatar of BASit Bulbulia

ASKER

Dear Roger,

Thanks for attempting to assist, I have stumbled across a few of these code snippets and the examples do not work with .Net VB or I am just way to dumb to get them converted :(

UPGRADE_ISSUE: Declaring a parameter 'As Any' is not supported.

I am totally lost . .  and am just beginning to learn .Net  . . Can you or someone else help converting same for .Net VB (Express 2005) …

Pretty please . . .

Thanks in advance
BASit
I've cobbled this together, plagiarising (with modifications) here and there.  I don't have any data to test it on.  In theory it should work, and it didn't produce any errors in compiling.

    Declare Sub CopyMemory Lib "KERNEL32" Alias "RtlMoveMemory" (ByVal pDst As IntPtr, ByVal pSrc As String, ByVal ByteLen As Long)

    Public Function MKI(ByVal ValToConvert As Integer) As String
        'This function converts an integer to a two byte string
        Dim WorkString As String
        WorkString = Space$(2)  'Get the size right
        CopyMemory(WorkString, ValToConvert, 2)
        Return WorkString
    End Function
    Public Function CVI(ByVal ValToConvert As String) As Integer
        'This function extracts an integer from a two byte string
        Dim WorkInt As Integer
        CopyMemory(WorkInt, ValToConvert, 2)
        Return WorkInt
    End Function
    Public Function MKL(ByVal ValToConvert As Long) As String
        'This function converts a Long to a four byte string
        Dim WorkString As String
        WorkString = Space$(4)  'Get the size right
        CopyMemory(WorkString, ValToConvert, 4)
        Return WorkString
    End Function
    Public Function CVL(ByVal ValToConvert As String) As Long
        'This function extracts a long from a four byte string
        Dim WorkLong As Long
        CopyMemory(WorkLong, ValToConvert, 4)
        Return WorkLong
    End Function
    Public Function MKS(ByVal ValToConvert As Single) As String
        'this function converts a single to a four byte string
        Dim WorkString As String
        WorkString = Space$(4)
        CopyMemory(WorkString, ValToConvert, 4)
        Return WorkString
    End Function
    Public Function CVS(ByVal ValToConvert As String) As Single
        'This function converts the content of a 4 byte string to a single
        Dim WorkSingle As Single
        CopyMemory(WorkSingle, ValToConvert, 4)
        Return WorkSingle
    End Function
    Public Function MKD(ByVal ValToConvert As Double) As String
        'This function places a double into an 8 byte string
        Dim WorkString As String
        WorkString = Space$(8)
        CopyMemory(WorkString, ValToConvert, 8)
        Return WorkString
    End Function
    Public Function CVD(ByVal ValToConvert As String) As Double
        'This function extracts a double form an 8 byte string
        Dim WorkDouble As Double
        CopyMemory(WorkDouble, ValToConvert, 8)
        Return WorkDouble
    End Function

    Private Sub readfile(ByVal myQBasicFileName As String)
        Dim myInteger As Integer
        Dim mySingle As Single
        Dim myDouble As Double
        Dim myString As String
        Using Reader As New Microsoft.VisualBasic.FileIO.TextFieldParser(myQBasicFileName)
            Reader.TextFieldType = Microsoft.VisualBasic.FileIO.FieldType.FixedWidth
            Reader.SetFieldWidths(2, 4, 8, 6)
            Dim currentRow As String()
            While Not Reader.EndOfData
                Try
                    currentRow = Reader.ReadFields()
                    myInteger = CVI(currentRow(0))
                    mySingle = CVS(currentRow(1))
                    myDouble = CVD(currentRow(2))
                    myString = currentRow(3)
                    'do something with values
                Catch ex As Microsoft.VisualBasic.FileIO.MalformedLineException
                    MsgBox("Line " & ex.Message & "is not valid and will be skipped.")
                End Try
            End While
        End Using
    End Sub

Give it a try and report back with any problems.

Roger
Forget that.  I've just had a chance to test, and it's not working.  I'll try and have another look later on, if no-one else comes up with anything.  But it won't be for quite some hours before I can come back to it.

Roger
ASKER CERTIFIED SOLUTION
Avatar of Sancler
Sancler

Link to home
membership
Create a free account to see this answer
Signing up is free and takes 30 seconds. No credit card required.
See answer
Dear Roger,

Thanks a stack  . . works like a charm and it's exactly what I needed *** you a star ***

I guess what I learnt form this exercise is priceless to me :-) ; you effort I wish I could reward in more ways then the points I will be allocating to you . .


BASit
www.compubyte.co.za

Dear Roger,


When I tested the files with your test file it worked perfectly; when i tested it with the data created from the qb progran it works with all integer values (CVI) but not with CVS and CVD. I think the legacy data may have a different format of cvs or cvd . The test file is a small 4 record file from www.compubyte.co.za/test.

I am assuming that it got to do with and olderIEEE standards etc .  Your demo program reads the data but the values of csv and cvd is wrong.

The test file has these values
record 1
1
1.1
11.1
tr-1

record 1
1
1.1
11.1
tr-1

record 1
1
1.1
11.1
tr-1

record 2
2
2.2
22.2
tr-2

record 3
3
3.3
33.3
tr-3

record 4
4
4.4
44.4
tr-4

What could be the issue . .

Thanks in advance

BASit
I've downloaded and tested the file and see what you mean.  

I think you're probably right that it's a format problem - probably byte-order.  On the other hand I am also struck by the fact that, opening the file in NotePad, it only appears to have 10 characters for each record whereas that written by my test program obviously had 20.  That suggests that there might be a text-encoding issue, although it's possible that that effect is just a result of sending the .txt file over the airwaves and the fact that the integer and string portions of the records come out OK seems to support that view.

I imagine we'll be able to sort it out but I can't remember the details of this sort of thing so will either have to do some detailed digging on the internet or (which may be simpler) have to analyse the data in the file at byte level to see what's what.  Either will take time, and I'm a bit pushed right now.  But I'll come back to it ASAP.  It may not be for 24 hours or so, though.

In the meantime, can you please confirm whether the text bits of your test file are supposed to be in upper or lower case?  Your post shows tr-1, etc. but my results are showing TR-1 etc.

Roger
Hi Roger,

Thanks for downloading the file and testing it;  I have included the same file with and extention as test.xxx at www.compubyte.co.za/test. The file size is 80 bytes (4 records x 20) ; when downloading if you save the file back make sure that save as type is not text.  

I am also sorry but it was a typing error the string value is in CAPS (TR-1).

I fully understand your busy schedule; when you do have time please do look into it.

Thanks in advance,

BASit

This is from

http://support.microsoft.com/kb/q69333/

>>
The IEEE floating-point format is found in the Standard and Professional Editions of Microsoft Visual Basic for MS-DOS, version 1.0; in Microsoft QuickBasic for MS-DOS (QB87.EXE coprocessor version only), versions 3.0, 4.0, 4.0b, and 4.5; in Microsoft Basic Compiler for MS-DOS and MS OS/2, versions 6.0 and 6.0b; and in Microsoft Basic Professional Development System (PDS) for MS-DOS and MS OS/2, versions 7.0 and 7.1.

MBF (Microsoft Binary Format) is found in Microsoft QuickBasic for MS-DOS (QB.EXE non-coprocessor version only), versions 1.0, 1.01, 2.0, 2.01, and 3.0, and in Microsoft GW-Basic Interpreter for MS-DOS, versions 3.2, 3.22, and 3.23.
<<

I've looked at this at byte-level, even bit-level, and not been able so far to make much (or certainly enough) of it.  The output from my test program readily ties in with IEEE 754, and the data in your test file looks like there is probably a match in the mantissa part.  This would be consistent, I think, with yours being in MBF.  But I've not yet found any doc sufficiently detailed to explain how the sign bit and exponent bits work in MBF.  I may be able to work it out but you may be able to help in that.

It looks as though you produced your test file specifically to post - I assume from the legacy QBasic program.  If that is so, could you please post another test file with plain integer values - 1 to 4 again would be fine - in all the slots: integer, single and double.  That should remove some of the "noise" from the bit level results and give me a greater chance of extracting the pattern (assuming that there is one).

And, to save me barking up a completely wrong tree, do you have any idea into which of the groups of program versions listed in the quote above your legacy program fits?

Roger
I am sure it's mbf as the file was created with PowerBasic using the MBF format.

Hope this helps . .

BASit
I have left these files on www.compubyte.co.za/test

test.yyy

which has 4 records with the following in them:-

1
2
3
T1

11
22
33
T2

111
2222
3333
T3

1111
11111
111111
T3

I have also a zip file which I used to create this data; using PowerBasic which has MKMS/MKMD functions to use MBF formatted data.

The zip files has test-m.bas and test-m.exe

BASit
I found this zip file from a forum on PowerBasic I subscribe to :-

msbf.zip   ( ww.compubyte.co.za/test )

It has a DLL ; how could I use this DLL which I assume is the solution


Thanks in advance

BASit
Unfortunately, I think I'm going to have to abandon you on this one.  I've been doing some testing with the Test-m.exe included in TEST-M.zip and got sufficient results to indicate that there is a clear pattern.  So - I think I've read the bytes in the right order -

1 is represented as 0000 0000 1000 0001
-1 is represented as 1000 0000 1000 0001
1.5 is represented as 0100 0000 1000 0001
-1.5 is represented as 1100 0000 1000 0001

Those representations are the same for singles and doubles, but leave out the unused bytes (two in the case of singles and six in the case of doubles) that are all blank with these "small" numbers.

These results suggests quite strongly that the leftmost bit is a "sign" bit.  But that is not consistent with the only description I've been able to find of the detail of the MBF structure - in this

http://www.petesqbsite.com/sections/zines/qbcm/issues/1-6/default.html#btau

- under the "Floating Point Values" heading.  According to that, the sign bit should be ninth (reading from the left).

I feel that, with sufficient time and application, and treating it as a "cryptography" problem, I should be able to crack it.  But, sorry, I'm not sufficiently interested in it as an issue to spend that time and application on it.  And even assuming I could crack it, there would then be the need to code for all the bit-shifting involved.  Although, for someone adept at lower level languages, the Msbf.bas file in Msbf.zip looks like it would provide a good basis (pun intended) for that.

I feel sure that, somewhere out there, there must be ready made code to tackle this.  Unfortunately, I've tried to build into a VB.NET project both the .dll you mention and another one - MBF2IEEE.DLL - referred to in and downloadable via

http://support.microsoft.com/kb/113439/EN-US

But neither are recognised as valid .dll files by my current system.  But with your own links - e.g. the PowerBasic forum you mention - I would have thought a specific question relating to conversion of MBF for VB.NET purposes might produce some results.  If nothing else, it might locate someone whose interests and expertise are better matched to working it out than mine are.

Sorry I can't help further.  Good luck with it.

Roger
Thanks for trying, much appreciated . .


BASit