github.com/graybobo/golang.org-package-offline-cache@v0.0.0-20200626051047-6608995c132f/x/mobile/internal/binres/node.go (about)

     1  // Copyright 2015 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  
     5  package binres
     6  
     7  // NodeHeader is header all xml node types have, providing additional
     8  // information regarding an xml node over binChunkHeader.
     9  type NodeHeader struct {
    10  	chunkHeader
    11  	LineNumber uint32  // line number in source file this element appears
    12  	Comment    PoolRef // optional xml comment associated with element, MaxUint32 if none
    13  }
    14  
    15  func (hdr *NodeHeader) UnmarshalBinary(bin []byte) error {
    16  	if err := (&hdr.chunkHeader).UnmarshalBinary(bin); err != nil {
    17  		return err
    18  	}
    19  	hdr.LineNumber = btou32(bin[8:])
    20  	hdr.Comment = PoolRef(btou32(bin[12:]))
    21  	return nil
    22  }
    23  
    24  func (hdr *NodeHeader) MarshalBinary() ([]byte, error) {
    25  	bin := make([]byte, 16)
    26  	b, err := hdr.chunkHeader.MarshalBinary()
    27  	if err != nil {
    28  		return nil, err
    29  	}
    30  	copy(bin, b)
    31  	putu32(bin[8:], hdr.LineNumber)
    32  	putu32(bin[12:], uint32(hdr.Comment))
    33  	return bin, nil
    34  }
    35  
    36  type Namespace struct {
    37  	NodeHeader
    38  	prefix PoolRef
    39  	uri    PoolRef
    40  
    41  	end *Namespace // TODO don't let this type be recursive
    42  }
    43  
    44  func (ns *Namespace) UnmarshalBinary(bin []byte) error {
    45  	if err := (&ns.NodeHeader).UnmarshalBinary(bin); err != nil {
    46  		return err
    47  	}
    48  	buf := bin[ns.headerByteSize:]
    49  	ns.prefix = PoolRef(btou32(buf))
    50  	ns.uri = PoolRef(btou32(buf[4:]))
    51  	return nil
    52  }
    53  
    54  func (ns *Namespace) MarshalBinary() ([]byte, error) {
    55  	bin := make([]byte, 24)
    56  	b, err := ns.NodeHeader.MarshalBinary()
    57  	if err != nil {
    58  		return nil, err
    59  	}
    60  	copy(bin, b)
    61  	putu32(bin[16:], uint32(ns.prefix))
    62  	putu32(bin[20:], uint32(ns.uri))
    63  	return bin, nil
    64  }
    65  
    66  type Element struct {
    67  	NodeHeader
    68  	NS             PoolRef
    69  	Name           PoolRef // name of node if element, otherwise chardata if CDATA
    70  	AttributeStart uint16  // byte offset where attrs start
    71  	AttributeSize  uint16  // byte size of attrs
    72  	AttributeCount uint16  // length of attrs
    73  	IdIndex        uint16  // Index (1-based) of the "id" attribute. 0 if none.
    74  	ClassIndex     uint16  // Index (1-based) of the "class" attribute. 0 if none.
    75  	StyleIndex     uint16  // Index (1-based) of the "style" attribute. 0 if none.
    76  
    77  	attrs    []*Attribute
    78  	Children []*Element
    79  	end      *ElementEnd
    80  
    81  	head, tail *CharData
    82  }
    83  
    84  func (el *Element) UnmarshalBinary(bin []byte) error {
    85  	if err := (&el.NodeHeader).UnmarshalBinary(bin); err != nil {
    86  		return err
    87  	}
    88  	buf := bin[el.headerByteSize:] // 16
    89  	el.NS = PoolRef(btou32(buf))
    90  	el.Name = PoolRef(btou32(buf[4:]))
    91  	el.AttributeStart = btou16(buf[8:])
    92  	el.AttributeSize = btou16(buf[10:])
    93  	el.AttributeCount = btou16(buf[12:])
    94  	el.IdIndex = btou16(buf[14:])
    95  	el.ClassIndex = btou16(buf[16:])
    96  	el.StyleIndex = btou16(buf[18:])
    97  
    98  	buf = buf[el.AttributeStart:]
    99  	el.attrs = make([]*Attribute, int(el.AttributeCount))
   100  	for i := range el.attrs {
   101  		attr := new(Attribute)
   102  		if err := attr.UnmarshalBinary(buf); err != nil {
   103  			return err
   104  		}
   105  		el.attrs[i] = attr
   106  		buf = buf[el.AttributeSize:]
   107  	}
   108  
   109  	return nil
   110  }
   111  
   112  func (el *Element) MarshalBinary() ([]byte, error) {
   113  	bin := make([]byte, 16+20+len(el.attrs)*int(el.AttributeSize))
   114  	b, err := el.NodeHeader.MarshalBinary()
   115  	if err != nil {
   116  		return nil, err
   117  	}
   118  	copy(bin, b)
   119  	putu32(bin[16:], uint32(el.NS))
   120  	putu32(bin[20:], uint32(el.Name))
   121  	putu16(bin[24:], el.AttributeStart)
   122  	putu16(bin[26:], el.AttributeSize)
   123  	putu16(bin[28:], el.AttributeCount)
   124  	putu16(bin[30:], el.IdIndex)
   125  	putu16(bin[32:], el.ClassIndex)
   126  	putu16(bin[34:], el.StyleIndex)
   127  
   128  	buf := bin[36:]
   129  	for _, attr := range el.attrs {
   130  		b, err := attr.MarshalBinary()
   131  		if err != nil {
   132  			return nil, err
   133  		}
   134  		copy(buf, b)
   135  		buf = buf[int(el.AttributeSize):]
   136  	}
   137  
   138  	return bin, nil
   139  }
   140  
   141  // ElementEnd marks the end of an element node, either Element or CharData.
   142  type ElementEnd struct {
   143  	NodeHeader
   144  	NS   PoolRef
   145  	Name PoolRef // name of node if binElement, raw chardata if binCharData
   146  }
   147  
   148  func (el *ElementEnd) UnmarshalBinary(bin []byte) error {
   149  	(&el.NodeHeader).UnmarshalBinary(bin)
   150  	buf := bin[el.headerByteSize:]
   151  	el.NS = PoolRef(btou32(buf))
   152  	el.Name = PoolRef(btou32(buf[4:]))
   153  	return nil
   154  }
   155  
   156  func (el *ElementEnd) MarshalBinary() ([]byte, error) {
   157  	bin := make([]byte, 24)
   158  	b, err := el.NodeHeader.MarshalBinary()
   159  	if err != nil {
   160  		return nil, err
   161  	}
   162  	copy(bin, b)
   163  	putu32(bin[16:], uint32(el.NS))
   164  	putu32(bin[20:], uint32(el.Name))
   165  	return bin, nil
   166  }
   167  
   168  type Attribute struct {
   169  	NS         PoolRef
   170  	Name       PoolRef
   171  	RawValue   PoolRef // The original raw string value of this attribute.
   172  	TypedValue Data    // Processesd typed value of this attribute.
   173  }
   174  
   175  func (attr *Attribute) UnmarshalBinary(bin []byte) error {
   176  	attr.NS = PoolRef(btou32(bin))
   177  	attr.Name = PoolRef(btou32(bin[4:]))
   178  	attr.RawValue = PoolRef(btou32(bin[8:]))
   179  	return (&attr.TypedValue).UnmarshalBinary(bin[12:])
   180  }
   181  
   182  func (attr *Attribute) MarshalBinary() ([]byte, error) {
   183  	bin := make([]byte, 20)
   184  	putu32(bin, uint32(attr.NS))
   185  	putu32(bin[4:], uint32(attr.Name))
   186  	putu32(bin[8:], uint32(attr.RawValue))
   187  	b, err := attr.TypedValue.MarshalBinary()
   188  	if err != nil {
   189  		return nil, err
   190  	}
   191  	copy(bin[12:], b)
   192  	return bin, nil
   193  }
   194  
   195  // CharData represents a CDATA node and includes ref to node's text value.
   196  type CharData struct {
   197  	NodeHeader
   198  	RawData   PoolRef // raw character data
   199  	TypedData Data    // typed value of character data
   200  }
   201  
   202  func (cdt *CharData) UnmarshalBinary(bin []byte) error {
   203  	if err := (&cdt.NodeHeader).UnmarshalBinary(bin); err != nil {
   204  		return err
   205  	}
   206  	buf := bin[cdt.headerByteSize:]
   207  	cdt.RawData = PoolRef(btou32(buf))
   208  	return (&cdt.TypedData).UnmarshalBinary(buf[4:])
   209  }
   210  
   211  func (cdt *CharData) MarshalBinary() ([]byte, error) {
   212  	bin := make([]byte, 28)
   213  	b, err := cdt.NodeHeader.MarshalBinary()
   214  	if err != nil {
   215  		return nil, err
   216  	}
   217  	copy(bin, b)
   218  	putu32(bin[16:], uint32(cdt.RawData))
   219  	b, err = cdt.TypedData.MarshalBinary()
   220  	if err != nil {
   221  		return nil, err
   222  	}
   223  	copy(bin[20:], b)
   224  	return bin, nil
   225  }