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
-
- Posts: 774
- Joined: Wed May 17, 2017 8:50 am
- Location: Germany
Ansi2Oem() / Oem2Ansi() behaviour
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
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
XSharp Development Team
The Netherlands
robert@xsharp.eu
The Netherlands
robert@xsharp.eu
-
- Posts: 774
- Joined: Wed May 17, 2017 8:50 am
- Location: Germany
Ansi2Oem() / Oem2Ansi() behaviour
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 ...
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
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
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
Wolfgang Riedmann
Meran, South Tyrol, Italy
wolfgang@riedmann.it
https://www.riedmann.it - https://docs.xsharp.it
Meran, South Tyrol, Italy
wolfgang@riedmann.it
https://www.riedmann.it - https://docs.xsharp.it
Ansi2Oem() / Oem2Ansi() behaviour
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
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
Chris Pyrgas
XSharp Development Team
chris(at)xsharp.eu
XSharp Development Team
chris(at)xsharp.eu
-
- Posts: 774
- Joined: Wed May 17, 2017 8:50 am
- Location: Germany
Ansi2Oem() / Oem2Ansi() behaviour
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
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
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
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
Chris Pyrgas
XSharp Development Team
chris(at)xsharp.eu
XSharp Development Team
chris(at)xsharp.eu
Ansi2Oem() / Oem2Ansi() behaviour
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
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
XSharp Development Team
The Netherlands
robert@xsharp.eu
The Netherlands
robert@xsharp.eu