Here´s what i´ve tried so far, not sure if i´m on the right track ...
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
// get the oem string from the bytes
c2 := Encoding.ASCII:GetString(b)
File.WriteAllBytes("d:\test\foo.txt", b ) // content shown as "Žrger"
? "OEM string: " + c2 // "?rger"
// write the byte array content to the dbf field ????....
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.
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.
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 ?
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.
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.
XSharp Development Team