Merge branch 'release/1.0.0'
This commit is contained in:
		
							
								
								
									
										162
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										162
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,162 @@
 | 
			
		||||
# Created by https://www.gitignore.io
 | 
			
		||||
 | 
			
		||||
*.log
 | 
			
		||||
 | 
			
		||||
### Gradle ###
 | 
			
		||||
.gradle
 | 
			
		||||
build/
 | 
			
		||||
classes/
 | 
			
		||||
 | 
			
		||||
# Ignore Gradle GUI config
 | 
			
		||||
gradle-app.setting
 | 
			
		||||
 | 
			
		||||
# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored)
 | 
			
		||||
!gradle-wrapper.jar
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### Intellij ###
 | 
			
		||||
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm
 | 
			
		||||
 | 
			
		||||
*.iml
 | 
			
		||||
 | 
			
		||||
## Directory-based project format:
 | 
			
		||||
.idea/
 | 
			
		||||
# if you remove the above rule, at least ignore the following:
 | 
			
		||||
 | 
			
		||||
# User-specific stuff:
 | 
			
		||||
# .idea/workspace.xml
 | 
			
		||||
# .idea/tasks.xml
 | 
			
		||||
# .idea/dictionaries
 | 
			
		||||
 | 
			
		||||
# Sensitive or high-churn files:
 | 
			
		||||
# .idea/dataSources.ids
 | 
			
		||||
# .idea/dataSources.xml
 | 
			
		||||
# .idea/sqlDataSources.xml
 | 
			
		||||
# .idea/dynamic.xml
 | 
			
		||||
# .idea/uiDesigner.xml
 | 
			
		||||
 | 
			
		||||
# Gradle:
 | 
			
		||||
# .idea/gradle.xml
 | 
			
		||||
# .idea/libraries
 | 
			
		||||
 | 
			
		||||
# Mongo Explorer plugin:
 | 
			
		||||
# .idea/mongoSettings.xml
 | 
			
		||||
 | 
			
		||||
## File-based project format:
 | 
			
		||||
*.ipr
 | 
			
		||||
*.iws
 | 
			
		||||
 | 
			
		||||
## Plugin-specific files:
 | 
			
		||||
 | 
			
		||||
# IntelliJ
 | 
			
		||||
/out/
 | 
			
		||||
 | 
			
		||||
# mpeltonen/sbt-idea plugin
 | 
			
		||||
.idea_modules/
 | 
			
		||||
 | 
			
		||||
# JIRA plugin
 | 
			
		||||
atlassian-ide-plugin.xml
 | 
			
		||||
 | 
			
		||||
# Crashlytics plugin (for Android Studio and IntelliJ)
 | 
			
		||||
com_crashlytics_export_strings.xml
 | 
			
		||||
crashlytics.properties
 | 
			
		||||
crashlytics-build.properties
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### Eclipse ###
 | 
			
		||||
*.pydevproject
 | 
			
		||||
.metadata
 | 
			
		||||
.gradle
 | 
			
		||||
bin/
 | 
			
		||||
tmp/
 | 
			
		||||
*.tmp
 | 
			
		||||
*.bak
 | 
			
		||||
*.swp
 | 
			
		||||
*~.nib
 | 
			
		||||
local.properties
 | 
			
		||||
.settings/
 | 
			
		||||
.loadpath
 | 
			
		||||
 | 
			
		||||
# Eclipse Core
 | 
			
		||||
.project
 | 
			
		||||
 | 
			
		||||
# External tool builders
 | 
			
		||||
.externalToolBuilders/
 | 
			
		||||
 | 
			
		||||
# Locally stored "Eclipse launch configurations"
 | 
			
		||||
*.launch
 | 
			
		||||
 | 
			
		||||
# CDT-specific
 | 
			
		||||
.cproject
 | 
			
		||||
 | 
			
		||||
# JDT-specific (Eclipse Java Development Tools)
 | 
			
		||||
.classpath
 | 
			
		||||
 | 
			
		||||
# PDT-specific
 | 
			
		||||
.buildpath
 | 
			
		||||
 | 
			
		||||
# sbteclipse plugin
 | 
			
		||||
.target
 | 
			
		||||
 | 
			
		||||
# TeXlipse plugin
 | 
			
		||||
.texlipse
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### Linux ###
 | 
			
		||||
*~
 | 
			
		||||
 | 
			
		||||
# KDE directory preferences
 | 
			
		||||
.directory
 | 
			
		||||
 | 
			
		||||
# Linux trash folder which might appear on any partition or disk
 | 
			
		||||
.Trash-*
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### OSX ###
 | 
			
		||||
.DS_Store
 | 
			
		||||
.AppleDouble
 | 
			
		||||
.LSOverride
 | 
			
		||||
 | 
			
		||||
# Icon must end with two \r
 | 
			
		||||
Icon
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Thumbnails
 | 
			
		||||
._*
 | 
			
		||||
 | 
			
		||||
# Files that might appear in the root of a volume
 | 
			
		||||
.DocumentRevisions-V100
 | 
			
		||||
.fseventsd
 | 
			
		||||
.Spotlight-V100
 | 
			
		||||
.TemporaryItems
 | 
			
		||||
.Trashes
 | 
			
		||||
.VolumeIcon.icns
 | 
			
		||||
 | 
			
		||||
# Directories potentially created on remote AFP share
 | 
			
		||||
.AppleDB
 | 
			
		||||
.AppleDesktop
 | 
			
		||||
Network Trash Folder
 | 
			
		||||
Temporary Items
 | 
			
		||||
.apdisk
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### Windows ###
 | 
			
		||||
# Windows image file caches
 | 
			
		||||
Thumbs.db
 | 
			
		||||
ehthumbs.db
 | 
			
		||||
 | 
			
		||||
# Folder config file
 | 
			
		||||
Desktop.ini
 | 
			
		||||
 | 
			
		||||
# Recycle Bin used on file shares
 | 
			
		||||
$RECYCLE.BIN/
 | 
			
		||||
 | 
			
		||||
# Windows Installer files
 | 
			
		||||
*.cab
 | 
			
		||||
*.msi
 | 
			
		||||
*.msm
 | 
			
		||||
*.msp
 | 
			
		||||
 | 
			
		||||
# Windows shortcuts
 | 
			
		||||
*.lnk
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										10
									
								
								.travis.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								.travis.yml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,10 @@
 | 
			
		||||
language: java
 | 
			
		||||
sudo: false # faster builds
 | 
			
		||||
jdk:
 | 
			
		||||
  - oraclejdk8
 | 
			
		||||
 | 
			
		||||
before_install:
 | 
			
		||||
  - pip install --user codecov
 | 
			
		||||
 | 
			
		||||
after_success:
 | 
			
		||||
  - codecov
 | 
			
		||||
							
								
								
									
										201
									
								
								LICENSE
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										201
									
								
								LICENSE
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,201 @@
 | 
			
		||||
                                 Apache License
 | 
			
		||||
                           Version 2.0, January 2004
 | 
			
		||||
                        http://www.apache.org/licenses/
 | 
			
		||||
 | 
			
		||||
   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
 | 
			
		||||
 | 
			
		||||
   1. Definitions.
 | 
			
		||||
 | 
			
		||||
      "License" shall mean the terms and conditions for use, reproduction,
 | 
			
		||||
      and distribution as defined by Sections 1 through 9 of this document.
 | 
			
		||||
 | 
			
		||||
      "Licensor" shall mean the copyright owner or entity authorized by
 | 
			
		||||
      the copyright owner that is granting the License.
 | 
			
		||||
 | 
			
		||||
      "Legal Entity" shall mean the union of the acting entity and all
 | 
			
		||||
      other entities that control, are controlled by, or are under common
 | 
			
		||||
      control with that entity. For the purposes of this definition,
 | 
			
		||||
      "control" means (i) the power, direct or indirect, to cause the
 | 
			
		||||
      direction or management of such entity, whether by contract or
 | 
			
		||||
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
 | 
			
		||||
      outstanding shares, or (iii) beneficial ownership of such entity.
 | 
			
		||||
 | 
			
		||||
      "You" (or "Your") shall mean an individual or Legal Entity
 | 
			
		||||
      exercising permissions granted by this License.
 | 
			
		||||
 | 
			
		||||
      "Source" form shall mean the preferred form for making modifications,
 | 
			
		||||
      including but not limited to software source code, documentation
 | 
			
		||||
      source, and configuration files.
 | 
			
		||||
 | 
			
		||||
      "Object" form shall mean any form resulting from mechanical
 | 
			
		||||
      transformation or translation of a Source form, including but
 | 
			
		||||
      not limited to compiled object code, generated documentation,
 | 
			
		||||
      and conversions to other media types.
 | 
			
		||||
 | 
			
		||||
      "Work" shall mean the work of authorship, whether in Source or
 | 
			
		||||
      Object form, made available under the License, as indicated by a
 | 
			
		||||
      copyright notice that is included in or attached to the work
 | 
			
		||||
      (an example is provided in the Appendix below).
 | 
			
		||||
 | 
			
		||||
      "Derivative Works" shall mean any work, whether in Source or Object
 | 
			
		||||
      form, that is based on (or derived from) the Work and for which the
 | 
			
		||||
      editorial revisions, annotations, elaborations, or other modifications
 | 
			
		||||
      represent, as a whole, an original work of authorship. For the purposes
 | 
			
		||||
      of this License, Derivative Works shall not include works that remain
 | 
			
		||||
      separable from, or merely link (or bind by name) to the interfaces of,
 | 
			
		||||
      the Work and Derivative Works thereof.
 | 
			
		||||
 | 
			
		||||
      "Contribution" shall mean any work of authorship, including
 | 
			
		||||
      the original version of the Work and any modifications or additions
 | 
			
		||||
      to that Work or Derivative Works thereof, that is intentionally
 | 
			
		||||
      submitted to Licensor for inclusion in the Work by the copyright owner
 | 
			
		||||
      or by an individual or Legal Entity authorized to submit on behalf of
 | 
			
		||||
      the copyright owner. For the purposes of this definition, "submitted"
 | 
			
		||||
      means any form of electronic, verbal, or written communication sent
 | 
			
		||||
      to the Licensor or its representatives, including but not limited to
 | 
			
		||||
      communication on electronic mailing lists, source code control systems,
 | 
			
		||||
      and issue tracking systems that are managed by, or on behalf of, the
 | 
			
		||||
      Licensor for the purpose of discussing and improving the Work, but
 | 
			
		||||
      excluding communication that is conspicuously marked or otherwise
 | 
			
		||||
      designated in writing by the copyright owner as "Not a Contribution."
 | 
			
		||||
 | 
			
		||||
      "Contributor" shall mean Licensor and any individual or Legal Entity
 | 
			
		||||
      on behalf of whom a Contribution has been received by Licensor and
 | 
			
		||||
      subsequently incorporated within the Work.
 | 
			
		||||
 | 
			
		||||
   2. Grant of Copyright License. Subject to the terms and conditions of
 | 
			
		||||
      this License, each Contributor hereby grants to You a perpetual,
 | 
			
		||||
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
 | 
			
		||||
      copyright license to reproduce, prepare Derivative Works of,
 | 
			
		||||
      publicly display, publicly perform, sublicense, and distribute the
 | 
			
		||||
      Work and such Derivative Works in Source or Object form.
 | 
			
		||||
 | 
			
		||||
   3. Grant of Patent License. Subject to the terms and conditions of
 | 
			
		||||
      this License, each Contributor hereby grants to You a perpetual,
 | 
			
		||||
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
 | 
			
		||||
      (except as stated in this section) patent license to make, have made,
 | 
			
		||||
      use, offer to sell, sell, import, and otherwise transfer the Work,
 | 
			
		||||
      where such license applies only to those patent claims licensable
 | 
			
		||||
      by such Contributor that are necessarily infringed by their
 | 
			
		||||
      Contribution(s) alone or by combination of their Contribution(s)
 | 
			
		||||
      with the Work to which such Contribution(s) was submitted. If You
 | 
			
		||||
      institute patent litigation against any entity (including a
 | 
			
		||||
      cross-claim or counterclaim in a lawsuit) alleging that the Work
 | 
			
		||||
      or a Contribution incorporated within the Work constitutes direct
 | 
			
		||||
      or contributory patent infringement, then any patent licenses
 | 
			
		||||
      granted to You under this License for that Work shall terminate
 | 
			
		||||
      as of the date such litigation is filed.
 | 
			
		||||
 | 
			
		||||
   4. Redistribution. You may reproduce and distribute copies of the
 | 
			
		||||
      Work or Derivative Works thereof in any medium, with or without
 | 
			
		||||
      modifications, and in Source or Object form, provided that You
 | 
			
		||||
      meet the following conditions:
 | 
			
		||||
 | 
			
		||||
      (a) You must give any other recipients of the Work or
 | 
			
		||||
          Derivative Works a copy of this License; and
 | 
			
		||||
 | 
			
		||||
      (b) You must cause any modified files to carry prominent notices
 | 
			
		||||
          stating that You changed the files; and
 | 
			
		||||
 | 
			
		||||
      (c) You must retain, in the Source form of any Derivative Works
 | 
			
		||||
          that You distribute, all copyright, patent, trademark, and
 | 
			
		||||
          attribution notices from the Source form of the Work,
 | 
			
		||||
          excluding those notices that do not pertain to any part of
 | 
			
		||||
          the Derivative Works; and
 | 
			
		||||
 | 
			
		||||
      (d) If the Work includes a "NOTICE" text file as part of its
 | 
			
		||||
          distribution, then any Derivative Works that You distribute must
 | 
			
		||||
          include a readable copy of the attribution notices contained
 | 
			
		||||
          within such NOTICE file, excluding those notices that do not
 | 
			
		||||
          pertain to any part of the Derivative Works, in at least one
 | 
			
		||||
          of the following places: within a NOTICE text file distributed
 | 
			
		||||
          as part of the Derivative Works; within the Source form or
 | 
			
		||||
          documentation, if provided along with the Derivative Works; or,
 | 
			
		||||
          within a display generated by the Derivative Works, if and
 | 
			
		||||
          wherever such third-party notices normally appear. The contents
 | 
			
		||||
          of the NOTICE file are for informational purposes only and
 | 
			
		||||
          do not modify the License. You may add Your own attribution
 | 
			
		||||
          notices within Derivative Works that You distribute, alongside
 | 
			
		||||
          or as an addendum to the NOTICE text from the Work, provided
 | 
			
		||||
          that such additional attribution notices cannot be construed
 | 
			
		||||
          as modifying the License.
 | 
			
		||||
 | 
			
		||||
      You may add Your own copyright statement to Your modifications and
 | 
			
		||||
      may provide additional or different license terms and conditions
 | 
			
		||||
      for use, reproduction, or distribution of Your modifications, or
 | 
			
		||||
      for any such Derivative Works as a whole, provided Your use,
 | 
			
		||||
      reproduction, and distribution of the Work otherwise complies with
 | 
			
		||||
      the conditions stated in this License.
 | 
			
		||||
 | 
			
		||||
   5. Submission of Contributions. Unless You explicitly state otherwise,
 | 
			
		||||
      any Contribution intentionally submitted for inclusion in the Work
 | 
			
		||||
      by You to the Licensor shall be under the terms and conditions of
 | 
			
		||||
      this License, without any additional terms or conditions.
 | 
			
		||||
      Notwithstanding the above, nothing herein shall supersede or modify
 | 
			
		||||
      the terms of any separate license agreement you may have executed
 | 
			
		||||
      with Licensor regarding such Contributions.
 | 
			
		||||
 | 
			
		||||
   6. Trademarks. This License does not grant permission to use the trade
 | 
			
		||||
      names, trademarks, service marks, or product names of the Licensor,
 | 
			
		||||
      except as required for reasonable and customary use in describing the
 | 
			
		||||
      origin of the Work and reproducing the content of the NOTICE file.
 | 
			
		||||
 | 
			
		||||
   7. Disclaimer of Warranty. Unless required by applicable law or
 | 
			
		||||
      agreed to in writing, Licensor provides the Work (and each
 | 
			
		||||
      Contributor provides its Contributions) on an "AS IS" BASIS,
 | 
			
		||||
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 | 
			
		||||
      implied, including, without limitation, any warranties or conditions
 | 
			
		||||
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
 | 
			
		||||
      PARTICULAR PURPOSE. You are solely responsible for determining the
 | 
			
		||||
      appropriateness of using or redistributing the Work and assume any
 | 
			
		||||
      risks associated with Your exercise of permissions under this License.
 | 
			
		||||
 | 
			
		||||
   8. Limitation of Liability. In no event and under no legal theory,
 | 
			
		||||
      whether in tort (including negligence), contract, or otherwise,
 | 
			
		||||
      unless required by applicable law (such as deliberate and grossly
 | 
			
		||||
      negligent acts) or agreed to in writing, shall any Contributor be
 | 
			
		||||
      liable to You for damages, including any direct, indirect, special,
 | 
			
		||||
      incidental, or consequential damages of any character arising as a
 | 
			
		||||
      result of this License or out of the use or inability to use the
 | 
			
		||||
      Work (including but not limited to damages for loss of goodwill,
 | 
			
		||||
      work stoppage, computer failure or malfunction, or any and all
 | 
			
		||||
      other commercial damages or losses), even if such Contributor
 | 
			
		||||
      has been advised of the possibility of such damages.
 | 
			
		||||
 | 
			
		||||
   9. Accepting Warranty or Additional Liability. While redistributing
 | 
			
		||||
      the Work or Derivative Works thereof, You may choose to offer,
 | 
			
		||||
      and charge a fee for, acceptance of support, warranty, indemnity,
 | 
			
		||||
      or other liability obligations and/or rights consistent with this
 | 
			
		||||
      License. However, in accepting such obligations, You may act only
 | 
			
		||||
      on Your own behalf and on Your sole responsibility, not on behalf
 | 
			
		||||
      of any other Contributor, and only if You agree to indemnify,
 | 
			
		||||
      defend, and hold each Contributor harmless for any liability
 | 
			
		||||
      incurred by, or claims asserted against, such Contributor by reason
 | 
			
		||||
      of your accepting any such warranty or additional liability.
 | 
			
		||||
 | 
			
		||||
   END OF TERMS AND CONDITIONS
 | 
			
		||||
 | 
			
		||||
   APPENDIX: How to apply the Apache License to your work.
 | 
			
		||||
 | 
			
		||||
      To apply the Apache License to your work, attach the following
 | 
			
		||||
      boilerplate notice, with the fields enclosed by brackets "{}"
 | 
			
		||||
      replaced with your own identifying information. (Don't include
 | 
			
		||||
      the brackets!)  The text should be enclosed in the appropriate
 | 
			
		||||
      comment syntax for the file format. We also recommend that a
 | 
			
		||||
      file or class name and description of purpose be included on the
 | 
			
		||||
      same "printed page" as the copyright notice for easier
 | 
			
		||||
      identification within third-party archives.
 | 
			
		||||
 | 
			
		||||
   Copyright {yyyy} {name of copyright owner}
 | 
			
		||||
 | 
			
		||||
   Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
   you may not use this file except in compliance with the License.
 | 
			
		||||
   You may obtain a copy of the License at
 | 
			
		||||
 | 
			
		||||
       http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 | 
			
		||||
   Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
   distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
   See the License for the specific language governing permissions and
 | 
			
		||||
   limitations under the License.
 | 
			
		||||
							
								
								
									
										87
									
								
								README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								README.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,87 @@
 | 
			
		||||
Simple MessagePack
 | 
			
		||||
==================
 | 
			
		||||
[](https://maven-badges.herokuapp.com/maven-central/ch.dissem.msgpack/msgpack)
 | 
			
		||||
[](http://www.javadoc.io/doc/ch.dissem.msgpack/msgpack)
 | 
			
		||||
[](https://raw.githubusercontent.com/Dissem/Jabit/master/LICENSE)
 | 
			
		||||
 | 
			
		||||
This is a simple Java library for handling MessagePack data. It doesn't do any object mapping, but maps to special
 | 
			
		||||
objects representing MessagePack types. To build, use command `./gradlew build`.
 | 
			
		||||
 | 
			
		||||
For most cases you might be better off using `org.msgpack:msgpack`, but I found that I needed something that generically
 | 
			
		||||
represents the internal structure of the data.
 | 
			
		||||
 | 
			
		||||
_Simple MessagePack_ uses Semantic Versioning, meaning as long as the major version doesn't change, nothing should break if you
 | 
			
		||||
update. Be aware though that this doesn't necessarily applies for SNAPSHOT builds and the development branch.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#### Master
 | 
			
		||||
[](https://travis-ci.org/Dissem/MsgPack) 
 | 
			
		||||
[](https://www.codacy.com/app/chrigu-meyer/MsgPack/dashboard?bid=4122049)
 | 
			
		||||
[](https://codecov.io/github/Dissem/MsgPack?branch=master)
 | 
			
		||||
 | 
			
		||||
#### Develop
 | 
			
		||||
[](https://travis-ci.org/Dissem/MsgPack?branch=develop) 
 | 
			
		||||
[](https://www.codacy.com/app/chrigu-meyer/MsgPack/dashboard?bid=4118049)
 | 
			
		||||
[](https://codecov.io/github/Dissem/MsgPack?branch=develop)
 | 
			
		||||
 | 
			
		||||
Limitations
 | 
			
		||||
--------------
 | 
			
		||||
 | 
			
		||||
* There is no fallback to BigInteger for large integer type numbers, so there might be an integer overflow when reading
 | 
			
		||||
  too large numbers
 | 
			
		||||
* `MPFloat` uses the data type you're using to decide on precision (float 32 or 64) - not the actual value. E.g. 0.5
 | 
			
		||||
  could be saved perfectly as a float 42, but if you provide a double value, it will be stored as float 64, wasting
 | 
			
		||||
  4 bytes.
 | 
			
		||||
* If you want to use the 'ext format family', you'll need to implement and register your own `MPType` and
 | 
			
		||||
  `MPType.Unpacker`.
 | 
			
		||||
* Be aware that custom `MPType.Unpacker` take precedence over the default unpackers, i.e. if you accidentally define
 | 
			
		||||
  your unpacker to handle strings, for example, you won't be able to unpack any regular strings anymore.
 | 
			
		||||
 | 
			
		||||
Setup
 | 
			
		||||
-----
 | 
			
		||||
 | 
			
		||||
Add msgpack as Gradle dependency:
 | 
			
		||||
```Gradle
 | 
			
		||||
compile "ch.dissem.msgpack:msgpack:1.0.0"
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Usage
 | 
			
		||||
-----
 | 
			
		||||
 | 
			
		||||
### Serialize Data
 | 
			
		||||
 | 
			
		||||
First, you'll need to create some msgpack objects to serialize:
 | 
			
		||||
```Java
 | 
			
		||||
MPMap<MPString, MPType<?>> object = new MPMap<>();
 | 
			
		||||
object.put(new MPString("compact"), new MPBoolean(true));
 | 
			
		||||
object.put(new MPString("schema"), new MPInteger(0));
 | 
			
		||||
```
 | 
			
		||||
or the shorthand version for simple types:
 | 
			
		||||
```Java
 | 
			
		||||
import static ch.dissem.msgpack.types.Utils.mp;
 | 
			
		||||
 | 
			
		||||
MPMap<MPString, MPType<?>> object = new MPMap<>();
 | 
			
		||||
object.put(mp("compact"), mp(true));
 | 
			
		||||
object.put(mp("schema"), mp(0));
 | 
			
		||||
```
 | 
			
		||||
then just use `pack(OutputStream)`:
 | 
			
		||||
```Java
 | 
			
		||||
OutputStream out = ...;
 | 
			
		||||
object.pack(out);
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### Deserialize Data
 | 
			
		||||
 | 
			
		||||
For deserializing data there is the reader object:
 | 
			
		||||
```Java
 | 
			
		||||
Reader reader = Reader.getInstance()
 | 
			
		||||
```
 | 
			
		||||
just use `reader.read(InputStream)`. Unfortunately you'll need to make sure you got what you expected, the following
 | 
			
		||||
example might result in `ClassCastException` at weird places:
 | 
			
		||||
```Java
 | 
			
		||||
InputStream in = ...;
 | 
			
		||||
MPType read = reader.read(in);
 | 
			
		||||
MPMap<MPString, MPString> map = (MPMap<MPString, MPString>) read;
 | 
			
		||||
String value = map.get(mp("key")).getValue();
 | 
			
		||||
```
 | 
			
		||||
							
								
								
									
										92
									
								
								build.gradle
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										92
									
								
								build.gradle
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,92 @@
 | 
			
		||||
apply plugin: 'java'
 | 
			
		||||
apply plugin: 'maven'
 | 
			
		||||
apply plugin: 'signing'
 | 
			
		||||
apply plugin: 'jacoco'
 | 
			
		||||
apply plugin: 'gitflow-version'
 | 
			
		||||
 | 
			
		||||
sourceCompatibility = 1.7
 | 
			
		||||
group = 'ch.dissem.msgpack'
 | 
			
		||||
 | 
			
		||||
repositories {
 | 
			
		||||
    mavenCentral()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
dependencies {
 | 
			
		||||
    testCompile group: 'junit', name: 'junit', version: '4.11'
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
test {
 | 
			
		||||
    testLogging {
 | 
			
		||||
        exceptionFormat = 'full'
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
task javadocJar(type: Jar) {
 | 
			
		||||
    classifier = 'javadoc'
 | 
			
		||||
    from javadoc
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
task sourcesJar(type: Jar) {
 | 
			
		||||
    classifier = 'sources'
 | 
			
		||||
    from sourceSets.main.allSource
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
artifacts {
 | 
			
		||||
    archives javadocJar, sourcesJar
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
signing {
 | 
			
		||||
    required { isRelease && project.getProperties().get("signing.keyId")?.length() > 0 }
 | 
			
		||||
    sign configurations.archives
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uploadArchives {
 | 
			
		||||
    repositories {
 | 
			
		||||
        mavenDeployer {
 | 
			
		||||
            beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) }
 | 
			
		||||
 | 
			
		||||
            repository(url: "https://oss.sonatype.org/service/local/staging/deploy/maven2/") {
 | 
			
		||||
                authentication(userName: ossrhUsername, password: ossrhPassword)
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            snapshotRepository(url: "https://oss.sonatype.org/content/repositories/snapshots/") {
 | 
			
		||||
                authentication(userName: ossrhUsername, password: ossrhPassword)
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            pom.project {
 | 
			
		||||
                name 'msgpack'
 | 
			
		||||
                packaging 'jar'
 | 
			
		||||
                url 'https://dissem.ch/msgpack'
 | 
			
		||||
 | 
			
		||||
                scm {
 | 
			
		||||
                    connection 'scm:git:https://git.dissem.ch/chris/MessagePack.git'
 | 
			
		||||
                    developerConnection 'scm:git:git@git.dissem.ch:chris/MessagePack.git'
 | 
			
		||||
                    url 'https://git.dissem.ch/chris/MessagePack.git'
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                licenses {
 | 
			
		||||
                    license {
 | 
			
		||||
                        name 'The Apache License, Version 2.0'
 | 
			
		||||
                        url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                developers {
 | 
			
		||||
                    developer {
 | 
			
		||||
                        name 'Christian Basler'
 | 
			
		||||
                        email 'chrigu.meyer@gmail.com'
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
jacocoTestReport {
 | 
			
		||||
    reports {
 | 
			
		||||
        xml.enabled = true
 | 
			
		||||
        html.enabled = true
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
check.dependsOn jacocoTestReport
 | 
			
		||||
@@ -0,0 +1,57 @@
 | 
			
		||||
package ch.dissem.gradle
 | 
			
		||||
 | 
			
		||||
import org.gradle.api.Plugin
 | 
			
		||||
import org.gradle.api.Project
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Sets the version as follows:
 | 
			
		||||
 * <ul>
 | 
			
		||||
 *     <li>If the branch is 'master', the version is set to the latest tag (which is expected to be set by Git flow)</li>
 | 
			
		||||
 *     <li>Otherwise, the version is set to the branch name, with '-SNAPSHOT' appended</li>
 | 
			
		||||
 * </ul>
 | 
			
		||||
 */
 | 
			
		||||
class GitFlowVersion implements Plugin<Project> {
 | 
			
		||||
    def getBranch(Project project) {
 | 
			
		||||
        def stdout = new ByteArrayOutputStream()
 | 
			
		||||
        project.exec {
 | 
			
		||||
            commandLine 'git', 'rev-parse', '--abbrev-ref', 'HEAD'
 | 
			
		||||
            standardOutput = stdout
 | 
			
		||||
        }
 | 
			
		||||
        return stdout.toString().trim()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    def getTag(Project project) {
 | 
			
		||||
        def stdout = new ByteArrayOutputStream()
 | 
			
		||||
        project.exec {
 | 
			
		||||
            commandLine 'git', 'describe', '--abbrev=0'
 | 
			
		||||
            standardOutput = stdout
 | 
			
		||||
        }
 | 
			
		||||
        return stdout.toString().trim()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    def isRelease(Project project) {
 | 
			
		||||
        return "master" == getBranch(project);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    def getVersion(Project project) {
 | 
			
		||||
        if (project.ext.isRelease) {
 | 
			
		||||
            return getTag(project)
 | 
			
		||||
        } else {
 | 
			
		||||
            def branch = getBranch(project)
 | 
			
		||||
            if ("develop" == branch) {
 | 
			
		||||
                return "development-SNAPSHOT"
 | 
			
		||||
            }
 | 
			
		||||
            return branch.replaceAll("/", "-") + "-SNAPSHOT"
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    void apply(Project project) {
 | 
			
		||||
        project.ext.isRelease = isRelease(project)
 | 
			
		||||
        project.version = getVersion(project)
 | 
			
		||||
 | 
			
		||||
        project.task('version') << {
 | 
			
		||||
            println "Version deduced from git: '${project.version}'"
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1 @@
 | 
			
		||||
implementation-class=ch.dissem.gradle.GitFlowVersion
 | 
			
		||||
							
								
								
									
										11
									
								
								gradle.properties
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								gradle.properties
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,11 @@
 | 
			
		||||
# Don't change this file - override those properties in the
 | 
			
		||||
# gradle.properties file in your home directory instead
 | 
			
		||||
 | 
			
		||||
signing.keyId=
 | 
			
		||||
signing.password=
 | 
			
		||||
#signing.secretKeyRingFile=
 | 
			
		||||
 | 
			
		||||
ossrhUsername=
 | 
			
		||||
ossrhPassword=
 | 
			
		||||
 | 
			
		||||
systemTestsEnabled=false
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								gradle/wrapper/gradle-wrapper.jar
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								gradle/wrapper/gradle-wrapper.jar
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										6
									
								
								gradle/wrapper/gradle-wrapper.properties
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								gradle/wrapper/gradle-wrapper.properties
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,6 @@
 | 
			
		||||
#Tue Jan 17 07:22:12 CET 2017
 | 
			
		||||
distributionBase=GRADLE_USER_HOME
 | 
			
		||||
distributionPath=wrapper/dists
 | 
			
		||||
zipStoreBase=GRADLE_USER_HOME
 | 
			
		||||
zipStorePath=wrapper/dists
 | 
			
		||||
distributionUrl=https\://services.gradle.org/distributions/gradle-3.1-all.zip
 | 
			
		||||
							
								
								
									
										169
									
								
								gradlew
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										169
									
								
								gradlew
									
									
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,169 @@
 | 
			
		||||
#!/usr/bin/env bash
 | 
			
		||||
 | 
			
		||||
##############################################################################
 | 
			
		||||
##
 | 
			
		||||
##  Gradle start up script for UN*X
 | 
			
		||||
##
 | 
			
		||||
##############################################################################
 | 
			
		||||
 | 
			
		||||
# Attempt to set APP_HOME
 | 
			
		||||
# Resolve links: $0 may be a link
 | 
			
		||||
PRG="$0"
 | 
			
		||||
# Need this for relative symlinks.
 | 
			
		||||
while [ -h "$PRG" ] ; do
 | 
			
		||||
    ls=`ls -ld "$PRG"`
 | 
			
		||||
    link=`expr "$ls" : '.*-> \(.*\)$'`
 | 
			
		||||
    if expr "$link" : '/.*' > /dev/null; then
 | 
			
		||||
        PRG="$link"
 | 
			
		||||
    else
 | 
			
		||||
        PRG=`dirname "$PRG"`"/$link"
 | 
			
		||||
    fi
 | 
			
		||||
done
 | 
			
		||||
SAVED="`pwd`"
 | 
			
		||||
cd "`dirname \"$PRG\"`/" >/dev/null
 | 
			
		||||
APP_HOME="`pwd -P`"
 | 
			
		||||
cd "$SAVED" >/dev/null
 | 
			
		||||
 | 
			
		||||
APP_NAME="Gradle"
 | 
			
		||||
APP_BASE_NAME=`basename "$0"`
 | 
			
		||||
 | 
			
		||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
 | 
			
		||||
DEFAULT_JVM_OPTS=""
 | 
			
		||||
 | 
			
		||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
 | 
			
		||||
MAX_FD="maximum"
 | 
			
		||||
 | 
			
		||||
warn ( ) {
 | 
			
		||||
    echo "$*"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
die ( ) {
 | 
			
		||||
    echo
 | 
			
		||||
    echo "$*"
 | 
			
		||||
    echo
 | 
			
		||||
    exit 1
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# OS specific support (must be 'true' or 'false').
 | 
			
		||||
cygwin=false
 | 
			
		||||
msys=false
 | 
			
		||||
darwin=false
 | 
			
		||||
nonstop=false
 | 
			
		||||
case "`uname`" in
 | 
			
		||||
  CYGWIN* )
 | 
			
		||||
    cygwin=true
 | 
			
		||||
    ;;
 | 
			
		||||
  Darwin* )
 | 
			
		||||
    darwin=true
 | 
			
		||||
    ;;
 | 
			
		||||
  MINGW* )
 | 
			
		||||
    msys=true
 | 
			
		||||
    ;;
 | 
			
		||||
  NONSTOP* )
 | 
			
		||||
    nonstop=true
 | 
			
		||||
    ;;
 | 
			
		||||
esac
 | 
			
		||||
 | 
			
		||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
 | 
			
		||||
 | 
			
		||||
# Determine the Java command to use to start the JVM.
 | 
			
		||||
if [ -n "$JAVA_HOME" ] ; then
 | 
			
		||||
    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
 | 
			
		||||
        # IBM's JDK on AIX uses strange locations for the executables
 | 
			
		||||
        JAVACMD="$JAVA_HOME/jre/sh/java"
 | 
			
		||||
    else
 | 
			
		||||
        JAVACMD="$JAVA_HOME/bin/java"
 | 
			
		||||
    fi
 | 
			
		||||
    if [ ! -x "$JAVACMD" ] ; then
 | 
			
		||||
        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
 | 
			
		||||
 | 
			
		||||
Please set the JAVA_HOME variable in your environment to match the
 | 
			
		||||
location of your Java installation."
 | 
			
		||||
    fi
 | 
			
		||||
else
 | 
			
		||||
    JAVACMD="java"
 | 
			
		||||
    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
 | 
			
		||||
 | 
			
		||||
Please set the JAVA_HOME variable in your environment to match the
 | 
			
		||||
location of your Java installation."
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
# Increase the maximum file descriptors if we can.
 | 
			
		||||
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
 | 
			
		||||
    MAX_FD_LIMIT=`ulimit -H -n`
 | 
			
		||||
    if [ $? -eq 0 ] ; then
 | 
			
		||||
        if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
 | 
			
		||||
            MAX_FD="$MAX_FD_LIMIT"
 | 
			
		||||
        fi
 | 
			
		||||
        ulimit -n $MAX_FD
 | 
			
		||||
        if [ $? -ne 0 ] ; then
 | 
			
		||||
            warn "Could not set maximum file descriptor limit: $MAX_FD"
 | 
			
		||||
        fi
 | 
			
		||||
    else
 | 
			
		||||
        warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
 | 
			
		||||
    fi
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
# For Darwin, add options to specify how the application appears in the dock
 | 
			
		||||
if $darwin; then
 | 
			
		||||
    GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
# For Cygwin, switch paths to Windows format before running java
 | 
			
		||||
if $cygwin ; then
 | 
			
		||||
    APP_HOME=`cygpath --path --mixed "$APP_HOME"`
 | 
			
		||||
    CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
 | 
			
		||||
    JAVACMD=`cygpath --unix "$JAVACMD"`
 | 
			
		||||
 | 
			
		||||
    # We build the pattern for arguments to be converted via cygpath
 | 
			
		||||
    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
 | 
			
		||||
    SEP=""
 | 
			
		||||
    for dir in $ROOTDIRSRAW ; do
 | 
			
		||||
        ROOTDIRS="$ROOTDIRS$SEP$dir"
 | 
			
		||||
        SEP="|"
 | 
			
		||||
    done
 | 
			
		||||
    OURCYGPATTERN="(^($ROOTDIRS))"
 | 
			
		||||
    # Add a user-defined pattern to the cygpath arguments
 | 
			
		||||
    if [ "$GRADLE_CYGPATTERN" != "" ] ; then
 | 
			
		||||
        OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
 | 
			
		||||
    fi
 | 
			
		||||
    # Now convert the arguments - kludge to limit ourselves to /bin/sh
 | 
			
		||||
    i=0
 | 
			
		||||
    for arg in "$@" ; do
 | 
			
		||||
        CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
 | 
			
		||||
        CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option
 | 
			
		||||
 | 
			
		||||
        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
 | 
			
		||||
            eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
 | 
			
		||||
        else
 | 
			
		||||
            eval `echo args$i`="\"$arg\""
 | 
			
		||||
        fi
 | 
			
		||||
        i=$((i+1))
 | 
			
		||||
    done
 | 
			
		||||
    case $i in
 | 
			
		||||
        (0) set -- ;;
 | 
			
		||||
        (1) set -- "$args0" ;;
 | 
			
		||||
        (2) set -- "$args0" "$args1" ;;
 | 
			
		||||
        (3) set -- "$args0" "$args1" "$args2" ;;
 | 
			
		||||
        (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
 | 
			
		||||
        (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
 | 
			
		||||
        (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
 | 
			
		||||
        (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
 | 
			
		||||
        (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
 | 
			
		||||
        (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
 | 
			
		||||
    esac
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
# Split up the JVM_OPTS And GRADLE_OPTS values into an value, following the shell quoting and substitution rules
 | 
			
		||||
function splitJvmOpts() {
 | 
			
		||||
    JVM_OPTS=("$@")
 | 
			
		||||
}
 | 
			
		||||
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
 | 
			
		||||
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
 | 
			
		||||
 | 
			
		||||
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
 | 
			
		||||
if [[ "$(uname)" == "Darwin" ]] && [[ "$HOME" == "$PWD" ]]; then
 | 
			
		||||
  cd "$(dirname "$0")"
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
 | 
			
		||||
							
								
								
									
										84
									
								
								gradlew.bat
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								gradlew.bat
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,84 @@
 | 
			
		||||
@if "%DEBUG%" == "" @echo off
 | 
			
		||||
@rem ##########################################################################
 | 
			
		||||
@rem
 | 
			
		||||
@rem  Gradle startup script for Windows
 | 
			
		||||
@rem
 | 
			
		||||
@rem ##########################################################################
 | 
			
		||||
 | 
			
		||||
@rem Set local scope for the variables with windows NT shell
 | 
			
		||||
if "%OS%"=="Windows_NT" setlocal
 | 
			
		||||
 | 
			
		||||
set DIRNAME=%~dp0
 | 
			
		||||
if "%DIRNAME%" == "" set DIRNAME=.
 | 
			
		||||
set APP_BASE_NAME=%~n0
 | 
			
		||||
set APP_HOME=%DIRNAME%
 | 
			
		||||
 | 
			
		||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
 | 
			
		||||
set DEFAULT_JVM_OPTS=
 | 
			
		||||
 | 
			
		||||
@rem Find java.exe
 | 
			
		||||
if defined JAVA_HOME goto findJavaFromJavaHome
 | 
			
		||||
 | 
			
		||||
set JAVA_EXE=java.exe
 | 
			
		||||
%JAVA_EXE% -version >NUL 2>&1
 | 
			
		||||
if "%ERRORLEVEL%" == "0" goto init
 | 
			
		||||
 | 
			
		||||
echo.
 | 
			
		||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
 | 
			
		||||
echo.
 | 
			
		||||
echo Please set the JAVA_HOME variable in your environment to match the
 | 
			
		||||
echo location of your Java installation.
 | 
			
		||||
 | 
			
		||||
goto fail
 | 
			
		||||
 | 
			
		||||
:findJavaFromJavaHome
 | 
			
		||||
set JAVA_HOME=%JAVA_HOME:"=%
 | 
			
		||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
 | 
			
		||||
 | 
			
		||||
if exist "%JAVA_EXE%" goto init
 | 
			
		||||
 | 
			
		||||
echo.
 | 
			
		||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
 | 
			
		||||
echo.
 | 
			
		||||
echo Please set the JAVA_HOME variable in your environment to match the
 | 
			
		||||
echo location of your Java installation.
 | 
			
		||||
 | 
			
		||||
goto fail
 | 
			
		||||
 | 
			
		||||
:init
 | 
			
		||||
@rem Get command-line arguments, handling Windows variants
 | 
			
		||||
 | 
			
		||||
if not "%OS%" == "Windows_NT" goto win9xME_args
 | 
			
		||||
 | 
			
		||||
:win9xME_args
 | 
			
		||||
@rem Slurp the command line arguments.
 | 
			
		||||
set CMD_LINE_ARGS=
 | 
			
		||||
set _SKIP=2
 | 
			
		||||
 | 
			
		||||
:win9xME_args_slurp
 | 
			
		||||
if "x%~1" == "x" goto execute
 | 
			
		||||
 | 
			
		||||
set CMD_LINE_ARGS=%*
 | 
			
		||||
 | 
			
		||||
:execute
 | 
			
		||||
@rem Setup the command line
 | 
			
		||||
 | 
			
		||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
 | 
			
		||||
 | 
			
		||||
@rem Execute Gradle
 | 
			
		||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
 | 
			
		||||
 | 
			
		||||
:end
 | 
			
		||||
@rem End local scope for the variables with windows NT shell
 | 
			
		||||
if "%ERRORLEVEL%"=="0" goto mainEnd
 | 
			
		||||
 | 
			
		||||
:fail
 | 
			
		||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
 | 
			
		||||
rem the _cmd.exe /c_ return code!
 | 
			
		||||
if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
 | 
			
		||||
exit /b 1
 | 
			
		||||
 | 
			
		||||
:mainEnd
 | 
			
		||||
if "%OS%"=="Windows_NT" endlocal
 | 
			
		||||
 | 
			
		||||
:omega
 | 
			
		||||
							
								
								
									
										2
									
								
								settings.gradle
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								settings.gradle
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,2 @@
 | 
			
		||||
rootProject.name = 'msgpack'
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										65
									
								
								src/main/java/ch/dissem/msgpack/Reader.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								src/main/java/ch/dissem/msgpack/Reader.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,65 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2017 Christian Basler
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package ch.dissem.msgpack;
 | 
			
		||||
 | 
			
		||||
import ch.dissem.msgpack.types.*;
 | 
			
		||||
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.io.InputStream;
 | 
			
		||||
import java.util.LinkedList;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Reads MPType object from an {@link InputStream}.
 | 
			
		||||
 */
 | 
			
		||||
public class Reader {
 | 
			
		||||
    private LinkedList<MPType.Unpacker<?>> unpackers = new LinkedList<>();
 | 
			
		||||
 | 
			
		||||
    private static final Reader instance = new Reader();
 | 
			
		||||
 | 
			
		||||
    private Reader() {
 | 
			
		||||
        unpackers.add(new MPNil.Unpacker());
 | 
			
		||||
        unpackers.add(new MPBoolean.Unpacker());
 | 
			
		||||
        unpackers.add(new MPInteger.Unpacker());
 | 
			
		||||
        unpackers.add(new MPFloat.Unpacker());
 | 
			
		||||
        unpackers.add(new MPString.Unpacker());
 | 
			
		||||
        unpackers.add(new MPBinary.Unpacker());
 | 
			
		||||
        unpackers.add(new MPMap.Unpacker(this));
 | 
			
		||||
        unpackers.add(new MPArray.Unpacker(this));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static Reader getInstance() {
 | 
			
		||||
        return instance;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Register your own extensions
 | 
			
		||||
     */
 | 
			
		||||
    public void register(MPType.Unpacker<?> unpacker) {
 | 
			
		||||
        unpackers.addFirst(unpacker);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public MPType read(InputStream in) throws IOException {
 | 
			
		||||
        int firstByte = in.read();
 | 
			
		||||
        for (MPType.Unpacker<?> unpacker : unpackers) {
 | 
			
		||||
            if (unpacker.is(firstByte)) {
 | 
			
		||||
                return unpacker.unpack(firstByte, in);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        throw new IOException(String.format("Unsupported input, no reader for 0x%02x", firstByte));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										256
									
								
								src/main/java/ch/dissem/msgpack/types/MPArray.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										256
									
								
								src/main/java/ch/dissem/msgpack/types/MPArray.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,256 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2017 Christian Basler
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package ch.dissem.msgpack.types;
 | 
			
		||||
 | 
			
		||||
import ch.dissem.msgpack.Reader;
 | 
			
		||||
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.io.InputStream;
 | 
			
		||||
import java.io.OutputStream;
 | 
			
		||||
import java.nio.ByteBuffer;
 | 
			
		||||
import java.util.*;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Representation of a msgpack encoded array. Uses a list to represent data internally, and implements the {@link List}
 | 
			
		||||
 * interface for your convenience.
 | 
			
		||||
 *
 | 
			
		||||
 * @param <T>
 | 
			
		||||
 */
 | 
			
		||||
public class MPArray<T extends MPType> implements MPType<List<T>>, List<T> {
 | 
			
		||||
    private List<T> array;
 | 
			
		||||
 | 
			
		||||
    public MPArray() {
 | 
			
		||||
        this.array = new LinkedList<>();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public MPArray(List<T> array) {
 | 
			
		||||
        this.array = array;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @SafeVarargs
 | 
			
		||||
    public MPArray(T... objects) {
 | 
			
		||||
        this.array = Arrays.asList(objects);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public List<T> getValue() {
 | 
			
		||||
        return array;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void pack(OutputStream out) throws IOException {
 | 
			
		||||
        int size = array.size();
 | 
			
		||||
        if (size < 16) {
 | 
			
		||||
            out.write(0b10010000 + size);
 | 
			
		||||
        } else if (size < 65536) {
 | 
			
		||||
            out.write(0xDC);
 | 
			
		||||
            out.write(ByteBuffer.allocate(2).putShort((short) size).array());
 | 
			
		||||
        } else {
 | 
			
		||||
            out.write(0xDD);
 | 
			
		||||
            out.write(ByteBuffer.allocate(4).putInt(size).array());
 | 
			
		||||
        }
 | 
			
		||||
        for (MPType o : array) {
 | 
			
		||||
            o.pack(out);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public int size() {
 | 
			
		||||
        return array.size();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean isEmpty() {
 | 
			
		||||
        return array.isEmpty();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean contains(Object o) {
 | 
			
		||||
        return array.contains(o);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public Iterator<T> iterator() {
 | 
			
		||||
        return array.iterator();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public Object[] toArray() {
 | 
			
		||||
        return array.toArray();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    @SuppressWarnings("SuspiciousToArrayCall")
 | 
			
		||||
    public <T1> T1[] toArray(T1[] t1s) {
 | 
			
		||||
        return array.toArray(t1s);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean add(T t) {
 | 
			
		||||
        return array.add(t);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean remove(Object o) {
 | 
			
		||||
        return array.remove(o);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean containsAll(Collection<?> collection) {
 | 
			
		||||
        return array.containsAll(collection);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean addAll(Collection<? extends T> collection) {
 | 
			
		||||
        return array.addAll(collection);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean addAll(int i, Collection<? extends T> collection) {
 | 
			
		||||
        return array.addAll(i, collection);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean removeAll(Collection<?> collection) {
 | 
			
		||||
        return array.removeAll(collection);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean retainAll(Collection<?> collection) {
 | 
			
		||||
        return array.retainAll(collection);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void clear() {
 | 
			
		||||
        array.clear();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean equals(Object o) {
 | 
			
		||||
        if (this == o) return true;
 | 
			
		||||
        if (o == null || getClass() != o.getClass()) return false;
 | 
			
		||||
        MPArray<?> mpArray = (MPArray<?>) o;
 | 
			
		||||
        return Objects.equals(array, mpArray.array);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public int hashCode() {
 | 
			
		||||
        return Objects.hash(array);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public T get(int i) {
 | 
			
		||||
        return array.get(i);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public T set(int i, T t) {
 | 
			
		||||
        return array.set(i, t);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void add(int i, T t) {
 | 
			
		||||
        array.add(i, t);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public T remove(int i) {
 | 
			
		||||
        return array.remove(i);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public int indexOf(Object o) {
 | 
			
		||||
        return array.indexOf(o);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public int lastIndexOf(Object o) {
 | 
			
		||||
        return array.lastIndexOf(o);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public ListIterator<T> listIterator() {
 | 
			
		||||
        return array.listIterator();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public ListIterator<T> listIterator(int i) {
 | 
			
		||||
        return array.listIterator(i);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public List<T> subList(int fromIndex, int toIndex) {
 | 
			
		||||
        return array.subList(fromIndex, toIndex);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String toString() {
 | 
			
		||||
        return toJson();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String toJson() {
 | 
			
		||||
        return toJson("");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    String toJson(String indent) {
 | 
			
		||||
        StringBuilder result = new StringBuilder();
 | 
			
		||||
        result.append("[\n");
 | 
			
		||||
        Iterator<T> iterator = array.iterator();
 | 
			
		||||
        String indent2 = indent + "  ";
 | 
			
		||||
        while (iterator.hasNext()) {
 | 
			
		||||
            T item = iterator.next();
 | 
			
		||||
            result.append(indent2);
 | 
			
		||||
            result.append(Utils.toJson(item, indent2));
 | 
			
		||||
            if (iterator.hasNext()) {
 | 
			
		||||
                result.append(',');
 | 
			
		||||
            }
 | 
			
		||||
            result.append('\n');
 | 
			
		||||
        }
 | 
			
		||||
        result.append("]");
 | 
			
		||||
        return result.toString();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static class Unpacker implements MPType.Unpacker<MPArray> {
 | 
			
		||||
        private final Reader reader;
 | 
			
		||||
 | 
			
		||||
        public Unpacker(Reader reader) {
 | 
			
		||||
            this.reader = reader;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public boolean is(int firstByte) {
 | 
			
		||||
            return firstByte == 0xDC || firstByte == 0xDD || (firstByte & 0b11110000) == 0b10010000;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public MPArray<MPType<?>> unpack(int firstByte, InputStream in) throws IOException {
 | 
			
		||||
            int size;
 | 
			
		||||
            if ((firstByte & 0b11110000) == 0b10010000) {
 | 
			
		||||
                size = firstByte & 0b00001111;
 | 
			
		||||
            } else if (firstByte == 0xDC) {
 | 
			
		||||
                size = in.read() << 8 | in.read();
 | 
			
		||||
            } else if (firstByte == 0xDD) {
 | 
			
		||||
                size = in.read() << 24 | in.read() << 16 | in.read() << 8 | in.read();
 | 
			
		||||
            } else {
 | 
			
		||||
                throw new IllegalArgumentException(String.format("Unexpected first byte 0x%02x", firstByte));
 | 
			
		||||
            }
 | 
			
		||||
            List<MPType<?>> list = new LinkedList<>();
 | 
			
		||||
            for (int i = 0; i < size; i++) {
 | 
			
		||||
                MPType value = reader.read(in);
 | 
			
		||||
                list.add(value);
 | 
			
		||||
            }
 | 
			
		||||
            return new MPArray<>(list);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										98
									
								
								src/main/java/ch/dissem/msgpack/types/MPBinary.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										98
									
								
								src/main/java/ch/dissem/msgpack/types/MPBinary.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,98 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2017 Christian Basler
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package ch.dissem.msgpack.types;
 | 
			
		||||
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.io.InputStream;
 | 
			
		||||
import java.io.OutputStream;
 | 
			
		||||
import java.nio.ByteBuffer;
 | 
			
		||||
import java.util.Arrays;
 | 
			
		||||
 | 
			
		||||
import static ch.dissem.msgpack.types.Utils.bytes;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Representation of msgpack encoded binary data a.k.a. byte array.
 | 
			
		||||
 */
 | 
			
		||||
public class MPBinary implements MPType<byte[]> {
 | 
			
		||||
    private byte[] value;
 | 
			
		||||
 | 
			
		||||
    public MPBinary(byte[] value) {
 | 
			
		||||
        this.value = value;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public byte[] getValue() {
 | 
			
		||||
        return value;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void pack(OutputStream out) throws IOException {
 | 
			
		||||
        int size = value.length;
 | 
			
		||||
        if (size < 256) {
 | 
			
		||||
            out.write(0xC4);
 | 
			
		||||
            out.write((byte) size);
 | 
			
		||||
        } else if (size < 65536) {
 | 
			
		||||
            out.write(0xC5);
 | 
			
		||||
            out.write(ByteBuffer.allocate(2).putShort((short) size).array());
 | 
			
		||||
        } else {
 | 
			
		||||
            out.write(0xC6);
 | 
			
		||||
            out.write(ByteBuffer.allocate(4).putInt(size).array());
 | 
			
		||||
        }
 | 
			
		||||
        out.write(value);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean equals(Object o) {
 | 
			
		||||
        if (this == o) return true;
 | 
			
		||||
        if (o == null || getClass() != o.getClass()) return false;
 | 
			
		||||
        MPBinary mpBinary = (MPBinary) o;
 | 
			
		||||
        return Arrays.equals(value, mpBinary.value);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public int hashCode() {
 | 
			
		||||
        return Arrays.hashCode(value);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String toString() {
 | 
			
		||||
        return toJson();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String toJson() {
 | 
			
		||||
        return Utils.base64(value);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static class Unpacker implements MPType.Unpacker<MPBinary> {
 | 
			
		||||
        public boolean is(int firstByte) {
 | 
			
		||||
            return firstByte == 0xC4 || firstByte == 0xC5 || firstByte == 0xC6;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public MPBinary unpack(int firstByte, InputStream in) throws IOException {
 | 
			
		||||
            int size;
 | 
			
		||||
            if (firstByte == 0xC4) {
 | 
			
		||||
                size = in.read();
 | 
			
		||||
            } else if (firstByte == 0xC5) {
 | 
			
		||||
                size = in.read() << 8 | in.read();
 | 
			
		||||
            } else if (firstByte == 0xC6) {
 | 
			
		||||
                size = in.read() << 24 | in.read() << 16 | in.read() << 8 | in.read();
 | 
			
		||||
            } else {
 | 
			
		||||
                throw new IllegalArgumentException(String.format("Unexpected first byte 0x%02x", firstByte));
 | 
			
		||||
            }
 | 
			
		||||
            return new MPBinary(bytes(in, size).array());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										88
									
								
								src/main/java/ch/dissem/msgpack/types/MPBoolean.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										88
									
								
								src/main/java/ch/dissem/msgpack/types/MPBoolean.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,88 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2017 Christian Basler
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package ch.dissem.msgpack.types;
 | 
			
		||||
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.io.InputStream;
 | 
			
		||||
import java.io.OutputStream;
 | 
			
		||||
import java.util.Objects;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Representation of a msgpack encoded boolean.
 | 
			
		||||
 */
 | 
			
		||||
public class MPBoolean implements MPType<Boolean> {
 | 
			
		||||
    private final static int FALSE = 0xC2;
 | 
			
		||||
    private final static int TRUE = 0xC3;
 | 
			
		||||
 | 
			
		||||
    private final boolean value;
 | 
			
		||||
 | 
			
		||||
    public MPBoolean(boolean value) {
 | 
			
		||||
        this.value = value;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Boolean getValue() {
 | 
			
		||||
        return value;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void pack(OutputStream out) throws IOException {
 | 
			
		||||
        if (value) {
 | 
			
		||||
            out.write(TRUE);
 | 
			
		||||
        } else {
 | 
			
		||||
            out.write(FALSE);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean equals(Object o) {
 | 
			
		||||
        if (this == o) return true;
 | 
			
		||||
        if (o == null || getClass() != o.getClass()) return false;
 | 
			
		||||
        MPBoolean mpBoolean = (MPBoolean) o;
 | 
			
		||||
        return value == mpBoolean.value;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public int hashCode() {
 | 
			
		||||
        return Objects.hash(value);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String toString() {
 | 
			
		||||
        return String.valueOf(value);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String toJson() {
 | 
			
		||||
        return String.valueOf(value);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static class Unpacker implements MPType.Unpacker<MPBoolean> {
 | 
			
		||||
 | 
			
		||||
        public boolean is(int firstByte) {
 | 
			
		||||
            return firstByte == TRUE || firstByte == FALSE;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public MPBoolean unpack(int firstByte, InputStream in) {
 | 
			
		||||
            if (firstByte == TRUE) {
 | 
			
		||||
                return new MPBoolean(true);
 | 
			
		||||
            } else if (firstByte == FALSE) {
 | 
			
		||||
                return new MPBoolean(false);
 | 
			
		||||
            } else {
 | 
			
		||||
                throw new IllegalArgumentException(String.format("0xC2 or 0xC3 expected but was 0x%02x", firstByte));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										110
									
								
								src/main/java/ch/dissem/msgpack/types/MPFloat.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										110
									
								
								src/main/java/ch/dissem/msgpack/types/MPFloat.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,110 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2017 Christian Basler
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package ch.dissem.msgpack.types;
 | 
			
		||||
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.io.InputStream;
 | 
			
		||||
import java.io.OutputStream;
 | 
			
		||||
import java.nio.ByteBuffer;
 | 
			
		||||
import java.util.Objects;
 | 
			
		||||
 | 
			
		||||
import static ch.dissem.msgpack.types.Utils.bytes;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Representation of a msgpack encoded float32 or float64 number.
 | 
			
		||||
 */
 | 
			
		||||
public class MPFloat implements MPType<Double> {
 | 
			
		||||
 | 
			
		||||
    public enum Precision {FLOAT32, FLOAT64}
 | 
			
		||||
 | 
			
		||||
    private final double value;
 | 
			
		||||
    private final Precision precision;
 | 
			
		||||
 | 
			
		||||
    public MPFloat(float value) {
 | 
			
		||||
        this.value = value;
 | 
			
		||||
        this.precision = Precision.FLOAT32;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public MPFloat(double value) {
 | 
			
		||||
        this.value = value;
 | 
			
		||||
        this.precision = Precision.FLOAT64;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public Double getValue() {
 | 
			
		||||
        return value;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Precision getPrecision() {
 | 
			
		||||
        return precision;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void pack(OutputStream out) throws IOException {
 | 
			
		||||
        switch (precision) {
 | 
			
		||||
            case FLOAT32:
 | 
			
		||||
                out.write(0xCA);
 | 
			
		||||
                out.write(ByteBuffer.allocate(4).putFloat((float) value).array());
 | 
			
		||||
                break;
 | 
			
		||||
            case FLOAT64:
 | 
			
		||||
                out.write(0xCB);
 | 
			
		||||
                out.write(ByteBuffer.allocate(8).putDouble(value).array());
 | 
			
		||||
                break;
 | 
			
		||||
            default:
 | 
			
		||||
                throw new IllegalArgumentException("Unknown precision: " + precision);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean equals(Object o) {
 | 
			
		||||
        if (this == o) return true;
 | 
			
		||||
        if (o == null || getClass() != o.getClass()) return false;
 | 
			
		||||
        MPFloat mpFloat = (MPFloat) o;
 | 
			
		||||
        return Double.compare(mpFloat.value, value) == 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public int hashCode() {
 | 
			
		||||
        return Objects.hash(value);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String toString() {
 | 
			
		||||
        return String.valueOf(value);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String toJson() {
 | 
			
		||||
        return String.valueOf(value);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static class Unpacker implements MPType.Unpacker<MPFloat> {
 | 
			
		||||
        public boolean is(int firstByte) {
 | 
			
		||||
            return firstByte == 0xCA || firstByte == 0xCB;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public MPFloat unpack(int firstByte, InputStream in) throws IOException {
 | 
			
		||||
            switch (firstByte) {
 | 
			
		||||
                case 0xCA:
 | 
			
		||||
                    return new MPFloat(bytes(in, 4).getFloat());
 | 
			
		||||
                case 0xCB:
 | 
			
		||||
                    return new MPFloat(bytes(in, 8).getDouble());
 | 
			
		||||
                default:
 | 
			
		||||
                    throw new IllegalArgumentException(String.format("Unexpected first byte 0x%02x", firstByte));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										160
									
								
								src/main/java/ch/dissem/msgpack/types/MPInteger.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										160
									
								
								src/main/java/ch/dissem/msgpack/types/MPInteger.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,160 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2017 Christian Basler
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package ch.dissem.msgpack.types;
 | 
			
		||||
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.io.InputStream;
 | 
			
		||||
import java.io.OutputStream;
 | 
			
		||||
import java.nio.ByteBuffer;
 | 
			
		||||
import java.util.Objects;
 | 
			
		||||
 | 
			
		||||
import static ch.dissem.msgpack.types.Utils.bytes;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Representation of a msgpack encoded integer. The encoding is automatically selected according to the value's size.
 | 
			
		||||
 * Uses long due to the fact that the msgpack integer implementation may contain up to 64 bit numbers, corresponding
 | 
			
		||||
 * to Java long values. Also note that uint64 values may be too large for signed long (thanks Java for not supporting
 | 
			
		||||
 * unsigned values) and end in a negative value.
 | 
			
		||||
 */
 | 
			
		||||
public class MPInteger implements MPType<Long> {
 | 
			
		||||
    private long value;
 | 
			
		||||
 | 
			
		||||
    public MPInteger(long value) {
 | 
			
		||||
        this.value = value;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public Long getValue() {
 | 
			
		||||
        return value;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void pack(OutputStream out) throws IOException {
 | 
			
		||||
        if ((value > ((byte) 0b11100000) && value < 0x80)) {
 | 
			
		||||
            out.write((int) value);
 | 
			
		||||
        } else if (value > 0) {
 | 
			
		||||
            if (value <= 0xFF) {
 | 
			
		||||
                out.write(0xCC);
 | 
			
		||||
                out.write((int) value);
 | 
			
		||||
            } else if (value <= 0xFFFF) {
 | 
			
		||||
                out.write(0xCD);
 | 
			
		||||
                out.write(ByteBuffer.allocate(2).putShort((short) value).array());
 | 
			
		||||
            } else if (value <= 0xFFFFFFFFL) {
 | 
			
		||||
                out.write(0xCE);
 | 
			
		||||
                out.write(ByteBuffer.allocate(4).putInt((int) value).array());
 | 
			
		||||
            } else {
 | 
			
		||||
                out.write(0xCF);
 | 
			
		||||
                out.write(ByteBuffer.allocate(8).putLong(value).array());
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            if (value >= -32) {
 | 
			
		||||
                out.write(new byte[]{
 | 
			
		||||
                        (byte) value
 | 
			
		||||
                });
 | 
			
		||||
            } else if (value >= Byte.MIN_VALUE) {
 | 
			
		||||
                out.write(0xD0);
 | 
			
		||||
                out.write(ByteBuffer.allocate(1).put((byte) value).array());
 | 
			
		||||
            } else if (value >= Short.MIN_VALUE) {
 | 
			
		||||
                out.write(0xD1);
 | 
			
		||||
                out.write(ByteBuffer.allocate(2).putShort((short) value).array());
 | 
			
		||||
            } else if (value >= Integer.MIN_VALUE) {
 | 
			
		||||
                out.write(0xD2);
 | 
			
		||||
                out.write(ByteBuffer.allocate(4).putInt((int) value).array());
 | 
			
		||||
            } else {
 | 
			
		||||
                out.write(0xD3);
 | 
			
		||||
                out.write(ByteBuffer.allocate(8).putLong(value).array());
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean equals(Object o) {
 | 
			
		||||
        if (this == o) return true;
 | 
			
		||||
        if (o == null || getClass() != o.getClass()) return false;
 | 
			
		||||
        MPInteger mpInteger = (MPInteger) o;
 | 
			
		||||
        return value == mpInteger.value;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public int hashCode() {
 | 
			
		||||
        return Objects.hash(value);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String toString() {
 | 
			
		||||
        return String.valueOf(value);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String toJson() {
 | 
			
		||||
        return String.valueOf(value);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static class Unpacker implements MPType.Unpacker<MPInteger> {
 | 
			
		||||
        public boolean is(int firstByte) {
 | 
			
		||||
            switch (firstByte) {
 | 
			
		||||
                case 0xCC:
 | 
			
		||||
                case 0xCD:
 | 
			
		||||
                case 0xCE:
 | 
			
		||||
                case 0xCF:
 | 
			
		||||
                case 0xD0:
 | 
			
		||||
                case 0xD1:
 | 
			
		||||
                case 0xD2:
 | 
			
		||||
                case 0xD3:
 | 
			
		||||
                    return true;
 | 
			
		||||
                default:
 | 
			
		||||
                    return (firstByte & 0b10000000) == 0 || (firstByte & 0b11100000) == 0b11100000;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public MPInteger unpack(int firstByte, InputStream in) throws IOException {
 | 
			
		||||
            if ((firstByte & 0b10000000) == 0 || (firstByte & 0b11100000) == 0b11100000) {
 | 
			
		||||
                return new MPInteger((byte) firstByte);
 | 
			
		||||
            } else {
 | 
			
		||||
                switch (firstByte) {
 | 
			
		||||
                    case 0xCC:
 | 
			
		||||
                        return new MPInteger(in.read());
 | 
			
		||||
                    case 0xCD:
 | 
			
		||||
                        return new MPInteger(in.read() << 8 | in.read());
 | 
			
		||||
                    case 0xCE: {
 | 
			
		||||
                        long value = 0;
 | 
			
		||||
                        for (int i = 0; i < 4; i++) {
 | 
			
		||||
                            value = value << 8 | in.read();
 | 
			
		||||
                        }
 | 
			
		||||
                        return new MPInteger(value);
 | 
			
		||||
                    }
 | 
			
		||||
                    case 0xCF: {
 | 
			
		||||
                        long value = 0;
 | 
			
		||||
                        for (int i = 0; i < 8; i++) {
 | 
			
		||||
                            value = value << 8 | in.read();
 | 
			
		||||
                        }
 | 
			
		||||
                        return new MPInteger(value);
 | 
			
		||||
                    }
 | 
			
		||||
                    case 0xD0:
 | 
			
		||||
                        return new MPInteger(bytes(in, 1).get());
 | 
			
		||||
                    case 0xD1:
 | 
			
		||||
                        return new MPInteger(bytes(in, 2).getShort());
 | 
			
		||||
                    case 0xD2:
 | 
			
		||||
                        return new MPInteger(bytes(in, 4).getInt());
 | 
			
		||||
                    case 0xD3:
 | 
			
		||||
                        return new MPInteger(bytes(in, 8).getLong());
 | 
			
		||||
                    default:
 | 
			
		||||
                        throw new IllegalArgumentException(String.format("Unexpected first byte 0x%02x", firstByte));
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										185
									
								
								src/main/java/ch/dissem/msgpack/types/MPMap.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										185
									
								
								src/main/java/ch/dissem/msgpack/types/MPMap.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,185 @@
 | 
			
		||||
package ch.dissem.msgpack.types;
 | 
			
		||||
 | 
			
		||||
import ch.dissem.msgpack.Reader;
 | 
			
		||||
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.io.InputStream;
 | 
			
		||||
import java.io.OutputStream;
 | 
			
		||||
import java.nio.ByteBuffer;
 | 
			
		||||
import java.util.*;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Representation of a msgpack encoded map. It is recommended to use a {@link LinkedHashMap} to ensure the order
 | 
			
		||||
 * of entries. For convenience, it also implements the {@link Map} interface.
 | 
			
		||||
 *
 | 
			
		||||
 * @param <K>
 | 
			
		||||
 * @param <V>
 | 
			
		||||
 */
 | 
			
		||||
public class MPMap<K extends MPType, V extends MPType> implements MPType<Map<K, V>>, Map<K, V> {
 | 
			
		||||
    private Map<K, V> map;
 | 
			
		||||
 | 
			
		||||
    public MPMap() {
 | 
			
		||||
        this.map = new LinkedHashMap<>();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public MPMap(Map<K, V> map) {
 | 
			
		||||
        this.map = map;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public Map<K, V> getValue() {
 | 
			
		||||
        return map;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void pack(OutputStream out) throws IOException {
 | 
			
		||||
        int size = map.size();
 | 
			
		||||
        if (size < 16) {
 | 
			
		||||
            out.write(0x80 + size);
 | 
			
		||||
        } else if (size < 65536) {
 | 
			
		||||
            out.write(0xDE);
 | 
			
		||||
            out.write(ByteBuffer.allocate(2).putShort((short) size).array());
 | 
			
		||||
        } else {
 | 
			
		||||
            out.write(0xDF);
 | 
			
		||||
            out.write(ByteBuffer.allocate(4).putInt(size).array());
 | 
			
		||||
        }
 | 
			
		||||
        for (Map.Entry<K, V> e : map.entrySet()) {
 | 
			
		||||
            e.getKey().pack(out);
 | 
			
		||||
            e.getValue().pack(out);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public int size() {
 | 
			
		||||
        return map.size();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean isEmpty() {
 | 
			
		||||
        return map.isEmpty();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean containsKey(Object o) {
 | 
			
		||||
        return map.containsKey(o);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean containsValue(Object o) {
 | 
			
		||||
        return map.containsValue(o);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public V get(Object o) {
 | 
			
		||||
        return map.get(o);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public V put(K k, V v) {
 | 
			
		||||
        return map.put(k, v);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public V remove(Object o) {
 | 
			
		||||
        return map.remove(o);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void putAll(Map<? extends K, ? extends V> map) {
 | 
			
		||||
        this.map.putAll(map);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void clear() {
 | 
			
		||||
        map.clear();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public Set<K> keySet() {
 | 
			
		||||
        return map.keySet();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public Collection<V> values() {
 | 
			
		||||
        return map.values();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public Set<Entry<K, V>> entrySet() {
 | 
			
		||||
        return map.entrySet();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean equals(Object o) {
 | 
			
		||||
        if (this == o) return true;
 | 
			
		||||
        if (o == null || getClass() != o.getClass()) return false;
 | 
			
		||||
        MPMap<?, ?> mpMap = (MPMap<?, ?>) o;
 | 
			
		||||
        return Objects.equals(map, mpMap.map);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public int hashCode() {
 | 
			
		||||
        return Objects.hash(map);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String toString() {
 | 
			
		||||
        return toJson();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    String toJson(String indent) {
 | 
			
		||||
        StringBuilder result = new StringBuilder();
 | 
			
		||||
        result.append("{\n");
 | 
			
		||||
        Iterator<Map.Entry<K, V>> iterator = map.entrySet().iterator();
 | 
			
		||||
        String indent2 = indent + "  ";
 | 
			
		||||
        while (iterator.hasNext()) {
 | 
			
		||||
            Map.Entry<K, V> item = iterator.next();
 | 
			
		||||
            result.append(indent2);
 | 
			
		||||
            result.append(Utils.toJson(item.getKey(), indent2));
 | 
			
		||||
            result.append(": ");
 | 
			
		||||
            result.append(Utils.toJson(item.getValue(), indent2));
 | 
			
		||||
            if (iterator.hasNext()) {
 | 
			
		||||
                result.append(',');
 | 
			
		||||
            }
 | 
			
		||||
            result.append('\n');
 | 
			
		||||
        }
 | 
			
		||||
        result.append(indent).append("}");
 | 
			
		||||
        return result.toString();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String toJson() {
 | 
			
		||||
        return toJson("");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static class Unpacker implements MPType.Unpacker<MPMap> {
 | 
			
		||||
        private final Reader reader;
 | 
			
		||||
 | 
			
		||||
        public Unpacker(Reader reader) {
 | 
			
		||||
            this.reader = reader;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public boolean is(int firstByte) {
 | 
			
		||||
            return firstByte == 0xDE || firstByte == 0xDF || (firstByte & 0xF0) == 0x80;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public MPMap<MPType<?>, MPType<?>> unpack(int firstByte, InputStream in) throws IOException {
 | 
			
		||||
            int size;
 | 
			
		||||
            if ((firstByte & 0xF0) == 0x80) {
 | 
			
		||||
                size = firstByte & 0x0F;
 | 
			
		||||
            } else if (firstByte == 0xDE) {
 | 
			
		||||
                size = in.read() << 8 | in.read();
 | 
			
		||||
            } else if (firstByte == 0xDF) {
 | 
			
		||||
                size = in.read() << 24 | in.read() << 16 | in.read() << 8 | in.read();
 | 
			
		||||
            } else {
 | 
			
		||||
                throw new IllegalArgumentException(String.format("Unexpected first byte 0x%02x", firstByte));
 | 
			
		||||
            }
 | 
			
		||||
            Map<MPType<?>, MPType<?>> map = new LinkedHashMap<>();
 | 
			
		||||
            for (int i = 0; i < size; i++) {
 | 
			
		||||
                MPType key = reader.read(in);
 | 
			
		||||
                MPType value = reader.read(in);
 | 
			
		||||
                map.put(key, value);
 | 
			
		||||
            }
 | 
			
		||||
            return new MPMap<>(map);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										70
									
								
								src/main/java/ch/dissem/msgpack/types/MPNil.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								src/main/java/ch/dissem/msgpack/types/MPNil.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,70 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2017 Christian Basler
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package ch.dissem.msgpack.types;
 | 
			
		||||
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.io.InputStream;
 | 
			
		||||
import java.io.OutputStream;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Representation of msgpack encoded nil / null.
 | 
			
		||||
 */
 | 
			
		||||
public class MPNil implements MPType<Void> {
 | 
			
		||||
    private final static int NIL = 0xC0;
 | 
			
		||||
 | 
			
		||||
    public Void getValue() {
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void pack(OutputStream out) throws IOException {
 | 
			
		||||
        out.write(NIL);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public int hashCode() {
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean equals(Object o) {
 | 
			
		||||
        return o instanceof MPNil;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String toString() {
 | 
			
		||||
        return "null";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String toJson() {
 | 
			
		||||
        return "null";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static class Unpacker implements MPType.Unpacker<MPNil> {
 | 
			
		||||
 | 
			
		||||
        public boolean is(int firstByte) {
 | 
			
		||||
            return firstByte == NIL;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public MPNil unpack(int firstByte, InputStream in) {
 | 
			
		||||
            if (firstByte != NIL) {
 | 
			
		||||
                throw new IllegalArgumentException(String.format("0xC0 expected but was 0x%02x", firstByte));
 | 
			
		||||
            }
 | 
			
		||||
            return new MPNil();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										185
									
								
								src/main/java/ch/dissem/msgpack/types/MPString.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										185
									
								
								src/main/java/ch/dissem/msgpack/types/MPString.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,185 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2017 Christian Basler
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package ch.dissem.msgpack.types;
 | 
			
		||||
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.io.InputStream;
 | 
			
		||||
import java.io.OutputStream;
 | 
			
		||||
import java.nio.ByteBuffer;
 | 
			
		||||
import java.nio.charset.Charset;
 | 
			
		||||
import java.util.Objects;
 | 
			
		||||
 | 
			
		||||
import static ch.dissem.msgpack.types.Utils.bytes;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Representation of a msgpack encoded string. The encoding is automatically selected according to the string's length.
 | 
			
		||||
 * <p>
 | 
			
		||||
 * The default encoding is UTF-8.
 | 
			
		||||
 * </p>
 | 
			
		||||
 */
 | 
			
		||||
public class MPString implements MPType<String>, CharSequence {
 | 
			
		||||
    private static final int FIXSTR_PREFIX = 0b10100000;
 | 
			
		||||
    private static final int FIXSTR_PREFIX_FILTER = 0b11100000;
 | 
			
		||||
    private static final int STR8_PREFIX = 0xD9;
 | 
			
		||||
    private static final int STR8_LIMIT = 256;
 | 
			
		||||
    private static final int STR16_PREFIX = 0xDA;
 | 
			
		||||
    private static final int STR16_LIMIT = 65536;
 | 
			
		||||
    private static final int STR32_PREFIX = 0xDB;
 | 
			
		||||
    private static final int FIXSTR_FILTER = 0b00011111;
 | 
			
		||||
 | 
			
		||||
    private static Charset encoding = Charset.forName("UTF-8");
 | 
			
		||||
 | 
			
		||||
    private final String value;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Use this method if for some messed up reason you really need to use something else than UTF-8.
 | 
			
		||||
     * Ask yourself: why should I? Is this really necessary?
 | 
			
		||||
     * <p>
 | 
			
		||||
     * It will set the encoding for all {@link MPString}s, but if you have inconsistent encoding in your
 | 
			
		||||
     * format you're lost anyway.
 | 
			
		||||
     * </p>
 | 
			
		||||
     */
 | 
			
		||||
    public static void setEncoding(Charset encoding) {
 | 
			
		||||
        MPString.encoding = encoding;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public MPString(String value) {
 | 
			
		||||
        this.value = value;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getValue() {
 | 
			
		||||
        return value;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void pack(OutputStream out) throws IOException {
 | 
			
		||||
        byte[] bytes = value.getBytes(encoding);
 | 
			
		||||
        int size = bytes.length;
 | 
			
		||||
        if (size < 32) {
 | 
			
		||||
            out.write(FIXSTR_PREFIX + size);
 | 
			
		||||
        } else if (size < STR8_LIMIT) {
 | 
			
		||||
            out.write(STR8_PREFIX);
 | 
			
		||||
            out.write(size);
 | 
			
		||||
        } else if (size < STR16_LIMIT) {
 | 
			
		||||
            out.write(STR16_PREFIX);
 | 
			
		||||
            out.write(ByteBuffer.allocate(2).putShort((short) size).array());
 | 
			
		||||
        } else {
 | 
			
		||||
            out.write(STR32_PREFIX);
 | 
			
		||||
            out.write(ByteBuffer.allocate(4).putInt(size).array());
 | 
			
		||||
        }
 | 
			
		||||
        out.write(bytes);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean equals(Object o) {
 | 
			
		||||
        if (this == o) return true;
 | 
			
		||||
        if (o == null || getClass() != o.getClass()) return false;
 | 
			
		||||
        MPString mpString = (MPString) o;
 | 
			
		||||
        return Objects.equals(value, mpString.value);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public int hashCode() {
 | 
			
		||||
        return Objects.hash(value);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public int length() {
 | 
			
		||||
        return value.length();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public char charAt(int i) {
 | 
			
		||||
        return value.charAt(i);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public CharSequence subSequence(int beginIndex, int endIndex) {
 | 
			
		||||
        return value.subSequence(beginIndex, endIndex);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String toString() {
 | 
			
		||||
        return value;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String toJson() {
 | 
			
		||||
        StringBuilder result = new StringBuilder(value.length() + 4);
 | 
			
		||||
        result.append('"');
 | 
			
		||||
        for (int i = 0; i < value.length(); i++) {
 | 
			
		||||
            char c = value.charAt(i);
 | 
			
		||||
            switch (c) {
 | 
			
		||||
                case '\\':
 | 
			
		||||
                case '"':
 | 
			
		||||
                case '/':
 | 
			
		||||
                    result.append('\\').append(c);
 | 
			
		||||
                    break;
 | 
			
		||||
                case '\b':
 | 
			
		||||
                    result.append("\\b");
 | 
			
		||||
                    break;
 | 
			
		||||
                case '\t':
 | 
			
		||||
                    result.append("\\t");
 | 
			
		||||
                    break;
 | 
			
		||||
                case '\n':
 | 
			
		||||
                    result.append("\\n");
 | 
			
		||||
                    break;
 | 
			
		||||
                case '\f':
 | 
			
		||||
                    result.append("\\f");
 | 
			
		||||
                    break;
 | 
			
		||||
                case '\r':
 | 
			
		||||
                    result.append("\\r");
 | 
			
		||||
                    break;
 | 
			
		||||
                default:
 | 
			
		||||
                    if (c < ' ') {
 | 
			
		||||
                        result.append("\\u");
 | 
			
		||||
                        String hex = Integer.toHexString(c);
 | 
			
		||||
                        for (int j = 0; j + hex.length() < 4; j++) {
 | 
			
		||||
                            result.append('0');
 | 
			
		||||
                        }
 | 
			
		||||
                        result.append(hex);
 | 
			
		||||
                    } else {
 | 
			
		||||
                        result.append(c);
 | 
			
		||||
                    }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        result.append('"');
 | 
			
		||||
        return result.toString();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static class Unpacker implements MPType.Unpacker<MPString> {
 | 
			
		||||
        public boolean is(int firstByte) {
 | 
			
		||||
            return firstByte == STR8_PREFIX || firstByte == STR16_PREFIX || firstByte == STR32_PREFIX
 | 
			
		||||
                    || (firstByte & FIXSTR_PREFIX_FILTER) == FIXSTR_PREFIX;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public MPString unpack(int firstByte, InputStream in) throws IOException {
 | 
			
		||||
            int size;
 | 
			
		||||
            if ((firstByte & FIXSTR_PREFIX_FILTER) == FIXSTR_PREFIX) {
 | 
			
		||||
                size = firstByte & FIXSTR_FILTER;
 | 
			
		||||
            } else if (firstByte == STR8_PREFIX) {
 | 
			
		||||
                size = in.read();
 | 
			
		||||
            } else if (firstByte == STR16_PREFIX) {
 | 
			
		||||
                size = in.read() << 8 | in.read();
 | 
			
		||||
            } else if (firstByte == STR32_PREFIX) {
 | 
			
		||||
                size = in.read() << 24 | in.read() << 16 | in.read() << 8 | in.read();
 | 
			
		||||
            } else {
 | 
			
		||||
                throw new IllegalArgumentException(String.format("Unexpected first byte 0x%02x", firstByte));
 | 
			
		||||
            }
 | 
			
		||||
            return new MPString(new String(bytes(in, size).array(), encoding));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										38
									
								
								src/main/java/ch/dissem/msgpack/types/MPType.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								src/main/java/ch/dissem/msgpack/types/MPType.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,38 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2017 Christian Basler
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package ch.dissem.msgpack.types;
 | 
			
		||||
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.io.InputStream;
 | 
			
		||||
import java.io.OutputStream;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Representation of some msgpack encoded data.
 | 
			
		||||
 */
 | 
			
		||||
public interface MPType<T> {
 | 
			
		||||
    interface Unpacker<M extends MPType> {
 | 
			
		||||
        boolean is(int firstByte);
 | 
			
		||||
 | 
			
		||||
        M unpack(int firstByte, InputStream in) throws IOException;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    T getValue();
 | 
			
		||||
 | 
			
		||||
    void pack(OutputStream out) throws IOException;
 | 
			
		||||
 | 
			
		||||
    String toJson();
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										115
									
								
								src/main/java/ch/dissem/msgpack/types/Utils.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										115
									
								
								src/main/java/ch/dissem/msgpack/types/Utils.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,115 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2017 Christian Basler
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package ch.dissem.msgpack.types;
 | 
			
		||||
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.io.InputStream;
 | 
			
		||||
import java.nio.ByteBuffer;
 | 
			
		||||
 | 
			
		||||
public class Utils {
 | 
			
		||||
    private static final char[] BASE64_CODES = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".toCharArray();
 | 
			
		||||
    private static final MPNil NIL = new MPNil();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns a {@link ByteBuffer} containing the next <code>count</code> bytes from the {@link InputStream}.
 | 
			
		||||
     */
 | 
			
		||||
    static ByteBuffer bytes(InputStream in, int count) throws IOException {
 | 
			
		||||
        byte[] result = new byte[count];
 | 
			
		||||
        int off = 0;
 | 
			
		||||
        while (off < count) {
 | 
			
		||||
            int read = in.read(result, off, count - off);
 | 
			
		||||
            if (read < 0) {
 | 
			
		||||
                throw new IOException("Unexpected end of stream, wanted to read " + count + " bytes but only got " + off);
 | 
			
		||||
            }
 | 
			
		||||
            off += read;
 | 
			
		||||
        }
 | 
			
		||||
        return ByteBuffer.wrap(result);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Helper method to decide which types support extra indention (for pretty printing JSON)
 | 
			
		||||
     */
 | 
			
		||||
    static String toJson(MPType<?> type, String indent) {
 | 
			
		||||
        if (type instanceof MPMap) {
 | 
			
		||||
            return ((MPMap) type).toJson(indent);
 | 
			
		||||
        }
 | 
			
		||||
        if (type instanceof MPArray) {
 | 
			
		||||
            return ((MPArray) type).toJson(indent);
 | 
			
		||||
        }
 | 
			
		||||
        return type.toJson();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Slightly improved code from https://en.wikipedia.org/wiki/Base64
 | 
			
		||||
     */
 | 
			
		||||
    static String base64(byte[] data) {
 | 
			
		||||
        StringBuilder result = new StringBuilder((data.length * 4) / 3 + 3);
 | 
			
		||||
        int b;
 | 
			
		||||
        for (int i = 0; i < data.length; i += 3) {
 | 
			
		||||
            b = (data[i] & 0xFC) >> 2;
 | 
			
		||||
            result.append(BASE64_CODES[b]);
 | 
			
		||||
            b = (data[i] & 0x03) << 4;
 | 
			
		||||
            if (i + 1 < data.length) {
 | 
			
		||||
                b |= (data[i + 1] & 0xF0) >> 4;
 | 
			
		||||
                result.append(BASE64_CODES[b]);
 | 
			
		||||
                b = (data[i + 1] & 0x0F) << 2;
 | 
			
		||||
                if (i + 2 < data.length) {
 | 
			
		||||
                    b |= (data[i + 2] & 0xC0) >> 6;
 | 
			
		||||
                    result.append(BASE64_CODES[b]);
 | 
			
		||||
                    b = data[i + 2] & 0x3F;
 | 
			
		||||
                    result.append(BASE64_CODES[b]);
 | 
			
		||||
                } else {
 | 
			
		||||
                    result.append(BASE64_CODES[b]);
 | 
			
		||||
                    result.append('=');
 | 
			
		||||
                }
 | 
			
		||||
            } else {
 | 
			
		||||
                result.append(BASE64_CODES[b]);
 | 
			
		||||
                result.append("==");
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return result.toString();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static MPString mp(String value) {
 | 
			
		||||
        return new MPString(value);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static MPBoolean mp(boolean value) {
 | 
			
		||||
        return new MPBoolean(value);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static MPFloat mp(double value) {
 | 
			
		||||
        return new MPFloat(value);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static MPFloat mp(float value) {
 | 
			
		||||
        return new MPFloat(value);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static MPInteger mp(long value) {
 | 
			
		||||
        return new MPInteger(value);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static MPBinary mp(byte... data) {
 | 
			
		||||
        return new MPBinary(data);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static MPNil nil() {
 | 
			
		||||
        return NIL;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										270
									
								
								src/test/java/ch/dissem/msgpack/ReaderTest.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										270
									
								
								src/test/java/ch/dissem/msgpack/ReaderTest.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,270 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2017 Christian Basler
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package ch.dissem.msgpack;
 | 
			
		||||
 | 
			
		||||
import ch.dissem.msgpack.types.*;
 | 
			
		||||
import org.junit.Test;
 | 
			
		||||
 | 
			
		||||
import java.io.ByteArrayInputStream;
 | 
			
		||||
import java.io.ByteArrayOutputStream;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.io.InputStream;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
import java.util.Random;
 | 
			
		||||
 | 
			
		||||
import static ch.dissem.msgpack.types.Utils.mp;
 | 
			
		||||
import static ch.dissem.msgpack.types.Utils.nil;
 | 
			
		||||
import static org.hamcrest.CoreMatchers.instanceOf;
 | 
			
		||||
import static org.hamcrest.core.Is.is;
 | 
			
		||||
import static org.junit.Assert.assertThat;
 | 
			
		||||
 | 
			
		||||
public class ReaderTest {
 | 
			
		||||
    private static final Random RANDOM = new Random();
 | 
			
		||||
    private Reader reader = Reader.getInstance();
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void ensureDemoJsonIsParsedCorrectly() throws Exception {
 | 
			
		||||
        MPType read = reader.read(stream("demo.mp"));
 | 
			
		||||
        assertThat(read, instanceOf(MPMap.class));
 | 
			
		||||
        assertThat(read.toString(), is(string("demo.json")));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void ensureDemoJsonIsEncodedCorrectly() throws Exception {
 | 
			
		||||
        @SuppressWarnings("MismatchedQueryAndUpdateOfCollection")
 | 
			
		||||
        MPMap<MPString, MPType<?>> object = new MPMap<>();
 | 
			
		||||
        object.put(mp("compact"), mp(true));
 | 
			
		||||
        object.put(mp("schema"), mp(0));
 | 
			
		||||
        ByteArrayOutputStream out = new ByteArrayOutputStream();
 | 
			
		||||
        object.pack(out);
 | 
			
		||||
        assertThat(out.toByteArray(), is(bytes("demo.mp")));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    @SuppressWarnings("unchecked")
 | 
			
		||||
    public void ensureMPArrayIsEncodedAndDecodedCorrectly() throws Exception {
 | 
			
		||||
        MPArray<MPType<?>> array = new MPArray<>(
 | 
			
		||||
                mp(new byte[]{1, 3, 3, 7}),
 | 
			
		||||
                mp(false),
 | 
			
		||||
                mp(Math.PI),
 | 
			
		||||
                mp(1.5f),
 | 
			
		||||
                mp(42),
 | 
			
		||||
                new MPMap<MPNil, MPNil>(),
 | 
			
		||||
                nil(),
 | 
			
		||||
                mp("yay! \uD83E\uDD13")
 | 
			
		||||
        );
 | 
			
		||||
        ByteArrayOutputStream out = new ByteArrayOutputStream();
 | 
			
		||||
        array.pack(out);
 | 
			
		||||
        MPType read = reader.read(new ByteArrayInputStream(out.toByteArray()));
 | 
			
		||||
        assertThat(read, instanceOf(MPArray.class));
 | 
			
		||||
        assertThat((MPArray<MPType<?>>) read, is(array));
 | 
			
		||||
        assertThat(read.toJson(), is("[\n  AQMDBw==,\n  false,\n  3.141592653589793,\n  1.5,\n  42,\n  {\n  },\n  null,\n  \"yay! 🤓\"\n]"));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void ensureFloatIsEncodedAndDecodedCorrectly() throws Exception {
 | 
			
		||||
        MPFloat expected = new MPFloat(1.5f);
 | 
			
		||||
        ByteArrayOutputStream out = new ByteArrayOutputStream();
 | 
			
		||||
        expected.pack(out);
 | 
			
		||||
        MPType read = reader.read(new ByteArrayInputStream(out.toByteArray()));
 | 
			
		||||
        assertThat(read, instanceOf(MPFloat.class));
 | 
			
		||||
        MPFloat actual = (MPFloat) read;
 | 
			
		||||
        assertThat(actual, is(expected));
 | 
			
		||||
        assertThat(actual.getPrecision(), is(MPFloat.Precision.FLOAT32));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void ensureDoubleIsEncodedAndDecodedCorrectly() throws Exception {
 | 
			
		||||
        MPFloat expected = new MPFloat(Math.PI);
 | 
			
		||||
        ByteArrayOutputStream out = new ByteArrayOutputStream();
 | 
			
		||||
        expected.pack(out);
 | 
			
		||||
        MPType read = reader.read(new ByteArrayInputStream(out.toByteArray()));
 | 
			
		||||
        assertThat(read, instanceOf(MPFloat.class));
 | 
			
		||||
        MPFloat actual = (MPFloat) read;
 | 
			
		||||
        assertThat(actual, is(expected));
 | 
			
		||||
        assertThat(actual.getValue(), is(Math.PI));
 | 
			
		||||
        assertThat(actual.getPrecision(), is(MPFloat.Precision.FLOAT64));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void ensureLongsAreEncodedAndDecodedCorrectly() throws Exception {
 | 
			
		||||
        // positive fixnum
 | 
			
		||||
        ensureLongIsEncodedAndDecodedCorrectly(0, 1);
 | 
			
		||||
        ensureLongIsEncodedAndDecodedCorrectly(127, 1);
 | 
			
		||||
        // negative fixnum
 | 
			
		||||
        ensureLongIsEncodedAndDecodedCorrectly(-1, 1);
 | 
			
		||||
        ensureLongIsEncodedAndDecodedCorrectly(-32, 1);
 | 
			
		||||
        // uint 8
 | 
			
		||||
        ensureLongIsEncodedAndDecodedCorrectly(128, 2);
 | 
			
		||||
        ensureLongIsEncodedAndDecodedCorrectly(255, 2);
 | 
			
		||||
        // uint 16
 | 
			
		||||
        ensureLongIsEncodedAndDecodedCorrectly(256, 3);
 | 
			
		||||
        ensureLongIsEncodedAndDecodedCorrectly(65535, 3);
 | 
			
		||||
        // uint 32
 | 
			
		||||
        ensureLongIsEncodedAndDecodedCorrectly(65536, 5);
 | 
			
		||||
        ensureLongIsEncodedAndDecodedCorrectly(4294967295L, 5);
 | 
			
		||||
        // uint 64
 | 
			
		||||
        ensureLongIsEncodedAndDecodedCorrectly(4294967296L, 9);
 | 
			
		||||
        ensureLongIsEncodedAndDecodedCorrectly(Long.MAX_VALUE, 9);
 | 
			
		||||
        // int 8
 | 
			
		||||
        ensureLongIsEncodedAndDecodedCorrectly(-33, 2);
 | 
			
		||||
        ensureLongIsEncodedAndDecodedCorrectly(-128, 2);
 | 
			
		||||
        // int 16
 | 
			
		||||
        ensureLongIsEncodedAndDecodedCorrectly(-129, 3);
 | 
			
		||||
        ensureLongIsEncodedAndDecodedCorrectly(-32768, 3);
 | 
			
		||||
        // int 32
 | 
			
		||||
        ensureLongIsEncodedAndDecodedCorrectly(-32769, 5);
 | 
			
		||||
        ensureLongIsEncodedAndDecodedCorrectly(Integer.MIN_VALUE, 5);
 | 
			
		||||
        // int 64
 | 
			
		||||
        ensureLongIsEncodedAndDecodedCorrectly(-2147483649L, 9);
 | 
			
		||||
        ensureLongIsEncodedAndDecodedCorrectly(Long.MIN_VALUE, 9);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void ensureLongIsEncodedAndDecodedCorrectly(long val, int bytes) throws Exception {
 | 
			
		||||
        MPInteger value = mp(val);
 | 
			
		||||
        ByteArrayOutputStream out = new ByteArrayOutputStream();
 | 
			
		||||
        value.pack(out);
 | 
			
		||||
        MPType read = reader.read(new ByteArrayInputStream(out.toByteArray()));
 | 
			
		||||
        assertThat(out.size(), is(bytes));
 | 
			
		||||
        assertThat(read, instanceOf(MPInteger.class));
 | 
			
		||||
        assertThat((MPInteger) read, is(value));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void ensureStringsAreEncodedAndDecodedCorrectly() throws Exception {
 | 
			
		||||
        ensureStringIsEncodedAndDecodedCorrectly(0);
 | 
			
		||||
        ensureStringIsEncodedAndDecodedCorrectly(31);
 | 
			
		||||
        ensureStringIsEncodedAndDecodedCorrectly(32);
 | 
			
		||||
        ensureStringIsEncodedAndDecodedCorrectly(255);
 | 
			
		||||
        ensureStringIsEncodedAndDecodedCorrectly(256);
 | 
			
		||||
        ensureStringIsEncodedAndDecodedCorrectly(65535);
 | 
			
		||||
        ensureStringIsEncodedAndDecodedCorrectly(65536);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void ensureJsonStringsAreEscapedCorrectly() throws Exception {
 | 
			
		||||
        StringBuilder builder = new StringBuilder();
 | 
			
		||||
        for (char c = '\u0001'; c < ' '; c++) {
 | 
			
		||||
            builder.append(c);
 | 
			
		||||
        }
 | 
			
		||||
        MPString string = new MPString(builder.toString());
 | 
			
		||||
        assertThat(string.toJson(), is("\"\\u0001\\u0002\\u0003\\u0004\\u0005\\u0006\\u0007\\b\\t\\n\\u000b\\f\\r\\u000e\\u000f\\u0010\\u0011\\u0012\\u0013\\u0014\\u0015\\u0016\\u0017\\u0018\\u0019\\u001a\\u001b\\u001c\\u001d\\u001e\\u001f\""));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void ensureStringIsEncodedAndDecodedCorrectly(int length) throws Exception {
 | 
			
		||||
        MPString value = new MPString(stringWithLength(length));
 | 
			
		||||
        ByteArrayOutputStream out = new ByteArrayOutputStream();
 | 
			
		||||
        value.pack(out);
 | 
			
		||||
        MPType read = reader.read(new ByteArrayInputStream(out.toByteArray()));
 | 
			
		||||
        assertThat(read, instanceOf(MPString.class));
 | 
			
		||||
        assertThat((MPString) read, is(value));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void ensureBinariesAreEncodedAndDecodedCorrectly() throws Exception {
 | 
			
		||||
        ensureBinaryIsEncodedAndDecodedCorrectly(0);
 | 
			
		||||
        ensureBinaryIsEncodedAndDecodedCorrectly(255);
 | 
			
		||||
        ensureBinaryIsEncodedAndDecodedCorrectly(256);
 | 
			
		||||
        ensureBinaryIsEncodedAndDecodedCorrectly(65535);
 | 
			
		||||
        ensureBinaryIsEncodedAndDecodedCorrectly(65536);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void ensureBinaryIsEncodedAndDecodedCorrectly(int length) throws Exception {
 | 
			
		||||
        MPBinary value = new MPBinary(new byte[length]);
 | 
			
		||||
        RANDOM.nextBytes(value.getValue());
 | 
			
		||||
        ByteArrayOutputStream out = new ByteArrayOutputStream();
 | 
			
		||||
        value.pack(out);
 | 
			
		||||
        MPType read = reader.read(new ByteArrayInputStream(out.toByteArray()));
 | 
			
		||||
        assertThat(read, instanceOf(MPBinary.class));
 | 
			
		||||
        assertThat((MPBinary) read, is(value));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void ensureArraysAreEncodedAndDecodedCorrectly() throws Exception {
 | 
			
		||||
        ensureArrayIsEncodedAndDecodedCorrectly(0);
 | 
			
		||||
        ensureArrayIsEncodedAndDecodedCorrectly(15);
 | 
			
		||||
        ensureArrayIsEncodedAndDecodedCorrectly(16);
 | 
			
		||||
        ensureArrayIsEncodedAndDecodedCorrectly(65535);
 | 
			
		||||
        ensureArrayIsEncodedAndDecodedCorrectly(65536);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @SuppressWarnings("unchecked")
 | 
			
		||||
    private void ensureArrayIsEncodedAndDecodedCorrectly(int length) throws Exception {
 | 
			
		||||
        MPNil nil = new MPNil();
 | 
			
		||||
        ArrayList<MPNil> list = new ArrayList<>(length);
 | 
			
		||||
        for (int i = 0; i < length; i++) {
 | 
			
		||||
            list.add(nil);
 | 
			
		||||
        }
 | 
			
		||||
        MPArray<MPNil> value = new MPArray<>(list);
 | 
			
		||||
        ByteArrayOutputStream out = new ByteArrayOutputStream();
 | 
			
		||||
        value.pack(out);
 | 
			
		||||
        MPType read = reader.read(new ByteArrayInputStream(out.toByteArray()));
 | 
			
		||||
        assertThat(read, instanceOf(MPArray.class));
 | 
			
		||||
        assertThat((MPArray<MPNil>) read, is(value));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void ensureMapsAreEncodedAndDecodedCorrectly() throws Exception {
 | 
			
		||||
        ensureMapIsEncodedAndDecodedCorrectly(0);
 | 
			
		||||
        ensureMapIsEncodedAndDecodedCorrectly(15);
 | 
			
		||||
        ensureMapIsEncodedAndDecodedCorrectly(16);
 | 
			
		||||
        ensureMapIsEncodedAndDecodedCorrectly(65535);
 | 
			
		||||
        ensureMapIsEncodedAndDecodedCorrectly(65536);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @SuppressWarnings("unchecked")
 | 
			
		||||
    private void ensureMapIsEncodedAndDecodedCorrectly(int size) throws Exception {
 | 
			
		||||
        MPNil nil = new MPNil();
 | 
			
		||||
        HashMap<MPInteger, MPNil> map = new HashMap<>(size);
 | 
			
		||||
        for (int i = 0; i < size; i++) {
 | 
			
		||||
            map.put(mp(i), nil);
 | 
			
		||||
        }
 | 
			
		||||
        MPMap<MPInteger, MPNil> value = new MPMap<>(map);
 | 
			
		||||
        ByteArrayOutputStream out = new ByteArrayOutputStream();
 | 
			
		||||
        value.pack(out);
 | 
			
		||||
        MPType read = reader.read(new ByteArrayInputStream(out.toByteArray()));
 | 
			
		||||
        assertThat(read, instanceOf(MPMap.class));
 | 
			
		||||
        assertThat((MPMap<MPInteger, MPNil>) read, is(value));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private String stringWithLength(int length) {
 | 
			
		||||
        StringBuilder result = new StringBuilder(length);
 | 
			
		||||
        for (int i = 0; i < length; i++) {
 | 
			
		||||
            result.append('a');
 | 
			
		||||
        }
 | 
			
		||||
        return result.toString();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private InputStream stream(String resource) {
 | 
			
		||||
        return getClass().getClassLoader().getResourceAsStream(resource);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private byte[] bytes(String resource) throws IOException {
 | 
			
		||||
        InputStream in = stream(resource);
 | 
			
		||||
        ByteArrayOutputStream out = new ByteArrayOutputStream();
 | 
			
		||||
        byte[] buffer = new byte[100];
 | 
			
		||||
        for (int size = in.read(buffer); size >= 0; size = in.read(buffer)) {
 | 
			
		||||
            out.write(buffer, 0, size);
 | 
			
		||||
        }
 | 
			
		||||
        return out.toByteArray();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private String string(String resource) throws IOException {
 | 
			
		||||
        return new String(bytes(resource), "UTF-8");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										4
									
								
								src/test/resources/demo.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								src/test/resources/demo.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,4 @@
 | 
			
		||||
{
 | 
			
		||||
  "compact": true,
 | 
			
		||||
  "schema": 0
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								src/test/resources/demo.mp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								src/test/resources/demo.mp
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
		Reference in New Issue
	
	Block a user