Advertisement
Guest User

Untitled

a guest
Apr 20th, 2019
107
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.30 KB | None | 0 0
  1. package rawxml
  2.  
  3. import (
  4. "bytes"
  5. "encoding/xml"
  6. "errors"
  7. "fmt"
  8. "sort"
  9. "strings"
  10. )
  11.  
  12. var errTODO = errors.New("TODO")
  13.  
  14. type errUnexpectedToken struct {
  15. Token xml.Token
  16. }
  17.  
  18. func (s errUnexpectedToken) Error() string {
  19. return fmt.Sprintf("unexpected token: %#v", s.Token)
  20. }
  21.  
  22. type errRedefinedPrefix struct {
  23. Prefix string
  24. }
  25.  
  26. func (s errRedefinedPrefix) Error() string {
  27. return fmt.Sprintf("redefined prefix: %v", s.Prefix)
  28. }
  29.  
  30. type xmlns struct {
  31. Parent *xmlns
  32. Spaces map[string]string
  33. }
  34.  
  35. func (s *xmlns) register(prefix, space string) (err error) {
  36. if defined, ok := s.Spaces[prefix]; ok {
  37. if defined != space {
  38. err = &errRedefinedPrefix{Prefix: prefix}
  39. }
  40. } else {
  41. s.Spaces[prefix] = space
  42. }
  43. return
  44. }
  45.  
  46. func (s *xmlns) encodeName(v Name) (r xml.Name, err error) {
  47. var prefix string
  48. if pl := strings.SplitN(v.Local, ":", 2); len(pl) == 2 {
  49. prefix, r.Local = pl[0], pl[1]
  50. }
  51. r.Local = v.Local
  52.  
  53. var known bool
  54. for ns := s; ns != nil && !known; ns = ns.Parent {
  55. known = (ns.Spaces[prefix] == v.Space)
  56. }
  57. if !known {
  58. err = s.register(prefix, v.Space)
  59. }
  60. return
  61. }
  62.  
  63. func (s *xmlns) decodeName(v xml.Name) (r Name, err error) {
  64. for ns := s; ns != nil && err == nil && r.Space == ""; ns = ns.Parent {
  65. if v, ok := ns.Spaces[v.Space]; ok {
  66. r.Space = v
  67. }
  68. }
  69.  
  70. if v.Space != "" {
  71. r.Local = strings.Join([]string{v.Space, v.Local}, ":")
  72. } else {
  73. r.Local = v.Local
  74. }
  75. return
  76. }
  77.  
  78. func (s *xmlns) encodeAttrs(v Attrs) (r []xml.Attr, err error) {
  79. for i := 0; i < len(v) && err == nil; i++ {
  80. attr := xml.Attr{
  81. Value: v[i].Value,
  82. }
  83. if attr.Name, err = s.encodeName(v[i].Name); err == nil {
  84. r = append(r, attr)
  85. }
  86. }
  87.  
  88. var prefixes []string
  89. for prefix := range s.Spaces {
  90. prefixes = append(prefixes, prefix)
  91. }
  92. sort.Strings(prefixes)
  93.  
  94. for _, prefix := range prefixes {
  95. local := "xmlns"
  96. if prefix != "" {
  97. local = strings.Join([]string{local, prefix}, ":")
  98. }
  99.  
  100. attr := xml.Attr{
  101. Name: xml.Name{Local: local},
  102. Value: s.Spaces[prefix],
  103. }
  104. r = append(r, attr)
  105. }
  106. return
  107. }
  108.  
  109. func (s *xmlns) decodeAttrs(v []xml.Attr) (r Attrs, err error) {
  110. var left []int
  111. for i := 0; i < len(v) && err == nil; i++ {
  112. space, local, value := v[i].Name.Space, v[i].Name.Local, v[i].Value
  113. if space == "" && local == "xmlns" {
  114. err = s.register(space, value)
  115. } else if space == "xmlns" {
  116. err = s.register(local, value)
  117. } else {
  118. left = append(left, i)
  119. }
  120. }
  121.  
  122. for j := 0; j < len(left) && err == nil; j++ {
  123. i := left[j]
  124.  
  125. attr := Attr{
  126. Value: v[i].Value,
  127. }
  128. if attr.Name, err = s.decodeName(v[i].Name); err == nil {
  129. r = append(r, attr)
  130. }
  131. }
  132. return
  133. }
  134.  
  135. // Name -
  136. type Name struct {
  137. Space string
  138. Local string
  139. }
  140.  
  141. // Attr -
  142. type Attr struct {
  143. Name Name
  144. Value string
  145. }
  146.  
  147. // Attrs -
  148. type Attrs []Attr
  149.  
  150. // Content -
  151. type Content [][]byte
  152.  
  153. func (s Content) isWhiteSpaces() bool {
  154. ok := true
  155. for i := 0; i < len(s) && ok; i++ {
  156. ok = isWhiteSpaces(s[i])
  157. }
  158. return ok
  159. }
  160.  
  161. // Element -
  162. type Element struct {
  163. Name Name
  164. Attrs Attrs
  165. Elements Elements
  166. Content Content
  167. }
  168.  
  169. func (s Element) encode(encoder Encoder, parent *xmlns) (err error) {
  170. xmlns := &xmlns{
  171. Parent: parent,
  172. Spaces: map[string]string{},
  173. }
  174.  
  175. var start xml.StartElement
  176. if start.Name, err = xmlns.encodeName(s.Name); err != nil {
  177. return
  178. }
  179. if start.Attr, err = xmlns.encodeAttrs(s.Attrs); err != nil {
  180. return
  181. }
  182. if err = encoder.EncodeToken(start); err != nil {
  183. return
  184. }
  185.  
  186. emptyContent := s.Content.isWhiteSpaces()
  187. emptyElements := s.Elements.isEmpty()
  188.  
  189. if !emptyElements {
  190. if !emptyContent {
  191. err = errTODO
  192. }
  193. for i := 0; i < len(s.Elements) && err == nil; i++ {
  194. err = s.Elements[i].encode(encoder, xmlns)
  195. }
  196. } else {
  197. if !emptyContent {
  198. v := bytes.Join([][]byte(s.Content), nil)
  199. err = encoder.EncodeToken(xml.CharData(v))
  200. }
  201. }
  202.  
  203. err = encoder.EncodeToken(start.End())
  204. return
  205. }
  206.  
  207. func (s *Element) decode(decoder Decoder, start *xml.StartElement, parent *xmlns) (err error) {
  208. xmlns := &xmlns{
  209. Parent: parent,
  210. Spaces: map[string]string{},
  211. }
  212.  
  213. if s.Attrs, err = xmlns.decodeAttrs(start.Attr); err != nil {
  214. return
  215. }
  216. if s.Name, err = xmlns.decodeName(start.Name); err != nil {
  217. return
  218. }
  219.  
  220. var end *xml.EndElement
  221. for end == nil && err == nil {
  222. var token xml.Token
  223. if token, err = decoder.RawToken(); err == nil {
  224. switch token.(type) {
  225. case xml.StartElement:
  226. c := xml.CopyToken(token)
  227. v := c.(xml.StartElement)
  228.  
  229. var child Element
  230. if err = child.decode(decoder, &v, xmlns); err == nil {
  231. s.Elements = append(s.Elements, child)
  232. }
  233.  
  234. case xml.EndElement:
  235. c := xml.CopyToken(token)
  236. v := c.(xml.EndElement)
  237. end = &v
  238.  
  239. if end.Name != start.Name {
  240. err = errTODO
  241. }
  242.  
  243. case xml.CharData:
  244. c := xml.CopyToken(token)
  245. v := c.(xml.CharData)
  246. s.Content = append(s.Content, v)
  247. }
  248. }
  249. }
  250.  
  251. if err == nil && !s.Elements.isEmpty() {
  252. if s.Content.isWhiteSpaces() {
  253. s.Content = nil
  254. } else {
  255. err = errTODO
  256. }
  257. }
  258. return
  259. }
  260.  
  261. // Elements -
  262. type Elements []Element
  263.  
  264. func (s Elements) isEmpty() bool {
  265. return len(s) == 0
  266. }
  267.  
  268. var isWhiteSpace = map[byte]bool{
  269. 0x20: true,
  270. 0x09: true,
  271. 0x0d: true,
  272. 0x0a: true,
  273. }
  274.  
  275. func isWhiteSpaces(v []byte) bool {
  276. ok := true
  277. for i := 0; i < len(v) && ok; i++ {
  278. ok = isWhiteSpace[v[i]]
  279. }
  280. return ok
  281. }
  282.  
  283. // Decoder -
  284. type Decoder interface {
  285. RawToken() (xml.Token, error)
  286. InputOffset() int64
  287. }
  288.  
  289. // Decode -
  290. func Decode(decoder Decoder) (element *Element, err error) {
  291. begin := true
  292. for element == nil && err == nil {
  293. var token xml.Token
  294. if token, err = decoder.RawToken(); err == nil {
  295. var unexpected bool
  296.  
  297. switch token.(type) {
  298. case xml.StartElement:
  299. c := xml.CopyToken(token)
  300. v := c.(xml.StartElement)
  301.  
  302. var swap Element
  303. if err = swap.decode(decoder, &v, nil); err == nil {
  304. element = &swap
  305. }
  306.  
  307. case xml.EndElement:
  308. unexpected = true
  309.  
  310. case xml.CharData:
  311. unexpected = begin || !isWhiteSpaces(token.(xml.CharData))
  312.  
  313. case xml.ProcInst:
  314. unexpected = !(begin && token.(xml.ProcInst).Target == "xml")
  315.  
  316. default:
  317. unexpected = begin
  318. }
  319. begin = false
  320.  
  321. if unexpected {
  322. err = &errUnexpectedToken{
  323. Token: xml.CopyToken(token),
  324. }
  325. }
  326. }
  327. }
  328. return
  329. }
  330.  
  331. // Encoder -
  332. type Encoder interface {
  333. EncodeToken(xml.Token) error
  334. Flush() error
  335. }
  336.  
  337. // Encode -
  338. func Encode(encoder Encoder, element *Element) (err error) {
  339. if err = element.encode(encoder, nil); err == nil {
  340. err = encoder.Flush()
  341. }
  342. return
  343. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement