A New Milestone is Reached
Marco van de Voort has reported that he has sent an E-Mail message using Indy
from a Mac OS/X machine. This proves to me that Indy is now capable of
running in multiple architectures.
This is not merely my pride in my colleague's work but rather a milestone for
the FPC Indy 10 port. Porting Indy is something I want to do properly and
there's more than what meets the eye. Indy was based on working
assumptions for the i386 platform that are not true on other
architectures. Some things I've noticed are:
- People were using Cardinals and LongWords interchangeably. In FPC,
this may not be a 4-byte integer. It may be an 8 byte unsigned integer
on x84 architectures. It's the same deal with the Integer type.
This has some potential real-world consequences. In some protocols,
record-like structures are written out in a standard form (e.g. 4 bytes for
field A, 2 bytes for field B). Code writing a Cardinal could easily
write 8 bytes and some of it gets overwritten and you wind up having a
flawed protocol implementation that will not work with servers.
- Some chips use the big endian byte-order for storing integer values while
others use little endian and network byte-order is standardized for big
endian. Usually, this is not a problem because stacks have byte
functions (htonl, htons, ntohl, and ntols) that provide transparency for this
meaning valures are converted to standard network byte-rrder and from
network-byte order to the byte order on the running machine.
Unfortunately, I found that ping uses little Endian instead of big endian when
writing a checksum value that the other side verifies. There may be
other places where little endian is used.
- Pointers may not always be 4 bytes. On 64bit architectures, those
are 8 bytes. In a few places, I had to make adjustments in Indy
code. Luckily, we had been restricting pointer usage so we could target
DotNET. Other code is more difficult to port because it uses pointers
- The Indy run-time units do not depend on any GUI elements or console
functions. The TIdAntifreeze unit is not included in run-time packages
at all. We put it some design-time packages because it will never be
completely portable because widget sets are so different. If you really
need to prevent programs from locking up, use TIdNotify in IdSync to send
queued notifications to the main thread or if you need to synchronize with the
main-thread, use TIdSync. The classes are not used by themselves but
rather, you make descendant classes for your programs. Other helpful
things are classes in IdThreadSafe that wrap variables in Critical sections
I admit this is rather long-winded but I feel that there is a difference
between simply porting code and porting code properly. I have seen code
that could NEVER work under non-i386 architectures.