| 108 | } |
| 109 | |
| 110 | func decodeChunk(r binary.Reader, x *xmlTree) (chunk, error) { |
| 111 | ty := r.Uint16() |
| 112 | if err := r.Error(); err != nil { |
| 113 | return nil, err |
| 114 | } |
| 115 | headerSize := r.Uint16() |
| 116 | if headerSize < 8 { |
| 117 | return nil, fmt.Errorf("Unexpected header size %d", headerSize) |
| 118 | } |
| 119 | dataSize := r.Uint32() |
| 120 | header := make([]byte, headerSize-8) |
| 121 | data := make([]byte, dataSize-uint32(headerSize)) |
| 122 | r.Data(header) |
| 123 | r.Data(data) |
| 124 | var c chunk |
| 125 | switch ty { |
| 126 | case resXMLResourceMapType: |
| 127 | c = &xmlResourceMap{} |
| 128 | case resStringPoolType: |
| 129 | c = &stringPool{} |
| 130 | case resXMLCDataType: |
| 131 | c = &xmlCData{} |
| 132 | case resXMLEndElementType: |
| 133 | c = &xmlEndElement{} |
| 134 | case resXMLEndNamespaceType: |
| 135 | c = &xmlEndNamespace{} |
| 136 | case resXMLStartElementType: |
| 137 | c = &xmlStartElement{} |
| 138 | case resXMLStartNamespaceType: |
| 139 | c = &xmlStartNamespace{} |
| 140 | case resXMLType: |
| 141 | c = x |
| 142 | default: |
| 143 | return nil, fmt.Errorf("Unknown chunk type 0x%x", ty) |
| 144 | } |
| 145 | c.setRoot(x) |
| 146 | err := c.decode(header, data) |
| 147 | if errors.Cause(err) == io.EOF { |
| 148 | return nil, fmt.Errorf("Chunk type %T read past end of data", c) |
| 149 | } |
| 150 | return c, err |
| 151 | } |
| 152 | |
| 153 | func decodeLength(r binary.Reader) uint32 { |
| 154 | length := uint32(r.Uint16()) |