1 // Copyright 2017 Google Inc. All Rights Reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 import Foundation 16 17 // The I/O code below is derived from Apple's swift-protobuf project. 18 // https://github.com/apple/swift-protobuf 19 // BEGIN swift-protobuf derivation 20 21 #if os(Linux) 22 import Glibc 23 #else 24 import Darwin.C 25 #endif 26 27 enum PluginError: Error { 28 /// Raised for any errors reading the input 29 case readFailure 30 } 31 32 // Alias clib's write() so Stdout.write(bytes:) can call it. 33 private let _write = write 34 35 class Stdin { readallnull36 static func readall() throws -> Data { 37 let fd: Int32 = 0 38 let buffSize = 32 39 var buff = [UInt8]() 40 while true { 41 var fragment = [UInt8](repeating: 0, count: buffSize) 42 let count = read(fd, &fragment, buffSize) 43 if count < 0 { 44 throw PluginError.readFailure 45 } 46 if count < buffSize { 47 buff += fragment[0..<count] 48 return Data(bytes: buff) 49 } 50 buff += fragment 51 } 52 } 53 } 54 55 class Stdout { writenull56 static func write(bytes: Data) { 57 bytes.withUnsafeBytes { (p: UnsafePointer<UInt8>) -> () in 58 _ = _write(1, p, bytes.count) 59 } 60 } 61 } 62 63 struct CodePrinter { 64 private(set) var content = "" 65 private var currentIndentDepth = 0 66 private var currentIndent = "" 67 private var atLineStart = true 68 printnull69 mutating func print() { 70 print("") 71 } 72 printnull73 mutating func print(_ text: String...) { 74 for t in text { 75 for c in t.characters { 76 if c == "\n" { 77 content.append(c) 78 atLineStart = true 79 } else { 80 if atLineStart { 81 content.append(currentIndent) 82 atLineStart = false 83 } 84 content.append(c) 85 } 86 } 87 } 88 content.append("\n") 89 atLineStart = true 90 } 91 resetIndentnull92 mutating private func resetIndent() { 93 currentIndent = (0..<currentIndentDepth).map { Int -> String in return " " } .joined(separator:"") 94 } 95 indentnull96 mutating func indent() { 97 currentIndentDepth += 1 98 resetIndent() 99 } outdentnull100 mutating func outdent() { 101 currentIndentDepth -= 1 102 resetIndent() 103 } 104 } 105 106 // END swift-protobuf derivation 107