poke-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH] pickles: add pickles for PCAP, UUID and RedoxFS


From: Jose E. Marchesi
Subject: Re: [PATCH] pickles: add pickles for PCAP, UUID and RedoxFS
Date: Wed, 16 Nov 2022 11:23:16 +0100
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (gnu/linux)

> 2022-11-15  Mohammad-Reza Nabipoor  <mnabipoor@gnu.org>
>
>       * pickles/uuid.pk: New pickle.
>       * pickles/redoxfs.pk: Likewise.
>       * pickles/pcap.pk: Likewise.
>       * testsuite/poke.pickles/uuid-test.pk: New test.
>       * testsuite/poke.pickles/pcap-test.pk: Likewise.
>       * testsuite/poke.pickles/redoxfs-test.pk: Likewise.
>       * pickles/Makefile.am (dist_pickles_DATA): Update.
>       * testsuite/Makefile.am (EXTRA_DIST): Likewise.
> ---
>
> Hello Jose,
>
> A bunch of new pickles :)
> I wrote them in the past and was available through pokology,
> now I tested them and are ready for the upstream :D

Very nice.  Thank you for the pickles!
OK for master.

>
>
> Regards,
> Mohammad-Reza
>
>
>  ChangeLog                              |  11 +
>  pickles/Makefile.am                    |   3 +-
>  pickles/pcap.pk                        |  88 ++++++++
>  pickles/redoxfs.pk                     | 276 +++++++++++++++++++++++++
>  pickles/uuid.pk                        |  45 ++++
>  testsuite/Makefile.am                  |   3 +
>  testsuite/poke.pickles/pcap-test.pk    | 228 ++++++++++++++++++++
>  testsuite/poke.pickles/redoxfs-test.pk |  31 +++
>  testsuite/poke.pickles/uuid-test.pk    |  85 ++++++++
>  9 files changed, 769 insertions(+), 1 deletion(-)
>  create mode 100644 pickles/pcap.pk
>  create mode 100644 pickles/redoxfs.pk
>  create mode 100644 pickles/uuid.pk
>  create mode 100644 testsuite/poke.pickles/pcap-test.pk
>  create mode 100644 testsuite/poke.pickles/redoxfs-test.pk
>  create mode 100644 testsuite/poke.pickles/uuid-test.pk
>
> diff --git a/ChangeLog b/ChangeLog
> index ec5ce257..1f253d26 100644
> --- a/ChangeLog
> +++ b/ChangeLog
> @@ -1,3 +1,14 @@
> +2022-11-15  Mohammad-Reza Nabipoor  <mnabipoor@gnu.org>
> +
> +     * pickles/uuid.pk: New pickle.
> +     * pickles/redoxfs.pk: Likewise.
> +     * pickles/pcap.pk: Likewise.
> +     * testsuite/poke.pickles/uuid-test.pk: New test.
> +     * testsuite/poke.pickles/pcap-test.pk: Likewise.
> +     * testsuite/poke.pickles/redoxfs-test.pk: Likewise.
> +     * pickles/Makefile.am (dist_pickles_DATA): Update.
> +     * testsuite/Makefile.am (EXTRA_DIST): Likewise.
> +
>  2022-11-13  Jose E. Marchesi  <jemarch@gnu.org>
>  
>       * libpoke/pvm.jitter: Change `map' instruction to not raise
> diff --git a/pickles/Makefile.am b/pickles/Makefile.am
> index e8ff1df5..226621d1 100644
> --- a/pickles/Makefile.am
> +++ b/pickles/Makefile.am
> @@ -25,4 +25,5 @@ dist_pickles_DATA = elf-common.pk elf-64.pk elf-32.pk 
> elf.pk ctf.pk ctf-dump.pk
>                      mcr.pk dwarf-expr.pk dwarf-info.pk id3v2.pk jffs2.pk 
> asn1-ber.pk \
>                      openpgp.pk search.pk riscv.pk coff.pk coff-i386.pk 
> coff-aarch64.pk \
>                      pe.pk pe-amd64.pk pe-arm.pk pe-arm64.pk pe-i386.pk 
> pe-ia64.pk \
> -                    pe-m32r.pk pe-mips.pk pe-ppc.pk pe-sh3.pk pe-riscv.pk 
> pe-debug.pk
> +                    pe-m32r.pk pe-mips.pk pe-ppc.pk pe-sh3.pk pe-riscv.pk 
> pe-debug.pk \
> +                 uuid.pk redoxfs.pk pcap.pk
> diff --git a/pickles/pcap.pk b/pickles/pcap.pk
> new file mode 100644
> index 00000000..45b8cd22
> --- /dev/null
> +++ b/pickles/pcap.pk
> @@ -0,0 +1,88 @@
> +/* pcap.pk - Pickle for libpcap capture file format.  */
> +
> +/* Copyright (C) 2022 The poke authors.  */
> +
> +/* This program is free software: you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation, either version 3 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program.  If not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +/* https://wiki.wireshark.org/Development/LibpcapFileFormat */
> +
> +/* Global Header */
> +type PCAP_Header =
> +  struct
> +  {
> +    uint<8>[4] magic :
> +      get_endian == ENDIAN_BIG ? magic in [[0xa1UB, 0xb2UB, 0xc3UB, 0xd4UB],
> +                                           [0xa1UB, 0xb2UB, 0x3cUB, 0xd4UB]]
> +                               : magic in [[0xd4UB, 0xc3UB, 0xb2UB, 0xa1UB],
> +                                           [0xd4UB, 0x3cUB, 0xb2UB, 0xa1UB]];
> +
> +    uint16 version_major == 2;
> +    uint16 version_minor == 4;
> +    int32  thiszone; /* GMT to local correction */
> +    uint32 sigfigs;  /* accuracy of timestamps */
> +    uint32 snaplen;  /* max length of captured packets, in octets */
> +    uint32 network;  /* data link type */
> +
> +    /* Nano-second resolution file? */
> +    method is_nsec_p = int:
> +      {
> +        return magic in [
> +          [0xa1UB, 0xb2UB, 0x3cUB, 0xd4UB],
> +          [0xd4UB, 0x3cUB, 0xb2UB, 0xa1UB],
> +        ];
> +      }
> +  };
> +
> +/* Packet (Record) Header */
> +type PCAP_PacketHeader =
> +  struct /* (int nsec_p) */
> +  {
> +    uint32 ts_sec;   /* timestamp seconds */
> +    uint32 ts_usec;  /* microseconds (or nanoseconds if `nsec_p`) */
> +    offset<uint32,B> incl_len : /* number of octets of packet saved in file 
> */
> +      incl_len > 0#B;
> +    offset<uint32,B> orig_len : /* actual length of packet */
> +      incl_len <= orig_len;
> +
> +    method is_sliced_p = int:
> +      {
> +        return incl_len != orig_len;
> +      }
> +  };
> +
> +type PCAP_Packet =
> +  struct
> +  {
> +    PCAP_PacketHeader header;
> +
> +    var body_offset = OFFSET;
> +    var body_length = header.incl_len;
> +
> +    byte[0] @ body_offset + body_length; /* End-of-packet marker */
> +
> +    method get_body_offset = offset<uint32,B>: { return body_offset; }
> +    method get_body_length = offset<uint32,B>: { return body_length; }
> +    method get_body = byte[]:
> +      {
> +        return byte[body_length] @ body_offset;
> +      }
> +  };
> +
> +type PCAP =
> +  struct
> +  {
> +    PCAP_Header header;
> +    PCAP_Packet[] packets;
> +  };
> diff --git a/pickles/redoxfs.pk b/pickles/redoxfs.pk
> new file mode 100644
> index 00000000..94380888
> --- /dev/null
> +++ b/pickles/redoxfs.pk
> @@ -0,0 +1,276 @@
> +/* redoxfs.pk - RedoxFS file system of Redox OS.  */
> +
> +/* Copyright (C) 2020 The poke authors */
> +
> +/* This program is free software: you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation, either version 3 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program.  If not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +/* RedoxFS
> + * File-system of RedoxOS (a Unix-like operating system written in Rust)
> + *
> + * The file-system has a header (type `RedoxFS_Header`). Header has a
> + * pointer to root node. Nodes are represented by type `RedoxFS_Node`.
> + * Data is stored in `extents` of each node. Extents are represented
> + * by type `RedoxFS_Extents`. Each node has 238 extents. If a node needs
> + * more extents, it will use the extents of the `next` node.
> + * Each node can be a file or directory or symlink.
> + * Extents of file nodes are point to the actual data. And extents of
> + * directory nodes are point to child nodes.
> + *
> + * https://gitlab.redox-os.org/redox-os/redoxfs/
> + */
> +
> +/* set_endian(ENDIAN_LITTLE); */
> +
> +load time;
> +load uuid;
> +
> +/* Block size */
> +unit RedoxFS_BLKSZ = 4096UL * 8;  /* `4096*8` bits */
> +
> +type RedoxFS_Extent =
> +  struct
> +  {
> +    offset<uint64,RedoxFS_BLKSZ> block;
> +    offset<uint64,B> length;
> +
> +    method is_empty_p = int:
> +      {
> +        return block == 0#B && length == 0#B;  /* CHKME block ?= 0#B */
> +      }
> +    method get_data = uint8[]:
> +      {
> +        return uint8[length] @ block;
> +      }
> +  };
> +
> +type RedoxFS_Time =
> +  struct
> +  {
> +    uint64 sec;
> +    uint32 nsec;
> +  };
> +
> +var RedoxFS_MODE_TYPE    = 0xF000UH,
> +    RedoxFS_MODE_FILE    = 0x8000UH,
> +    RedoxFS_MODE_DIR     = 0x4000UH,
> +    RedoxFS_MODE_SYMLINK = 0xA000UH;
> +
> +var RedoxFS_MODE_PERM  = 0x0FFFUH,
> +    RedoxFS_MODE_EXEC  = 0o1UH,
> +    RedoxFS_MODE_WRITE = 0o2UH,
> +    RedoxFS_MODE_READ  = 0o4UH;
> +
> +/* Callback for extent visitor */
> +type RedoxFS_EVisitor = (RedoxFS_Extent) void;
> +
> +/* A file/folder node */
> +type RedoxFS_Node =
> +  struct
> +  {
> +    uint16 mode;
> +    uint32 uid;
> +    uint32 gid;
> +    RedoxFS_Time ctime;
> +    RedoxFS_Time mtime;
> +    RedoxFS_Time atime;
> +    uint8[226] name;
> +    offset<uint64,RedoxFS_BLKSZ> parent;
> +    offset<uint64,RedoxFS_BLKSZ> next;
> +    RedoxFS_Extent[#RedoxFS_BLKSZ - 288#B] extents;
> +
> +    method is_file_p = int:
> +      {
> +        return (mode & RedoxFS_MODE_FILE) == RedoxFS_MODE_FILE;
> +      }
> +    method is_dir_p = int:
> +      {
> +        return (mode & RedoxFS_MODE_DIR) == RedoxFS_MODE_DIR;
> +      }
> +    method is_symlink_p = int:
> +      {
> +        return (mode & RedoxFS_MODE_SYMLINK) == RedoxFS_MODE_SYMLINK;
> +      }
> +    method get_name = string:
> +      {
> +        return catos (name);
> +      }
> +    method visit_extents = (RedoxFS_EVisitor v) uint64:
> +      {
> +        var c = 0;  /* counter */
> +
> +        for (e in extents where !e.is_empty_p)
> +          {
> +            ++c;
> +            v (e);
> +          }
> +        return c;
> +      }
> +    /* Node pretty-printer
> +     *
> +     * Prints the contents of a `RedoxFS_Node` in a readable fashion.
> +     * To increase readability, prints the non-empty extents before
> +     * the other fields.
> +     */
> +    method _print = void:
> +      {
> +        print ("#<\n  extents = [\n");
> +
> +        var f = 0UL;             /* first */
> +        var l = extents'length;  /* last  */
> +
> +        while (f != l) {
> +          var e = extents[f];
> +
> +          if (!e.is_empty_p)
> +            printf ("    .[%u64d]=%v\n", f, e);
> +          ++f;
> +        }
> +
> +        var mtype =
> +          is_symlink_p ? "FILE | SYM"
> +          : is_dir_p ? "DIR"
> +          : is_file_p ? "FILE"
> +          : "?";  /* This is for zero blocks */
> +
> +        printf (
> +          "  ],\n  mode=%s | %u12o,\n  uid=%u32d,\n  gid=%u32d,\n  ctime=%v 
> (",
> +          mtype, mode & RedoxFS_MODE_PERM, uid, gid, ctime);
> +        ptime (ctime.sec);
> +        printf ("),\n  mtime=%v (", mtime);
> +        ptime (mtime.sec);
> +        printf ("),\n  atime=%v (", atime);
> +        ptime (atime.sec);
> +        printf ("),\n  name=%s,\n", get_name);
> +        printf ("  parent=%v,\n  next=%v,\n>\n", parent, next);
> +      }
> +  };
> +
> +/* Visit all extents of a node, including the nodes pointed to by `next`
> + * field.
> + *
> + * Note that this function cannot be implemented as a method of
> + * `RedoxFS_Node`; because we need to map the `RedoxFS_Node` and we cannot
> + * map an incomplete type.
> + */
> +fun redoxfs_visit_extents = (RedoxFS_Node n, RedoxFS_EVisitor v) uint64:
> +  {
> +    var counter = n.visit_extents (v);
> +
> +    while (n.next != 0#B)
> +      {
> +        n = RedoxFS_Node @ n.next;
> +        counter += n.visit_extents (v);
> +      }
> +    return counter;
> +  }
> +
> +type RedoxFS_Header =
> +  struct
> +  {
> +    string signature = "RedoxFS";
> +    uint64 version = 4UL;
> +
> +    /* Disk ID, a 128-bit unique identifier */
> +    UUID uuid;
> +
> +    offset<uint64,B> size;
> +
> +    offset<uint64,RedoxFS_BLKSZ> root;  /* Block of root node */
> +    offset<uint64,RedoxFS_BLKSZ> free;  /* Block of free space node */
> +
> +    /* Padding */
> +    uint8[#RedoxFS_BLKSZ - 56#B];
> +
> +    method _print = void:
> +      {
> +        printf "#<\n  signature=%s,\n  version=%u64d,\n  uuid=%v,\n  \
> +size=%v,\n  root=%v,\n  free=%v\n>", signature, version, uuid, size, root, 
> free;
> +      }
> +  };
> +
> +assert (#RedoxFS_Node == #RedoxFS_BLKSZ);
> +assert ((RedoxFS_Header {})'size == #RedoxFS_BLKSZ);
> +
> +/* Callback for file-system walker
> + *
> + * FTYPE  'f' for files, 'd' for directories, 's' for symlinks
> + * NAME   Name of the entity
> + * PATH   Path of the parent directory
> + * ES     Array of extents corresponding to the entity
> + */
> +type RedoxFS_Visitor = (char /*ftype*/,
> +                        string /*name*/,
> +                        string /*path*/,
> +                        RedoxFS_Extent[] /*es*/)void;
> +
> +type RedoxFS_Filesystem =
> +  struct
> +  {
> +    RedoxFS_Header header;
> +    RedoxFS_Node root @ header.root;
> +
> +    /* File-system walker
> +     *
> +     * `redoxfs_walk` traverses the file-system hierarchy and call the 
> visitor
> +     * callback function for each entity (file, directory or symlink).
> +     */
> +    method walk = (RedoxFS_Visitor v, RedoxFS_Node n = root) void:
> +      {
> +        fun nothing = (RedoxFS_Extent e) void: {};
> +        fun filev = (RedoxFS_Node n, string curdir) void:
> +          {
> +            /* TODO(mnabipoor) Measure performance of array construction */
> +            var es_count = redoxfs_visit_extents (n, nothing);
> +            var es = RedoxFS_Extent[es_count] ();
> +            var i = 0UL;
> +            fun cp = (RedoxFS_Extent e) void: { es[i++] = e; };
> +
> +            redoxfs_visit_extents (n, cp);
> +            v('f', n.get_name, curdir, es);
> +          }
> +        fun visit = (RedoxFS_Node n, string curdir) void:
> +          {
> +            if (n.is_symlink_p)
> +              v('s', catos (n.extents[0].get_data), curdir, RedoxFS_Extent[] 
> ());
> +            else if (n.is_dir_p)
> +              {
> +                var name = n.get_name;
> +                var path = (curdir == "/" ? "" :  curdir) + "/" + name;
> +                var es_count = redoxfs_visit_extents (n, nothing);
> +                var es = RedoxFS_Extent[es_count] ();
> +                var i = 0UL;
> +                fun ev = (RedoxFS_Extent e) void:
> +                  {
> +                    es[i++] = e;
> +                    visit (RedoxFS_Node @ e.block, path);
> +                  };
> +
> +                redoxfs_visit_extents (n, ev);
> +                v('d', name, curdir, es);
> +              }
> +            else if (n.is_file_p)
> +              filev (n, curdir);
> +          }
> +        var nxt = n.next;
> +
> +        visit (n, "/");
> +        while (nxt != 0#B)
> +          {
> +            n = RedoxFS_Node @ nxt;
> +            nxt = n.next;
> +            visit (n, "/");
> +          }
> +      }
> +  };
> diff --git a/pickles/uuid.pk b/pickles/uuid.pk
> new file mode 100644
> index 00000000..618c7e65
> --- /dev/null
> +++ b/pickles/uuid.pk
> @@ -0,0 +1,45 @@
> +/* uuid.pk - Universally Unique IDentifier (UUID) as defined by RFC4122.  */
> +
> +/* Copyright (C) 2021-2022 The poke authors.  */
> +
> +/* This program is free software: you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation, either version 3 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program.  If not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +/* A Universally Unique IDentifier also known as GUIDs (Globally Unique
> + * IDentifier).
> + * A UUID is 128 bits long, and requires no central registration process.
> + *
> + * Ref: https://www.rfc-editor.org/rfc/rfc4122
> + */
> +
> +type UUID =
> +  struct
> +  {
> +    big uint<32> time_low;
> +    big uint<16> time_mid;
> +    uint<4>      version : version <= 5;
> +    big uint<12> time_hi;
> +    uint<2>      reserved == 0b10; // variant
> +    big uint<14> clock_seq;
> +    big uint<48> node;
> +
> +    computed int<60> time;
> +
> +    method get_time = int<60>:
> +      { return time_hi ::: time_mid ::: time_low; }
> +    method set_time = (int<60> t) void:
> +      { time_hi ::: time_mid ::: time_low = t; }
> +  };
> +
> +assert (UUID {}'size == 128#b);
> diff --git a/testsuite/Makefile.am b/testsuite/Makefile.am
> index dcba512d..2265c330 100644
> --- a/testsuite/Makefile.am
> +++ b/testsuite/Makefile.am
> @@ -606,6 +606,9 @@ EXTRA_DIST = \
>    poke.pickles/id3v1-test.pk \
>    poke.pickles/rgb24-test.pk \
>    poke.pickles/elf-test.pk \
> +  poke.pickles/uuid-test.pk \
> +  poke.pickles/redoxfs-test.pk \
> +  poke.pickles/pcap-test.pk \
>    poke.pkl/pkl.exp \
>    poke.pkl/postincr-1.pk \
>    poke.pkl/postincr-2.pk \
> diff --git a/testsuite/poke.pickles/pcap-test.pk 
> b/testsuite/poke.pickles/pcap-test.pk
> new file mode 100644
> index 00000000..332898ea
> --- /dev/null
> +++ b/testsuite/poke.pickles/pcap-test.pk
> @@ -0,0 +1,228 @@
> +/* pcap-test.pk - Tests for the PCAP pickle.  */
> +
> +/* Copyright (C) 2022 The poke authors.  */
> +
> +/* This program is free software: you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation, either version 3 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program.  If not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +load pktest;
> +load pcap;
> +
> +/* Data is a subset of `dns.cap' extracted from
> +   https://wiki.wireshark.org/SampleCaptures  */
> +
> +var DNS_DATA = [
> +  0xd4UB, 0xc3UB, 0xb2UB, 0xa1UB, 0x02UB, 0x00UB, 0x04UB, 0x00UB,
> +  0x00UB, 0x00UB, 0x00UB, 0x00UB, 0x00UB, 0x00UB, 0x00UB, 0x00UB,
> +  0xffUB, 0xffUB, 0x00UB, 0x00UB, 0x01UB, 0x00UB, 0x00UB, 0x00UB,
> +  0xb2UB, 0x67UB, 0x4aUB, 0x42UB, 0xaeUB, 0x91UB, 0x07UB, 0x00UB,
> +  0x46UB, 0x00UB, 0x00UB, 0x00UB, 0x46UB, 0x00UB, 0x00UB, 0x00UB,
> +  0x00UB, 0xc0UB, 0x9fUB, 0x32UB, 0x41UB, 0x8cUB, 0x00UB, 0xe0UB,
> +  0x18UB, 0xb1UB, 0x0cUB, 0xadUB, 0x08UB, 0x00UB, 0x45UB, 0x00UB,
> +  0x00UB, 0x38UB, 0x00UB, 0x00UB, 0x40UB, 0x00UB, 0x40UB, 0x11UB,
> +  0x65UB, 0x47UB, 0xc0UB, 0xa8UB, 0xaaUB, 0x08UB, 0xc0UB, 0xa8UB,
> +  0xaaUB, 0x14UB, 0x80UB, 0x1bUB, 0x00UB, 0x35UB, 0x00UB, 0x24UB,
> +  0x85UB, 0xedUB, 0x10UB, 0x32UB, 0x01UB, 0x00UB, 0x00UB, 0x01UB,
> +  0x00UB, 0x00UB, 0x00UB, 0x00UB, 0x00UB, 0x00UB, 0x06UB, 0x67UB,
> +  0x6fUB, 0x6fUB, 0x67UB, 0x6cUB, 0x65UB, 0x03UB, 0x63UB, 0x6fUB,
> +  0x6dUB, 0x00UB, 0x00UB, 0x10UB, 0x00UB, 0x01UB, 0xb2UB, 0x67UB,
> +  0x4aUB, 0x42UB, 0xc0UB, 0x93UB, 0x07UB, 0x00UB, 0x62UB, 0x00UB,
> +  0x00UB, 0x00UB, 0x62UB, 0x00UB, 0x00UB, 0x00UB, 0x00UB, 0xe0UB,
> +  0x18UB, 0xb1UB, 0x0cUB, 0xadUB, 0x00UB, 0xc0UB, 0x9fUB, 0x32UB,
> +  0x41UB, 0x8cUB, 0x08UB, 0x00UB, 0x45UB, 0x00UB, 0x00UB, 0x54UB,
> +  0xcbUB, 0xecUB, 0x00UB, 0x00UB, 0x80UB, 0x11UB, 0x99UB, 0x3eUB,
> +  0xc0UB, 0xa8UB, 0xaaUB, 0x14UB, 0xc0UB, 0xa8UB, 0xaaUB, 0x08UB,
> +  0x00UB, 0x35UB, 0x80UB, 0x1bUB, 0x00UB, 0x40UB, 0xc7UB, 0x25UB,
> +  0x10UB, 0x32UB, 0x81UB, 0x80UB, 0x00UB, 0x01UB, 0x00UB, 0x01UB,
> +  0x00UB, 0x00UB, 0x00UB, 0x00UB, 0x06UB, 0x67UB, 0x6fUB, 0x6fUB,
> +  0x67UB, 0x6cUB, 0x65UB, 0x03UB, 0x63UB, 0x6fUB, 0x6dUB, 0x00UB,
> +  0x00UB, 0x10UB, 0x00UB, 0x01UB, 0xc0UB, 0x0cUB, 0x00UB, 0x10UB,
> +  0x00UB, 0x01UB, 0x00UB, 0x00UB, 0x01UB, 0x0eUB, 0x00UB, 0x10UB,
> +  0x0fUB, 0x76UB, 0x3dUB, 0x73UB, 0x70UB, 0x66UB, 0x31UB, 0x20UB,
> +  0x70UB, 0x74UB, 0x72UB, 0x20UB, 0x3fUB, 0x61UB, 0x6cUB, 0x6cUB,
> +  0xb6UB, 0x67UB, 0x4aUB, 0x42UB, 0x14UB, 0xa6UB, 0x07UB, 0x00UB,
> +  0x46UB, 0x00UB, 0x00UB, 0x00UB, 0x46UB, 0x00UB, 0x00UB, 0x00UB,
> +  0x00UB, 0xc0UB, 0x9fUB, 0x32UB, 0x41UB, 0x8cUB, 0x00UB, 0xe0UB,
> +  0x18UB, 0xb1UB, 0x0cUB, 0xadUB, 0x08UB, 0x00UB, 0x45UB, 0x00UB,
> +  0x00UB, 0x38UB, 0x00UB, 0x00UB, 0x40UB, 0x00UB, 0x40UB, 0x11UB,
> +  0x65UB, 0x47UB, 0xc0UB, 0xa8UB, 0xaaUB, 0x08UB, 0xc0UB, 0xa8UB,
> +  0xaaUB, 0x14UB, 0x80UB, 0x1bUB, 0x00UB, 0x35UB, 0x00UB, 0x24UB,
> +  0x9eUB, 0xb0UB, 0xf7UB, 0x6fUB, 0x01UB, 0x00UB, 0x00UB, 0x01UB,
> +  0x00UB, 0x00UB, 0x00UB, 0x00UB, 0x00UB, 0x00UB, 0x06UB, 0x67UB,
> +  0x6fUB, 0x6fUB, 0x67UB, 0x6cUB, 0x65UB, 0x03UB, 0x63UB, 0x6fUB,
> +  0x6dUB, 0x00UB, 0x00UB, 0x0fUB, 0x00UB, 0x01UB, 0xb7UB, 0x67UB,
> +  0x4aUB, 0x42UB, 0x59UB, 0x16UB, 0x05UB, 0x00UB, 0x2aUB, 0x01UB,
> +  0x00UB, 0x00UB, 0x2aUB, 0x01UB, 0x00UB, 0x00UB, 0x00UB, 0xe0UB,
> +  0x18UB, 0xb1UB, 0x0cUB, 0xadUB, 0x00UB, 0xc0UB, 0x9fUB, 0x32UB,
> +  0x41UB, 0x8cUB, 0x08UB, 0x00UB, 0x45UB, 0x00UB, 0x01UB, 0x1cUB,
> +  0xccUB, 0xbbUB, 0x00UB, 0x00UB, 0x80UB, 0x11UB, 0x97UB, 0xa7UB,
> +  0xc0UB, 0xa8UB, 0xaaUB, 0x14UB, 0xc0UB, 0xa8UB, 0xaaUB, 0x08UB,
> +  0x00UB, 0x35UB, 0x80UB, 0x1bUB, 0x01UB, 0x08UB, 0xd6UB, 0xf3UB,
> +  0xf7UB, 0x6fUB, 0x81UB, 0x80UB, 0x00UB, 0x01UB, 0x00UB, 0x06UB,
> +  0x00UB, 0x00UB, 0x00UB, 0x06UB, 0x06UB, 0x67UB, 0x6fUB, 0x6fUB,
> +  0x67UB, 0x6cUB, 0x65UB, 0x03UB, 0x63UB, 0x6fUB, 0x6dUB, 0x00UB,
> +  0x00UB, 0x0fUB, 0x00UB, 0x01UB, 0xc0UB, 0x0cUB, 0x00UB, 0x0fUB,
> +  0x00UB, 0x01UB, 0x00UB, 0x00UB, 0x02UB, 0x28UB, 0x00UB, 0x0aUB,
> +  0x00UB, 0x28UB, 0x05UB, 0x73UB, 0x6dUB, 0x74UB, 0x70UB, 0x34UB,
> +  0xc0UB, 0x0cUB, 0xc0UB, 0x0cUB, 0x00UB, 0x0fUB, 0x00UB, 0x01UB,
> +  0x00UB, 0x00UB, 0x02UB, 0x28UB, 0x00UB, 0x0aUB, 0x00UB, 0x0aUB,
> +  0x05UB, 0x73UB, 0x6dUB, 0x74UB, 0x70UB, 0x35UB, 0xc0UB, 0x0cUB,
> +  0xc0UB, 0x0cUB, 0x00UB, 0x0fUB, 0x00UB, 0x01UB, 0x00UB, 0x00UB,
> +  0x02UB, 0x28UB, 0x00UB, 0x0aUB, 0x00UB, 0x0aUB, 0x05UB, 0x73UB,
> +  0x6dUB, 0x74UB, 0x70UB, 0x36UB, 0xc0UB, 0x0cUB, 0xc0UB, 0x0cUB,
> +  0x00UB, 0x0fUB, 0x00UB, 0x01UB, 0x00UB, 0x00UB, 0x02UB, 0x28UB,
> +  0x00UB, 0x0aUB, 0x00UB, 0x0aUB, 0x05UB, 0x73UB, 0x6dUB, 0x74UB,
> +  0x70UB, 0x31UB, 0xc0UB, 0x0cUB, 0xc0UB, 0x0cUB, 0x00UB, 0x0fUB,
> +  0x00UB, 0x01UB, 0x00UB, 0x00UB, 0x02UB, 0x28UB, 0x00UB, 0x0aUB,
> +  0x00UB, 0x0aUB, 0x05UB, 0x73UB, 0x6dUB, 0x74UB, 0x70UB, 0x32UB,
> +  0xc0UB, 0x0cUB, 0xc0UB, 0x0cUB, 0x00UB, 0x0fUB, 0x00UB, 0x01UB,
> +  0x00UB, 0x00UB, 0x02UB, 0x28UB, 0x00UB, 0x0aUB, 0x00UB, 0x28UB,
> +  0x05UB, 0x73UB, 0x6dUB, 0x74UB, 0x70UB, 0x33UB, 0xc0UB, 0x0cUB,
> +  0xc0UB, 0x2aUB, 0x00UB, 0x01UB, 0x00UB, 0x01UB, 0x00UB, 0x00UB,
> +  0x02UB, 0x58UB, 0x00UB, 0x04UB, 0xd8UB, 0xefUB, 0x25UB, 0x1aUB,
> +  0xc0UB, 0x40UB, 0x00UB, 0x01UB, 0x00UB, 0x01UB, 0x00UB, 0x00UB,
> +  0x02UB, 0x58UB, 0x00UB, 0x04UB, 0x40UB, 0xe9UB, 0xa7UB, 0x19UB,
> +  0xc0UB, 0x56UB, 0x00UB, 0x01UB, 0x00UB, 0x01UB, 0x00UB, 0x00UB,
> +  0x02UB, 0x58UB, 0x00UB, 0x04UB, 0x42UB, 0x66UB, 0x09UB, 0x19UB,
> +  0xc0UB, 0x6cUB, 0x00UB, 0x01UB, 0x00UB, 0x01UB, 0x00UB, 0x00UB,
> +  0x02UB, 0x58UB, 0x00UB, 0x04UB, 0xd8UB, 0xefUB, 0x39UB, 0x19UB,
> +  0xc0UB, 0x82UB, 0x00UB, 0x01UB, 0x00UB, 0x01UB, 0x00UB, 0x00UB,
> +  0x02UB, 0x58UB, 0x00UB, 0x04UB, 0xd8UB, 0xefUB, 0x25UB, 0x19UB,
> +  0xc0UB, 0x98UB, 0x00UB, 0x01UB, 0x00UB, 0x01UB, 0x00UB, 0x00UB,
> +  0x02UB, 0x58UB, 0x00UB, 0x04UB, 0xd8UB, 0xefUB, 0x39UB, 0x1aUB,
> +  0xbfUB, 0x67UB, 0x4aUB, 0x42UB, 0x8fUB, 0xc7UB, 0x04UB, 0x00UB,
> +  0x46UB, 0x00UB, 0x00UB, 0x00UB, 0x46UB, 0x00UB, 0x00UB, 0x00UB,
> +  0x00UB, 0xc0UB, 0x9fUB, 0x32UB, 0x41UB, 0x8cUB, 0x00UB, 0xe0UB,
> +  0x18UB, 0xb1UB, 0x0cUB, 0xadUB, 0x08UB, 0x00UB, 0x45UB, 0x00UB,
> +  0x00UB, 0x38UB, 0x00UB, 0x00UB, 0x40UB, 0x00UB, 0x40UB, 0x11UB,
> +  0x65UB, 0x47UB, 0xc0UB, 0xa8UB, 0xaaUB, 0x08UB, 0xc0UB, 0xa8UB,
> +  0xaaUB, 0x14UB, 0x80UB, 0x1bUB, 0x00UB, 0x35UB, 0x00UB, 0x24UB,
> +  0x4cUB, 0x71UB, 0x49UB, 0xa1UB, 0x01UB, 0x00UB, 0x00UB, 0x01UB,
> +  0x00UB, 0x00UB, 0x00UB, 0x00UB, 0x00UB, 0x00UB, 0x06UB, 0x67UB,
> +  0x6fUB, 0x6fUB, 0x67UB, 0x6cUB, 0x65UB, 0x03UB, 0x63UB, 0x6fUB,
> +  0x6dUB, 0x00UB, 0x00UB, 0x1dUB, 0x00UB, 0x01UB, 0xbfUB, 0x67UB,
> +  0x4aUB, 0x42UB, 0x9fUB, 0xe6UB, 0x06UB, 0x00UB, 0x46UB, 0x00UB,
> +  0x00UB, 0x00UB, 0x46UB, 0x00UB, 0x00UB, 0x00UB, 0x00UB, 0xe0UB,
> +  0x18UB, 0xb1UB, 0x0cUB, 0xadUB, 0x00UB, 0xc0UB, 0x9fUB, 0x32UB,
> +  0x41UB, 0x8cUB, 0x08UB, 0x00UB, 0x45UB, 0x00UB, 0x00UB, 0x38UB,
> +  0xccUB, 0xcdUB, 0x00UB, 0x00UB, 0x80UB, 0x11UB, 0x98UB, 0x79UB,
> +  0xc0UB, 0xa8UB, 0xaaUB, 0x14UB, 0xc0UB, 0xa8UB, 0xaaUB, 0x08UB,
> +  0x00UB, 0x35UB, 0x80UB, 0x1bUB, 0x00UB, 0x24UB, 0xcbUB, 0xf0UB,
> +  0x49UB, 0xa1UB, 0x81UB, 0x80UB, 0x00UB, 0x01UB, 0x00UB, 0x00UB,
> +  0x00UB, 0x00UB, 0x00UB, 0x00UB, 0x06UB, 0x67UB, 0x6fUB, 0x6fUB,
> +  0x67UB, 0x6cUB, 0x65UB, 0x03UB, 0x63UB, 0x6fUB, 0x6dUB, 0x00UB,
> +  0x00UB, 0x1dUB, 0x00UB, 0x01UB, 0xc7UB, 0x67UB, 0x4aUB, 0x42UB,
> +  0x69UB, 0xe5UB, 0x04UB, 0x00UB, 0x55UB, 0x00UB, 0x00UB, 0x00UB,
> +  0x55UB, 0x00UB, 0x00UB, 0x00UB, 0x00UB, 0xc0UB, 0x9fUB, 0x32UB,
> +  0x41UB, 0x8cUB, 0x00UB, 0xe0UB, 0x18UB, 0xb1UB, 0x0cUB, 0xadUB,
> +  0x08UB, 0x00UB, 0x45UB, 0x00UB, 0x00UB, 0x47UB, 0x00UB, 0x00UB,
> +  0x40UB, 0x00UB, 0x40UB, 0x11UB, 0x65UB, 0x38UB, 0xc0UB, 0xa8UB,
> +  0xaaUB, 0x08UB, 0xc0UB, 0xa8UB, 0xaaUB, 0x14UB, 0x80UB, 0x1bUB,
> +  0x00UB, 0x35UB, 0x00UB, 0x33UB, 0x17UB, 0xc2UB, 0x9bUB, 0xbbUB,
> +  0x01UB, 0x00UB, 0x00UB, 0x01UB, 0x00UB, 0x00UB, 0x00UB, 0x00UB,
> +  0x00UB, 0x00UB, 0x03UB, 0x31UB, 0x30UB, 0x34UB, 0x01UB, 0x39UB,
> +  0x03UB, 0x31UB, 0x39UB, 0x32UB, 0x02UB, 0x36UB, 0x36UB, 0x07UB,
> +  0x69UB, 0x6eUB, 0x2dUB, 0x61UB, 0x64UB, 0x64UB, 0x72UB, 0x04UB,
> +  0x61UB, 0x72UB, 0x70UB, 0x61UB, 0x00UB, 0x00UB, 0x0cUB, 0x00UB,
> +  0x01UB, 0xc7UB, 0x67UB, 0x4aUB, 0x42UB, 0x63UB, 0xe7UB, 0x04UB,
> +  0x00UB, 0x81UB, 0x00UB, 0x00UB, 0x00UB, 0x81UB, 0x00UB, 0x00UB,
> +  0x00UB, 0x00UB, 0xe0UB, 0x18UB, 0xb1UB, 0x0cUB, 0xadUB, 0x00UB,
> +  0xc0UB, 0x9fUB, 0x32UB, 0x41UB, 0x8cUB, 0x08UB, 0x00UB, 0x45UB,
> +  0x00UB, 0x00UB, 0x73UB, 0xcdUB, 0x1bUB, 0x00UB, 0x00UB, 0x80UB,
> +  0x11UB, 0x97UB, 0xf0UB, 0xc0UB, 0xa8UB, 0xaaUB, 0x14UB, 0xc0UB,
> +  0xa8UB, 0xaaUB, 0x08UB, 0x00UB, 0x35UB, 0x80UB, 0x1bUB, 0x00UB,
> +  0x5fUB, 0x82UB, 0xb5UB, 0x9bUB, 0xbbUB, 0x81UB, 0x80UB, 0x00UB,
> +  0x01UB, 0x00UB, 0x01UB, 0x00UB, 0x00UB, 0x00UB, 0x00UB, 0x03UB,
> +  0x31UB, 0x30UB, 0x34UB, 0x01UB, 0x39UB, 0x03UB, 0x31UB, 0x39UB,
> +  0x32UB, 0x02UB, 0x36UB, 0x36UB, 0x07UB, 0x69UB, 0x6eUB, 0x2dUB,
> +  0x61UB, 0x64UB, 0x64UB, 0x72UB, 0x04UB, 0x61UB, 0x72UB, 0x70UB,
> +  0x61UB, 0x00UB, 0x00UB, 0x0cUB, 0x00UB, 0x01UB, 0xc0UB, 0x0cUB,
> +  0x00UB, 0x0cUB, 0x00UB, 0x01UB, 0x00UB, 0x01UB, 0x51UB, 0x25UB,
> +  0x00UB, 0x20UB, 0x0cUB, 0x36UB, 0x36UB, 0x2dUB, 0x31UB, 0x39UB,
> +  0x32UB, 0x2dUB, 0x39UB, 0x2dUB, 0x31UB, 0x30UB, 0x34UB, 0x03UB,
> +  0x67UB, 0x65UB, 0x6eUB, 0x09UB, 0x74UB, 0x77UB, 0x74UB, 0x65UB,
> +  0x6cUB, 0x65UB, 0x63UB, 0x6fUB, 0x6dUB, 0x03UB, 0x6eUB, 0x65UB,
> +  0x74UB, 0x00UB, 0x0eUB, 0x68UB, 0x4aUB, 0x42UB, 0x7fUB, 0x77UB,
> +  0x0aUB, 0x00UB, 0x4aUB, 0x00UB, 0x00UB, 0x00UB, 0x4aUB, 0x00UB,
> +  0x00UB, 0x00UB, 0x00UB, 0xc0UB, 0x9fUB, 0x32UB, 0x41UB, 0x8cUB,
> +  0x00UB, 0xe0UB, 0x18UB, 0xb1UB, 0x0cUB, 0xadUB, 0x08UB, 0x00UB,
> +  0x45UB, 0x00UB, 0x00UB, 0x3cUB, 0x00UB, 0x00UB, 0x40UB, 0x00UB,
> +  0x40UB, 0x11UB, 0x65UB, 0x43UB, 0xc0UB, 0xa8UB, 0xaaUB, 0x08UB,
> +  0xc0UB, 0xa8UB, 0xaaUB, 0x14UB, 0x80UB, 0x1bUB, 0x00UB, 0x35UB,
> +  0x00UB, 0x28UB, 0xafUB, 0x61UB, 0x75UB, 0xc0UB, 0x01UB, 0x00UB,
> +  0x00UB, 0x01UB, 0x00UB, 0x00UB, 0x00UB, 0x00UB, 0x00UB, 0x00UB,
> +  0x03UB, 0x77UB, 0x77UB, 0x77UB, 0x06UB, 0x6eUB, 0x65UB, 0x74UB,
> +  0x62UB, 0x73UB, 0x64UB, 0x03UB, 0x6fUB, 0x72UB, 0x67UB, 0x00UB,
> +  0x00UB, 0x01UB, 0x00UB, 0x01UB, 0x0eUB, 0x68UB, 0x4aUB, 0x42UB,
> +  0x8eUB, 0x36UB, 0x0bUB, 0x00UB, 0x5aUB, 0x00UB, 0x00UB, 0x00UB,
> +  0x5aUB, 0x00UB, 0x00UB, 0x00UB, 0x00UB, 0xe0UB, 0x18UB, 0xb1UB,
> +  0x0cUB, 0xadUB, 0x00UB, 0xc0UB, 0x9fUB, 0x32UB, 0x41UB, 0x8cUB,
> +  0x08UB, 0x00UB, 0x45UB, 0x00UB, 0x00UB, 0x4cUB, 0xcfUB, 0xf9UB,
> +  0x00UB, 0x00UB, 0x80UB, 0x11UB, 0x95UB, 0x39UB, 0xc0UB, 0xa8UB,
> +  0xaaUB, 0x14UB, 0xc0UB, 0xa8UB, 0xaaUB, 0x08UB, 0x00UB, 0x35UB,
> +  0x80UB, 0x1bUB, 0x00UB, 0x38UB, 0xa3UB, 0x17UB, 0x75UB, 0xc0UB,
> +  0x81UB, 0x80UB, 0x00UB, 0x01UB, 0x00UB, 0x01UB, 0x00UB, 0x00UB,
> +  0x00UB, 0x00UB, 0x03UB, 0x77UB, 0x77UB, 0x77UB, 0x06UB, 0x6eUB,
> +  0x65UB, 0x74UB, 0x62UB, 0x73UB, 0x64UB, 0x03UB, 0x6fUB, 0x72UB,
> +  0x67UB, 0x00UB, 0x00UB, 0x01UB, 0x00UB, 0x01UB, 0xc0UB, 0x0cUB,
> +  0x00UB, 0x01UB, 0x00UB, 0x01UB, 0x00UB, 0x01UB, 0x40UB, 0xefUB,
> +  0x00UB, 0x04UB, 0xccUB, 0x98UB, 0xbeUB, 0x0cUB,
> +];
> +
> +var tests = [
> +  PkTest {
> +    name = "Decode DNS sample in little endian mode",
> +    func = lambda (string name) void:
> +      {
> +        with_temp_ios
> +          :endian ENDIAN_LITTLE
> +          :do lambda void:
> +            {
> +              byte[] @ 0#B = DNS_DATA;
> +
> +              var pcap = PCAP @ 0#B,
> +                  hdr = pcap.header,
> +                  packets = pcap.packets;
> +
> +              assert (hdr.magic == [0xd4UB, 0xc3UB, 0xb2UB, 0xa1UB]);
> +              assert (hdr.snaplen == 65535);
> +              assert (packets'length == 10);
> +            };
> +      },
> +  },
> +  PkTest {
> +    name = "Decode DNS sample in big endian mode",
> +    func = lambda (string name) void:
> +      {
> +        with_temp_ios
> +          :endian ENDIAN_BIG
> +          :do lambda void:
> +            {
> +              byte[] @ 0#B = DNS_DATA;
> +
> +              try PCAP @ 0#B;
> +              catch (Exception ex)
> +                {
> +                  assert (ex.code == EC_constraint);
> +                  assert (ex.msg[39:] == "PCAP_Header.magic");
> +                  return;
> +                }
> +              assert (0, "Unreachable reached!");
> +            };
> +      },
> +  },
> +];
> +
> +var ok = pktest_run (tests);
> +exit (ok ? 0 : 1);
> diff --git a/testsuite/poke.pickles/redoxfs-test.pk 
> b/testsuite/poke.pickles/redoxfs-test.pk
> new file mode 100644
> index 00000000..8eead199
> --- /dev/null
> +++ b/testsuite/poke.pickles/redoxfs-test.pk
> @@ -0,0 +1,31 @@
> +/* redoxfs-test.pk - Tests for the redoxfs pickle.  */
> +
> +/* Copyright (C) 2022 The poke authors.  */
> +
> +/* This program is free software: you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation, either version 3 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program.  If not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +load pktest;
> +load redoxfs;
> +
> +var tests = [
> +  PkTest {
> +    name = "successful load",
> +    func = lambda (string name) void:
> +      {},
> +  },
> +];
> +
> +var ok = pktest_run (tests);
> +exit (ok ? 0 : 1);
> diff --git a/testsuite/poke.pickles/uuid-test.pk 
> b/testsuite/poke.pickles/uuid-test.pk
> new file mode 100644
> index 00000000..e8427d4f
> --- /dev/null
> +++ b/testsuite/poke.pickles/uuid-test.pk
> @@ -0,0 +1,85 @@
> +/* uuid-test.pk - Tests for the UUID pickle.  */
> +
> +/* Copyright (C) 2022 The poke authors.  */
> +
> +/* This program is free software: you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation, either version 3 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program.  If not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +load pktest;
> +load uuid;
> +
> +// b183fa14-6477-11ed-81ce-0242ac120002
> +var DATA_UUIDv1_1 = [
> +  0xb1UB, 0x83UB, 0xfaUB, 0x14UB, 0x64UB, 0x77UB, 0x11UB, 0xedUB,
> +  0x81UB, 0xceUB, 0x02UB, 0x42UB, 0xacUB, 0x12UB, 0x00UB, 0x02UB,
> +];
> +
> +assert (DATA_UUIDv1_1'size == 128#b);
> +
> +var tests = [
> +  PkTest {
> +    name = "UUID version 1 (check both endians)",
> +    func = lambda (string name) void:
> +      {
> +        with_temp_ios
> +          :endian ENDIAN_BIG
> +          :do lambda void:
> +            {
> +              byte[128#b] @ 0#B = DATA_UUIDv1_1;
> +
> +              var uuid = UUID @ 0#B;
> +
> +              assert (uuid.version == 1);
> +
> +              assert (uuid.time_low == 0xb183fa14U);
> +              assert (uuid.time_mid == 0x6477UH);
> +              assert (uuid.time_hi == 0x1ed);
> +
> +              // Seconds since 15 Oct. 1582 times 100
> +              // 2022-11-14 23:54:36.045570.0 UTC
> +              assert (uuid.time == 0x1ed6477b183fa14);
> +              assert (uuid.time == 138877628760455700);
> +
> +              assert (uuid.clock_seq == 462);
> +              assert (uuid.node == 0x02_42_ac_12_00_02);
> +            };
> +
> +        with_temp_ios
> +          :endian ENDIAN_LITTLE
> +          :do lambda void:
> +            {
> +              byte[128#b] @ 0#B = DATA_UUIDv1_1;
> +
> +              var uuid = UUID @ 0#B;
> +
> +              assert (uuid.version == 1);
> +
> +              assert (uuid.time_low == 0xb183fa14U);
> +              assert (uuid.time_mid == 0x6477UH);
> +              assert (uuid.time_hi == 0x1ed);
> +
> +              // Seconds since 15 Oct. 1582 times 100
> +              // 2022-11-14 23:54:36.045570.0 UTC
> +              assert (uuid.time == 0x1ed6477b183fa14);
> +              assert (uuid.time == 138877628760455700);
> +
> +              assert (uuid.clock_seq == 462);
> +              assert (uuid.node == 0x02_42_ac_12_00_02);
> +            };
> +      },
> +  },
> +];
> +
> +var ok = pktest_run (tests);
> +exit (ok ? 0 : 1);



reply via email to

[Prev in Thread] Current Thread [Next in Thread]