XNS data format is a flexible text-based encoding of a sequence of numbers, intended for the transport, storage and archiving of binary data. The encoded numbers are of arbitrary size, they may represent bytes, or words of any size, as determined by the application. XNS uses printable characters for ease of management and manipulation. Comments can be included in a file, checksums may optionally be included, and an optional addressing scheme allows the format to be used for memory or boot loading.

XNS is a simple language with a post-fix operator structure. XNS is trivial to encode, and decoding is easy to implement as a simple character-driven state machine. An XNS decoder revolves around a state variable number, numeric characters in the input stream accumulate a value in number, a following operator character determines what to do with the number.

Base XNS

The base functionality is implemented with:

CharacterOperation / Description
(initial conditions) A state variable number is declared and set to 0.
0..9 A..F Append numeral. number is multiplied by the base (16 normally) and the enumerated value of the character added to number. In other words, a new digit is appended to number.
~ Enter Number. Indicates the end of a number, the current value of number is accepted as a number in the sequence. number is set to 0.
SP, CR, LF Reserved as zeroing characters. number is set to 0. This allows comments which contain numeral characters to be inserted in the stream without being entered as data. The only limitation on comments is they must avoid operator characters (such as ~) which may have an undesired action.
... Any other characters in the input stream, including unimplemented operators, set number to 0.

End of Data

If the decoder cannot adequately detect an EOF condition in the input stream, the EOF operator may be implemented.

CharacterOperation / Description
! EOD. End of Data/File.

Checksums

Checksums may be implemented, as an option in both encoders and decoders.

If a decoder does not implement checksums, the checksum characters in a file are inherently ignored. If an encoder does not implement checksums, a decoder simply takes no action. A checksum can be removed from a given file if one is experimenting with a manual modification to the data, with no necessity to recalculate the checksum. Multiple XNS files or segments may be concatentated, while retaining the checksums, also without having to recalculate a final checksum.

CharacterOperation / Description
(initial conditions) An additional state variable checksum is declared and set to 0.
~  : Number Entry & Set Address. number is added to checksum.
] Checksum check. checksum is compared to number, if they differ an error is indicated. The modulo factor is left up to the application. checksum is set to 0.
[ Checksum start. checksum is set to 0. May be used to define a checksum region.

Addressing

Addressing or location specification may be implemented for applications which require it, such as a memory- or boot-loader.

CharacterOperation / Description
(initial conditions) A state variable address is declared and set to 0.
~ Number Entry. address is incremented.
: Set Address. address is set to the current value of number. number is set to 0.

Extensions

An application may declare and implement operators for particular purposes.

Examples

  1. XNS encoding of 5 values:
    00~01~02~03~04~
    
  2. Same as above:
    This comment is ignored
    0~ 01~ 2~ 03~
    following is the fifth number
    00004~
    
  3. 5 numbers with checksum:
    00~01~02~03~04~0A]
    
  4. 5 bytes beginning at location hex FF00, with checksum;
    Note first tilde enters a 0
    FF00:~1~2~3~4~FF0A]
    

Reference Decoder

Following is a reference minimal XNS decoder in Python:
#------------------------------------------------
# XNS Decode
#
# Read characters from the file fd, interpret them as an XNS-encoded stream,
# and put the numbers of the interpreted sequence into a buffer.
# A user-supplied putBuf() function is assumed.

def XNS_Decode( buf, fd ):
	num = 0						# number state-variable

	while True:
		c = fd.read( 1 )			# get character
		if c == '':				# exit on EOF
			break;

		n = '0123456789ABCDEF'.find( c )
		if n>= 0:				# digit of number
			num = (num<<4) | n
		elif c == '~':				# end of number
			putBuf( buf, num )
			num = 0
		elif c == '!':				# exit
			break;
		else:					# anything else clears number state
			num = 0

# End XNS Decode
#------------------------------------------------