From e0c6872cf40896c7be36b11dcc744620f10adf1d Mon Sep 17 00:00:00 2001 From: Norbert Preining Date: Mon, 2 Sep 2019 13:46:59 +0900 Subject: Initial commit --- macros/latex/contrib/bytefield/README | 46 + macros/latex/contrib/bytefield/bf-example.pdf | Bin 0 -> 199324 bytes macros/latex/contrib/bytefield/bf-example.tex | 496 ++++ macros/latex/contrib/bytefield/bytefield.dtx | 3484 +++++++++++++++++++++++++ macros/latex/contrib/bytefield/bytefield.ins | 51 + macros/latex/contrib/bytefield/bytefield.pdf | Bin 0 -> 405723 bytes 6 files changed, 4077 insertions(+) create mode 100644 macros/latex/contrib/bytefield/README create mode 100644 macros/latex/contrib/bytefield/bf-example.pdf create mode 100644 macros/latex/contrib/bytefield/bf-example.tex create mode 100644 macros/latex/contrib/bytefield/bytefield.dtx create mode 100644 macros/latex/contrib/bytefield/bytefield.ins create mode 100644 macros/latex/contrib/bytefield/bytefield.pdf (limited to 'macros/latex/contrib/bytefield') diff --git a/macros/latex/contrib/bytefield/README b/macros/latex/contrib/bytefield/README new file mode 100644 index 0000000000..e1e0d208b9 --- /dev/null +++ b/macros/latex/contrib/bytefield/README @@ -0,0 +1,46 @@ + +---------------------------------+ + | THE BYTEFIELD PACKAGE | + | Scott Pakin, scott+bf@pakin.org | + +---------------------------------+ + + +Description +----------- + +The bytefield package helps the user create illustrations for network +protocol specifications and anything else that utilizes fields of +data. These illustrations show how the bits and bytes are laid out in +a packet, register, or memory. + + +Building bytefield +------------------ + +tex bytefield.ins <== Produces bytefield.sty (the package proper) +latex bytefield.dtx <== Produces bytefield.dvi (the documentation) +makeindex -s gind.ist bytefield.idx -o bytefield.ind <== Writes an index +makeindex -s gglo.ist bytefield.glo -o bytefield.gls <== Writes a change log +latex bytefield.dtx <== Incorporates the index and change log into + bytefield.dvi + +Note that bytefield comes with pre-built documentation. Also, there +is an example.tex file that shows how one might include hyperlinks in +a protocol diagram. example.tex needs the hyperref package and should +be run through pdfLaTeX, VTeX, dvipdfm, or any other backend that +supports hyperref hyperlinks. + + +Copyright and license +--------------------- + +Copyright (C) 2017 Scott Pakin, scott+bf@pakin.org + +This package may be distributed and/or modified under the conditions +of the LaTeX Project Public License, either version 1.3a of this +license or (at your option) any later version. The latest version of +this license is in: + + http://www.latex-project.org/lppl.txt + +and version 1.3c or later is part of all distributions of LaTeX version +2006/05/20 or later. diff --git a/macros/latex/contrib/bytefield/bf-example.pdf b/macros/latex/contrib/bytefield/bf-example.pdf new file mode 100644 index 0000000000..adf30c5deb Binary files /dev/null and b/macros/latex/contrib/bytefield/bf-example.pdf differ diff --git a/macros/latex/contrib/bytefield/bf-example.tex b/macros/latex/contrib/bytefield/bf-example.tex new file mode 100644 index 0000000000..1604261a2c --- /dev/null +++ b/macros/latex/contrib/bytefield/bf-example.tex @@ -0,0 +1,496 @@ +\documentclass[11pt]{article} +\usepackage[margin=1in]{geometry} +\usepackage{longtable} +\usepackage[bitheight=6ex]{bytefield} +\usepackage{color} +\usepackage[bookmarksopen=true]{hyperref} + +\title{Integrating \texttt{bytefield} and \texttt{hyperref}} +\author{\href{http://www.pakin.org/~scott}{Scott Pakin + \texttt{}}} +\date{18 January 2011} +\hypersetup{% +pdftitle={Integrating bytefield and hyperref}, +pdfauthor={Scott Pakin }, +pdfsubject={Example of bytefield package}, +pdfkeywords={bytefield, hyperref, multicast transport protocol, hyperlink, example}} + +% Set up hyperlink colors +\definecolor{darkred}{rgb}{0.5,0,0} +\definecolor{darkgreen}{rgb}{0,0.3,0} +\definecolor{darkblue}{rgb}{0,0,0.5} +\definecolor{darkbrown}{rgb}{0.28,0.07,0.07} +\hypersetup{% + colorlinks=true, + citecolor=darkblue, + urlcolor=darkgreen, + linkcolor=darkred, + menucolor=darkbrown} + +\begin{document} +\sloppy +\maketitle + +\begin{abstract} +This document is a demonstration of how the \texttt{bytefield} package can +integrate seamlessly with \texttt{hyperref}. The text that follows was +copy-and-pasted from +\href{http://www.rfc-editor.org/rfc/rfc1301.txt}{RFC~1301, ``Multicast +Transport Protocol''}~\cite{Armstrong92}. + +The important thing to note is the way the fields in the protocol diagrams +(drawn with \texttt{bytefield}) are hyperlinked to their descriptions (with +\texttt{hyperref}). Few typesetting systems enable authors to specify +hyperlinks from within a figure to the surrounding text. Fewer still do +not require hyperlinks to be re-specified when the figure changes. +\texttt{bytefield}~+ \texttt{hyperref} can do both. +\end{abstract} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\setcounter{section}{1} + +\section{Protocol description} + + MTP is a transport in that it is a client of the network layer (as + defined by the OSI networking model).\footnote{The network layer is not + specified by MTP. One of the goals is to specify a transport that can be + implemented with equal functionality on many network architectures.} + MTP provides reliable delivery of client data between one or more + communicating processes, as well as a predefined principal process. The + collection of processes is called a web. + + In addition to transporting data reliably and efficiently, MTP + provides the synchronization necessary for web members to agree on + the order of receipt of all messages and can agree on the delivery of + the message even in the face of partitions. This ordering and + agreement protocol uses serialized tokens granted by the master to + producers. + + The processes may have any one of three levels of capability. One + member must be the master. The master instantiates and controls the + behavior of the web, including its membership and performance. Non + master members may be either producer/consumers or pure consumers. + The former class of member is permitted to transmit user data to the + entire membership (and expected to logically hear itself), while the + latter is prohibited from transmitting user data. + + MTP is a negative acknowledgement protocol, exploiting the highly + reliable delivery of the local area and wide area network + technologies of today. Successful delivery of data is accepted by + consuming stations silently rather than having the successful + delivery noted to the producing process, thus reducing the amount of + reverse traffic required to maintain synchronization. + +\subsection{Definition of terms} + +\begin{center} + \fbox{Skipped; see~\cite{Armstrong92}} +\end{center} + +\subsection{Packet format} + + An MTP packet consists of a transport protocol header followed by a + variable amount of data. The protocol header, shown in + Figure~\ref{fig:packet-format}, is part of every packet. The remainder + of the packet is either user data (packet type = data) or additional + transport specific information. The fields in the header are statically + defined as n-bit wide quantities. There are no undefined fields or + fields that may at any time have undefined values. Reserved fields, if + they exist, must always have a value of zero. + +\begin{figure}[htbp] + \centering + \begin{bytefield}{32} + \bitheader{0,7-8,15-16,23-24,31} \\ + + \begin{rightwordgroup}{transport \\ header} + % We have to do the \parbox explicitly in the next line because + % \hyperlink typesets its argument in horizontal mode. + \bitbox{8}{\hyperlink{protocol-version}{\parbox{\width}{\centering protocol version}}} & + \bitbox{8}{\hyperlink{packet-type-modifier}{packet type}} & + \bitbox{8}{\hyperlink{packet-type-modifier}{type modifier}} & + \bitbox{8}{\hyperlink{subchannel}{client channel}} \\ + + \wordbox{1}{\hyperlink{source-connect}{source connection identifier}} \\ + + \wordbox{1}{\hyperlink{dest-connect}{destination connection identifier}} \\ + + \wordbox{1}{\hyperlink{msg-accept}{message acceptance criteria}} \\ + + \wordbox{1}{\hyperlink{heartbeat}{heartbeat}} \\ + + \bitbox{16}{\hyperlink{window}{window}} & + \bitbox{16}{\hyperlink{retention}{retention}} + \end{rightwordgroup} \\ + + \begin{rightwordgroup}{data \\ fields} + \wordbox[lrt]{1}{% + \parbox{0.6\width}{\centering (data content and format dependent on packet type and modifier)}} \\ + \skippedwords \\ + \wordbox[lrb]{1}{} + \end{rightwordgroup} + \end{bytefield} + \caption{MTP packet format} + \label{fig:packet-format} +\end{figure} + +\hypertarget{protocol-version}{\subsubsection{Protocol version}} + + The first 8 bits of the packet are the protocol version number. This + document describes version 1 of the Multicast Transport Protocol and + thus the version field has a value of 0x01. + +\hypertarget{packet-type-modifier}{\subsubsection{Packet type and modifier}} + + The second byte of the header is the packet type and the following + byte contains the packet type modifier. Typical control message + exchanges are in a request/response pair. The modifier field + simplifies the construction of responses by permitting reuse of the + incoming message with minimal modification. The following table gives + the packet type field values along with their modifiers. The + modifiers are valid only in the context of the type. In the prose of + the definitions and later in the document, the syntax for referring + to one of the entries described in the following table will be + type[modifier]. For example, a reference to data[eow] would be a + packet of type data with an end of window modifier. + +\begin{center} +\renewcommand{\arraystretch}{1.5} +\begin{longtable}{llp{0.6\textwidth}} + type & modifier & description \\ \hline + + data(0) & data(0) & The packet is one that contains user + information. Only the process possessing a + transmit token is permitted to send data + unless specifically requested to retransmit + previously transmitted data. All packets of + type data are multicast to the entire web. \\ + + & eow(1) & A data packet with the eow (end of window) + modifier set indicates that the transmitter + intends to send no more packets in this + heartbeat either because it has sent as many + as permitted given the window parameter or + simply has no more data to send during the + current heartbeat. This is not client + information but rather a hint to be used by + transport providers to synchronize the + computation and transmission of naks. \\ + + & eom(2) & Data[eom] marks the end of the message to the + consumers, and the surrendering of the + transmit token to the master. And like a + data[eow] a data[eom] packet implies the end + of window. \\ + nak(1) & request(0) & A nak[request] packet is a consumer + requesting a retransmission of one or more + data packets. The data field contains an + ordered list of packet sequence numbers that + are being requested. Naks of any form are + always unicast. \\ + + & deny(1) & A nak[deny] message indicates that the + producer source of the nak[deny]) cannot + retransmit one or more of the packets + requested. The process receiving the + nak[deny] must report the failure to its + client. \\ + + empty(2) & dally(0) & An empty[dally] packet is multicast to + maintain synchronization when no client data + is available. \\ + + & cancel(1) & If a producer finds itself in possession of a + transmit token and has no data to send, it + may cancel the token[request] by multicasting + an empty[cancel] message. \\ + + & hibernate(2)&If the master possesses all of the web's + transmit tokens and all outstanding messages + have been accepted or rejected, the master + may transmit empty[hibernate] packets at a + rate significantly slower than indicated by + the web's value of heartbeat. \\ + + join(3) & request(0) & A join[request] packet is sent by a process + wishing to join a web to the web's unknown + TSAP (see section~\ref{sec:dest-connect}). \\ + + & confirm(1) & The join[confirm] packet is the master's + confirmation of the destination's request to + join the web. It will be unicast by the + master (and only the master) to the station + that sent the join[request]. \\ + + & deny(2) & A join[deny] packet indicates permission to + join the web was denied. It may only be + transmitted by the master and will be unicast + to the member that sent the join[request]. \\ + + quit(4) & request(0) & A quit[request] may be unicast to the master + by any member of the web at any time to + indicate the sending process wishes to + withdraw from the web. Any member may unicast + a quit to another member requesting that the + destination member quit the web due to + intolerable behavior. The master may + multicast a quit[request] requiring that the + entire web disband. The request will be + multicast at regular heartbeat intervals + until there are no responses to retention + requests. \\ + + & confirm(1) & The quit[confirm] packet is the indication + that a quit[request] has been observed and + appropriate local action has been taken. + Quit[confirm] are always unicast. \\ + + token(5) & request(0) & A token[request] is a producing member + requesting a transmit token from the master. + Such packets are unicast to the master. \\ + + & confirm(1) & The token[confirm] packet is sent by the + master to assign the transmit token to a + member that has requested it. token[confirm] + will be unicast to the member being granted + the token. \\ + + isMember(6)&request(0)& An isMember[request] is soliciting + verification that the target member is a + recognized member of the web. All forms of + the isMember packet are unicast to a specific + member. \\ + + & confirm(1) & IsMember[confirm] packets are positive + responses to isMember[requests]. \\ + + & deny(2) & If the member receiving the isMember[request] + cannot confirm the target's membership in the + web, it responds with a isMember[deny]. +\end{longtable} +\end{center} + +\hypertarget{subchannel}{\subsubsection{Subchannel}} + + The fourth byte of the transport header contains the client's + subchannel value. The default value of the subchannel field is zero. + Semantics of the subchannel value are defined by the transport client + and therefore are only applicable to packets of type data. All other + packet types must have a subchannel value of zero. + +\hypertarget{source-connect}{\subsubsection{Source connection identifier}} + + The source connection identifier field is a 32 bit field containing a + transmitting system unique value assigned at the time the transport + is created. The field is used in identifying the particular transport + instantiation and is a component of the TSAP\@. Every packet + transmitted by the transport must have this field set. + +\hypertarget{dest-connect}{\subsubsection{Destination connection identifier}} +\label{sec:dest-connect} + + The destination connection identifier is the 32 bit identifier of the + target transport. From the point of view of a process sending a + packet, there are three types of destination connection identifiers. + First, there is the unknown connection identifier (0x00000000). The + unknown value is used only as the destination connection identifier + in the join[request] packet. + + Second, there is the multicast connection identifier gleaned from the + join[confirm] message sent by the master. The multicast connection + identifier is used in conjunction with the multicast NSAP to form the + destination TSAP of all packets multicast to the entire + web.\footnote{There's only one such multicast connection identifier per + web. If there are multiple processes on the same machine participating + in a web, the transport must descriminate between those processes by + using the connnection identifier.} + + The last class of connection identifier is a unicast identifier and + is used to form the destination TSAP when unicasting packets to + individual members. Every member of the web has associated with it a + unicast connection identifier that is used to form its own unicast + TSAP. + +\hypertarget{msg-accept}{\subsubsection{Message acceptance}} + + MTP ensures that all processes agree on which messages are accepted + and in what order they are accepted. The master controls this aspect + of the protocol by controlling allocation of transmit tokens and + setting the status of messages. Once a token for a message has been + assigned (see section 3.2.1) the master sets the status of that + message according to the following rules~\cite{Armstrong91}: + + \begin{itemize} + \item If the master has seen the entire message (i.e., has seen the + data[eom] and all intervening data packets), the status is accepted. + + \item If the master has not seen the entire message but believes the + message sender is still operational and connected to the master (as + determined by the master), the status is pending. + + \item If the master has not seen the entire message and believes the + sender to have failed or partitioned away, the status is rejected. + \end{itemize} + + Message status is carried in the message acceptance record (see + Figure~\ref{fig:msg-accept}) of every packet, and processes learn the + status of earlier messages by processing this information. + + The acceptance criteria is a multiple part record that carries the rules + of agreement to determine the message acceptance. + \hypertarget{synchro}{The most significant 8 bits is a flag that, if not + zero, indicates synchronization is required.} The field may vary on a + per message basis as directed by producing transport's client. The + default is that no synchronization is required. + + \hypertarget{tri-state}{The second part of the record is a 12 element + vector that represents the status of the last 12 messages transmitted + into the web.} + +\begin{figure}[htbp] + \centering + \begin{bytefield}{32} + \bitheader{0,7-8,15-16,23-24,31} \\ + + \bitbox{8}{\hyperlink{synchro}{synchro}} & + \bitbox{24}{\hyperlink{tri-state}{tri-state bitmask{[12]}}} \\ + + \bitbox{16}{\hyperlink{msg-seq}{message sequence number}} & + \bitbox{16}{\hyperlink{packet-seq}{packet sequence number}} + \end{bytefield} + \caption{Message acceptance record} + \label{fig:msg-accept} +\end{figure} + + Each element of the array is two bits in length and may have one of + three values: accepted(0), pending(1) or rejected(2). Initially, the + bit mask is set to all zeros. When the token for message $m$ is + transmitted, the first (left-most) element of the vector represents + the the state of message $m - 1$, the second element of the vector is + the status of message $m - 2$, and so forth. Therefore the status of + the last 12 messages are visible, the status of older messages are + lost, logically by shifting the elements out of the vector. Only the + master is permitted to set the status of messages. The master is not + permitted to shift a status of pending beyond the end of the vector. + If that situation arises, the master must instead not confirm any + token[request] until the oldest message can be marked as either + rejected or accepted. + + \hypertarget{msg-seq}{Message sequence numbers are 16 bit unsigned + values.} The field is initialized to zero by the master when the + transport is initialized, and incremented by one after each token is + granted. Only the master is permitted to change the value of the message + sequence number. Once granted, that message sequence number is consumed + and the state of the message must eventually become either accepted or + rejected. No transmit tokens may be granted if the assignment of a + message sequence number that would cause a value of pending to be + shifted beyond the end of the status vector. + + \hypertarget{packet-seq}{Packet sequence numbers are unsigned 16 bit + numbers assigned by the producing process on a per message basis.} + Packet sequence numbers start at a value of zero for each new message + and are incremented by one (consumed) for each data packet making up the + message. Consumers detecting missing packet sequence numbers must send a + nak[request] to the appropriate producer to recover the missed data. + + Control packets always contain the message acceptance criteria with a + synchronization flag set to zero (0x00), the highest message sequence + number observed and a packet sequence number one greater than + previously observed. Control packets do not consume any sequence + numbers. Since control messages are not reliably delivered, the + acceptance criteria should only be checked to see if they fall within + the proper range of message numbers, relative to the current message + number of the receiving station. The range of acceptable sequence + numbers should be $m-11$ to $m-13$, inclusive, where $m$ is the current + message number. + +\hypertarget{heartbeat}{\subsubsection{Heartbeat}} + + Heartbeat is an unsigned 32 bit field that has the units of + milliseconds. The value of heartbeat is shared by all members of the + web. By definition at least one packet (either data, empty or quit + from the master) will be multicast into the web within every + heartbeat period. + +\hypertarget{window}{\subsubsection{Window}} + + The allocation window (or simply window) is a 16 bit unsigned field + that indicates the maximum number of data packets that can be + multicasted by a member in a single heartbeat. It is the sum of the + retransmitted and new data packets. + +\hypertarget{retention}{\subsubsection{Retention}} + + The retention field is a 16 bit unsigned value that is the number of + heartbeats for which a producer must retain transmitted client data + and state for the purpose of retransmission. + +\subsection{Transport addresses} + + Associated with each transport are logically three transport service + access points (TSAP), logically formed by the concatenation of a + network service access point (NSAP) and a transport connection + identifier. These TSAPs are the unknown TSAP, the web's multicast + TSAP and each individual member's TSAP. + +\subsubsection{Unknown transport address} + + Stations that are just joining must use the multicast NSAP associated + with the transport, but are not yet aware of either the web's + multicast TSAP the master process' TSAP\@. Therefore, joining stations + fabricate a temporary TSAP (referred to as a unknown TSAP) by using a + connection identifier reserved to mean unknown (0x00000000). The + join[confirm] message will be sourced from the master's TSAP and will + include the multicast transport connection identifier in the data + field. Those values must be extracted from the join[confirm] and + remembered by the joining process. + +\subsubsection{Web's multicast address} + + The multicast TSAP is formed by logically concatenating the multicast + NSAP associated with the transport creation and the transport + connection identifier returned in the data field of the join[confirm] + packet. If more than one network is involved in the web, then the + multicast transport address becomes a list, one for each network + represented. This list is supplied in the data field of + token[confirm] packets. + + The multicast TSAP is used as the target for all messages that are + destined to the entire web, such as data and empty. The master's + decision to abandon the transport (quit) is also sent to the + multicast transport address. + +\subsubsection{Member addresses} + + The member TSAP is formed by using the process' unicast NSAP + concatenated with a locally generated unique connection identifier. + That TSAP must be the source of every packet transmitted by the + process, regardless of its destination, for the lifetime of the + transport. + + Packets unicast to specific members must contain the appropriate + TSAP\@. For producers and consumers this is not difficult. The only + TSAPs of interest are the master and the station(s) currently + transmitting data. + + + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\begin{thebibliography}{AFM91} +\bibitem[AFM91]{Armstrong91} +S.~Armstrong, A.~Freier, and K.~Marzullo. +\emph{MTP: An atomic multicast transport protocol}. +Xerox Webster Research Center technical report X9100359, +March 1991. + +\bibitem[AFM92]{Armstrong92} +S.~Armstrong, A.~Freier, and K.~Marzullo. +\emph{Multicast transport protocol}. +RFC 1301, Internet Engineering Task Force, February 1992. +Available from \url{http://www.rfc-editor.org/rfc/rfc1301.txt}. +\end{thebibliography} + +\end{document} diff --git a/macros/latex/contrib/bytefield/bytefield.dtx b/macros/latex/contrib/bytefield/bytefield.dtx new file mode 100644 index 0000000000..deb30c81be --- /dev/null +++ b/macros/latex/contrib/bytefield/bytefield.dtx @@ -0,0 +1,3484 @@ +% \iffalse meta-comment +% +% Copyright (C) 2017 by Scott Pakin +% ------------------------------------------------------ +% +% This file may be distributed and/or modified under the +% conditions of the LaTeX Project Public License, either version 1.3a +% of this license or (at your option) any later version. +% The latest version of this license is in: +% +% http://www.latex-project.org/lppl.txt +% +% and version 1.3c or later is part of all distributions of LaTeX +% version 2006/05/20 or later. +% +% \fi +% +% \iffalse +%<*driver> +\ProvidesFile{bytefield.dtx} +% +%\NeedsTeXFormat{LaTeX2e}[1999/12/01] +%\ProvidesPackage{bytefield} +%<*package> + [2017/09/15 v2.4 Network protocol diagrams] +% +% +%<*driver> +\documentclass{ltxdoc} +\usepackage{textcomp} +\usepackage{bytefield} +\usepackage{color} +\usepackage{rotating} +\usepackage{multirow} +\usepackage{calc} +\usepackage{array} +\usepackage{wasysym} +\usepackage{hyperxmp} +\usepackage{hypdoc} +\usepackage{hyperref} +\usepackage[figure]{hypcap} + +\hypersetup{% + pdftitle={The bytefield package}, + pdfauthor={Scott Pakin}, + pdfsubject={Protocol diagrams for LaTeX}, + pdfkeywords={bits, bytes, bit fields, communication, network protocol diagrams, LaTeX2e, memory maps}, + pdfcopyright={Copyright (C) 2017, Scott Pakin}, + pdflicenseurl={http://www.latex-project.org/lppl/}, + pdfcaptionwriter={Scott Pakin}, + pdfcontactemail={scott+bf@pakin.org}, + pdfcontacturl={http://www.pakin.org/\xmptilde scott/}, + pdflang={en-US}, + baseurl={http://mirrors.ctan.org/macros/latex/contrib/bytefield/bytefield.pdf}, + pdfstartview=Fit, + colorlinks=false, + bookmarksopen=true} +\EnableCrossrefs +\CodelineIndex +\RecordChanges +\setcounter{IndexColumns}{2} +\begin{document} + \DocInput{bytefield.dtx} + \PrintChanges + \PrintIndex +\end{document} +% +% \fi +% +% \CheckSum{1028} +% +% \CharacterTable +% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z +% Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z +% Digits \0\1\2\3\4\5\6\7\8\9 +% Exclamation \! Double quote \" Hash (number) \# +% Dollar \$ Percent \% Ampersand \& +% Acute accent \' Left paren \( Right paren \) +% Asterisk \* Plus \+ Comma \, +% Minus \- Point \. Solidus \/ +% Colon \: Semicolon \; Less than \< +% Equals \= Greater than \> Question mark \? +% Commercial at \@ Left bracket \[ Backslash \\ +% Right bracket \] Circumflex \^ Underscore \_ +% Grave accent \` Left brace \{ Vertical bar \| +% Right brace \} Tilde \~} +% +% +% \changes{v1.0}{2000/07/02}{Initial version} +% \changes{v1.1}{2002/09/14}{Restructured the \texttt{.dtx} file} +% \changes{v1.4}{2011/01/09}{Made assignments to \cs{counting@words} +% global to prevent vertical-spacing problems with back-to-back word +% groups (bug fix due to Steven R. King)} +% \changes{v1.4}{2011/01/16}{Split \cs{curlyspace}, \cs{labelspace}, and +% \cs{curlyshrinkage} into \texttt{left} and \texttt{right} versions} +% \changes{v2.0}{2011/01/18}{Made a number of non-backwards-compatible +% changes, including replacing \cs{wordgroupr} and \cs{endwordgroupr} +% with a \texttt{rightwordgroup} environment and \cs{wordgroupl} and +% \cs{endwordgroupl} with a \texttt{leftwordgroup} environment and +% also replacing a slew of user-visible lengths and macros with a +% single \cs{bytefieldsetup} macro} +% +% \GetFileInfo{bytefield.dtx} +% +% \DoNotIndex{\&,\{,\}} +% \DoNotIndex{\addtocounter,\advance} +% \DoNotIndex{\begin,\begingroup,\bgroup} +% \DoNotIndex{\catcode,\ch@ck,\count,\cr,\csname} +% \DoNotIndex{\DeclareRobustCommand,\def,\dimen,\dimendef} +% \DoNotIndex{\edef,\egroup,\else,\end,\endcsname,\endgroup,\expandafter} +% \DoNotIndex{\fi} +% \DoNotIndex{\gdef,\global} +% \DoNotIndex{\hspace} +% \DoNotIndex{\if,\ifnum,\ifx,\ignorespaces,\insc@unt} +% \DoNotIndex{\left,\let,\loop} +% \DoNotIndex{\MessageBreak} +% \DoNotIndex{\newbox,\newcommand,\newcounter,\newenvironment,\newif,\next} +% \DoNotIndex{\newlength,\newsavebox,\noexpand} +% \DoNotIndex{\raisebox,\ratio,\real,\relax,\renewcommand,\right} +% \DoNotIndex{\par,\protect} +% \DoNotIndex{\renewenvironment,\repeat} +% \DoNotIndex{\sbox,\setcounter,\setlength,\settowidth,\space,\string} +% \DoNotIndex{\the} +% \DoNotIndex{\unskip,\usebox,\usepackage} +% \DoNotIndex{\value,\vbox,\vspace} +% \DoNotIndex{\wlog} +% \DoNotIndex{\xdef} +% +% +% \title{The \textsf{bytefield} package\thanks{This document +% corresponds to \textsf{bytefield}~\fileversion, dated \filedate.}} +% \author{Scott Pakin \\ \texttt{scott+bf@pakin.org}} +% +% \sloppy +% \maketitle +% +% ^^A Define an environment for command/environment delcarations. +% \newsavebox{\declbox} +% \newenvironment{decl}{^^A +% \begin{lrbox}{\declbox}\begin{tabular}{l}}{^^A +% \end{tabular}\end{lrbox}^^A +% \vspace{3ex}\noindent\hspace*{-3em}\fbox{\usebox{\declbox}}\vspace*{2ex}} +% +% ^^A Define an ellipsis that permits a subsequent line break. +% \newcommand{\ellipsis}{$\ldots$\linebreak[0]} +% +% ^^A Define an environment for showing sample bytefield diagrams. +% \newenvironment{bffigure}{% +% \bigskip +% \noindent\hspace*{3em}% +% }{% +% \bigskip +% } +% +% ^^A Define something like \cs to use within \StopEventually. +% \DeclareRobustCommand{\cseq}[1]{\texttt{\string#1}} +% +% ^^A Index a package. This code was adapted from \SpecialEnvIndex. +% \makeatletter +% \def\SpecialPkgIndex#1{^^A +% \@bsphack +% \index{#1\actualchar{\protect\sffamily#1} (package)\encapchar usage}^^A +% \index{packages:\levelchar#1\actualchar{\protect\sffamily#1}^^A +% \encapchar usage}^^A +% \@esphack +% } +% +% ^^A The following was adapted from hypdoc's redefinition of \SpecialEnvIndex. +% \expandafter\ifx\csname c@HD@hypercount\endcsname\relax +% \else +% \let\HDorg@SpecialPkgIndex\SpecialPkgIndex +% \renewcommand*\SpecialPkgIndex[1]{^^A +% \@bsphack +% \begingroup +% \HD@target +% \let\HDorg@encapchar\encapchar +% \edef\encapchar usage{^^A +% \HDorg@encapchar hdpindex{usage}^^A +% }^^A +% \HDorg@SpecialPkgIndex{#1}^^A +% \endgroup +% \@esphack +% } +% \fi +% \makeatother +% +% ^^A Define a logical style for package names. +% \DeclareRobustCommand{\pkgname}[1]{^^A +% \textsf{#1}^^A +% \SpecialPkgIndex{#1}^^A +% } +% +% +% ^^A Index an option. This code was adapted from \SpecialEnvIndex. +% \makeatletter +% \def\SpecialOptionIndex#1{^^A +% \@bsphack +% \index{#1\actualchar{\protect\sffamily#1} (option)\encapchar usage}^^A +% \index{options:\levelchar#1\actualchar{\protect\sffamily#1}^^A +% \encapchar usage}^^A +% \@esphack +% } +% +% ^^A The following was adapted from hypdoc's redefinition of \SpecialEnvIndex. +% \expandafter\ifx\csname c@HD@hypercount\endcsname\relax +% \else +% \let\HDorg@SpecialOptionIndex\SpecialOptionIndex +% \renewcommand*\SpecialOptionIndex[1]{^^A +% \@bsphack +% \begingroup +% \HD@target +% \let\HDorg@encapchar\encapchar +% \edef\encapchar usage{^^A +% \HDorg@encapchar hdpindex{usage}^^A +% }^^A +% \HDorg@SpecialOptionIndex{#1}^^A +% \endgroup +% \@esphack +% } +% \fi +% \makeatother +% +% ^^A Define a logical style for package-option names. +% \DeclareRobustCommand{\optname}[1]{^^A +% \texttt{#1}^^A +% \SpecialOptionIndex{#1}^^A +% } +% +% ^^A We use this box to help center protocol diagrams. +% \newsavebox{\protocoldiagram} +% +% +% \begin{abstract} +% The \pkgname{bytefield} package helps the user create illustrations for +% network protocol specifications and anything else that utilizes fields of +% data. These illustrations show how the bits and bytes are laid out in a +% packet or in memory. +% \end{abstract} +% +% +% \vspace{\baselineskip} +% \begin{center} +% \fbox{% +% \begin{minipage}{0.65\linewidth} +% \textsc{Warning}: \pkgname{bytefield} version~2.\textit{x} breaks +% compatibility with older versions of the package. See +% Section~\ref{sec:upgrading} for help porting documents to the new +% interface. +% \end{minipage}% +% } +% \end{center} +% \vspace{\baselineskip} +% +% +% \section{Introduction} +% +% Network protocols are usually specified in terms of a sequence of bits +% and bytes arranged in a field. This is portrayed graphically as a +% grid of boxes. Each row in the grid represents one word (frequently, +% 8, 16, or 32~bits), and each column represents a bit within a word. +% The \pkgname{bytefield} package makes it easy to typeset these sorts +% of figures. \pkgname{bytefield} facilitates drawing protocol diagrams +% that contain +% +% \begin{itemize} +% \item words of any arbitrary number of bits, +% \item column headers showing bit positions, +% \item multiword fields---even non-word-aligned and even if the total +% number of bits is not a multiple of the word length, +% \item word labels on either the left or right of the figure, and +% \item ``skipped words'' within fields. +% \end{itemize} +% +% Because \pkgname{bytefield} draws its figures using only +% the \LaTeX{} \texttt{picture} environment, these figures are not +% specific to any particular backend, do not require PostScript support, +% and do not need support from external programs. Furthermore, unlike an +% imported graphic, \pkgname{bytefield} pictures can include arbitrary +% \LaTeX{} constructs, such as mathematical equations, |\ref|s and +% |\cite|s to the surrounding document, and macro calls. +% +% +% \section{Usage} +% \label{sec:usage} +% +% \subsection{A first example} +% \label{sec:first-example} +% +% The Internet Engineering Task Force's Request for Comments (RFC) +% number~3016 includes the following ASCII-graphics illustration of +% the RTP packetization of an \mbox{MPEG-4} Visual bitstream: +% +% \begin{verbatim} +% 0 1 2 3 +% 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +% +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +% |V=2|P|X| CC |M| PT | sequence number | RTP +% +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +% | timestamp | Header +% +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +% | synchronization source (SSRC) identifier | +% +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ +% | contributing source (CSRC) identifiers | +% | .... | +% +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ +% | | RTP +% | MPEG-4 Visual stream (byte aligned) | Pay- +% | | load +% | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +% | :...OPTIONAL RTP padding | +% +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +% \end{verbatim} +% +% \noindent +% The following \LaTeX\ code shows how straightforward it is to typeset +% that illustration using the \pkgname{bytefield} package: +% +% \begin{verbatim} +% \begin{bytefield}[bitwidth=1.1em]{32} +% \bitheader{0-31} \\ +% \begin{rightwordgroup}{RTP \\ Header} +% \bitbox{2}{V=2} & \bitbox{1}{P} & \bitbox{1}{X} +% & \bitbox{4}{CC} & \bitbox{1}{M} & \bitbox{7}{PT} +% & \bitbox{16}{sequence number} \\ +% \bitbox{32}{timestamp} +% \end{rightwordgroup} \\ +% \bitbox{32}{synchronization source (SSRC) identifier} \\ +% \wordbox[tlr]{1}{contributing source (CSRC) identifiers} \\ +% \wordbox[blr]{1}{$\cdots$} \\ +% \begin{rightwordgroup}{RTP \\ Payload} +% \wordbox[tlr]{3}{MPEG-4 Visual stream (byte aligned)} \\ +% \bitbox[blr]{16}{} +% & \bitbox{16}{\dots\emph{optional} RTP padding} +% \end{rightwordgroup} +% \end{bytefield} +% \end{verbatim} +% +% Figure~\ref{fig:rtp-mpeg4} presents the typeset output of the +% preceding code. Sections~\ref{sec:basic-cmds} and~\ref{sec:options} +% explain each of the environments, macros, and arguments that were +% utilized plus many additional features of the \pkgname{bytefield} +% package. +% +% \begin{figure}[hbp] +% \centering +% \begin{lrbox}{\protocoldiagram} +% \begin{bytefield}[bitwidth=1.1em]{32} +% \bitheader{0-31} \\ +% \begin{rightwordgroup}{RTP \\ Header} +% \bitbox{2}{V=2} & \bitbox{1}{P} & \bitbox{1}{X} +% & \bitbox{4}{CC} & \bitbox{1}{M} & \bitbox{7}{PT} +% & \bitbox{16}{sequence number} \\ +% \bitbox{32}{timestamp} +% \end{rightwordgroup} \\ +% \bitbox{32}{synchronization source (SSRC) identifier} \\ +% \wordbox[tlr]{1}{contributing source (CSRC) identifiers} \\ +% \wordbox[blr]{1}{$\cdots$} \\ +% \begin{rightwordgroup}{RTP \\ Payload} +% \wordbox[tlr]{3}{MPEG-4 Visual stream (byte aligned)} \\ +% \bitbox[blr]{16}{} +% & \bitbox{16}{\dots\emph{optional} RTP padding} +% \end{rightwordgroup} +% \end{bytefield} +% \end{lrbox} +% \makebox[0pt][c]{\usebox{\protocoldiagram}} +% \caption{Sample \pkgname{bytefield} output} +% \label{fig:rtp-mpeg4} +% \end{figure} +% +% +% \subsection{Basic commands} +% \label{sec:basic-cmds} +% +% This section explains how to use the \pkgname{bytefield} package. It +% lists all the exported macros and environments in approximately +% decreasing order of usefulness. +% +% \begin{decl} +% \SpecialEnvIndex{bytefield} +% |\begin{bytefield}| \oarg{parameters} \marg{bit-width} \\ +% \meta{fields} \\ +% |\end{bytefield}| +% \end{decl} +% +% The \pkgname{bytefield} package's top-level environment is called, not +% surprisingly, ``|bytefield|''. It takes one mandatory argument, which +% is the number of bits in each word, and one optional argument, which +% is a set of parameters, described in Section~\ref{sec:options}, for +% formatting the bit-field's layout. One can think of a |bytefield| as +% being analogous to a |tabular|: words are separated by~``|\\|'', and +% fields within a word are separated by~``|&|''. As in a |tabular|, +% ``|\\|'' accepts a \meta{length} as an optional argument, and this +% specifies the amount of additional vertical whitespace to include +% after the current word is typeset. +% +% \begin{decl} +% \SpecialUsageIndex{\bitbox} +% |\bitbox| \oarg{sides} \marg{width} \marg{text} \\ +% \SpecialUsageIndex{\wordbox} +% |\wordbox| \oarg{sides} \marg{height} \marg{text} +% \end{decl} +% +% The two main commands one uses within a \pkgname{bytefield} +% environment are |\bitbox| and |\wordbox|. The former typesets a field +% that is one or more bits wide and a single word tall. The latter +% typesets a field that is an entire word wide and one or more words +% tall. +% +% The optional argument, \meta{sides}, is a list of letters specifying +% which sides of the field box to draw---[|l|]eft, [|r|]ight, [|t|]op, +% and/or [|b|]ottom.\footnote{Uppercase |L|, |R|, |T|, and |B| undo a +% prior |l|, |r|, |t|, or |b| and may be useful for writing wrapper +% commands around \texttt{\string\bitbox} and +% \texttt{\string\wordbox}.} The default is ``|lrtb|'' (i.e.,~all +% sides are drawn). \meta{text} is the text to include within the +% |\bitbox| or |\wordbox|. It is typeset horizontally centered within a +% vertically centered |\parbox|. Hence, words will wrap, and ``|\\|'' +% can be used to break lines manually. +% +% The following example shows how to produce a simple 16-bit-wide field: +% +% \begin{verbatim} +% \begin{bytefield}{16} +% \wordbox{1}{A 16-bit field} \\ +% \bitbox{8}{8 bits} & \bitbox{8}{8 more bits} \\ +% \wordbox{2}{A 32-bit field. Note that text wraps within the box.} +% \end{bytefield} +% \end{verbatim} +% +% The resulting bit field looks like this: +% +% \begin{bffigure} +% \begin{bytefield}{16} +% \wordbox{1}{A 16-bit field} \\ +% \bitbox{8}{8 bits} & \bitbox{8}{8 more bits} \\ +% \wordbox{2}{A 32-bit field. Note that text wraps within the box.} +% \end{bytefield} +% \end{bffigure} +% +% It is the user's responsibility to ensure that the total number of +% bits in each row adds up to the number of bits in a single word (the +% mandatory argument to the |bytefield| environment); +% \pkgname{bytefield} does not currently check for under- or overruns. +% +% Within a |\bitbox| or |\wordbox|, the \pkgname{bytefield} package +% defines |\height|, |\depth|, |\totalheight|, and |\width| to the +% corresponding dimensions of the box. Section~\ref{sec:tricks} gives an +% example of how these lengths may be utilized. +% +% \begin{decl} +% \SpecialUsageIndex{\bitboxes} +% |\bitboxes| \oarg{sides} \marg{width} \marg{tokens} \\ +% |\bitboxes*| \oarg{sides} \marg{width} \marg{tokens} \\ +% \end{decl} +% +% The |\bitboxes| command provides a shortcut for typesetting a sequence +% of fields of the same width. It takes essentially the same arguments +% as |\bitbox| but interpets these differently. Instead of representing +% a single piece of text to typeset within a field of width +% \meta{width}, |\bitboxes|'s \meta{tokens} argument represents a list +% of tokens (e.g,~individual characters), each of which is typeset +% within a separate box of width \meta{width}. Consider, for example, +% the following sequence of |\bitbox| commands: +% +% \begin{verbatim} +% \begin{bytefield}{8} +% \bitbox{1}{D} & \bitbox{1}{R} & \bitbox{1}{M} & \bitbox{1}{F} & +% \bitbox{1}{S} & \bitbox{1}{L} & \bitbox{1}{T} & \bitbox{1}{D} +% \end{bytefield} +% \end{verbatim} +% +% \begin{bffigure} +% \begin{bytefield}{8} +% \bitbox{1}{D} & \bitbox{1}{R} & \bitbox{1}{M} & \bitbox{1}{F} & +% \bitbox{1}{S} & \bitbox{1}{L} & \bitbox{1}{T} & \bitbox{1}{D} +% \end{bytefield} +% \end{bffigure} +% +% \noindent +% With |\bitboxes| this can be abbreviated to +% +% \begin{verbatim} +% \begin{bytefield}{8} +% \bitboxes{1}{DRMFSLTD} +% \end{bytefield} +% \end{verbatim} +% +% Spaces are ignored within |\bitboxes|'s \meta{text} argument, and +% curly braces can be used to group multiple characters into a single +% token: +% +% \begin{verbatim} +% \begin{bytefield}{24} +% \bitboxes{3}{{DO} {RE} {MI} {FA} {SOL} {LA} {TI} {DO}} +% \end{bytefield} +% \end{verbatim} +% +% \begin{bffigure} +% \begin{bytefield}{24} +% \bitboxes{3}{{DO} {RE} {MI} {FA} {SOL} {LA} {TI} {DO}} +% \end{bytefield} +% \end{bffigure} +% +% The starred form of |\bitboxes| is identical except that it suppresses +% all internal vertical lines. It can therefore be quite convenient for +% typesetting binary constants: +% +% \begin{verbatim} +% \begin{bytefield}{16} +% \bitboxes*{1}{01000010} & \bitbox{4}{src\strut} & +% \bitbox{4}{dest\strut} & \bitbox{4}{const\strut} +% \end{bytefield} +% \end{verbatim} +% +% \begin{bffigure} +% \begin{bytefield}{16} +% \bitboxes*{1}{01000010} & \bitbox{4}{src\strut} & +% \bitbox{4}{dest\strut} & \bitbox{4}{const\strut} +% \end{bytefield} +% \end{bffigure} +% +% \begin{decl} +% \SpecialUsageIndex{\bitheader} +% |\bitheader| \oarg{parameters} \marg{bit-positions} +% \end{decl} +% +% To make the bit field more readable, it helps to label bit positions +% across the top. The |\bitheader| command provides a flexible way to +% do that. The optional argument is a set of parameters from the set +% described in Section~\ref{sec:options}. In practice, the only +% parameters that are meaningful in the context of |\bitheader| are +% |bitformatting|, |endianness|, and |lsb|. See +% Section~\ref{sec:options} for descriptions and examples of those +% parameters. +% +% |\bitheader|'s mandatory argument, \meta{bit-positions}, is a +% comma-separated list of bit positions to label. For example, +% ``|0,2,4,6,8,10,12,14|'' means to label those bit positions. The +% numbers must be listed in increasing order. (Use the +% \optname{endianness} parameter to display the header in reverse +% order.) Hyphen-separated ranges are also valid. For example, +% ``|0-15|'' means to label all bits from~0 to~15, inclusive. Ranges +% and single numbers can even be intermixed, as in ``|0-3,8,12-15|''. +% +% The following example shows how |\bitheader| may be used: +% +% \begin{verbatim} +% \begin{bytefield}{32} +% \bitheader{0-31} \\ +% \bitbox{4}{Four} & \bitbox{8}{Eight} & +% \bitbox{16}{Sixteen} & \bitbox{4}{Four} +% \end{bytefield} +% \end{verbatim} +% +% The resulting bit field looks like this: +% +% \begin{bffigure} +% \begin{bytefield}{32} +% \bitheader{0-31} \\ +% \bitbox{4}{Four} & \bitbox{8}{Eight} & +% \bitbox{16}{Sixteen} & \bitbox{4}{Four} +% \end{bytefield} +% \end{bffigure} +% +% +% \begin{decl} +% \SpecialEnvIndex{rightwordgroup} +% |\begin{rightwordgroup}| \marg{text} \\ +% \meta{rows of bit boxes and word boxes} \\ +% |\end{rightwordgroup}| \\ +% \\ +% \SpecialEnvIndex{leftwordgroup} +% |\begin{leftwordgroup}| \marg{text} \\ +% \meta{rows of bit boxes and word boxes} \\ +% |\end{leftwordgroup}| +% \end{decl} +% +% When a set of words functions as a single, logical unit, it helps to +% group these words together visually. All words defined between +% |\begin{rightwordgroup}| and |\end{rightwordgroup}| will be labeled on +% the right with \meta{text}. Similarly, all words defined between +% |\begin{leftwordgroup}| and |\end{leftwordgroup}| will be labeled on +% the left with \meta{text}. |\begin{|\meta{side}|wordgroup}| must lie +% at the beginning of a row (i.e.,~right after a ``|\\|''), and +% |\end{|\meta{side}|wordgroup}| must lie right \emph{before} the end of +% the row (i.e.,~right before a ``|\\|''). +% +% Unlike other \LaTeX\ environments, |rightwordgroup| and +% |leftwordgroup| do not have to nest properly with each other. +% However, they cannot overlap themselves. In other words, +% |\begin{rightwordgroup}|\ellipsis |\begin{leftwordgroup}|\ellipsis +% |\end{rightwordgroup}|\ellipsis |\end{leftwordgroup}| is a valid +% sequence, but |\begin{rightwordgroup}|\ellipsis +% |\begin{rightwordgroup}|\ellipsis |\end{rightwordgroup}|\ellipsis +% |\end{rightwordgroup}| is not. +% +% The following example presents the basic usage of +% |\begin{rightwordgroup}| and |\end{rightwordgroup}|: +% +% \begin{verbatim} +% \begin{bytefield}{16} +% \bitheader{0,7,8,15} \\ +% \begin{rightwordgroup}{Header} +% \bitbox{4}{Tag} & \bitbox{12}{Mask} \\ +% \bitbox{8}{Source} & \bitbox{8}{Destination} +% \end{rightwordgroup} \\ +% \wordbox{3}{Data} +% \end{bytefield} +% \end{verbatim} +% +% \noindent +% Note the juxtaposition of ``|\\|'' to the |\begin{rightwordgroup}| and +% the |\end{rightwordgroup}| in the above. The resulting bit field +% looks like this: +% +% \begin{bffigure} +% \begin{bytefield}{16} +% \bitheader{0,7,8,15} \\ +% \begin{rightwordgroup}{Header} +% \bitbox{4}{Tag} & \bitbox{12}{Mask} \\ +% \bitbox{8}{Source} & \bitbox{8}{Destination} +% \end{rightwordgroup} \\ +% \wordbox{3}{Data} +% \end{bytefield} +% \end{bffigure} +% +% \noindent +% As a more complex example, the following nests left and right labels: +% +% \begin{verbatim} +% \begin{bytefield}{16} +% \bitheader{0,7,8,15} \\ +% \begin{rightwordgroup}{Header} +% \bitbox{4}{Tag} & \bitbox{12}{Mask} \\ +% \begin{leftwordgroup}{Node IDs} +% \bitbox{8}{Source} & \bitbox{8}{Destination} +% \end{leftwordgroup} +% \end{rightwordgroup} \\ +% \wordbox{3}{Data} +% \end{bytefield} +% \end{verbatim} +% +% \begin{bffigure} +% \begin{bytefield}{16} +% \bitheader{0,7,8,15} \\ +% \begin{rightwordgroup}{Header} +% \bitbox{4}{Tag} & \bitbox{12}{Mask} \\ +% \begin{leftwordgroup}{Node IDs} +% \bitbox{8}{Source} & \bitbox{8}{Destination} +% \end{leftwordgroup} +% \end{rightwordgroup} \\ +% \wordbox{3}{Data} +% \end{bytefield} +% \end{bffigure} +% +% \noindent +% Because |rightwordgroup| and |leftwordgroup| are not required to nest +% properly, the resulting bit field would look the same if the +% |\end{leftwordgroup}| and |\end{rightwordgroup}| were swapped. Again, +% note the justaposition of ``|\\|'' to the various word-grouping +% commands in the above. +% +% \begin{decl} +% \SpecialUsageIndex{\skippedwords} +% |\skippedwords| +% \end{decl} +% +% Draw a graphic representing a number of words that are not shown. +% |\skippedwords| is intended to work with the \meta{sides} argument +% to |\wordbox|, as in the following example: +% +% \begin{verbatim} +% \begin{bytefield}{16} +% \wordbox{1}{Some data} \\ +% \wordbox[lrt]{1}{Lots of data} \\ +% \skippedwords \\ +% \wordbox[lrb]{1}{} \\ +% \wordbox{2}{More data} +% \end{bytefield} +% \end{verbatim} +% +% \begin{bffigure} +% \begin{bytefield}{16} +% \wordbox{1}{Some data} \\ +% \wordbox[lrt]{1}{Lots of data} \\ +% \skippedwords \\ +% \wordbox[lrb]{1}{} \\ +% \wordbox{2}{More data} +% \end{bytefield} +% \end{bffigure} +% +% \begin{decl} +% \SpecialUsageIndex{\bytefieldsetup} +% |\bytefieldsetup| \marg{key-value list} +% \end{decl} +% +% Alter the formatting of all subsequent bit fields. +% Section~\ref{sec:options} describes the possible values for each +% \meta{key}=\meta{value} item in the comma-separated list that +% |\bytefieldsetup| accepts as its argument. Note that changes made +% with |\bytefieldsetup| are local to their current scope. Hence, if +% used within an environment (e.g.,~|figure|), |\bytefieldsetup| does +% not impact bit fields drawn outside that environment. +% +% +% \subsection{Formatting options} +% \label{sec:options} +% +% A document author can customize many of the \pkgname{bytefield} +% package's figure-formatting parameters, either globally or on a +% per-figure basis. The parameters described below can be specified in +% four locations: +% +% \begin{itemize} +% \item as package options (i.e.,~in the +% |\usepackage|\oarg{options}|{bytefield}| line), which affects all +% |bytefield| environments in the entire document, +% +% \item anywhere in the document using the |\bytefieldsetup| command, +% which affects all subsequent |bytefield| environments in the +% current scope, +% +% \item as the optional argument to a |\begin{bytefield}|, which +% affects only that single bit-field figure, or +% +% \item as the optional argument to a |\bitheader|, which affects only +% that particular header. (Only a few parameters are meaningful in +% this context.) +% \end{itemize} +% +% Unfortunately, \LaTeX\ tends to abort with a ``\texttt{TeX capacity +% exceeded}'' or ``\texttt{Missing \cs{endcsname} inserted}'' error +% when a control sequence (i.e.,~|\|\meta{name}) or |\|\meta{symbol}) is +% encountered within the optional argument to |\usepackage|. Hence, +% parameters that typically expect a control sequence in their +% argument---in particular, \optname{bitformatting}, +% \optname{boxformatting}, \optname{leftcurly}, and +% \optname{rightcurly}---should best be avoided within the +% |\usepackage|\oarg{options}|{bytefield}| line. +% +% \begin{decl} +% \optname{bitwidth} = \meta{length} \\ +% \optname{bitheight} = \meta{length} +% \end{decl} +% +% The above parameters represent the width and height of each bit in a +% bit field. The default value of \optname{bitwidth} is the width of +% ``|{\tiny 99i}|'', i.e.,~the width of a two-digit number plus a small +% amount of extra space. This enables |\bitheader| to show two-digit +% numbers without overlap. The default value of \optname{bitheight} +% is~|2ex|, which should allow a normal piece of text to appear within a +% |\bitbox| or |\wordbox| without abutting the box's top or bottom edge. +% +% As a special case, if \optname{bitwidth} is set to the word +% ``|auto|'', it will be set to the width of ``|99i|'' in the current +% bit-number formatting (cf.~\optname{bitformatting} below). This +% feature provides a convenient way to adjust the bit width after a +% formatting change. +% +% \begin{decl} +% \optname{endianness} = |little| \emph{or} |big| +% \end{decl} +% +% Specify either little-endian (left-to-right) or big-endian +% (right-to-left) ordering of the bit numbers. The default is +% little-endian numbering. Contrast the following two examples. The +% first formats a bit field in little-endian ordering using an explicit +% |endianness=little|, and the second formats the same bit field in +% big-endian ordering using |endianness=big|. +% +% \begin{verbatim} +% \begin{bytefield}[endianness=little,bitwidth=0.11111\linewidth]{8} +% \bitheader{0-7} \\ +% \bitbox{1}{Res} & \bitbox{1}{BE} & \bitbox{1}{CF} +% & \bitbox{3}{$\mbox{Name\_Len}-1$} & \bitbox{2}{Len\_Len} \\ +% \end{bytefield} +% \end{verbatim} +% +% \begin{bffigure} +% \begin{bytefield}[endianness=little,bitwidth=0.11111\linewidth]{8} +% \bitheader{0-7} \\ +% \bitbox{1}{Res} & \bitbox{1}{BE} & \bitbox{1}{CF} +% & \bitbox{3}{$\mbox{Name\_Len}-1$} & \bitbox{2}{Len\_Len} \\ +% \end{bytefield} +% \end{bffigure} +% +% \begin{verbatim} +% \begin{bytefield}[endianness=big,bitwidth=0.11111\linewidth]{8} +% \bitheader{0-7} \\ +% \bitbox{2}{Len\_Len} & \bitbox{3}{$\mbox{Name\_Len}-1$} +% & \bitbox{1}{CF} & \bitbox{1}{BE} & \bitbox{1}{Res} \\ +% \end{bytefield} +% \end{verbatim} +% +% \begin{bffigure} +% \begin{bytefield}[endianness=big,bitwidth=0.11111\linewidth]{8} +% \bitheader{0-7} \\ +% \bitbox{2}{Len\_Len} & \bitbox{3}{$\mbox{Name\_Len}-1$} +% & \bitbox{1}{CF} & \bitbox{1}{BE} & \bitbox{1}{Res} \\ +% \end{bytefield} +% \end{bffigure} +% +% \begin{decl} +% \optname{bitformatting} = \meta{command} \emph{or} \marg{commands} +% \end{decl} +% +% The numbers that appear in a bit header are typeset in the +% \optname{bitformatting} style, which defaults to |\tiny|. To alter +% the style of bit numbers in the bit header, set +% \optname{bitformatting} to a macro that takes a single argument (like +% |\textbf|) or no arguments (like |\small|). Groups of commands +% (e.g.,~|{\large\itshape}|) are also acceptable. +% +% When \optname{bitformatting} is set, \optname{bitwidth} usually needs +% to be recalculated as well to ensure that a correct amount of spacing +% surrounds each number in the bit header. As described above, setting +% |bitwidth=auto| is a convenient shortcut for recalculating the +% bit-width in the common case of bit fields containing no more than 99 +% bits per line and no particularly wide labels in bit boxes that +% contain only a few bits. +% +% The following example shows how to use \optname{bitformatting} and +% \optname{bitwidth} to format a bit header with small, boldface text: +% +% \begin{verbatim} +% \begin{bytefield}[bitformatting={\small\bfseries}, +% bitwidth=auto, +% endianness=big]{20} +% \bitheader{0-19} \\ +% \bitbox{1}{\tiny F/E} & \bitbox{1}{\tiny T0} & \bitbox{1}{\tiny T1} +% & \bitbox{1}{\tiny Fwd} & \bitbox{16}{Data value} \\ +% \end{bytefield} +% \end{verbatim} +% +% \noindent +% The resulting bit field looks like this: +% +% \begin{bffigure} +% \begin{bytefield}[bitformatting={\small\bfseries}, +% bitwidth=auto, +% endianness=big]{20} +% \bitheader{0-19} \\ +% \bitbox{1}{\tiny F/E} & \bitbox{1}{\tiny T0} & \bitbox{1}{\tiny T1} +% & \bitbox{1}{\tiny Fwd} & \bitbox{16}{Data value} \\ +% \end{bytefield} +% \end{bffigure} +% +% \begin{decl} +% \optname{boxformatting} = \meta{command} \emph{or} \marg{commands} +% \end{decl} +% +% The text that appears in a |\bitbox| or |\wordbox| is formatted in the +% \optname{boxformatting} style, which defaults to |\centering|. To +% alter the style of bit numbers in the bit header, set +% \optname{boxformatting} to a macro that takes a single argument (like +% |\textbf| but not |\textbf|---see below) or no arguments (like +% |\small|). Groups of commands (e.g.,~|{\large\itshape}|) are also +% acceptable. +% +% If \optname{boxformatting} is set to a macro that takes an argument, +% the macro must be defined as a ``long'' macro, which means it can +% accept more than one paragraph as an argument. Commands defined with +% |\newcommand| are automatically made long, but commands defined with +% |\newcommand*| are not. \LaTeX's |\text|\dots\ formatting commands +% (e.g.,~|\textbf|) are not long and therefore cannot be used directly +% in \optname{boxformatting}; use the zero-argument versions +% (e.g.,~|\bfseries|) instead. +% +% The following example shows how to use \optname{boxformatting} to +% format the text within each box horizontally centered and italicized: +% +% \begin{verbatim} +% \begin{bytefield}[boxformatting={\centering\itshape}, +% bitwidth=1.5em, +% endianness=big]{20} +% \bitheader{0-19} \\ +% \bitbox{1}{\tiny F/E} & \bitbox{1}{\tiny T0} & \bitbox{1}{\tiny T1} +% & \bitbox{1}{\tiny Fwd} & \bitbox{16}{Data value} \\ +% \end{bytefield} +% \end{verbatim} +% +% \noindent +% The resulting bit field looks like this: +% +% \begin{bffigure} +% \begin{bytefield}[boxformatting={\centering\itshape}, +% bitwidth=1.5em, +% endianness=big]{20} +% \bitheader{0-19} \\ +% \bitbox{1}{\tiny F/E} & \bitbox{1}{\tiny T0} & \bitbox{1}{\tiny T1} +% & \bitbox{1}{\tiny Fwd} & \bitbox{16}{Data value} \\ +% \end{bytefield} +% \end{bffigure} +% +% \begin{decl} +% \optname{leftcurly} = \meta{delimiter} \\ +% \optname{rightcurly} = \meta{delimiter} +% \end{decl} +% +% Word groups are normally indicated by a curly brace spanning all of +% its rows. However, the curly brace can be replaced by any other +% extensible math delimiter (i.e.,~a symbol that can meaningfully follow +% |\left| or |\right| in math mode) via a suitable redefinition of +% \optname{leftcurly} or \optname{rightcurly}. As in math mode, ``|.|'' +% means ``no symbol'', as in the following example (courtesy of +% Steven~R. King): +% +% \begin{verbatim} +% \begin{bytefield}[rightcurly=., rightcurlyspace=0pt]{32} +% \bitheader[endianness=big]{0,7,8,15,16,23,24,31} \\ +% \begin{rightwordgroup}{0Ch} +% \bitbox{8}{Byte 15 \\ \tiny (highest address)} +% & \bitbox{8}{Byte 14} +% & \bitbox{8}{Byte 13} +% & \bitbox{8}{Byte 12} +% \end{rightwordgroup} \\ +% \begin{rightwordgroup}{08h} +% \bitbox{32}{Long 0} +% \end{rightwordgroup} \\ +% \begin{rightwordgroup}{04h} +% \bitbox{16}{Word 1} & \bitbox{16}{Word 0} +% \end{rightwordgroup} \\ +% \begin{rightwordgroup}{00h} +% \bitbox{8}{Byte 3} +% & \bitbox{8}{Byte 2} +% & \bitbox{8}{Byte 1} +% & \bitbox{8}{Byte 0 \\ \tiny (lowest address)} +% \end{rightwordgroup} +% \end{bytefield} +% \end{verbatim} +% +% \begin{bffigure} +% \begin{bytefield}[rightcurly=., rightcurlyspace=0pt]{32} +% \bitheader[endianness=big]{0,7,8,15,16,23,24,31} \\ +% \begin{rightwordgroup}{0Ch} +% \bitbox{8}{Byte 15 \\ \tiny (highest address)} +% & \bitbox{8}{Byte 14} +% & \bitbox{8}{Byte 13} +% & \bitbox{8}{Byte 12} +% \end{rightwordgroup} \\ +% \begin{rightwordgroup}{08h} +% \bitbox{32}{Long 0} +% \end{rightwordgroup} \\ +% \begin{rightwordgroup}{04h} +% \bitbox{16}{Word 1} & \bitbox{16}{Word 0} +% \end{rightwordgroup} \\ +% \begin{rightwordgroup}{00h} +% \bitbox{8}{Byte 3} +% & \bitbox{8}{Byte 2} +% & \bitbox{8}{Byte 1} +% & \bitbox{8}{Byte 0 \\ \tiny (lowest address)} +% \end{rightwordgroup} +% \end{bytefield} +% \end{bffigure} +% +% \begin{decl} +% \optname{leftcurlyspace} = \meta{length} \\ +% \optname{rightcurlyspace} = \meta{length} \\ +% \optname{curlyspace} = \meta{length} +% \end{decl} +% +% \optname{leftcurlyspace} and \optname{rightcurlyspace} specify the +% space to insert between the bit field and the curly brace in a left or +% right word group (default:~|1ex|). Setting \optname{curlyspace} is a +% shortcut for setting both \optname{leftcurlyspace} and +% \optname{rightcurlyspace} to the same value. +% +% \begin{decl} +% |leftlabelspace| = \meta{length} \\ +% |rightlabelspace| = \meta{length} \\ +% |labelspace| = \meta{length} +% \end{decl} +% +% |leftlabelspace| and |rightlabelspace| specify the space to insert +% between the curly brace and the text label in a left or right word +% group (default:~|0.5ex|). Setting |labelspace| is a shortcut for +% setting both |leftlabelbrace| and |rightlabelspace| to the same value. +% +% \bigskip +% +% Figure~\ref{fig:rightspace} illustrates the juxtaposition of +% \optname{rightcurlyspace} and |rightlabelspace| to a word group and +% its label. The \optname{leftcurlyspace} and |leftlabelspace| +% parameters are symmetric. +% +% \begin{figure}[htbp] +% \[ +% \begin{array}{*5{@{}c}@{}} +% \cline{1-1} +% \multicolumn{1}{c|}{\cdots\quad\meta{bit-field rows}} +% & +% & \left.\rule{0pt}{3ex}\right\} +% & +% & \meta{label} \\[2ex] \cline{1-1} +% & \underbrace{\hspace*{6em}}_{\mathtt{rightcurlyspace}} +% & +% & \underbrace{\hspace*{6em}}_{\mathtt{rightlabelspace}} \\ +% \end{array} +% \] +% \caption{Role of \texttt{rightcurlyspace} and \texttt{rightlabelspace}} +% \label{fig:rightspace} +% \end{figure} +% +% \begin{decl} +% \optname{leftcurlyshrinkage} = \meta{length} \\ +% \optname{rightcurlyshrinkage} = \meta{length} \\ +% \optname{curlyshrinkage} = \meta{length} +% \end{decl} +% +% In \TeX/\LaTeX, the height of a curly brace does not include the tips. +% Hence, in a word group label, the tips of the curly brace will extend +% beyond the height of the word group. +% \optname{leftcurlyshrinkage}\slash \optname{rightcurlyshrinkage} is an +% amount by which to reduce the height of the curly brace in a +% left\slash right word group's label. Setting \optname{curlyshrinkage} +% is a shortcut for setting both \optname{leftcurlyshrinkage} and +% \optname{rightcurlyshrinkage} to the same value. Shrinkages default +% to~|5pt|, and it is extremely unlikely that one would ever need to +% change them. Nevertheless, these parameters are included here in case +% a document is typeset with a math font containing radically different +% curly braces from the ones that come with \TeX/\LaTeX\ or that +% replaces the curly braces (using \optname{leftcurly}\slash +% \optname{rightcurly}, described above) with symbols of substantially +% different heights. +% +% \begin{decl} +% \optname{lsb} = \meta{integer} +% \end{decl} +% +% Designate the least significant bit (LSB) in the bit header. By +% default, the LSB is zero, which means that the first bit position in +% the header corresponds to bit~0. Specifying a different LSB shifts +% the bit header such that the first bit position instead corresponds to +% \meta{integer}. Note that the \optname{lsb} option affects bit +% \emph{positions} regardless of whether these positions are labeled, as +% demonstrated by the following two examples: +% +% \begin{verbatim} +% \begin{bytefield}{32} +% \bitheader[lsb=0]{4,12,20,28} \\ +% \bitbox{16}{ar\$hrd} & \bitbox{16}{ar\$pro} \\ +% \bitbox{8}{ar\$hln} & \bitbox{8}{ar\$pln} & \bitbox{16}{ar\$op} \\ +% \end{bytefield} +% \end{verbatim} +% +% \begin{bffigure} +% \begin{bytefield}{32} +% \bitheader[lsb=0]{4,12,20,28} \\ +% \bitbox{16}{ar\$hrd} & \bitbox{16}{ar\$pro} \\ +% \bitbox{8}{ar\$hln} & \bitbox{8}{ar\$pln} & \bitbox{16}{ar\$op} \\ +% \end{bytefield} +% \end{bffigure} +% +% \begin{verbatim} +% \begin{bytefield}{32} +% \bitheader[lsb=4]{4,12,20,28} \\ +% \bitbox{16}{ar\$hrd} & \bitbox{16}{ar\$pro} \\ +% \bitbox{8}{ar\$hln} & \bitbox{8}{ar\$pln} & \bitbox{16}{ar\$op} \\ +% \end{bytefield} +% \end{verbatim} +% +% \begin{bffigure} +% \begin{bytefield}{32} +% \bitheader[lsb=4]{4,12,20,28} \\ +% \bitbox{16}{ar\$hrd} & \bitbox{16}{ar\$pro} \\ +% \bitbox{8}{ar\$hln} & \bitbox{8}{ar\$pln} & \bitbox{16}{ar\$op} \\ +% \end{bytefield} +% \end{bffigure} +% +% +% \subsection{Common tricks} +% \label{sec:tricks} +% +% This section shows some clever ways to use \pkgname{bytefield}'s commands +% to produce some useful effects. +% +% \paragraph{Odd-sized fields} +% To produce a field that is, say, 1\textonehalf{} words long, use a +% |\bitbox| for the fractional part and specify appropriate values +% for the various \meta{sides} parameters. For instance: +% +% \begin{verbatim} +% \begin{bytefield}{16} +% \bitheader{0,7,8,15} \\ +% \bitbox{8}{8-bit field} & \bitbox[lrt]{8}{} \\ +% \wordbox[lrb]{1}{24-bit field} +% \end{bytefield} +% \end{verbatim} +% +% \begin{bffigure} +% \begin{bytefield}{16} +% \bitheader{0,7,8,15} \\ +% \bitbox{8}{8-bit field} & \bitbox[lrt]{8}{} \\ +% \wordbox[lrb]{1}{24-bit field} +% \end{bytefield} +% \end{bffigure} +% +% \paragraph{Ellipses} +% To skip words that appear the middle of enumerated data, put some +% |\vdots| in a |\wordbox| with empty \meta{sides}: +% +% \begin{verbatim} +% \begin{bytefield}{16} +% \bitbox{8}{Type} & \bitbox{8}{\# of nodes} \\ +% \wordbox{1}{Node~1} \\ +% \wordbox{1}{Node~2} \\ +% \wordbox[]{1}{$\vdots$} \\[1ex] +% \wordbox{1}{Node~$N$} +% \end{bytefield} +% \end{verbatim} +% +% \begin{bffigure} +% \begin{bytefield}{16} +% \bitbox{8}{Type} & \bitbox{8}{\# of nodes} \\ +% \wordbox{1}{Node~1} \\ +% \wordbox{1}{Node~2} \\ +% \wordbox[]{1}{$\vdots$} \\[1ex] +% \wordbox{1}{Node~$N$} +% \end{bytefield} +% \end{bffigure} +% +% \noindent +% The extra |1ex| of vertical space helps vertically center the |\vdots| +% a bit better. +% +% \paragraph{Narrow fields} +% There are a number of options for labeling a narrow field (e.g.,~one +% occupying a single bit): +% +% \newsavebox{\defaultOK} +% \begin{lrbox}{\defaultOK} +% \begin{bytefield}{8} +% \bitbox{1}{OK} & \bitbox{7}{Data} \\ +% \end{bytefield} +% \end{lrbox} +% +% \newsavebox{\bitwidthOK} +% \begin{lrbox}{\bitwidthOK} +% \bytefieldsetup{bitwidth=\widthof{OK~}}\relax +% \begin{bytefield}{8} +% \bitbox{1}{OK} & \bitbox{7}{Data} \\ +% \end{bytefield} +% \end{lrbox} +% +% \newsavebox{\tinyOK} +% \begin{lrbox}{\tinyOK} +% \begin{bytefield}{8} +% \bitbox{1}{\tiny OK} & \bitbox{7}{Data} \\ +% \end{bytefield} +% \end{lrbox} +% +% \newsavebox{\verticalOK} +% \begin{lrbox}{\verticalOK} +% \begin{bytefield}{8} +% \bitbox{1}{\tiny O \\ K} & \bitbox{7}{Data} \\ +% \end{bytefield} +% \end{lrbox} +% +% \newsavebox{\rotateOK} +% \begin{lrbox}{\rotateOK} +% \begin{bytefield}{8} +% \bitbox{1}{\rotatebox{90}{\small OK}} & \bitbox{7}{Data} \\ +% \end{bytefield} +% \end{lrbox} +% +% \newsavebox{\resizeOK} +% \begin{lrbox}{\resizeOK} +% \begin{bytefield}{8} +% \bitbox{1}{\let\bw=\width\resizebox{\bw}{!}{~OK~}} & \bitbox{7}{Data} \\ +% \end{bytefield} +% \end{lrbox} +% +% \bigskip +% +% \begin{tabular}{ll} +% \emph{Default}: & \raisebox{-4ex}{\usebox{\defaultOK}} \\ +% |\bytefieldsetup{%| +% & \multirow{2}*{\raisebox{-4ex}{\usebox{\bitwidthOK}}} \\ +% | bitwidth=\widthof{OK~}}|: & \\[2ex] +% |\tiny OK|: & \raisebox{-4ex}{\usebox{\tinyOK}} \\ +% |\tiny O \\ K|: & \raisebox{-4ex}{\usebox{\verticalOK}} \\ +% |\rotatebox{90}{\small OK}|: & \raisebox{-4ex}{\usebox{\rotateOK}} \\ +% |\let\bw=\width| & \multirow{2}*{\raisebox{-4ex}{\usebox{\resizeOK}}} \\ +% |\resizebox{\bw}{!}{~OK~}|: & \\[2ex] +% \end{tabular} +% +% \paragraph{Multi-line bit fields} +% Presentations of wide registers are often easier to read when split +% across multiple lines. (This capability was originally requested by +% Chris L'Esperance and is currently implemented in \pkgname{bytefield} +% based on code provided by Renaud Pacalet.) The trick behind the +% typesetting of multi-line bit fields is to pass the \optname{lsb} +% option to |\bitheader| to change the starting bit number used in each +% bit header: +% +% \begin{verbatim} +% \begin{bytefield}[endianness=big,bitwidth=2em]{16} +% \bitheader[lsb=16]{16-31} \\ +% \bitbox{1}{\tiny Enable} & \bitbox{7}{Reserved} +% & \bitbox{8}{Bus} \\[3ex] +% \bitheader{0-15} \\ +% \bitbox{5}{Device} & \bitbox{3}{Function} & \bitbox{6}{Register} +% & \bitbox{2}{00} +% \end{bytefield} +% \end{verbatim} +% +% \begin{bffigure} +% \begin{bytefield}[endianness=big,bitwidth=2em]{16} +% \bitheader[lsb=16]{16-31} \\ +% \bitbox{1}{\tiny Enable} & \bitbox{7}{Reserved} +% & \bitbox{8}{Bus} \\[3ex] +% \bitheader{0-15} \\ +% \bitbox{5}{Device} & \bitbox{3}{Function} & \bitbox{6}{Register} +% & \bitbox{2}{00} +% \end{bytefield} +% \end{bffigure} +% +% Note the use of the optional argument to |\\| to introduce three +% \mbox{x-heights} of additional whitespace between the two rows of +% bits. +% +% \paragraph{Rotated bit labels} +% A problem with using very large bit numbers is that the labels run +% into each other, as in the following example: +% +% \begin{verbatim} +% \begin{bytefield}[endianness=big]{8} +% \bitheader[lsb=995]{995-1002} \\ +% \bitbox{4}{A} & \bitbox{4}{B} +% \end{bytefield} +% \end{verbatim} +% +% \begin{bffigure} +% \begin{bytefield}[endianness=big]{8} +% \bitheader[lsb=995]{995-1002} \\ +% \bitbox{4}{A} & \bitbox{4}{B} +% \end{bytefield} +% \end{bffigure} +% +% One solution is to use the \optname{bitformatting} option and the +% \pkgname{graphicx} package's |\rotatebox| command to rotate each bit +% label by 90\textdegree. Unfortunately, the naive use of +% \optname{bitformatting} and |\rotatebox| does not typeset nicely: +% +% \begin{verbatim} +% \begin{bytefield}[endianness=big]{8} +% \bitheader[lsb=995, +% bitformatting={\tiny\rotatebox[origin=B]{90}}]{995-1002} \\ +% \bitbox{4}{A} & \bitbox{4}{B} +% \end{bytefield} +% \end{verbatim} +% +% \begin{bffigure} +% \begin{bytefield}[endianness=big]{8} +% \bitheader[lsb=995, +% bitformatting={\tiny\rotatebox[origin=B]{90}}]{995-1002} \\ +% \bitbox{4}{A} & \bitbox{4}{B} +% \end{bytefield} +% \end{bffigure} +% +% The two problems are that (1)~the numbers are left-justified, and +% (2)~the numbers touch the top margin of the word box. To address these +% problems we use |\makebox| to construct a right-justified region that +% is sufficiently wide to hold our largest number plus some additional +% space to shift the rotated numbers upwards: +% +% \begin{verbatim} +% \newlength{\bitlabelwidth} +% \newcommand{\rotbitheader}[1]{% +% \tiny +% \settowidth{\bitlabelwidth}{\quad 9999}% +% \rotatebox[origin=B]{90}{\makebox[\bitlabelwidth][r]{#1}}% +% } +% +% \begin{bytefield}[endianness=big]{8} +% \bitheader[lsb=995,bitformatting=\rotbitheader]{995-1002} \\ +% \bitbox{4}{A} & \bitbox{4}{B} +% \end{bytefield} +% \end{verbatim} +% +% \begin{bffigure} +% \newlength{\bitlabelwidth} +% \newcommand{\rotbitheader}[1]{^^A +% \tiny +% \settowidth{\bitlabelwidth}{\quad 9999}% +% \rotatebox[origin=B]{90}{\makebox[\bitlabelwidth][r]{#1}}^^A +% } +% +% \begin{bytefield}[endianness=big]{8} +% \bitheader[lsb=995,bitformatting=\rotbitheader]{995-1002} \\ +% \bitbox{4}{A} & \bitbox{4}{B} +% \end{bytefield} +% \end{bffigure} +% +% \paragraph{Unused bits} +% Because |\width| and |\height| are defined within bit boxes (also word +% boxes), we can represent unused bits by filling a |\bitbox| with a +% rule of size |\width|~$\times$ |\height|: +% +% \begin{verbatim} +% \begin{bytefield}{32} +% \bitheader{0,4,8,12,16,20,24,28} \\ +% \bitbox{8}{Tag} & \bitbox{8}{Value} & +% \bitbox{4}{\rule{\width}{\height}} & +% \bitbox{12}{Mask} \\ +% \wordbox{1}{Key} +% \end{bytefield} +% \end{verbatim} +% +% \begin{bffigure} +% \begin{bytefield}{32} +% \bitheader{0,4,8,12,16,20,24,28} \\ +% \bitbox{8}{Tag} & \bitbox{8}{Value} & +% \bitbox{4}{\rule{\width}{\height}} & +% \bitbox{12}{Mask} \\ +% \wordbox{1}{Key} +% \end{bytefield} +% \end{bffigure} +% +% \noindent +% The effect is much better when the \pkgname{color} package is used to +% draw the unused bits in color. (Light gray looks nice.) +% +% \begin{verbatim} +% \definecolor{lightgray}{gray}{0.8} +% \begin{bytefield}{32} +% \bitheader{0,4,8,12,16,20,24,28} \\ +% \bitbox{8}{Tag} & \bitbox{8}{Value} & +% \bitbox{4}{\color{lightgray}\rule{\width}{\height}} & +% \bitbox{12}{Mask} \\ +% \wordbox{1}{Key} +% \end{bytefield} +% \end{verbatim} +% +% \definecolor{lightgray}{gray}{0.8} +% \begin{bffigure} +% \begin{bytefield}{32} +% \bitheader{0,4,8,12,16,20,24,28} \\ +% \bitbox{8}{Tag} & \bitbox{8}{Value} & +% \bitbox{4}{\color{lightgray}\rule{\width}{\height}} & +% \bitbox{12}{Mask} \\ +% \wordbox{1}{Key} +% \end{bytefield} +% \end{bffigure} +% +% \paragraph{Aligning text on the baseline} +% Because \pkgname{bytefield} internally uses \LaTeX's |picture| +% environment and that environment's |\makebox| command to draw bit +% boxes and word boxes, the text within a box is centered vertically +% with no attention paid to the text's baseline. As a result, some +% bit-field labels appear somewhat askew: +% +% \begin{verbatim} +% \begin{bytefield}[bitwidth=1.5em]{2} +% \bitbox{1}{M} & \bitbox{1}{y} +% \end{bytefield} +% \end{verbatim} +% +% \begin{bffigure} +% \begin{bytefield}[bitwidth=1.5em]{2} +% \bitbox{1}{M} & \bitbox{1}{y} +% \end{bytefield} +% \end{bffigure} +% +% A solution is to use the \optname{boxformatting} option to trick +% |\makebox| into thinking that all text has the same height and depth. +% Here we use |\raisebox| to indicate that all text is as tall as a +% ``|W|'' and does not descend at all below the baseline: +% +% \begin{verbatim} +% \newlength{\maxheight} +% \setlength{\maxheight}{\heightof{W}} +% +% \newcommand{\baselinealign}[1]{% +% \centering +% \raisebox{0pt}[\maxheight][0pt]{#1}% +% } +% +% \begin{bytefield}[boxformatting=\baselinealign, +% bitwidth=1.5em]{2} +% \bitbox{1}{M} & \bitbox{1}{y} +% \end{bytefield} +% \end{verbatim} +% +% \begin{bffigure} +% \newlength{\maxheight} +% \setlength{\maxheight}{\heightof{W}} +% \newcommand{\baselinealign}[1]{^^A +% \centering +% \raisebox{0pt}[\maxheight][0pt]{#1}^^A +% } +% \begin{bytefield}[boxformatting=\baselinealign, +% bitwidth=1.5em]{2} +% \bitbox{1}{M} & \bitbox{1}{y} +% \end{bytefield} +% \end{bffigure} +% +% \paragraph{Register contents} +% Sometimes, rather than listing the \emph{meaning} of each bit field +% within each |\bitbox| or |\wordbox|, it may be desirable to list the +% \emph{contents}, with the meaning described in an additional label +% above each bit number in the bit header. Although the +% \pkgname{register} package is more suited to this form of layout, +% \pkgname{bytefield} can serve in a pinch with the help of the +% |\turnbox| macro from the \pkgname{rotating} package: +% +% \begin{verbatim} +% \newcommand{\bitlabel}[2]{% +% \bitbox[]{#1}{% +% \raisebox{0pt}[4ex][0pt]{% +% \turnbox{45}{\fontsize{7}{7}\selectfont#2}% +% }% +% }% +% } +% +% \begin{bytefield}[bitwidth=1em]{16} +% \bitlabel{1}{Carry} & \bitlabel{1}{Reserved} & +% \bitlabel{1}{Parity} & \bitlabel{1}{Reserved} & +% \bitlabel{1}{Adjust} & \bitlabel{1}{Reserved} & +% \bitlabel{1}{Zero} & \bitlabel{1}{Sign} & +% \bitlabel{1}{Trap} & \bitlabel{1}{Interrupt enable} & +% \bitlabel{1}{Direction} & \bitlabel{1}{Overflow} & +% \bitlabel{2}{I/O privilege level (12--13)} & +% \bitlabel{1}{Nested task} & \bitlabel{1}{Reserved} \\ +% \bitheader{0-15} \\ +% \bitbox{1}{0} & \bitbox{1}{1} & \bitbox{1}{0} & \bitbox{1}{0} & +% \bitbox{1}{0} & \bitbox{1}{0} & \bitbox{1}{0} & \bitbox{1}{1} & +% \bitbox{1}{0} & \bitbox{1}{1} & \bitbox{1}{0} & \bitbox{1}{0} & +% \bitbox{1}{0} & \bitbox{1}{0} & \bitbox{1}{0} & \bitbox{1}{0} +% \end{bytefield} +% \end{verbatim} +% +% \vspace{3\baselineskip} ^^A Allow extra room for the rotated headers. +% \begin{bffigure} +% \newcommand{\bitlabel}[2]{% +% \bitbox[]{#1}{% +% \raisebox{0pt}[4ex][0pt]{% +% \turnbox{45}{\fontsize{7}{7}\selectfont#2}% +% }% +% }% +% } +% \begin{bytefield}[bitwidth=1em]{16} +% \bitlabel{1}{Carry} & \bitlabel{1}{Reserved} & +% \bitlabel{1}{Parity} & \bitlabel{1}{Reserved} & +% \bitlabel{1}{Adjust} & \bitlabel{1}{Reserved} & +% \bitlabel{1}{Zero} & \bitlabel{1}{Sign} & +% \bitlabel{1}{Trap} & \bitlabel{1}{Interrupt enable} & +% \bitlabel{1}{Direction} & \bitlabel{1}{Overflow} & +% \bitlabel{2}{I/O privilege level (12--13)} & +% \bitlabel{1}{Nested task} & \bitlabel{1}{Reserved} \\ +% \bitheader{0-15} \\ +% \bitbox{1}{0} & \bitbox{1}{1} & \bitbox{1}{0} & \bitbox{1}{0} & +% \bitbox{1}{0} & \bitbox{1}{0} & \bitbox{1}{0} & \bitbox{1}{1} & +% \bitbox{1}{0} & \bitbox{1}{1} & \bitbox{1}{0} & \bitbox{1}{0} & +% \bitbox{1}{0} & \bitbox{1}{0} & \bitbox{1}{0} & \bitbox{1}{0} +% \end{bytefield} +% \end{bffigure} +% +% +% \subsection{Not-so-common tricks} +% +% \paragraph{Colored fields} +% A similar approach to that utilized to indicate unused bits can be +% applied to coloring an individual bit field. The trick is to use the +% \TeX\ |\rlap| primitive to draw a colored box that overlaps whatever +% follows it to the right: +% +% \begin{verbatim} +% \newcommand{\colorbitbox}[3]{% +% \rlap{\bitbox{#2}{\color{#1}\rule{\width}{\height}}}% +% \bitbox{#2}{#3}} +% \definecolor{lightcyan}{rgb}{0.84,1,1} +% \definecolor{lightgreen}{rgb}{0.64,1,0.71} +% \definecolor{lightred}{rgb}{1,0.7,0.71} +% \begin{bytefield}[bitheight=\widthof{~Sign~}, +% boxformatting={\centering\small}]{32} +% \bitheader[endianness=big]{31,23,0} \\ +% \colorbitbox{lightcyan}{1}{\rotatebox{90}{Sign}} & +% \colorbitbox{lightgreen}{8}{Exponent} & +% \colorbitbox{lightred}{23}{Mantissa} +% \end{bytefield} +% \end{verbatim} +% +% \begin{bffigure} +% \newcommand{\colorbitbox}[3]{^^A +% \rlap{\bitbox{#2}{\color{#1}\rule{\width}{\height}}}^^A +% \bitbox{#2}{#3}}^^A +% \definecolor{lightcyan}{rgb}{0.84,1,1} +% \definecolor{lightgreen}{rgb}{0.64,1,0.71} +% \definecolor{lightred}{rgb}{1,0.7,0.71} +% \begin{bytefield}[bitheight=\widthof{~Sign~}, +% boxformatting={\centering\small}]{32} +% \bitheader[endianness=big]{31,23,0} \\ +% \colorbitbox{lightcyan}{1}{\rotatebox{90}{Sign}} & +% \colorbitbox{lightgreen}{8}{Exponent} & +% \colorbitbox{lightred}{23}{Mantissa} +% \end{bytefield} +% \end{bffigure} +% +% \paragraph{Omitted bit numbers} +% It is occasionally convenient to show a wide bit field in which the +% middle numbers are replaced with an ellipsis. The trick to +% typesetting such a thing with \pkgname{bytefield} is to point the +% |bitformatting| option to a macro that conditionally modifies the +% given bit number before outputting it. One catch is that +% \pkgname{bytefield} measures the height of the string ``|1234567890|'' +% using the current bit formatting, so that needs to be a valid input. +% (If \optname{bitwidth} is set to ``|auto|'', then ``|99i|'' also has +% to be a valid input, but we're not using ``|auto|'' here.) The +% following example shows how to \emph{conditionally} modify the bit +% number: If the number is |1234567890|, it is used as is; numbers +% greater than~9 are increased by 48; numbers less than~4 are +% unmodified; the number~6 is replaced by an ellipsis; and all other +% numbers are discarded. +% +% \begin{verbatim} +% \newcommand{\fakesixtyfourbits}[1]{% +% \tiny +% \ifnum#1=1234567890 +% #1 +% \else +% \ifnum#1>9 +% \count32=#1 +% \advance\count32 by 48 +% \the\count32% +% \else +% \ifnum#1<4 +% #1% +% \else +% \ifnum#1=6 +% $\cdots$% +% \fi +% \fi +% \fi +% \fi +% } +% \begin{bytefield}[% +% bitwidth=\widthof{\tiny Fwd~}, +% bitformatting=\fakesixtyfourbits, +% endianness=big]{16} +% \bitheader{0-15} \\ +% \bitbox{1}{\tiny F/E} & \bitbox{1}{\tiny T0} & \bitbox{1}{\tiny T1} +% & \bitbox{1}{\tiny Fwd} & \bitbox{12}{Data value} +% \end{bytefield} +% \end{verbatim} +% +% \begin{bffigure} +% \newcommand{\fakesixtyfourbits}[1]{% +% \tiny +% \ifnum#1=1234567890 +% #1 +% \else +% \ifnum#1>9 +% \count32=#1 +% \advance\count32 by 48 +% \the\count32^^A +% \else +% \ifnum#1<4 +% #1% +% \else +% \ifnum#1=6 +% $\cdots$^^A +% \fi +% \fi +% \fi +% \fi +% } +% \begin{bytefield}[^^A +% bitwidth=\widthof{\tiny Fwd~}, +% bitformatting=\fakesixtyfourbits, +% endianness=big]{16} +% \bitheader{0-15} \\ +% \bitbox{1}{\tiny F/E} & \bitbox{1}{\tiny T0} & \bitbox{1}{\tiny T1} +% & \bitbox{1}{\tiny Fwd} & \bitbox{12}{Data value} +% \end{bytefield} +% \end{bffigure} +% +% \paragraph{Memory-map diagrams} +% While certainly not the intended purpose of the \pkgname{bytefield} +% package, one can utilize word boxes with empty \meta{sides} and +% word labels to produce memory-map diagrams: +% +% \begin{verbatim} +% \newcommand{\descbox}[2]{\parbox[c][3.8\baselineskip]{0.95\width}{% +% \raggedright #1\vfill #2}} +% \begin{bytefield}[bitheight=4\baselineskip]{32} +% \begin{rightwordgroup}{Partition 4} +% \bitbox[]{8}{\texttt{0xFFFFFFFF} \\[2\baselineskip] +% \texttt{0xC0000000}} & +% \bitbox{24}{\descbox{1\,GB area for VxDs, memory manager, +% file system code; shared by all processes.}{Read/writable.}} +% \end{rightwordgroup} \\ +% \begin{rightwordgroup}{Partition 3} +% \bitbox[]{8}{\texttt{0xBFFFFFFF} \\[2\baselineskip] +% \texttt{0x80000000}} & +% \bitbox{24}{\descbox{1\,GB area for memory-mapped files, +% shared system \textsc{dll}s, file system code; shared by all +% processes.}{Read/writable.}} +% \end{rightwordgroup} \\ +% \begin{rightwordgroup}{Partition 2} +% \bitbox[]{8}{\texttt{0x7FFFFFFF} \\[2\baselineskip] +% \texttt{0x00400000}} & +% \bitbox{24}{\descbox{$\sim$2\,GB area private to process, +% process code, and data.}{Read/writable.}} +% \end{rightwordgroup} \\ +% \begin{rightwordgroup}{Partition 1} +% \bitbox[]{8}{\texttt{0x003FFFFF} \\[2\baselineskip] +% \texttt{0x00001000}} & +% \bitbox{24}{\descbox{4\,MB area for MS-DOS and Windows~3.1 +% compatibility.}{Read/writable.}} \\ +% \bitbox[]{8}{\texttt{0x00000FFF} \\[2\baselineskip] +% \texttt{0x00000000}} & +% \bitbox{24}{\descbox{4096~byte area for MS-DOS and Windows~3.1 +% compatibility.}{Protected---catches \textsc{null} +% pointers.}} +% \end{rightwordgroup} +% \end{bytefield} +% \end{verbatim} +% +% \begin{bffigure} +% \newcommand{\descbox}[2]{\parbox[c][3.8\baselineskip]{0.95\width}{% +% \raggedright #1\vfill #2}} +% \begin{bytefield}[bitheight=4\baselineskip]{32} +% \begin{rightwordgroup}{Partition 4} +% \bitbox[]{8}{\texttt{0xFFFFFFFF} \\[2\baselineskip] +% \texttt{0xC0000000}} & +% \bitbox{24}{\descbox{1\,GB area for VxDs, memory manager, +% file system code; shared by all processes.}{Read/writable.}} +% \end{rightwordgroup} \\ +% \begin{rightwordgroup}{Partition 3} +% \bitbox[]{8}{\texttt{0xBFFFFFFF} \\[2\baselineskip] +% \texttt{0x80000000}} & +% \bitbox{24}{\descbox{1\,GB area for memory-mapped files, +% shared system \textsc{dll}s, file system code; shared by all +% processes.}{Read/writable.}} +% \end{rightwordgroup} \\ +% \begin{rightwordgroup}{Partition 2} +% \bitbox[]{8}{\texttt{0x7FFFFFFF} \\[2\baselineskip] +% \texttt{0x00400000}} & +% \bitbox{24}{\descbox{$\sim$2\,GB area private to process, process +% code, and data.}{Read/writable.}} +% \end{rightwordgroup} \\ +% \begin{rightwordgroup}{Partition 1} +% \bitbox[]{8}{\texttt{0x003FFFFF} \\[2\baselineskip] +% \texttt{0x00001000}} & +% \bitbox{24}{\descbox{4\,MB area for MS-DOS and Windows~3.1 +% compatibility.}{Read/writable.}} \\ +% \bitbox[]{8}{\texttt{0x00000FFF} \\[2\baselineskip] +% \texttt{0x00000000}} & +% \bitbox{24}{\descbox{4096~byte area for MS-DOS and Windows~3.1 +% compatibility.}{Protected---catches \textsc{null} +% pointers.}} +% \end{rightwordgroup} +% \end{bytefield} +% \end{bffigure} +% +% The following variation uses variable-height regions in the memory map: +% \changes{v2.1}{2012/09/02}{Included in the documentation a variable-height +% memory-map example suggested by Martin Demling} +% +% \begin{verbatim} +% \newcommand{\descbox}[2]{\parbox[c][3.8\baselineskip]{0.95\width}{% +% % facilitates the creation of memory maps. Start address at the bottom, +% % end address at the top. +% % syntax: +% % \memsection{end address}{start address}{height in lines}{text in box} +% \newcommand{\memsection}[4]{% +% % define the height of the memsection +% \bytefieldsetup{bitheight=#3\baselineskip}% +% \bitbox[]{10}{% +% \texttt{#1}% print end address +% \\ +% % do some spacing +% \vspace{#3\baselineskip} +% \vspace{-2\baselineskip} +% \vspace{-#3pt} +% \texttt{#2}% print start address +% }% +% \bitbox{16}{#4}% print box with caption +% } +% +% \begin{bytefield}{24} +% \memsection{ffff ffff}{0040 0000}{15}{-- free --}\\ +% \begin{rightwordgroup}{internal memory} +% \memsection{003f ffff}{002f c000}{4}{Special Function +% Registers}\\ +% \memsection{002f bfff}{0007 0000}{3}{-- reserved --}\\ +% \memsection{0006 ffff}{0000 0000}{8}{Internal Flash} +% \end{rightwordgroup}\\ +% \end{bytefield} +% \end{verbatim} +% +% \begin{bffigure} +% \newcommand{\memsection}[4]{^^A +% \bytefieldsetup{bitheight=#3\baselineskip}^^A +% \bitbox[]{10}{^^A +% \texttt{#1}^^A +% \\ \vspace{#3\baselineskip}\vspace{-2\baselineskip}\vspace{-#3pt}^^A +% \texttt{#2}^^A +% }^^A +% \bitbox{16}{#4}^^A +% } +% \begin{bytefield}{24} +% \memsection{ffff ffff}{0040 0000}{15}{-- free --}\\ +% \begin{rightwordgroup}{internal memory} +% \memsection{003f ffff}{002f c000}{4}{Special Function Registers}\\ +% \memsection{002f bfff}{0007 0000}{3}{-- reserved --}\\ +% \memsection{0006 ffff}{0000 0000}{8}{Internal Flash} +% \end{rightwordgroup}\\ +% \end{bytefield} +% \end{bffigure} +% +% +% \subsection{Putting it all together} +% +% The following code showcases most of \pkgname{bytefield}'s features in a +% single figure. +% +% \begin{verbatim} +% \begin{bytefield}[bitheight=2.5\baselineskip]{32} +% \bitheader{0,7,8,15,16,23,24,31} \\ +% \begin{rightwordgroup}{\parbox{6em}{\raggedright These words were taken +% verbatim from the TCP header definition (RFC~793).}} +% \bitbox{4}{Data offset} & \bitbox{6}{Reserved} & +% \bitbox{1}{\tiny U\\R\\G} & \bitbox{1}{\tiny A\\C\\K} & +% \bitbox{1}{\tiny P\\S\\H} & \bitbox{1}{\tiny R\\S\\T} & +% \bitbox{1}{\tiny S\\Y\\N} & \bitbox{1}{\tiny F\\I\\N} & +% \bitbox{16}{Window} \\ +% \bitbox{16}{Checksum} & \bitbox{16}{Urgent pointer} +% \end{rightwordgroup} \\ +% \wordbox[lrt]{1}{Data octets} \\ +% \skippedwords \\ +% \wordbox[lrb]{1}{} \\ +% \begin{leftwordgroup}{\parbox{6em}{\raggedright Note that we can display, +% for example, a misaligned 64-bit value with clever use of the +% optional argument to \texttt{\string\wordbox} and +% \texttt{\string\bitbox}.}} +% \bitbox{8}{Source} & \bitbox{8}{Destination} & +% \bitbox[lrt]{16}{} \\ +% \wordbox[lr]{1}{Timestamp} \\ +% \begin{rightwordgroup}{\parbox{6em}{\raggedright Why two Length fields? +% No particular reason.}} +% \bitbox[lrb]{16}{} & \bitbox{16}{Length} +% \end{leftwordgroup} \\ +% \bitbox{6}{Key} & \bitbox{6}{Value} & \bitbox{4}{Unused} & +% \bitbox{16}{Length} +% \end{rightwordgroup} \\ +% \wordbox{1}{Total number of 16-bit data words that follow this +% header word, excluding the subsequent checksum-type value} \\ +% \bitbox{16}{Data~1} & \bitbox{16}{Data~2} \\ +% \bitbox{16}{Data~3} & \bitbox{16}{Data~4} \\ +% \bitbox[]{16}{$\vdots$ \\[1ex]} & +% \bitbox[]{16}{$\vdots$ \\[1ex]} \\ +% \bitbox{16}{Data~$N-1$} & \bitbox{16}{Data~$N$} \\ +% \bitbox{20}{\[ \mbox{A5A5}_{\mbox{\scriptsize H}} \oplus +% \left(\sum_{i=1}^N \mbox{Data}_i \right) \bmod 2^{20} \]} & +% \bitboxes*{1}{000010 000110} \\ +% \wordbox{2}{64-bit random number} +% \end{bytefield} +% \end{verbatim} +% +% \noindent +% Figure~\ref{fig:complex-diagram} shows the resulting protocol diagram. +% +% \begin{figure}[phtb] +% \centering +% \begin{lrbox}{\protocoldiagram} +% \begin{bytefield}[bitheight=2.5\baselineskip]{32} +% \bitheader{0,7,8,15,16,23,24,31} \\ +% \begin{rightwordgroup}{\parbox{6em}{\raggedright These words were taken +% verbatim from the TCP header definition (RFC~793).}} +% \bitbox{4}{Data offset} & \bitbox{6}{Reserved} & +% \bitbox{1}{\tiny U\\R\\G} & \bitbox{1}{\tiny A\\C\\K} & +% \bitbox{1}{\tiny P\\S\\H} & \bitbox{1}{\tiny R\\S\\T} & +% \bitbox{1}{\tiny S\\Y\\N} & \bitbox{1}{\tiny F\\I\\N} & +% \bitbox{16}{Window} \\ +% \bitbox{16}{Checksum} & \bitbox{16}{Urgent pointer} +% \end{rightwordgroup} \\ +% \wordbox[lrt]{1}{Data octets} \\ +% \skippedwords \\ +% \wordbox[lrb]{1}{} \\ +% \begin{leftwordgroup}{\parbox{6em}{\raggedright Note that we can display, +% for example, a misaligned 64-bit value with clever use of the +% optional argument to \texttt{\string\wordbox} and +% \texttt{\string\bitbox}.}} +% \bitbox{8}{Source} & \bitbox{8}{Destination} & \bitbox[lrt]{16}{} \\ +% \wordbox[lr]{1}{Timestamp} \\ +% \begin{rightwordgroup}{\parbox{6em}{\raggedright Why two Length fields? +% No particular reason.}} +% \bitbox[lrb]{16}{} & \bitbox{16}{Length} +% \end{leftwordgroup} \\ +% \bitbox{6}{Key} & \bitbox{6}{Value} & \bitbox{4}{Unused} & +% \bitbox{16}{Length} +% \end{rightwordgroup} \\ +% \wordbox{1}{Total number of 16-bit data words that follow this +% header word, excluding the subsequent checksum-type value} \\ +% \bitbox{16}{Data~1} & \bitbox{16}{Data~2} \\ +% \bitbox{16}{Data~3} & \bitbox{16}{Data~4} \\ +% \bitbox[]{16}{$\vdots$ \\[1ex]} & \bitbox[]{16}{$\vdots$ \\[1ex]} \\ +% \bitbox{16}{Data~$N-1$} & \bitbox{16}{Data~$N$} \\ +% \bitbox{20}{\[ \mbox{A5A5}_{\mbox{\scriptsize H}} \oplus +% \left(\sum_{i=1}^N \mbox{Data}_i \right) \bmod 2^{20} \]} & +% \bitboxes*{1}{000010 000110} \\ +% \wordbox{2}{64-bit random number} +% \end{bytefield} +% \end{lrbox} +% \makebox[0pt][c]{\usebox{\protocoldiagram}} +% \caption{Complex protocol diagram drawn with the \pkgname{bytefield} +% package} +% \label{fig:complex-diagram} +% \end{figure} +% +% +% \subsection{Upgrading from older versions} +% \label{sec:upgrading} +% +% \pkgname{bytefield}'s user interface changed substantially with the +% introduction of version~2.0. Because documents written for +% \pkgname{bytefield}~v1.\textit{x} will not build properly under later +% versions of the package, this section explains how to convert documents +% to the new interface. +% +% \begin{decl} +% \SpecialUsageIndex{\wordgroupr} +% |\wordgroupr| \\ +% \SpecialUsageIndex{\endwordgroupr} +% |\endwordgroupr| +% \end{decl} +% +% These have been replaced with the |rightwordgroup| environment to make +% their invocation more \LaTeX-like. Use |\begin{rightwordgroup}| +% instead of |\wordgroupr| and |\end{rightwordgroup}| instead of +% |\endwordgroupr|. +% +% \begin{decl} +% \SpecialUsageIndex{\wordgroupl} +% |\wordgroupl| \\ +% \SpecialUsageIndex{\endwordgroupl} +% |\endwordgroupl| +% \end{decl} +% +% These have been replaced with the |leftwordgroup| environment to make +% their invocation more \LaTeX-like. Use |\begin{leftwordgroup}| +% instead of |\wordgroupl| and |\end{leftwordgroup}| instead of +% |\endwordgroupl|. +% +% \begin{decl} +% \SpecialUsageIndex{\bitwidth} +% |\bitwidth| +% \end{decl} +% +% Instead of changing bit widths with +% |\setlength{\bitwidth}{|\meta{width}|}|, use +% |\bytefieldsetup{bitwidth=|\meta{width}|}|. +% +% \begin{decl} +% \SpecialUsageIndex{\byteheight} +% |\byteheight| +% \end{decl} +% +% Instead of changing bit heights with +% |\setlength{\byteheight}{|\meta{height}|}|, use +% |\bytefieldsetup{bitheight=|\meta{height}|}| (and note the change from +% ``|byte|'' to ``|bit|'' for consistency with \optname{bitwidth}). +% +% \begin{decl} +% \SpecialUsageIndex{\curlyspace} +% |\curlyspace| \\ +% \SpecialUsageIndex{\labelspace} +% |\labelspace| +% \end{decl} +% +% Instead of using |\setlength{\curlyspace}{|\meta{dist}|}| and +% |\setlength{\labelspace}{|\meta{dist}|}| to alter the horizontal space +% that appears before and after a curly brace, use +% |\bytefieldsetup{curlyspace=|\meta{dist}|}| and +% |\bytefieldsetup{labelspace=|\meta{dist}|}|. Note that, as described +% in Section~\ref{sec:basic-cmds}, left and right spacing can be set +% independently if desired. +% +% \begin{decl} +% \SpecialUsageIndex{\curlyshrinkage} +% |\curlyshrinkage| +% \end{decl} +% +% Instead of using |\setlength{\curlyshrinkage}{|\meta{dist}|}| to +% reduce the vertical space occupied by a curly brace, use +% |\bytefieldsetup{curlyshrinkage=|\meta{dist}|}|. Note that, as +% described in Section~\ref{sec:basic-cmds}, left and right curly-brace +% height can be reduced independently if desired. +% +% \begin{decl} +% \SpecialUsageIndex{\bitwidth} +% |\bitwidth| \oarg{endianness} \marg{bit-positions} +% \end{decl} +% +% The meaning of |\bitwidth|'s optional argument changed with +% \pkgname{bytefield}~v2.1. In older versions of the package, the +% optional argument was one of ``|l|'' or ``|b|'' for, respectively, +% little-endian or big-endian bit ordering. Starting with version~2.1, +% the optional argument can be any of the parameters described in +% Section~\ref{sec:options} (but practically only |bitformatting|, +% |endianness|, and |lsb|). Hence, ``|l|'' should be replaced with +% |endianness=little| and ``|b|'' should be replaced with +% |endianness=big|. Although more verbose, these new options can be +% specified once for the entire document by listing them as package +% options or as arguments to |\bytefieldsetup|. +% +% \bigskip +% +% As a crutch to help build older documents with minimal modification, +% \pkgname{bytefield} provides a |compat1| package option that restores +% the old interface. This option, invoked with +% |\usepackage[compat1]{bytefield}|, may disappear in a future version +% of the package and should therefore not be relied upon as a long-term +% approach to using \pkgname{bytefield}. +% +% +% \StopEventually{^^A +% +% \section{Future work} +% +% \pkgname{bytefield} is my first \LaTeX\ package, and, as such, there +% are a number of macros that could probably have been implemented a +% lot better. For example, \pkgname{bytefield} is somewhat wasteful +% of \meta{dimen} registers (although it did get a lot better with +% version~1.1 and again with version~1.3). The package should really +% get a major overhaul now that I've gotten better at \TeX\slash +% \LaTeX\ programming. One minor improvement I'd like to make in the +% package is to move left, small curly braces closer to the bit field. +% In the following figure, notice how distant the small curly appears +% from the bit-field body: +% +% \begin{bffigure} +% \bytefieldsetup{bitheight=4ex} +% \begin{bytefield}{16} +% \begin{leftwordgroup}{Too distant} +% \wordbox{1}{Something} +% \end{leftwordgroup} \\ +% \begin{leftwordgroup}{Looks okay} +% \wordbox{4}{Something else} +% \end{leftwordgroup} +% \end{bytefield} +% \end{bffigure} +% +% \noindent +% The problem is that the curly braces are left-aligned relative to +% each other, while they should be right-aligned. +% } +% +% +% \section{Implementation} +% +% \newcommand{\usermacro}{\marginpar{\vspace*{1ex}{\strut\hspace{18pt}\huge$\star$}\vspace*{-1ex}}} +% +% This section contains the complete source code for \pkgname{bytefield}. +% Most users will not get much out of it, but it should be of use to +% those who need more precise documentation and those who want to extend +% (or debug~\smiley) the \pkgname{bytefield} package. +% +% In this section, macros marked in the margin with a ``{\Large +% $\star$}'' are intended to be called by the user (and were described +% in Section~\ref{sec:usage}). All other macros are used only +% internally by \pkgname{bytefield}. +% +% \subsection{Required packages} +% +% Although |\widthof| and |\heightof| were introduced in June~1998, +% te\kern-1.5pt\TeX~2.0---still in widespread use at the time of this +% writing (2005)---ships with an earlier |calc.sty| in the |source| +% directory. Because a misconfigured system may find the |source| +% version of |calc.sty| we explicitly specify a later date when loading +% the |calc| package. +% \changes{v1.2a}{2005/07/31}{Specified an explicit package date when +% loading the \pkgname{calc} package to avoid loading an outdated +% version. Thanks to Kevin Quick for discovering that outdated versions +% of \pkgname{calc} are still being included in \TeX{} distributions.} +% \begin{macrocode} +\RequirePackage{calc}[1998/07/07] +\RequirePackage{keyval} +% \end{macrocode} +% +% +% \subsection{Utility macros} +% +% The following macros in this section are used by the box-drawing macros +% and the ``skipped words''-drawing macros. +% +% \begin{macro}{\bf@newdimen} +% \begin{macro}{\allocationnumber} +% \changes{v1.1}{2002/09/15}{Bug fix: Added \cs{bf@newdimen} to greatly +% reduce the likelihood of ``\texttt{No room for a new \cs{dimen}}'' +% errors (reported by Vitaly A. Repin)} +% |\newdimen| defines new \meta{dimen}s globally. |\bf@newdimen| +% defines them locally. It simply merges \LaTeXe's |\newdimen| and +% |\alloc@| macros while omitting |\alloc@|'s ``|\global|'' declaration. +% \begin{macrocode} +\def\bf@newdimen#1{\advance\count11 by 1 + \ch@ck1\insc@unt\dimen + \allocationnumber=\count11 + \dimendef#1=\allocationnumber + \wlog{\string#1=\string\dimen\the\allocationnumber\space (locally)}% +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\bf@newdimen} +% $\varepsilon$-\TeX\ provides many more \meta{dimen}s than the original +% \TeX's 255. When running newer versions of $\varepsilon$-\TeX\ we +% rebind |\bf@newdimen| to |\newdimen|. If the \pkgname{etex} package +% is loaded, however, we instead rebind |\bf@newdimen| to |\locdimen| to +% keep the allocation local. Finally, if we're not running +% $\varepsilon$-\TeX\ we leave |\bf@newdimen| defined as above to help +% reduce register pressure when only 255 \meta{dimen}s are available. +% \changes{v1.3}{2010/10/31}{Added support for $\varepsilon$-\TeX's larger +% local \meta{dimen} pool (code provided by Heiko Oberdiek)} +% \changes{v2.3}{2015/10/28}{Rewrote the macro based on discussions with +% David Carlisle to avoid producing ``\texttt{No room for a new +% \string\string\string\dimen}'' errors in newer versions of $\varepsilon$-\TeX\ +% (cf.~\url{http://tex.stackexchange.com/q/275042})} +% \begin{macrocode} +\AtBeginDocument{% + \expandafter\ifx\csname e@alloc\endcsname\relax + \expandafter\ifx\csname locdimen\endcsname\relax + \else + \let\bf@newdimen=\locdimen + \fi + \else + \let\bf@newdimen=\newdimen + \fi +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\bytefield@height} +% \begin{macro}{\ifcounting@words} +% When |\ifcounting@words| is \textsc{true}, add the height of the next +% \texttt{picture} environment to |\bytefield@height|. We set +% |\counting@wordstrue| at the beginning of each word, and +% |\counting@wordsfalse| after each |\bitbox|, |\wordbox|, or |\skippedwords| +% picture. +% \begin{macrocode} +\newlength{\bytefield@height} +\newif\ifcounting@words +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\inc@bytefield@height} +% We have to define a special macro to increment |\bytefield@height| +% because the \pkgname{calc} package's |\addtolength| macro doesn't seem +% to see the global value. So we |\setlength| a temporary (to get +% \pkgname{calc}'s nice infix features) and |\advance| |\bytefield@height| +% by that amount. +% \begin{macrocode} +\newlength{\bytefield@height@increment} +\DeclareRobustCommand{\inc@bytefield@height}[1]{% + \setlength{\bytefield@height@increment}{#1}% + \global\advance\bytefield@height by \bytefield@height@increment} +% \end{macrocode} +% \end{macro} +% +% \subsection{Top-level environment} +% +% \begin{macro}{\entire@bytefield@picture} +% Declare a box for containing the entire bytefield. By storing +% everything in a box and then typesetting it later (at the +% |\end{bytefield}|), we can center the bit field, put a box around it, +% and do other operations on the entire figure. +% \begin{macrocode} +\newsavebox{\entire@bytefield@picture} +% \end{macrocode} +% \end{macro} +% +% \begin{environment}{bytefield} +% \usermacro +% \changes{v2.4}{2017/09/15}{Make the code resilient to changes in +% \texttt{\string\string\string\baselinestretch}. Thanks to +% Karst Koymans for the bug report} +% \begin{macro}{\bits@wide} +% \begin{macro}{\old@nl} +% \begin{macro}{\amp} +% The |bytefield| environment contains the layout of bits in a sequence +% of words. This is the main environment defined by the +% \pkgname{bytefield} package. The argument is the number of bits wide +% the bytefield should be. We turn |&| into a space character so the +% user can think of a \pkgname{bytefield} as being analogous to a +% \texttt{tabular} environment, even though we're really setting the +% bulk of the picture in a single column. (Row labels go in separate +% columns, however.) +% \begin{macrocode} +\newenvironment{bytefield}[2][]{% + \bf@bytefieldsetup{#1}% + \renewcommand{\baselinestretch}{}% + \selectfont + \def\bits@wide{#2}% + \let\old@nl=\\% + \let\amp=&% + \catcode`\&=10 + \openup -1pt + \setlength{\bytefield@height}{0pt}% + \setlength{\unitlength}{1pt}% + \global\counting@wordstrue + \begin{lrbox}{\entire@bytefield@picture}% +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \begin{macro}{\\} +% \usermacro +% We redefine |\\| within the |bytefield| environment to make it aware +% of curly braces that surround the protocol diagram. +% \changes{v2.1}{2011/06/12}{Augmented the definition +% of~\texttt{\string\string\string\\} to accept an optional argument, +% just like in a \texttt{tabular} environment} +% \begin{macrocode} + \renewcommand{\\}[1][0pt]{% + \unskip + \vspace{##1}% + \amp\show@wordlabelr\cr + \ignorespaces\global\counting@wordstrue\make@lspace\amp}% +% \end{macrocode} +% \end{macro} +% \begin{macrocode} + \vbox\bgroup\ialign\bgroup##\amp##\amp##\cr\amp +}{% + \amp\show@wordlabelr\cr\egroup\egroup + \end{lrbox}% + \usebox{\entire@bytefield@picture}} +% \end{macrocode} +% \end{environment} +% +% \subsection{Box-drawing macros} +% +% \subsubsection{Drawing (proper)} +% +% \begin{macro}{\bf@bitformatting} +% Format a bit number in the bit header. |\bf@bitformatting| may be +% redefined to take either a single argument (\`a~la |\textbf|) or no +% argument (\`a~la |\small|). +% \changes{v1.4}{2011/01/15}{Introduced this macro at Steven R. King's +% request to enable users to alter the bit header's font size} +% \begin{macrocode} +\newcommand*{\bf@bitformatting}{\tiny} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\bf@boxformatting} +% Format the text within a bit box or word box. |\bf@boxformatting| +% takes either a single argument (\`a~la |\textbf|) or no argument +% (\`a~la |\small|). The text that follows |\bf@boxformatting| is +% guaranteed to be a group that ends in |\par|, so if +% |\bf@boxformatting| accepts an argument, the macro should be defined +% with |\long| (e.g.,~with |\newcommand| but not with |\newcommand*|). +% \begin{macrocode} +\newcommand*{\bf@boxformatting}{\centering} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\bf@bitwidth} +% Define the width of a single bit. Note that this is wide enough to +% display a two-digit number without it running into adjacent numbers. +% For larger words, be sure to |\setlength| this larger. +% \begin{macrocode} +\newlength{\bf@bitwidth} +\settowidth{\bf@bitwidth}{\bf@bitformatting{99i}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\bf@bitheight} +% This is the height of a single bit within the bit field. +% \begin{macrocode} +\newlength{\bf@bitheight} +\setlength{\bf@bitheight}{4ex} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\units@wide} +% \begin{macro}{\units@tall} +% These are scratch variables for storing the width and height (in +% points) of the box we're about to draw. +% \begin{macrocode} +\newlength{\units@wide} +\newlength{\units@tall} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\bitbox} +% \usermacro +% Put some text (|#3|) in a box that's a given number of bits (|#2|) +% wide and one byte tall. An optional argument (|#1|) specifies which +% lines to draw---|[l]|eft, |[r]|ight, |[t]|op, and/or |[b]|ottom +% (default: |lrtb|). Uppercase letters suppress drawing the |[L]|eft, +% |[R]|ight, |[T]|op, and/or |[B]|ottom sides. +% \begin{macrocode} +\DeclareRobustCommand{\bitbox}[3][lrtb]{% + \setlength{\units@wide}{\bf@bitwidth * #2}% + \bf@parse@bitbox@arg{#1}% + \draw@bit@picture{\strip@pt\units@wide}{\strip@pt\bf@bitheight}{#3}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\wordbox} +% \usermacro +% Put some text (|#3|) in a box that's a given number of bytes (|#2|) +% tall and one word (|\bits@wide| bits) wide. +% An optional argument (|#1|) specifies which lines to draw---|[l]|eft, +% |[r]|ight, |[t]|op, and/or |[b]|ottom (default: |lrtb|). Uppercase +% letters suppress drawing the |[L]|eft, |[R]|ight, |[T]|op, and/or +% |[B]|ottom sides. +% \begin{macrocode} +\DeclareRobustCommand{\wordbox}[3][lrtb]{% + \setlength{\units@wide}{\bf@bitwidth * \bits@wide}% + \setlength{\units@tall}{\bf@bitheight * #2}% + \bf@parse@bitbox@arg{#1}% + \draw@bit@picture{\strip@pt\units@wide}{\strip@pt\units@tall}{#3}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\draw@bit@picture} +% Put some text (|#3|) in a box that's a given number of units (|#1|) +% wide and a given number of units (|#2|) tall. +% We format the text with a |\parbox| to enable word-wrapping and explicit +% line breaks. In addition, we define |\height|, |\depth|, |\totalheight|, +% and |\width| (\`a la |\makebox| and friends), so the user can utilize +% those for special effects (e.g., a |\rule| that fills the entire box). +% As an added bonus, we define |\widthunits| and |\heightunits|, which +% are the width and height of the box in multiples of |\unitlength| +% (i.e., |#1| and |#2|, respectively). +% \begin{macrocode} +\DeclareRobustCommand{\draw@bit@picture}[3]{% + \begin{picture}(#1,#2)% +% \end{macrocode} +% \begin{macro}{\height} +% \usermacro +% \begin{macro}{\depth} +% \usermacro +% \begin{macro}{\totalheight} +% \usermacro +% \begin{macro}{\width} +% \usermacro +% \begin{macro}{\widthunits} +% \usermacro +% \begin{macro}{\heightunits} +% \usermacro +% First, we plot the user's text, with all sorts of useful lengths +% predefined. +% \begin{macrocode} + \put(0,0){\makebox(#1,#2){\parbox{#1\unitlength}{% + \bf@newdimen\height + \bf@newdimen\depth + \bf@newdimen\totalheight + \bf@newdimen\width + \height=#2\unitlength + \depth=0pt% + \totalheight=#2\unitlength + \width=#1\unitlength + \def\widthunits{#1}% + \def\heightunits{#2}% + \bf@boxformatting{#3\par}}}}% +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% Next, we draw each line individually. I suppose we could make a special +% case for ``all lines'' and use a |\framebox| above, but the following +% works just fine. +% \begin{macrocode} + \ifbitbox@top + \put(0,#2){\line(1,0){#1}}% + \fi + \ifbitbox@bottom + \put(0,0){\line(1,0){#1}}% + \fi + \ifbitbox@left + \put(0,0){\line(0,1){#2}}% + \fi + \ifbitbox@right + \put(#1,0){\line(0,1){#2}}% + \fi + \end{picture}% +% \end{macrocode} +% Finally, we indicate that we're no longer at the beginning of a word. +% The following code structure (albeit with different arguments to +% |\inc@bytefield@height|) is repeated in various places throughout this +% package. We document it only here, however. +% \begin{macrocode} + \ifcounting@words + \inc@bytefield@height{\unitlength * \real{#2}}% + \global\counting@wordsfalse + \fi + \ignorespaces} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\bitboxes} +% \usermacro +% \changes{v2.2}{2014/06/01}{Added this macro based on an idea proposed +% by Andrew Mertz} +% \begin{macro}{\bitboxes*} +% \usermacro +% Put each token in |#3| into a box that's a given number of bits (|#2|) +% wide and one byte tall. An optional argument (|#1|) specifies which +% lines to draw---|[l]|eft, |[r]|ight, |[t]|op, and/or |[b]|ottom +% (default: |lrtb|). Uppercase letters suppress drawing the |[L]|eft, +% |[R]|ight, |[T]|op, and/or |[B]|ottom sides. The |*|-form of the +% command omits interior left and right lines. +% \begin{macrocode} +\DeclareRobustCommand{\bitboxes}{% + \@ifstar\bf@bitboxes@star\bf@bitboxes@no@star +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\bf@relax} +% Define a macro that expands to |\relax| for use with |\ifx| tests +% against |\bf@bitboxes@arg|, which can contain either tokens to typeset +% or |\relax|. +% \begin{macrocode} +\def\bf@relax{\relax} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\bf@bitboxes@no@star} +% Implement the unstarred version of |\bitboxes|. +% \begin{macrocode} +\newcommand{\bf@bitboxes@no@star}[3][lrtb]{% +% \end{macrocode} +% \begin{macro}{\bf@bitboxes@no@star@i} +% Define a helper macro that walks the final argument of +% |\bf@bitboxes@no@star| token-by-token. +% \begin{macrocode} + \def\bf@bitboxes@no@star@i##1{% +% \end{macrocode} +% \begin{macro}{\bf@bitboxes@arg} +% \begin{macro}{\next} +% Store the current argument token in |\bf@bitboxes@arg| for use with |\ifx|. +% \begin{macrocode} + \def\bf@bitboxes@arg{##1}% + \ifx\bf@bitboxes@arg\bf@relax + \let\next=\relax + \else + \bitbox[#1]{#2}{##1}% + \let\next=\bf@bitboxes@no@star@i + \fi + \next + }% + \bf@bitboxes@no@star@i#3\relax + \ignorespaces +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\bf@bitboxes@star} +% Implement the starred version of |\bitboxes|. +% \begin{macrocode} +\newcommand{\bf@bitboxes@star}[3][lrtb]{% +% \end{macrocode} +% \begin{macro}{\bf@bitboxes@star@i} +% If the argument to |\bitboxes*| contains a single (or no) token, +% simply pass control to |\bitbox| and stop. Otherwise, suppress the +% box's right border by appending ``|R|'' to |\bitboxes*|'s +% argument~|#1| and proceeding with the remaining tokens in~|#3|. +% \begin{macrocode} + \def\bf@bitboxes@star@i##1##2{% +% \end{macrocode} +% \begin{macro}{\bf@bitboxes@arg} +% \begin{macro}{\next} +% Store the current argument token in |\bf@bitboxes@arg| for use with |\ifx|. +% \begin{macrocode} + \def\bf@bitboxes@arg{##2}% + \ifx\bf@bitboxes@arg\bf@relax + \bitbox[#1]{#2}{##1}% + \let\next=\relax + \else + \bitbox[#1R]{#2}{##1}% + \def\next{\bf@bitboxes@star@ii{##2}}% + \fi + \next + }% +% \end{macrocode} +% \begin{macro}{\bf@bitboxes@star@ii} +% Process all tokens in |\bitboxes*|'s argument |#3| following the first +% argument. For each token, produce a box with the left side suppressed +% using~``|L|''. +% \begin{macrocode} + \def\bf@bitboxes@star@ii##1##2{% +% \end{macrocode} +% \begin{macro}{\bf@bitboxes@arg@i} +% \begin{macro}{\bf@bitboxes@arg@ii} +% \begin{macro}{\bf@bitboxes@sides} +% \begin{macro}{\next} +% Store the next two argument tokens in |\bf@bitboxes@arg@i| and +% |\bf@bitboxes@arg@i| for use with |\ifx|. We use those to set +% |\bf@bitboxes@sides| to |\bitbox*|'s argument~|#1| with the left side +% and, for the final token, the right side suppressed. +% \begin{macrocode} + \def\bf@bitboxes@arg@i{##1}% + \def\bf@bitboxes@arg@ii{##2}% + \ifx\bf@bitboxes@arg@ii\bf@relax + \def\bf@bitboxes@sides{#1L}% + \else + \def\bf@bitboxes@sides{#1LR}% + \fi + \ifx\bf@bitboxes@arg@i\bf@relax + \let\next=\relax + \else + \expandafter\bitbox\expandafter[\bf@bitboxes@sides]{#2}{##1}% + \def\next{\bf@bitboxes@star@ii{##2}}% + \fi + \next + }% +% \end{macrocode} +% \begin{macrocode} + \bf@bitboxes@star@i#3\relax\relax + \ignorespaces +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \subsubsection{Parsing arguments} +% +% The macros in this section are used to parse the optional argument to +% |\bitbox| or |\wordbox|, which is some subset of $\{ |l|, |r|, |t|, +% |b|, |L|, |R|, |T|, |B| \}$. Lowercase letters display the left, +% right, top, or bottom side of a box; uppercase letters inhibit the +% display. The default is not to display any sides, but an uppercase +% letter can negate the effect of a prior lowercase letter. +% +% \begin{macro}{\ifbitbox@top} +% \begin{macro}{\ifbitbox@bottom} +% \begin{macro}{\ifbitbox@left} +% \begin{macro}{\ifbitbox@right} +% These macros are set to \textsc{true} if we're to draw the +% corresponding edge on the subsequent |\bitbox| or |\wordbox|. +% \begin{macrocode} +\newif\ifbitbox@top +\newif\ifbitbox@bottom +\newif\ifbitbox@left +\newif\ifbitbox@right +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\bf@parse@bitbox@arg} +% This main parsing macro merely resets the above conditionals and +% calls a helper function, |\bf@parse@bitbox@sides|. +% \begin{macrocode} +\def\bf@parse@bitbox@arg#1{% + \bitbox@topfalse + \bitbox@bottomfalse + \bitbox@leftfalse + \bitbox@rightfalse + \bf@parse@bitbox@sides#1X} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\bf@parse@bitbox@sides} +% The helper function for |\bf@parse@bitbox@arg| parses a single letter, +% sets the appropriate conditional to \textsc{true}, and calls itself +% tail-recursively until it sees an~``|X|''. +% \begin{macrocode} +\def\bf@parse@bitbox@sides#1{% + \ifx#1X% + \else + \ifx#1t% + \bitbox@toptrue + \else + \ifx#1b% + \bitbox@bottomtrue + \else + \ifx#1l% + \bitbox@lefttrue + \else + \ifx#1r% + \bitbox@righttrue + \else + \ifx#1T% + \bitbox@topfalse + \else + \ifx#1B% + \bitbox@bottomfalse + \else + \ifx#1L% + \bitbox@leftfalse + \else + \ifx#1R% + \bitbox@rightfalse + \else + \PackageWarning{bytefield}{Unrecognized box side `#1'}% + \fi + \fi + \fi + \fi + \fi + \fi + \fi + \fi + \expandafter\bf@parse@bitbox@sides + \fi} +% \end{macrocode} +% \end{macro} +% +% \subsection{Skipped words} +% +% \begin{macro}{\units@high} +% This is the height of each diagonal line in the |\skippedwords| +% graphic. Note that |\units@high|~$=$ |\units@tall|~$-$ +% \textit{optional argument to} |\skippedwords|. +% \begin{macrocode} +\newlength{\units@high} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\skippedwords} +% \usermacro +% Output a fancy graphic representing skipped words. The optional argument +% is the vertical space between the two diagonal lines (default: |2ex|). +% \begin{macrocode} +\DeclareRobustCommand{\skippedwords}[1][2ex]{% + \setlength{\units@wide}{\bf@bitwidth * \bits@wide}% + \setlength{\units@high}{1pt * \ratio{\units@wide}{6.0pt}}% + \setlength{\units@tall}{#1 + \units@high}% + \edef\num@wide{\strip@pt\units@wide}% + \edef\num@tall{\strip@pt\units@tall}% + \edef\num@high{\strip@pt\units@high}% + \begin{picture}(\num@wide,\num@tall) + \put(0,\num@tall){\line(6,-1){\num@wide}} + \put(\num@wide,0){\line(-6,1){\num@wide}} + \put(0,0){\line(0,1){\num@high}} + \put(\num@wide,\num@tall){\line(0,-1){\num@high}} + \end{picture}% + \ifcounting@words + \inc@bytefield@height{\unitlength * \real{\num@tall}}% + \global\counting@wordsfalse + \fi} +% \end{macrocode} +% \end{macro} +% +% \subsection{Bit-position labels} +% +% \begin{macro}{\bf@bit@endianness} +% \pkgname{bytefield} can label bit headers in either little-endian ($0, +% 1, 2,~\ldots, N-1$) or big-endian ($N-1, N-2, N-3,~\ldots, 0$) fashion. +% The |\bf@bit@endianness| macro specifies which to use, either ``|l|'' +% for little-endian (the default) or ``|b|'' for big-endian. +% \begin{macrocode} +\newcommand*{\bf@bit@endianness}{l} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\bf@first@bit} +% Normally, bits are numbered starting from zero. However, +% |\bf@first@bit| can be altered (usually locally) to begin numbering +% from a different value. +% \begin{macrocode} +\newcommand*{\bf@first@bit}{0} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\bitheader} +% \usermacro +% Output a header of numbered bit positions. The optional argument (|#1|) +% is ``|l|'' for little-endian (default) or ``|b|'' for big-endian. +% The required argument (|#2|) is a list of bit positions to label. +% It is composed of comma-separated ranges of numbers, for example, +% ``|0-31|'', ``|0,7-8,15-16,23-24,31|'', or even something odd like +% ``|0-7,15-23|''. Ranges must be specified in increasing order; use the +% \optname{lsb} option to reverse the labels' direction. +% \changes{v2.1}{2011/06/17}{Changed the optional argument to accept +% \meta{key}!=\meta{value} pairs instead of just ``\texttt{l}'' and +% ``\texttt{b}''} +% \begin{macrocode} +\DeclareRobustCommand{\bitheader}[2][]{% + \bf@parse@bitbox@arg{lrtb}% + \setlength{\units@wide}{\bf@bitwidth * \bits@wide}% + \setlength{\units@tall}{\heightof{\bf@bitformatting{1234567890}}}% + \setlength{\units@high}{\units@tall * -1}% + \bf@process@bitheader@opts{#1}% + \begin{picture}(\strip@pt\units@wide,\strip@pt\units@tall)% + (0,\strip@pt\units@high) + \bf@parse@range@list#2,X, + \end{picture}% + \ifcounting@words + \inc@bytefield@height{\unitlength * \real{\strip@pt\units@tall}}% + \global\counting@wordsfalse + \fi + \ignorespaces} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\bf@parse@range@list} +% This is helper function~\#1 for |\bitheader|. It parses a +% comma-separated list of ranges, calling |\bf@parse@range| on each +% range. +% \changes{v1.1}{2002/06/24}{Bug fix: Swapped order of arguments to +% \texttt{\string\bslash\space ifx} test (suggested by Hans-Joachim +% Widmaier)} +% \begin{macrocode} +\def\bf@parse@range@list#1,{% + \ifx X#1 + \else + \bf@parse@range#1-#1-#1\relax + \expandafter\bf@parse@range@list + \fi} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\header@xpos} +% \begin{macro}{header@val} +% \begin{macro}{max@header@val} +% Define some miscellaneous variables to be used internally by +% |\bf@parse@range|: $x$~position of header, current label to output, +% and maximum label to output ($+ 1$). +% \begin{macrocode} +\newlength{\header@xpos} +\newcounter{header@val} +\newcounter{max@header@val} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\bf@parse@range} +% This is helper function~\#2 for |\bitheader|. It parses a +% hyphen-separated pair of numbers (or a single number) and displays the +% number at the correct bit position. +% \changes{v2.1}{2011/06/16}{Added code due to Renaud Pacalet for shifting +% the bit header by a distance corresponding to +% \texttt{\string\string\string\bf@first@bit}, used for typesetting +% registers split across rows} +% \begin{macrocode} +\def\bf@parse@range#1-#2-#3\relax{% + \setcounter{header@val}{#1} + \setcounter{max@header@val}{#2 + 1} + \loop + \ifnum\value{header@val}<\value{max@header@val}% + \if\bf@bit@endianness b% + \setlength{\header@xpos}{% + \bf@bitwidth * (\bits@wide - \value{header@val} + \bf@first@bit - 1)}% + \else + \setlength{\header@xpos}{\bf@bitwidth * (\value{header@val} - \bf@first@bit)}% + \fi + \put(\strip@pt\header@xpos,0){% + \makebox(\strip@pt\bf@bitwidth,\strip@pt\units@tall){% + \bf@bitformatting{\theheader@val}}} + \addtocounter{header@val}{1} + \repeat} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\bf@process@bitheader@opts} +% \begin{macro}{\KV@bytefield@l} +% \begin{macro}{\KV@bytefield@b} +% \begin{macro}{\KV@bytefield@l@default} +% \begin{macro}{\KV@bytefield@b@default} +% This is helper function~\#3 for |\bitheader|. It processes the +% optional argument to |\bitheader|. +% \begin{macrocode} +\newcommand*{\bf@process@bitheader@opts}{% + \let\KV@bytefield@l=\KV@bitheader@l + \let\KV@bytefield@b=\KV@bitheader@b + \let\KV@bytefield@l@default=\KV@bitheader@l@default + \let\KV@bytefield@b@default=\KV@bitheader@b@default + \setkeys{bytefield}% +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\KV@bitheader@l} +% \begin{macro}{\KV@bitheader@b} +% For backwards compatibility we also accept the (now deprecated) |l| as +% a synonym for |endianness=little| and |b| as a synonym for +% |endianness=big|. A typical document will specify an |endianness| +% option not as an argument to |\bitheader| but rather as a package +% option that applies to the entire document. If the \optname{compat1} +% option was provided to \pkgname{bytefield} (determined below by the +% existence of the |\curlyshrinkage| control word), we suppress the +% deprecation warning message. +% \begin{macrocode} +\define@key{bitheader}{l}[true]{% + \expandafter\ifx\csname curlyshrinkage\endcsname\relax + \PackageWarning{bytefield}{% + The "l" argument to \protect\bitheader\space is deprecated.\MessageBreak + Instead, please use "endianness=little", which can\MessageBreak + even be declared globally for the entire document.\MessageBreak + This warning occurred}% + \fi + \def\bf@bit@endianness{l}% +} +\define@key{bitheader}{b}[true]{% + \expandafter\ifx\csname curlyshrinkage\endcsname\relax + \PackageWarning{bytefield}{% + The "b" argument to \protect\bitheader\space is deprecated.\MessageBreak + Instead, please use "endianness=big", which can\MessageBreak + even be declared globally for the entire document.\MessageBreak + This warning occurred}% + \fi + \def\bf@bit@endianness{b}% +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% +% \subsection{Word labels} +% +% \subsubsection{Curly-brace manipulation} +% +% \begin{macro}{\bf@leftcurlyshrinkage} +% \begin{macro}{\bf@rightcurlyshrinkage} +% Reduce the height of a left (right) curly brace by +% |\bf@leftcurlyshrinkage| (|\bf@rightcurlyshrinkage|) so its ends don't +% overlap whatever is above or below it. The default value (5\,pt.) was +% determined empirically and shouldn't need to be changed. However, on +% the off-chance the user employs a math font with very different curly +% braces from Computer Modern's, |\bf@leftcurlyshrinkage| and +% |\bf@rightcurlyshrinkage| can be modified. +% \begin{macrocode} +\def\bf@leftcurlyshrinkage{5pt} +\def\bf@rightcurlyshrinkage{5pt} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\bf@leftcurlyspace} +% \begin{macro}{\bf@rightcurlyspace} +% \begin{macro}{\bf@leftlabelspace} +% \begin{macro}{\bf@rightlabelspace} +% Define the amount of space to insert before a curly brace and before a +% word label (i.e.,~after a curly brace). +% \begin{macrocode} +\def\bf@leftcurlyspace{1ex} +\def\bf@rightcurlyspace{1ex} +\def\bf@leftlabelspace{0.5ex} +\def\bf@rightlabelspace{0.5ex} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\bf@leftcurly} +% \begin{macro}{\bf@rightcurly} +% Define the symbols to use as left and right curly braces. These +% symbols must be extensible math symbols (i.e.,~they will immediately +% follow |\left| or |\right| in math mode). +% \begin{macrocode} +\let\bf@leftcurly=\{ +\let\bf@rightcurly=\} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\curly@box} +% Define a box in which to temporarily store formatted curly braces. +% \changes{v1.2}{2004/06/14}{Bug fix: Defined \cs{curly@box} globally +% (suggested by Stefan Ulrich)} +% \begin{macrocode} +\newbox{\curly@box} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\store@rcurly} +% \begin{macro}{\curly@height} +% \begin{macro}{\half@curly@height} +% \begin{macro}{\curly@shift} +% \begin{macro}{\old@axis} +% Store a ``\}'' that's |#2| tall in box |#1|. +% The only unintuitive thing here is that we have to redefine +% |\fontdimen22|---axis height---to~0\,pt.\ before typesetting the curly +% brace. Otherwise, the brace would be vertically off-center by a few +% points. When we're finished, we reset it back to its old value. +% \begin{macrocode} +\def\store@rcurly#1#2{% + \begingroup + \bf@newdimen\curly@height + \setlength{\curly@height}{#2 - \bf@rightcurlyshrinkage}% + \bf@newdimen\half@curly@height + \setlength{\half@curly@height}{0.5\curly@height}% + \bf@newdimen\curly@shift + \setlength{\curly@shift}{\bf@rightcurlyshrinkage}% + \setlength{\curly@shift}{\half@curly@height + 0.5\curly@shift}% + \global\sbox{#1}{\raisebox{\curly@shift}{% + $\xdef\old@axis{\the\fontdimen22\textfont2}$% + $\fontdimen22\textfont2=0pt% + \left. + \vrule height\half@curly@height + width 0pt + depth\half@curly@height\right\bf@rightcurly$% + $\fontdimen22\textfont2=\old@axis$}}% + \endgroup +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\store@lcurly} +% \begin{macro}{\curly@height} +% \begin{macro}{\half@curly@height} +% \begin{macro}{\curly@shift} +% These are the same as |\store@rcurly|, etc.\ but using a ``\{'' +% instead of a ``\}''. +% \begin{macrocode} +\def\store@lcurly#1#2{% + \begingroup + \bf@newdimen\curly@height + \setlength{\curly@height}{#2 - \bf@leftcurlyshrinkage}% + \bf@newdimen\half@curly@height + \setlength{\half@curly@height}{0.5\curly@height}% + \bf@newdimen\curly@shift + \setlength{\curly@shift}{\bf@leftcurlyshrinkage}% + \setlength{\curly@shift}{\half@curly@height + 0.5\curly@shift}% + \global\sbox{#1}{\raisebox{\curly@shift}{% + $\xdef\old@axis{\the\fontdimen22\textfont2}$% + $\fontdimen22\textfont2=0pt% + \left\bf@leftcurly + \vrule height\half@curly@height + width 0pt + depth\half@curly@height\right.$% + $\fontdimen22\textfont2=\old@axis$}}% + \endgroup +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \subsubsection{Right-side labels} +% +% \begin{macro}{\show@wordlabelr} +% This macro is output in the third column of every row of the +% |\ialign|ed bytefield table. It's normally a no-op, but +% |\end{rightwordgroup}| defines it to output the word label and then +% reset itself to a no-op. +% \begin{macrocode} +\def\show@wordlabelr{} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\wordlabelr@start} +% \begin{macro}{\wordlabelr@end} +% Declare the starting and ending height (in points) of the set of rows +% to be labeled on the right. +% \begin{macrocode} +\newlength{\wordlabelr@start} +\newlength{\wordlabelr@end} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{environment}{rightwordgroup} +% \usermacro +% Label the words defined between |\begin{rightwordgroup}| and |\end{rightwordgroup}| +% on the right side of the bit field. +% The argument is the text of the label. The label is typeset to the +% right of a large curly brace, which groups the words together. +% \begin{macrocode} +\newenvironment{rightwordgroup}[1]{% +% \end{macrocode} +% We begin by ending the group that |\begin{rightwordgroup}| created. This +% lets the |rightwordgroup| environment span rows (because we're technically +% no longer within the environment). +% \begin{macrocode} + \endgroup +% \end{macrocode} +% \begin{macro}{\wordlabelr@start} +% \begin{macro}{\wordlabelr@text} +% |\begin{rightwordgroup}| merely stores the starting height in |\wordlabelr@start| +% and the user-supplied text in |\wordlabelr@text|. |\end{rightwordgroup}| +% does most of the work. +% \begin{macrocode} + \global\wordlabelr@start=\bytefield@height + \gdef\wordlabelr@text{#1}% + \ignorespaces +}{% +% \end{macrocode} +% \end{macro} +% \end{macro} +% \begin{macro}{\wordlabelr@end} +% Because we already ended the group that |\begin{rightwordgroup}| created +% we now have to begin a group for |\end{rightwordgroup}| to end. +% \begin{macrocode} + \begingroup + \global\wordlabelr@end=\bytefield@height +% \end{macrocode} +% \end{macro} +% \begin{macro}{\show@wordlabelr} +% Redefine |\show@wordlabelr| to output |\bf@rightcurlyspace| space, +% followed by a large curly brace (in |\curlybox|), followed by +% |\bf@rightlabelspace| space, followed by the user's text (previously +% recorded in |\wordlabelr@text|). We typeset |\wordlabelr@text| within +% a |tabular| environment, so \LaTeX\ will calculate its width +% automatically. +% \begin{macrocode} + \gdef\show@wordlabelr{% + \sbox{\word@label@box}{% + \begin{tabular}[b]{@{}l@{}}\wordlabelr@text\end{tabular}}% + \settowidth{\label@box@width}{\usebox{\word@label@box}}% + \setlength{\label@box@height}{\wordlabelr@end-\wordlabelr@start}% + \store@rcurly{\curly@box}{\label@box@height}% + \bf@newdimen\total@box@width + \setlength{\total@box@width}{% + \bf@rightcurlyspace + + \widthof{\usebox{\curly@box}} + + \bf@rightlabelspace + + \label@box@width}% + \begin{picture}(\strip@pt\total@box@width,0) + \put(0,0){% + \hspace*{\bf@rightcurlyspace}% + \usebox{\curly@box}% + \hspace*{\bf@rightlabelspace}% + \makebox(\strip@pt\label@box@width,\strip@pt\label@box@height){% + \usebox{\word@label@box}}} + \end{picture}% +% \end{macrocode} +% The last thing |\show@wordlabelr| does is redefine itself back to a no-op. +% \begin{macrocode} + \gdef\show@wordlabelr{}}% +% \end{macrocode} +% \end{macro} +% \begin{macro}{\@currenvir} +% Because of our meddling with |\begingroup| and |\endgroup|, the +% current environment is all messed up. We therefore force the +% |\end{rightwordgroup}| to succeed, even if it doesn't match the preceding +% |\begin|. +% \begin{macrocode} + \def\@currenvir{rightwordgroup}% + \ignorespaces +} +% \end{macrocode} +% \end{macro} +% \end{environment} +% +% \subsubsection{Left-side labels} +% +% \begin{macro}{\wordlabell@start} +% \begin{macro}{\wordlabell@end} +% Declare the starting and ending height (in points) of the set of rows +% to be labeled on the left. +% \begin{macrocode} +\newlength{\wordlabell@start} +\newlength{\wordlabell@end} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\total@box@width} +% Declare the total width of the next label to typeset on the left of +% the bit field, that is, the aggregate width of the text box, curly +% brace, and spaces on either side of the curly brace. +% \begin{macrocode} +\newlength{\total@lbox@width} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\make@lspace} +% This macro is output in the first column of every row of the +% |\ialign|ed bytefield table. It's normally a no-op, but +% |\begin{leftwordgroup}| defines it to output enough space for the next word +% label and then reset itself to a no-op. +% \begin{macrocode} +\gdef\make@lspace{} +% \end{macrocode} +% \end{macro} +% +% \begin{environment}{leftwordgroup} +% \usermacro +% This environment is essentially the same as the |rightwordgroup| +% environment but puts the label on the left. However, the following +% code is not symmetric to that of |rightwordgroup|. The problem is that we +% encounter |\begin{leftwordgroup}| after entering the second +% (i.e.,~figure) column, which doesn't give us a chance to reserve space +% in the first (i.e.,~left label) column. When we reach the +% |\end{leftwordgroup}|, we know the height of the group of words we wish +% to label. However, if we try to label the words in the subsequent +% first column, we won't know the vertical offset from the ``cursor'' at +% which to start drawing the label, because we can't know the height of +% the subsequent row until we reach the second +% column.\footnote{Question: Is there a way to push the label up to the +% \emph{top} of the subsequent row, perhaps with +% \texttt{\string\vfill}?} +% +% Our solution is to allocate space for the box the next time we enter a +% first column. As long as space is eventually allocated, the column +% will expand to fit that space. |\end{leftwordgroup}| outputs the label +% immediately. Even though |\end{leftwordgroup}| is called at the end of +% the \emph{second} column, it |\put|s the label at a sufficiently +% negative $x$ location for it to overlap the first column. Because +% there will eventually be enough space to accomodate the label, we know +% that the label won't overlap the bit field or extend beyond the bit-field +% boundaries. +% \begin{macrocode} +\newenvironment{leftwordgroup}[1]{% +% \end{macrocode} +% We begin by ending the group that |\begin{rightwordgroup}| created. This +% lets the |leftwordgroup| environment span rows (because we're technically +% no longer within the environment). +% \begin{macrocode} + \endgroup +% \end{macrocode} +% \begin{macro}{\wordlabell@start} +% \begin{macro}{\wordlabell@text} +% We store the starting height and label text, which are needed by the +% |\end{leftwordgroup}|. +% \begin{macrocode} + \global\wordlabell@start=\bytefield@height + \gdef\wordlabell@text{#1}% +% \end{macrocode} +% \end{macro} +% \end{macro} +% Next, we typeset a draft version of the label into |\word@label@box|, +% which we measure (into |\total@lbox@width|) and then discard. +% We can't typeset the final version of the label until we reach the +% |\end{leftwordgroup}|, because that's when we learn the height of the +% word group. Without knowing the height of the word group, we don't +% how how big to make the curly brace. In the scratch version, we make +% the curly brace 5\,cm.~tall. This should be more than large enough to +% reach the maximum curly-brace width, which is all we really care about +% at this point. +% \begin{macrocode} + \sbox{\word@label@box}{% + \begin{tabular}[b]{@{}l@{}}\wordlabell@text\end{tabular}}% + \settowidth{\label@box@width}{\usebox{\word@label@box}}% + \store@lcurly{\curly@box}{5cm}% + \setlength{\total@lbox@width}{% + \bf@leftcurlyspace + + \widthof{\usebox{\curly@box}} + + \bf@leftlabelspace + + \label@box@width}% + \global\total@lbox@width=\total@lbox@width +% \end{macrocode} +% \begin{macro}{\make@lspace} +% Now we know how wide the box is going to be (unless, of course, +% the user is using some weird math font that scales the width of a curly +% brace proportionally to its height). So we redefine |\make@lspace| to +% output |\total@lbox@width|'s worth of space and then redefine itself +% back to a no-op. +% \begin{macrocode} + \gdef\make@lspace{% + \hspace*{\total@lbox@width}% + \gdef\make@lspace{}}% + \ignorespaces +}{% +% \end{macrocode} +% \end{macro} +% Because we already ended the group that |\begin{leftwordgroup}| created +% we have to start the |\end{leftwordgroup}| by beginning a group for +% |\end{leftwordgroup}| to end. +% \begin{macrocode} + \begingroup +% \end{macrocode} +% The |\end{leftwordgroup}| code is comparatively straightforward. We +% calculate the final height of the word group, and then output the +% label text, followed by |\bf@leftlabelspace| space, followed by a +% curly brace (now that we know how tall it's supposed to be), followed +% by |\bf@leftcurlyspace| space. The trick, as described earlier, is +% that we typeset the entire label in the second column, but in a $0 +% \times 0$ |picture| environment and with a negative horizontal offset +% (|\starting@point|), thereby making it overlap the first column. +% \begin{macrocode} + \global\wordlabell@end=\bytefield@height + \bf@newdimen\starting@point + \setlength{\starting@point}{% + -\total@lbox@width - \bf@bitwidth*\bits@wide}% + \sbox{\word@label@box}{% + \begin{tabular}[b]{@{}l@{}}\wordlabell@text\end{tabular}}% + \settowidth{\label@box@width}{\usebox{\word@label@box}}% + \setlength{\label@box@height}{\wordlabell@end-\wordlabell@start}% + \store@lcurly{\curly@box}{\label@box@height}% + \begin{picture}(0,0) + \put(\strip@pt\starting@point,0){% + \makebox(\strip@pt\label@box@width,\strip@pt\label@box@height){% + \usebox{\word@label@box}}% + \hspace*{\bf@leftlabelspace}% + \usebox{\curly@box}% + \hspace*{\bf@leftcurlyspace}} + \end{picture}% +% \end{macrocode} +% \begin{macro}{\@currenvir} +% Because of our meddling with |\begingroup| and |\endgroup|, the +% current environment is all messed up. We therefore force the +% |\end{leftwordgroup}| to succeed, even if it doesn't match the preceding +% |\begin|. +% \begin{macrocode} + \def\@currenvir{leftwordgroup}% + \ignorespaces} +% \end{macrocode} +% \end{macro} +% \end{environment} +% +% \subsubsection{Scratch space} +% +% \begin{macro}{\label@box@width} +% \begin{macro}{\label@box@height} +% \begin{macro}{\word@label@box} +% Declare some scratch storage for the width, height, and contents of +% the word label we're about to output. +% \begin{macrocode} +\newlength{\label@box@width} +\newlength{\label@box@height} +\newsavebox{\word@label@box} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \subsection{Compatibility mode} +% +% \begin{macro}{\bf@enter@compatibility@mode@i} +% \pkgname{bytefield}'s interface changed substantially with the move to +% version~2.0. To give version~1.\textit{x} users a quick way to build +% their old documents, we provide a version~1.\textit{x} compatibility +% mode. We don't enable this by default because it exposes a number of +% extra length registers (a precious resource) and because we want to +% encourage users to migrate to the new interface. +% \begin{macrocode} +\newcommand{\bf@enter@compatibility@mode@i}{% +% \end{macrocode} +% \begin{macro}{\bitwidth} +% \begin{macro}{\byteheight} +% \begin{macro}{\curlyspace} +% \begin{macro}{\labelspace} +% \begin{macro}{\curlyshrinkage} +% Define a handful of lengths that the user was allowed to |\setlength| +% explicitly in \pkgname{bytefield}~1.\textit{x}. +% \begin{macrocode} + \PackageInfo{bytefield}{Entering version 1 compatibility mode}% + \newlength{\bitwidth}% + \newlength{\byteheight}% + \newlength{\curlyspace}% + \newlength{\labelspace}% + \newlength{\curlyshrinkage}% +% \end{macrocode} +% \begin{macrocode} + \settowidth{\bitwidth}{\tiny 99i}% + \setlength{\byteheight}{4ex}% + \setlength{\curlyspace}{1ex}% + \setlength{\labelspace}{0.5ex}% + \setlength{\curlyshrinkage}{5pt}% +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \begin{macro}{\newbytefield} +% \begin{macro}{\endnewbytefield} +% \begin{environment}{bytefield} +% Redefine the |bytefield| environment in terms of the existing +% (new-interface) |bytefield| environment. The difference is that the +% redefinition utilizes all of the preceding lengths. +% \begin{macrocode} + \let\newbytefield=\bytefield + \let\endnewbytefield=\endbytefield + \renewenvironment{bytefield}[1]{% + \begin{newbytefield}[% + bitwidth=\bitwidth, + bitheight=\byteheight, + curlyspace=\curlyspace, + labelspace=\labelspace, + curlyshrinkage=\curlyshrinkage]{##1}% + }{% + \end{newbytefield}% + } +% \end{macrocode} +% \end{environment} +% \end{macro} +% \end{macro} +% \begin{macro}{\wordgroupr} +% \begin{macro}{\endwordgroupr} +% \begin{macro}{\wordgroupl} +% \begin{macro}{\endwordgroupl} +% Define |\wordgroupr|, |\endwordgroupr|, |\wordgroupl|, and +% |\endwordgroupl| in terms of the new |rightwordgroup| and +% |leftwordgroup| environments. +% \begin{macrocode} + \def\wordgroupr{\begin{rightwordgroup}} + \def\endwordgroupr{\end{rightwordgroup}} + \def\wordgroupl{\begin{leftwordgroup}} + \def\endwordgroupl{\end{leftwordgroup}} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\bytefieldsetup} +% Disable |\bytefieldsetup| in compatibility mode because it doesn't +% work as expected. (Every use of the compatibility-mode |bytefield| +% environment overwrites all of the figure-formatting values.) +% \begin{macrocode} + \renewcommand{\bytefieldsetup}[1]{% + \PackageError{bytefield}{% + The \protect\bytefieldsetup\space macro is not available in\MessageBreak + version 1 compatibility mode% + }{% + Remove [compat1] from the \protect\usepackage{bytefield} line to + make \protect\bytefieldsetup\MessageBreak + available to this document.\space\space (The document may also need + to be modified to use\MessageBreak + the new bytefield interface.) + }% + }% +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\wordgroupr} +% \begin{macro}{\endwordgroupr} +% \begin{macro}{\wordgroupl} +% \begin{macro}{\endwordgroupl} +% Issue a helpful error message for the commands that were removed in +% \pkgname{bytefield}~v2.0. While this won't help users whose first +% invalid action is to modify a no-longer-extant length register such as +% |\bitwidth| or |\byteheight|, it may benefit at least a few users who +% didn't realize that the \pkgname{bytefield} interface has changed +% substantially with version~2.0. +% \begin{macrocode} +\newcommand{\wordgroupr}{% + \PackageError{bytefield}{% + Macros \protect\wordgroupr, \protect\wordgroupl, \protect\endwordgroupr, + \MessageBreak + and \protect\endwordgroupl\space no longer exist% + }{% + Starting with version 2.0, bytefield uses \protect\begin{wordgroupr}... + \MessageBreak + \protect\end{wordgroupr} and \protect\begin{wordgroupl}...% + \protect\end{wordgroupl}\MessageBreak + to specify word groups and a new \protect\bytefieldsetup\space macro to + \MessageBreak + change bytefield's various formatting parameters.% + }% +} +\let\endwordgroupr=\wordgroupr +\let\wordgroupl=\wordgroupr +\let\endwordgroupl=\wordgroupr +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% \subsection{Option processing} +% +% We use the \textsf{keyval} package to handle option processing. +% Because all of \pkgname{bytefield}'s options have local impact, options +% can be specified either as package arguments or through the use of the +% |\bytefieldsetup| macro. +% +% \begin{macro}{\KV@bytefield@bitwidth} +% \begin{macro}{\bf@bw@arg} +% \begin{macro}{\bf@auto} +% Specify the width of a bit number in the bit header. If the special +% value ``|auto|'' is given, set the width to the width of a formatted +% ``|99i|''. +% \begin{macrocode} +\define@key{bytefield}{bitwidth}{% + \def\bf@bw@arg{#1}% + \def\bf@auto{auto}% + \ifx\bf@bw@arg\bf@auto + \settowidth{\bf@bitwidth}{\bf@bitformatting{99i}}% + \else + \setlength{\bf@bitwidth}{#1}% + \fi +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\KV@bytefield@bf@bitheight} +% Specify the height of a bit in a |\bitbox| or |\wordbox|. +% \begin{macrocode} +\define@key{bytefield}{bitheight}{\setlength{\bf@bitheight}{#1}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\KV@bytefield@bitformatting} +% Specify the style of a bit number in the bit header. This should be +% passed an expression that takes either one argument (e.g.,~|\textit|) +% or no arguments (e.g.,~|{\small\bfseries}|). +% \begin{macrocode} +\define@key{bytefield}{bitformatting}{\def\bf@bitformatting{#1}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\KV@bytefield@boxformatting} +% Specify a style to be applied to the contents of every bit box and +% word box. This should be passed an expression that takes either one +% argument (e.g.,~|\textit|) or no arguments +% (e.g.,~|{\small\bfseries}|). +% \begin{macrocode} +\define@key{bytefield}{boxformatting}{\def\bf@boxformatting{#1}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\KV@bytefield@leftcurly} +% \begin{macro}{\KV@bytefield@rightcurly} +% Specify the symbol to use for bracketing a left or right word group. +% This must be an extensible math delimiter (i.e.,~something that can +% immediately follow |\left| or |\right| in math mode). +% \begin{macrocode} +\define@key{bytefield}{leftcurly}{\def\bf@leftcurly{#1}} +\define@key{bytefield}{rightcurly}{\def\bf@rightcurly{#1}} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\KV@bytefield@leftcurlyspace} +% \begin{macro}{\KV@bytefield@rightcurlyspace} +% \begin{macro}{\KV@bytefield@curlyspace} +% Specify the amount of space between the bit fields in a word group and +% the adjacent left or right curly brace. The \optname{curlyspace} +% option is a shortcut that puts the same space before both left and +% right curly braces. +% \begin{macrocode} +\define@key{bytefield}{leftcurlyspace}{\def\bf@leftcurlyspace{#1}} +\define@key{bytefield}{rightcurlyspace}{\def\bf@rightcurlyspace{#1}} +\define@key{bytefield}{curlyspace}{% + \def\bf@leftcurlyspace{#1}% + \def\bf@rightcurlyspace{#1}% +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\KV@bytefield@leftlabelspace} +% \begin{macro}{\KV@bytefield@rightlabelspace} +% \begin{macro}{\KV@bytefield@labelspace} +% Specify the amount of space between a left or right word group's curly +% brace and the associated label text. The |labelspace| option is a +% shortcut that puts the same space after both left and right curly +% braces. +% \begin{macrocode} +\define@key{bytefield}{leftlabelspace}{\def\bf@leftlabelspace{#1}} +\define@key{bytefield}{rightlabelspace}{\def\bf@rightlabelspace{#1}} +\define@key{bytefield}{labelspace}{% + \def\bf@leftlabelspace{#1}% + \def\bf@rightlabelspace{#1}% +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\KV@bytefield@leftcurlyshrinkage} +% \begin{macro}{\KV@bytefield@rightcurlyshrinkage} +% \begin{macro}{\KV@bytefield@curlyshrinkage} +% Specify the number of points by which to reduce the height of a curly +% brace (left, right, or both) so its ends don't overlap whatever's +% above or below it. +% \begin{macrocode} +\define@key{bytefield}{leftcurlyshrinkage}{\def\bf@leftcurlyshrinkage{#1}} +\define@key{bytefield}{rightcurlyshrinkage}{\def\bf@rightcurlyshrinkage{#1}} +\define@key{bytefield}{curlyshrinkage}{% + \def\bf@leftcurlyshrinkage{#1}% + \def\bf@rightcurlyshrinkage{#1}% +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\KV@bytefield@endianness} +% \begin{macro}{\bf@parse@endianness} +% Set the default endianness to either little endian or big endian. +% \begin{macrocode} +\define@key{bytefield}{endianness}{\bf@parse@endianness{#1}} +% \end{macrocode} +% \begin{macrocode} +\newcommand{\bf@parse@endianness}[1]{% + \def\bf@little{little}% + \def\bf@big{big}% + \def\bf@arg{#1}% + \ifx\bf@arg\bf@little + \def\bf@bit@endianness{l}% + \else + \ifx\bf@arg\bf@big + \def\bf@bit@endianness{b}% + \else + \PackageError{bytefield}{% + Invalid argument "#1" to the endianness option% + }{% + The endianness option must be set to either "little" or + "big".\MessageBreak + Please specify either endianness=little or endianness=big. + }% + \fi + \fi +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\KV@bytefield@lsb} +% Specify a numerical value for the least significant bit of a word. +% \begin{macrocode} +\define@key{bytefield}{lsb}{\def\bf@first@bit{#1}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\bytefieldsetup} +% \usermacro +% \changes{v2.0}{2011/01/18}{Introduced this macro to provide a more +% convenient way of configuring \pkgname{bytefield}'s parameters} +% \begin{macro}{\bf@bytefieldsetup} +% Reconfigure values for various \pkgname{bytefield} parameters. +% Internally to the package we use the |\bf@bytefieldsetup| macro +% instead of |\bytefieldsetup|. This enables us to redefine +% |\bytefieldsetup| when entering version~1 compatibility mode without +% impacting the rest of \pkgname{bytefield}. +% \begin{macrocode} +\newcommand{\bf@bytefieldsetup}{\setkeys{bytefield}} +\let\bytefieldsetup=\bf@bytefieldsetup +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% We define only a single option that can be used only as a package +% option, not as an argument to |\bytefieldsetup|: |compat1| instructs +% \pkgname{bytefield} to enter version~1 compatibility mode---at the +% cost of a number of additional length registers and the inability to +% specify parameters in the argument to the |bytefield| environment. +% \begin{macrocode} +\DeclareOption{compat1}{\bf@enter@compatibility@mode@i} +% \end{macrocode} +% +% \begin{macro}{\bf@package@options} +% \begin{macro}{\next} +% We want to use |\bf@bytefieldsetup| to process \pkgname{bytefield} +% package options. Unfortunately, |\DeclareOption| doesn't handle +% \meta{key}=\meta{value} arguments. Hence, we use |\DeclareOption*| to +% catch \emph{all} options, each of which it appends to +% |\bf@package@options|. |\bf@package@options| is passed to +% |\bf@bytefieldsetup| only at the beginning of the document so that the +% options it specifies (a)~can refer to ex-heights and (b)~override the +% default values, which are also set at the beginning of the document. +% \begin{macrocode} +\def\bf@package@options{} +\DeclareOption*{% + \edef\next{% + \noexpand\g@addto@macro\noexpand\bf@package@options{,\CurrentOption}% + }% + \next +} +\ProcessOptions\relax +\expandafter\bf@bytefieldsetup\expandafter{\bf@package@options} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \Finale +\endinput diff --git a/macros/latex/contrib/bytefield/bytefield.ins b/macros/latex/contrib/bytefield/bytefield.ins new file mode 100644 index 0000000000..37197a9ab0 --- /dev/null +++ b/macros/latex/contrib/bytefield/bytefield.ins @@ -0,0 +1,51 @@ +%% +%% Copyright (C) 2017 by Scott Pakin +%% +%% This file may be distributed and/or modified under the conditions of +%% the LaTeX Project Public License, either version 1.3a of this license +%% or (at your option) any later version. The latest version of this +%% license is in: +%% +%% http://www.latex-project.org/lppl.txt +%% +%% and version 1.3c or later is part of all distributions of LaTeX version +%% 2006/05/20 or later. +%% + +\input docstrip.tex +\keepsilent + +\usedir{tex/latex/bytefield} + +\preamble + +This is a generated file. + +Copyright (C) 2017 by Scott Pakin + +This file may be distributed and/or modified under the conditions of +the LaTeX Project Public License, either version 1.3a of this license +or (at your option) any later version. The latest version of this +license is in: + + http://www.latex-project.org/lppl.txt + +and version 1.3c or later is part of all distributions of LaTeX version +2006/05/20 or later. + +\endpreamble + +\generate{\file{bytefield.sty}{\from{bytefield.dtx}{package}}} + +\obeyspaces +\Msg{***************************************************************} +\Msg{* To finish the installation, move bytefield.sty into a *} +\Msg{* directory searched by TeX. *} +\Msg{* *} +\Msg{* To produce the documentation, run the file bytefield.dtx *} +\Msg{* through LaTeX. *} +\Msg{* *} +\Msg{* Happy TeXing! *} +\Msg{***************************************************************} + +\endbatchfile diff --git a/macros/latex/contrib/bytefield/bytefield.pdf b/macros/latex/contrib/bytefield/bytefield.pdf new file mode 100644 index 0000000000..3436fa27fa Binary files /dev/null and b/macros/latex/contrib/bytefield/bytefield.pdf differ -- cgit v1.2.3