| OLD | NEW |
| (Empty) |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 package bindings | |
| 6 | |
| 7 import ( | |
| 8 "encoding/binary" | |
| 9 "fmt" | |
| 10 "math" | |
| 11 | |
| 12 "mojo/public/go/system" | |
| 13 ) | |
| 14 | |
| 15 // Decoder is a helper to decode mojo complex elements from mojo archive format. | |
| 16 type Decoder struct { | |
| 17 // Buffer containing data to decode. | |
| 18 buf []byte | |
| 19 | |
| 20 // Index of the first unclaimed byte in buf. | |
| 21 end int | |
| 22 | |
| 23 // Array containing handles to decode. | |
| 24 handles []system.UntypedHandle | |
| 25 | |
| 26 // The first unclaimed handle index. | |
| 27 nextHandle int | |
| 28 | |
| 29 // A stack of encoding states matching current one-level value stack | |
| 30 // of the decoding data structure. | |
| 31 stateStack []encodingState | |
| 32 } | |
| 33 | |
| 34 // NewDecoder returns a decoder that will decode structured data from provided | |
| 35 // byte array and with handles. | |
| 36 func NewDecoder(bytes []byte, handles []system.UntypedHandle) *Decoder { | |
| 37 return &Decoder{buf: bytes, handles: handles} | |
| 38 } | |
| 39 | |
| 40 // claimData claims a block of |size| bytes for a one-level value. | |
| 41 func (d *Decoder) claimData(size int) error { | |
| 42 if d.end+size > len(d.buf) { | |
| 43 return &ValidationError{IllegalMemoryRange, "data buffer is too
small"} | |
| 44 } | |
| 45 d.end += size | |
| 46 return nil | |
| 47 } | |
| 48 | |
| 49 func (d *Decoder) claimHandle(index int) (system.UntypedHandle, error) { | |
| 50 if index >= len(d.handles) { | |
| 51 return nil, &ValidationError{IllegalHandle, "trying to access no
n present handle"} | |
| 52 } | |
| 53 if index < d.nextHandle { | |
| 54 return nil, &ValidationError{IllegalHandle, "trying to access ha
ndle out of order"} | |
| 55 } | |
| 56 d.nextHandle = index + 1 | |
| 57 return d.handles[index], nil | |
| 58 } | |
| 59 | |
| 60 func (d *Decoder) popState() { | |
| 61 if len(d.stateStack) != 0 { | |
| 62 d.stateStack = d.stateStack[:len(d.stateStack)-1] | |
| 63 } | |
| 64 } | |
| 65 | |
| 66 func (d *Decoder) pushState(header DataHeader, checkElements bool) error { | |
| 67 oldEnd := d.end | |
| 68 if err := d.claimData(int(header.Size - dataHeaderSize)); err != nil { | |
| 69 return err | |
| 70 } | |
| 71 elements := uint32(0) | |
| 72 if checkElements { | |
| 73 elements = header.ElementsOrVersion | |
| 74 } | |
| 75 d.stateStack = append(d.stateStack, encodingState{ | |
| 76 offset: oldEnd, | |
| 77 limit: d.end, | |
| 78 elements: elements, | |
| 79 checkElements: checkElements, | |
| 80 }) | |
| 81 return nil | |
| 82 } | |
| 83 | |
| 84 // state returns state of the top-level value. | |
| 85 func (d *Decoder) state() *encodingState { | |
| 86 if len(d.stateStack) == 0 { | |
| 87 return nil | |
| 88 } | |
| 89 return &d.stateStack[len(d.stateStack)-1] | |
| 90 } | |
| 91 | |
| 92 // StartArray starts decoding an array and reads its data header, | |
| 93 // returning number of elements declared in data header. | |
| 94 // Note: it doesn't read a pointer to the encoded array. | |
| 95 // Call |Finish()| after reading all array elements. | |
| 96 func (d *Decoder) StartArray(elementBitSize uint32) (uint32, error) { | |
| 97 header, err := d.readDataHeader() | |
| 98 if err != nil { | |
| 99 return 0, err | |
| 100 } | |
| 101 minSize := bytesForBits(uint64(header.ElementsOrVersion) * uint64(elemen
tBitSize)) | |
| 102 if got, want := int(header.Size), dataHeaderSize+minSize; got < want { | |
| 103 return 0, &ValidationError{UnexpectedArrayHeader, | |
| 104 fmt.Sprintf("data header size(%d) should be at least %d"
, got, want), | |
| 105 } | |
| 106 } | |
| 107 if err := d.pushState(header, true); err != nil { | |
| 108 return 0, err | |
| 109 } | |
| 110 return header.ElementsOrVersion, nil | |
| 111 } | |
| 112 | |
| 113 // StartMap starts decoding a map and reads its data header. | |
| 114 // Note: it doesn't read a pointer to the encoded map. | |
| 115 // Call |Finish()| after reading keys array and values array. | |
| 116 func (d *Decoder) StartMap() error { | |
| 117 header, err := d.readDataHeader() | |
| 118 if err != nil { | |
| 119 return err | |
| 120 } | |
| 121 if header != mapHeader { | |
| 122 return &ValidationError{UnexpectedStructHeader, | |
| 123 fmt.Sprintf("invalid map header: %v", header), | |
| 124 } | |
| 125 } | |
| 126 if err := d.pushState(header, false); err != nil { | |
| 127 return err | |
| 128 } | |
| 129 return nil | |
| 130 } | |
| 131 | |
| 132 // StartStruct starts decoding a struct and reads its data header. | |
| 133 // Returns the read data header. The caller should check if it is valid. | |
| 134 // Note: it doesn't read a pointer to the encoded struct. | |
| 135 // Call |Finish()| after reading all fields. | |
| 136 func (d *Decoder) StartStruct() (DataHeader, error) { | |
| 137 header, err := d.readDataHeader() | |
| 138 if err != nil { | |
| 139 return DataHeader{}, err | |
| 140 } | |
| 141 if header.Size < dataHeaderSize { | |
| 142 return DataHeader{}, &ValidationError{UnexpectedStructHeader, | |
| 143 fmt.Sprintf("data header size(%d) should be at least %d"
, header.Size, dataHeaderSize), | |
| 144 } | |
| 145 } | |
| 146 if err := d.pushState(header, false); err != nil { | |
| 147 return DataHeader{}, err | |
| 148 } | |
| 149 return header, nil | |
| 150 } | |
| 151 | |
| 152 // StartNestedUnion starts decoding a union. | |
| 153 // Note: it doesn't read a pointer to the encoded struct or the union header. | |
| 154 // Call |Finish()| after reading the header and data. | |
| 155 func (d *Decoder) StartNestedUnion() error { | |
| 156 // We have to trick pushState into claiming 16 bytes. | |
| 157 header := DataHeader{uint32(24), uint32(0)} | |
| 158 if err := d.pushState(header, false); err != nil { | |
| 159 return err | |
| 160 } | |
| 161 return nil | |
| 162 } | |
| 163 | |
| 164 // ReadUnionHeader reads the union header and returns the union's size and tag. | |
| 165 func (d *Decoder) ReadUnionHeader() (uint32, uint32, error) { | |
| 166 if err := ensureElementBitSizeAndCapacity(d.state(), 64); err != nil { | |
| 167 return 0, 0, err | |
| 168 } | |
| 169 d.state().alignOffsetToBytes() | |
| 170 d.state().offset = align(d.state().offset, 8) | |
| 171 size := binary.LittleEndian.Uint32(d.buf[d.state().offset:]) | |
| 172 tag := binary.LittleEndian.Uint32(d.buf[d.state().offset+4:]) | |
| 173 d.state().offset += 8 | |
| 174 if err := ensureElementBitSizeAndCapacity(d.state(), 64); err != nil { | |
| 175 return 0, 0, err | |
| 176 } | |
| 177 return size, tag, nil | |
| 178 } | |
| 179 | |
| 180 // FinishReadingUnionValue should be called after the union value has been read | |
| 181 // in order to indicate to move the decoder past the union value field. | |
| 182 func (d *Decoder) FinishReadingUnionValue() { | |
| 183 d.state().offset = align(d.state().offset, 8) | |
| 184 d.state().alignOffsetToBytes() | |
| 185 } | |
| 186 | |
| 187 // SkipUnionValue skips the union's value. | |
| 188 func (d *Decoder) SkipUnionValue() { | |
| 189 d.state().offset += 8 | |
| 190 d.state().elementsProcessed += 1 | |
| 191 } | |
| 192 | |
| 193 func (d *Decoder) readDataHeader() (DataHeader, error) { | |
| 194 if err := d.claimData(dataHeaderSize); err != nil { | |
| 195 return DataHeader{}, err | |
| 196 } | |
| 197 oldEnd := d.end - dataHeaderSize | |
| 198 header := DataHeader{ | |
| 199 Size: binary.LittleEndian.Uint32(d.buf[oldEnd:]), | |
| 200 ElementsOrVersion: binary.LittleEndian.Uint32(d.buf[oldEnd+4:]), | |
| 201 } | |
| 202 return header, nil | |
| 203 } | |
| 204 | |
| 205 // Finish indicates the decoder that you have finished reading elements of | |
| 206 // a one-level value. | |
| 207 func (d *Decoder) Finish() error { | |
| 208 if d.state() == nil { | |
| 209 return fmt.Errorf("state stack is empty") | |
| 210 } | |
| 211 if d.state().checkElements && d.state().elementsProcessed != d.state().e
lements { | |
| 212 return fmt.Errorf("unexpected number of elements read: defined i
n header %d, but read %d", d.state().elements, d.state().elementsProcessed) | |
| 213 } | |
| 214 d.popState() | |
| 215 return nil | |
| 216 } | |
| 217 | |
| 218 // ReadBool reads a bool value. | |
| 219 func (d *Decoder) ReadBool() (bool, error) { | |
| 220 if err := ensureElementBitSizeAndCapacity(d.state(), 1); err != nil { | |
| 221 return false, err | |
| 222 } | |
| 223 value := ((d.buf[d.state().offset] >> d.state().bitOffset) & 1) == 1 | |
| 224 d.state().skipBits(1) | |
| 225 d.state().elementsProcessed++ | |
| 226 return value, nil | |
| 227 } | |
| 228 | |
| 229 // ReadInt8 reads an int8 value. | |
| 230 func (d *Decoder) ReadInt8() (int8, error) { | |
| 231 value, err := d.ReadUint8() | |
| 232 return int8(value), err | |
| 233 } | |
| 234 | |
| 235 // ReadUint8 reads an uint8 value. | |
| 236 func (d *Decoder) ReadUint8() (uint8, error) { | |
| 237 if err := ensureElementBitSizeAndCapacity(d.state(), 8); err != nil { | |
| 238 return 0, err | |
| 239 } | |
| 240 d.state().alignOffsetToBytes() | |
| 241 value := d.buf[d.state().offset] | |
| 242 d.state().skipBytes(1) | |
| 243 d.state().elementsProcessed++ | |
| 244 return value, nil | |
| 245 } | |
| 246 | |
| 247 // ReadInt16 reads an int16 value. | |
| 248 func (d *Decoder) ReadInt16() (int16, error) { | |
| 249 value, err := d.ReadUint16() | |
| 250 return int16(value), err | |
| 251 } | |
| 252 | |
| 253 // ReadUint16 reads an uint16 value. | |
| 254 func (d *Decoder) ReadUint16() (uint16, error) { | |
| 255 if err := ensureElementBitSizeAndCapacity(d.state(), 16); err != nil { | |
| 256 return 0, err | |
| 257 } | |
| 258 d.state().alignOffsetToBytes() | |
| 259 d.state().offset = align(d.state().offset, 2) | |
| 260 value := binary.LittleEndian.Uint16(d.buf[d.state().offset:]) | |
| 261 d.state().skipBytes(2) | |
| 262 d.state().elementsProcessed++ | |
| 263 return value, nil | |
| 264 } | |
| 265 | |
| 266 // ReadInt32 reads an int32 value. | |
| 267 func (d *Decoder) ReadInt32() (int32, error) { | |
| 268 value, err := d.ReadUint32() | |
| 269 return int32(value), err | |
| 270 } | |
| 271 | |
| 272 // ReadUint32 reads an uint32 value. | |
| 273 func (d *Decoder) ReadUint32() (uint32, error) { | |
| 274 if err := ensureElementBitSizeAndCapacity(d.state(), 32); err != nil { | |
| 275 return 0, err | |
| 276 } | |
| 277 d.state().alignOffsetToBytes() | |
| 278 d.state().offset = align(d.state().offset, 4) | |
| 279 value := binary.LittleEndian.Uint32(d.buf[d.state().offset:]) | |
| 280 d.state().skipBytes(4) | |
| 281 d.state().elementsProcessed++ | |
| 282 return value, nil | |
| 283 } | |
| 284 | |
| 285 // ReadInt64 reads an int64 value. | |
| 286 func (d *Decoder) ReadInt64() (int64, error) { | |
| 287 value, err := d.ReadUint64() | |
| 288 return int64(value), err | |
| 289 } | |
| 290 | |
| 291 // ReadUint64 reads an uint64 value. | |
| 292 func (d *Decoder) ReadUint64() (uint64, error) { | |
| 293 if err := ensureElementBitSizeAndCapacity(d.state(), 64); err != nil { | |
| 294 return 0, err | |
| 295 } | |
| 296 d.state().alignOffsetToBytes() | |
| 297 d.state().offset = align(d.state().offset, 8) | |
| 298 value := binary.LittleEndian.Uint64(d.buf[d.state().offset:]) | |
| 299 d.state().skipBytes(8) | |
| 300 d.state().elementsProcessed++ | |
| 301 return value, nil | |
| 302 } | |
| 303 | |
| 304 // ReadFloat32 reads a float32 value. | |
| 305 func (d *Decoder) ReadFloat32() (float32, error) { | |
| 306 bits, err := d.ReadUint32() | |
| 307 return math.Float32frombits(bits), err | |
| 308 } | |
| 309 | |
| 310 // ReadFloat64 reads a float64 value. | |
| 311 func (d *Decoder) ReadFloat64() (float64, error) { | |
| 312 bits, err := d.ReadUint64() | |
| 313 return math.Float64frombits(bits), err | |
| 314 } | |
| 315 | |
| 316 // ReadString reads a string value. It doesn't read a pointer to the encoded | |
| 317 // string. | |
| 318 func (d *Decoder) ReadString() (string, error) { | |
| 319 length, err := d.StartArray(8) | |
| 320 if err != nil { | |
| 321 return "", err | |
| 322 } | |
| 323 var bytes []byte | |
| 324 for i := uint32(0); i < length; i++ { | |
| 325 b, err := d.ReadUint8() | |
| 326 if err != nil { | |
| 327 return "", err | |
| 328 } | |
| 329 bytes = append(bytes, b) | |
| 330 } | |
| 331 if err := d.Finish(); err != nil { | |
| 332 return "", err | |
| 333 } | |
| 334 return string(bytes), nil | |
| 335 } | |
| 336 | |
| 337 // ReadPointer reads a pointer and reassigns first unclaimed byte index if the | |
| 338 // pointer is not null. | |
| 339 func (d *Decoder) ReadPointer() (uint64, error) { | |
| 340 pointer, err := d.ReadUint64() | |
| 341 if err != nil { | |
| 342 return pointer, err | |
| 343 } | |
| 344 if pointer == 0 { | |
| 345 return pointer, nil | |
| 346 } | |
| 347 | |
| 348 newEnd := uint64(d.state().offset-8) + pointer | |
| 349 if pointer >= uint64(len(d.buf)) || newEnd >= uint64(len(d.buf)) { | |
| 350 return 0, &ValidationError{IllegalPointer, "trying to access out
of range memory"} | |
| 351 } | |
| 352 if newEnd < uint64(d.end) { | |
| 353 return 0, &ValidationError{IllegalMemoryRange, "trying to access
memory out of order"} | |
| 354 } | |
| 355 if newEnd%8 != 0 { | |
| 356 return 0, &ValidationError{MisalignedObject, | |
| 357 fmt.Sprintf("incorrect pointer data alignment: %d", newE
nd), | |
| 358 } | |
| 359 } | |
| 360 d.claimData(int(newEnd) - d.end) | |
| 361 return pointer, nil | |
| 362 } | |
| 363 | |
| 364 // ReadUntypedHandle reads an untyped handle. | |
| 365 func (d *Decoder) ReadUntypedHandle() (system.UntypedHandle, error) { | |
| 366 handleIndex, err := d.ReadUint32() | |
| 367 if err != nil { | |
| 368 return nil, err | |
| 369 } | |
| 370 if handleIndex == ^uint32(0) { | |
| 371 return &InvalidHandle{}, nil | |
| 372 } | |
| 373 return d.claimHandle(int(handleIndex)) | |
| 374 } | |
| 375 | |
| 376 // ReadHandle reads a handle. | |
| 377 func (d *Decoder) ReadHandle() (system.Handle, error) { | |
| 378 return d.ReadUntypedHandle() | |
| 379 } | |
| 380 | |
| 381 // ReadMessagePipeHandle reads a message pipe handle. | |
| 382 func (d *Decoder) ReadMessagePipeHandle() (system.MessagePipeHandle, error) { | |
| 383 if handle, err := d.ReadUntypedHandle(); err != nil { | |
| 384 return nil, err | |
| 385 } else { | |
| 386 return handle.ToMessagePipeHandle(), nil | |
| 387 } | |
| 388 } | |
| 389 | |
| 390 // ReadConsumerHandle reads a data pipe consumer handle. | |
| 391 func (d *Decoder) ReadConsumerHandle() (system.ConsumerHandle, error) { | |
| 392 if handle, err := d.ReadUntypedHandle(); err != nil { | |
| 393 return nil, err | |
| 394 } else { | |
| 395 return handle.ToConsumerHandle(), nil | |
| 396 } | |
| 397 } | |
| 398 | |
| 399 // ReadProducerHandle reads a data pipe producer handle. | |
| 400 func (d *Decoder) ReadProducerHandle() (system.ProducerHandle, error) { | |
| 401 if handle, err := d.ReadUntypedHandle(); err != nil { | |
| 402 return nil, err | |
| 403 } else { | |
| 404 return handle.ToProducerHandle(), nil | |
| 405 } | |
| 406 } | |
| 407 | |
| 408 // ReadSharedBufferHandle reads a shared buffer handle. | |
| 409 func (d *Decoder) ReadSharedBufferHandle() (system.SharedBufferHandle, error) { | |
| 410 if handle, err := d.ReadUntypedHandle(); err != nil { | |
| 411 return nil, err | |
| 412 } else { | |
| 413 return handle.ToSharedBufferHandle(), nil | |
| 414 } | |
| 415 } | |
| 416 | |
| 417 // ReadInterface reads an encoded interface and returns the message pipe handle. | |
| 418 // The version field is ignored for now. | |
| 419 func (d *Decoder) ReadInterface() (system.MessagePipeHandle, error) { | |
| 420 handle, err := d.ReadMessagePipeHandle() | |
| 421 if err != nil { | |
| 422 return nil, err | |
| 423 } | |
| 424 d.state().elementsProcessed-- | |
| 425 if _, err := d.ReadUint32(); err != nil { | |
| 426 return nil, err | |
| 427 } | |
| 428 return handle, nil | |
| 429 } | |
| OLD | NEW |