Skip to content

Commit f83bae7

Browse files
committed
Move interface classes, update README.md
1 parent 082318c commit f83bae7

18 files changed

Lines changed: 92 additions & 135 deletions

README.md

Lines changed: 72 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,10 @@ A pure PHP implementation of the [MessagePack](https://msgpack.org/) serializati
2626
* [Packing options](#packing-options)
2727
* [Unpacking](#unpacking)
2828
* [Unpacking options](#unpacking-options)
29-
* [Extensions](#extensions)
30-
* [Type transformers](#type-transformers)
29+
* [Custom types](#custom-types)
30+
* [Type objects](#type-objects)
31+
* [Type transformers](#type-transformers)
32+
* [Extensions](#extensions)
3133
* [Exceptions](#exceptions)
3234
* [Tests](#tests)
3335
* [Fuzzing](#fuzzing)
@@ -108,7 +110,7 @@ $packer->packMap(['a' => 1]); // MP map
108110
$packer->packExt(1, "\xaa"); // MP ext
109111
```
110112

111-
> *Check the ["Type transformers"](#type-transformers) section below on how to pack custom types.*
113+
> *Check the ["Custom types"](#custom-types) section below on how to pack custom types.*
112114
113115

114116
#### Packing options
@@ -135,8 +137,9 @@ the packing process (defaults are in bold):
135137
> UTF-8 strings or/and associative arrays), you can eliminate this overhead by
136138
> forcing the packer to use the appropriate type, which will save it from running
137139
> the auto-detection routine. Another option is to explicitly specify the value
138-
> type. The library provides 2 auxiliary classes for this, `Map` and `Bin`.
139-
> Check the ["Type transformers"](#type-transformers) section below for details.*
140+
> type. The library provides 2 auxiliary classes for this, [Map](src/Type/Map.php)
141+
> and [Bin](src/Type/Bin.php). Check the ["Custom types"](#custom-types) section
142+
> below for details.*
140143
141144
Examples:
142145

@@ -180,7 +183,8 @@ $value = MessagePack::unpack($packed);
180183

181184
If the packed data is received in chunks (e.g. when reading from a stream),
182185
use the `tryUnpack` method, which attempts to unpack data and returns an array
183-
of unpacked messages (if any) instead of throwing an `InsufficientDataException`:
186+
of unpacked messages (if any) instead of throwing
187+
an [InsufficientDataException](src/Exception/InsufficientDataException.php):
184188

185189
```php
186190
while ($chunk = ...) {
@@ -284,120 +288,65 @@ var_dump($unpacker->unpack()); // object(Decimal\Decimal) {...}
284288
```
285289

286290

287-
### Extensions
291+
### Custom types
288292

289-
The `Ext` class is used to represent [extension types](https://github.com/msgpack/msgpack/blob/master/spec.md#extension-types):
290-
291-
```php
292-
use MessagePack\Ext;
293-
use MessagePack\MessagePack;
294-
295-
$packed = MessagePack::pack(new Ext(42, "\xaa"));
296-
$ext = MessagePack::unpack($packed);
297-
298-
assert($ext->type === 42);
299-
assert($ext->data === "\xaa");
300-
```
301-
302-
Although it can be useful for dealing with types that are not supported by your
303-
setup, in most cases you will not use `Ext`, but rather type transformers that
304-
make extension types first-class citizens in your code.
293+
In addition to the [basic types](https://github.com/msgpack/msgpack/blob/master/spec.md#type-system),
294+
the library provides functionality to serialize and deserialize arbitrary types.
295+
This can be done in several ways, depending on your use case. Let's take a look at them.
305296

297+
#### Type objects
306298

307-
### Type transformers
308-
309-
In addition to [the basic types](https://github.com/msgpack/msgpack/blob/master/spec.md#type-system),
310-
the library provides functionality to serialize and deserialize arbitrary types.
311-
In order to support a custom type you need to create and register a transformer.
312-
The transformer should implement either the `CanPack` interface or the `Extension`
313-
interface.
314-
315-
The purpose of `CanPack` transformers is to serialize a specific value to
316-
one of the basic MessagePack types. A good example of such a transformer is
317-
a `MapTransformer` that comes with the library. It serializes `Map` objects
318-
(which are simple wrappers around PHP arrays) to MessagePack maps. This is
319-
useful when you want to explicitly mark that a given PHP array must be packed
320-
as a MessagePack map, without triggering the type's auto-detection routine.
321-
322-
> *More types and type transformers can be found in [src/Type](src/Type)
323-
> and [src/TypeTransformer](src/TypeTransformer) directories.*
324-
325-
The implementation is trivial:
299+
If you need to *serialize* a specific value into one of the basic MessagePack types, it is recommended
300+
to use an instance of a class that implements the [CanBePacked](src/CanBePacked.php) interface. A good
301+
example of such a class is the [Map](src/Type/Map.php) type class that comes with the library. This type
302+
is useful when you want to explicitly specify that a given PHP array should be packed as a MessagePack
303+
map without triggering an automatic type detection routine:
326304

327305
```php
328-
namespace MessagePack\TypeTransformer;
329-
330306
use MessagePack\Packer;
331307
use MessagePack\Type\Map;
332308

333-
class MapTransformer implements CanPack
334-
{
335-
public function pack(Packer $packer, $value) : ?string
336-
{
337-
return $value instanceof Map
338-
? $packer->packMap($value->map)
339-
: null;
340-
}
341-
}
309+
$packer = new Packer();
310+
311+
$packedMap = $packer->pack(new Map([1, 2, 3]));
312+
$packedArray = $packer->pack([1, 2, 3]);
342313
```
343314

344-
Once `MapTransformer` is registered, you can pack `Map` objects:
315+
> *More type examples can be found in the [src/Type](src/Type) directory.*
345316
346-
```php
347-
use MessagePack\Packer;
348-
use MessagePack\Type\Map;
349-
use MessagePack\TypeTransformer\MapTransformer;
317+
#### Type transformers
350318

351-
$packer = new Packer(null, [new MapTransformer()]);
319+
As with type objects, type transformers are only responsible for *serializing* values. They should be
320+
used when you need to serialize a value that does not implement the [CanBePacked](src/CanBePacked.php)
321+
interface. Examples of such values could be instances of built-in or third-party classes that you don't
322+
own, or non-objects such as resources.
352323

353-
$packed = $packer->pack([
354-
[1, 2, 3], // MP array
355-
new Map([1, 2, 3]), // MP map
356-
]);
357-
```
358-
359-
Transformers implementing the `Extension` interface are intended to handle
360-
[extension types](https://github.com/msgpack/msgpack/blob/master/spec.md#extension-types).
361-
For example, the code below shows how to create an extension that allows you
362-
to work transparently with `DateTime` objects:
324+
A transformer class must implement the [CanPack](src/CanPack.php) interface. To use a transformer,
325+
it must first be registered in the packer. Here is an example of how to serialize PHP streams into
326+
the MessagePack `bin` format type using one of the supplied transformers, `StreamTransformer`:
363327

364328
```php
365-
use MessagePack\BufferUnpacker;
366329
use MessagePack\Packer;
367-
use MessagePack\TypeTransformer\Extension;
330+
use MessagePack\TypeTransformer\StreamTransformer;
368331

369-
class DateTimeExtension implements Extension
370-
{
371-
private $type;
332+
$packer = new Packer(null, [new StreamTransformer()]);
372333

373-
public function __construct(int $type)
374-
{
375-
$this->type = $type;
376-
}
377-
378-
public function getType() : int
379-
{
380-
return $this->type;
381-
}
334+
$packedBin = $packer->pack(fopen('/path/to/file', 'r+'));
335+
```
382336

383-
public function pack(Packer $packer, $value) : ?string
384-
{
385-
if (!$value instanceof \DateTimeInterface) {
386-
return null;
387-
}
337+
> *More type transformer examples can be found in the [src/TypeTransformer](src/TypeTransformer) directory.*
388338
389-
return $packer->packExt($this->type, $value->format('YmdHisue'));
390-
}
339+
#### Extensions
391340

392-
public function unpackExt(BufferUnpacker $unpacker, int $extLength)
393-
{
394-
return \DateTimeImmutable::createFromFormat('YmdHisue', $unpacker->read($extLength));
395-
}
396-
}
397-
```
341+
In contrast to the cases described above, extensions are intended to handle
342+
[extension types](https://github.com/msgpack/msgpack/blob/master/spec.md#extension-types)
343+
and are responsible for *serializing* and *deserializing* values. An extension class must implement
344+
the [Extension](src/Extension.php) interface.
398345

399-
Register `DateTimeExtension` for both the packer and the unpacker with a unique
400-
extension type (an integer from 0 to 127) and you're ready to go:
346+
For example, to make the built-in PHP `DateTime` objects first-class citizens in your code, you can
347+
create a corresponding extension, as shown in the [example](examples/MessagePack/DateTimeExtension.php).
348+
Register the extension for both the packer and the unpacker with a unique extension type (an integer
349+
from 0 to 127) and you're ready to go:
401350

402351
```php
403352
use App\MessagePack\DateTimeExtension;
@@ -412,21 +361,37 @@ $packer = $packer->extendWith($dateTimeExtension);
412361
$unpacker = new BufferUnpacker();
413362
$unpacker = $unpacker->extendWith($dateTimeExtension);
414363

415-
$packed = $packer->pack(new DateTimeImmutable());
416-
$date = $unpacker->reset($packed)->unpack();
364+
$packedDate = $packer->pack(new DateTimeImmutable());
365+
$originalDate = $unpacker->reset($packed)->unpack();
366+
```
367+
368+
If you unpack a value from an extension that is not known to the unpacker, an [Ext](src/Type/Ext.php)
369+
object will be returned. It can also be used to pack an extension:
370+
371+
```php
372+
use MessagePack\Ext;
373+
use MessagePack\MessagePack;
374+
375+
$packed = MessagePack::pack(new Ext(42, "\xaa"));
376+
$ext = MessagePack::unpack($packed);
377+
378+
assert($ext->type === 42);
379+
assert($ext->data === "\xaa");
417380
```
418381

419-
> *More type transformer examples can be found in the [examples](examples) directory.*
382+
> *More extension examples can be found in the [examples/MessagePack](examples/MessagePack) directory.*
420383
421384

422385
## Exceptions
423386

424-
If an error occurs during packing/unpacking, a `PackingFailedException` or
425-
an `UnpackingFailedException` will be thrown, respectively. In addition,
426-
an `InsufficientDataException` can be thrown during unpacking.
387+
If an error occurs during packing/unpacking,
388+
a [PackingFailedException](src/Exception/PackingFailedException.php) or
389+
an [UnpackingFailedException](src/Exception/UnpackingFailedException.php) will be thrown, respectively.
390+
In addition, an [InsufficientDataException](src/Exception/InsufficientDataException.php) can be thrown
391+
during unpacking.
427392

428-
An `InvalidOptionException` will be thrown in case an invalid option
429-
(or a combination of mutually exclusive options) is used.
393+
An [InvalidOptionException](src/Exception/InvalidOptionException.php) will be thrown in case an invalid
394+
option (or a combination of mutually exclusive options) is used.
430395

431396

432397
## Tests
@@ -924,5 +889,4 @@ Ignored 16 16 0 7
924889

925890
## License
926891

927-
The library is released under the MIT License. See the bundled [LICENSE](LICENSE)
928-
file for details.
892+
The library is released under the MIT License. See the bundled [LICENSE](LICENSE) file for details.

examples/MessagePack/DateTimeExtension.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@
1212
namespace App\MessagePack;
1313

1414
use MessagePack\BufferUnpacker;
15+
use MessagePack\Extension;
1516
use MessagePack\Packer;
16-
use MessagePack\TypeTransformer\Extension;
1717

1818
class DateTimeExtension implements Extension
1919
{

examples/MessagePack/StructListExtension.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@
1212
namespace App\MessagePack;
1313

1414
use MessagePack\BufferUnpacker;
15+
use MessagePack\Extension;
1516
use MessagePack\Packer;
16-
use MessagePack\TypeTransformer\Extension;
1717

1818
class StructListExtension implements Extension
1919
{

examples/MessagePack/TextExtension.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@
1212
namespace App\MessagePack;
1313

1414
use MessagePack\BufferUnpacker;
15+
use MessagePack\Extension;
1516
use MessagePack\Packer;
16-
use MessagePack\TypeTransformer\Extension;
1717

1818
class TextExtension implements Extension
1919
{

examples/MessagePack/TraversableExtension.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@
1212
namespace App\MessagePack;
1313

1414
use MessagePack\BufferUnpacker;
15+
use MessagePack\Extension;
1516
use MessagePack\Packer;
16-
use MessagePack\TypeTransformer\Extension;
1717

1818
class TraversableExtension implements Extension
1919
{

examples/MessagePack/Uint64.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@
1111

1212
namespace App\MessagePack;
1313

14+
use MessagePack\CanBePacked;
1415
use MessagePack\Packer;
15-
use MessagePack\TypeTransformer\CanBePacked;
1616

1717
final class Uint64 implements CanBePacked
1818
{

src/BufferUnpacker.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
use MessagePack\Exception\InvalidOptionException;
1717
use MessagePack\Exception\UnpackingFailedException;
1818
use MessagePack\Type\Ext;
19-
use MessagePack\TypeTransformer\Extension;
2019

2120
class BufferUnpacker
2221
{
Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,7 @@
99
* file that was distributed with this source code.
1010
*/
1111

12-
namespace MessagePack\TypeTransformer;
13-
14-
use MessagePack\Packer;
12+
namespace MessagePack;
1513

1614
interface CanBePacked
1715
{
Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,7 @@
99
* file that was distributed with this source code.
1010
*/
1111

12-
namespace MessagePack\TypeTransformer;
13-
14-
use MessagePack\Packer;
12+
namespace MessagePack;
1513

1614
interface CanPack
1715
{
Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,7 @@
99
* file that was distributed with this source code.
1010
*/
1111

12-
namespace MessagePack\TypeTransformer;
13-
14-
use MessagePack\BufferUnpacker;
12+
namespace MessagePack;
1513

1614
interface Extension extends CanPack
1715
{

0 commit comments

Comments
 (0)