darwin.go 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. // Copyright 2012 The Go Authors. 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. //go:build darwin
  5. // +build darwin
  6. package main
  7. /*
  8. #cgo LDFLAGS: -framework CoreFoundation
  9. #include <CoreFoundation/CFBase.h>
  10. #include <CoreFoundation/CoreFoundation.h>
  11. */
  12. import "C"
  13. import (
  14. "unsafe"
  15. )
  16. func init() {
  17. AddFactory(CollatorFactory{"osx", newOSX16Collator,
  18. "OS X/Darwin collator, using native strings."})
  19. AddFactory(CollatorFactory{"osx8", newOSX8Collator,
  20. "OS X/Darwin collator for UTF-8."})
  21. }
  22. func osxUInt8P(s []byte) *C.UInt8 {
  23. return (*C.UInt8)(unsafe.Pointer(&s[0]))
  24. }
  25. func osxCharP(s []uint16) *C.UniChar {
  26. return (*C.UniChar)(unsafe.Pointer(&s[0]))
  27. }
  28. // osxCollator implements an Collator based on OS X's CoreFoundation.
  29. type osxCollator struct {
  30. loc C.CFLocaleRef
  31. opt C.CFStringCompareFlags
  32. }
  33. func (c *osxCollator) init(locale string) {
  34. l := C.CFStringCreateWithBytes(
  35. C.kCFAllocatorDefault,
  36. osxUInt8P([]byte(locale)),
  37. C.CFIndex(len(locale)),
  38. C.kCFStringEncodingUTF8,
  39. C.Boolean(0),
  40. )
  41. c.loc = C.CFLocaleCreate(C.kCFAllocatorDefault, l)
  42. }
  43. func newOSX8Collator(locale string) (Collator, error) {
  44. c := &osx8Collator{}
  45. c.init(locale)
  46. return c, nil
  47. }
  48. func newOSX16Collator(locale string) (Collator, error) {
  49. c := &osx16Collator{}
  50. c.init(locale)
  51. return c, nil
  52. }
  53. func (c osxCollator) Key(s Input) []byte {
  54. return nil // sort keys not supported by OS X CoreFoundation
  55. }
  56. type osx8Collator struct {
  57. osxCollator
  58. }
  59. type osx16Collator struct {
  60. osxCollator
  61. }
  62. func (c osx16Collator) Compare(a, b Input) int {
  63. sa := C.CFStringCreateWithCharactersNoCopy(
  64. C.kCFAllocatorDefault,
  65. osxCharP(a.UTF16),
  66. C.CFIndex(len(a.UTF16)),
  67. C.kCFAllocatorDefault,
  68. )
  69. sb := C.CFStringCreateWithCharactersNoCopy(
  70. C.kCFAllocatorDefault,
  71. osxCharP(b.UTF16),
  72. C.CFIndex(len(b.UTF16)),
  73. C.kCFAllocatorDefault,
  74. )
  75. _range := C.CFRangeMake(0, C.CFStringGetLength(sa))
  76. return int(C.CFStringCompareWithOptionsAndLocale(sa, sb, _range, c.opt, c.loc))
  77. }
  78. func (c osx8Collator) Compare(a, b Input) int {
  79. sa := C.CFStringCreateWithBytesNoCopy(
  80. C.kCFAllocatorDefault,
  81. osxUInt8P(a.UTF8),
  82. C.CFIndex(len(a.UTF8)),
  83. C.kCFStringEncodingUTF8,
  84. C.Boolean(0),
  85. C.kCFAllocatorDefault,
  86. )
  87. sb := C.CFStringCreateWithBytesNoCopy(
  88. C.kCFAllocatorDefault,
  89. osxUInt8P(b.UTF8),
  90. C.CFIndex(len(b.UTF8)),
  91. C.kCFStringEncodingUTF8,
  92. C.Boolean(0),
  93. C.kCFAllocatorDefault,
  94. )
  95. _range := C.CFRangeMake(0, C.CFStringGetLength(sa))
  96. return int(C.CFStringCompareWithOptionsAndLocale(sa, sb, _range, c.opt, c.loc))
  97. }