bytes_unsafe.go 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344
  1. // +build !appengine,!appenginevm
  2. package jsonparser
  3. import (
  4. "reflect"
  5. "strconv"
  6. "unsafe"
  7. "runtime"
  8. )
  9. //
  10. // The reason for using *[]byte rather than []byte in parameters is an optimization. As of Go 1.6,
  11. // the compiler cannot perfectly inline the function when using a non-pointer slice. That is,
  12. // the non-pointer []byte parameter version is slower than if its function body is manually
  13. // inlined, whereas the pointer []byte version is equally fast to the manually inlined
  14. // version. Instruction count in assembly taken from "go tool compile" confirms this difference.
  15. //
  16. // TODO: Remove hack after Go 1.7 release
  17. //
  18. func equalStr(b *[]byte, s string) bool {
  19. return *(*string)(unsafe.Pointer(b)) == s
  20. }
  21. func parseFloat(b *[]byte) (float64, error) {
  22. return strconv.ParseFloat(*(*string)(unsafe.Pointer(b)), 64)
  23. }
  24. // A hack until issue golang/go#2632 is fixed.
  25. // See: https://github.com/golang/go/issues/2632
  26. func bytesToString(b *[]byte) string {
  27. return *(*string)(unsafe.Pointer(b))
  28. }
  29. func StringToBytes(s string) []byte {
  30. b := make([]byte, 0, 0)
  31. bh := (*reflect.SliceHeader)(unsafe.Pointer(&b))
  32. sh := (*reflect.StringHeader)(unsafe.Pointer(&s))
  33. bh.Data = sh.Data
  34. bh.Cap = sh.Len
  35. bh.Len = sh.Len
  36. runtime.KeepAlive(s)
  37. return b
  38. }