| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252 |
- // Copyright 2015 The Go Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style
- // license that can be found in the LICENSE file.
- package binres
- // NodeHeader is header all xml node types have, providing additional
- // information regarding an xml node over binChunkHeader.
- type NodeHeader struct {
- chunkHeader
- LineNumber uint32 // line number in source file this element appears
- Comment PoolRef // optional xml comment associated with element, MaxUint32 if none
- }
- func (hdr *NodeHeader) UnmarshalBinary(bin []byte) error {
- if err := (&hdr.chunkHeader).UnmarshalBinary(bin); err != nil {
- return err
- }
- hdr.LineNumber = btou32(bin[8:])
- hdr.Comment = PoolRef(btou32(bin[12:]))
- return nil
- }
- func (hdr *NodeHeader) MarshalBinary() ([]byte, error) {
- bin := make([]byte, 16)
- b, err := hdr.chunkHeader.MarshalBinary()
- if err != nil {
- return nil, err
- }
- copy(bin, b)
- putu32(bin[8:], hdr.LineNumber)
- putu32(bin[12:], uint32(hdr.Comment))
- return bin, nil
- }
- type Namespace struct {
- NodeHeader
- prefix PoolRef
- uri PoolRef
- end *Namespace // TODO don't let this type be recursive
- }
- func (ns *Namespace) UnmarshalBinary(bin []byte) error {
- if err := (&ns.NodeHeader).UnmarshalBinary(bin); err != nil {
- return err
- }
- buf := bin[ns.headerByteSize:]
- ns.prefix = PoolRef(btou32(buf))
- ns.uri = PoolRef(btou32(buf[4:]))
- return nil
- }
- func (ns *Namespace) MarshalBinary() ([]byte, error) {
- if ns.end == nil {
- ns.typ = ResXMLEndNamespace
- } else {
- ns.typ = ResXMLStartNamespace
- }
- ns.headerByteSize = 16
- ns.byteSize = 24
- bin := make([]byte, ns.byteSize)
- b, err := ns.NodeHeader.MarshalBinary()
- if err != nil {
- return nil, err
- }
- copy(bin, b)
- putu32(bin[16:], uint32(ns.prefix))
- putu32(bin[20:], uint32(ns.uri))
- return bin, nil
- }
- type Element struct {
- NodeHeader
- NS PoolRef
- Name PoolRef // name of node if element, otherwise chardata if CDATA
- AttributeStart uint16 // byte offset where attrs start
- AttributeSize uint16 // byte size of attrs
- AttributeCount uint16 // length of attrs
- IdIndex uint16 // Index (1-based) of the "id" attribute. 0 if none.
- ClassIndex uint16 // Index (1-based) of the "class" attribute. 0 if none.
- StyleIndex uint16 // Index (1-based) of the "style" attribute. 0 if none.
- attrs []*Attribute
- Children []*Element
- end *ElementEnd
- head, tail *CharData
- }
- func (el *Element) UnmarshalBinary(buf []byte) error {
- if err := (&el.NodeHeader).UnmarshalBinary(buf); err != nil {
- return err
- }
- buf = buf[el.headerByteSize:]
- el.NS = PoolRef(btou32(buf))
- el.Name = PoolRef(btou32(buf[4:]))
- el.AttributeStart = btou16(buf[8:])
- el.AttributeSize = btou16(buf[10:])
- el.AttributeCount = btou16(buf[12:])
- el.IdIndex = btou16(buf[14:])
- el.ClassIndex = btou16(buf[16:])
- el.StyleIndex = btou16(buf[18:])
- buf = buf[el.AttributeStart:]
- el.attrs = make([]*Attribute, int(el.AttributeCount))
- for i := range el.attrs {
- attr := new(Attribute)
- if err := attr.UnmarshalBinary(buf); err != nil {
- return err
- }
- el.attrs[i] = attr
- buf = buf[el.AttributeSize:]
- }
- return nil
- }
- func (el *Element) MarshalBinary() ([]byte, error) {
- el.typ = ResXMLStartElement
- el.headerByteSize = 16
- el.AttributeSize = 20
- el.AttributeStart = 20
- el.AttributeCount = uint16(len(el.attrs))
- el.IdIndex = 0
- el.ClassIndex = 0
- el.StyleIndex = 0
- el.byteSize = uint32(el.headerByteSize) + uint32(el.AttributeStart) + uint32(len(el.attrs)*int(el.AttributeSize))
- bin := make([]byte, el.byteSize)
- b, err := el.NodeHeader.MarshalBinary()
- if err != nil {
- return nil, err
- }
- copy(bin, b)
- putu32(bin[16:], uint32(el.NS))
- putu32(bin[20:], uint32(el.Name))
- putu16(bin[24:], el.AttributeStart)
- putu16(bin[26:], el.AttributeSize)
- putu16(bin[28:], el.AttributeCount)
- putu16(bin[30:], el.IdIndex)
- putu16(bin[32:], el.ClassIndex)
- putu16(bin[34:], el.StyleIndex)
- buf := bin[36:]
- for _, attr := range el.attrs {
- b, err := attr.MarshalBinary()
- if err != nil {
- return nil, err
- }
- copy(buf, b)
- buf = buf[int(el.AttributeSize):]
- }
- return bin, nil
- }
- // ElementEnd marks the end of an element node, either Element or CharData.
- type ElementEnd struct {
- NodeHeader
- NS PoolRef
- Name PoolRef // name of node if binElement, raw chardata if binCharData
- }
- func (el *ElementEnd) UnmarshalBinary(bin []byte) error {
- (&el.NodeHeader).UnmarshalBinary(bin)
- buf := bin[el.headerByteSize:]
- el.NS = PoolRef(btou32(buf))
- el.Name = PoolRef(btou32(buf[4:]))
- return nil
- }
- func (el *ElementEnd) MarshalBinary() ([]byte, error) {
- el.typ = ResXMLEndElement
- el.headerByteSize = 16
- el.byteSize = 24
- bin := make([]byte, 24)
- b, err := el.NodeHeader.MarshalBinary()
- if err != nil {
- return nil, err
- }
- copy(bin, b)
- putu32(bin[16:], uint32(el.NS))
- putu32(bin[20:], uint32(el.Name))
- return bin, nil
- }
- type Attribute struct {
- NS PoolRef
- Name PoolRef
- RawValue PoolRef // The original raw string value of this attribute.
- TypedValue Data // Processesd typed value of this attribute.
- }
- func (attr *Attribute) UnmarshalBinary(bin []byte) error {
- attr.NS = PoolRef(btou32(bin))
- attr.Name = PoolRef(btou32(bin[4:]))
- attr.RawValue = PoolRef(btou32(bin[8:]))
- return (&attr.TypedValue).UnmarshalBinary(bin[12:])
- }
- func (attr *Attribute) MarshalBinary() ([]byte, error) {
- bin := make([]byte, 20)
- putu32(bin, uint32(attr.NS))
- putu32(bin[4:], uint32(attr.Name))
- putu32(bin[8:], uint32(attr.RawValue))
- b, err := attr.TypedValue.MarshalBinary()
- if err != nil {
- return nil, err
- }
- copy(bin[12:], b)
- return bin, nil
- }
- // CharData represents a CDATA node and includes ref to node's text value.
- type CharData struct {
- NodeHeader
- RawData PoolRef // raw character data
- TypedData Data // typed value of character data
- }
- func (cdt *CharData) UnmarshalBinary(bin []byte) error {
- if err := (&cdt.NodeHeader).UnmarshalBinary(bin); err != nil {
- return err
- }
- buf := bin[cdt.headerByteSize:]
- cdt.RawData = PoolRef(btou32(buf))
- return (&cdt.TypedData).UnmarshalBinary(buf[4:])
- }
- func (cdt *CharData) MarshalBinary() ([]byte, error) {
- cdt.typ = ResXMLCharData
- cdt.headerByteSize = 16
- cdt.byteSize = 28
- bin := make([]byte, cdt.byteSize)
- b, err := cdt.NodeHeader.MarshalBinary()
- if err != nil {
- return nil, err
- }
- copy(bin, b)
- putu32(bin[16:], uint32(cdt.RawData))
- b, err = cdt.TypedData.MarshalBinary()
- if err != nil {
- return nil, err
- }
- copy(bin[20:], b)
- return bin, nil
- }
|