PocketMine-MP 5.15.1 git-5ef247620a7c6301a849b54e5ef1009217729fc8
BaseNbtSerializer.php
1<?php
2
3/*
4 *
5 * ____ _ _ __ __ _ __ __ ____
6 * | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
7 * | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
8 * | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
9 * |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
10 *
11 * This program is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License as published by
13 * the Free Software Foundation, either version 3 of the License, or
14 * (at your option) any later version.
15 *
16 * @author PocketMine Team
17 * @link http://www.pocketmine.net/
18 *
19 *
20*/
21
22declare(strict_types=1);
23
25
30use function strlen;
31
37 protected $buffer;
38
39 public function __construct(){
40 $this->buffer = new BinaryStream();
41 }
42
47 private function readRoot(int $maxDepth) : TreeRoot{
48 $type = $this->readByte();
49 if($type === NBT::TAG_End){
50 throw new NbtDataException("Found TAG_End at the start of buffer");
51 }
52
53 $rootName = $this->readString();
54 return new TreeRoot(NBT::createTag($type, $this, new ReaderTracker($maxDepth)), $rootName);
55 }
56
64 public function read(string $buffer, int &$offset = 0, int $maxDepth = 0) : TreeRoot{
65 $this->buffer = new BinaryStream($buffer, $offset);
66
67 try{
68 $data = $this->readRoot($maxDepth);
69 }catch(BinaryDataException $e){
70 throw new NbtDataException($e->getMessage(), 0, $e);
71 }
72 $offset = $this->buffer->getOffset();
73
74 return $data;
75 }
76
87 public function readHeadless(string $buffer, int $rootType, int &$offset = 0, int $maxDepth = 0) : Tag{
88 $this->buffer = new BinaryStream($buffer, $offset);
89
90 $data = NBT::createTag($rootType, $this, new ReaderTracker($maxDepth));
91 $offset = $this->buffer->getOffset();
92
93 return $data;
94 }
95
104 public function readMultiple(string $buffer, int $maxDepth = 0) : array{
105 $this->buffer = new BinaryStream($buffer);
106
107 $retval = [];
108
109 while(!$this->buffer->feof()){
110 try{
111 $retval[] = $this->readRoot($maxDepth);
112 }catch(BinaryDataException $e){
113 throw new NbtDataException($e->getMessage(), 0, $e);
114 }
115 }
116
117 return $retval;
118 }
119
120 private function writeRoot(TreeRoot $root) : void{
121 $this->writeByte($root->getTag()->getType());
122 $this->writeString($root->getName());
123 $root->getTag()->write($this);
124 }
125
126 public function write(TreeRoot $data) : string{
127 $this->buffer = new BinaryStream();
128
129 $this->writeRoot($data);
130
131 return $this->buffer->getBuffer();
132 }
133
140 public function writeHeadless(Tag $data) : string{
141 $this->buffer = new BinaryStream();
142 $data->write($this);
143 return $this->buffer->getBuffer();
144 }
145
149 public function writeMultiple(array $data) : string{
150 $this->buffer = new BinaryStream();
151 foreach($data as $root){
152 $this->writeRoot($root);
153 }
154 return $this->buffer->getBuffer();
155 }
156
157 public function readByte() : int{
158 return $this->buffer->getByte();
159 }
160
161 public function readSignedByte() : int{
162 return Binary::signByte($this->buffer->getByte());
163 }
164
165 public function writeByte(int $v) : void{
166 $this->buffer->putByte($v);
167 }
168
169 public function readByteArray() : string{
170 $length = $this->readInt();
171 if($length < 0){
172 throw new NbtDataException("Array length cannot be less than zero ($length < 0)");
173 }
174 return $this->buffer->get($length);
175 }
176
177 public function writeByteArray(string $v) : void{
178 $this->writeInt(strlen($v)); //TODO: overflow
179 $this->buffer->put($v);
180 }
181
185 protected static function checkReadStringLength(int $len) : int{
186 if($len > 32767){
187 throw new NbtDataException("NBT string length too large ($len > 32767)");
188 }
189 return $len;
190 }
191
195 protected static function checkWriteStringLength(int $len) : int{
196 if($len > 32767){
197 throw new \InvalidArgumentException("NBT string length too large ($len > 32767)");
198 }
199 return $len;
200 }
201
202 public function readString() : string{
203 return $this->buffer->get(self::checkReadStringLength($this->readShort()));
204 }
205
209 public function writeString(string $v) : void{
210 $this->writeShort(self::checkWriteStringLength(strlen($v)));
211 $this->buffer->put($v);
212 }
213}
read(string $buffer, int &$offset=0, int $maxDepth=0)
readHeadless(string $buffer, int $rootType, int &$offset=0, int $maxDepth=0)
readMultiple(string $buffer, int $maxDepth=0)
static createTag(int $type, NbtStreamReader $reader, ReaderTracker $tracker)
Definition: NBT.php:60