zorldo

Goofing around with Ebiten
git clone git://bsandro.tech/zorldo
Log | Files | Refs | README

slice_js.go (2778B)


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