go113_js.go (2926B)
1 // Copyright 2019 The Ebiten Authors 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 // +build go1.13 16 17 package jsutil 18 19 import ( 20 "fmt" 21 "reflect" 22 "runtime" 23 "syscall/js" 24 "unsafe" 25 ) 26 27 func Uint8ArrayToSlice(value js.Value) []byte { 28 s := make([]byte, value.Get("byteLength").Int()) 29 js.CopyBytesToGo(s, value) 30 return s 31 } 32 33 func ArrayBufferToSlice(value js.Value) []byte { 34 return Uint8ArrayToSlice(js.Global().Get("Uint8Array").New(value)) 35 } 36 37 func sliceToByteSlice(s interface{}) (bs []byte) { 38 switch s := s.(type) { 39 case []int8: 40 h := (*reflect.SliceHeader)(unsafe.Pointer(&s)) 41 bs = *(*[]byte)(unsafe.Pointer(h)) 42 runtime.KeepAlive(s) 43 case []int16: 44 h := (*reflect.SliceHeader)(unsafe.Pointer(&s)) 45 h.Len *= 2 46 h.Cap *= 2 47 bs = *(*[]byte)(unsafe.Pointer(h)) 48 runtime.KeepAlive(s) 49 case []int32: 50 h := (*reflect.SliceHeader)(unsafe.Pointer(&s)) 51 h.Len *= 4 52 h.Cap *= 4 53 bs = *(*[]byte)(unsafe.Pointer(h)) 54 runtime.KeepAlive(s) 55 case []int64: 56 h := (*reflect.SliceHeader)(unsafe.Pointer(&s)) 57 h.Len *= 8 58 h.Cap *= 8 59 bs = *(*[]byte)(unsafe.Pointer(h)) 60 runtime.KeepAlive(s) 61 case []uint8: 62 return s 63 case []uint16: 64 h := (*reflect.SliceHeader)(unsafe.Pointer(&s)) 65 h.Len *= 2 66 h.Cap *= 2 67 bs = *(*[]byte)(unsafe.Pointer(h)) 68 runtime.KeepAlive(s) 69 case []uint32: 70 h := (*reflect.SliceHeader)(unsafe.Pointer(&s)) 71 h.Len *= 4 72 h.Cap *= 4 73 bs = *(*[]byte)(unsafe.Pointer(h)) 74 runtime.KeepAlive(s) 75 case []uint64: 76 h := (*reflect.SliceHeader)(unsafe.Pointer(&s)) 77 h.Len *= 8 78 h.Cap *= 8 79 bs = *(*[]byte)(unsafe.Pointer(h)) 80 runtime.KeepAlive(s) 81 case []float32: 82 h := (*reflect.SliceHeader)(unsafe.Pointer(&s)) 83 h.Len *= 4 84 h.Cap *= 4 85 bs = *(*[]byte)(unsafe.Pointer(h)) 86 runtime.KeepAlive(s) 87 case []float64: 88 h := (*reflect.SliceHeader)(unsafe.Pointer(&s)) 89 h.Len *= 8 90 h.Cap *= 8 91 bs = *(*[]byte)(unsafe.Pointer(h)) 92 runtime.KeepAlive(s) 93 default: 94 panic(fmt.Sprintf("jsutil: unexpected value at sliceToBytesSlice: %T", s)) 95 } 96 return 97 } 98 99 func CopySliceToJS(dst js.Value, src interface{}) { 100 switch s := src.(type) { 101 case []uint8: 102 js.CopyBytesToJS(dst, s) 103 case []int8, []int16, []int32, []uint16, []uint32, []float32, []float64: 104 a := js.Global().Get("Uint8Array").New(dst.Get("buffer"), dst.Get("byteOffset"), dst.Get("byteLength")) 105 js.CopyBytesToJS(a, sliceToByteSlice(s)) 106 default: 107 panic(fmt.Sprintf("jsutil: unexpected value at CopySliceToJS: %T", s)) 108 } 109 }