File: String.swift

package info (click to toggle)
swiftlang 6.0.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,519,992 kB
  • sloc: cpp: 9,107,863; ansic: 2,040,022; asm: 1,135,751; python: 296,500; objc: 82,456; f90: 60,502; lisp: 34,951; pascal: 19,946; sh: 18,133; perl: 7,482; ml: 4,937; javascript: 4,117; makefile: 3,840; awk: 3,535; xml: 914; fortran: 619; cs: 573; ruby: 573
file content (111 lines) | stat: -rw-r--r-- 4,857 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

@_implementationOnly import CoreFoundation

extension String: _ObjectiveCBridgeable {
    
    public typealias _ObjectType = NSString
    public func _bridgeToObjectiveC() -> _ObjectType {
        return NSString(self)
    }
    
    static public func _forceBridgeFromObjectiveC(_ source: _ObjectType, result: inout String?) {
        result = _unconditionallyBridgeFromObjectiveC(source)
    }
    
    @discardableResult
    static public func _conditionallyBridgeFromObjectiveC(_ source: _ObjectType, result: inout String?) -> Bool {
        if type(of: source) == NSString.self || type(of: source) == NSMutableString.self {
            result = source._storage
        } else if type(of: source) == _NSCFString.self {
            let cf = unsafeBitCast(source, to: CFString.self)
            let length = CFStringGetLength(cf)
            if length == 0 {
                result = ""
            } else if let ptr = CFStringGetCStringPtr(cf, CFStringEncoding(kCFStringEncodingASCII)) {
                // ASCII encoding has 1 byte per code point and CFStringGetLength() returned the length in
                // codepoints so length should be the length of the ASCII string in bytes. We can't ask for the UTF-8
                // encoding as some codepoints are multi-byte in UTF8 so the buffer length wouldn't be known.
                // Note: CFStringGetCStringPtr(cf, CFStringEncoding(kCFStringEncodingUTF8)) does seems to return NULL
                // for strings with multibyte UTF-8 but this isn't guaranteed or documented so ASCII is safer.
                result = ptr.withMemoryRebound(to: UInt8.self, capacity: length) {
                    return String(decoding: UnsafeBufferPointer(start: $0, count: length), as: UTF8.self)
                }
            } else if let ptr = CFStringGetCharactersPtr(cf) {
                result = String(decoding: UnsafeBufferPointer(start: ptr, count: length), as: UTF16.self)
            } else {
                let buffer = UnsafeMutablePointer<UniChar>.allocate(capacity: length)
                CFStringGetCharacters(cf, CFRangeMake(0, length), buffer)
                
                result = String(decoding: UnsafeBufferPointer(start: buffer, count: length), as: UTF16.self)
                buffer.deinitialize(count: length)
                buffer.deallocate()
            }
        } else if type(of: source) == _NSCFConstantString.self {
            let conststr = unsafeDowncast(source, to: _NSCFConstantString.self)
            result = String(decoding: UnsafeBufferPointer(start: conststr._ptr, count: Int(conststr._length)), as: UTF8.self)
        } else {
            let len = source.length
            let characters = [unichar](unsafeUninitializedCapacity: len) { buf, initializedCount in
                source.getCharacters(buf.baseAddress!, range: NSRange(location: 0, length: len))
                initializedCount = len
            }
            result = String(decoding: characters, as: UTF16.self)
        }
        return result != nil
    }
    
    static public func _unconditionallyBridgeFromObjectiveC(_ source: _ObjectType?) -> String {
        if let object = source {
            var value: String?
            _conditionallyBridgeFromObjectiveC(object, result: &value)
            return value!
        } else {
            return ""
        }
    }
}


extension Substring: _ObjectiveCBridgeable {

    public func _bridgeToObjectiveC() -> NSString {
        return NSString(String(self))
    }

    public static func _forceBridgeFromObjectiveC(_ source: NSString, result: inout Substring?) {
        result = _unconditionallyBridgeFromObjectiveC(source)
    }

    @discardableResult
    public static func _conditionallyBridgeFromObjectiveC(_ source: NSString, result: inout Substring?) -> Bool {
        var value: String?
        if String._conditionallyBridgeFromObjectiveC(source, result: &value) {
            result = Substring(value!)
            return true
        } else {
            return false
        }
    }

    public static func _unconditionallyBridgeFromObjectiveC(_ source: NSString?) -> Substring {
        if let object = source {
            var value: Substring?
            _conditionallyBridgeFromObjectiveC(object, result: &value)
            return value!
        } else {
            return ""
        }
    }

}