Subject: [core] Variable length uints in CoAP options

From: Stephan Lohse <[email-masked]>
Date: Mon, 16 Jan 2012 16:41:29 +0100

Hi,

this might seem like a stupid question, but CoAP defines options that
are of uint type and can be between 0 and 4 byte long (currently that
affects Max-Age only).
Does that mean, that an "odd" number of bytes, like 3 for example, is
something I have to care about, or do I have to consider only option
lengths that are powers of 2?
The reason I'm asking is that I work with a cross plattform framework,
where endianness is a concern.

Regards,
- Stephan Lohse

---

From: Carsten Bormann <[email-masked]>
Date: Mon, 16 Jan 2012 17:44:29 +0100

> lengths that are powers of 2?

Yes, uints can be any number of bytes (as limited by the specification of the option), see core-coap appendix A.

> where endianness is a concern.

Endianness never is a concern here -- everything is in network byte order (see core-coap appendix A).  Can you elaborate?

As a side observation, I'm personally not very happy with the variable length uints we have, but they seem to be an appropriate compromise between doing this right and staying with the familiar.  See the PS for how to do this right, which I'm not proposing (not even in coap-misc :-).

Grüße, Carsten

PS.:  With our variable length uints, there are multiple representations for every number, which runs against the principle of minimizing unnecessary choice and interop complexity, and also wastes bytes.  We could solve the first, but not the second, by outlawing leading zeroes, but then we have to cope with error cases caused by illegal values, another encoding no-no.  A correct and exceedingly simple way to solve both would be to have each byte in the base-256 place-value system stand for a number between 1 and 256 instead of 0 to 255; 0 would always be encoded in zero bytes; 1 to 256 would be one byte, 257 (0x101) to 65792 (0x10100) would be two bytes, 65793 (0x10101) to 16843008 (0x1010100) would be three bytes, etc.  But that would be a completely new thought for most implementers (who rarely think about number representation), so I never went ahead and actually proposed this.

0 -> 0x'' -> 0
1 -> 0x'00' -> 1
2 -> 0x'01' -> 2
3 -> 0x'02' -> 3
255 -> 0x'fe' -> 255
256 -> 0x'ff' -> 256
257 -> 0x'0000' -> 257
258 -> 0x'0001' -> 258
65534 -> 0x'fefd' -> 65534
65535 -> 0x'fefe' -> 65535
65536 -> 0x'feff' -> 65536
65792 -> 0x'ffff' -> 65792
65793 -> 0x'000000' -> 65793
65794 -> 0x'000001' -> 65794