PocketMine-MP 5.23.3 git-976fc63567edab7a6fb6aeae739f43cf9fe57de4
Loading...
Searching...
No Matches
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
105 public function readMultiple(string $buffer, int $maxDepth = 0) : array{
106 $this->buffer = new BinaryStream($buffer);
107
108 $retval = [];
109
110 while(!$this->buffer->feof()){
111 try{
112 $retval[] = $this->readRoot($maxDepth);
113 }catch(BinaryDataException $e){
114 throw new NbtDataException($e->getMessage(), 0, $e);
115 }
116 }
117
118 return $retval;
119 }
120
121 private function writeRoot(TreeRoot $root) : void{
122 $this->writeByte($root->getTag()->getType());
123 $this->writeString($root->getName());
124 $root->getTag()->write($this);
125 }
126
127 public function write(TreeRoot $data) : string{
128 $this->buffer = new BinaryStream();
129
130 $this->writeRoot($data);
131
132 return $this->buffer->getBuffer();
133 }
134
141 public function writeHeadless(Tag $data) : string{
142 $this->buffer = new BinaryStream();
143 $data->write($this);
144 return $this->buffer->getBuffer();
145 }
146
150 public function writeMultiple(array $data) : string{
151 $this->buffer = new BinaryStream();
152 foreach($data as $root){
153 $this->writeRoot($root);
154 }
155 return $this->buffer->getBuffer();
156 }
157
158 public function readByte() : int{
159 return $this->buffer->getByte();
160 }
161
162 public function readSignedByte() : int{
163 return Binary::signByte($this->buffer->getByte());
164 }
165
166 public function writeByte(int $v) : void{
167 $this->buffer->putByte($v);
168 }
169
170 public function readByteArray() : string{
171 $length = $this->readInt();
172 if($length < 0){
173 throw new NbtDataException("Array length cannot be less than zero ($length < 0)");
174 }
175 return $this->buffer->get($length);
176 }
177
178 public function writeByteArray(string $v) : void{
179 $this->writeInt(strlen($v)); //TODO: overflow
180 $this->buffer->put($v);
181 }
182
186 protected static function checkReadStringLength(int $len) : int{
187 if($len > 32767){
188 throw new NbtDataException("NBT string length too large ($len > 32767)");
189 }
190 return $len;
191 }
192
196 protected static function checkWriteStringLength(int $len) : int{
197 if($len > 32767){
198 throw new \InvalidArgumentException("NBT string length too large ($len > 32767)");
199 }
200 return $len;
201 }
202
203 public function readString() : string{
204 return $this->buffer->get(self::checkReadStringLength($this->readShort()));
205 }
206
210 public function writeString(string $v) : void{
211 $this->writeShort(self::checkWriteStringLength(strlen($v)));
212 $this->buffer->put($v);
213 }
214}
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