@@ -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
141144Examples:
142145
@@ -180,7 +183,8 @@ $value = MessagePack::unpack($packed);
180183
181184If the packed data is received in chunks (e.g. when reading from a stream),
182185use 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
186190while ($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-
330306use MessagePack\Packer;
331307use 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;
366329use 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
403352use 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.
0 commit comments