ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/CBOR-XS/README
(Generate patch)

Comparing CBOR-XS/README (file contents):
Revision 1.4 by root, Sat Oct 26 23:02:55 2013 UTC vs.
Revision 1.9 by root, Fri Nov 22 16:18:59 2013 UTC

8 $perl_value = decode_cbor $binary_cbor_data; 8 $perl_value = decode_cbor $binary_cbor_data;
9 9
10 # OO-interface 10 # OO-interface
11 11
12 $coder = CBOR::XS->new; 12 $coder = CBOR::XS->new;
13 #TODO 13 $binary_cbor_data = $coder->encode ($perl_value);
14 $perl_value = $coder->decode ($binary_cbor_data);
15
16 # prefix decoding
17
18 my $many_cbor_strings = ...;
19 while (length $many_cbor_strings) {
20 my ($data, $length) = $cbor->decode_prefix ($many_cbor_strings);
21 # data was decoded
22 substr $many_cbor_strings, 0, $length, ""; # remove decoded cbor string
23 }
14 24
15DESCRIPTION 25DESCRIPTION
16 WARNING! THIS IS A PRE-ALPHA RELEASE! IT WILL CRASH, CORRUPT YOUR DATA 26 WARNING! This module is very new, and not very well tested (that's up to
17 AND EAT YOUR CHILDREN! (Actually, apart from being untested and a bit 27 you to do). Furthermore, details of the implementation might change
18 feature-limited, it might already be useful). 28 freely before version 1.0. And lastly, most extensions depend on an IANA
29 assignment, and until that assignment is official, this implementation
30 is not interoperable with other implementations (even future versions of
31 this module) until the assignment is done.
32
33 You are still invited to try out CBOR, and this module.
19 34
20 This module converts Perl data structures to the Concise Binary Object 35 This module converts Perl data structures to the Concise Binary Object
21 Representation (CBOR) and vice versa. CBOR is a fast binary 36 Representation (CBOR) and vice versa. CBOR is a fast binary
22 serialisation format that aims to use a superset of the JSON data model, 37 serialisation format that aims to use a superset of the JSON data model,
23 i.e. when you can represent something in JSON, you should be able to 38 i.e. when you can represent something in JSON, you should be able to
24 represent it in CBOR. 39 represent it in CBOR.
25 40
26 This makes it a faster and more compact binary alternative to JSON. 41 In short, CBOR is a faster and very compact binary alternative to JSON,
42 with the added ability of supporting serialisation of Perl objects.
43 (JSON often compresses better than CBOR though, so if you plan to
44 compress the data later you might want to compare both formats first).
45
46 To give you a general idea about speed, with texts in the megabyte
47 range, "CBOR::XS" usually encodes roughly twice as fast as Storable or
48 JSON::XS and decodes about 15%-30% faster than those. The shorter the
49 data, the worse Storable performs in comparison.
50
51 As for compactness, "CBOR::XS" encoded data structures are usually about
52 20% smaller than the same data encoded as (compact) JSON or Storable.
53
54 In addition to the core CBOR data format, this module implements a
55 number of extensions, to support cyclic and self-referencing data
56 structures (see "allow_sharing"), string deduplication (see
57 "allow_stringref") and scalar references (always enabled).
27 58
28 The primary goal of this module is to be *correct* and the secondary 59 The primary goal of this module is to be *correct* and the secondary
29 goal is to be *fast*. To reach the latter goal it was written in C. 60 goal is to be *fast*. To reach the latter goal it was written in C.
30 61
31 See MAPPING, below, on how CBOR::XS maps perl values to CBOR values and 62 See MAPPING, below, on how CBOR::XS maps perl values to CBOR values and
53 *disabled*. 84 *disabled*.
54 85
55 The mutators for flags all return the CBOR object again and thus 86 The mutators for flags all return the CBOR object again and thus
56 calls can be chained: 87 calls can be chained:
57 88
58 #TODO my $cbor = CBOR::XS->new->encode ({a => [1,2]}); 89 my $cbor = CBOR::XS->new->encode ({a => [1,2]});
59 90
60 $cbor = $cbor->max_depth ([$maximum_nesting_depth]) 91 $cbor = $cbor->max_depth ([$maximum_nesting_depth])
61 $max_depth = $cbor->get_max_depth 92 $max_depth = $cbor->get_max_depth
62 Sets the maximum nesting level (default 512) accepted while encoding 93 Sets the maximum nesting level (default 512) accepted while encoding
63 or decoding. If a higher nesting level is detected in CBOR data or a 94 or decoding. If a higher nesting level is detected in CBOR data or a
94 as when 0 is specified). 125 as when 0 is specified).
95 126
96 See SECURITY CONSIDERATIONS, below, for more info on why this is 127 See SECURITY CONSIDERATIONS, below, for more info on why this is
97 useful. 128 useful.
98 129
130 $cbor = $cbor->allow_unknown ([$enable])
131 $enabled = $cbor->get_allow_unknown
132 If $enable is true (or missing), then "encode" will *not* throw an
133 exception when it encounters values it cannot represent in CBOR (for
134 example, filehandles) but instead will encode a CBOR "error" value.
135
136 If $enable is false (the default), then "encode" will throw an
137 exception when it encounters anything it cannot encode as CBOR.
138
139 This option does not affect "decode" in any way, and it is
140 recommended to leave it off unless you know your communications
141 partner.
142
143 $cbor = $cbor->allow_sharing ([$enable])
144 $enabled = $cbor->get_allow_sharing
145 If $enable is true (or missing), then "encode" will not
146 double-encode values that have been referenced before (e.g. when the
147 same object, such as an array, is referenced multiple times), but
148 instead will emit a reference to the earlier value.
149
150 This means that such values will only be encoded once, and will not
151 result in a deep cloning of the value on decode, in decoders
152 supporting the value sharing extension.
153
154 It is recommended to leave it off unless you know your communication
155 partner supports the value sharing extensions to CBOR
156 (http://cbor.schmorp.de/value-sharing).
157
158 Detecting shared values incurs a runtime overhead when values are
159 encoded that have a reference counter large than one, and might
160 unnecessarily increase the encoded size, as potentially shared
161 values are encode as sharable whether or not they are actually
162 shared.
163
164 At the moment, only targets of references can be shared (e.g.
165 scalars, arrays or hashes pointed to by a reference). Weirder
166 constructs, such as an array with multiple "copies" of the *same*
167 string, which are hard but not impossible to create in Perl, are not
168 supported (this is the same as for Storable).
169
170 If $enable is false (the default), then "encode" will encode
171 exception when it encounters anything it cannot encode as CBOR.
172
173 This option does not affect "decode" in any way - shared values and
174 references will always be decoded properly if present.
175
176 $cbor = $cbor->allow_stringref ([$enable])
177 $enabled = $cbor->get_allow_stringref
178 If $enable is true (or missing), then "encode" will try not to
179 encode the same string twice, but will instead encode a reference to
180 the string instead. Depending on your data format. this can save a
181 lot of space, but also results in a very large runtime overhead
182 (expect encoding times to be 2-4 times as high as without).
183
184 It is recommended to leave it off unless you know your
185 communications partner supports the stringref extension to CBOR
186 (http://cbor.schmorp.de/stringref).
187
188 If $enable is false (the default), then "encode" will encode
189 exception when it encounters anything it cannot encode as CBOR.
190
191 This option does not affect "decode" in any way - string references
192 will always be decoded properly if present.
193
194 $cbor = $cbor->filter ([$cb->($tag, $value)])
195 $cb_or_undef = $cbor->get_filter
196 Sets or replaces the tagged value decoding filter (when $cb is
197 specified) or clears the filter (if no argument or "undef" is
198 provided).
199
200 The filter callback is called only during decoding, when a
201 non-enforced tagged value has been decoded (see "TAG HANDLING AND
202 EXTENSIONS" for a list of enforced tags). For specific tags, it's
203 often better to provide a default converter using the
204 %CBOR::XS::FILTER hash (see below).
205
206 The first argument is the numerical tag, the second is the (decoded)
207 value that has been tagged.
208
209 The filter function should return either exactly one value, which
210 will replace the tagged value in the decoded data structure, or no
211 values, which will result in default handling, which currently means
212 the decoder creates a "CBOR::XS::Tagged" object to hold the tag and
213 the value.
214
215 When the filter is cleared (the default state), the default filter
216 function, "CBOR::XS::default_filter", is used. This function simply
217 looks up the tag in the %CBOR::XS::FILTER hash. If an entry exists
218 it must be a code reference that is called with tag and value, and
219 is responsible for decoding the value. If no entry exists, it
220 returns no values.
221
222 Example: decode all tags not handled internally into
223 CBOR::XS::Tagged objects, with no other special handling (useful
224 when working with potentially "unsafe" CBOR data).
225
226 CBOR::XS->new->filter (sub { })->decode ($cbor_data);
227
228 Example: provide a global filter for tag 1347375694, converting the
229 value into some string form.
230
231 $CBOR::XS::FILTER{1347375694} = sub {
232 my ($tag, $value);
233
234 "tag 1347375694 value $value"
235 };
236
99 $cbor_data = $cbor->encode ($perl_scalar) 237 $cbor_data = $cbor->encode ($perl_scalar)
100 Converts the given Perl data structure (a scalar value) to its CBOR 238 Converts the given Perl data structure (a scalar value) to its CBOR
101 representation. 239 representation.
102 240
103 $perl_scalar = $cbor->decode ($cbor_data) 241 $perl_scalar = $cbor->decode ($cbor_data)
145 arrays, maps 283 arrays, maps
146 CBOR arrays and CBOR maps will be converted into references to a 284 CBOR arrays and CBOR maps will be converted into references to a
147 Perl array or hash, respectively. The keys of the map will be 285 Perl array or hash, respectively. The keys of the map will be
148 stringified during this process. 286 stringified during this process.
149 287
150 true, false 288 null
151 These CBOR values become "CBOR::XS::true" and "CBOR::XS::false", 289 CBOR null becomes "undef" in Perl.
290
291 true, false, undefined
292 These CBOR values become "Types:Serialiser::true",
293 "Types:Serialiser::false" and "Types::Serialiser::error",
152 respectively. They are overloaded to act almost exactly like the 294 respectively. They are overloaded to act almost exactly like the
153 numbers 1 and 0. You can check whether a scalar is a CBOR boolean by 295 numbers 1 and 0 (for true and false) or to throw an exception on
154 using the "CBOR::XS::is_bool" function. 296 access (for error). See the Types::Serialiser manpage for details.
155 297
156 null, undefined 298 tagged values
157 CBOR null and undefined values becomes "undef" in Perl (in the
158 future, Undefined may raise an exception or something else).
159
160 tags
161 Tagged items consists of a numeric tag and another CBOR value. The 299 Tagged items consists of a numeric tag and another CBOR value.
162 tag 55799 is ignored (this tag implements the magic header).
163 300
164 All other tags are currently converted into a CBOR::XS::Tagged 301 See "TAG HANDLING AND EXTENSIONS" and the description of "->filter"
165 object, which is simply a blessed array reference consistsing of the 302 for details.
166 numeric tag value followed by the (decoded) BOR value.
167 303
168 anything else 304 anything else
169 Anything else (e.g. unsupported simple values) will raise a decoding 305 Anything else (e.g. unsupported simple values) will raise a decoding
170 error. 306 error.
171 307
191 and 1, which get turned into false and true in CBOR. 327 and 1, which get turned into false and true in CBOR.
192 328
193 CBOR::XS::Tagged objects 329 CBOR::XS::Tagged objects
194 Objects of this type must be arrays consisting of a single "[tag, 330 Objects of this type must be arrays consisting of a single "[tag,
195 value]" pair. The (numerical) tag will be encoded as a CBOR tag, the 331 value]" pair. The (numerical) tag will be encoded as a CBOR tag, the
196 value will be encoded as appropriate for the value. 332 value will be encoded as appropriate for the value. You cna use
333 "CBOR::XS::tag" to create such objects.
197 334
198 CBOR::XS::true, CBOR::XS::false 335 Types::Serialiser::true, Types::Serialiser::false,
336 Types::Serialiser::error
199 These special values become CBOR true and CBOR false values, 337 These special values become CBOR true, CBOR false and CBOR undefined
200 respectively. You can also use "\1" and "\0" directly if you want. 338 values, respectively. You can also use "\1", "\0" and "\undef"
339 directly if you want.
201 340
202 blessed objects 341 other blessed objects
203 Other blessed objects currently need to have a "TO_CBOR" method. It 342 Other blessed objects are serialised via "TO_CBOR" or "FREEZE". See
204 will be called on every object that is being serialised, and must 343 "TAG HANDLING AND EXTENSIONS" for specific classes handled by this
205 return something that can be encoded in CBOR. 344 module, and "OBJECT SERIALISATION" for generic object serialisation.
206 345
207 simple scalars 346 simple scalars
208 TODO Simple Perl scalars (any scalar that is not a reference) are 347 Simple Perl scalars (any scalar that is not a reference) are the
209 the most difficult objects to encode: CBOR::XS will encode undefined 348 most difficult objects to encode: CBOR::XS will encode undefined
210 scalars as CBOR null values, scalars that have last been used in a 349 scalars as CBOR null values, scalars that have last been used in a
211 string context before encoding as CBOR strings, and anything else as 350 string context before encoding as CBOR strings, and anything else as
212 number value: 351 number value:
213 352
214 # dump as number 353 # dump as number
245 IEEE single format if possible without loss of precision, otherwise 384 IEEE single format if possible without loss of precision, otherwise
246 the IEEE double format will be used. Perls that use formats other 385 the IEEE double format will be used. Perls that use formats other
247 than IEEE double to represent numerical values are supported, but 386 than IEEE double to represent numerical values are supported, but
248 might suffer loss of precision. 387 might suffer loss of precision.
249 388
389 OBJECT SERIALISATION
390 This module knows two way to serialise a Perl object: The CBOR-specific
391 way, and the generic way.
392
393 Whenever the encoder encounters a Perl object that it cnanot serialise
394 directly (most of them), it will first look up the "TO_CBOR" method on
395 it.
396
397 If it has a "TO_CBOR" method, it will call it with the object as only
398 argument, and expects exactly one return value, which it will then
399 substitute and encode it in the place of the object.
400
401 Otherwise, it will look up the "FREEZE" method. If it exists, it will
402 call it with the object as first argument, and the constant string
403 "CBOR" as the second argument, to distinguish it from other serialisers.
404
405 The "FREEZE" method can return any number of values (i.e. zero or more).
406 These will be encoded as CBOR perl object, together with the classname.
407
408 If an object supports neither "TO_CBOR" nor "FREEZE", encoding will fail
409 with an error.
410
411 Objects encoded via "TO_CBOR" cannot be automatically decoded, but
412 objects encoded via "FREEZE" can be decoded using the following
413 protocol:
414
415 When an encoded CBOR perl object is encountered by the decoder, it will
416 look up the "THAW" method, by using the stored classname, and will fail
417 if the method cannot be found.
418
419 After the lookup it will call the "THAW" method with the stored
420 classname as first argument, the constant string "CBOR" as second
421 argument, and all values returned by "FREEZE" as remaining arguments.
422
423 EXAMPLES
424 Here is an example "TO_CBOR" method:
425
426 sub My::Object::TO_CBOR {
427 my ($obj) = @_;
428
429 ["this is a serialised My::Object object", $obj->{id}]
430 }
431
432 When a "My::Object" is encoded to CBOR, it will instead encode a simple
433 array with two members: a string, and the "object id". Decoding this
434 CBOR string will yield a normal perl array reference in place of the
435 object.
436
437 A more useful and practical example would be a serialisation method for
438 the URI module. CBOR has a custom tag value for URIs, namely 32:
439
440 sub URI::TO_CBOR {
441 my ($self) = @_;
442 my $uri = "$self"; # stringify uri
443 utf8::upgrade $uri; # make sure it will be encoded as UTF-8 string
444 CBOR::XS::tagged 32, "$_[0]"
445 }
446
447 This will encode URIs as a UTF-8 string with tag 32, which indicates an
448 URI.
449
450 Decoding such an URI will not (currently) give you an URI object, but
451 instead a CBOR::XS::Tagged object with tag number 32 and the string -
452 exactly what was returned by "TO_CBOR".
453
454 To serialise an object so it can automatically be deserialised, you need
455 to use "FREEZE" and "THAW". To take the URI module as example, this
456 would be a possible implementation:
457
458 sub URI::FREEZE {
459 my ($self, $serialiser) = @_;
460 "$self" # encode url string
461 }
462
463 sub URI::THAW {
464 my ($class, $serialiser, $uri) = @_;
465
466 $class->new ($uri)
467 }
468
469 Unlike "TO_CBOR", multiple values can be returned by "FREEZE". For
470 example, a "FREEZE" method that returns "type", "id" and "variant"
471 values would cause an invocation of "THAW" with 5 arguments:
472
473 sub My::Object::FREEZE {
474 my ($self, $serialiser) = @_;
475
476 ($self->{type}, $self->{id}, $self->{variant})
477 }
478
479 sub My::Object::THAW {
480 my ($class, $serialiser, $type, $id, $variant) = @_;
481
482 $class-<new (type => $type, id => $id, variant => $variant)
483 }
484
250 MAGIC HEADER 485MAGIC HEADER
251 There is no way to distinguish CBOR from other formats programmatically. 486 There is no way to distinguish CBOR from other formats programmatically.
252 To make it easier to distinguish CBOR from other formats, the CBOR 487 To make it easier to distinguish CBOR from other formats, the CBOR
253 specification has a special "magic string" that can be prepended to any 488 specification has a special "magic string" that can be prepended to any
254 CBOR string without changing it's meaning. 489 CBOR string without changing its meaning.
255 490
256 This string is available as $CBOR::XS::MAGIC. This module does not 491 This string is available as $CBOR::XS::MAGIC. This module does not
257 prepend this string tot he CBOR data it generates, but it will ignroe it 492 prepend this string to the CBOR data it generates, but it will ignore it
258 if present, so users can prepend this string as a "file type" indicator 493 if present, so users can prepend this string as a "file type" indicator
259 as required. 494 as required.
260 495
496THE CBOR::XS::Tagged CLASS
497 CBOR has the concept of tagged values - any CBOR value can be tagged
498 with a numeric 64 bit number, which are centrally administered.
499
500 "CBOR::XS" handles a few tags internally when en- or decoding. You can
501 also create tags yourself by encoding "CBOR::XS::Tagged" objects, and
502 the decoder will create "CBOR::XS::Tagged" objects itself when it hits
503 an unknown tag.
504
505 These objects are simply blessed array references - the first member of
506 the array being the numerical tag, the second being the value.
507
508 You can interact with "CBOR::XS::Tagged" objects in the following ways:
509
510 $tagged = CBOR::XS::tag $tag, $value
511 This function(!) creates a new "CBOR::XS::Tagged" object using the
512 given $tag (0..2**64-1) to tag the given $value (which can be any
513 Perl value that can be encoded in CBOR, including serialisable Perl
514 objects and "CBOR::XS::Tagged" objects).
515
516 $tagged->[0]
517 $tagged->[0] = $new_tag
518 $tag = $tagged->tag
519 $new_tag = $tagged->tag ($new_tag)
520 Access/mutate the tag.
521
522 $tagged->[1]
523 $tagged->[1] = $new_value
524 $value = $tagged->value
525 $new_value = $tagged->value ($new_value)
526 Access/mutate the tagged value.
527
528 EXAMPLES
529 Here are some examples of "CBOR::XS::Tagged" uses to tag objects.
530
531 You can look up CBOR tag value and emanings in the IANA registry at
532 <http://www.iana.org/assignments/cbor-tags/cbor-tags.xhtml>.
533
534 Prepend a magic header ($CBOR::XS::MAGIC):
535
536 my $cbor = encode_cbor CBOR::XS::tag 55799, $value;
537 # same as:
538 my $cbor = $CBOR::XS::MAGIC . encode_cbor $value;
539
540 Serialise some URIs and a regex in an array:
541
542 my $cbor = encode_cbor [
543 (CBOR::XS::tag 32, "http://www.nethype.de/"),
544 (CBOR::XS::tag 32, "http://software.schmorp.de/"),
545 (CBOR::XS::tag 35, "^[Pp][Ee][Rr][lL]\$"),
546 ];
547
548 Wrap CBOR data in CBOR:
549
550 my $cbor_cbor = encode_cbor
551 CBOR::XS::tag 24,
552 encode_cbor [1, 2, 3];
553
554TAG HANDLING AND EXTENSIONS
555 This section describes how this module handles specific tagged values
556 and extensions. If a tag is not mentioned here and no additional filters
557 are provided for it, then the default handling applies (creating a
558 CBOR::XS::Tagged object on decoding, and only encoding the tag when
559 explicitly requested).
560
561 Tags not handled specifically are currently converted into a
562 CBOR::XS::Tagged object, which is simply a blessed array reference
563 consisting of the numeric tag value followed by the (decoded) CBOR
564 value.
565
566 Future versions of this module reserve the right to special case
567 additional tags (such as base64url).
568
569 ENFORCED TAGS
570 These tags are always handled when decoding, and their handling cannot
571 be overriden by the user.
572
573 <unassigned> (perl-object, <http://cbor.schmorp.de/perl-object>)
574 These tags are automatically created (and decoded) for serialisable
575 objects using the "FREEZE/THAW" methods (the Types::Serialier object
576 serialisation protocol). See "OBJECT SERIALISATION" for details.
577
578 <unassigned>, <unassigned> (sharable, sharedref, L
579 <http://cbor.schmorp.de/value-sharing>)
580 These tags are automatically decoded when encountered, resulting in
581 shared values in the decoded object. They are only encoded, however,
582 when "allow_sharable" is enabled.
583
584 <unassigned>, <unassigned> (stringref-namespace, stringref, L
585 <http://cbor.schmorp.de/stringref>)
586 These tags are automatically decoded when encountered. They are only
587 encoded, however, when "allow_stringref" is enabled.
588
589 22098 (indirection, <http://cbor.schmorp.de/indirection>)
590 This tag is automatically generated when a reference are encountered
591 (with the exception of hash and array refernces). It is converted to
592 a reference when decoding.
593
594 55799 (self-describe CBOR, RFC 7049)
595 This value is not generated on encoding (unless explicitly requested
596 by the user), and is simply ignored when decoding.
597
598 NON-ENFORCED TAGS
599 These tags have default filters provided when decoding. Their handling
600 can be overriden by changing the %CBOR::XS::FILTER entry for the tag, or
601 by providing a custom "filter" callback when decoding.
602
603 When they result in decoding into a specific Perl class, the module
604 usually provides a corresponding "TO_CBOR" method as well.
605
606 When any of these need to load additional modules that are not part of
607 the perl core distribution (e.g. URI), it is (currently) up to the user
608 to provide these modules. The decoding usually fails with an exception
609 if the required module cannot be loaded.
610
611 2, 3 (positive/negative bignum)
612 These tags are decoded into Math::BigInt objects. The corresponding
613 "Math::BigInt::TO_CBOR" method encodes "small" bigints into normal
614 CBOR integers, and others into positive/negative CBOR bignums.
615
616 4, 5 (decimal fraction/bigfloat)
617 Both decimal fractions and bigfloats are decoded into Math::BigFloat
618 objects. The corresponding "Math::BigFloat::TO_CBOR" method *always*
619 encodes into a decimal fraction.
620
621 CBOR cannot represent bigfloats with *very* large exponents -
622 conversion of such big float objects is undefined.
623
624 Also, NaN and infinities are not encoded properly.
625
626 21, 22, 23 (expected later JSON conversion)
627 CBOR::XS is not a CBOR-to-JSON converter, and will simply ignore
628 these tags.
629
630 32 (URI)
631 These objects decode into URI objects. The corresponding
632 "URI::TO_CBOR" method again results in a CBOR URI value.
633
261 CBOR and JSON 634CBOR and JSON
262 CBOR is supposed to implement a superset of the JSON data model, and is, 635 CBOR is supposed to implement a superset of the JSON data model, and is,
263 with some coercion, able to represent all JSON texts (something that 636 with some coercion, able to represent all JSON texts (something that
264 other "binary JSON" formats such as BSON generally do not support). 637 other "binary JSON" formats such as BSON generally do not support).
265 638
266 CBOR implements some extra hints and support for JSON interoperability, 639 CBOR implements some extra hints and support for JSON interoperability,
340 713
341SEE ALSO 714SEE ALSO
342 The JSON and JSON::XS modules that do similar, but human-readable, 715 The JSON and JSON::XS modules that do similar, but human-readable,
343 serialisation. 716 serialisation.
344 717
718 The Types::Serialiser module provides the data model for true, false and
719 error values.
720
345AUTHOR 721AUTHOR
346 Marc Lehmann <schmorp@schmorp.de> 722 Marc Lehmann <schmorp@schmorp.de>
347 http://home.schmorp.de/ 723 http://home.schmorp.de/
348 724

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines