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