decode.go 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. package goyaml
  2. /* #include "helpers.c" */
  3. import "C"
  4. import (
  5. "unsafe"
  6. "reflect"
  7. "strconv"
  8. )
  9. type decoder struct {
  10. parser *C.yaml_parser_t
  11. event *C.yaml_event_t
  12. }
  13. func newDecoder(b []byte) *decoder {
  14. if len(b) == 0 {
  15. panic("Can't handle empty buffers yet") // XXX Fix this.
  16. }
  17. d := decoder{}
  18. d.event = &C.yaml_event_t{}
  19. d.parser = &C.yaml_parser_t{}
  20. C.yaml_parser_initialize(d.parser)
  21. // How unsafe is this really? Will this break if the GC becomes compacting?
  22. // Probably not, otherwise that would likely break &parse below as well.
  23. input := (*C.uchar)(unsafe.Pointer(&b[0]))
  24. C.yaml_parser_set_input_string(d.parser, input, (C.size_t)(len(b)))
  25. d.next()
  26. if d.event._type != C.YAML_STREAM_START_EVENT {
  27. panic("Expected stream start event, got " +
  28. strconv.Itoa(int(d.event._type)))
  29. }
  30. d.next()
  31. return &d
  32. }
  33. func (d *decoder) destroy() {
  34. if d.event._type != C.YAML_NO_EVENT {
  35. C.yaml_event_delete(d.event)
  36. }
  37. C.yaml_parser_delete(d.parser)
  38. }
  39. func (d *decoder) next() {
  40. if d.event._type != C.YAML_NO_EVENT {
  41. if d.event._type == C.YAML_STREAM_END_EVENT {
  42. panic("Attempted to go past the end of stream. Corrupted value?")
  43. }
  44. C.yaml_event_delete(d.event)
  45. }
  46. if C.yaml_parser_parse(d.parser, d.event) == 0 {
  47. panic("Parsing failed.") // XXX Need better error handling here.
  48. }
  49. }
  50. func (d *decoder) skip(_type C.yaml_event_type_t) {
  51. for d.event._type != _type {
  52. d.next()
  53. }
  54. d.next()
  55. }
  56. func (d *decoder) unmarshal(out reflect.Value) bool {
  57. switch d.event._type {
  58. case C.YAML_SCALAR_EVENT:
  59. return d.scalar(out)
  60. case C.YAML_MAPPING_START_EVENT:
  61. return d.mapping(out)
  62. case C.YAML_SEQUENCE_START_EVENT:
  63. return d.sequence(out)
  64. case C.YAML_DOCUMENT_START_EVENT:
  65. return d.document(out)
  66. default:
  67. panic("Attempted to unmarshal unexpected event: " +
  68. strconv.Itoa(int(d.event._type)))
  69. }
  70. return true
  71. }
  72. func (d *decoder) document(out reflect.Value) bool {
  73. d.next()
  74. result := d.unmarshal(out)
  75. if d.event._type != C.YAML_DOCUMENT_END_EVENT {
  76. panic("Expected end of document event but got " +
  77. strconv.Itoa(int(d.event._type)))
  78. }
  79. d.next()
  80. return result
  81. }
  82. func (d *decoder) scalar(out reflect.Value) (ok bool) {
  83. scalar := C.event_scalar(d.event)
  84. str := GoYString(scalar.value)
  85. resolved, _ := resolve(str)
  86. switch out := out.(type) {
  87. case *reflect.StringValue:
  88. out.Set(str)
  89. ok = true
  90. case *reflect.InterfaceValue:
  91. out.Set(reflect.NewValue(resolved))
  92. ok = true
  93. case *reflect.IntValue:
  94. switch resolved := resolved.(type) {
  95. case int:
  96. out.Set(int64(resolved))
  97. ok = true
  98. case int64:
  99. out.Set(resolved)
  100. // ok = true // XXX TEST ME
  101. }
  102. default:
  103. panic("Can't handle scalar type yet: " + out.Type().String())
  104. }
  105. d.next()
  106. return ok
  107. }
  108. func (d *decoder) sequence(out reflect.Value) bool {
  109. sv, ok := out.(*reflect.SliceValue)
  110. if !ok {
  111. d.skip(C.YAML_SEQUENCE_END_EVENT)
  112. return false
  113. }
  114. st := sv.Type().(*reflect.SliceType)
  115. et := st.Elem()
  116. d.next()
  117. for d.event._type != C.YAML_SEQUENCE_END_EVENT {
  118. e := reflect.MakeZero(et)
  119. if ok := d.unmarshal(e); ok {
  120. sv.SetValue(reflect.Append(sv, e))
  121. }
  122. }
  123. d.next()
  124. return true
  125. }
  126. func (d *decoder) mapping(out reflect.Value) bool {
  127. //if iface, ok := out.(*reflect.InterfaceValue); ok {
  128. // XXX What if it's an interface{}?
  129. mv, ok := out.(*reflect.MapValue)
  130. if !ok {
  131. d.skip(C.YAML_MAPPING_END_EVENT)
  132. return false
  133. }
  134. mt := mv.Type().(*reflect.MapType)
  135. kt := mt.Key()
  136. et := mt.Elem()
  137. d.next()
  138. for d.event._type != C.YAML_MAPPING_END_EVENT {
  139. k := reflect.MakeZero(kt)
  140. kok := d.unmarshal(k)
  141. e := reflect.MakeZero(et)
  142. eok := d.unmarshal(e)
  143. if kok && eok {
  144. mv.SetElem(k, e)
  145. }
  146. }
  147. d.next()
  148. return false
  149. }
  150. func GoYString(s *C.yaml_char_t) string {
  151. return C.GoString((*C.char)(unsafe.Pointer(s)))
  152. }