Binary data transmission?
This is a possible extension. Recently I see discussion in several places on how to efficiently send binary data for terminals. One instance is image protocols (specification/#26). Another instance is the binary encoding of the feature reporting (specification/!8).
I don't know what kind of protocol would be the best and whether it should be handled at the parser level, but I think it's worth discussing it at a lower layer instead of separately discussing it for each control function (such like image protocols and feature reporting).
-
baseXX: Base N systems such as Hex encoding, base64, and base85 are popular encoding schemes. For example, hex encoding is used in DA3 response. The sixel format uses a kind of base64 mapping though it doesn't define the encoding of octet streams. There are several options for the mapping table between the bit combinations and ASCII characters:
- The common base64 uses
A-Za-z0-9+/
, which avoids characters that may have special meaning in URLs, filenames, etc. Instead, the conversion is not trivial. It seems we do not have to refrain from using these special characters for terminal communications, so we may consider more straightforward mapping as follows. - Another mapping is
?-~
which is used in sixel format. The conversion is really simple: the value can be obtained by just subtracting the code of?
from the ASCII character. - Also,
@-~?
may be another choice. The lowest six bits (b1..b6) of the ASCII character code can be directly used. The mapping between@-~
and 0-62 is used for parameters of C0/C1 control characters in ISO 2022 IR-132..134 (which came from CCITT T.101 Data Syntax).
- The common base64 uses
But do we really need to transform the binary data to the string of printable characters for terminals? If the terminal and the terminal application can make an agreement, they can directly communicate with binary data because they are connected with each other through a binary stream. In this way, we can minimize the increase of data size and the computation cost of encoding/decoding.
-
XMODEM-like protocol: For example, XMODEM-like protocol may be standardized. XMODEM includes checks for reliability by ENQ/ACK and data integrity checks by checksums, but the protocol is blockwise. It seems that the data size needs to be the multiples of 128 or 1024 in XMODEM, so some adjustment is needed. I think reliability checks and integrity checks can be dropped for modern terminals because these transmission issues are already processed by a lower layer such as SSH. In fact, I have never felt the necessity of reliability/integrity checks for CSI sequences and DCS sequences.
-
Header+Data: Or, maybe a typical binary frame of (a binary header with data type and data size) + (payload) can be used. It is useful that we know the data size in advance to allocate a sufficient size of the buffer.
-
ISO 1745 Information block: Instead of sending the data size in advance, a more terminal-like approach is to enclose the binary data with
STX
andETX
with an appropriate escaping byDLE
(i.e., first replaceDLE
in the payload withDLE DLE
and next enclose the data inDLE STX
andDLE ETX
). But the problem of this approach is that the data size doubles in worst cases. -
Escape (Beehive): Similar escaping seems to be used in APC strings of Beehive ATL-008.
&
is used as the escape character. First&
is replaced by& &
, and then C0 characters00/00
-01/15
are replaced by& @
-& _
. This also doubles the data size in the worst cases. -
COBS: To avoid the inflation of data size, COBS (consistent overhead byte stuffing) can be used. The basic idea is first to split the data into blocks by
00/00
, and each block is encoded as(length)+(block_data)
(see Wikipedia for the details). The encoding/decoding is a little bit complicated, but the encoded data size (for large data) is 100.4% (= 256/255) at worst. -
baseXX with more characters: In image protocols (specification/#26), base192 (105.47%), base224 (102.46%) are base 253 (100.21%) are discussed, but I'm not sure if they are realistic because they require multiple-precision integer calculations. For example, to achieve 106%/103%/100.3% efficiency, we need at least 144bit/280bit/2680bit integers, respectively. We need to use a multiple-precision integer library. and also it is not so efficient computationally. base128 is the upper limit when we only have 64bit integers.
If we develop the terminal parser for the stream of Unicode code points rather than the byte stream, special care needs to be paid for binary data transmission. For example, binary data needs to be processed before UTF-8 decoding.
Edit 2020-07-13 Added descriptions on base64 tables, Beehive escaping, COBS. Updated DLE escapes.