func TagRead(r io.ReadSeeker) (TagFileEntry, error) { reader := binary.BinaryReader{Reader: r, Endianess: binary.LittleEndian} var err error var entry TagFileEntry if err = reader.ReadInterface(&entry); err == nil { offset, err := r.Seek(0, 1) entry.Data = io.NewSectionReader(util.ReaderAt(r), offset, int64(entry.Size)) return entry, err } return TagFileEntry{}, err }
func (a *Archive) parse() (err error) { reader := binary.BinaryReader{Reader: a.reader, Endianess: binary.LittleEndian} if err = reader.ReadInterface(&a.header); err != nil { return } entryOffset := int64(0x10) a.entries = make([]archiveEntry, a.header.EntryCount) for i := uint32(0); i < a.header.EntryCount; i++ { entry := &a.entries[i] if err = reader.ReadInterface(entry); err != nil { return } entry.Data = io.NewSectionReader(util.ReaderAt(a.reader), entryOffset+int64(entry.DataOffset), int64(entry.DataSize)) entryOffset += int64(entry.DataEnd) } return }
func (f *TagFile) parse() error { var err error reader := binary.BinaryReader{Reader: f.reader, Endianess: binary.LittleEndian} offset := int64(0) var entry TagFileEntry for err = reader.ReadInterface(&entry); err == nil; err = reader.ReadInterface(&entry) { offset += 8 entry.Data = io.NewSectionReader(util.ReaderAt(f.reader), offset, int64(entry.Size)) f.Entries = append(f.Entries, entry) _, err = f.reader.Seek(int64(entry.Size), 1) offset += int64(entry.Size) } if err == io.EOF { return nil } return err }
func (m *Model) parse() (err error) { reader := binary.BinaryReader{Reader: m.reader, Endianess: binary.LittleEndian} if err = reader.ReadInterface(&m.Header); err != nil { return } reader.Seek(int64(m.Header.HeaderSize)-0x10, 1) offset := int64(m.Header.HeaderSize) for err == nil { entry := ModelEntry{} if err = reader.ReadInterface(&entry); err != nil { if err == io.EOF { return nil } return } entry.Data = io.NewSectionReader(util.ReaderAt(m.reader), offset+0x0c, int64(entry.Size)-0x04) offset += 0x08 + int64(entry.Size) m.Entries = append(m.Entries, entry) switch entry.SubType { case "NODE": // Bone data case "NODO": // More bone things case "VSET": // Vertex data shit err = parseModelEntryVSET(&entry) } } return }
func (t *TextFile) parse(r io.ReadSeeker) (err error) { nifl, err := TagRead(r) if err != nil { return err } if nifl.Tag != "NIFL" { return errors.New("NIFL tag expected") } reader := binary.BinaryReader{Reader: nifl.Data, Endianess: binary.LittleEndian} type niflHeaderType struct { Unk, OffsetREL0, SizeREL0, OffsetNOF0, SizeNOF0 uint32 } var niflHeader niflHeaderType if err = reader.ReadInterface(&niflHeader); err != nil { return err } if niflHeader.Unk != 1 { return errors.New("NIFL header magic != 1") } r.Seek(int64(niflHeader.OffsetREL0), 0) rel0, err := TagRead(r) if rel0.Tag != "REL0" { return errors.New("REL0 tag expected") } var rel0data io.ReadSeeker var rel0strings io.ReadSeeker reader = binary.BinaryReader{Reader: rel0.Data, Endianess: binary.LittleEndian} rel0size, err := reader.Uint32() rel0data = io.NewSectionReader(util.ReaderAt(rel0.Data), 8, int64(rel0size)-8) rel0strings = io.NewSectionReader(util.ReaderAt(rel0.Data), int64(rel0size), int64(rel0.Size-rel0size)) if rel0size < textBufferDataThreshold { rel0data, err = util.MemReader(rel0data) if err != nil { return err } } if rel0.Size-rel0size < textBufferThreshold { rel0strings, err = util.MemReader(rel0strings) if err != nil { return err } } r.Seek(int64(niflHeader.OffsetNOF0), 0) nof0, err := TagRead(r) if nof0.Tag != "NOF0" { return errors.New("NOF0 tag expected") } nof0reader := binary.BinaryReader{Reader: nof0.Data, Endianess: binary.LittleEndian} count, err := nof0reader.Uint32() offsets := make([]uint32, int(count)+1) i := 0 for offset, _ := nof0reader.Uint32(); i < int(count); i++ { end, _ := nof0reader.Uint32() offsets[i] = end - offset offset = end if offsets[i]%4 != 0 { return errors.New("nof0 entry not a multiple of 32 bits") } } offsets[i] = 8 t.Entries = make([]TextEntry, len(offsets)) rel0reader := binary.BinaryReader{Reader: rel0data, Endianess: binary.LittleEndian} pairMode := false var pair *string var pairi int for i, offset := range offsets { entry := &t.Entries[i] entry.Value = make([]uint32, offset/4) for i := 0; i < int(offset/4); i++ { entry.Value[i], err = rel0reader.Uint32() } if entry.Value[0] == 0xffffffff { pairMode = true } else if entry.Value[0] == 0x14 { pairMode = false pair = nil } if len(entry.Value) == 1 && entry.Value[0] != 0xffffffff { rel0strings.Seek(int64(entry.Value[0]-rel0size-8), 0) charSize := 1 if pair != nil { charSize = 2 } entry.Text, _ = readString(charSize, rel0strings) if pair != nil { entry.TextStatus = TextEntryString t.Pairs = append(t.Pairs, TextPair{*pair, entry.Text, pairi, i}) pair = nil } else { entry.TextStatus = TextEntryIdentifier if pairMode { pair = &entry.Text pairi = i } } } } _, err = r.Seek(int64((nof0.Size+8+0x0f)/0x10*0x10)-8, 1) nend, err := TagRead(r) if nend.Tag != "NEND" { return errors.New("NEND tag expected") } return err }