浏览代码

初始化提交

master
SisMaker 4 年前
当前提交
d077d20b8d
共有 11 个文件被更改,包括 3061 次插入0 次删除
  1. +24
    -0
      .gitignore
  2. +19
    -0
      LICENSE
  3. +7
    -0
      README.md
  4. +621
    -0
      VelocyPack.md
  5. +323
    -0
      VelocyPack_zh.md
  6. +19
    -0
      include/eVPack.hrl
  7. +4
    -0
      rebar.config
  8. +230
    -0
      src/decoderTest.erl
  9. +14
    -0
      src/eVPack.app.src
  10. +1549
    -0
      src/eVPack.erl
  11. +251
    -0
      src/encoderTest.erl

+ 24
- 0
.gitignore 查看文件

@ -0,0 +1,24 @@
.eunit
*.o
*.beam
*.plt
erl_crash.dump
.concrete/DEV_MODE
# rebar 2.x
.rebar
rel/example_project
ebin/*
deps
# rebar 3
.rebar3
_build/
_checkouts/
rebar.lock
# idea
.idea
*.iml
rebar3.crashdump
*~

+ 19
- 0
LICENSE 查看文件

@ -0,0 +1,19 @@
MIT License Copyright (c) <year> <copyright holders>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:
The above copyright notice and this permission notice (including the next
paragraph) shall be included in all copies or substantial portions of the
Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

+ 7
- 0
README.md 查看文件

@ -0,0 +1,7 @@
erlVPack
=====
erlAarango 二进制序列化库
Build
-----
$ rebar3 compile

+ 621
- 0
VelocyPack.md 查看文件

@ -0,0 +1,621 @@
VelocyPack (VPack)
==================
Version 1
VelocyPack (VPack) is a fast and compact serialization format
## Generalities
VPack is (unsigned) byte oriented, so VPack values are simply sequences
of bytes and are platform independent. Values are not necessarily
aligned, so all access to larger subvalues must be properly organised to
avoid alignment assumptions of the CPU.
## Value types
We describe a single VPack value, which is recursive in nature, but
resides (with two exceptions, see below) in a single contiguous block of
memory. Assume that the value starts at address A, the first byte V
indicates the type (and often the length) of the VPack value at hand:
We first give an overview with a brief but accurate description for
reference, for arrays and objects see below for details:
- 0x00 : none - this indicates absence of any type and value,
this is not allowed in VPack values
- 0x01 : empty array
- 0x02 : array without index table (all subitems have the same
byte length), 1-byte byte length
- 0x03 : array without index table (all subitems have the same
byte length), 2-byte byte length
- 0x04 : array without index table (all subitems have the same
byte length), 4-byte byte length
- 0x05 : array without index table (all subitems have the same
byte length), 8-byte byte length
- 0x06 : array with 1-byte index table offsets, bytelen and # subvals
- 0x07 : array with 2-byte index table offsets, bytelen and # subvals
- 0x08 : array with 4-byte index table offsets, bytelen and # subvals
- 0x09 : array with 8-byte index table offsets, bytelen and # subvals
- 0x0a : empty object
- 0x0b : object with 1-byte index table offsets, sorted by
attribute name, 1-byte bytelen and # subvals
- 0x0c : object with 2-byte index table offsets, sorted by
attribute name, 2-byte bytelen and # subvals
- 0x0d : object with 4-byte index table offsets, sorted by
attribute name, 4-byte bytelen and # subvals
- 0x0e : object with 8-byte index table offsets, sorted by
attribute name, 8-byte bytelen and # subvals
- 0x0f : object with 1-byte index table offsets, not sorted by
attribute name, 1-byte bytelen and # subvals
- 0x10 : object with 2-byte index table offsets, not sorted by
attribute name, 2-byte bytelen and # subvals
- 0x11 : object with 4-byte index table offsets, not sorted by
attribute name, 4-byte bytelen and # subvals
- 0x12 : object with 8-byte index table offsets, not sorted by
attribute name, 8-byte bytelen and # subvals
- 0x13 : compact array, no index table
- 0x14 : compact object, no index table
- 0x15-0x16 : reserved
- 0x17 : illegal - this type can be used to indicate a value that
is illegal in the embedding application
- 0x18 : null
- 0x19 : false
- 0x1a : true
- 0x1b : double IEEE-754, 8 bytes follow, stored as little
endian uint64 equivalent
- 0x1c : UTC-date in milliseconds since the epoch, stored as 8 byte
signed int, little endian, two's complement
- 0x1d : external (only in memory): a char* pointing to the actual
place in memory, where another VPack item resides, not
allowed in VPack values on disk or on the network
- 0x1e : minKey, nonsensical value that compares < than all other values
- 0x1f : maxKey, nonsensical value that compares > than all other values
- 0x20-0x27 : signed int, little endian, 1 to 8 bytes, number is V - 0x1f,
two's complement
- 0x28-0x2f : uint, little endian, 1 to 8 bytes, number is V - 0x27
- 0x30-0x39 : small integers 0, 1, ... 9
- 0x3a-0x3f : small negative integers -6, -5, ..., -1
- 0x40-0xbe : UTF-8-string, using V - 0x40 bytes (not Unicode characters!),
length 0 is possible, so 0x40 is the empty string,
maximal length is 126, note that strings here are not
zero-terminated and may contain NUL bytes
- 0xbf : long UTF-8-string, next 8 bytes are length of string in
bytes (not Unicode characters) as little endian unsigned
integer, note that long strings are not zero-terminated
and may contain NUL bytes
- 0xc0-0xc7 : binary blob, next V - 0xbf bytes are the length of blob in
bytes, note that binary blobs are not zero-terminated
- 0xc8-0xcf : positive long packed BCD-encoded float, V - 0xc7 bytes follow
that encode in a little endian way the length of the
mantissa in bytes. Directly after that follow 4 bytes
encoding the (power of 10) exponent, by which the mantissa
is to be multiplied, stored as little endian two's
complement signed 32-bit integer. After that, as many
bytes follow as the length information at the beginning
has specified, each byte encodes two digits in
big-endian packed BCD
Example: 12345 decimal can be encoded as
0xc8 0x03 0x00 0x00 0x00 0x00 0x01 0x23 0x45
or 0xc8 0x03 0xff 0xff 0xff 0xff 0x12 0x34 0x50
- 0xd0-0xd7 : negative long packed BCD-encoded float, V - 0xcf bytes
follow that encode in a little endian way the length of
the mantissa in bytes. After that, same as positive long
packed BCD-encoded float above.
- 0xd8-0xed : reserved
- 0xee-0xef : value tagging for logical types
- 0xf0-0xff : custom types
## Arrays
Empty arrays are simply a single byte 0x01.
We next describe the type cases 0x02 to 0x09, see below for the
special compact type 0x13.
Non-empty arrays look like one of the following:
one of 0x02 to 0x05
BYTELENGTH
OPTIONAL UNUSED: padding
sub VPack values
or
0x06
BYTELENGTH in 1 byte
NRITEMS in 1 byte
OPTIONAL UNUSED: 6 bytes of padding
sub VPack values
INDEXTABLE with 1 byte per entry
or
0x07
BYTELENGTH in 2 bytes
NRITEMS in 2 bytes
OPTIONAL UNUSED: 4 bytes of padding
sub VPack values
INDEXTABLE with 4 byte per entry
or
0x08
BYTELENGTH in 4 bytes
NRITEMS in 4 bytes
sub VPack values
INDEXTABLE with 4 byte per entry
or
0x09
BYTELENGTH in 8 bytes
sub VPack values
INDEXTABLE with 8 byte per entry
NRITEMS in 8 bytes
If any optional padding is allowed for a type, the padding must consist
of exactly that many bytes that the length of the padding, the length of
BYTELENGTH and the length of NRITEMS (if present) sums up to 8. If the
length of BYTELENGTH is already 8, there is no padding allowed. The
entire padding must consist of zero bytes (ASCII NUL).
Numbers (for byte length, number of subvalues and offsets in the
INDEXTABLE) are little endian unsigned integers, using 1 byte for
types 0x02 and 0x06, 2 bytes for types 0x03 and 0x07, 4 bytes for types
0x04 and 0x08, and 8 bytes for types 0x05 and 0x09.
NRITEMS is a single number as described above.
The INDEXTABLE consists of:
- for types 0x06-0x09 an array of offsets (unaligned, in the number
format described above) earlier offsets reside at lower addresses.
Offsets are measured from the start of the VPack value.
Non-empty arrays of types 0x06 to 0x09 have a small header including
their byte length, the number of subvalues, then all the subvalues and
finally an index table containing offsets to the subvalues. To find the
index table, find the number of subvalues, then the end, and from that
the base of the index table, considering how wide its entries are.
For types 0x02 to 0x05 there is no offset table and no number of items.
The first item begins at address A+2, A+3, A+5 or respectively A+9,
depending on the type and thus the width of the byte length field. Note
the following special rule: The actual position of the first subvalue
is allowed to be further back, after some run of padding zero bytes.
For example, if 2 bytes are used for both the byte length (BYTELENGTH),
then an optional padding of 4 zero bytes is then allowed to follow, and
the actual VPack subvalues can start at A+9.
This is to give a program that builds a VPack value the opportunity to
reserve 8 bytes in the beginning and only later find out that fewer bytes
suffice to write the byte length. One can determine the number of
subvalues by finding the first subvalue, its byte length, and
dividing the amount of available space by it.
For types 0x06 to 0x09 the offset table describes where the subvalues
reside. It is not necessary for the subvalues to start immediately after
the number of subvalues field.
As above, it is allowed to include optional padding. Again here, any
padding must consist of a run of consecutive zero bytes (ASCII NUL) and
must be as long that it fills up the length of BYTELENGTH and the length
of NRITEMS to 8.
For example, if both BYTELENGTH and NRITEMS can be expressed using 2 bytes
each, the sum of their lengths is 4. It is therefore allowed to add 4
bytes of padding here, so that the first subvalue could be at address A+9.
There is one exception for the 8-byte numbers case (type 0x05):
In this case the number of elements is moved behind the index table.
This is to get away without moving memory when one has reserved 8 bytes
in the beginning and later noticed that all 8 bytes are needed for the
byte length. For this case it is not allowed to include any padding.
All offsets are measured from base A.
*Example*:
`[1,2,3]` has the hex dump
02 05 31 32 33
in the most compact representation, but the following are equally
possible, though not necessarily advised to use:
*Examples*:
03 06 00 31 32 33
04 08 00 00 00 31 32 33
05 0c 00 00 00 00 00 00 00 31 32 33
06 09 03 31 32 33 03 04 05
07 0e 00 03 00 31 32 33 05 00 06 00 07 00
08 18 00 00 00 03 00 00 00 31 32 33 09 00 00 00 0a 00 00 00 0b 00 00 00
09
2c 00 00 00 00 00 00 00
31 32 33
09 00 00 00 00 00 00 00
0a 00 00 00 00 00 00 00
0b 00 00 00 00 00 00 00
03 00 00 00 00 00 00 00
Note that it is not recommended to encode short arrays in too long a
format.
We now describe the special type 0x13, which is useful for a
particularly compact array representation. Note that to some extent this
goes against the principles of the VelocyPack format, since quick access
to subvalues is no longer possible, all items in the array must be
scanned to find a particular one. However, there are certain use cases
for VelocyPack which only require sequential access (for example JSON
dumping) and have a particular need for compactness.
The overall format of this array type is
0x13 as type byte
BYTELENGTH
sub VPack values
NRITEMS
There is no index table at all, although the sub VelocyPack values can
have different byte sizes. The BYTELENGTH and NRITEMS are encoded in a
special format, which we describe now.
The BYTELENGTH consists of 1 to 8 bytes, of which all but the last one
have their high bit set. Thus, the high bits determine, how many bytes
are actually used. The lower 7 bits of all these bits together comprise
the actual byte length in a little endian fashion. That is, the byte at
address A+1 contains the least significant 7 bits (0 to 6) of the byte length,
the following byte at address A+2 contains the bits 7 to 13, and so on.
Since the total number of bytes is limited to 8, this encodes unsigned
integers of up to 56 bits, which is the overall limit for the size of
such a compact array representation.
The NRITEMS entry is encoded essentially the same, except that it is
laid out in reverse order in memory. That is, one has to use the
BYTELENGTH to find the end of the array value and go back bytes until
one finds a byte with high bit reset. The last byte (at the highest
memory address) contains the least significant 7 bits of the NRITEMS
value, the second one bits 7 to 13 and so on.
Here is an example, the array [1, 16] can be encoded as follows:
13 06
31 28 10
02
## Objects
Empty objects are simply a single byte 0x0a.
We next describe the type cases 0x0b to 0x12, see below for the
special compact type 0x14.
Non-empty objects look like this:
one of 0x0b - 0x12
BYTELENGTH
optional NRITEMS
sub VPack values as pairs of attribute and value
optional INDEXTABLE
NRITEMS for the 8-byte case
Numbers (for byte length, number of subvalues and offsets in the
INDEXTABLE) are little endian unsigned integers, using 1 byte for
types 0x0b and 0x0f, 2 bytes for types 0x0c and 0x10, 4 bytes for types
0x0d and 0x11, and 8 bytes for types 0x0e and 0x12.
NRITEMS is a single number as described above.
The INDEXTABLE consists of:
- an array of offsets (unaligned, in the number format described
above) earlier offsets reside at lower addresses.
Offsets are measured from the beginning of the VPack value.
Non-empty objects have a small header including their byte length, the
number of subvalues, then all the subvalues and finally an index table
containing offsets to the subvalues. To find the index table, find
number of subvalues, then the end, and from that the base of the index
table, considering how wide its entries are.
For all types the offset table describes where the subvalues reside. It
is not necessary for the subvalues to start immediately after the number
of subvalues field. For performance reasons when building the value, it
could be desirable to reserve 8 bytes for the byte length and the number
of subvalues and not fill the gap, even though it turns out later that
offsets and thus the byte length only uses 2 bytes, say.
There is one special case: the empty object is simply stored as the
single byte 0x0a.
There is another exception: For 8-byte numbers (0x12) the number of
subvalues is stored behind the INDEXTABLE. This is to get away without
moving memory when one has reserved 8 bytes in the beginning and later
noticed that all 8 bytes are needed for the byte length.
All offsets are measured from base A.
Each entry consists of two parts, the key and the value, they are
encoded as normal VPack values as above, the first is always a short or
long UTF-8 string starting with a byte 0x40-0xbf as described below. The
second is any other VPack value.
There is one extension: For the key it is possible to use the positive
small integer values 0x30-0x39 or an unsigned integer starting with a
type byte of 0x28-0x2f. Any such integer value is an index into an
outside-given table of attribute names. These are convenient when only
very few attribute names occur or some are repeated very often. The
standard way to encode such an attribute name table is as a VPack array
of strings as specified here.
Objects are always stored with sorted key/value pairs, sorted by bytewise
comparions of the keys on each nesting level. Sorting has some overhead
but will allow looking up keys in logarithmic time later. Note that only the
index table needs to be sorted, it is not required that the offsets in
these tables are increasing. Since the index table resides after the actual
subvalues, one can build up a complex VPack value by writing linearly.
Example: the object `{"a": 12, "b": true, "c": "xyz"}` can have the hexdump:
0b
13 03
41 62 1a
41 61 28 0c
41 63 43 78 79 7a
06 03 0a
The same object could have been done with an index table with longer
entries, as in this example:
0d
22 00 00 00
03 00 00 00
41 62 1a
41 61 28 0c
41 63 43 78 79 7a
0c 00 00 00 09 00 00 00 10 00 00 00
Similarly with type 0x0c and 2-byte offsets, byte length and number of
subvalues, or with type 0x0e and 8-byte numbers.
Note that it is not recommended to encode short objects with too long
index tables.
### Special compact objects
We now describe the special type 0x14, which is useful for a
particularly compact object representation. Note that to some extent
this goes against the principles of the VelocyPack format, since quick
access to subvalues is no longer possible, all key/value pairs in the
object must be scanned to find a particular one. However, there are
certain use cases for VelocyPack which only require sequential access
(for example JSON dumping) and have a particular need for compactness.
The overall format of this object type is
0x14 as type byte
BYTELENGTH
sub VPack key/value pairs
NRPAIRS
There is no index table at all, although the sub VelocyPack values can
have different byte sizes. The BYTELENGTH and NRPAIRS are encoded in a
special format, which we describe now. It is the same as for the special
compact array type 0x13, which we repeat here for the sake of
completeness.
The BYTELENGTH consists of 1 to 8 bytes, of which all but the last one
have their high bit set. Thus, the high bits determine, how many bytes
are actually used. The lower 7 bits of all these bits together comprise
the actual byte length in a little endian fashion. That is, the byte at
address A+1 contains the least significant 7 bits (0 to 6) of the byte
length, the following byte at address A+2 contains the bits 7 to 13, and
so on. Since the total number of bytes is limited to 8, this encodes
unsigned integers of up to 56 bits, which is the overall limit for the
size of such a compact array representation.
The NRPAIRS entry is encoded essentially the same, except that it
is laid out in reverse order in memory. That is, one has to use the
BYTELENGTH to find the end of the array value and go back bytes until
one finds a byte with high bit reset. The last byte (at the highest
memory address) contains the least significant 7 bits of the NRPAIRS
value, the second one bits 7 to 13 and so on.
Here is an example, the object {"a":1, "b":16} can be encoded as follows:
14 0a
41 61 31 42 62 28 10
02
## Doubles
Type 0x1b indicates a double IEEE-754 value using the 8 bytes following
the type byte. To guarantee platform-independentness the details of the
byte order are as follows. Encoding is done by using memcpy to copy the
internal double value to an uint64\_t. This 64-bit unsigned integer is
then stored as little endian 8 byte integer in the VPack value. Decoding
works in the opposite direction. This should sort out the undetermined
byte order in IEEE-754 in practice.
## Dates
Type 0x1c indicates a signed 64-int integer stored in 8 bytes little
endian two's complement notation directly after the type. The value means
a universal UTC-time measured in milliseconds since the epoch, which is
00:00 on 1 January 1970 UTC.
## External VPack values
This type is only for use within memory, not for data exchange over disk
or network. Therefore, we only need to specify that the following k
bytes are the memcpy of a char* on the current architecture. That char*
points to the actual VPack value elsewhere in memory.
## Artifical minimal and maximal keys
These values of types 0x1e and 0x1f have no meaning other than comparing
smaller or greater respectively than any other VPack value. The idea is
that these can be used in systems that define a total order on all VPack
values to specify left or right ends of infinite intervals.
## Integer types
There are different ways to specify integers. For small values -6 to 9
inclusively there are specific type bytes in the range 0x30 to 0x3f to
allow for storage in a single byte. After that there are signed and
unsigned integer types that can code in the type byte the number of
bytes used (ranges 0x20-0x27 for signed and 0x28-0x2f for unsigned).
## Null and boolean values
These three values use a single byte to store the corresponding JSON
values.
## Strings
Strings are stored as UTF-8 encoded byte sequences. There are two
variants, a short one and a long one. In the short one, the byte length
(not the number of UTF-8 characters) is directly encoded in the type,
and this works up to and including byte length 126. Types 0x40 to 0xbe
are used for this and the byte length is V - 0x3f, if V is the type
byte. For strings longer than 126 bytes, the type byte is 0xbf and the
byte length of the string is stored in the first 8 bytes after the type
byte, using a little endian unsigned integer representation. The actual
string follows after these 8 bytes. There is no terminating zero byte in
either case and the string may contain zero bytes.
## Binary data
The type bytes 0xc0 to 0xc7 allow to store arbitrary binary byte
sequences as a VPack value. The format is as follows: If V is the type
byte, then V - 0xbf bytes follow it to make a little endian unsigned
integer representing the length of the binary data, which directly
follows these length bytes. No alignment is guaranteed. The content is
entirely up to the user.
## Packed BCD long floats
These types are used to represent arbitrary precision decimal numbers.
There are different types for positive and negative numbers. The overall
format of these values is:
one of 0xc8 - 0xcf (positive) or of 0xd0 - 0xd7 (negative)
LENGTH OF MANTISSA in bytes
EXPONENT (as 4-byte little endian signed two's complement integer)
MANTISSA (as packed BCD-encoded integer, big-endian)
The type byte describes the sign of the number as well as the number of
bytes used to specify the byte length of the mantissa. As usual, if V is
the type byte, then V - 0xc7 (in the positive case) or V - 0xcf (in the
negative case) bytes are used for the length of the mantissa, stored as
little endian unsigned integer directly after the byte length. After
this follow exactly 4 bytes (little endian signed two's complement
integer) to specify the exponent. After the exponent, the actual
mantissa bytes follow.
Packed BCD is used, so that each byte stores exactly 2 decimal digits as
in 0x34 for the decimal digits 34. Therefore, the mantissa always has an
even number of decimal digits. Note that the mantissa is stored in big
endian form, to make parsing and dumping efficient. This leads to the
"unholy nibble problem": When a JSON parser sees the beginning of a
longish number, it does not know whether an even or odd number of digits
follow. However, for efficiency reasons it wants to start writing bytes
to the output as it reads the input. This is, where the exponent comes
to the rescue, which is illustrated by the following example:
12345 decimal can be encoded as:
0xc8 0x03 0x00 0x00 0x00 0x00 0x01 0x23 0x45
0xc8 0x03 0xff 0xff 0xff 0xff 0x12 0x34 0x50
The former encoding puts a leading 0 in the first byte and uses exponent
0, the latter encoding directly starts putting two decimal digits in one
byte and then in the end has to "erase" the trailing 0 by using exponent
-1, encoded by the 4 byte sequence 0xff 0xff 0xff 0xff.
There for the unholy nibble problem is solved and parsing (and indeed
dumping) can be efficient.
## Tagging
Types 0xee-0xef are used for tagging of values to implement logical
types.
For example, if type 0x1c did not exist, the database driver could
serialize a timestamp object (Date in JavaScript, Instant in Java, etc)
into a Unix timestamp, a 64-bit integer. Assuming the lack of schema,
upon deserialization it would not be possible to tell an integer from
a timestamp and deserialize the value accordingly.
Type tagging resolves this by attaching an integer tag to values that
can then be read when deserializing the value, e.g. that tag=1 is a
timestamp and the relevant timestamp class should be used.
The tag values are specified separately and applications can also
specify their own to have the database driver deserialize their specific
data types into the appropriate classes (including models).
Essentially this is object-relational mapping for parts of documents.
The format of the type is:
0xee
TAG number in 1 byte
sub VPack value
or
0xef
TAG number in 8 bytes, little-endian encoding
sub VPack value
## Custom types
Note that custom types should usually not be used for data exchange but
only internally in systems. Nevertheless, the design of this part of
the specification is made such that it is possible by generic methods
to derive the byte length of each custom data type.
The following user-defined types exist:
- 0xf0 : 1 byte payload, directly following the type byte
- 0xf1 : 2 bytes payload, directly following the type byte
- 0xf2 : 4 bytes payload, directly following the type byte
- 0xf3 : 8 bytes payload, directly following the type byte
- 0xf4-0xf6 : length of the payload is described by a single further
unsigned byte directly following the type byte, the
payload of that many bytes follows
- 0xf7-0xf9 : length of the payload is described by two bytes (little
endian unsigned integer) directly following the type
byte, the payload of that many bytes follows
- 0xfa-0xfc : length of the payload is described by four bytes (little
endian unsigned integer) directly following the type
byte, the payload of that many bytes follows
- 0xfd-0xff : length of the payload is described by eight bytes (little
endian unsigned integer) directly following the type
byte, the payload of that many bytes follows
Note: In types 0xf4 to 0xff the "payload" refers to the actual data not
including the length specification.

+ 323
- 0
VelocyPack_zh.md 查看文件

@ -0,0 +1,323 @@
# VelocyPack(VPack)
Version 1
VelocyPack(VPack)是一种快速而紧凑的序列化格式
# 共性
VPack是面向(无符号)字节的,因此VPack值只是字节序列,并且与平台无关。值不一定要对齐,因此必须正确组织对较大子值的所有访问,以避免CPU的对齐假设。
# 值类型
我们描述了一个VPack值,该值本质上是递归的,但驻留在一个连续的内存块中(有两个例外,请参见下文)。假设该值从地址A开始,则第一个字节V指示当前VPack值的类型(通常是长度):
# 总述 我们首先给出一个简短而准确的概述作为参考,以供参考,有关数组和对象的详细信息,请参见下文:
0x00:0 无-表示不存在任何类型和值,VPack值中不允许
0x01:1 空数组
0x02:2 不带索引表的数组(所有子项具有相同的字节长度),1字节字节长度
0x03:3 不带索引表的数组(所有子项具有相同的字节长度),2字节字节长度
0x04:4 不带索引表的数组(所有子项具有相同的字节长),4字节字节长
0x05:5 不带索引表的数组(所有子项具有相同的字节长度),8字节字节长度
0x06:6 具有1字节索引表偏移量,bytelen和#个子区间的数组
0x07:7 具有2字节索引表偏移量,bytelen和#个子区间的数组
0x08:8 具有4字节索引表偏移量,bytelen和#个子区间的数组
0x09:9 具有8字节索引表偏移量,bytelen和#个子区间的数组
0x0a:10 空对象
0x0b:11 具有1字节索引表偏移量的对象,按属性名称排序,1字节bytelen和#个子值
0x0c:12 具有2字节索引表偏移量的对象,按属性名称排序,2字节bytelen和#个子值
0x0d:13 具有4字节索引表偏移量的对象,按属性名称排序,4字节bytelen和#个子值
0x0e:14 具有8字节索引表偏移量的对象,按属性名称排序,8字节bytelen和#个子值
0x0f:15 具有1字节索引表偏移量的对象,未按属性名称排序,1字节bytelen和#个子值
0x10:16 具有2字节索引表偏移量的对象,未按属性名称排序,2字节bytelen和#个子值
0x11:17 具有4字节索引表偏移量的对象,未按属性名称排序,4字节bytelen和#个子值
0x12:18 具有8字节索引表偏移量的对象,未按属性名称排序,8字节字节数和#个子值
0x13:19 紧凑数组,没有索引表
0x14:20 紧凑对象,没有索引表
0x15-0x16:21-22保留
0x17:23 不合法-此类型可用于指示嵌入应用程序中不合法的值
0x18:24 null
0x19:25 false
0x1a:26 true
0x1b:27 双IEEE-754,后跟8个字节,存储为与uint64等效的小字节序
0x1c:28 UTC日期(自纪元以来),以8字节有符号int,little endian,二进制补码形式存储
0x1d:29 外部(仅在内存中):一个char *,指向另一个VPack项在内存中的实际位置,磁盘或网络上的VPack值中不允许
0x1e:30 minKey,比较所有其他值<的无意义的值
0x1f:31 maxKey,与所有其他值相比>的无意义值
0x20-0x27:32-39带符号的int,小字节序,1至8个字节,数字为V-0x1f,二进制补码
0x28-0x2f:40-47 uint,小端,1至8字节,数字为V-0x27
0x30-0x39:48-57 ,小整数0,1,... 9
0x3a-0x3f:58- 63 小负整数-6,-5,...,-1
0x40-0xbe:64- 190 UTF-8字符串,使用V-0x40字节(不是Unicode字符!),长度为0,所以0x40是空字符串,最大长度为126,请注意,这里的字符串不是以0结尾的,并且可以包含NUL个字节
0xbf:191 长UTF-8字符串,接下来的8个字节是字符串的长度(以字节为单位)(不是Unicode字符),是小端无符号整数,请注意,长字符串不以0结尾,并且可以包含NUL字节
0xc0-0xc7:192-199 二进制blob,下一个V-0xbf字节是blob的长度(以字节为单位),请注意二进制blob不会以零结尾
0xc8-0xcf:200-207 正长打包BCD编码的浮点数,后跟V-0xc7字节,以一点尾数方式对尾数的长度(以字节为单位)进行编码。之后紧随其后的是4个字节(乘以10的幂),然后乘以尾数,将其存储为小尾数2的补码有符号32位整数。
之后,跟着指定的开始处的长度信息一样多的字节,每个字节以大端字节序打包的BCD编码两位。
示例:12345十进制可以编码为0xc8 0x03 0x00 0x00 0x00 0x00 0x01 0x23 0x45或0xc8 0x03 0xff 0xff 0xff 0xff 0x12 0x34 0x50
0xd0-0xd7:208- 215 负长打包BCD编码的浮点数,后跟V-0xcf字节,以一点尾数法对尾数的长度(以字节为单位)进行编码。之后,与上面的正长打包BCD编码浮点相同。
0xd8-0xed:216-237 保留
0xee-0xef:238-239 逻辑类型的值标记
0xf0-0xff:240-255 自定义类型
# 详述
## Arrays
空数组只是一个字节0x01。
接下来,我们将描述类型为0x02到0x09的情况,请参见下面的特殊紧凑型0x13。
非空数组看起来像以下之一:
one of 0x02 to 0x05
BYTELENGTH
OPTIONAL UNUSED: padding
sub VPack values
要么
0x06
BYTELENGTH in 1 byte
NRITEMS in 1 byte
OPTIONAL UNUSED: 6 bytes of padding
sub VPack values
INDEXTABLE with 1 byte per entry
要么
0x07
BYTELENGTH in 2 bytes
NRITEMS in 2 bytes
OPTIONAL UNUSED: 4 bytes of padding
sub VPack values
INDEXTABLE with 4 byte per entry
要么
0x08
BYTELENGTH in 4 bytes
NRITEMS in 4 bytes
sub VPack values
INDEXTABLE with 4 byte per entry
要么
0x09
BYTELENGTH in 8 bytes
sub VPack values
INDEXTABLE with 8 byte per entry
NRITEMS in 8 bytes
如果类型允许使用任何可选的填充,则填充必须完全由填充字节的长度,BYTELENGTH的长度和NRITEMS的长度(如果存在)之和等于8的字节数组成。如果BYTELENGTH的长度为已经是8,不允许填充。整个填充必须由零字节(ASCII NUL)组成。
数字(对于字节长度,INDEXTABLE中的子值数量和偏移量)是小端无符号整数,对于类型0x02和0x06使用1字节,对于类型0x03和0x07使用2字节,对于类型0x04和0x08使用4字节,对于类型0x05和0x09使用8字节。
NRITEMS是如上所述的单个数字。
INDEXTABLE包含:
对于类型0x06-0x09,偏移量数组(未对齐,采用上述数字格式)较早的偏移量位于较低地址。偏移量从VPack值的开头开始测量。
类型为0x06到0x09的非空数组具有一个小的标头,包括它们的字节长度,子值数量,所有子值以及最后一个包含这些子值偏移量的索引表。要找到索引表,请先考虑子值的数量,然后是末尾,再从索引表的底部开始,并考虑其条目的宽度。
对于类型0x02至0x05,没有偏移表,也没有项目数。第一项根据字节长度字段的类型和宽度而定,从地址A + 2,A + 3,A + 5或分别为A + 9开始。请注意以下特殊规则:在填充零字节之后,允许第一个子值的实际位置再退一步。
例如,如果两个字节长度(BYTELENGTH)都使用了2个字节,则随后可以选择填充4个零字节,并且实际的VPack子值可以从A + 9开始。这是为了给构建VPack值的程序提供在开始时保留8个字节的机会,直到以后才发现可以写出字节长度的字节更少。可以通过找到第一个子值,其字节长度并将可用空间除以它来确定子值的数量。
对于类型0x06至0x09,偏移量表描述了子值所在的位置。子值不必在“子值数”字段之后立即开始。
如上所述,允许包括可选的填充。同样在这里,任何填充都必须由连续的零字节(ASCII NUL)组成,并且填充长度必须足以填充BYTELENGTH的长度和NRITEMS的长度为8。
例如,如果BYTELENGTH和NRITEMS都可以用2个字节表示,则它们的长度之和为4。因此,允许在此处添加4个字节的填充,以便第一个子值可以位于地址A + 9。
对于8字节数字情况(类型0x05),有一个例外:在这种情况下,元素数被移到索引表的后面。当一个人在开始时已经保留了8个字节,后来又注意到字节长度需要全部8个字节时,这是为了不移动内存而逃脱。在这种情况下,不允许包含任何填充。
所有偏移量均从基数A开始测量。
范例:
[1,2,3] 有十六进制转储
02 05 31 32 33
以最紧凑的形式表示,但以下情况同样可行,尽管不一定建议使用:
例子:
03 06 00 31 32 33
04 08 00 00 00 31 32 33
05 0c 00 00 00 00 00 00 00 31 32 33
06 09 03 31 32 33 03 04 05
07 0e 00 03 00 31 32 33 05 00 06 00 07 00
08 18 00 00 00 03 00 00 00 31 32 33 09 00 00 00 0a 00 00 00 0b 00 00 00
09
2c 00 00 00 00 00 00 00
31 32 33
09 00 00 00 00 00 00 00
0a 00 00 00 00 00 00 00
0b 00 00 00 00 00 00 00
03 00 00 00 00 00 00 00
请注意,不建议以太长的格式编码短数组。
现在我们描述特殊类型0x13,它对于特别紧凑的数组表示很有用。请注意,在某种程度上这与VelocyPack格式的原理背道而驰,因为不再能够快速访问子值,因此必须扫描数组中的所有项以找到特定项。但是,VelocyPack的某些用例只需要顺序访问(例如JSON转储),并且对紧凑性有特殊的需求。
此数组类型的整体格式为
0x13作为类型字节BYTELENGTH子VPack值NRITEMS
尽管子VelocyPack值可以具有不同的字节大小,但根本没有索引表。BYTELENGTH和NRITEMS以特殊格式编码,我们现在将对其进行描述。
BYTELENGTH由1到8个字节组成,除最后一个字节外,所有字节均已设置其高位。因此,高位确定实际使用了多少个字节。所有这些位的低7位以一点字节序的形式一起构成了实际的字节长度。也就是说,地址A + 1处的字节包含字节长度的最低有效7位(0至6),地址A + 2之后的字节包含位7至13,依此类推。由于字节的总数限制为8,因此可以对多达56位的无符号整数进行编码,这是此类紧凑数组表示形式的大小的总体限制。
NRITEMS条目的编码方式基本上相同,只是它以相反的顺序排列在内存中。也就是说,必须使用BYTELENGTH来查找数组值的末尾并返回字节,直到找到高复位位的字节为止。最后一个字节(在最高的存储器地址处)包含NRITEMS值的最低有效7位,后一个7至13位,依此类推。
这是一个示例,可以将数组[1,16]编码如下:
13 06
31 28 10
02
## Objects
空对象只是一个字节0x0a。
接下来,我们描述类型为0x0b到0x12的情况,有关特殊的紧凑型0x14,请参见下文。
非空对象如下所示:
one of 0x0b - 0x12
BYTELENGTH
optional NRITEMS
sub VPack values as pairs of attribute and value
optional INDEXTABLE
NRITEMS for the 8-byte case
数字(对于字节长度,INDEXTABLE中的子值数量和偏移量)是小端无符号整数,对于类型0x0b和0x0f使用1个字节,对于类型0x0c和0x10使用2个字节,对于类型0x0d和0x11使用4个字节,对于类型8x类型0x0e和0x12。
NRITEMS是如上所述的单个数字。
INDEXTABLE包含:
较早的偏移量数组(未对齐,采用上述数字格式)位于较低的地址。偏移量是从VPack值的开头开始测量的。
非空对象的标头很小,包括字节长度,子值数量,所有子值以及最后一个包含子值偏移量的索引表。要查找索引表,请先考虑子值的数量,然后查找末尾,再从索引表的底部开始,考虑其条目的宽度。
对于所有类型,偏移量表都描述了子值所在的位置。子值不必在“子值数”字段之后立即开始。出于性能原因,在构建值时,可能希望为字节长度和子值的数量保留8个字节,而不填补空白,即使后来发现偏移量(因此字节长度仅使用2个字节)也是如此。 。
有一种特殊情况:空对象仅存储为单个字节0x0a。
还有一个例外:对于8字节数字(0x12),子值的数量存储在INDEXTABLE的后面。当一个人在开始时已经保留了8个字节,后来又注意到字节长度需要全部8个字节时,这是为了不移动内存而逃脱。
所有偏移量均从基数A开始测量。
每个条目都由键和值两部分组成,它们如上所述被编码为普通的VPack值,第一个始终是长或短的UTF-8字符串,从字节0x40-0xbf开始,如下所述。第二个是任何其他VPack值。
有一个扩展:对于密钥,可以使用正的小整数值0x30-0x39或以类型字节0x28-0x2f开头的无符号整数。任何此类整数值都是属性名称的外部表的索引。当仅出现很少的属性名称或经常重复某些属性名称时,这些方法很方便。编码此类属性名称表的标准方法是使用此处指定的VPack字符串数组。
对象总是存储有排序的键/值对,并按每个嵌套级别上键的按字节比较排序。排序有一些开销,但允许在以后的对数时间内查找键。注意,仅索引表需要排序,不需要这些表中的偏移量增加。由于索引表位于实际的子值之后,因此可以通过线性写入来构建复杂的VPack值。
示例:对象{"a": 12, "b": true, "c": "xyz"}可以具有hexdump:
0b
13 03
41 62 1a
41 61 28 0c
41 63 43 78 79 7a
06 03 0a
可以使用具有更长条目的索引表来完成相同的对象,如以下示例所示:
0d
22 00 00 00
03 00 00 00
41 62 1a
41 61 28 0c
41 63 43 78 79 7a
0c 00 00 00 09 00 00 00 10 00 00 00
类似地,对于类型0x0c和2个字节的偏移量,字节长度和子值数量,或者对于类型0x0e和8个字节的数字。
请注意,不建议对索引表太长的短对象进行编码。
特殊的紧凑物体
现在我们描述特殊类型0x14,它对于特别紧凑的对象表示很有用。请注意,在某种程度上这与VelocyPack格式的原理背道而驰,因为不再能够快速访问子值,因此必须扫描对象中的所有键/值对以找到特定的键/值对。但是,VelocyPack的某些用例只需要顺序访问(例如JSON转储),并且对紧凑性有特殊的需求。
该对象类型的整体格式为
0x14作为字节BYTELENGTH子VPack键/值对的类型字节NRPAIRS
尽管子VelocyPack值可以具有不同的字节大小,但根本没有索引表。BYTELENGTH和NRPAIRS以特殊格式编码,我们现在将对其进行描述。它与特殊紧凑型数组0x13相同,为完整起见,在此重复。
BYTELENGTH由1到8个字节组成,除最后一个字节外,所有字节均已设置其高位。因此,高位确定实际使用了多少个字节。所有这些位的低7位以一点字节序的形式一起构成了实际的字节长度。也就是说,地址A + 1处的字节包含字节长度的最低有效7位(0至6),地址A + 2之后的字节包含位7至13,依此类推。由于字节的总数限制为8,因此可以对多达56位的无符号整数进行编码,这是此类紧凑数组表示形式的大小的总体限制。
NRPAIRS条目的编码方式基本上相同,只是它在内存中的排列顺序相反。也就是说,必须使用BYTELENGTH来查找数组值的末尾并返回字节,直到找到高复位位的字节为止。最后一个字节(在最高的存储器地址处)包含NRPAIRS值的最低有效7位,后一个7至13位,依此类推。
这是一个示例,对象{“ a”:1,“ b”:16}可以编码如下:
14 0a
41 61 31 42 62 28 10
02
## Doubles
类型0x1b使用类型字节后的8个字节指示双IEEE-754值。为了保证平台独立性,字节顺序的详细信息如下。通过使用memcpy将内部double值复制到uint64_t来完成编码。然后,将此64位无符号整数存储为VPack值中的8位小字节序。解码的方向相反。实际上,这应该整理出IEEE-754中未确定的字节顺序。
## Dates
类型0x1c指示在类型之后紧接着以8字节小尾数补码表示的有符号64位整数。该值表示自该时期以来的通用UTC时间(以毫秒为单位),该时间是1970年1月1日UTC的00:00。
## External VPack values
此类型仅用于内存中,而不用于通过磁盘或网络进行数据交换。因此,我们仅需要指定以下k个字节为当前体系结构上char *的memcpy。该char *指向内存中其他位置的实际VPack值。
## Artifical minimal and maximal keys
这些类型0x1e和0x1f的值除了分别比较小于或大于任何其他VPack值之外没有其他意义。这个想法是可以在定义所有VPack值的总顺序以指定无限间隔的左端或右端的系统中使用它们。
## Integer types
有多种指定整数的方法。对于-6到9的小数值(包括-6)(包括0x30到0x3f),可以在单个字节中存储。此后,可以在字节类型中对有符号和无符号整数类型进行编码,这些字节类型使用的字节数(有符号的范围为0x20-0x27,无符号的范围为0x28-0x2f)。
## Null and boolean values
这三个值使用单个字节存储相应的JSON值。
## Binary data
字符串存储为UTF-8编码的字节序列。有两种变体,短的和长的。简短地说,字节长度(不是UTF-8字符的数量)直接在该类型中编码,并且可以工作至字节长度126,包括字节长度126。为此使用类型0x40至0xbe,字节长度为V -0x3f(如果V是类型字节)。对于长度超过126个字节的字符串,类型字节为0xbf,并且字符串的字节长度使用小尾数无符号整数表示形式存储在类型字节之后的前8个字节中。实际的字符串在这8个字节之后。两种情况都没有终止的零字节,并且字符串可能包含零字节。
## Binary data
字节类型0xc0至0xc7允许将任意二进制字节序列存储为VPack值。格式如下:如果V是类型字节,则V-0xbf字节跟在其后,以一个小端无符号整数表示二进制数据的长度,该整数紧随这些长度字节之后。不保证对齐。内容完全取决于用户。
## Packed BCD long floats
这些类型用于表示任意精度的十进制数字。正数和负数有不同的类型。这些值的整体格式为:
one of 0xc8 - 0xcf (positive) or of 0xd0 - 0xd7 (negative)
LENGTH OF MANTISSA in bytes
EXPONENT (as 4-byte little endian signed two's complement integer)
MANTISSA (as packed BCD-encoded integer, big-endian)
字节类型描述数字的符号以及用于指定尾数字节长度的字节数。通常,如果V是类型字节,则将V-0xc7(在正数情况下)或V-0xcf(在负数情况下)字节用作尾数的长度,并在该字节后直接存储为小端无符号整数长度。在此之后,正好跟随4个字节(小尾数有符号二进制补码整数)来指定指数。指数之后,是实际的尾数字节。
使用压缩的BCD,以便每个字节正好存储2个十进制数字,如0x34中的十进制数字34一样。因此,尾数始终为偶数个十进制数字。请注意,尾数以大尾数形式存储,以提高解析和转储效率。这导致“邪恶的半字节问题”:当JSON解析器看到一个长数字的开头时,它不知道后面是偶数还是奇数。但是,出于效率原因,它希望在读取输入时开始将字节写入输出。这就是救援的关键所在,如以下示例所示:
12345 decimal can be encoded as:
0xc8 0x03 0x00 0x00 0x00 0x00 0x01 0x23 0x45
0xc8 0x03 0xff 0xff 0xff 0xff 0x12 0x34 0x50
前一种编码在第一个字节中放置前导0并使用指数0,后一种编码直接开始在一个字节中放置两个十进制数字,然后最后必须使用由-1编码的指数-1“擦除”尾随0。 4字节序列0xff 0xff 0xff 0xff。
在那里解决了邪恶的蚕食问题,并且解析(实际上是转储)效率很高。
## Tagging
类型0xee-0xef用于标记值以实现逻辑类型。
例如,如果类型0x1c不存在,则数据库驱动程序可以将时间戳对象(JavaScript中的Date,Java中的Instant等)序列化为Unix时间戳(64位整数)。假设缺少模式,则在反序列化时,不可能从时间戳中分辨出整数并相应地反序列化该值。
类型标记通过将整数标记附加到值上来解决此问题,这些值可在反序列化值时读取,例如,tag = 1是时间戳,应使用相关的时间戳类。
标记值是分别指定的,应用程序也可以指定它们自己的名称,以使数据库驱动程序将其特定数据类型反序列化为适当的类(包括模型)。
本质上,这是文档各部分的对象关系映射。
类型的格式为:
0xee
TAG number in 1 byte
sub VPack value
要么
0xef
TAG number in 8 bytes, little-endian encoding
sub VPack value
## Custom types
请注意,自定义类型通常不应用于数据交换,而只能用于系统内部。尽管如此,本规范的这一部分仍进行了设计,使得可以通过通用方法得出每种自定义数据类型的字节长度。
存在以下用户定义的类型:
0xf0:1字节有效负载,紧随类型字节之后
0xf1:2字节有效负载,紧随类型字节之后
0xf2:4字节有效负载,紧随类型字节之后
0xf3:8字节有效负载,紧随类型字节之后
0xf4-0xf6:有效载荷的长度由紧随类型字节之后的另一个无符号字节描述,该多个字节的有效载荷如下
0xf7-0xf9:有效负载的长度由紧随类型字节之后的两个字节(小尾数无符号整数)描述,该字节的有效负载紧随其后
0xfa-0xfc:有效载荷的长度由紧随类型字节之后的四个字节(小尾数无符号整数)描述,该字节的有效载荷如下
0xfd-0xff:有效载荷的长度由紧随类型字节之后的八个字节(小尾数无符号整数)描述,该字节的有效载荷如下
注意:在类型0xf4至0xff中,“有效负载”是指不包括长度说明的实际数据。

+ 19
- 0
include/eVPack.hrl 查看文件

@ -0,0 +1,19 @@
-type vpack() :: binary() | iodata().
-type vpOpt() :: pos_integer().
-export_type([vpack/0, vpOpt/0]).
-define(vpObjNcNs, 0). %% Key
-define(vpObjNcYs, 1). %% Key
-define(vpObjYc, 2). %%
-define(vpArrNc, 0). %%
-define(vpArrYc, 1). %%
-define(VpDefObjOpt, 0). %% Obj key Obj不压缩
-define(VpDefArrOpt, 0). %% Arr不压缩
-define(VpAllOpts(Arr, Obj), Obj bsl 1 bor Arr). %% Obj Arr选项
-define(VpObjOpts(VpAllOpts), VpAllOpts bsr 1). %% Obj选项
-define(VpArrOpts(VpAllOpts), VpAllOpts band 1). %% Arr选项
-define(VpBinaryCopyRatio, 1.2).

+ 4
- 0
rebar.config 查看文件

@ -0,0 +1,4 @@
{erl_opts, [debug_info, {i, "include"}]}.
{deps, [
{erlSync, ".*", {git, "http://47.108.26.175:53000/SisMaker/erlSync.git", {branch, "master"}}}
]}.

+ 230
- 0
src/decoderTest.erl 查看文件

@ -0,0 +1,230 @@
-module(decoderTest).
-compile([no_auto_import]).
-export([
test/0
]).
test() ->
try do() of
_ ->
ok
catch
E:C:S ->
{E:C:S}
end.
do() ->
[] = erlVPack:decode(<<1>>),
#{} = erlVPack:decode(<<10>>),
illegal = erlVPack:decode(<<23>>),
nil = erlVPack:decode(<<24>>),
false = erlVPack:decode(<<25>>),
true = erlVPack:decode(<<26>>),
1.33699999999999988631e+2 = erlVPack:decode(<<27, 102, 102, 102, 102, 102, 182, 96, 64>>),
-1.33699999999999988631e+2 = erlVPack:decode(<<27, 102, 102, 102, 102, 102, 182, 96, 192>>),
609976800000 = erlVPack:decode(<<28, 0, 83, 115, 5, (-114), 0, 0, 0>>),
min_key = erlVPack:decode(<<30>>),
max_key = erlVPack:decode(<<31>>),
0 = erlVPack:decode(<<48>>),
1 = erlVPack:decode(<<49>>),
2 = erlVPack:decode(<<50>>),
3 = erlVPack:decode(<<51>>),
4 = erlVPack:decode(<<52>>),
5 = erlVPack:decode(<<53>>),
6 = erlVPack:decode(<<54>>),
7 = erlVPack:decode(<<55>>),
8 = erlVPack:decode(<<56>>),
9 = erlVPack:decode(<<57>>),
-6 = erlVPack:decode(<<58>>),
-5 = erlVPack:decode(<<59>>),
-4 = erlVPack:decode(<<60>>),
-3 = erlVPack:decode(<<61>>),
-2 = erlVPack:decode(<<62>>),
-1 = erlVPack:decode(<<63>>),
-1 = erlVPack:decode(<<32, 255>>),
127 = erlVPack:decode(<<32, 127>>),
-128 = erlVPack:decode(<<32, 128>>),
-1 = erlVPack:decode(<<33, 255, 255>>),
-1 = erlVPack:decode(<<34, 255, 255, 255>>),
-1 = erlVPack:decode(<<35, 255, 255, 255, 255>>),
-1 = erlVPack:decode(<<36, 255, 255, 255, 255, 255>>),
-1 = erlVPack:decode(<<37, 255, 255, 255, 255, 255, 255>>),
-1 = erlVPack:decode(<<38, 255, 255, 255, 255, 255, 255, 255>>),
-1 = erlVPack:decode(<<39, 255, 255, 255, 255, 255, 255, 255, 255>>),
9223372036854775807 = erlVPack:decode(<<39, 255, 255, 255, 255, 255, 255, 255, 127>>),
255 = erlVPack:decode(<<40, 255>>),
65535 = erlVPack:decode(<<41, 255, 255>>),
16777215 = erlVPack:decode(<<42, 255, 255, 255>>),
4294967295 = erlVPack:decode(<<43, 255, 255, 255, 255>>),
1099511627775 = erlVPack:decode(<<44, 255, 255, 255, 255, 255>>),
281474976710655 = erlVPack:decode(<<45, 255, 255, 255, 255, 255, 255>>),
72057594037927935 = erlVPack:decode(<<46, 255, 255, 255, 255, 255, 255, 255>>),
18446744073709551615 = erlVPack:decode(<<47, 255, 255, 255, 255, 255, 255, 255, 255>>),
<<"Hallo Welt!">> = erlVPack:decode(<<75, 72, 97, 108, 108, 111, 32, 87, 101, 108, 116, 33>>),
<<"Hello World!">> = erlVPack:decode(<<76, 72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 33>>),
Str =
<<"Lorem ipsum dolor sit amet, consectetuer "
"adipiscing elit. Aenean commodo ligula "
"eget dolor. ",
"Aenean massa. Cum sociis natoque penatibus "
"et magnis dis parturient montes, nascetur "
"ridiculus mus. ",
"Donec quam felis, ultricies nec, pellentesque "
"eu, pretium quis, sem. Nulla consequat "
"massa quis enim. ",
"Donec pede justo, fringilla vel, aliquet "
"nec, vulputate eget, arcu. In enim justo, "
"rhoncus ut, imperdiet a, ",
"venenatis vitae, justo. Nullam dictum "
"felis eu pede mollis pretium. Integer "
"tincidunt. Cras dapibus. ",
"Vivamus elementum semper nisi. Aenean "
"vulputate eleifend tellus.">>,
StrBin = <<191, 55, 2, 0, 0, 0, 0, 0, 0, 76, 111, 114, 101, 109, 32, 105, 112, 115, 117, 109, 32, 100, 111, 108, 111, 114, 32, 115,
105, 116, 32, 97, 109, 101, 116, 44, 32, 99, 111, 110, 115, 101, 99, 116, 101, 116, 117, 101, 114, 32, 97, 100,
105, 112, 105, 115, 99, 105, 110, 103, 32, 101, 108, 105, 116, 46, 32, 65, 101, 110, 101, 97, 110, 32, 99, 111,
109, 109, 111, 100, 111, 32, 108, 105, 103, 117, 108, 97, 32, 101, 103, 101, 116, 32, 100, 111, 108, 111, 114, 46,
32, 65, 101, 110, 101, 97, 110, 32, 109, 97, 115, 115, 97, 46, 32, 67, 117, 109, 32, 115, 111, 99, 105, 105,
115, 32, 110, 97, 116, 111, 113, 117, 101, 32, 112, 101, 110, 97, 116, 105, 98, 117, 115, 32, 101, 116, 32, 109,
97, 103, 110, 105, 115, 32, 100, 105, 115, 32, 112, 97, 114, 116, 117, 114, 105, 101, 110, 116, 32, 109, 111, 110,
116, 101, 115, 44, 32, 110, 97, 115, 99, 101, 116, 117, 114, 32, 114, 105, 100, 105, 99, 117, 108, 117, 115, 32,
109, 117, 115, 46, 32, 68, 111, 110, 101, 99, 32, 113, 117, 97, 109, 32, 102, 101, 108, 105, 115, 44, 32, 117, 108, 116, 114, 105,
99, 105, 101, 115, 32, 110, 101, 99, 44, 32, 112, 101, 108, 108, 101, 110, 116, 101, 115, 113, 117, 101, 32, 101,
117, 44, 32, 112, 114, 101, 116, 105, 117, 109, 32, 113, 117, 105, 115, 44, 32, 115, 101, 109, 46, 32, 78, 117,
108, 108, 97, 32, 99, 111, 110, 115, 101, 113, 117, 97, 116, 32, 109, 97, 115, 115, 97, 32, 113, 117, 105, 115, 32, 101, 110, 105,
109, 46, 32, 68, 111, 110, 101, 99, 32, 112, 101, 100, 101, 32, 106, 117, 115, 116, 111, 44, 32, 102, 114, 105, 110, 103, 105, 108,
108, 97, 32, 118, 101, 108, 44, 32, 97, 108, 105, 113, 117, 101, 116, 32, 110, 101, 99, 44, 32, 118, 117, 108,
112, 117, 116, 97, 116, 101, 32, 101, 103, 101, 116, 44, 32, 97, 114, 99, 117, 46, 32, 73, 110, 32, 101, 110,
105, 109, 32, 106, 117, 115, 116, 111, 44, 32, 114, 104, 111, 110, 99, 117, 115, 32, 117, 116, 44, 32, 105, 109, 112, 101, 114, 100,
105, 101, 116, 32, 97, 44, 32, 118, 101, 110, 101, 110, 97, 116, 105, 115, 32, 118, 105, 116, 97, 101, 44, 32, 106, 117, 115, 116,
111, 46, 32, 78, 117, 108, 108, 97, 109, 32, 100, 105, 99, 116, 117, 109, 32, 102, 101, 108, 105, 115, 32, 101,
117, 32, 112, 101, 100, 101, 32, 109, 111, 108, 108, 105, 115, 32, 112, 114, 101, 116, 105, 117, 109, 46, 32, 73,
110, 116, 101, 103, 101, 114, 32, 116, 105, 110, 99, 105, 100, 117, 110, 116, 46, 32, 67, 114, 97, 115, 32, 100,
97, 112, 105, 98, 117, 115, 46, 32, 86, 105, 118, 97, 109, 117, 115, 32, 101, 108, 101, 109, 101, 110, 116, 117,
109, 32, 115, 101, 109, 112, 101, 114, 32, 110, 105, 115, 105, 46, 32, 65, 101, 110, 101, 97, 110, 32, 118, 117,
108, 112, 117, 116, 97, 116, 101, 32, 101, 108, 101, 105, 102, 101, 110, 100, 32, 116, 101, 108, 108, 117, 115, 46>>,
Str = erlVPack:decode(StrBin),
ExBin = erlVPack:decode(<<49, 50, 51, 52, 53, 54, 55, 56, 57>>),
ExBin = erlVPack:decode(<<192, 9, 49, 50, 51, 52, 53, 54, 55, 56, 57>>),
ExBin = erlVPack:decode(<<193, 9, 0, 49, 50, 51, 52, 53, 54, 55, 56, 57>>),
ExBin = erlVPack:decode(<<194, 9, 0, 0, 49, 50, 51, 52, 53, 54, 55, 56, 57>>),
ExBin = erlVPack:decode(<<195, 9, 0, 0, 0, 49, 50, 51, 52, 53, 54, 55, 56, 57>>),
ExBin = erlVPack:decode(<<196, 9, 0, 0, 0, 0, 49, 50, 51, 52, 53, 54, 55, 56, 57>>),
ExBin = erlVPack:decode(<<197, 9, 0, 0, 0, 0, 0, 49, 50, 51, 52, 53, 54, 55, 56, 57>>),
ExBin = erlVPack:decode(<<198, 9, 0, 0, 0, 0, 0, 0, 49, 50, 51, 52, 53, 54, 55, 56, 57>>),
ExBin = erlVPack:decode(<<199, 9, 0, 0, 0, 0, 0, 0, 0, 49, 50, 51, 52, 53, 54, 55, 56, 57>>),
ExBin = [1, 2, 3],
Ex3 = erlVPack:decode(<<6, 9, 3, 49, 50, 51, 3, 4, 5>>),
Ex3 = erlVPack:decode(<<6, 10, 3, 0, 49, 50, 51, 3, 4, 5>>),
Ex3 = erlVPack:decode(<<7, 14, 0, 3, 0, 49, 50, 51, 5, 0, 6, 0, 7, 0>>),
Ex3 = erlVPack:decode(<<8, 24, 0, 0, 0, 3, 0, 0, 0, 49, 50, 51, 9, 0, 0, 0, 10, 0, 0, 0, 11, 0, 0, 0>>),
Ex3 = erlVPack:decode(<<9, 44, 0, 0, 0, 0, 0, 0, 0, 49, 50, 51, 9, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0>>),
Ex3 = erlVPack:decode(<<6, 5, 1, 49, 3>>),
Ex3 = [1],
Ex4 = [1, 2, 3],
Ex4 = erlVPack:decode(<<2, 5, 49, 50, 51>>),
Ex4 = erlVPack:decode(<<2, 6, 0, 49, 50, 51>>),
Ex4 = erlVPack:decode(<<3, 6, 0, 49, 50, 51>>),
Ex4 = erlVPack:decode(<<4, 8, 0, 0, 0, 49, 50, 51>>),
Ex4 = erlVPack:decode(<<5, 12, 0, 0, 0, 0, 0, 0, 0, 49, 50, 51>>),
[0.0] = erlVPack:decode(<<2, 11, 27, 0:64/integer-little-unsigned>>),
0 = erlVPack:decode(<<2, 11, 28, 0:64/integer-little-unsigned>>),
[1, 16] = erlVPack:decode(<<19, 6, 49, 40, 16, 2>>),
Ex5 = [[1, 2, 3], [1, 2, 3]],
Ex5 = erlVPack:decode(<<2, 12, 2, 5, 49, 50, 51, 2, 5, 49, 50, 51>>),
Ex6 = [[1, 2, 3], [1, 2, 3]],
Ex6 = erlVPack:decode(<<2, 14, 19, 6, 49, 50, 51, 3, 19, 6, 49, 50, 51, 3>>),
Ex7 = #{<<"a">> => <<"b">>},
Ex7 = erlVPack:decode(<<11, 8, 1, 65, 97, 65, 98, 3>>),
Ex8 = #{<<"a">> => 12, <<"b">> => true, <<"c">> => <<"xyz">>},
Ex8 = erlVPack:decode(<<20, 16, 65, 97, 40, 12, 65, 98, 26, 65, 99, 67, 120, 121, 122, 3>>),
Ex9 = [#{<<"a">> => 12, <<"b">> => true, <<"c">> => <<"xyz">>}, #{<<"a">> => 12, <<"b">> => true, <<"c">> => <<"xyz">>}],
Ex9 = erlVPack:decode(<<19, 35, 20, 16, 65, 97, 40, 12, 65, 98, 26, 65, 99, 67, 120, 121, 122, 3, 20, 16, 65, 97, 40, 12, 65, 98, 26, 65, 99, 67, 120, 121, 122, 3, 2>>),
Ex10 = [#{<<"key">> => 42}, <<"fooooobar">>, <<"x">>, <<1, 2, 3, 4, 5, 6, 7, 8>>],
Ex10Bin = <<2, 42, 11, 10, 1, 67, 107, 101, 121, 40, 42, 3, 73, 102, 111, 111, 111, 111, 111,
98, 97, 114, 191, 1, 0, 0, 0, 0, 0, 0, 0, 120, 192, 8, 1, 2, 3, 4, 5, 6, 7, 8>>,
Ex10 = erlVPack:decode(Ex10Bin),
_Ex11 = #{<<"0">> =>
#{<<"0">> => <<"test">>, <<"1">> => <<"test">>,
<<"2">> => <<"test">>, <<"3">> => <<"test">>,
<<"4">> => <<"test">>},
<<"1">> =>
#{<<"0">> => <<"test">>, <<"1">> => <<"test">>,
<<"2">> => <<"test">>, <<"3">> => <<"test">>,
<<"4">> => <<"test">>},
<<"2">> =>
#{<<"0">> => <<"test">>, <<"1">> => <<"test">>,
<<"2">> => <<"test">>, <<"3">> => <<"test">>,
<<"4">> => <<"test">>},
<<"3">> =>
#{<<"0">> => <<"test">>, <<"1">> => <<"test">>,
<<"2">> => <<"test">>, <<"3">> => <<"test">>,
<<"4">> => <<"test">>},
<<"4">> =>
#{<<"0">> => <<"test">>, <<"1">> => <<"test">>,
<<"2">> => <<"test">>, <<"3">> => <<"test">>,
<<"4">> => <<"test">>}},
_Ex12 = #{<<"0">> =>
#{<<"0">> => <<"test">>, <<"1">> => <<"test">>,
<<"2">> => <<"test">>, <<"3">> => <<"test">>,
<<"4">> => <<"test">>, <<"5">> => <<"test">>,
<<"6">> => <<"test">>, <<"7">> => <<"test">>,
<<"8">> => <<"test">>, <<"9">> => <<"test">>},
<<"1">> =>
#{<<"0">> => <<"test">>, <<"1">> => <<"test">>,
<<"2">> => <<"test">>, <<"3">> => <<"test">>,
<<"4">> => <<"test">>, <<"5">> => <<"test">>,
<<"6">> => <<"test">>, <<"7">> => <<"test">>,
<<"8">> => <<"test">>, <<"9">> => <<"test">>},
<<"2">> =>
#{<<"0">> => <<"test">>, <<"1">> => <<"test">>,
<<"2">> => <<"test">>, <<"3">> => <<"test">>,
<<"4">> => <<"test">>, <<"5">> => <<"test">>,
<<"6">> => <<"test">>, <<"7">> => <<"test">>,
<<"8">> => <<"test">>, <<"9">> => <<"test">>},
<<"3">> =>
#{<<"0">> => <<"test">>, <<"1">> => <<"test">>,
<<"2">> => <<"test">>, <<"3">> => <<"test">>,
<<"4">> => <<"test">>, <<"5">> => <<"test">>,
<<"6">> => <<"test">>, <<"7">> => <<"test">>,
<<"8">> => <<"test">>, <<"9">> => <<"test">>},
<<"4">> =>
#{<<"0">> => <<"test">>, <<"1">> => <<"test">>,
<<"2">> => <<"test">>, <<"3">> => <<"test">>,
<<"4">> => <<"test">>, <<"5">> => <<"test">>,
<<"6">> => <<"test">>, <<"7">> => <<"test">>,
<<"8">> => <<"test">>, <<"9">> => <<"test">>},
<<"5">> =>
#{<<"0">> => <<"test">>, <<"1">> => <<"test">>,
<<"2">> => <<"test">>, <<"3">> => <<"test">>,
<<"4">> => <<"test">>, <<"5">> => <<"test">>,
<<"6">> => <<"test">>, <<"7">> => <<"test">>,
<<"8">> => <<"test">>, <<"9">> => <<"test">>},
<<"6">> =>
#{<<"0">> => <<"test">>, <<"1">> => <<"test">>,
<<"2">> => <<"test">>, <<"3">> => <<"test">>,
<<"4">> => <<"test">>, <<"5">> => <<"test">>,
<<"6">> => <<"test">>, <<"7">> => <<"test">>,
<<"8">> => <<"test">>, <<"9">> => <<"test">>},
<<"7">> =>
#{<<"0">> => <<"test">>, <<"1">> => <<"test">>,
<<"2">> => <<"test">>, <<"3">> => <<"test">>,
<<"4">> => <<"test">>, <<"5">> => <<"test">>,
<<"6">> => <<"test">>, <<"7">> => <<"test">>,
<<"8">> => <<"test">>, <<"9">> => <<"test">>},
<<"8">> =>
#{<<"0">> => <<"test">>, <<"1">> => <<"test">>,
<<"2">> => <<"test">>, <<"3">> => <<"test">>,
<<"4">> => <<"test">>, <<"5">> => <<"test">>,
<<"6">> => <<"test">>, <<"7">> => <<"test">>,
<<"8">> => <<"test">>, <<"9">> => <<"test">>},
<<"9">> =>
#{<<"0">> => <<"test">>, <<"1">> => <<"test">>,
<<"2">> => <<"test">>, <<"3">> => <<"test">>,
<<"4">> => <<"test">>, <<"5">> => <<"test">>,
<<"6">> => <<"test">>, <<"7">> => <<"test">>,
<<"8">> => <<"test">>, <<"9">> => <<"test">>}}.

+ 14
- 0
src/eVPack.app.src 查看文件

@ -0,0 +1,14 @@
{application, eVPack,
[{description, "An OTP library"},
{vsn, "0.1.0"},
{registered, []},
{applications,
[kernel,
stdlib
]},
{env,[]},
{modules, []},
{licenses, ["Apache 2.0"]},
{links, []}
]}.

+ 1549
- 0
src/eVPack.erl
文件差异内容过多而无法显示
查看文件


+ 251
- 0
src/encoderTest.erl 查看文件

@ -0,0 +1,251 @@
-module(encoderTest).
-include("erlVPack.hrl").
-compile([no_auto_import]).
-export([
test/0
]).
test() ->
try do() of
_ ->
ok
catch
E:C:S ->
{E:C:S}
end.
do() ->
<<23>> = erlVPack:encode(illegal),
<<24>> = erlVPack:encode(nil),
<<25>> = erlVPack:encode(false),
<<26>> = erlVPack:encode(true),
<<27, 102, 102, 102, 102, 102, 182, 96, 64>> = erlVPack:encode(1.33699999999999988631e+2),
<<27, 102, 102, 102, 102, 102, 182, 96, 192>> = erlVPack:encode(-1.33699999999999988631e+2),
<<30>> = erlVPack:encode(min_key),
<<31>> = erlVPack:encode(max_key),
<<48>> = erlVPack:encode(0),
<<49>> = erlVPack:encode(1),
<<50>> = erlVPack:encode(2),
<<51>> = erlVPack:encode(3),
<<52>> = erlVPack:encode(4),
<<53>> = erlVPack:encode(5),
<<54>> = erlVPack:encode(6),
<<55>> = erlVPack:encode(7),
<<56>> = erlVPack:encode(8),
<<57>> = erlVPack:encode(9),
<<58>> = erlVPack:encode(-6),
<<59>> = erlVPack:encode(-5),
<<60>> = erlVPack:encode(-4),
<<61>> = erlVPack:encode(-3),
<<62>> = erlVPack:encode(-2),
<<63>> = erlVPack:encode(-1),
<<32, (-7)/integer-little-signed>> = erlVPack:encode(-7),
<<32, 128>> = erlVPack:encode(-128),
<<33, 0, 128>> = erlVPack:encode(-32768),
<<34, 0, 0, 128>> = erlVPack:encode(-8388608),
<<35, 0, 0, 0, 128>> = erlVPack:encode(-2147483648),
<<36, 0, 0, 0, 0, 128>> = erlVPack:encode(-549755813888),
<<37, 0, 0, 0, 0, 0, 128>> = erlVPack:encode(-140737488355328),
<<38, 0, 0, 0, 0, 0, 0, 128>> = erlVPack:encode(-36028797018963968),
<<39, 0, 0, 0, 0, 0, 0, 0, 128>> = erlVPack:encode(-9223372036854775808),
<<40, 255>> = erlVPack:encode(255),
<<41, 255, 255>> = erlVPack:encode(65535),
<<42, 255, 255, 255>> = erlVPack:encode(16777215),
<<43, 255, 255, 255, 255>> = erlVPack:encode(4294967295),
<<44, 255, 255, 255, 255, 255>> = erlVPack:encode(1099511627775),
<<45, 255, 255, 255, 255, 255, 255>> = erlVPack:encode(281474976710655),
<<46, 255, 255, 255, 255, 255, 255, 255>> = erlVPack:encode(72057594037927935),
<<47, 255, 255, 255, 255, 255, 255, 255, 255>> = erlVPack:encode(18446744073709551615),
<<75, 72, 97, 108, 108, 111, 32, 87, 101, 108, 116, 33>> = erlVPack:encode(<<"Hallo Welt!">>),
<<76, 72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 33>> = erlVPack:encode(<<"Hello World!">>),
Str = <<"Lorem ipsum dolor sit amet, consectetuer "
"adipiscing elit. Aenean commodo ligula "
"eget dolor. ",
"Aenean massa. Cum sociis natoque penatibus "
"et magnis dis parturient montes, nascetur "
"ridiculus mus. ",
"Donec quam felis, ultricies nec, pellentesque "
"eu, pretium quis, sem. Nulla consequat "
"massa quis enim. ",
"Donec pede justo, fringilla vel, aliquet "
"nec, vulputate eget, arcu. In enim justo, "
"rhoncus ut, imperdiet a, ",
"venenatis vitae, justo. Nullam dictum "
"felis eu pede mollis pretium. Integer "
"tincidunt. Cras dapibus. ",
"Vivamus elementum semper nisi. Aenean "
"vulputate eleifend tellus.">>,
StrBin = <<191, 55, 2, 0, 0, 0, 0, 0, 0, 76, 111, 114, 101, 109, 32, 105, 112, 115, 117, 109, 32, 100, 111, 108, 111,
114, 32, 115, 105, 116, 32, 97, 109, 101, 116, 44, 32, 99, 111, 110, 115, 101, 99, 116, 101, 116, 117, 101,
114, 32, 97, 100, 105, 112, 105, 115, 99, 105, 110, 103, 32, 101, 108, 105, 116, 46, 32, 65, 101, 110, 101,
97, 110, 32, 99, 111, 109, 109, 111, 100, 111, 32, 108, 105, 103, 117, 108, 97, 32, 101, 103, 101,
116, 32, 100, 111, 108, 111, 114, 46, 32, 65, 101, 110, 101, 97, 110, 32, 109, 97, 115, 115,
97, 46, 32, 67, 117, 109, 32, 115, 111, 99, 105, 105, 115, 32, 110, 97, 116, 111, 113, 117,
101, 32, 112, 101, 110, 97, 116, 105, 98, 117, 115, 32, 101, 116, 32, 109, 97, 103, 110, 105,
115, 32, 100, 105, 115, 32, 112, 97, 114, 116, 117, 114, 105, 101, 110, 116, 32, 109, 111, 110,
116, 101, 115, 44, 32, 110, 97, 115, 99, 101, 116, 117, 114, 32, 114, 105, 100, 105, 99, 117,
108, 117, 115, 32, 109, 117, 115, 46, 32, 68, 111, 110, 101, 99, 32, 113, 117, 97, 109, 32,
102, 101, 108, 105, 115, 44, 32, 117, 108, 116, 114, 105, 99, 105, 101, 115, 32, 110, 101, 99,
44, 32, 112, 101, 108, 108, 101, 110, 116, 101, 115, 113, 117, 101, 32, 101, 117, 44, 32, 112,
114, 101, 116, 105, 117, 109, 32, 113, 117, 105, 115, 44, 32, 115, 101, 109, 46, 32, 78, 117,
108, 108, 97, 32, 99, 111, 110, 115, 101, 113, 117, 97, 116, 32, 109, 97, 115, 115, 97, 32,
113, 117, 105, 115, 32, 101, 110, 105, 109, 46, 32, 68, 111, 110, 101, 99, 32, 112, 101, 100,
101, 32, 106, 117, 115, 116, 111, 44, 32, 102, 114, 105, 110, 103, 105, 108, 108, 97, 32, 118,
101, 108, 44, 32, 97, 108, 105, 113, 117, 101, 116, 32, 110, 101, 99, 44, 32, 118, 117, 108,
112, 117, 116, 97, 116, 101, 32, 101, 103, 101, 116, 44, 32, 97, 114, 99, 117, 46, 32, 73,
110, 32, 101, 110, 105, 109, 32, 106, 117, 115, 116, 111, 44, 32, 114, 104, 111, 110, 99, 117,
115, 32, 117, 116, 44, 32, 105, 109, 112, 101, 114, 100, 105, 101, 116, 32, 97, 44, 32, 118,
101, 110, 101, 110, 97, 116, 105, 115, 32, 118, 105, 116, 97, 101, 44, 32, 106, 117, 115, 116,
111, 46, 32, 78, 117, 108, 108, 97, 109, 32, 100, 105, 99, 116, 117, 109, 32, 102, 101, 108,
105, 115, 32, 101, 117, 32, 112, 101, 100, 101, 32, 109, 111, 108, 108, 105, 115, 32, 112, 114,
101, 116, 105, 117, 109, 46, 32, 73, 110, 116, 101, 103, 101, 114, 32, 116, 105, 110, 99, 105,
100, 117, 110, 116, 46, 32, 67, 114, 97, 115, 32, 100, 97, 112, 105, 98, 117, 115, 46, 32,
86, 105, 118, 97, 109, 117, 115, 32, 101, 108, 101, 109, 101, 110, 116, 117, 109, 32, 115, 101,
109, 112, 101, 114, 32, 110, 105, 115, 105, 46, 32, 65, 101, 110, 101, 97, 110, 32, 118, 117,
108, 112, 117, 116, 97, 116, 101, 32, 101, 108, 101, 105, 102, 101, 110, 100, 32, 116, 101, 108,
108, 117, 115, 46>>,
StrBin = erlVPack:encode(Str),
<<1>>, erlVPack:encode([]),
<<2, 5, "1", "2", "3">>, erlVPack:encode([1, 2, 3]),
<<19, 6, 49, 40, 16, 2>> = erlVPack:encode([1, 16], [{compact_arrays, true}]),
Arr = <<"Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. ", "Aenean massa. Cum sociis ...">>,
ArrList = [Arr, 1, 2, 42],
<<19, _/binary>> = ArrBin = erlVPack:encode(ArrList, ?vpArrYc, ?VpDefObjOpt),
ArrList = erlVPack:decode(ArrBin),
ArrLists = <<2, 12, 2, 5, 49, 50, 51, 2, 5, 49, 50, 51>>,
ArrsBin = [[1, 2, 3], [1, 2, 3]],
ArrLists = erlVPack:encode(ArrsBin),
<<10>> = erlVPack:encode(#{}),
<<11, 8, 1, 65, 97, 65, 98, 3>> = erlVPack:encode(#{<<"a">> => <<"b">>}),
<<11, 13, 2, 65, 97, 65, 98, 65, 98, 65, 97, 3, 7>> = erlVPack:encode(#{a => <<"b">>, b => <<"a">>}),
Maps = #{<<"0">> =>
#{<<"0">> => <<"test">>, <<"1">> => <<"test">>,
<<"2">> => <<"test">>, <<"3">> => <<"test">>,
<<"4">> => <<"test">>},
<<"1">> =>
#{<<"0">> => <<"test">>, <<"1">> => <<"test">>,
<<"2">> => <<"test">>, <<"3">> => <<"test">>,
<<"4">> => <<"test">>},
<<"2">> =>
#{<<"0">> => <<"test">>, <<"1">> => <<"test">>,
<<"2">> => <<"test">>, <<"3">> => <<"test">>,
<<"4">> => <<"test">>},
<<"3">> =>
#{<<"0">> => <<"test">>, <<"1">> => <<"test">>,
<<"2">> => <<"test">>, <<"3">> => <<"test">>,
<<"4">> => <<"test">>},
<<"4">> =>
#{<<"0">> => <<"test">>, <<"1">> => <<"test">>,
<<"2">> => <<"test">>, <<"3">> => <<"test">>,
<<"4">> => <<"test">>}},
MapBin = <<11, 233, 5, 65, 48, 11, 43, 5, 65, 48, 68, 116, 101, 115, 116, 65, 49, 68, 116, 101, 115, 116, 65, 50, 68, 116, 101,
115, 116, 65, 51, 68, 116, 101, 115, 116, 65, 52, 68, 116, 101, 115, 116, 3, 10, 17, 24, 31, 65, 49, 11,
43, 5, 65, 48, 68, 116, 101, 115, 116, 65, 49, 68, 116, 101, 115, 116, 65, 50, 68, 116, 101, 115, 116, 65, 51, 68, 116, 101,
115, 116, 65, 52, 68, 116, 101, 115, 116, 3, 10, 17, 24, 31, 65, 50, 11, 43, 5, 65, 48, 68, 116, 101, 115, 116, 65, 49,
68, 116, 101, 115, 116, 65, 50, 68, 116, 101, 115, 116, 65, 51, 68, 116, 101, 115, 116, 65, 52, 68, 116, 101, 115, 116, 3, 10,
17, 24, 31, 65, 51, 11, 43, 5, 65, 48, 68, 116, 101, 115, 116, 65, 49, 68, 116, 101, 115, 116, 65, 50, 68, 116, 101, 115,
116, 65, 51, 68, 116, 101, 115, 116, 65, 52, 68, 116, 101, 115, 116, 3, 10, 17, 24, 31, 65, 52, 11, 43,
5, 65, 48, 68, 116, 101, 115, 116, 65, 49, 68, 116, 101, 115, 116, 65, 50, 68, 116, 101, 115, 116, 65, 51, 68, 116, 101, 115,
116, 65, 52, 68, 116, 101, 115, 116, 3, 10, 17, 24, 31, 3, 48, 93, 138, 183>>,
MapBin = erlVPack:encode(Maps),
Mapss = #{<<"0">> =>
#{<<"0">> => <<"test">>, <<"1">> => <<"test">>,
<<"2">> => <<"test">>, <<"3">> => <<"test">>,
<<"4">> => <<"test">>, <<"5">> => <<"test">>,
<<"6">> => <<"test">>, <<"7">> => <<"test">>,
<<"8">> => <<"test">>, <<"9">> => <<"test">>},
<<"1">> =>
#{<<"0">> => <<"test">>, <<"1">> => <<"test">>,
<<"2">> => <<"test">>, <<"3">> => <<"test">>,
<<"4">> => <<"test">>, <<"5">> => <<"test">>,
<<"6">> => <<"test">>, <<"7">> => <<"test">>,
<<"8">> => <<"test">>, <<"9">> => <<"test">>},
<<"2">> =>
#{<<"0">> => <<"test">>, <<"1">> => <<"test">>,
<<"2">> => <<"test">>, <<"3">> => <<"test">>,
<<"4">> => <<"test">>, <<"5">> => <<"test">>,
<<"6">> => <<"test">>, <<"7">> => <<"test">>,
<<"8">> => <<"test">>, <<"9">> => <<"test">>},
<<"3">> =>
#{<<"0">> => <<"test">>, <<"1">> => <<"test">>,
<<"2">> => <<"test">>, <<"3">> => <<"test">>,
<<"4">> => <<"test">>, <<"5">> => <<"test">>,
<<"6">> => <<"test">>, <<"7">> => <<"test">>,
<<"8">> => <<"test">>, <<"9">> => <<"test">>},
<<"4">> =>
#{<<"0">> => <<"test">>, <<"1">> => <<"test">>,
<<"2">> => <<"test">>, <<"3">> => <<"test">>,
<<"4">> => <<"test">>, <<"5">> => <<"test">>,
<<"6">> => <<"test">>, <<"7">> => <<"test">>,
<<"8">> => <<"test">>, <<"9">> => <<"test">>},
<<"5">> =>
#{<<"0">> => <<"test">>, <<"1">> => <<"test">>,
<<"2">> => <<"test">>, <<"3">> => <<"test">>,
<<"4">> => <<"test">>, <<"5">> => <<"test">>,
<<"6">> => <<"test">>, <<"7">> => <<"test">>,
<<"8">> => <<"test">>, <<"9">> => <<"test">>},
<<"6">> =>
#{<<"0">> => <<"test">>, <<"1">> => <<"test">>,
<<"2">> => <<"test">>, <<"3">> => <<"test">>,
<<"4">> => <<"test">>, <<"5">> => <<"test">>,
<<"6">> => <<"test">>, <<"7">> => <<"test">>,
<<"8">> => <<"test">>, <<"9">> => <<"test">>},
<<"7">> =>
#{<<"0">> => <<"test">>, <<"1">> => <<"test">>,
<<"2">> => <<"test">>, <<"3">> => <<"test">>,
<<"4">> => <<"test">>, <<"5">> => <<"test">>,
<<"6">> => <<"test">>, <<"7">> => <<"test">>,
<<"8">> => <<"test">>, <<"9">> => <<"test">>},
<<"8">> =>
#{<<"0">> => <<"test">>, <<"1">> => <<"test">>,
<<"2">> => <<"test">>, <<"3">> => <<"test">>,
<<"4">> => <<"test">>, <<"5">> => <<"test">>,
<<"6">> => <<"test">>, <<"7">> => <<"test">>,
<<"8">> => <<"test">>, <<"9">> => <<"test">>},
<<"9">> =>
#{<<"0">> => <<"test">>, <<"1">> => <<"test">>,
<<"2">> => <<"test">>, <<"3">> => <<"test">>,
<<"4">> => <<"test">>, <<"5">> => <<"test">>,
<<"6">> => <<"test">>, <<"7">> => <<"test">>,
<<"8">> => <<"test">>, <<"9">> => <<"test">>}},
MapsBin = <<12, 107, 3, 10, 0, 65, 48, 11, 83, 10, 65, 48, 68, 116, 101, 115, 116, 65, 49, 68, 116, 101, 115, 116, 65, 50, 68,
116, 101, 115, 116, 65, 51, 68, 116, 101, 115, 116, 65, 52, 68, 116, 101, 115, 116, 65, 53, 68, 116, 101, 115, 116, 65, 54, 68, 116, 101, 115, 116,
65, 55, 68, 116, 101, 115, 116, 65, 56, 68, 116, 101, 115, 116, 65, 57, 68, 116, 101, 115, 116, 3, 10, 17, 24, 31, 38, 45,
52, 59, 66, 65, 49, 11, 83, 10, 65, 48, 68, 116, 101, 115, 116, 65, 49, 68, 116, 101, 115, 116, 65, 50, 68, 116, 101, 115,
116, 65, 51, 68, 116, 101, 115, 116, 65, 52, 68, 116, 101, 115, 116, 65, 53, 68, 116, 101, 115, 116, 65, 54,
68, 116, 101, 115, 116, 65, 55, 68, 116, 101, 115, 116, 65, 56, 68, 116, 101, 115, 116, 65, 57, 68, 116, 101,
115, 116, 3, 10, 17, 24, 31, 38, 45, 52, 59, 66, 65, 50, 11, 83, 10, 65, 48, 68, 116, 101, 115, 116,
65, 49, 68, 116, 101, 115, 116, 65, 50, 68, 116, 101, 115, 116, 65, 51, 68, 116, 101, 115, 116, 65, 52, 68,
116, 101, 115, 116, 65, 53, 68, 116, 101, 115, 116, 65, 54, 68, 116, 101, 115, 116, 65, 55, 68, 116, 101, 115,
116, 65, 56, 68, 116, 101, 115, 116, 65, 57, 68, 116, 101, 115, 116, 3, 10, 17, 24, 31, 38, 45, 52, 59,
66, 65, 51, 11, 83, 10, 65, 48, 68, 116, 101, 115, 116, 65, 49, 68, 116, 101, 115, 116, 65, 50, 68, 116, 101, 115, 116, 65,
51, 68, 116, 101, 115, 116, 65, 52, 68, 116, 101, 115, 116, 65, 53, 68, 116, 101, 115, 116, 65, 54, 68, 116,
101, 115, 116, 65, 55, 68, 116, 101, 115, 116, 65, 56, 68, 116, 101, 115, 116, 65, 57, 68, 116, 101, 115, 116,
3, 10, 17, 24, 31, 38, 45, 52, 59, 66, 65, 52, 11, 83, 10, 65, 48, 68, 116, 101, 115, 116, 65, 49,
68, 116, 101, 115, 116, 65, 50, 68, 116, 101, 115, 116, 65, 51, 68, 116, 101, 115, 116, 65, 52, 68, 116, 101, 115, 116, 65, 53,
68, 116, 101, 115, 116, 65, 54, 68, 116, 101, 115, 116, 65, 55, 68, 116, 101, 115, 116, 65, 56, 68, 116, 101, 115, 116, 65, 57,
68, 116, 101, 115, 116, 3, 10, 17, 24, 31, 38, 45, 52, 59, 66, 65, 53, 11, 83, 10, 65, 48, 68, 116, 101, 115, 116, 65,
49, 68, 116, 101, 115, 116, 65, 50, 68, 116, 101, 115, 116, 65, 51, 68, 116, 101, 115, 116, 65, 52, 68, 116,
101, 115, 116, 65, 53, 68, 116, 101, 115, 116, 65, 54, 68, 116, 101, 115, 116, 65, 55, 68, 116, 101, 115, 116,
65, 56, 68, 116, 101, 115, 116, 65, 57, 68, 116, 101, 115, 116, 3, 10, 17, 24, 31, 38, 45, 52, 59, 66,
65, 54, 11, 83, 10, 65, 48, 68, 116, 101, 115, 116, 65, 49, 68, 116, 101, 115, 116, 65, 50, 68, 116, 101, 115, 116, 65, 51, 68, 116, 101, 115,
116, 65, 52, 68, 116, 101, 115, 116, 65, 53, 68, 116, 101, 115, 116, 65, 54, 68, 116, 101, 115, 116, 65, 55,
68, 116, 101, 115, 116, 65, 56, 68, 116, 101, 115, 116, 65, 57, 68, 116, 101, 115, 116, 3, 10, 17, 24, 31,
38, 45, 52, 59, 66, 65, 55, 11, 83, 10, 65, 48, 68, 116, 101, 115, 116, 65, 49, 68, 116, 101, 115, 116, 65, 50, 68, 116,
101, 115, 116, 65, 51, 68, 116, 101, 115, 116, 65, 52, 68, 116, 101, 115, 116, 65, 53, 68, 116, 101, 115, 116, 65, 54, 68, 116,
101, 115, 116, 65, 55, 68, 116, 101, 115, 116, 65, 56, 68, 116, 101, 115, 116, 65, 57, 68, 116, 101, 115, 116, 3, 10, 17, 24,
31, 38, 45, 52, 59, 66, 65, 56, 11, 83, 10, 65, 48, 68, 116, 101, 115, 116, 65, 49, 68, 116, 101, 115, 116, 65, 50, 68,
116, 101, 115, 116, 65, 51, 68, 116, 101, 115, 116, 65, 52, 68, 116, 101, 115, 116, 65, 53, 68, 116, 101, 115, 116, 65, 54, 68,
116, 101, 115, 116, 65, 55, 68, 116, 101, 115, 116, 65, 56, 68, 116, 101, 115, 116, 65, 57, 68, 116, 101, 115, 116, 3, 10, 17,
24, 31, 38, 45, 52, 59, 66, 65, 57, 11, 83, 10, 65, 48, 68, 116, 101, 115, 116, 65, 49, 68, 116, 101, 115, 116, 65, 50,
68, 116, 101, 115, 116, 65, 51, 68, 116, 101, 115, 116, 65, 52, 68, 116, 101, 115, 116, 65, 53, 68, 116, 101, 115, 116, 65, 54,
68, 116, 101, 115, 116, 65, 55, 68, 116, 101, 115, 116, 65, 56, 68, 116, 101, 115, 116, 65, 57, 68, 116, 101,
115, 116, 3, 10, 17, 24, 31, 38, 45, 52, 59, 66, 5, 0, 90, 0, 175, 0, 4, 1, 89, 1, 174, 1, 3, 2, 88, 2, 173, 2, 2, 3>>,
MapsBin = erlVPack:encode(Mapss),
MapCom = #{<<"a">> => 12, <<"b">> => true, <<"c">> => <<"xyz">>},
MapComBin = <<20, 16, 65, 97, 40, 12, 65, 98, 26, 65, 99, 67, 120, 121, 122, 3>>,
MapComBin = erlVPack:encode(MapCom, ?VpDefArrOpt, ?vpObjYc).

正在加载...
取消
保存