packedobjects is a data encoding tool based on the telecommunications standard Packed Encoding Rules (PER). An abstract syntax language is used to define a protocol specification. packedobjects uses the Scheme programming language to represent the protocol specification within a symbolic expression (s-expression).
packedobjects is suitable for simple cross platform request/response protocols that require efficient encoding.
So far packedobjects has been run on the following platforms:
- Mac OS X (PowerPC)
- Linux (PowerPC)
- Linux (Intel)
- Linux (ARM)
- NetBSD (alpha)
- NetBSD (x86-64)
For a more detailed introduction refer to the following short paper.
John P. T. Moore <firstname.lastname@example.org>
- 0.78 reworked use of deprecated null-pointer and null-pointer? to #f by peter
- 0.77 ported to CHICKEN 4 by felix
- 0.76 fixed .setup issue
- 0.74 Removed .html from egg
- 0.73 Added set-finalizer! to automatically free PDU buffer
- 0.72 Bugfix to SET data type
- 0.71 Minor code improvement
- 0.70 Added two new data types: numeric-string and null
- 0.69 Performance improvements
- 0.66 Inital wiki version
Building from subversion repository
svn checkout http://anonymous:@code.call-cc.org/svn/chicken-eggs/release/4/packedobjects/trunk packedobjects cd packedobjects chicken-install
(packedobjects <protocol> #!key <pdusize> <strsize>)
Creates a packedobject using the supplied protocol specification. Optional values for the PDU and string buffer sizes can be specified. They default to 5000 and 1000 respectively. Both the PDU buffer and string buffer are fixed in size. The string buffer must be large enough to handle any string used by the protocol. The PDU buffer must be manually freed.
(<packedobject> 'pack <values>)
Encodes a list of values and returns the number of bytes used.
Returns a list of values.
(<packedobject> 'read <fd> <size>)
Reads a number of bytes from a file descriptor into the PDU buffer.
(<packedobject> 'write <fd> <size>)
Writes a number of bytes from the PDU buffer to a file descriptor.
(<packedobject> 'read-message <fd>)
Reads a message from a file descriptor into the PDU buffer.
(<packedobject> 'write-message <fd> <size>)
Writes a message containing a number of bytes from the PDU buffer to a file descriptor.
A message consists of the encoded data plus a 2 byte header representing the length of the message. Therefore, the maximum message size is 2^16-1 bytes.
(<packedobject> 'dump-buffer <filename> <size>)
Dumps a number of bytes from the PDU buffer to a file.
Explicitly frees the PDU buffer. N.B. This call is optional as the memory will be automatically garbage collected.
Data types with examples
The following data types are currently supported.
- (foobar string (size 1 10))
- (foobar "foobar")
- 7 bit string limited to 10 characters in length.
- (foobar octet-string ())
- (foobar "foobar")
- 8 bit string with no length restriction.
- (foobar bit-string (size 8))
- (foobar "10101010")
- Bitstring fixed in length.
- (foobar hex-string (size 1 max))
- (foobar "afafaf")
- String of hexadecimal characters with no length restriction.
- (foobar numeric-string ())
- (foobar "123")
- String of numeric characters with no length restriction.
- (foobar integer (range 1 10))
- (foobar 5)
- Integer with a minimum allowed value of 1 and maximum allowed value of 10.
- (foobar boolean)
- (foobar #t)
- Boolean value.
- (foobar enumerated (mon tues wed thurs fri))
- (foobar fri)
- List of alternative symbols.
- (foobar null)
- Null value.
- (foobar sequence (foo string (size 1 10)) (bar string (size 1 10)))
- (foobar (foo "foo") (bar "bar"))
- Ordered sequence of types.
- (foobar sequence-of (foo string (size 1 10)) (bar string (size 1 10)))
- (foobar ((foo "foo") (bar "bar")) ((foo "anotherfoo") (bar "anotherbar")))
- Ordered sequence of types where the sequence may repeat.
- (foobar set (foo string (size 1 10)) (bar string (size 1 10)))
- (foobar (bar "bar") (foo "foo"))
- Unordered sequence of types. Each element of a set is also optional.
- (foobar choice (foo integer ()) (bar integer ()))
- (foobar (bar 100))
- Single item from a series of types.
Constraints may be placed on all string types as well as integers. Restricting the size of strings and the range of integers can reduce the amount of bits encoded.
The following are valid string contraints:
- (size min max)
- (size <unsigned> <unsigned>)
- (size <unsigned>)
The following are valid integer constraints:
- (range min max)
- (range <int> <int>)
Note, min and max denotes no lower bound and upper bound respectively, therefore () is equivalent to (size min max) or (range min max).
(require-extension packedobjects) (define bbcard '(bbcard sequence (name string (size 1 60)) (team string (size 1 60)) (age integer (range 1 100)) (position string (size 1 60)) (handedness enumerated (left-handed right-handed ambidextrous)) (batting-average sequence (mantissa integer ()) (base enumerated (2 10)) (exponent integer ())))) (define bbcard-values '(bbcard (name "Casey") (team "Mudville Nine") (age 32) (position "left field") (handedness ambidextrous) (batting-average (mantissa 250) (base 10) (exponent -3)))) (define po (packedobjects bbcard)) (print* "encoded in " (po 'pack bbcard-values) " bytes.\n") (print (po 'unpack)) (po 'free)
The following example retrieves random numbers from random.org.
The client talks to a server process which in turn obtains the numbers using HTTP. The data transferred between client and server is significantly more efficient, in terms of bits on the wire, than if the client talked directly to random.org using HTTP.
- The length of strings, the number of elements in a set and the number of times a sequence-of may repeat is restricted to 2^30-1.
- The maximum integer (unsigned), the number of choices and the number of enumerations is restricted to 2^32-1.
- Tidy code.
- Performance enhancements.
- Improvements to error/exception handling.
- Further testing.
Copyright (c) 2006, John P. T. Moore
All rights reserved.