Я за третий вариант. Только, чуток, подкрутил бы:
## Код:
```
TYPE
  Writer* = RECORD
    offset*: INTEGER
  END;

  PROCEDURE (VAR this: Writer) WriteByte* (VAR dst: ARRAY OF BYTE; value: BYTE), NEW;
  BEGIN dst[this.offset] := value; INC(this.offset)
  END WriteByte;
```


wr.offset := 12;
wr.WriteByte(buffer, value1);
wr.WriteShort(buffer, value2);
wr.WriteInt(buffer, value3);

Модуль с таким Writer (и соответствующим Reader) можно потом повторно использовать для различных целей...