ENOSUCHBLOG

Programming, philosophy, pedaling.


Introducing netstring.cr

Oct 10, 2018     Tags: crystal, devblog, programming    

This post is at least a year old.

Yet another Crystal shard announcement: I’m releasing netstring.cr, a tiny library for parsing netstrings.

Net-whats?

Netstrings are a barebones string serialization format, containing just enough information to parse a string of exactly N bytes. Every netstring begins with an (ASCII) length prefix, followed by a literal ‘:’, followed by exactly length bytes of data, followed by a literal ‘,’.

So,

1
6:foobar,

parses as “foobar”. Because they specify their exact length, netstrings are trivially nestable:

1
12:3:foo,3:bar,,

parses as “3:foo,3:bar,”, each of which can then be parsed individually.

Installation and usage

The easiest way to install netstring.cr is via Crystal’s shards dependency manager. You can find the relevant steps in the repository README.

To instantiate a netstring, use Netstring.parse with either a source String or IO:

1
2
3
4
5
6
7
require "netstring"

ns1 = Netstring.parse "22:parsing from a string!,"

io = IO::Memory.new("19:parsing from an IO!,")

ns2 = Netstring.parse io

By default, netstring.cr limits the size of a netstring to Netstring::NETSTRING_MAX (999999999, taken from djb’s reference implementation). Users can make this either higher or lower by passing their own maximum to parse:

1
2
3
4
ns3 = Netstring.parse "5:apple,", max: 6

# parse error!
ns4 = Netstring.parse "8:cucumber,", max: 6

Both parse forms return a new Netstring instance, which provides three simple methods for querying the state of a netstring: #size, #data, and #to_s:

1
2
3
4
5
6
ns1.size # => 22

ns2.data # => Bytes[112, 97, 114, 115, ...]

# encodes to UTF-8, so make sure your netstring is valid unicode!
ns1.to_s # => "parsing from a string!"

Thanks for reading!


Discussions: Reddit