Module: NBTFile

Includes:
Private
Defined in:
lib/nbtfile.rb

Defined Under Namespace

Modules: Private, Tokens, Types Classes: Emitter, EncodingError

Constant Summary

Constants included from Private

Private::TOKEN_CLASSES_BY_INDEX, Private::TOKEN_INDICES_BY_CLASS

Class Method Summary collapse

Class Method Details

.emit(io) ⇒ Object

Emit a NBT tokens to a stream



573
574
575
576
577
578
579
580
# File 'lib/nbtfile.rb', line 573

def self.emit(io) #:yields: emitter
  emitter = Emitter.new(io)
  begin
    yield emitter
  ensure
    emitter.finish
  end
end

.load(io) ⇒ Object

Load an NBT file as a Ruby data structure; returns a pair containing the name of the top-level compound tag and its value



584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
# File 'lib/nbtfile.rb', line 584

def self.load(io)
  root = {}
  stack = [root]

  self.tokenize(io) do |token|
    case token
    when Tokens::TAG_Compound
      value = {}
    when Tokens::TAG_List
      value = []
    when Tokens::TAG_End
      stack.pop
      next
    else
      value = token.value
    end

    stack.last[token.name] = value

    case token
    when Tokens::TAG_Compound, Tokens::TAG_List
      stack.push value
    end
  end

  root.first
end

.read(io) ⇒ Object

Reads an NBT stream as a data structure and returns a pair containing the name of the top-level compound tag and its value.



619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
# File 'lib/nbtfile.rb', line 619

def self.read(io)
  root = {}
  stack = [root]

  self.tokenize(io) do |token|
    case token
    when Tokens::TAG_Byte
      value = Types::Byte.new(token.value)
    when Tokens::TAG_Short
      value = Types::Short.new(token.value)
    when Tokens::TAG_Int
      value = Types::Int.new(token.value)
    when Tokens::TAG_Long
      value = Types::Long.new(token.value)
    when Tokens::TAG_Float
      value = Types::Float.new(token.value)
    when Tokens::TAG_Double
      value = Types::Double.new(token.value)
    when Tokens::TAG_String
      value = Types::String.new(token.value)
    when Tokens::TAG_Byte_Array
      value = Types::ByteArray.new(token.value)
    when Tokens::TAG_List
      tag = token.value
      case
      when tag == Tokens::TAG_Byte
        type = Types::Byte
      when tag == Tokens::TAG_Short
        type = Types::Short
      when tag == Tokens::TAG_Int
        type = Types::Int
      when tag == Tokens::TAG_Long
        type = Types::Long
      when tag == Tokens::TAG_Float
        type = Types::Float
      when tag == Tokens::TAG_Double
        type = Types::Double
      when tag == Tokens::TAG_String
        type = Types::String
      when tag == Tokens::TAG_Byte_Array
        type = Types::ByteArray
      when tag == Tokens::TAG_List
        type = Types::List
      when tag == Tokens::TAG_Compound
        type = Types::Compound
      else
        raise TypeError, "Unexpected list type #{token.value}"
      end
      value = Types::List.new(type)
    when Tokens::TAG_Compound
      value = Types::Compound.new
    when Tokens::TAG_End
      stack.pop
      next
    else
      raise TypeError, "Unexpected token type #{token.class}"
    end

    current = stack.last
    case current
    when Types::List
      current << value
    else
      current[token.name] = value
    end

    case token
    when Tokens::TAG_Compound, Tokens::TAG_List
      stack.push value
    end
  end

  root.first
end

.tokenize(io) ⇒ Object

Produce a sequence of NBT tokens from a stream



556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
# File 'lib/nbtfile.rb', line 556

def self.tokenize(io)
  case io
  when String
    io = StringIO.new(io, "rb")
  end
  reader = Tokenizer.new(io)

  if block_given?
    reader.each_token { |token| yield token }
  else
    tokens = []
    reader.each_token { |token| tokens << token }
    tokens
  end
end

.transcode_to_yaml(input, output) ⇒ Object

Utility helper which transcodes a stream directly to YAML



613
614
615
# File 'lib/nbtfile.rb', line 613

def self.transcode_to_yaml(input, output)
  YAML.dump(load(input), output)
end

.write(io, name, body) ⇒ Object



764
765
766
767
768
769
# File 'lib/nbtfile.rb', line 764

def self.write(io, name, body)
  emit(io) do |emitter|
    writer = Writer.new(emitter)
    writer.write_pair(name, body)
  end
end