0001    // File.swift
0002    //
0003    // The MIT License (MIT)
0004    //
0005    // Copyright (c) 2015 Zewo
0006    //
0007    // Permission is hereby granted, free of charge, to any person obtaining a copy
0008    // of this software and associated documentation files (the "Software"), to deal
0009    // in the Software without restriction, including without limitation the rights
0010    // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
0011    // copies of the Software, and to permit persons to whom the Software is
0012    // furnished to do so, subject to the following conditions:
0013    //
0014    // The above copyright notice and this permission notice shall be included in all
0015    // copies or substantial portions of the Software.
0016    //
0017    // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
0018    // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0019    // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
0020    // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
0021    // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
0022    // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
0023    // SOFTWARE.
0024    
0025    import CLibvenice
0026    @_exported import Venice
0027    @_exported import Data
0028    @_exported import String
0029    
0030    public var standardInputStream = try! File(fileDescriptor: STDIN_FILENO)
0031    public var standardOutputStream = try! File(fileDescriptor: STDOUT_FILENO)
0032    public var standardErrorStream = try! File(fileDescriptor: STDERR_FILENO)
0033    
0034    public final class File
File.swift:30
public var standardInputStream = try! File(fileDescriptor: STDIN_FILENO)
File.swift:31
public var standardOutputStream = try! File(fileDescriptor: STDOUT_FILENO)
File.swift:32
public var standardErrorStream = try! File(fileDescriptor: STDERR_FILENO)
File.swift:206
extension File {
File.swift:212
extension File {
FileStream.swift:28
    private let file: File
FileStream.swift:38
    public init(file: File, lowWaterMark: Int = 1, highWaterMark: Int = 4096) {
{ 0035 public enum Mode
File.swift:100
	public convenience init(path: String, mode: Mode = .Read) throws {
{ 0036 case Read
File.swift:47
            case .Read: return O_RDONLY
File.swift:100
	public convenience init(path: String, mode: Mode = .Read) throws {
0037 case CreateWrite
File.swift:48
            case .CreateWrite: return (O_WRONLY | O_CREAT | O_EXCL)
0038 case TruncateWrite
File.swift:49
            case .TruncateWrite: return (O_WRONLY | O_CREAT | O_TRUNC)
0039 case AppendWrite
File.swift:50
            case .AppendWrite: return (O_WRONLY | O_CREAT | O_APPEND)
0040 case ReadWrite
File.swift:51
            case .ReadWrite: return (O_RDWR)
0041 case CreateReadWrite
File.swift:52
            case .CreateReadWrite: return (O_RDWR | O_CREAT | O_EXCL)
0042 case TruncateReadWrite
File.swift:53
            case .TruncateReadWrite: return (O_RDWR | O_CREAT | O_TRUNC)
0043 case AppendReadWrite
File.swift:54
            case .AppendReadWrite: return (O_RDWR | O_CREAT | O_APPEND)
0044 0045 var value: Int32 { 0046 switch self { 0047 case .Read: return O_RDONLY 0048 case .CreateWrite: return (O_WRONLY | O_CREAT | O_EXCL) 0049 case .TruncateWrite: return (O_WRONLY | O_CREAT | O_TRUNC) 0050 case .AppendWrite: return (O_WRONLY | O_CREAT | O_APPEND) 0051 case .ReadWrite: return (O_RDWR) 0052 case .CreateReadWrite: return (O_RDWR | O_CREAT | O_EXCL) 0053 case .TruncateReadWrite: return (O_RDWR | O_CREAT | O_TRUNC) 0054 case .AppendReadWrite: return (O_RDWR | O_CREAT | O_APPEND) 0055 } 0056 } 0057 } 0058 0059 private var file
File.swift:64
        let position = Int(filetell(file))
File.swift:70
        let position = Int(fileseek(file, off_t(position)))
File.swift:76
        return fileeof(file) != 0
File.swift:96
        self.file = file
File.swift:110
        if !closed && file != nil {
File.swift:111
            fileclose(file)
File.swift:195
        fileclose(file)
: mfile 0060 public private(set) var closed
File.swift:110
        if !closed && file != nil {
File.swift:174
        if !closed {
File.swift:180
        closed = false
File.swift:185
        closed = true
File.swift:190
        if closed {
File.swift:194
        closed = true
File.swift:200
        if closed {
FileStream.swift:35
        return file.closed
= false 0061 public private(set) var path
File.swift:80
        guard let path = self.path else {
File.swift:102
        self.path = path
: String? = nil 0062 0063 public func tell() throws -> Int { 0064 let position = Int(filetell(file)) 0065 try FileError.assertNoError() 0066 return position 0067 } 0068 0069 public func seek(position: Int) throws -> Int { 0070 let position = Int(fileseek(file, off_t(position))) 0071 try FileError.assertNoError() 0072 return position 0073 } 0074 0075 public var eof
File.swift:159
            if eof {
FileStream.swift:47
            if file.eof {
: Bool { 0076 return fileeof(file) != 0 0077 } 0078 0079 public lazy var fileExtension: String? = { 0080 guard let path = self.path else { 0081 return nil 0082 } 0083 0084 guard let fileExtension = path.split(".").last else { 0085 return nil 0086 } 0087 0088 if fileExtension.split("/").count > 1 { 0089 return nil 0090 } 0091 0092 return fileExtension 0093 }() 0094 0095 init(file: mfile) throws { 0096 self.file = file 0097 try FileError.assertNoError() 0098 } 0099 0100 public convenience init(path: String, mode: Mode = .Read) throws { 0101 try self.init(file: fileopen(path, mode.value, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) 0102 self.path = path 0103 } 0104 0105 public convenience init(fileDescriptor: FileDescriptor) throws { 0106 try self.init(file: fileattach(fileDescriptor)) 0107 } 0108 0109 deinit { 0110 if !closed && file != nil { 0111 fileclose(file) 0112 } 0113 } 0114 0115 public func write
File.swift:207
    public func write(convertible: DataConvertible, flush: Bool = true, deadline: Deadline = never) throws {
(data: Data, flush: Bool = true, deadline: Deadline = never) throws { 0116 try assertNotClosed() 0117 0118 let bytesProcessed = data.withUnsafeBufferPointer { 0119 filewrite(file, $0.baseAddress, $0.count, deadline) 0120 } 0121 0122 try FileError.assertNoSendErrorWithData(data, bytesProcessed: bytesProcessed) 0123 0124 if flush { 0125 try self.flush(deadline) 0126 } 0127 } 0128 0129 public func read
File.swift:141
    public func read(lowWaterMark lowWaterMark: Int, highWaterMark: Int, deadline: Deadline = never) throws -> Data {
File.swift:153
    public func read(deadline deadline: Deadline = never) throws -> Data {
(length length: Int, deadline: Deadline = never) throws -> Data { 0130 try assertNotClosed() 0131 0132 var data = Data.bufferWithSize(length) 0133 let bytesProcessed = data.withUnsafeMutableBufferPointer { 0134 fileread(file, $0.baseAddress, $0.count, deadline) 0135 } 0136 0137 try FileError.assertNoReceiveErrorWithData(data, bytesProcessed: bytesProcessed) 0138 return data.prefix(bytesProcessed) 0139 } 0140 0141 public func read(lowWaterMark lowWaterMark: Int, highWaterMark: Int, deadline: Deadline = never) throws -> Data { 0142 try assertNotClosed() 0143 0144 var data = Data.bufferWithSize(highWaterMark) 0145 let bytesProcessed = data.withUnsafeMutableBufferPointer { 0146 filereadlh(file, $0.baseAddress, lowWaterMark, highWaterMark, deadline) 0147 } 0148 0149 try FileError.assertNoReceiveErrorWithData(data, bytesProcessed: bytesProcessed) 0150 return data.prefix(bytesProcessed) 0151 } 0152 0153 public func read(deadline deadline: Deadline = never) throws -> Data { 0154 var data = Data() 0155 0156 while true { 0157 data += try read(length: 256, deadline: deadline) 0158 0159 if eof { 0160 break 0161 } 0162 } 0163 0164 return data 0165 } 0166 0167 public func flush(deadline: Deadline = never) throws { 0168 try assertNotClosed() 0169 fileflush(file, deadline) 0170 try FileError.assertNoError() 0171 } 0172 0173 public func attach(fileDescriptor: FileDescriptor) throws { 0174 if !closed { 0175 close() 0176 } 0177 0178 file = fileattach(fileDescriptor) 0179 try FileError.assertNoError() 0180 closed = false 0181 } 0182 0183 public func detach() throws -> FileDescriptor { 0184 try assertNotClosed() 0185 closed = true 0186 return filedetach(file) 0187 } 0188 0189 public func close
File.swift:175
            close()
FileStream.swift:48
                file.close()
FileStream.swift:83
        return file.close()
() -> Bool { 0190 if closed { 0191 return false 0192 } 0193 0194 closed = true 0195 fileclose(file) 0196 return true 0197 } 0198 0199 func assertNotClosed
File.swift:116
        try assertNotClosed()
File.swift:130
        try assertNotClosed()
File.swift:142
        try assertNotClosed()
File.swift:168
        try assertNotClosed()
File.swift:184
        try assertNotClosed()
() throws { 0200 if closed { 0201 throw FileError.closedFileError 0202 } 0203 } 0204 } 0205 0206 extension File { 0207 public func write(convertible: DataConvertible, flush: Bool = true, deadline: Deadline = never) throws { 0208 try write(convertible.data, flush: flush, deadline: deadline) 0209 } 0210 } 0211 0212 extension File { 0213 public static func workingDirectory() throws -> String { 0214 var buffer = String.bufferWithSize(Int(MAXNAMLEN)) 0215 errno = 0 0216 let workingDirectory = getcwd(&buffer, buffer.count) 0217 try FileError.assertNoError() 0218 return String.fromCString(workingDirectory)! 0219 } 0220 0221 public static func contentsOfDirectoryAt(path: String) throws -> [String] { 0222 var contents: [String] = [] 0223 0224 let dir = opendir(path) 0225 0226 if dir == nil { 0227 throw FileError.Unknown(description: "Could not open directory at \(path)") 0228 } 0229 0230 defer { 0231 closedir(dir) 0232 } 0233 0234 let excludeNames = [".", ".."] 0235 0236 var entry: UnsafeMutablePointer<dirent> = readdir(dir) 0237 0238 while entry != nil { 0239 if let entryName = withUnsafePointer(&entry.memory.d_name, { (ptr) -> String? in 0240 let int8Ptr = unsafeBitCast(ptr, UnsafePointer<Int8>.self) 0241 return String.fromCString(int8Ptr) 0242 }) { 0243 0244 // TODO: `entryName` should be limited in length to `entry.memory.d_namlen`. 0245 if !excludeNames.contains(entryName) { 0246 contents.append(entryName) 0247 } 0248 } 0249 0250 entry = readdir(dir) 0251 } 0252 0253 return contents 0254 } 0255 0256 public static func fileExistsAt
File.swift:288
            let (fileExists, isDirectory) = fileExistsAt(path)
File.swift:292
                if fileExistsAt(path).fileExists {
(path: String) -> (fileExists: Bool, isDirectory: Bool) { 0257 var s = stat() 0258 var isDirectory = false 0259 0260 if lstat(path, &s) >= 0 { 0261 if (s.st_mode & S_IFMT) == S_IFLNK { 0262 if stat(path, &s) >= 0 { 0263 isDirectory = (s.st_mode & S_IFMT) == S_IFDIR 0264 } else { 0265 return (false, isDirectory) 0266 } 0267 } else { 0268 isDirectory = (s.st_mode & S_IFMT) == S_IFDIR 0269 } 0270 0271 // don't chase the link for this magic case -- we might be /Net/foo 0272 // which is a symlink to /private/Net/foo which is not yet mounted... 0273 if (s.st_mode & S_IFMT) == S_IFLNK { 0274 if (s.st_mode & S_ISVTX) == S_ISVTX { 0275 return (true, isDirectory) 0276 } 0277 // chase the link; too bad if it is a slink to /Net/foo 0278 stat(path, &s) >= 0 0279 } 0280 } else { 0281 return (false, isDirectory) 0282 } 0283 return (true, isDirectory) 0284 } 0285 0286 public static func createDirectoryAt(path: String, withIntermediateDirectories createIntermediates: Bool = false) throws { 0287 if createIntermediates { 0288 let (fileExists, isDirectory) = fileExistsAt(path) 0289 if fileExists { 0290 let parent = path.dropLastPathComponent 0291 0292 if fileExistsAt(path).fileExists { 0293 try createDirectoryAt(parent, withIntermediateDirectories: true) 0294 } 0295 mkdir(path, S_IRWXU | S_IRWXG | S_IRWXO) 0296 try FileError.assertNoError() 0297 } else if isDirectory { 0298 return 0299 } else { 0300 throw FileError.FileExists(description: "File exists") 0301 } 0302 } else { 0303 mkdir(path, S_IRWXU | S_IRWXG | S_IRWXO) 0304 try FileError.assertNoError() 0305 } 0306 } 0307 0308 public static func removeItemAt(path: String) throws { 0309 if rmdir(path) == 0 { 0310 return 0311 } else if errno == ENOTDIR { 0312 unlink(path) 0313 } 0314 try FileError.assertNoError() 0315 } 0316 } 0317