Thread: Binary tx format for an array?

Binary tx format for an array?

From
"Michael Guyver"
Date:
Hi there,

My question relates to trying to implement the binary transmission
protocol for an Array type. I understand that the only place the
format is documented is in the Postgres C source code.

I've had a look through it and it seems comprehensible enough (to a
non-C programmer), but I was wondering how the following expression
would evaluate:

// arrayfuncs.c, in array_recv
element_type = pq_getmsgint(buf, sizeof(Oid));

or more specifically, the

int size = sizeof(Oid);

expression. Knowing this value would mean knowing how many bytes
describing the Oid to transmit.

Cheers

Michael

Re: Binary tx format for an array?

From
Dave Cramer
Date:
My guess is that it depends on the machine it is on.

Dave
On 21-Jun-06, at 1:26 PM, Michael Guyver wrote:

> Hi there,
>
> My question relates to trying to implement the binary transmission
> protocol for an Array type. I understand that the only place the
> format is documented is in the Postgres C source code.
>
> I've had a look through it and it seems comprehensible enough (to a
> non-C programmer), but I was wondering how the following expression
> would evaluate:
>
> // arrayfuncs.c, in array_recv
> element_type = pq_getmsgint(buf, sizeof(Oid));
>
> or more specifically, the
>
> int size = sizeof(Oid);
>
> expression. Knowing this value would mean knowing how many bytes
> describing the Oid to transmit.
>
> Cheers
>
> Michael
>
> ---------------------------(end of
> broadcast)---------------------------
> TIP 6: explain analyze is your friend
>


Re: Binary tx format for an array?

From
Mark Lewis
Date:
The definition of Oid is in postgres_ext.h:

typedef unsigned int Oid;

All the architectures that I'm familiar with (x86, x86_64, Sparc-64) use
32-bit unsigned int data types.  Also, the JDBC driver code always uses
32-bit integers for Oid types, so I think you're pretty safe using a 32-
bit integer.

There might be some weirdness at the 2GB boundary because Java doesn't
support natively unsigned integers, but if there is then it would
probably occur across the whole driver and not just in the code you want
to write.

-- Mark

On Wed, 2006-06-21 at 18:26 +0100, Michael Guyver wrote:
> Hi there,
>
> My question relates to trying to implement the binary transmission
> protocol for an Array type. I understand that the only place the
> format is documented is in the Postgres C source code.
>
> I've had a look through it and it seems comprehensible enough (to a
> non-C programmer), but I was wondering how the following expression
> would evaluate:
>
> // arrayfuncs.c, in array_recv
> element_type = pq_getmsgint(buf, sizeof(Oid));
>
> or more specifically, the
>
> int size = sizeof(Oid);
>
> expression. Knowing this value would mean knowing how many bytes
> describing the Oid to transmit.
>
> Cheers
>
> Michael
>
> ---------------------------(end of broadcast)---------------------------
> TIP 6: explain analyze is your friend

Re: Binary tx format for an array?

From
Tom Lane
Date:
"Michael Guyver" <kenevel@googlemail.com> writes:
> ... or more specifically, the
> int size = sizeof(Oid);

sizeof(Oid) is 4 [bytes].  You can check this and other basic datatype
sizes by looking in pg_type.

            regards, tom lane

Re: Binary tx format for an array?

From
"Michael Guyver"
Date:
Thanks very much for your prompt help on this lads.

> sizeof(Oid) is 4 [bytes].  You can check this and other basic datatype
> sizes by looking in pg_type.

So in the following code

StringInfo    buf = (StringInfo) PG_GETARG_POINTER(0)
// ...
Oid element_type = pq_getmsgint(buf, sizeof(Oid));

are the bytes representing an int4 Oid simply 23, represented in variable buf as

[0x17][0x00][0x00][0x00]

The reason for asking is I'm under the impression there can be
differences between network byte-order and other representations.
Hopefully this isn't an inane question - apologies if it is.

Regards,

Michael

Re: Binary tx format for an array?

From
Tom Lane
Date:
"Michael Guyver" <kenevel@googlemail.com> writes:
> are the bytes representing an int4 Oid simply 23, represented in variable buf as

> [0x17][0x00][0x00][0x00]

No, in the buffer they'll be in network (big-endian) byte order,

[0x00][0x00][0x00][0x17]

If you are running in a little-endian architecture (eg Intel) then at
some point you'll be wanting to reverse the byte order to make a native
integer.  In C you'd use ntohl() to do this.  I'm not sure what's the
appropriate thing in Java --- I was under the impression that Java tried
to hide hardware details like endianness, so there may be some
convention about how you turn a sequence of bytes into a native integer.

            regards, tom lane

Re: Binary tx format for an array?

From
Mark Lewis
Date:
> appropriate thing in Java --- I was under the impression that Java tried
> to hide hardware details like endianness, so there may be some
> convention about how you turn a sequence of bytes into a native integer.

Java tried so hard to hide endianness from you that it didn't provide
any real support for those times when you DO need to be aware of it.  So
the "convention" looks kind of like this (snipped from the PG JDBC
driver):

    public void SendInteger4(int val) throws IOException
    {
        SendChar((val >> 24)&255);
        SendChar((val >> 16)&255);
        SendChar((val >> 8)&255);
        SendChar(val&255);
    }

There finally were endian-aware buffer operations added in JDK 1.4, but
using them would be a big code change and would make the driver
unavailable for users of antique JVM's.

-- Mark

Re: Binary tx format for an array?

From
"Michael Guyver"
Date:
On 22/06/06, Tom Lane <tgl@sss.pgh.pa.us> wrote:
> No, in the buffer they'll be in network (big-endian) byte order,
>
> [0x00][0x00][0x00][0x17]

On 22/06/06, Mark Lewis <mark.lewis@mir3.com> wrote:
> Java tried so hard to hide endianness from you that it didn't provide
> any real support for those times when you DO need to be aware of it.  So
> the "convention" looks kind of like this (snipped from the PG JDBC
> driver):
>
>    public void SendInteger4(int val) throws IOException {
>        SendChar((val >> 24)&255);
>        SendChar((val >> 16)&255);
>        SendChar((val >> 8)&255);
>        SendChar(val&255);
>    }

Of course that's right: I got myself confused.

Thanks very much for your help, no doubt I'll be back for some more
(please sir) in the future.

I'm optimistic I'm on the right track but wanted to conceive a way of
unit testing the different Java classes that represent PG types, and
their binary Tx and Rx methods.

One way I thought of doing this is simply to send the values over JDBC
(specifying binary parameters) and check the contents of a test table
once all the inserts are done, but such unit tests get very messy very
quickly, and you wind up storing your expected results in a different
file, which is firstly something you have to keep in sync with the
source code and secondly tends to grow and become unmanageable very
quickly.

Another way would be to use the JNI mechanism to talk directly to the
PG code, calling the xxxrecv() functions for the type you're testing,
reading back the type's value using the xxxsend() method. Not being a
C man, I'm not sure how easy this would be and would appreciate any
suggestions.

Regards,

Michael

Re: Binary tx format for an array?

From
Dave Cramer
Date:
Michael

I'm curious. Are you attempting to implement the binary protocol for
the jdbc driver ?

If so, how are you dealing with date types which are either 64 bit or
floating point.

Have you done any testing to see if it is actually faster ?

There's certainly no question with timestamp/date parsing, others may
be questionable .

Dave
On 23-Jun-06, at 4:22 AM, Michael Guyver wrote:

> On 22/06/06, Tom Lane <tgl@sss.pgh.pa.us> wrote:
>> No, in the buffer they'll be in network (big-endian) byte order,
>>
>> [0x00][0x00][0x00][0x17]
>
> On 22/06/06, Mark Lewis <mark.lewis@mir3.com> wrote:
>> Java tried so hard to hide endianness from you that it didn't provide
>> any real support for those times when you DO need to be aware of
>> it.  So
>> the "convention" looks kind of like this (snipped from the PG JDBC
>> driver):
>>
>>    public void SendInteger4(int val) throws IOException {
>>        SendChar((val >> 24)&255);
>>        SendChar((val >> 16)&255);
>>        SendChar((val >> 8)&255);
>>        SendChar(val&255);
>>    }
>
> Of course that's right: I got myself confused.
>
> Thanks very much for your help, no doubt I'll be back for some more
> (please sir) in the future.
>
> I'm optimistic I'm on the right track but wanted to conceive a way of
> unit testing the different Java classes that represent PG types, and
> their binary Tx and Rx methods.
>
> One way I thought of doing this is simply to send the values over JDBC
> (specifying binary parameters) and check the contents of a test table
> once all the inserts are done, but such unit tests get very messy very
> quickly, and you wind up storing your expected results in a different
> file, which is firstly something you have to keep in sync with the
> source code and secondly tends to grow and become unmanageable very
> quickly.
>
> Another way would be to use the JNI mechanism to talk directly to the
> PG code, calling the xxxrecv() functions for the type you're testing,
> reading back the type's value using the xxxsend() method. Not being a
> C man, I'm not sure how easy this would be and would appreciate any
> suggestions.
>
> Regards,
>
> Michael
>
> ---------------------------(end of
> broadcast)---------------------------
> TIP 4: Have you searched our list archives?
>
>               http://archives.postgresql.org
>


Re: Binary tx format for an array?

From
Markus Schaber
Date:
Hi, Dave,

Dave Cramer wrote:

> I'm curious. Are you attempting to implement the binary protocol for the
> jdbc driver ?
>
> If so, how are you dealing with date types which are either 64 bit or
> floating point.
>
> Have you done any testing to see if it is actually faster ?
>
> There's certainly no question with timestamp/date parsing, others may be
> questionable .

At least for PostGIS (which uses a hexed representation for text
protocol currently), I expect the data volume to be exactly 50% for binary.

Bytea and blobs may be similar.


Markus



--
Markus Schaber | Logical Tracking&Tracing International AG
Dipl. Inf.     | Software Development GIS

Fight against software patents in EU! www.ffii.org www.nosoftwarepatents.org

Re: Binary tx format for an array?

From
"Michael Guyver"
Date:
> > :) good question, I'm sure I'll stare it in the face soon enough. At
> > the moment I'm labouring under the impression that individual
> > parameters can be specified as binary or text.
>
> Unfortunately this is not possible. :( And one of the reasons that
> I've not spent a lot of time on this.

Hi Dave,

the page Message Formats
(http://www.postgresql.org/docs/8.1/static/protocol-message-formats.html)
specifies that the bind message should send the following for each
parameter:

    Int16 - The number of parameter format codes that follow (denoted
C below). This can be zero to indicate that there are no parameters or
that the parameters all use the default format (text); or one, in
which case the specified format code is applied to all parameters; or
it can equal the actual number of parameters.

    Int16[C] - The parameter format codes. Each must presently be zero
(text) or one (binary).

Does your understanding of the spec mean that the Int16[C] must either
be an array containg all zero's, or all ones? It reads as though these
can be mixed.

Re: Binary tx format for an array?

From
Dave Cramer
Date:
On 23-Jun-06, at 8:47 AM, Michael Guyver wrote:

>> > :) good question, I'm sure I'll stare it in the face soon
>> enough. At
>> > the moment I'm labouring under the impression that individual
>> > parameters can be specified as binary or text.
>>
>> Unfortunately this is not possible. :( And one of the reasons that
>> I've not spent a lot of time on this.
>
> Hi Dave,
>
> the page Message Formats
> (http://www.postgresql.org/docs/8.1/static/protocol-message-
> formats.html)
> specifies that the bind message should send the following for each
> parameter:
>
>    Int16 - The number of parameter format codes that follow (denoted
> C below). This can be zero to indicate that there are no parameters or
> that the parameters all use the default format (text); or one, in
> which case the specified format code is applied to all parameters; or
> it can equal the actual number of parameters.
>
>    Int16[C] - The parameter format codes. Each must presently be zero
> (text) or one (binary).
>
> Does your understanding of the spec mean that the Int16[C] must either
> be an array containg all zero's, or all ones? It reads as though these
> can be mixed.

Actually, it's the return value that is either/or . It appears that
input parameters can be mixed.

Tom can they be mixed going in ?

I'm very curious to see how much performance gain can be had here. As
I said the real gains would be on result sets especially parsing date/
time, timestamps.
>


Re: Binary tx format for an array?

From
Dave Cramer
Date:
On 23-Jun-06, at 8:56 AM, Dave Cramer wrote:

>
> On 23-Jun-06, at 8:47 AM, Michael Guyver wrote:
>
>>> > :) good question, I'm sure I'll stare it in the face soon
>>> enough. At
>>> > the moment I'm labouring under the impression that individual
>>> > parameters can be specified as binary or text.
>>>
>>> Unfortunately this is not possible. :( And one of the reasons that
>>> I've not spent a lot of time on this.
>>
>> Hi Dave,
>>
>> the page Message Formats
>> (http://www.postgresql.org/docs/8.1/static/protocol-message-
>> formats.html)
>> specifies that the bind message should send the following for each
>> parameter:
>>
>>    Int16 - The number of parameter format codes that follow (denoted
>> C below). This can be zero to indicate that there are no
>> parameters or
>> that the parameters all use the default format (text); or one, in
>> which case the specified format code is applied to all parameters; or
>> it can equal the actual number of parameters.
>>
>>    Int16[C] - The parameter format codes. Each must presently be zero
>> (text) or one (binary).
>>
>> Does your understanding of the spec mean that the Int16[C] must
>> either
>> be an array containg all zero's, or all ones? It reads as though
>> these
>> can be mixed.
>
> Actually, it's the return value that is either/or . It appears that
> input parameters can be mixed.
Hmmm maybe I should read before sending. It appears that both input,
and output can be text. The only catch with output is that you have
to do a describe first to get the types. This may negate any gains on
small result sets, but certainly for large ones it would help.
>
> Tom can they be mixed going in ?
>
> I'm very curious to see how much performance gain can be had here.
> As I said the real gains would be on result sets especially parsing
> date/time, timestamps.
>>
>
>
> ---------------------------(end of
> broadcast)---------------------------
> TIP 9: In versions below 8.0, the planner will ignore your desire to
>       choose an index scan if your joining column's datatypes do not
>       match
>


Re: Binary tx format for an array?

From
Tom Lane
Date:
Dave Cramer <pg@fastcrypt.com> writes:
> Hmmm maybe I should read before sending. It appears that both input,
> and output can be text. The only catch with output is that you have
> to do a describe first to get the types. This may negate any gains on
> small result sets, but certainly for large ones it would help.

Right, both parameters and results can be mixed, but to ask for
mixed-format result columns you have to know how many there are
... and in reality you probably want to know what the column
types are before you make your decisions, anyway.  So unless the
driver has a-priori knowledge of the result column set, which I
gather it doesn't, there'd need to be an additional round trip
to fetch and inspect the query's result column set before issuing BIND.

I think that in practice most clients would do "all text all the time"
or "all binary all the time", which is why the protocol allows compact
selection of those two cases.

            regards, tom lane

Re: Binary tx format for an array?

From
Mark Lewis
Date:
> Hmmm maybe I should read before sending. It appears that both input,
> and output can be text. The only catch with output is that you have
> to do a describe first to get the types. This may negate any gains on
> small result sets, but certainly for large ones it would help.

Disclaimer: this is my first real trip through the v3 protocol and the
JDBC driver source in general.  So take anything below with several
grains of salt.

As far as I can tell from reading the JDBC CVS code, the sequence for
preparing and executing a statement for the first time is:

PREPARE            (name=my_statement)
DESCRIBE STATEMENT (name=my_statement)
SYNC/FLUSH
Read Responses

BIND               (portal=my_portal)
DESCRIBE PORTAL    (name=my_portal)
EXECUTE            (portal=my_portal)
SYNC/FLUSH
Read Responses

So it seems that we could do all text, mixed or all binary parameters
without adding a round trip, because we already do an extra round trip
when a statement is first prepared and we already know all of the
parameter types.

We could do all text or all binary outputs without adding a round trip
as well, because you can globally set the output format, but to do mixed
outputs we'd need to execute the DESCRIBE PORTAL to get the return
types, and then (not sure?) execute BIND again with different format
parameters?

-- Mark Lewis

Re: Binary tx format for an array?

From
Dave Cramer
Date:
On 23-Jun-06, at 4:32 PM, Mark Lewis wrote:

>> Hmmm maybe I should read before sending. It appears that both input,
>> and output can be text. The only catch with output is that you have
>> to do a describe first to get the types. This may negate any gains on
>> small result sets, but certainly for large ones it would help.
>
> Disclaimer: this is my first real trip through the v3 protocol and the
> JDBC driver source in general.  So take anything below with several
> grains of salt.
>
> As far as I can tell from reading the JDBC CVS code, the sequence for
> preparing and executing a statement for the first time is:
>
> PREPARE            (name=my_statement)
> DESCRIBE STATEMENT (name=my_statement)
> SYNC/FLUSH
> Read Responses
>
> BIND               (portal=my_portal)
> DESCRIBE PORTAL    (name=my_portal)
> EXECUTE            (portal=my_portal)
> SYNC/FLUSH
> Read Responses
>
> So it seems that we could do all text, mixed or all binary parameters
> without adding a round trip, because we already do an extra round trip
> when a statement is first prepared and we already know all of the
> parameter types.

Yup, you could, however the real win here is on parsing the return
parameters, going from object to string is not terribly expensive.

Network times are probably a red herring.

>
> We could do all text or all binary outputs without adding a round trip
> as well, because you can globally set the output format, but to do
> mixed
> outputs we'd need to execute the DESCRIBE PORTAL to get the return
> types, and then (not sure?) execute BIND again with different format
> parameters?
Yes, you can do binary results, but consider what happens if someone
returns a type the driver doesn't know about ?
>
> -- Mark Lewis
>


Re: Binary tx format for an array?

From
Kris Jurka
Date:

On Fri, 23 Jun 2006, Mark Lewis wrote:

> As far as I can tell from reading the JDBC CVS code, the sequence for
> preparing and executing a statement for the first time is:
>
> PREPARE            (name=my_statement)
> DESCRIBE STATEMENT (name=my_statement)
> SYNC/FLUSH
> Read Responses
>
> BIND               (portal=my_portal)
> DESCRIBE PORTAL    (name=my_portal)
> EXECUTE            (portal=my_portal)
> SYNC/FLUSH
> Read Responses
>

Nope. There is no Sync in the middle there.  The driver sends Parse,
Describe Statement, Bind, Execute, Sync all at once.  You may be confused
by the driver's ability to Parse/Describe/Sync a query to implement
ParameterMetaData, but that's an unusual operation, not the normal path.

Kris Jurka

Re: Binary tx format for an array?

From
Mark Lewis
Date:
On Fri, 2006-06-23 at 15:46 -0500, Kris Jurka wrote:
> > As far as I can tell from reading the JDBC CVS code, the sequence for
> > preparing and executing a statement for the first time is:
> >
> > PREPARE            (name=my_statement)
> > DESCRIBE STATEMENT (name=my_statement)
> > SYNC/FLUSH
> > Read Responses
> >
> > BIND               (portal=my_portal)
> > DESCRIBE PORTAL    (name=my_portal)
> > EXECUTE            (portal=my_portal)
> > SYNC/FLUSH
> > Read Responses
> >
>
> Nope. There is no Sync in the middle there.  The driver sends Parse,
> Describe Statement, Bind, Execute, Sync all at once.  You may be confused
> by the driver's ability to Parse/Describe/Sync a query to implement
> ParameterMetaData, but that's an unusual operation, not the normal path.

Ah, yes that's where I was confused.  Now I understand why it was such a
pain to support things like timestamp with/without timezone; you don't
get the describe statement back until you've already run the BIND.

-- Mark

java & endianness [Re: Binary tx format for an array?]

From
Marc Herbert
Date:
Mark Lewis <mark.lewis@mir3.com> writes:

> Java tried so hard to hide endianness from you that it didn't provide
> any real support for those times when you DO need to be aware of it.

Could you give sample cases when you DO need it? I don't think that
many people write hardware drivers in Java ;-)

I don't think network communication qualifies either, see below.


> So the "convention" looks kind of like this (snipped from the PG JDBC
> driver):
>
>     public void SendInteger4(int val) throws IOException
>     {
>         SendChar((val >> 24)&255);
>         SendChar((val >> 16)&255);
>         SendChar((val >> 8)&255);
>         SendChar(val&255);
>     }

This code is like copied/pasted from the JDK:

 * @since   JDK1.0
DataOutputStream#writeInt()


Any reason for duplicating it in the driver?



> There finally were endian-aware buffer operations added in JDK 1.4,

Could you detail which ones? Thanks in advance.


Re: java & endianness [Re: Binary tx format for an array?]

From
Mark Lewis
Date:
On Mon, 2006-07-10 at 11:19 +0200, Marc Herbert wrote:
> Mark Lewis <mark.lewis@mir3.com> writes:
>
> > Java tried so hard to hide endianness from you that it didn't provide
> > any real support for those times when you DO need to be aware of it.
>
> Could you give sample cases when you DO need it? I don't think that
> many people write hardware drivers in Java ;-)

Any time you're working with network protocols, as was the case with
this example here.  Try to send a 32-bit integer over the network, for
the other end to receive it correctly, it needs to be in the byte-order
the client expects.

> I don't think network communication qualifies either, see below.
>
>
> > So the "convention" looks kind of like this (snipped from the PG JDBC
> > driver):
> >
> >     public void SendInteger4(int val) throws IOException
> >     {
> >         SendChar((val >> 24)&255);
> >         SendChar((val >> 16)&255);
> >         SendChar((val >> 8)&255);
> >         SendChar(val&255);
> >     }
>
> This code is like copied/pasted from the JDK:
>
>  * @since   JDK1.0
> DataOutputStream#writeInt()
>
>
> Any reason for duplicating it in the driver?

Well, in the general case you can only use DataOutputStream's writeInt()
method if everything is in big-endian byte order, which is true in this
case but not universally so.  Here it IS big-endian, so the choice is
between duplicating one method a few lines long, or wrapping the main
OutputStream in an extra DataOutputStream which would only be used when
writing big-endian integers.  Not sure if one solution is better than
the other.

> > There finally were endian-aware buffer operations added in JDK 1.4,
>
> Could you detail which ones? Thanks in advance.

It's in the java.nio stuff, look at the javadoc for ByteBuffer.order()
for a starting point.

-- Mark

Re: java & endianness [Re: Binary tx format for an array?]

From
Marc Herbert
Date:
Mark Lewis <mark.lewis@mir3.com> writes:

>> >     public void SendInteger4(int val) throws IOException
>> >     {
>> >         SendChar((val >> 24)&255);
>> >         SendChar((val >> 16)&255);
>> >         SendChar((val >> 8)&255);
>> >         SendChar(val&255);
>> >     }
>>
>> This code is like copied/pasted from the JDK:
>>
>>  * @since   JDK1.0
>> DataOutputStream#writeInt()
>>
>>
>> Any reason for duplicating it in the driver?
>
> Well, in the general case you can only use DataOutputStream's writeInt()
> method if everything is in big-endian byte order, which is true in this
> case but not universally so.

My point is that it IS universally true in the Java universe AND in
the networking universe. There simply cannot be two opposed networking
universes... that would mean we'd have two Internets for instance?

So I think the whole point of Java is that everything is big-endian, so
you do not need to know about endianness anymore. IMHO this is a
success.


> Here it IS big-endian, so the choice is between duplicating one
> method a few lines long, or wrapping the main OutputStream in an
> extra DataOutputStream which would only be used when writing
> big-endian integers.  Not sure if one solution is better than the
> other.

OK you can bypass/copy-paste some JDK code for performance
reasons. But then you can not honestly complain Java does a poor job
of hiding endianness when you fiddled with the machine internals
instead of safely staying outside.

Moreover you don't really need to think about endianness when simply
copy/pasting this code.


> It's in the java.nio stuff, look at the javadoc for
> ByteBuffer.order() for a starting point.

Interesting. Looks like you need this only when dealing with
badly-behaved applications that do not use the network order, right?
Should be very seldom, don't you think?


Thanks for answering.




Re: java & endianness [Re: Binary tx format for an array?]

From
Mark Lewis
Date:
On Mon, 2006-07-10 at 19:54 +0200, Marc Herbert wrote:
> My point is that it IS universally true in the Java universe AND in
> the networking universe. There simply cannot be two opposed networking
> universes... that would mean we'd have two Internets for instance?
>
> So I think the whole point of Java is that everything is big-endian, so
> you do not need to know about endianness anymore. IMHO this is a
> success.

Just because Java is big-endian and this particular protocol is big-
endian does not mean that the universe is big-endian.  There are
protocols which either always use little-endian, or allow the endian-
ness of parameters to be negotiated for performance.  One example is the
TDS protocol, so you may want to look at the open source jTDS JDBC
driver and see how they handle it.

Your point is however well taken that there are more big-endian
protocols out there than little-endian protocols, and Java works easily
with those.

> Interesting. Looks like you need this only when dealing with
> badly-behaved applications that do not use the network order, right?
> Should be very seldom, don't you think?

It's not badly-behaving applications, it's protocols whose designers
chose to use little-endian formatting, usually for performance reasons
on common x86 hardware.

-- Mark