xsharp.eu • Ansi2Oem() / Oem2Ansi() behaviour
Page 1 of 1

Ansi2Oem() / Oem2Ansi() behaviour

Posted: Wed Aug 29, 2018 6:56 pm
by Karl-Heinz
Here´s what i´ve tried:

c := "Ärger"

? Ansi2Oem ( c ) // "-rger"

? Oem2Ansi ( Ansi2Oem ( c ) ) // "-rger"


Is there something missing in the current implementation, or is there a special setting required to make it work ?

regards
Karl-Heinz

Ansi2Oem() / Oem2Ansi() behaviour

Posted: Wed Aug 29, 2018 9:17 pm
by robert
Karl-Heinz,

The Ansi2Oem function and its counterpart are really not easy to implement in .Net.
The conversion involved is Unicode -> Ansi -> Oem -> Unicode

I think this can only be safely done on byte arrays.
That is why we have also added an overload with byte[] param and byte[] return value.

What are your Windows and OEM codepages ?

Robert

Ansi2Oem() / Oem2Ansi() behaviour

Posted: Wed Aug 29, 2018 10:14 pm
by Karl-Heinz
Hi Robert,

my codepages are:

RuntimeState:WinCodePage == 1252
RuntimeState:DosCodePage == 850


Here´s what i´ve tried so far, not sure if i´m on the right track ...

Code: Select all


LOCAL c, c2 AS STRING
LOCAL eDosEncoding AS encoding
LOCAL nDosCp  AS LONG
LOCAL b, b2 AS BYTE[]


c := "Ärger"


// 1. simulate a Ansi2Oem() ....
// ----------------------------- 
//
// get the DOS codepage. Here it´s 850.

nDosCp := RuntimeState:DosCodePage
eDosEncoding := encoding.GetEncoding( nDosCp )
b := eDosEncoding:GetBytes ( c )
?"Codepage " + nDosCP + " encoding:"

FOREACH x AS BYTE  IN b
  ? x  
	
NEXT

?

/*  ok
142  "Ä"
114  "r"
103  "g"
101  "e" 
114  "r"

*/


// get the oem string from the bytes

c2 := Encoding.ASCII:GetString(b)
File.WriteAllBytes("d:testfoo.txt", b ) // content shown as "Žrger"
	
? "OEM string: " + c2  //  "?rger"	

// write the byte array content to the dbf field  ????....


Ansi2Oem() / Oem2Ansi() behaviour

Posted: Thu Aug 30, 2018 4:57 am
by wriedmann
Hi Robert,

this may be a hard thing, but it is absolutely needed.
IMHO these functions need to call the relative Windows functions and not the .NET counterparts at least in the Vulcan/VO dialect, because they need to be compatible 100% with the relative VO functions. Otherwise it will invalidate a lot of our DBF stored data.

Wolfgang

Ansi2Oem() / Oem2Ansi() behaviour

Posted: Thu Aug 30, 2018 6:03 am
by Chris
Guys,

Those functions are almost irrelevant now in .Net, at least with regard to DBFs. Oem/Ansi makes a difference only for 8bit strings, like the ones we have in VO. In .Net, strings are always unicode, there's no such thing as Oem<->Ansi conversion for unicode strings, this does not make sense by definition. Only area where it could make sense would be in PSZs, which are indeed still 8bit per char.

When reading to/writing from DBFs, it's the RDD that takes care of all the conversion between the unicode strings and the 8bit data that needs to be written to/read from the dbf fields, also the RDD saves/reads the data in the correct ansi or oem format, based on the settings (codepage) saved in the dbf header. But all this is transparent, the end result is that (in .Net) the RDD returns a standard unicode .Net string when reading a CHAR field from a dbf.

So, Karl-Heinz, are you just doing some tests to test VO compatibility in this area, or are you trying to solve a specific problem? Depending on what you want to do, you'll need to use a different approach, but always need to keep in mind this very fundamental difference between .Net and VO, in .Net strings are unicode compared to VO's 8bit strings.

Chris

Ansi2Oem() / Oem2Ansi() behaviour

Posted: Thu Aug 30, 2018 7:51 am
by Karl-Heinz
Hi Chris,

i was wondering about the oem2ansi()/ansi2oem() results, so i played a little bit ;-). Can´t remember when i needed these funcs to write/read to/from a dos/win dbf in the past, because the VO read/write automatic conversions are working since years without problems. if the x# rdds will behave 1:1, no further thinkings about these funcs are necessary ;-)

A real problem are the current sort results. I always use the setting setinternational(#CLIPPER) in conjuncion with the german nation dll. I already opened some days ago a thread on this topic - any news on this topic ?

regards
Karl-Heinz

Ansi2Oem() / Oem2Ansi() behaviour

Posted: Thu Aug 30, 2018 9:37 am
by Chris
Hi Karl-Heinz,

Yes, for "real" (containing text) strings, it will work exactly the same as in VO, as it has been working already in vulcan actually. Only difference will be regarding saving binary data (bitmaps, encrypted strings etc) in CHAR fields, for that we will offer methods to write/read byte data, something which was missing in vulcan. We could also support saving 1-1 PSZ strings as well for this , although I am not sure it would be a good idea to encourage again the use of PSZs in X#...

About the sort results with SetInternational(#CLIPPER), sorry about that, but managed to somehow miss it, thanks for the remainder. Will look closely into it and will get back to you.

Chris

Ansi2Oem() / Oem2Ansi() behaviour

Posted: Thu Aug 30, 2018 3:00 pm
by robert
Karl-Heinz,

To add to what Chris said: we should have probably not implemented these functions at all. What would make more sense is:

Unicode2OEM which takes a string and returns a byte[]
And OEM2Unicode which takes a byte[] and returns a string.

The handling of Ansi <-> OEM inside the RDD is a conversion from byte[] to byte[] because the records in the DBF are not strings but bytes.

And indeed our RDD system will have FieldGetBytes() and FieldPutBytes() that return or accept a byte[]. These bytes will be written to the record unchanged. This allows you to store encrypted data in a DBF field.

Robert