example_test.go 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. // Copyright 2014 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package riff_test
  5. import (
  6. "fmt"
  7. "io"
  8. "io/ioutil"
  9. "log"
  10. "strings"
  11. "golang.org/x/image/riff"
  12. )
  13. func ExampleReader() {
  14. formType, r, err := riff.NewReader(strings.NewReader(data))
  15. if err != nil {
  16. log.Fatal(err)
  17. }
  18. fmt.Printf("RIFF(%s)\n", formType)
  19. if err := dump(r, ".\t"); err != nil {
  20. log.Fatal(err)
  21. }
  22. // Output:
  23. // RIFF(ROOT)
  24. // . ZERO ""
  25. // . ONE "a"
  26. // . LIST(META)
  27. // . . LIST(GOOD)
  28. // . . . ONE "a"
  29. // . . . FIVE "klmno"
  30. // . . ZERO ""
  31. // . . LIST(BAD )
  32. // . . . THRE "def"
  33. // . TWO "bc"
  34. // . LIST(UGLY)
  35. // . . FOUR "ghij"
  36. // . . SIX "pqrstu"
  37. }
  38. func dump(r *riff.Reader, indent string) error {
  39. for {
  40. chunkID, chunkLen, chunkData, err := r.Next()
  41. if err == io.EOF {
  42. return nil
  43. }
  44. if err != nil {
  45. return err
  46. }
  47. if chunkID == riff.LIST {
  48. listType, list, err := riff.NewListReader(chunkLen, chunkData)
  49. if err != nil {
  50. return err
  51. }
  52. fmt.Printf("%sLIST(%s)\n", indent, listType)
  53. if err := dump(list, indent+".\t"); err != nil {
  54. return err
  55. }
  56. continue
  57. }
  58. b, err := ioutil.ReadAll(chunkData)
  59. if err != nil {
  60. return err
  61. }
  62. fmt.Printf("%s%s %q\n", indent, chunkID, b)
  63. }
  64. }
  65. func encodeU32(u uint32) string {
  66. return string([]byte{
  67. byte(u >> 0),
  68. byte(u >> 8),
  69. byte(u >> 16),
  70. byte(u >> 24),
  71. })
  72. }
  73. func encode(chunkID, contents string) string {
  74. n := len(contents)
  75. if n&1 == 1 {
  76. contents += "\x00"
  77. }
  78. return chunkID + encodeU32(uint32(n)) + contents
  79. }
  80. func encodeMulti(typ0, typ1 string, chunks ...string) string {
  81. n := 4
  82. for _, c := range chunks {
  83. n += len(c)
  84. }
  85. s := typ0 + encodeU32(uint32(n)) + typ1
  86. for _, c := range chunks {
  87. s += c
  88. }
  89. return s
  90. }
  91. var (
  92. d0 = encode("ZERO", "")
  93. d1 = encode("ONE ", "a")
  94. d2 = encode("TWO ", "bc")
  95. d3 = encode("THRE", "def")
  96. d4 = encode("FOUR", "ghij")
  97. d5 = encode("FIVE", "klmno")
  98. d6 = encode("SIX ", "pqrstu")
  99. l0 = encodeMulti("LIST", "GOOD", d1, d5)
  100. l1 = encodeMulti("LIST", "BAD ", d3)
  101. l2 = encodeMulti("LIST", "UGLY", d4, d6)
  102. l01 = encodeMulti("LIST", "META", l0, d0, l1)
  103. data = encodeMulti("RIFF", "ROOT", d0, d1, l01, d2, l2)
  104. )