...
1
2
3
4
5
6
7
8 package strs
9
10 import (
11 "unsafe"
12
13 "google.golang.org/protobuf/reflect/protoreflect"
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 )
27
28
29
30
31
32
33 func UnsafeString(b []byte) (s string) {
34 src := (*sliceHeader)(unsafe.Pointer(&b))
35 dst := (*stringHeader)(unsafe.Pointer(&s))
36 dst.Data = src.Data
37 dst.Len = src.Len
38 return s
39 }
40
41
42
43
44
45 func UnsafeBytes(s string) (b []byte) {
46 src := (*stringHeader)(unsafe.Pointer(&s))
47 dst := (*sliceHeader)(unsafe.Pointer(&b))
48 dst.Data = src.Data
49 dst.Len = src.Len
50 dst.Cap = src.Len
51 return b
52 }
53
54
55
56 type Builder struct {
57 buf []byte
58 }
59
60
61
62 func (sb *Builder) AppendFullName(prefix protoreflect.FullName, name protoreflect.Name) protoreflect.FullName {
63 n := len(prefix) + len(".") + len(name)
64 if len(prefix) == 0 {
65 n -= len(".")
66 }
67 sb.grow(n)
68 sb.buf = append(sb.buf, prefix...)
69 sb.buf = append(sb.buf, '.')
70 sb.buf = append(sb.buf, name...)
71 return protoreflect.FullName(sb.last(n))
72 }
73
74
75
76 func (sb *Builder) MakeString(b []byte) string {
77 sb.grow(len(b))
78 sb.buf = append(sb.buf, b...)
79 return sb.last(len(b))
80 }
81
82 func (sb *Builder) grow(n int) {
83 if cap(sb.buf)-len(sb.buf) >= n {
84 return
85 }
86
87
88
89
90 sb.buf = make([]byte, 0, 2*(cap(sb.buf)+n))
91 }
92
93 func (sb *Builder) last(n int) string {
94 return UnsafeString(sb.buf[len(sb.buf)-n:])
95 }
96
View as plain text