mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
204 lines
5.1 KiB
Go
204 lines
5.1 KiB
Go
// 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/go/system/embedder"
|
|
"mojo/public/go/bindings"
|
|
"mojo/public/go/system"
|
|
)
|
|
|
|
var core system.Core
|
|
var waiter bindings.AsyncWaiter
|
|
|
|
func init() {
|
|
embedder.InitializeMojoEmbedder()
|
|
core = system.GetCore()
|
|
waiter = bindings.GetAsyncWaiter()
|
|
}
|
|
|
|
type mockHandle struct {
|
|
bindings.InvalidHandle
|
|
handle system.MojoHandle
|
|
}
|
|
|
|
func (h *mockHandle) IsValid() bool {
|
|
return true
|
|
}
|
|
|
|
func (h *mockHandle) ReleaseNativeHandle() system.MojoHandle {
|
|
return h.handle
|
|
}
|
|
|
|
func (h *mockHandle) ToUntypedHandle() system.UntypedHandle {
|
|
return h
|
|
}
|
|
|
|
func (h *mockHandle) ToConsumerHandle() system.ConsumerHandle {
|
|
return h
|
|
}
|
|
|
|
func (h *mockHandle) ToProducerHandle() system.ProducerHandle {
|
|
return h
|
|
}
|
|
|
|
func (h *mockHandle) ToMessagePipeHandle() system.MessagePipeHandle {
|
|
return h
|
|
}
|
|
|
|
func (h *mockHandle) ToSharedBufferHandle() system.SharedBufferHandle {
|
|
return h
|
|
}
|
|
|
|
// 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.UntypedHandle) {
|
|
var bytes []byte
|
|
var buf [8]byte
|
|
// We need non-nil slice for comparing values with reflect.DeepEqual.
|
|
handles := []system.UntypedHandle{}
|
|
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.UntypedHandle, value)
|
|
for i, _ := range handles {
|
|
handles[i] = &mockHandle{handle: system.MojoHandle(i + 1)}
|
|
}
|
|
default:
|
|
panic(fmt.Sprintf("unsupported item type: %v", item.Type))
|
|
}
|
|
}
|
|
if len(pointers) != 0 {
|
|
panic(fmt.Sprintf("unmatched pointers: %v", pointers))
|
|
}
|
|
return bytes, handles
|
|
}
|