0001
0025 import System
0026
0027 extension String {
0028 public static func bufferWithSizeString.swift:33 | var buffer = String.bufferWithSize(length + 1) |
(size: Int) -> [Int8] {
0029 return [Int8](count: size, repeatedValue: 0)
0030 }
0031
0032 public init?(pointer: UnsafePointer<Int8>, length: Int) {
0033 var buffer = String.bufferWithSize(length + 1)
0034 strncpy(&buffer, pointer, length)
0035
0036 guard let string = String.fromCString(buffer) else {
0037 return nil
0038 }
0039
0040 self.init(string)
0041 }
0042
0043 subscript (i: Int) -> Character? {
0044 guard i >= 0 && i < characters.count else { return nil }
0045 return self[startIndex.advancedBy(i)]
0046 }
0047
0048 subscript (i: Range<Int>) -> String? {
0049 let start = i.startIndex, end = i.endIndex
0050 guard start >= 0 && start <= characters.count && end >= 0 && end <= characters.count && start < end else { return nil }
0051 return self[startIndex.advancedBy(start) ..< startIndex.advancedBy(end)]
0052 }
0053
0054 public func split(separator: Character, maxSplit: Int = .max, allowEmptySlices: Bool = false) -> [String] {
0055 return characters.split(separator, maxSplit: maxSplit, allowEmptySlices: allowEmptySlices).map(String.init)
0056 }
0057
0058 public func trim() -> String {
0059 return trim(CharacterSet.whitespaceAndNewline)
0060 }
0061
0062 public func trimString.swift:59 | return trim(CharacterSet.whitespaceAndNewline) |
(characters: CharacterSet) -> String {
0063 let string = trimLeft(characters)
0064 return string.trimRight(characters)
0065 }
0066
0067 public func trimLeftString.swift:63 | let string = trimLeft(characters) |
(characterSet: CharacterSet) -> String {
0068 var start = characters.count
0069
0070 for (index, character) in characters.enumerate() {
0071 if !characterSet.contains(character) {
0072 start = index
0073 break
0074 }
0075 }
0076
0077 return self[startIndex.advancedBy(start) ..< endIndex]
0078 }
0079
0080 public func trimRightString.swift:64 | return string.trimRight(characters) |
(characterSet: CharacterSet) -> String {
0081 var end = characters.count
0082
0083 for (index, character) in characters.reverse().enumerate() {
0084 if !characterSet.contains(character) {
0085 end = index
0086 break
0087 }
0088 }
0089
0090 return self[startIndex ..< startIndex.advancedBy(characters.count - end)]
0091 }
0092
0093 public func indexOfString.swift:98 | return indexOf(string) != nil |
(string: String) -> String.CharacterView.Index? {
0094 return characters.indexOf(string.characters)
0095 }
0096
0097 public func contains(string: String) -> Bool {
0098 return indexOf(string) != nil
0099 }
0100
0101 public func splitBy(separator: String) -> [String] {
0102 let separatorChars = separator.characters
0103 guard var index = characters.indexOf(separatorChars) else {
0104 return [self]
0105 }
0106 let separatorCount = separatorChars.count
0107 var start = characters.startIndex
0108 var array: [String] = []
0109 while true {
0110 let distance = characters.startIndex.distanceTo(index)
0111 let trange = start ..< characters.startIndex.advancedBy(distance + characters.startIndex.distanceTo(start))
0112 array.append(String(characters[trange]))
0113 start = start.advancedBy(distance + separatorCount)
0114 let substr = characters.suffixFrom(start)
0115 if let _index = substr.indexOf(separatorChars) {
0116 index = _index
0117 } else {
0118 break
0119 }
0120 }
0121 array.append(String(characters[start ..< characters.endIndex]))
0122 return array
0123 }
0124
0125 public mutating func replace(string: String, with: String) {
0126 let strChars = string.characters
0127 let strCount = strChars.count
0128 while true {
0129 guard let index = characters.indexOf(strChars) else { break }
0130 replaceRange(index ..< index.advancedBy(strCount), with: with)
0131 }
0132 }
0133
0134 }
0135
0136 extension String.CharacterView {
0137
0138 func indexOfString.swift:94 | return characters.indexOf(string.characters) |
String.swift:103 | guard var index = characters.indexOf(separatorChars) else { |
String.swift:115 | if let _index = substr.indexOf(separatorChars) { |
String.swift:129 | guard let index = characters.indexOf(strChars) else { break } |
(sequence: String.CharacterView) -> String.CharacterView.Index? {
0139 guard let firstChar = sequence.first else {
0140 return nil
0141 }
0142 let seqString = String(sequence)
0143 for (i, char) in enumerate() {
0144 guard char == firstChar else { continue }
0145 let start = startIndex.advancedBy(i)
0146 let end = startIndex.advancedBy(i+sequence.count)
0147 if String(self[start ..< end]) == seqString {
0148 return start
0149 }
0150 }
0151 return nil
0152 }
0153
0154 }
0155
0156 public struct CharacterSetString.swift:59 | return trim(CharacterSet.whitespaceAndNewline) |
String.swift:62 | public func trim(characters: CharacterSet) -> String { |
String.swift:67 | public func trimLeft(characterSet: CharacterSet) -> String { |
String.swift:80 | public func trimRight(characterSet: CharacterSet) -> String { |
String.swift:157 | public static var whitespaceAndNewline: CharacterSet { |
String.swift:161 | public static var digits: CharacterSet { |
String.swift:169 | return CharacterSet(characters: characters, inverted: !isInverted) |
String.swift:168 | public var inverted: CharacterSet { |
: ArrayLiteralConvertible {
0157 public static var whitespaceAndNewlineString.swift:59 | return trim(CharacterSet.whitespaceAndNewline) |
: CharacterSet {
0158 return [" ", "\t", "\r", "\n"]
0159 }
0160
0161 public static var digits: CharacterSet {
0162 return ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]
0163 }
0164
0165 private let charactersString.swift:169 | return CharacterSet(characters: characters, inverted: !isInverted) |
String.swift:173 | self.characters = characters |
String.swift:182 | let contains = characters.contains(character) |
: Set<Character>
0166 private let isInvertedString.swift:169 | return CharacterSet(characters: characters, inverted: !isInverted) |
String.swift:174 | self.isInverted = inverted |
String.swift:183 | return isInverted ? !contains : contains |
: Bool
0167
0168 public var inverted: CharacterSet {
0169 return CharacterSet(characters: characters, inverted: !isInverted)
0170 }
0171
0172 public initString.swift:169 | return CharacterSet(characters: characters, inverted: !isInverted) |
String.swift:178 | self.init(characters: Set(elements)) |
(characters: Set<Character>, inverted: Bool = false) {
0173 self.characters = characters
0174 self.isInverted = inverted
0175 }
0176
0177 public init(arrayLiteral elements: Character...) {
0178 self.init(characters: Set(elements))
0179 }
0180
0181 public func containsString.swift:71 | if !characterSet.contains(character) { |
String.swift:84 | if !characterSet.contains(character) { |
(character: Character) -> Bool {
0182 let contains = characters.contains(character)
0183 return isInverted ? !contains : contains
0184 }
0185 }
0186
0187 extension String {
0188 public func startsWith(prefix: String) -> Bool {
0189 return prefix == String(self.characters.prefix(prefix.characters.count))
0190 }
0191
0192 public func endsWithString.swift:220 | precondition(!endsWith("/") && characters.count > 1) |
String.swift:269 | if stripTrailing && result.endsWith("/") { |
(suffix: String) -> Bool {
0193 return suffix == String(self.characters.suffix(suffix.characters.count))
0194 }
0195
0196 public var dropLastPathComponent: String {
0197 let fixedSelf = fixSlashes()
0198
0199 if fixedSelf == "/" {
0200 return fixedSelf
0201 }
0202
0203 switch fixedSelf.startOfLastPathComponent {
0204
0205 case fixedSelf.startIndex:
0207 return ""
0208
0209 case fixedSelf.startIndex.successor():
0211 return "/"
0212
0213 case let startOfLast:
0215 return String(fixedSelf.characters.prefixUpTo(startOfLast.predecessor()))
0216 }
0217 }
0218
0219 var startOfLastPathComponentString.swift:203 | switch fixedSelf.startOfLastPathComponent { |
: String.CharacterView.Index {
0220 precondition(!endsWith("/") && characters.count > 1)
0221
0222 let characterView = characters
0223 let startPos = characterView.startIndex
0224 let endPosition = characterView.endIndex
0225 var currentPosition = endPosition
0226
0227 while currentPosition > startPos {
0228 let previousPosition = currentPosition.predecessor()
0229 if characterView[previousPosition] == "/" {
0230 break
0231 }
0232 currentPosition = previousPosition
0233 }
0234
0235 return currentPosition
0236 }
0237
0238 func fixSlashesString.swift:197 | let fixedSelf = fixSlashes() |
(compress compress: Bool = true, stripTrailing: Bool = true) -> String {
0239 if self == "/" {
0240 return self
0241 }
0242
0243 var result = self
0244
0245 if compress {
0246 result.withMutableCharacters { characterView in
0247 let startPosition = characterView.startIndex
0248 var endPosition = characterView.endIndex
0249 var currentPosition = startPosition
0250
0251 while currentPosition < endPosition {
0252 if characterView[currentPosition] == "/" {
0253 var afterLastSlashPosition = currentPosition
0254 while afterLastSlashPosition < endPosition && characterView[afterLastSlashPosition] == "/" {
0255 afterLastSlashPosition = afterLastSlashPosition.successor()
0256 }
0257 if afterLastSlashPosition != currentPosition.successor() {
0258 characterView.replaceRange(currentPosition ..< afterLastSlashPosition, with: ["/"])
0259 endPosition = characterView.endIndex
0260 }
0261 currentPosition = afterLastSlashPosition
0262 } else {
0263 currentPosition = currentPosition.successor()
0264 }
0265 }
0266 }
0267 }
0268
0269 if stripTrailing && result.endsWith("/") {
0270 result.removeAtIndex(result.characters.endIndex.predecessor())
0271 }
0272
0273 return result
0274 }
0275 }
0276
0277 extension String {
0278 public init(percentEncoded: String) throws {
0279 struct Error: ErrorType, CustomStringConvertible {
0280 let description: String
0281 }
0282
0283 let spaceCharacter: UInt8 = 32
0284 let percentCharacter: UInt8 = 37
0285 let plusCharacter: UInt8 = 43
0286
0287 var encodedBytes: [UInt8] = [] + percentEncoded.utf8
0288 var decodedBytes: [UInt8] = []
0289 var i = 0
0290
0291 while i < encodedBytes.count {
0292 let currentCharacter = encodedBytes[i]
0293
0294 switch currentCharacter {
0295 case percentCharacter:
0296 let unicodeA = UnicodeScalar(encodedBytes[i + 1])
0297 let unicodeB = UnicodeScalar(encodedBytes[i + 2])
0298
0299 let hexString = "\(unicodeA)\(unicodeB)"
0300
0301
0302
0303 guard let character = Int(hexString, radix: 16) else {
0304 throw Error(description: "Invalid string")
0305 }
0306
0307 decodedBytes.append(UInt8(character))
0308 i += 3
0309
0310 case plusCharacter:
0311 decodedBytes.append(spaceCharacter)
0312 i += 1
0313
0314 default:
0315 decodedBytes.append(currentCharacter)
0316 i += 1
0317 }
0318 }
0319
0320 var string = ""
0321 var decoder = UTF8()
0322 var generator = decodedBytes.generate()
0323 var finished = false
0324
0325 while !finished {
0326 let decodingResult = decoder.decode(&generator)
0327 switch decodingResult {
0328 case .Result(let char): string.append(char)
0329 case .EmptyInput: finished = true
0330 case .Error:
0331 throw Error(description: "UTF-8 decoding failed")
0332 }
0333 }
0334
0335 self.init(string)
0336 }
0337 }