Qbasicnews.com

Full Version: CVI - Not working?
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
CVI does not seem to be converting 2 byte strings read from
a file. I did read the thread about MID$ and CVI, but this does
not involve MID$.

The FB keywords reference says CVI converts 2 byte strings and
CVL converts 4 byte strings, as it had been in QB, however CVI is
not converting.

I need to read .DBF file headers, and in every .DBF file, bytes
9 & 10 store the header size in ascii as a 2 byte string. If you have
any .DBF file, this code below works in QB, but not in FB:

DIM Header.String AS String * 2
INPUT "Enter .DBF file name "; Dbf.File$
OPEN DBF.FILE$ FOR BINARY ACCESS READ WRITE SHARED AS #1
SEEK #1, 9
GET #1,, Header.String
PRINT CVI(Header.String)
INPUT "Hit any key to continue...", X$

I'm getting 0 all the time in FB. Am I doing something wrong?

Dean
CVI expects a 4 byte's string as integers are 32-bit in FB, there's no CVS for shorts as it's already taken.

Code:
function cvshort( byval s as string ) as short
    function = s[0] or (s[1] shl 8)
end function
Then what's the difference betwen CVI and CVL?

Seems like they must be doing the same thing. Why shouldn't
CVL do what CVL always did -- 4 byte "long" integers, and
CVI do 2 byte shorts -- just as the FB doc's say? Or
come up with something else like CVISHORT.

For now, I have to do this manually, which is not a big deal,
but all my DOS code using CVI from ages ago has to be changed
in order to read files containing 2 byte short integers (which
is a standard for certain file formats like .DBF files):

Dim Byte9 as string * 1
Dim Byte10 as string * 1

Input "Enter the .dbf file"; Dbf.File$
OPEN Dbf.File$ FOR BINARY ACCESS READ WRITE SHARED AS #1
SEEK #1, 9
GET #1, , Byte9
SEEK #1, 10
GET #1, , Byte10

Header.Size = ASC(Byte9) + (ASC(Byte10) * 256)
PRINT Header.Size

I know how busy you are, but can't you squeeze a function in to
covert 2 byte integers?

Dean
Well, long is an alias for integer in FB, same goes for CVL and CVI, integers are 32-bit, if CVI expected a 2-byte string, people would complain it wouldn't be working too.

Wouldn't it be simple to just use a short there? get #1, 9, shortvar.

I may add CVSH later, not a big deal.. it stills way slower than simply using a short var, as temp strings must be checked etc..
Yeah, getting a short worked -- actually didn't realize I could do it that
way. Thought I had to get a string, then CV_ it to the data type I needed.

Thanks Smile

So, then, I don't really ever need to CVL or CVI anything I get
from a file in the first place -- corect? I just dim a variable of the
data type I want, seek & get it it from the file, and it automatically
converts the ascii characters from the file into that data type.
Cool.

Dean
Yeah, GET, PUT, LEN, PRINT, WRITE use "fake" overloading, so depending on the data type used, a different function will be called.

I only see use for CV? and MK? when you need to access a string buffer, but in FB you have byte arrays, so string buffers aren't a good idea either.

GET and PUT work with arrays ("GET #1, , array()" will try fill array()) and with UDT's too ("GET #1, , myudt"), but padding is taken into account, but UDT's can be packed using "TYPE mytype FIELD=1".

Btw, cvshort, cvlongint, mkshort, mklongint were added, changes are in CVS, it may take up to 5 hours to sourceforge.net update the anonymous access though.
Cool cool cool.

Last question -- Getting a short is returning a value that
is 1 less than qb CVI is returning.

My dbf header size is 1218 bytes, per foxpro, per QB CVI function,
and by manually calculating it.

My Get #1, 9, shortvar is returning 1217.

I don't mind adding 1, if for some reason that is always going
to be necessary with getting short vars -- seems like something
is off a bit?

Dean
Get# will simply read the binary number, nothing else is done.

I doubt QB does some voodoo with CVI/MKI, but we never know for sure ;)