42final class CompoundTag extends Tag implements \Countable, \IteratorAggregate{
43 use NoDynamicFieldsTrait;
48 public function __construct(){
49 self::restrictArgCount(__METHOD__, func_num_args(), 0);
55 public static function create() : self{
59 public function count() : int{
60 return count($this->value);
67 return count($this->value);
85 return $this->value[$name] ?? null;
93 $tag = $this->getTag($name);
94 if($tag !==
null && !($tag instanceof
ListTag)){
105 $tag = $this->getTag($name);
106 if($tag !==
null && !($tag instanceof
CompoundTag)){
118 $this->value[$name] = $tag;
127 foreach($names as $name){
128 unset($this->value[$name]);
146 private function getTagValue(
string $name,
string $expectedClass, $default =
null){
147 $tag = $this->getTag($name);
148 if($tag instanceof $expectedClass){
149 return $tag->getValue();
152 throw new UnexpectedTagTypeException(
"Expected a tag of type $expectedClass, got " . get_class($tag));
155 if($default ===
null){
156 throw new NoSuchTagException(
"Tag \"$name\" does not exist");
166 public function getByte(
string $name, ?
int $default =
null) : int{
167 return $this->getTagValue($name, ByteTag::class, $default);
170 public function getShort(
string $name, ?
int $default =
null) : int{
171 return $this->getTagValue($name, ShortTag::class, $default);
174 public function getInt(
string $name, ?
int $default =
null) : int{
175 return $this->getTagValue($name, IntTag::class, $default);
178 public function getLong(
string $name, ?
int $default =
null) : int{
179 return $this->getTagValue($name, LongTag::class, $default);
182 public function getFloat(
string $name, ?
float $default =
null) : float{
183 return $this->getTagValue($name, FloatTag::class, $default);
186 public function getDouble(
string $name, ?
float $default =
null) : float{
187 return $this->getTagValue($name, DoubleTag::class, $default);
190 public function getByteArray(
string $name, ?
string $default =
null) : string{
191 return $this->getTagValue($name, ByteArrayTag::class, $default);
194 public function getString(
string $name, ?
string $default =
null) : string{
195 return $this->getTagValue($name, StringTag::class, $default);
203 public function getIntArray(
string $name, ?array $default =
null) : array{
204 return $this->getTagValue($name,
IntArrayTag::class, $default);
214 public function setByte(
string $name,
int $value) : self{
215 return $this->setTag($name, new
ByteTag($value));
221 public function setShort(
string $name,
int $value) : self{
222 return $this->setTag($name, new
ShortTag($value));
228 public function setInt(
string $name,
int $value) : self{
229 return $this->setTag($name, new
IntTag($value));
235 public function setLong(
string $name,
int $value) : self{
236 return $this->setTag($name, new
LongTag($value));
242 public function setFloat(
string $name,
float $value) : self{
243 return $this->setTag($name, new
FloatTag($value));
249 public function setDouble(
string $name,
float $value) : self{
250 return $this->setTag($name, new
DoubleTag($value));
263 public function setString(
string $name,
string $value) : self{
264 return $this->setTag($name, new
StringTag($value));
273 return $this->setTag($name, new
IntArrayTag($value));
276 protected function getTypeName() : string{
280 public function getType() : int{
281 return
NBT::TAG_Compound;
284 public static function read(NbtStreamReader $reader, ReaderTracker $tracker) : self{
286 $tracker->protectDepth(
static function() use($reader, $tracker, $result) :
void{
287 for($type = $reader->readByte(); $type !== NBT::TAG_End; $type = $reader->readByte()){
288 $name = $reader->readString();
289 $tag = NBT::createTag($type, $reader, $tracker);
290 if($result->getTag($name) !==
null){
298 $result->setTag($name, $tag);
304 public function write(NbtStreamWriter $writer) : void{
305 foreach($this->value as $name => $tag){
309 $name = (string) $name;
311 $writer->writeByte($tag->getType());
312 $writer->writeString($name);
313 $tag->write($writer);
315 $writer->writeByte(NBT::TAG_End);
318 protected function stringifyValue(
int $indentation) : string{
320 foreach($this->value as $name => $tag){
321 $str .= str_repeat(
" ", $indentation + 1) .
"\"$name\" => " . $tag->toString($indentation + 1) .
"\n";
323 return $str . str_repeat(
" ", $indentation) .
"}";
326 public function __clone(){
327 foreach($this->value as $key => $tag){
328 $this->value[$key] = $tag->safeClone();
341 foreach($this->value as $name => $tag){
344 yield strval($name) => $tag;
349 if(!($that instanceof $this) or $this->count() !== $that->count()){
353 foreach($this as $k => $v){
354 $other = $that->getTag($k);
355 if($other ===
null or !$v->equals($other)){
372 foreach($other as $k => $namedTag){
373 $new->setTag($k, clone $namedTag);