wa-lang.org/wazero@v1.0.2/imports/proxywasm/internal/serde.go (about) 1 // Copyright 2020-2021 Tetrate 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package internal 16 17 import ( 18 "encoding/binary" 19 "unsafe" 20 ) 21 22 func DeserializeMap(bs []byte) [][2]string { 23 numHeaders := binary.LittleEndian.Uint32(bs[0:4]) 24 var sizeIndex = 4 25 var dataIndex = 4 + 4*2*int(numHeaders) 26 ret := make([][2]string, numHeaders) 27 for i := 0; i < int(numHeaders); i++ { 28 keySize := int(binary.LittleEndian.Uint32(bs[sizeIndex : sizeIndex+4])) 29 sizeIndex += 4 30 keyPtr := bs[dataIndex : dataIndex+keySize] 31 key := *(*string)(unsafe.Pointer(&keyPtr)) 32 dataIndex += keySize + 1 33 34 valueSize := int(binary.LittleEndian.Uint32(bs[sizeIndex : sizeIndex+4])) 35 sizeIndex += 4 36 valuePtr := bs[dataIndex : dataIndex+valueSize] 37 value := *(*string)(unsafe.Pointer(&valuePtr)) 38 dataIndex += valueSize + 1 39 ret[i] = [2]string{key, value} 40 } 41 return ret 42 } 43 44 func SerializeMap(ms [][2]string) []byte { 45 size := 4 46 for _, m := range ms { 47 // key/value's bytes + len * 2 (8 bytes) + nil * 2 (2 bytes) 48 size += len(m[0]) + len(m[1]) + 10 49 } 50 51 ret := make([]byte, size) 52 binary.LittleEndian.PutUint32(ret[0:4], uint32(len(ms))) 53 54 var base = 4 55 for _, m := range ms { 56 binary.LittleEndian.PutUint32(ret[base:base+4], uint32(len(m[0]))) 57 base += 4 58 binary.LittleEndian.PutUint32(ret[base:base+4], uint32(len(m[1]))) 59 base += 4 60 } 61 62 for _, m := range ms { 63 for i := 0; i < len(m[0]); i++ { 64 ret[base] = m[0][i] 65 base++ 66 } 67 base++ // nil 68 69 for i := 0; i < len(m[1]); i++ { 70 ret[base] = m[1][i] 71 base++ 72 } 73 base++ // nil 74 } 75 return ret 76 } 77 78 func SerializePropertyPath(path []string) []byte { 79 // TODO: for static paths, like upstream.address, we'd better pre-define []byte so that 80 // we do not incur any serialization cost 81 if len(path) == 0 { 82 return []byte{} 83 } 84 85 var size int 86 for _, p := range path { 87 size += len(p) + 1 88 } 89 ret := make([]byte, 0, size) 90 for _, p := range path { 91 ret = append(ret, p...) 92 ret = append(ret, 0) 93 } 94 ret = ret[:len(ret)-1] 95 return ret 96 }