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 }