Skip to content

Instantly share code, notes, and snippets.

@landonf
Last active August 29, 2015 14:16
Show Gist options
  • Save landonf/7276a3a2b562a6d2aa56 to your computer and use it in GitHub Desktop.
Save landonf/7276a3a2b562a6d2aa56 to your computer and use it in GitHub Desktop.
using namespace codecs;
/* Define a set of codecs for encoding/decoding VoodooPad's encrypted document header */
auto versionCodec = (
// `|' associates an arbitrary string context with a codec; this is used
// for error reporting, providing additional information on parse errors.
("record_compat_version" | codecs::uint8 ) &
("record_feature_version" | codecs::uint8 )
).as<VDERecordVersion>();
// `as` takes a set of Codecs over types <T...> and returns a new Codec<U> that
// 1) Extracts T... from U's fields when encoding, and
// 2) Applies T... to U's constructor to produce a well-typed object when decoding.
auto sectionCodec = (
// The base uintXX codecs assume big endian serialization; the `L'
// variants assume little endian serialization. */
("section_offset" | codecs::uint64L ) &
("section_length" | codecs::uint64L )
).as<VDESectionRecord>();
const auto fileMagic = ByteVector::Bytes("VPVDE", 5, false);
auto headerCodec = (
// The `constant' codec always encodes the given constant, producing
// no value, and on decoding, consumes sizeof(fileMagic) bytes
// and produces a parse error if the consumed value does not match
// the expected constant.
//
// The '>>' operator drops the produced/consumed constant from the
// set of input/output of the combined codec; since it's a constant,
// we don't need to save the value anywhere after we've parsed it,
// and we don't need to supply the value when encoding.
("magic" | constant(fileMagic) ) >>
("file_version" | versionCodec ) &
("vde_encrypted_sect" | sectionCodec ) &
("vde_session_sect" | sectionCodec )
).as<VDEFileHeader>();
/* XCTAssertRoundTrip() is a test assertion that encodes the given value,
* decodes it, and asserts that the initial value and final decoded value
* are identical */
auto header = VDEFileHeader(VDERecordVersion(1, 2), VDESectionRecord(10, 20), VDESectionRecord(30, 40));
XCTAssertRoundTrip(headerCodec, header);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment