Răsfoiți Sursa

Added "Scopes" DSL.

Damian Kołakowski 10 ani în urmă
părinte
comite
d972ecdc07

+ 28 - 0
Sources/Swifter/DemoServer.swift

@@ -16,6 +16,7 @@ public func demoServer(_ publicDir: String) -> HttpServer {
     server["/public/:path"] = HttpHandlers.shareFilesFromDirectory(publicDir)
 
     server["/"] = { r in
+        
         var listPage = "Available services:<br><ul>"
         for services in server.routes {
             if services.isEmpty {
@@ -121,5 +122,32 @@ public func demoServer(_ publicDir: String) -> HttpServer {
         return .MovedPermanently("https://github.com/404")
     }
     
+    server.GET["/scope"] = HttpHandlers.scopes {
+        html {
+            head {
+                stylesheet {
+                    href = "theme.cssśļ"
+                }
+            }
+            body {
+                header {
+                    title { inner = "My Web Page" }
+                }
+                table {
+                    for (index, item) in ["Item1", "Item2"].enumerated() {
+                        tr {
+                            td {
+                                div { inner = "\(index)" }
+                            }
+                            td {
+                                div { inner = item }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+    
     return server
 }

+ 146 - 0
Sources/Swifter/HttpHandlers+Scopes.swift

@@ -0,0 +1,146 @@
+//
+//  HttpHandlers+Scopes.swift
+//  Swifter
+//
+//  Copyright © 2014-2016 Damian Kołakowski. All rights reserved.
+//
+
+import Foundation
+
+extension HttpHandlers {
+    
+    public class func scopes(_ scope: Scope) -> ((HttpRequest) -> HttpResponse) {
+        return { r in
+            bufferToken = ""
+            scope()
+            return .RAW(200, "OK", ["Content-Type": "text/html"], { $0.write([UInt8](("<!DOCTYPE html>" + bufferToken).utf8)) })
+        }
+    }
+}
+
+public var src    : String? = nil
+public var style  : String? = nil
+public var width  : String? = nil
+public var height : String? = nil
+public var inner  : String? = nil
+public var ref    : String? = nil
+public var href   : String? = nil
+public var type   : String? = nil
+
+private func scopesPushAttributes() {
+    attributesStack.append(["src": src, "style": style, "width": width, "height": height, "inner": inner, "ref": ref, "href": href, "type": type])
+    src = nil
+    style = nil
+    width = nil
+    height = nil
+    inner = nil
+    ref = nil
+    href = nil
+    type = nil
+}
+
+private func scopesPopAttributes() {
+    if let last = attributesStack.last {
+        src = last["src"]!
+        style = last["style"]!
+        width = last["width"]!
+        height = last["height"]!
+        inner = last["inner"]!
+        ref = last["ref"]!
+        href = last["href"]!
+        type = last["type"]!
+        attributesStack.removeLast()
+    }
+}
+
+public var attributesStack = [[String: String?]]()
+
+var bufferToken = ""
+
+public typealias Scope = (Void) -> Void
+
+public func element( _ node: String, attrs: [String: String?] = [:], scope: Scope) {
+    
+    scopesPushAttributes()
+    
+    bufferToken = bufferToken + "<" + node
+    
+    var bufferClone = bufferToken
+    bufferToken = ""
+    
+    scope()
+    
+    var mergedAttributes = [String: String?]()
+    for item in ["src": src, "style": style, "width": width, "height": height, "ref": ref, "href": href, "type": type].enumerated() {
+        mergedAttributes.updateValue(item.element.value, forKey: item.element.key)
+    }
+    for item in attrs.enumerated() {
+        mergedAttributes.updateValue(item.element.value, forKey: item.element.key)
+    }
+    
+    bufferClone = bufferClone + mergedAttributes.reduce("") {
+        if let value = $0.1.value {
+            return $0.0 + " \($0.1.key)=\"\(value)\""
+        } else {
+            return $0.0
+        }
+    }
+    
+    bufferToken = bufferClone + ">" + (inner ?? bufferToken) + "</" + node + ">"
+    
+    scopesPopAttributes()
+}
+
+public func a(scope: Scope) { element("a", scope: scope) }
+public func p(scope: Scope) { element("p", scope: scope) }
+public func u(scope: Scope) { element("u", scope: scope) }
+public func b(scope: Scope) { element("b", scope: scope) }
+
+public func br(scope: Scope) { element("br", scope: scope) }
+public func hr(scope: Scope) { element("hr", scope: scope) }
+public func h1(scope: Scope) { element("h1", scope: scope) }
+public func h2(scope: Scope) { element("h2", scope: scope) }
+public func h3(scope: Scope) { element("h3", scope: scope) }
+public func h4(scope: Scope) { element("h4", scope: scope) }
+public func h5(scope: Scope) { element("h5", scope: scope) }
+public func td(scope: Scope) { element("td", scope: scope) }
+public func tr(scope: Scope) { element("tr", scope: scope) }
+public func li(scope: Scope) { element("li", scope: scope) }
+public func ul(scope: Scope) { element("ul", scope: scope) }
+
+public func div(scope: Scope) { element("div", scope: scope) }
+public func img(scope: Scope) { element("img", scope: scope) }
+public func big(scope: Scope) { element("big", scope: scope) }
+public func nav(scope: Scope) { element("nav", scope: scope) }
+
+public func html(scope: Scope) { element("html", scope: scope) }
+public func meta(scope: Scope) { element("meta", scope: scope) }
+public func head(scope: Scope) { element("head", scope: scope) }
+public func body(scope: Scope) { element("body", scope: scope) }
+public func span(scope: Scope) { element("span", scope: scope) }
+public func form(scope: Scope) { element("form", scope: scope) }
+public func link(scope: Scope) { element("link", scope: scope) }
+
+public func table(scope: Scope) { element("table", scope: scope) }
+public func tbody(scope: Scope) { element("tbody", scope: scope) }
+public func small(scope: Scope) { element("small", scope: scope) }
+public func input(scope: Scope) { element("input", scope: scope) }
+public func label(scope: Scope) { element("label", scope: scope) }
+public func video(scope: Scope) { element("video", scope: scope) }
+public func style(scope: Scope) { element("style", scope: scope) }
+public func title(scope: Scope) { element("title", scope: scope) }
+
+public func header(scope: Scope) { element("header", scope: scope) }
+public func footer(scope: Scope) { element("footer", scope: scope) }
+public func iframe(scope: Scope) { element("iframe", scope: scope) }
+public func strong(scope: Scope) { element("strong", scope: scope) }
+public func option(scope: Scope) { element("option", scope: scope) }
+public func center(scope: Scope) { element("center", scope: scope) }
+public func object(scope: Scope) { element("object", scope: scope) }
+
+public func script(scope: Scope) { element("script", scope: scope) }
+public func canvas(scope: Scope) { element("canvas", scope: scope) }
+
+public func textarea(scope: Scope) { element("textarea", scope: scope) }
+
+public func stylesheet(scope: Scope) { element("link", attrs: ["rel": "stylesheet", "type": "text/css"], scope: scope) }

+ 2 - 0
Sources/Swifter/HttpServer.swift

@@ -7,6 +7,8 @@
 
 import Foundation
 
+typealias Elo = ((HttpRequest) -> HttpResponse)
+
 public class HttpServer: HttpServerIO {
     
     public static let VERSION = "1.1.3"

+ 1 - 0
Sources/Swifter/HttpServerIO.swift

@@ -101,6 +101,7 @@ public class HttpServerIO {
         
         func write(_ file: File) {
             var offset: off_t = 0
+            
             let _ = sendfile(fileno(file.pointer), socket.socketFileDescriptor, 0, &offset, nil, 0)
         }
         

+ 10 - 4
Sources/Swifter/Process.swift

@@ -9,14 +9,20 @@ import Foundation
 
 public class Process {
     
-    public static var PID: Int { return Int(getpid()) }
+    public static var PID: Int {
+        return Int(getpid())
+    }
     
-    public typealias SignalCallback = (Int32) -> Void
+    public static var TID: UInt64 {
+        var tid: __uint64_t = 0
+        pthread_threadid_np(nil, &tid);
+        return UInt64(tid)
+    }
     
-    private static var signalsWatchers = [SignalCallback]()
+    private static var signalsWatchers = Array<(Int32) -> Void>()
     private static var signalsObserved = false
     
-    public static func watchSignals(_ callback: SignalCallback) {
+    public static func watchSignals(_ callback: (Int32) -> Void) {
         if !signalsObserved {
             [SIGTERM, SIGHUP, SIGSTOP, SIGINT].forEach { item in
                 signal(item) {

+ 6 - 0
XCode/Swifter.xcodeproj/project.pbxproj

@@ -75,6 +75,8 @@
 		7C31963A1CC2C68F00DF5406 /* String+SHA1.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C3195FA1CC2C68F00DF5406 /* String+SHA1.swift */; };
 		7C31963B1CC2C68F00DF5406 /* String+SHA1.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C3195FA1CC2C68F00DF5406 /* String+SHA1.swift */; };
 		7C31963C1CC2C68F00DF5406 /* String+SHA1.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C3195FA1CC2C68F00DF5406 /* String+SHA1.swift */; };
+		7C3945641D256FDA003EEABA /* HttpHandlers+Scopes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C3945631D256FDA003EEABA /* HttpHandlers+Scopes.swift */; };
+		7C3945651D256FDA003EEABA /* HttpHandlers+Scopes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C3945631D256FDA003EEABA /* HttpHandlers+Scopes.swift */; };
 		7C4785E91C71D15600A9FE73 /* SwifterTestsWebSocketSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C4785E81C71D15600A9FE73 /* SwifterTestsWebSocketSession.swift */; };
 		7C4785EA1C71D15600A9FE73 /* SwifterTestsWebSocketSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C4785E81C71D15600A9FE73 /* SwifterTestsWebSocketSession.swift */; };
 		7C5915221C92A99300D884BC /* SwifterTestsReflection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C5915211C92A99300D884BC /* SwifterTestsReflection.swift */; };
@@ -196,6 +198,7 @@
 		7C3195F81CC2C68F00DF5406 /* String+BASE64.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "String+BASE64.swift"; sourceTree = "<group>"; };
 		7C3195F91CC2C68F00DF5406 /* String+Misc.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "String+Misc.swift"; sourceTree = "<group>"; };
 		7C3195FA1CC2C68F00DF5406 /* String+SHA1.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "String+SHA1.swift"; sourceTree = "<group>"; };
+		7C3945631D256FDA003EEABA /* HttpHandlers+Scopes.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "HttpHandlers+Scopes.swift"; sourceTree = "<group>"; };
 		7C4785E81C71D15600A9FE73 /* SwifterTestsWebSocketSession.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SwifterTestsWebSocketSession.swift; sourceTree = "<group>"; };
 		7C5915211C92A99300D884BC /* SwifterTestsReflection.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SwifterTestsReflection.swift; sourceTree = "<group>"; };
 		7C6B57EA1CA6C3AA0042655C /* SwifterTestsHttpRouter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SwifterTestsHttpRouter.swift; sourceTree = "<group>"; };
@@ -344,6 +347,7 @@
 				7C3195E81CC2C68F00DF5406 /* DemoServer.swift */,
 				7C3195E91CC2C68F00DF5406 /* File.swift */,
 				7C3195EA1CC2C68F00DF5406 /* HttpHandlers+Files.swift */,
+				7C3945631D256FDA003EEABA /* HttpHandlers+Scopes.swift */,
 				7C3195EB1CC2C68F00DF5406 /* HttpHandlers+WebSockets.swift */,
 				7C3195EC1CC2C68F00DF5406 /* HttpHandlers.swift */,
 				7C3195ED1CC2C68F00DF5406 /* HttpParser.swift */,
@@ -798,6 +802,7 @@
 				7C3196071CC2C68F00DF5406 /* File.swift in Sources */,
 				7C3196041CC2C68F00DF5406 /* DemoServer.swift in Sources */,
 				7C3196281CC2C68F00DF5406 /* Reflection.swift in Sources */,
+				7C3945641D256FDA003EEABA /* HttpHandlers+Scopes.swift in Sources */,
 				7C3196161CC2C68F00DF5406 /* HttpRequest.swift in Sources */,
 				7C3196221CC2C68F00DF5406 /* HttpServerIO.swift in Sources */,
 				7C3196101CC2C68F00DF5406 /* HttpHandlers.swift in Sources */,
@@ -825,6 +830,7 @@
 				7C3196081CC2C68F00DF5406 /* File.swift in Sources */,
 				7C3196051CC2C68F00DF5406 /* DemoServer.swift in Sources */,
 				7C3196291CC2C68F00DF5406 /* Reflection.swift in Sources */,
+				7C3945651D256FDA003EEABA /* HttpHandlers+Scopes.swift in Sources */,
 				7C3196171CC2C68F00DF5406 /* HttpRequest.swift in Sources */,
 				7C3196231CC2C68F00DF5406 /* HttpServerIO.swift in Sources */,
 				7C3196111CC2C68F00DF5406 /* HttpHandlers.swift in Sources */,