| Index: mojo/go/tests/testutil.go
|
| diff --git a/mojo/go/tests/testutil.go b/mojo/go/tests/testutil.go
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..334650d8556223b6e55156bb38268ece7a0837dd
|
| --- /dev/null
|
| +++ b/mojo/go/tests/testutil.go
|
| @@ -0,0 +1,158 @@
|
| +// Copyright 2015 The Chromium 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 tests
|
| +
|
| +import (
|
| + "encoding/binary"
|
| + "fmt"
|
| + "math"
|
| + "strings"
|
| +
|
| + "mojo/public/go/system"
|
| +)
|
| +
|
| +// inputParser parses validation tests input format as described in
|
| +// |mojo/public/cpp/bindings/tests/validation_test_input_parser.h|
|
| +type inputParser struct {
|
| +}
|
| +
|
| +type dataItem struct {
|
| + Type string
|
| + Value string
|
| +}
|
| +
|
| +type pointerPlaceholder struct {
|
| + Position int
|
| + Size int
|
| +}
|
| +
|
| +func (p *inputParser) parseToDataItems(s string) []dataItem {
|
| + var items []dataItem
|
| + s = strings.TrimSpace(s)
|
| + for len(s) > 0 {
|
| + // Parsing data item type.
|
| + var itemType string
|
| + if s[0] == '[' {
|
| + closeBracket := strings.Index(s, "]")
|
| + if closeBracket == -1 {
|
| + panic("unmatched left [")
|
| + }
|
| + itemType = strings.TrimSpace(s[1:closeBracket])
|
| + s = strings.TrimSpace(s[closeBracket+1:])
|
| + } else {
|
| + itemType = "u1"
|
| + }
|
| +
|
| + // Parsing data item value.
|
| + itemEnd := strings.IndexAny(s, "[ \t\n\r")
|
| + if itemEnd == -1 {
|
| + items = append(items, dataItem{itemType, strings.TrimSpace(s)})
|
| + s = ""
|
| + } else {
|
| + items = append(items, dataItem{itemType, strings.TrimSpace(s[:itemEnd])})
|
| + s = strings.TrimSpace(s[itemEnd:])
|
| + }
|
| + }
|
| + return items
|
| +}
|
| +
|
| +// Parse parses a validation tests input string that has no comments.
|
| +// Panics if input has errors.
|
| +func (p *inputParser) Parse(s string) ([]byte, []system.Handle) {
|
| + var bytes []byte
|
| + var handles []system.Handle
|
| + var buf [8]byte
|
| + pointers := make(map[string]pointerPlaceholder)
|
| + for _, item := range p.parseToDataItems(s) {
|
| + switch item.Type {
|
| + case "u1":
|
| + var value uint8
|
| + fmt.Sscan(item.Value, &value)
|
| + bytes = append(bytes, byte(value))
|
| + case "u2":
|
| + var value uint16
|
| + fmt.Sscan(item.Value, &value)
|
| + binary.LittleEndian.PutUint16(buf[:2], value)
|
| + bytes = append(bytes, buf[:2]...)
|
| + case "u4":
|
| + var value uint32
|
| + fmt.Sscan(item.Value, &value)
|
| + binary.LittleEndian.PutUint32(buf[:4], value)
|
| + bytes = append(bytes, buf[:4]...)
|
| + case "u8":
|
| + var value uint64
|
| + fmt.Sscan(item.Value, &value)
|
| + binary.LittleEndian.PutUint64(buf[:8], value)
|
| + bytes = append(bytes, buf[:8]...)
|
| + case "s1":
|
| + var value int8
|
| + fmt.Sscan(item.Value, &value)
|
| + bytes = append(bytes, byte(value))
|
| + case "s2":
|
| + var value int16
|
| + fmt.Sscan(item.Value, &value)
|
| + binary.LittleEndian.PutUint16(buf[:2], uint16(value))
|
| + bytes = append(bytes, buf[:2]...)
|
| + case "s4":
|
| + var value int32
|
| + fmt.Sscan(item.Value, &value)
|
| + binary.LittleEndian.PutUint32(buf[:4], uint32(value))
|
| + bytes = append(bytes, buf[:4]...)
|
| + case "s8":
|
| + var value int64
|
| + fmt.Sscan(item.Value, &value)
|
| + binary.LittleEndian.PutUint64(buf[:8], uint64(value))
|
| + bytes = append(bytes, buf[:8]...)
|
| + case "b":
|
| + var value byte
|
| + for i := 0; i < 8; i++ {
|
| + value <<= 1
|
| + if item.Value[i] == '1' {
|
| + value++
|
| + }
|
| + }
|
| + bytes = append(bytes, value)
|
| + case "f":
|
| + var value float32
|
| + fmt.Sscan(item.Value, &value)
|
| + binary.LittleEndian.PutUint32(buf[:4], math.Float32bits(value))
|
| + bytes = append(bytes, buf[:4]...)
|
| + case "d":
|
| + var value float64
|
| + fmt.Sscan(item.Value, &value)
|
| + binary.LittleEndian.PutUint64(buf[:8], math.Float64bits(value))
|
| + bytes = append(bytes, buf[:8]...)
|
| + case "dist4":
|
| + pointers[item.Value] = pointerPlaceholder{len(bytes), 4}
|
| + bytes = append(bytes, buf[:4]...)
|
| + case "dist8":
|
| + pointers[item.Value] = pointerPlaceholder{len(bytes), 8}
|
| + bytes = append(bytes, buf[:8]...)
|
| + case "anchr":
|
| + placeholder := pointers[item.Value]
|
| + dist := len(bytes) - placeholder.Position
|
| + switch placeholder.Size {
|
| + case 4:
|
| + binary.LittleEndian.PutUint32(bytes[placeholder.Position:], uint32(dist))
|
| + case 8:
|
| + binary.LittleEndian.PutUint64(bytes[placeholder.Position:], uint64(dist))
|
| + }
|
| + delete(pointers, item.Value)
|
| + case "handles":
|
| + var value int
|
| + fmt.Sscan(item.Value, &value)
|
| + handles = make([]system.Handle, value)
|
| + for i, _ := range handles {
|
| + handles[i] = system.GetCore().AcquireNativeHandle(0)
|
| + }
|
| + default:
|
| + panic(fmt.Sprintf("unsupported item type: %v", item.Type))
|
| + }
|
| + }
|
| + if len(pointers) != 0 {
|
| + panic(fmt.Sprintf("unmatched pointers: %v", pointers))
|
| + }
|
| + return bytes, handles
|
| +}
|
|
|