harbour / core

Portable, xBase compatible programming language and environment
https://harbour.github.io/
Other
324 stars 207 forks source link

RDDADS Problem #354

Open VarenL opened 8 months ago

VarenL commented 8 months ago

Hi,

I have a problem with rddads:

alcz commented 8 months ago

BTW, what's your HB_CdpSelect()? AdsGet, AdsPut ACE API on Windows really do prefer ANSI, maybe they are the same on Linux - but there are no translations active, see rddads.h ADS_USE_OEM_TRANSLATION is only defined on Windows. Does Linux ADS server have ANSI setting at all?

VarenL commented 7 months ago

I am using code page PL852. According to the documentation, the Linux ADS server performs automatic conversion from OEM to ANSI if the table is opened in OEM mode. In the case of the Linux client, code pages stamped in the server (in libadsd.so) are used. I have CP852 and CP1250 sides stamped in, and still the conversion takes place using CP437 and CP1252. In my opinion, this is a bug in ADS that can be bypassed by reading and writing in raw mode.

From ADS documentation:

"· This information applies only to tables opened with the OEM character set type.

When using DBF (ADS_CDX or ADS_NTX) tables with the OEM character set type, Advantage must perform translations between ANSI and OEM character values. If a DBF table is opened with the OEM character set type, then the character data in the table is expected to have OEM values. Advantage converts the values to ANSI before returning it to client applications and performs the reverse conversion when storing data in the tables. The conversions must be done at various times in processing. When reading data, for example, the conversions are performed at the client. When performing SQL operations, some of the conversions must occur at the server.

The Advantage Database Server for Linux has translation tables built into it for converting characters between ANSI and OEM character sets. The existing tables are for converting from OEM character set 437 to the ANSI character set 1252 (the common character sets used in the United States). If you use different character sets, then it is possible you may need different conversion tables. For example, ANSI character 165 (in code page 1252) gets converted to OEM character 190 when using OEM code page 850 and to OEM character 157 when using OEM code page 437.

If you use different code pages, you must stamp the corresponding translation tables into the ADS daemon. The utility stampansioem.exe is provided for this purpose. It must be run from a Windows client. When you run it, provide the adsd binary as the command line parameter. The utility will generate the ANSI/OEM translation tables based on the current operating system settings and stamp those tables into the adds binary.

The Advantage Client Engine for Linux reads the ANSI/OEM translation tables from the server when it connects, so it does not require the tables to be stamped into the client. Win32 clients use the translation functions that are built into the Windows operating systems."

alcz commented 7 months ago

OK, though you seem to miss one information. ACE API functions (as far as i used them and skipping any ...Raw ...UTF8 flavours) always speak ANSI, doesn't matter what the underlying database is. That may need HB_CdpSelect("PLWIN") app(?).

A Windows app speaking OEM internally (may be not common apart from Harbour and Xbase++) to OEM databases on disk encounters double conversion. 1st conv to-ANSI before it reaches ACE lib, 2nd to-OEM before it reaches the disk.

Linux build of Harbour's RDDADS as i pointed before, doesn't have the automatic 1st stage, there goes my speculation.

VarenL commented 7 months ago

HB_CdpSelect() does not matter, both PLWIN and PL852 give the same, incorrect results. Sample read:

ADS_ANSI,PLWIN: ŁĄCZNIKÓ - ok
ADS_ANSI,PL852: ŁĄCZNIKÓ - ok
ADS_OEM, PLWIN: ą˝CZNIKa
ADS_OEM, PL852: ą˝CZNIKa
ADS_OEM, PL852, translate from ESMWIN to EN: ŁĄCZNIKa - partly ok

alcz commented 7 months ago

Can you paste here a sample source code for your simple failing tests? I don't have a Linux ADS installation at hand, but maybe someone else will take a look at this too.

VarenL commented 7 months ago

Sample code and table in the attachment. test.zip