txl.go 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. package main
  2. import (
  3. "bytes"
  4. "encoding/binary"
  5. "strings"
  6. )
  7. type TXL struct {
  8. NumOfTPL uint16
  9. Unknown uint16
  10. }
  11. type TPLOffSet struct {
  12. // Offset is relative to the beginning of the txl1 section
  13. Offset uint32
  14. Padding uint32
  15. }
  16. func (r *Root) ParseTXL(data []byte, sectionSize uint32) {
  17. var tplOffsets []uint32
  18. var tplNames []string
  19. var txl TXL
  20. err := binary.Read(bytes.NewReader(data), binary.BigEndian, &txl)
  21. if err != nil {
  22. panic(err)
  23. }
  24. for i := 0; i < int(txl.NumOfTPL); i++ {
  25. // By now we have only read the header.
  26. // We will read the TPLOffset table in order to get our names.
  27. var tplTable TPLOffSet
  28. offset := 4 + (i * 8)
  29. err = binary.Read(bytes.NewReader(data[offset:]), binary.BigEndian, &tplTable)
  30. if err != nil {
  31. panic(err)
  32. }
  33. tplOffsets = append(tplOffsets, tplTable.Offset+4)
  34. // If we have reached the last index, append the section size to the slice.
  35. if i == int(txl.NumOfTPL)-1 {
  36. tplOffsets = append(tplOffsets, sectionSize-8)
  37. }
  38. }
  39. // Now that we have the offsets, retrieve the TPL names.
  40. for i := 0; i < int(txl.NumOfTPL); i++ {
  41. tplName := string(data[tplOffsets[i]:tplOffsets[i+1]])
  42. // Strip the null terminator
  43. tplName = strings.Replace(tplName, "\x00", "", -1)
  44. tplNames = append(tplNames, tplName)
  45. }
  46. r.TXL = &TPLNames{TPLName: tplNames}
  47. }
  48. func (b *BRLYTWriter) WriteTXL(data Root) {
  49. sectionWriter := bytes.NewBuffer(nil)
  50. header := SectionHeader{
  51. Type: SectionTypeTXL,
  52. Size: 0,
  53. }
  54. txl := TXL{
  55. NumOfTPL: uint16(len(data.TXL.TPLName)),
  56. Unknown: 0,
  57. }
  58. offset := len(data.TXL.TPLName) * 8
  59. offsets := make([]TPLOffSet, len(data.TXL.TPLName))
  60. for i, _ := range data.TXL.TPLName {
  61. if i != 0 {
  62. offset += len(data.TXL.TPLName[i-1]) + 1
  63. }
  64. tplOffset := TPLOffSet{
  65. Offset: uint32(offset),
  66. Padding: 0,
  67. }
  68. offsets[i] = tplOffset
  69. }
  70. for _, s := range data.TXL.TPLName {
  71. _, err := sectionWriter.WriteString(s)
  72. if err != nil {
  73. panic(err)
  74. }
  75. // Write null terminator
  76. _, _ = sectionWriter.Write([]byte{0})
  77. }
  78. for (b.Len()+sectionWriter.Len())%4 != 0 {
  79. _, _ = sectionWriter.Write([]byte{0})
  80. }
  81. header.Size = uint32(12 + (8 * len(data.TXL.TPLName)) + sectionWriter.Len())
  82. write(b, header)
  83. write(b, txl)
  84. write(b, offsets)
  85. write(b, sectionWriter.Bytes())
  86. }