Crate test_assembler[][src]

Expand description

A set of types for building complex binary streams.

For testing code that consumes binary data, it is necessary to be able to generate test inputs consisting of various valid and invalid permutations. The Section struct defined in this crate allows for easily building a stream of bytes in any desired endianness.

This crate defines two useful structs: Section and Label. A Section is simply a stream of bytes which can be written to, and a Label is a placeholder for a value that can be computed based on other values, but can be written to a Section without knowing its value at that time.

This crate is based on Jim Blandy’s fantastic C++ implementation in Google Breakpad.

Examples

Section provides many convenient methods for appending data of specific endianness and byte width. There are methods for appending 8, 16, 32, and 64-bit integers using the Section’s default endianness, or explicitly using big or little-endian byte ordering. These methods all have shorthand names of the form:

[endianness][bits]

Where endianness is one of:

  • D: The Section’s default endianness
  • L: little-endian
  • B: big-endian And bits is any of 8, 16, 32, or 64 to write an integer from 1 to 8 bytes in length.

So, for example, to write a little-endian 32-bit integer, call L32.

The Section methods for appending data all consume and return the Section so that they can be chained:

use test_assembler::Section;

let mut section = Section::new();
assert_eq!(section.D8(0xFF).L16(0xABCD).B32(0x12345678)
            .get_contents().unwrap(),
           &[0xFF, 0xCD, 0xAB, 0x12, 0x34, 0x56, 0x78]);

Labels can be appended to a section as placeholders for values that are not yet known using the same methods:

use test_assembler::*;

let l = Label::new();
let mut s = Section::with_endian(Endian::Little);
s = s.D32(&l);
// Now assign a value to l.
l.set_const(0x12345678);
assert_eq!(s.get_contents().unwrap(),
           &[0x78, 0x56, 0x34, 0x12]);

Labels can also be set to the current length of the Section by calling mark, which is useful for calculating an offset into the data:

use test_assembler::*;

let l = Label::new();
let s = Section::with_endian(Endian::Little);
let start = s.start();
s.append_repeated(0, 10)
    .mark(&l)
    .append_repeated(0, 10);
assert_eq!(&l - &start, 10);

Structs

A Label represents a value not yet known that is stored in a Section.

A section is a sequence of bytes, constructed by appending bytes to the end.

Enums

Possible byte orders

An enum to hold Labels or Nums.

Constants

The default endianness for this system.

Traits

Methods for creating a Label (or a RealLabel, but don’t do that).

A marker trait for number types.

A trait to allow passing numbers or Labels.