(10-27-2024, 09:57 PM)Justin Case Wrote: It was 10.2.3 - very old!
IIRC, that version predates Indy's inclusion of Unicode support. Everything in that version treated AnsiString as raw bytes, so didn't care about any character encodings.
(10-27-2024, 09:57 PM)Justin Case Wrote: I'm using Delphi 6.
That version's support for Unicode is *extremely* limited. Everything was based on AnsiString. That hasn't been the case in newer Delphi versions for the past 15 years.
In any case, modern Indy *does* still support Delphi 6. However, Indy uses Unicode internally, and only handles ANSI data at the boundaries where data enters and leaves Indy. So, you need to take extra steps to handle charset encodings properly in such old environments. Such as setting the IOHandler.DefAnsiEncoding property to match the encoding that AnsiString uses.
(10-27-2024, 09:57 PM)Justin Case Wrote: It's the character I've always used - even in Indy 8 and 9 - the ¦ (166) character always seemed a good non-obvious one that a user was unlikely to type in.
That character is not a good choice for a communication prototol, as it is dependent on charset interpretation. Even worse if you are dependent on the user's system charset, because it doesn't exist in many charset.
(10-27-2024, 09:57 PM)Justin Case Wrote: As for whether it's ASCII or not, I just assumed if it was on a computer keyboard, it was ok to use
Most modern keyboards don't have a key for ¦, and those that do will usually produce | instead.
(10-27-2024, 09:57 PM)Justin Case Wrote: as v8 and 9 had no problems with it, I've always used it - even in the previous version 10 that I was using.
Only because none of those handled Unicode at all. Now, with Unicode, it is more complicated since ¦ is outside of ASCII.
(10-27-2024, 09:57 PM)Justin Case Wrote: The CmdDelimiter and ParamDelimiter for all my command handlers are set to #166 and have been for years - and it worked well.
In order for that to continue working for you, the DefStringEncoding and DefAnsiEncoding properties need to be compatible with the encoding of the bytes on the wire.
When Indy is receiving a command, before it can parse the command and compare the command's delimiters, it has to receive the command as a native String,which in your case is AnsiString. It will receive the raw bytes, decode them to Unicode first using DefStringEncoding, and then convert the Unicode to AnsiString using DefAnsiEncoding.
Conversely, to send an AnsiString, it has to first be converted to Unicode using DefAnsiEncoding, and then encoded to bytes using DefStringEncoding, and then the bytes are sent on the wire.
Any of those steps can cause data loss if the charset encodings are mismatched.
(10-27-2024, 09:57 PM)Justin Case Wrote: Well that's just it - I've not set a charset on the client or server
Then you are dependent on the user's default system charset. Which can differ from one machine to another. That is not a good position to be in if you need to communicate with other machines.
(10-27-2024, 09:57 PM)Justin Case Wrote: But it didn't do this in the previous 10.2.3 that I was using?
Because that old version predates both Delphi's and Indy's modern Unicode handling.
(10-27-2024, 09:57 PM)Justin Case Wrote: I have no idea what values to use there? - it's defined as a property of IIdTextEncoding but I can't find a definition for IIdTextEncoding anywhere to know what i can use as a value
IIdTextEncoding is an interface type that is defined in Indy's IdGlobal unit. There are several IndyTextEncoding...() functions that return IIdTextEncoding wrappers for various system-defined and user-defined charsets.
(10-27-2024, 09:57 PM)Justin Case Wrote: Ok, eventually I managed to find: IdTextEncodingType = (encIndyDefault, encOSDefault, enc8Bit, encASCII, encUTF16BE, encUTF16LE, encUTF7, encUTF8);
You can't assign an IdTextEncodingType enum directly to DefStringEncoding or DefAnsiEncoding (however, there is an overload of IndyTextEncoding() that returns an IIdTextEncoding for a IdTextEncodingType).
(10-27-2024, 09:57 PM)Justin Case Wrote: I'm not sure how I'm supposed to change the AContext.Connection.IOHandler.DefStringEncoding property..
In this situation, I would suggest using IndyTextEncoding_OSDefault (or IndyTextEncoding_8bit), eg:
Code:
with AContext.Connection.IOHandler do
begin
DefStringEncoding := IndyTextEncoding_OSDefault; // or 8bit
DefAnsiEncoding := IndyTextEncoding_OSDefault; // or 8bit
end;
That should preserve the old behavior you are looking for.