BinaryStream

BinaryStream - a handy tool for working with binary data and the best replacement for pack()/unpack() with big list of features.

If you are looking for a convenient tool that would allow read and write binary data (whether existing or created by you format), you choose the correct library.

_BinaryStream_ - is a powerful tool for reading and writing binary files. It supports a variety of high-level data types and sometimes lets you forget that you are working with unstructured binary data.

With BinaryStream you can handle network packets, binary files, system protocols and other low-level data.

A more complex example, where the data were located in the following order:
- integer (int, 32 bit)
- float (float, 32 bit)
- flag byte (where each bit has its own value, 8 bits): first bit determines whether there after this byte written another data, 5-bit empty, and the last 2 bits of the data type:

- `0b00` - after this data recorded 1 character (char, 8 bits)
- `0b01` - after this data recorded 10 characters (string, 10 bytes)
- `0b10` - after this data time in unixtime format packaged in long integer (long, 64 bits)
- `0b11` - not used at this moment.

In order to read these data and those that depend on the flags, this example is suitable:

If you are reading a file in which such groups of data are repeated, you can save a group with a name, and then simply refer to it to read the next data. Let us introduce one more value for data_type: 0b11 - means that this is the last group of data in the file. An example would be:

And now imagine that we have moved to a new file format that is different from the previous one and has a certain mark in the beginning of the file, which will help to distinguish the new from the old format. For example, a new label is a sequence of characters 'A', 'S', 'C'. We need to check the label and if it is present, parse the file according to another scheme, and if it does not, use the old version of the processor. An example to illustrate this:

Example:
$flags = $s->readBits(['a' => 2, '_' => 5, 'b' => 3]);
If size of field (an array element value is 1, then this field will have true/false, if larger 1, then N consecutive bits will be combined in an integer.)
- char:
- readChar(): string(1)

| Method | Usage | Notes | |
|----------------------------|-------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---|
| readGroup($name) | $data = $s->readGroup('data'); | It allows you to read data from pre-saved configuration. To save a group under a new name, use the method saveGroup($name, array $fields) | |
| readGroup(array $fields) | $data = $s->readGroup(['i:field' => 32, 's:text' => 20]); | The fields are listed in the as array in which the keys determine the type and the name of the data fields, and values - dimension (understood as bytes for string and chars, and as bits for everything else). Supported: s, c, i, f and b. If the type is not specified, the field is perceived as a bit (or a few bits). The type and name are separated by a colon (:). | |

To save a group of data under one name, use saveGroup() method
`php
saveGroup($name, array $fields)
`
Create new group with few fields. If group with that name already exists, it replaces original group.

Comparation of bytes:
`php
compare($length, $bytes)
`
Compares $length bytes from current position with $bytes. Carrent position will not be changed. Returns true or false.

Caret moving:
To change the position of the cursor in the file use the following methods.

| Method | Usage | Notes |
|----------------|----------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------|
| go($offset) | $stream->go(-128); | It goes to the absolute position in the file. If you pass a negative value, the value of the cursor will be set to -$offset bytes from the end of the file. |
| go($mark) | $stream->go('FirstTag'); | It moves to the position where the $mark mark has been set. |
| skip($bytes) | $stream->skip(4); | Skip the following $bytes bytes. |

Current position testing:
`php
isEnd(): boolean
`
Returns true if cursor is at the end of file.

| Method | Usage | Notes |
|----------------------------|---------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| loadConfiguration($file | $stream->loadConfiguration('file_format.conf'); | Load configuration (byte order and data groups) from an external file. Configuration format - ini. To see an example of such a file, open the conf/mp3.conf file. |
| saveConfiguration($file) | $stream->saveConfiguration('file_format.conf') | Saves the current settings of byte order and all created data groups to an external file in ini-format. This configuration can be later restored from the file with the method loadConfiguration(). |

Advanced usage. Writing

If you are the one who needs to write data to binary files, you can use additional methods to do so.

Firstly, you need to open a file in one of the modes that allow writing of a file (by default, files are opened in read-only mode). For this when you create an object BinaryStream specify in second argument one of the following modes: