You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

112 lines
2.5 KiB

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