go-bot

Форк
0
99 строк · 2.7 Кб
1
// Copyright 2018 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
//go:build !purego && !appengine
6
// +build !purego,!appengine
7

8
package protoreflect
9

10
import (
11
	"unsafe"
12

13
	"google.golang.org/protobuf/internal/pragma"
14
)
15

16
type (
17
	stringHeader struct {
18
		Data unsafe.Pointer
19
		Len  int
20
	}
21
	sliceHeader struct {
22
		Data unsafe.Pointer
23
		Len  int
24
		Cap  int
25
	}
26
	ifaceHeader struct {
27
		Type unsafe.Pointer
28
		Data unsafe.Pointer
29
	}
30
)
31

32
var (
33
	nilType     = typeOf(nil)
34
	boolType    = typeOf(*new(bool))
35
	int32Type   = typeOf(*new(int32))
36
	int64Type   = typeOf(*new(int64))
37
	uint32Type  = typeOf(*new(uint32))
38
	uint64Type  = typeOf(*new(uint64))
39
	float32Type = typeOf(*new(float32))
40
	float64Type = typeOf(*new(float64))
41
	stringType  = typeOf(*new(string))
42
	bytesType   = typeOf(*new([]byte))
43
	enumType    = typeOf(*new(EnumNumber))
44
)
45

46
// typeOf returns a pointer to the Go type information.
47
// The pointer is comparable and equal if and only if the types are identical.
48
func typeOf(t interface{}) unsafe.Pointer {
49
	return (*ifaceHeader)(unsafe.Pointer(&t)).Type
50
}
51

52
// value is a union where only one type can be represented at a time.
53
// The struct is 24B large on 64-bit systems and requires the minimum storage
54
// necessary to represent each possible type.
55
//
56
// The Go GC needs to be able to scan variables containing pointers.
57
// As such, pointers and non-pointers cannot be intermixed.
58
type value struct {
59
	pragma.DoNotCompare // 0B
60

61
	// typ stores the type of the value as a pointer to the Go type.
62
	typ unsafe.Pointer // 8B
63

64
	// ptr stores the data pointer for a String, Bytes, or interface value.
65
	ptr unsafe.Pointer // 8B
66

67
	// num stores a Bool, Int32, Int64, Uint32, Uint64, Float32, Float64, or
68
	// Enum value as a raw uint64.
69
	//
70
	// It is also used to store the length of a String or Bytes value;
71
	// the capacity is ignored.
72
	num uint64 // 8B
73
}
74

75
func valueOfString(v string) Value {
76
	p := (*stringHeader)(unsafe.Pointer(&v))
77
	return Value{typ: stringType, ptr: p.Data, num: uint64(len(v))}
78
}
79
func valueOfBytes(v []byte) Value {
80
	p := (*sliceHeader)(unsafe.Pointer(&v))
81
	return Value{typ: bytesType, ptr: p.Data, num: uint64(len(v))}
82
}
83
func valueOfIface(v interface{}) Value {
84
	p := (*ifaceHeader)(unsafe.Pointer(&v))
85
	return Value{typ: p.Type, ptr: p.Data}
86
}
87

88
func (v Value) getString() (x string) {
89
	*(*stringHeader)(unsafe.Pointer(&x)) = stringHeader{Data: v.ptr, Len: int(v.num)}
90
	return x
91
}
92
func (v Value) getBytes() (x []byte) {
93
	*(*sliceHeader)(unsafe.Pointer(&x)) = sliceHeader{Data: v.ptr, Len: int(v.num), Cap: int(v.num)}
94
	return x
95
}
96
func (v Value) getIface() (x interface{}) {
97
	*(*ifaceHeader)(unsafe.Pointer(&x)) = ifaceHeader{Type: v.typ, Data: v.ptr}
98
	return x
99
}
100

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.