github.com/cellofellow/gopkg@v0.0.0-20140722061823-eec0544a62ad/image/jxr/utils.go (about)

     1  // Copyright 2014 <chaishushan{AT}gmail.com>. 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  package jxr
     6  
     7  import (
     8  	"fmt"
     9  	"reflect"
    10  	"unsafe"
    11  )
    12  
    13  func byteSlice(slice interface{}) (data []byte) {
    14  	sv := reflect.ValueOf(slice)
    15  	if sv.Kind() != reflect.Slice {
    16  		panic(fmt.Sprintf("ByteSlice called with non-slice value of type %T", slice))
    17  	}
    18  	h := (*reflect.SliceHeader)((unsafe.Pointer(&data)))
    19  	h.Cap = sv.Cap() * int(sv.Type().Elem().Size())
    20  	h.Len = sv.Len() * int(sv.Type().Elem().Size())
    21  	h.Data = sv.Pointer()
    22  	return
    23  }
    24  
    25  func slice(slice interface{}, newSliceType reflect.Type) interface{} {
    26  	sv := reflect.ValueOf(slice)
    27  	if sv.Kind() != reflect.Slice {
    28  		panic(fmt.Sprintf("Slice called with non-slice value of type %T", slice))
    29  	}
    30  	if newSliceType.Kind() != reflect.Slice {
    31  		panic(fmt.Sprintf("Slice called with non-slice type of type %T", newSliceType))
    32  	}
    33  	newSlice := reflect.New(newSliceType)
    34  	hdr := (*reflect.SliceHeader)(unsafe.Pointer(newSlice.Pointer()))
    35  	hdr.Cap = sv.Cap() * int(sv.Type().Elem().Size()) / int(newSliceType.Elem().Size())
    36  	hdr.Len = sv.Len() * int(sv.Type().Elem().Size()) / int(newSliceType.Elem().Size())
    37  	hdr.Data = uintptr(sv.Pointer())
    38  	return newSlice.Elem().Interface()
    39  }