精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

用Swift來寫命令行程序

移動開發(fā) iOS
試試自己動手 現(xiàn)在的翻譯程序還有很多可以優(yōu)化的地方。下面是一個你可以嘗試的列表: 接受命令行參數(shù)來設置默認的源語言和目標語言 接受命令行參數(shù)來實現(xiàn)非交互模式 添加 swap 命令來交換源語言和目標語言 添加 help 命令 整合 from 命令和 to 命令。實現(xiàn)一行可以同時設置兩者, 比如 from en to es 現(xiàn)在當輸入 from 命令和 to 命令時,沒有同時輸入對應的語言時會崩潰,修復這個BUG 實現(xiàn)對轉義符 \ 的處理,實現(xiàn)程序的“命令”也可以被翻譯(比如退出命令:quit) 通過 localizedDescript

這是探索 Swift 寫 Linux 程序的系列文章中的一篇。

在上一個例子中,我們通過組合使用 popen 和 wget 命令來調(diào)用 自然語言翻譯服務 ,來實現(xiàn)像 Google 翻譯 那樣的翻譯功能。本文的程序會基于之前我們已經(jīng)完成的工作來進行。但與之前每次執(zhí)行都只能翻譯一句話所不同的是,這次我們要實現(xiàn)一個具備交互功能的 shell 程序,來翻譯在控制臺輸入的每一句話。像下面的截圖一樣:

翻譯程序會顯示它接受什么語言(源語言)以及翻譯的目標語言。比如:

en->es 英語翻譯為西班牙語
es->it 西班牙語翻譯為意大利語
it->ru 意大利語翻譯為俄羅斯語

翻譯程序默認是 en->es ,并提供了兩個命令: to 和 from 來實現(xiàn)語言的切換。比如,輸入 to es 將會把翻譯的目標語言設置為西班牙語。輸入 quit 可以退出程序。

如果用戶輸入的字符串不是命令的話,翻譯程序會把輸入逐字地發(fā)送到翻譯的 web 服務。然后把返回的結果打印出來。
需要注意的幾點

如果你是系統(tǒng)或者運維程序員,并且以前也沒接觸過 Swift 的話,下面是一些你在代碼里需要注意的事情。我想你會發(fā)現(xiàn) Swift 為兩種類型的工程師都提供了很多有用的特性,并且會成為 Linux 開發(fā)體系中一股很受歡迎的新力量。

let variable = value 常量賦值
元組(tuples)
switch-case 支持字符串
switch-case 使用時必須包含所有情況(邏輯完備性)
計算型 屬性
import Glibc 可以導入標準的 C 函數(shù)
guard 語句
可以使用 NSThread 和 NSNotificationCenter 這些蘋果的 Foundation 框架中的類。
在不同的線程或不同的對象里通過發(fā)送消息來觸發(fā)特定代碼的執(zhí)行

程序設計

我們的翻譯程序可以拆分成一個主程序、兩個類以及一個 globals.swift 文件。如果你打算跟著做,那你應該使用 Swift 的包管理器 ,然后調(diào)整你的目錄結構為下面這樣:

  1. translator/Sources/main.swift  
  2.           /Sources/CommandInterpreter.swift  
  3.           /Sources/...  
  4.           /Package.swift 

main.swift 文件是 Swift 應用程序的入口并且應該是唯一一個包含可執(zhí)行代碼的文件(在這里,像「變量賦值」,或者「聲明一個類」不屬于「可執(zhí)行的代碼」)。

main.swift :

  1. import Foundation  
  2. import Glibc  
  3.    
  4. let interpreter = CommandInterpreter()  
  5. let translator  = Translator()  
  6.    
  7. // Listen for events to translate  
  8. nc.addObserverForName(INPUT_NOTIFICATION, object:nil, queue:nil) {  
  9.   (_) in  
  10.   let tc = translationCommand 
  11.   translator.translate(tc.text, from:tc.from, to:tc.to){  
  12.     translation, error in  
  13.     guard error == nil && translation != nil else {  
  14.       print("Translation failure:  \(error!.code)")  
  15.       return  
  16.     }  
  17.     print(translation!)  
  18.   }  
  19. }  
  20.    
  21. interpreter.start()  
  22.    
  23. select(0, nil, nil, nil, nil) 

上面的代碼表示我們的程序不接受命令行參數(shù)。具體的流程說明:

分別創(chuàng)建 CommandInterpreter 和 Translator 類的實例
為 InputNotification 通知添加觀察者(這里用到的常量 INPUT_NOTIFICATION 常量定義在 globals.swift )
添加當收到通知的時候要執(zhí)行的代碼
調(diào)用 Interpreter 類實例的 start 方法
調(diào)用 select 來實現(xiàn)當程序有其他線程在運行的時候,鎖定主線程。(譯注:也就是防止主線程提前結束)

CommandInterpreter 類

CommandInterpreter 類主要負責從終端讀入輸入的字符串,并且分析輸入的類型并分別進行處理。考慮到你可能剛接觸 Swift,我在代碼里對涉及到語言特性的地方進行了注釋。

  1. // Import statements  
  2. import Foundation  
  3. import Glibc  
  4.    
  5. // Enumerations  
  6. enum CommandType {  
  7. case None  
  8. case Translate  
  9. case SetFrom  
  10. case SetTo  
  11. case Quit  
  12. }  
  13.    
  14. // Structs  
  15. struct Command {  
  16.   var type:CommandType  
  17.   var data:String  
  18. }  
  19.    
  20. // Classes  
  21. class CommandInterpreter {  
  22.    
  23.   // Read-only computed property  
  24.   var prompt:String {  
  25.     return "\(translationCommand.from)->\(translationCommand.to)"  
  26.   }  
  27.    
  28.   // Class constant  
  29.   let delim:Character = "\n" 
  30.    
  31.   init() {  
  32.   }  
  33.    
  34.   func start() {  
  35.     let readThread = NSThread(){  
  36.       var input:String    = "" 
  37.         
  38.       print("To set input language, type 'from LANG'")  
  39.       print("To set output language, type 'to LANG'")  
  40.       print("Type 'quit' to exit")  
  41.       self.displayPrompt()  
  42.    
  43.       while true {  
  44.         let c = Character(UnicodeScalar(UInt32(fgetc(stdin))))  
  45.         if c == self.delim {  
  46.           let command = self.parseInput(input)  
  47.           self.doCommand(command)  
  48.           input = "" // Clear input  
  49.           self.displayPrompt()  
  50.         } else {  
  51.           input.append(c)  
  52.         }  
  53.       }  
  54.     }  
  55.       
  56.     readThread.start()  
  57.   }  
  58.    
  59.   func displayPrompt() {  
  60.     print("\(self.prompt):  ", terminator:"")  
  61.   }  
  62.    
  63.   func parseInput(input:String) -> Command {  
  64.     var commandType:CommandType  
  65.     var commandData:String = "" 
  66.       
  67.     // Splitting a string  
  68.     let tokens = input.characters.split{$0 == " "}.map(String.init)  
  69.    
  70.     // guard statement to validate that there are tokens  
  71.     guard tokens.count > 0 else {  
  72.       return Command(type:CommandType.None, data:"")  
  73.     }  
  74.    
  75.     switch tokens[0] {  
  76.     case "quit":  
  77.       commandType = .Quit  
  78.     case "from":  
  79.       commandType = .SetFrom  
  80.       commandData = tokens[1]  
  81.     case "to":  
  82.       commandType = .SetTo  
  83.       commandData = tokens[1]  
  84.     default:  
  85.       commandType = .Translate  
  86.       commandData = input 
  87.     }  
  88.     return Command(type:commandType,data:commandData)  
  89.   }  
  90.    
  91.   func doCommand(command:Command) {  
  92.     switch command.type {  
  93.     case .Quit:  
  94.       exit(0)  
  95.     case .SetFrom:  
  96.       translationCommand.from = command.data  
  97.     case .SetTo:  
  98.       translationCommand.to   = command.data  
  99.     case .Translate:  
  100.       translationCommand.text = command.data  
  101.       nc.postNotificationName(INPUT_NOTIFICATION, object:nil)     
  102.     case .None:  
  103.       break  
  104.     }  
  105.   }  

CommandInterpreter 類的實現(xiàn)邏輯非常直觀。當 start 函數(shù)被調(diào)用的時候,通過 NSThread 來創(chuàng)建一個線程,線程中再通過 block fgetc 的回調(diào)參數(shù) stdin 來獲取終端的輸入。當遇到換行符 RETURN (用戶按了回車)后,輸入的字符串會被解析并映射成一個 Command 對象。然后傳遞給 doCommand 函數(shù)進行剩下的處理。

我們的 doCommand 函數(shù)就是一個簡單的 switch-case 語句。對于 .Quit 命令則就簡單調(diào)用 exit(0) 來終止程序。 .SetFrom 和 .SetTo 命令的功能是顯而易見的。當遇到 .Translate 命令時,F(xiàn)oundation 的消息系統(tǒng)就派上用場了。 doCommand 函數(shù)自己并不完成任何的翻譯功能,它只是簡單的 發(fā)送 一個應用程序級別的消息,也就是 InputNotification 。任何監(jiān)聽這個消息的代碼都會被調(diào)用(比如我們之前的主線程):

  1. // Listen for events to translate  
  2. nc.addObserverForName(INPUT_NOTIFICATION, object:nil, queue:nil) {  
  3.   (_) in  
  4.   let tc = translationCommand 
  5.   translator.translate(tc.text, from:tc.from, to:tc.to){  
  6.     translation, error in  
  7.     guard error == nil && translation != nil else {  
  8.       print("Translation failure:  \(error!.code)")  
  9.       return  
  10.     }  
  11.     print(translation!)  
  12.   }  

我在 這篇文章 中提到,在對 NSNotification 的 userInfo 字典做類型轉換時會有一個 SILGen 的閃退 crash,在這里我們用一個叫做 translationCommand 的全局變量來繞過這個 crash。在這段代碼里:

為了代碼的簡潔,把 translationCommand 的內(nèi)容賦值給 tc
調(diào)用 Translator 對象的 translate 方法,并傳入相關的參數(shù)
實現(xiàn)翻譯完成后的回調(diào)
用一個 Swift 漂亮的 guard 語句來檢測是否有錯并返回
打印出翻譯的文本

Translator

Translator 類最開始是在 這篇文章 中介紹的,我們在這里直接重用:

  1. import Glibc  
  2. import Foundation  
  3. import CcURL  
  4. import CJSONC  
  5.    
  6. class Translator {  
  7.    
  8.   let BUFSIZE = 1024 
  9.    
  10.   init() {  
  11.   }  
  12.    
  13.   func translate(text:String, from:String, to:String,  
  14.                         completion:(translation:String?, error:NSError?) -> Void) {  
  15.    
  16.     let curl = curl_easy_init()  
  17.    
  18.     guard curl != nil else {  
  19.       completion(translation:nil,  
  20.                  error:NSError(domain:"translator", code:1, userInfo:nil))  
  21.       return  
  22.     }  
  23.    
  24.     let escapedText = curl_easy_escape(curl, text, Int32(strlen(text)))  
  25.    
  26.     guard escapedText != nil else {  
  27.       completion(translation:nil,  
  28.                  error:NSError(domain:"translator", code:2, userInfo:nil))  
  29.       return  
  30.     }  
  31.       
  32.     let langPair = from + "%7c" + to  
  33.     let wgetCommand = "wget -qO- http://api.mymemory.translated.net/get\\?q\\=" + String.fromCString(escapedText)! + "\\&langpair\\=" + langPair  
  34.       
  35.     let pp      = popen(wgetCommand, "r")  
  36.     var buf     = [CChar](count:BUFSIZE, repeatedValue:CChar(0))  
  37.       
  38.     var response:String = "" 
  39.     while fgets(&buf, Int32(BUFSIZE), pp) != nil {  
  40.       responseresponse = response + String.fromCString(buf)!  
  41.     }  
  42.       
  43.     let translation = getTranslatedText(response)  
  44.    
  45.     guard translation.error == nil else {  
  46.       completion(translation:nil, error:translation.error)  
  47.       return  
  48.     }  
  49.    
  50.     completion(translation:translation.translation, error:nil)  
  51.   }  
  52.    
  53.   private func getTranslatedText(jsonString:String) -> (error:NSError?, translation:String?) {  
  54.    
  55.     let obj = json_tokener_parse(jsonString)  
  56.    
  57.     guard obj != nil else {  
  58.       return (NSError(domain:"translator", code:3, userInfo:nil),  
  59.              nil)  
  60.     }  
  61.    
  62.     let responseData = json_object_object_get(obj, "responseData")  
  63.    
  64.     guard responseData != nil else {  
  65.       return (NSError(domain:"translator", code:3, userInfo:nil),  
  66.               nil)  
  67.     }  
  68.    
  69.     let translatedTextObj = json_object_object_get(responseData,  
  70.                                                    "translatedText")  
  71.    
  72.     guard translatedTextObj != nil else {  
  73.       return (NSError(domain:"translator", code:3, userInfo:nil),  
  74.               nil)  
  75.     }  
  76.    
  77.     let translatedTextStr = json_object_get_string(translatedTextObj)  
  78.    
  79.     return (nil, String.fromCString(translatedTextStr)!)  
  80.              
  81.   }  
  82.    

整合各個部分

要把上面介紹的組件結合到一起,我們還需要創(chuàng)建額外的兩個文件: globals.swift 和 Package.swift 。

globals.swift :

  1.  
  2.  
  3. import Foundation  
  4.    
  5. let INPUT_NOTIFICATION   = "InputNotification" 
  6. let nc = NSNotificationCenter.defaultCenter()  
  7.    
  8. struct TranslationCommand {  
  9.   var from:String  
  10.   var to:String  
  11.   var text:String  
  12. }  
  13.    
  14. var translationCommand:TranslationCommand = TranslationCommand(from:"en",  
  15.                                                                to:"es",  
  16.                                                                text:"")  
  17.  
  18. Package.swift :  
  19.  
  20. import PackageDescription  
  21.    
  22. let package = Package(  
  23.   name:  "translator",  
  24.   dependencies: [  
  25.     .Package(url:  "https://github.com/iachievedit/CJSONC", majorVersion: 1),  
  26.     .Package(url:  "https://github.com/PureSwift/CcURL", majorVersion: 1)  
  27.   ]  

如果一切都配置正確的話,最后執(zhí)行 swift build ,一個極具特色的翻譯程序就完成了。

  1. swift build  
  2. Cloning https://github.com/iachievedit/CJSONC  
  3. Using version 1.0.0 of package CJSONC  
  4. Cloning https://github.com/PureSwift/CcURL  
  5. Using version 1.0.0 of package CcURL  
  6. Compiling Swift Module 'translator' (4 sources)  
  7. Linking Executable:  .build/debug/translator 

試試自己動手

現(xiàn)在的翻譯程序還有很多可以優(yōu)化的地方。下面是一個你可以嘗試的列表:

  • 接受命令行參數(shù)來設置默認的源語言和目標語言
  • 接受命令行參數(shù)來實現(xiàn)非交互模式
  • 添加 swap 命令來交換源語言和目標語言
  • 添加 help 命令
  • 整合 from 命令和 to 命令。實現(xiàn)一行可以同時設置兩者, 比如 from en to es
  • 現(xiàn)在當輸入 from 命令和 to 命令時,沒有同時輸入對應的語言時會崩潰,修復這個BUG
  • 實現(xiàn)對轉義符 \ 的處理,實現(xiàn)程序的“命令”也可以被翻譯(比如退出命令:quit)
  • 通過 localizedDescription 對錯誤提示添加本地化的支持
  • 在 Translator 類中實現(xiàn)但有錯誤發(fā)生時,通過 throws 來處理異常

結束語

試試自己動手

現(xiàn)在的翻譯程序還有很多可以優(yōu)化的地方。下面是一個你可以嘗試的列表:

  • 接受命令行參數(shù)來設置默認的源語言和目標語言
  • 接受命令行參數(shù)來實現(xiàn)非交互模式
  • 添加 swap 命令來交換源語言和目標語言
  • 添加 help 命令
  • 整合 from 命令和 to 命令。實現(xiàn)一行可以同時設置兩者, 比如 from en to es
  • 現(xiàn)在當輸入 from 命令和 to 命令時,沒有同時輸入對應的語言時會崩潰,修復這個BUG
  • 實現(xiàn)對轉義符 \ 的處理,實現(xiàn)程序的“命令”也可以被翻譯(比如退出命令:quit)
  • 通過 localizedDescription 對錯誤提示添加本地化的支持
  • Translator 類中實現(xiàn)但有錯誤發(fā)生時,通過 throws 來處理異常

結束語

我從來不掩飾我是一個狂熱的 Swift 愛好者,我堅信它很可能既能像 Perl、Python 和 Ruby 這樣語言一樣出色的完成運維工作,也能像 C、C++ 和 Java 一樣出色的完成系統(tǒng)編程的任務。我知道現(xiàn)在和那些個單文件腳本語言相比,Swift 比較蛋疼的一點就是必須得編譯成二進制文件。我真誠的希望這一點能夠改善,這樣我就能不再關注語言層面的東西而是去做一些新,酷酷的東西。

我真誠的希望這一點能夠改善,這樣我就能不再關注語言層面的東西而是去做一些新,酷酷的東西。

責任編輯:陳琳 來源: SwiftGG
相關推薦

2010-07-15 10:58:23

Perl命令行程序

2023-03-31 08:44:55

Go開發(fā)命令

2019-04-16 06:50:34

2025-08-26 03:00:00

2015-07-15 10:32:44

Node.js命令行程序

2022-09-23 09:50:45

Python

2022-09-27 13:07:41

clickPython命令行

2020-02-13 10:57:59

Python數(shù)據(jù)設計

2022-10-26 09:02:28

SourcerySwift

2022-02-08 17:19:05

Linux命令grep

2019-12-09 09:23:04

Linux命令sort

2018-05-04 09:15:35

PythonPlumbum命令行

2022-02-08 13:24:49

LinuxLinux命令

2009-07-14 14:03:56

Swing程序

2010-03-16 12:16:23

Python小程序

2010-03-24 14:14:42

Python GUI

2020-12-11 06:44:16

命令行工具開發(fā)

2020-12-10 16:16:08

工具代碼開發(fā)

2014-02-12 10:11:08

掃描病毒掃描Clam Antivi

2010-07-26 09:14:22

Perl命令行
點贊
收藏

51CTO技術棧公眾號

九色丨蝌蚪丨成人| 亚洲不卡的av| av电影院在线看| 成人一区二区三区视频在线观看| 欧美激情视频在线观看| 亚洲精品无码一区二区| 一本大道色婷婷在线| 国产视频在线观看一区二区三区| 国产精品十八以下禁看| 久久99久久久| 欧美极度另类| 国产精品毛片大码女人| 不卡日韩av| 国产精品久免费的黄网站| 久久精品国产68国产精品亚洲| 欧美精品色综合| 人人妻人人澡人人爽欧美一区双 | 国产成人一区二区三区影院| 欧美三级在线播放| 国产精品www在线观看| av在线之家电影网站| 亚洲日韩视频| 日韩一区二区三区在线观看 | 亚洲这里只有精品| 欧美家庭影院| 中文字幕不卡的av| 国产一级精品aaaaa看| 国产又粗又长又硬| 久久大胆人体视频| 91精品午夜视频| 亚洲欧洲精品在线| 神宫寺奈绪一区二区三区| 麻豆精品久久精品色综合| 91精品国产91久久久久福利| 日韩在线一卡二卡| 国产精品午夜一区二区三区| 日韩精品一区在线| 亚洲一区日韩精品| 浪潮色综合久久天堂| 亚洲成在人线免费| 4444在线观看| 黄色网在线播放| 中文字幕第一区综合| 欧美日韩在线高清| 亚洲av成人精品一区二区三区在线播放 | 国产精品粉嫩| 午夜精品久久久久久不卡8050| 中文字幕一区二区三区四区五区六区| 你懂的在线播放| av男人天堂一区| 久久久这里只有精品视频| 亚洲一级理论片| 国产尤物久久久| 国产婷婷色综合av蜜臀av| 韩国一区二区av| 51精品视频| 午夜成人免费视频| 老太脱裤让老头玩ⅹxxxx| 久久青青色综合| 亚洲综合男人的天堂| 天堂av在线中文| 97caopor国产在线视频| jiyouzz国产精品久久| 97netav| 亚洲精品久久久久久无码色欲四季 | 国产欧美久久久| 精品一区二区国语对白| 国产精品一区二区久久国产| 91免费公开视频| 看亚洲a级一级毛片| 欧美肥胖老妇做爰| 邪恶网站在线观看| 高清一区二区| 欧美变态口味重另类| 亚洲一区和二区| 都市激情亚洲欧美| 日韩电影免费在线观看中文字幕| 国产一级二级在线观看| 国产一区二区三区电影在线观看| 一区二区在线视频播放| 久久久久麻豆v国产| 亚洲乱码精品| 97视频免费观看| 久久人人爽人人爽人人片av免费| 美腿丝袜亚洲综合| 性视频1819p久久| 天天综合网入口| 日产国产欧美视频一区精品| 国产日韩欧美夫妻视频在线观看| 国产女人高潮时对白| 本田岬高潮一区二区三区| 欧美自拍资源在线| 嫩草在线视频| 午夜av区久久| 91小视频网站| 国产精品毛片av| 亚洲天堂一区二区三区| 五月天av网站| 中文高清一区| 国产日韩精品在线| 无码精品黑人一区二区三区| 国产精品麻豆一区二区 | 菠萝蜜视频国产在线播放| 亚洲一二三专区| 日本女优爱爱视频| 国产一区二区高清在线| 亚洲精品有码在线| 成熟的女同志hd| 丝袜诱惑制服诱惑色一区在线观看| 成人精品在线视频| 人成在线免费视频| 亚洲精品一卡二卡| 亚洲性生活网站| 红杏成人性视频免费看| 最近2019中文字幕mv免费看 | 亚洲va电影大全| 全色精品综合影院| 夜夜精品视频一区二区 | 国产精品小仙女| 日韩精品一区二区三区丰满| 天堂av一区二区三区| 欧美韩国日本一区| 91成人在线观看喷潮教学| 亚洲一区二区三区久久久| 精品在线观看国产| 欧美又粗又大又长| 蜜桃av一区二区三区电影| 精品欧美一区二区久久久伦| 中文字幕有码在线观看| 欧美性极品少妇| 亚洲男人天堂色| 国产调教精品| 欧美黄色片视频| 亚洲自拍偷拍另类| 久草中文综合在线| 日本不卡一区二区三区在线观看| 波多野结衣在线高清| 制服丝袜亚洲色图| 538精品视频| 老司机免费视频久久| 精品国产一区二区三区麻豆小说| 羞羞视频在线观看不卡| 91精品国产黑色紧身裤美女| 蜜桃av免费观看| 日本va欧美va欧美va精品| 免费观看成人在线| 成年人在线观看视频| 欧美小视频在线观看| 97香蕉碰碰人妻国产欧美| 在线欧美福利| 92国产精品久久久久首页| 色大18成网站www在线观看| 在线观看日产精品| 免费黄色片网站| 蜜臀国产一区二区三区在线播放| 日本一区二区三区四区在线观看| 在线手机中文字幕| 精品一区二区电影| 一级黄色av片| 国产精品1区二区.| 最新av网址在线观看| 免费观看亚洲视频大全| 久操成人在线视频| www.亚洲欧美| 亚洲.国产.中文慕字在线| 丝袜熟女一区二区三区| 亚洲深夜福利| 日韩高清在线播放| 久久麻豆视频| 久色乳综合思思在线视频| www五月婷婷| 五月婷婷久久丁香| 双性尿奴穿贞c带憋尿| 免费视频一区二区三区在线观看| 裸模一区二区三区免费| yw.尤物在线精品视频| 丝袜情趣国产精品| japanese国产| 天天综合日日夜夜精品| 青青草视频播放| 日韩高清一区二区| 日本不卡一区二区三区四区| 51精品在线| 亚洲欧美第一页| 亚洲字幕av一区二区三区四区| 亚洲三级在线免费观看| 国产国语老龄妇女a片| 影音先锋久久久| 日韩免费中文专区| 亚洲一区导航| 2019亚洲男人天堂| 尤物网在线观看| 亚洲福利精品在线| 超碰在线观看91| 亚洲精品成人在线| 无码熟妇人妻av| 激情综合亚洲| 极品尤物一区二区三区| 国产精品一区二区免费福利视频| 久久国产精品久久久久| 在线观看xxx| 欧美高清dvd| 国产精品黄色大片| 亚洲婷婷国产精品电影人久久| 亚洲制服丝袜在线播放| 美国一区二区三区在线播放| 国产日韩欧美精品在线观看| 日韩精品免费| 国产精品三级在线| 国产丝袜在线播放| 日韩中文av在线| 香蕉视频网站在线| 69av一区二区三区| 日韩精品一区不卡| 亚洲成人综合视频| 九九精品视频免费| 国产喷白浆一区二区三区| 95视频在线观看| 九色|91porny| 无码人妻精品一区二区三区66| 欧美午夜视频| 亚洲综合网中心| 九九久久电影| 国产欧美日韩亚洲| 日韩中文字幕| 91久久精品日日躁夜夜躁国产| 一本一道波多野毛片中文在线| 亚洲国产精彩中文乱码av在线播放| 一级黄色大毛片| 色哟哟在线观看一区二区三区| 精品无码久久久久| 亚洲人吸女人奶水| 免费成人深夜蜜桃视频 | 亚洲黄色小说视频| 成人av动漫在线| 不卡的一区二区| 久久av资源站| 最新天堂中文在线| 日本不卡一区二区三区| 日韩一级在线免费观看| 美女黄色成人网| 国产午夜大地久久| 99亚洲一区二区| 欧美午夜小视频| 1024日韩| 极品粉嫩国产18尤物| 亚洲一级网站| 人人妻人人澡人人爽欧美一区双| 欧美国产91| 日韩一二区视频| 欧美日韩1080p| 久久男人资源站| 国内精品99| 国产毛片视频网站| 亚洲欧洲视频| 凹凸国产熟女精品视频| 国产精品尤物| 亚洲 中文字幕 日韩 无码| 久久综合伊人| 91极品视频在线观看| 久久精品国产**网站演员| 国产精品嫩草影院8vv8| 国产一区中文字幕| 成年人看片网站| 成人激情免费网站| 美国黄色a级片| 国产喷白浆一区二区三区| 黄色录像免费观看| 亚洲在线视频网站| 久久狠狠高潮亚洲精品| 色激情天天射综合网| 中文字幕在线观看1| 3751色影院一区二区三区| www.天天干.com| 亚洲精品二三区| 国产高清自拍视频在线观看| 深夜福利一区二区| 先锋成人av| 91成人免费观看网站| 亚洲日本在线观看视频| 91久久精品国产91久久性色| 黄色欧美网站| 日韩性感在线| 一区二区影院| 97成人在线免费视频| 日韩黄色小视频| 亚洲第一狼人区| 成人免费视频免费观看| 国产免费无遮挡吸奶头视频| 亚洲欧美视频在线观看| 国产精品va无码一区二区三区| 欧美绝品在线观看成人午夜影视| www.激情五月.com| 亚洲色图美腿丝袜| a级网站在线播放| 国产91精品高潮白浆喷水| 国产91在线精品| 午夜剧场成人观在线视频免费观看| 日本蜜桃在线观看视频| 91精品久久久久久久久久久久久久 | 婷婷亚洲综合| 久色视频在线播放| 六月婷婷色综合| 一级特级黄色片| 亚洲柠檬福利资源导航| 伊人久久久久久久久久久久| 日韩欧美中文字幕制服| 成人在线免费视频| 久久欧美在线电影| 色综合视频一区二区三区44| 国产精品视频yy9099| 99亚洲乱人伦aⅴ精品| 婷婷久久青草热一区二区| 亚洲黄色三级| 三级av免费看| 欧美激情一区二区三区在线| 国产性xxxx高清| 日韩欧美中文字幕公布| 91大神在线网站| 欧美在线www| 精品淫伦v久久水蜜桃| 91精品一区二区三区四区| 麻豆免费精品视频| 色婷婷av777| 午夜欧美在线一二页| 国产成人精品av在线观| 色偷偷88888欧美精品久久久 | 精品欧美不卡一区二区在线观看| 久久99精品久久久久久噜噜| 欧美伊人亚洲伊人色综合动图| 欧美日韩一区二区三区在线视频 | 在线一级成人| 隔壁人妻偷人bd中字| 国产黄色成人av| 伊人久久久久久久久久久久久久| 在线免费精品视频| 九色在线播放| 茄子视频成人在线| 欧美大胆a级| 免费 成 人 黄 色| 不卡高清视频专区| 精品在线视频免费观看| 日韩欧美一卡二卡| 在线三级电影| 999视频在线免费观看| 亚洲精品成人无限看| 91网址在线观看精品| 亚洲丝袜制服诱惑| 国产伦理吴梦梦伦理| 日韩有码片在线观看| 久久精品国产精品亚洲毛片| 亚洲一区精彩视频| 捆绑紧缚一区二区三区视频| 美女网站视频色| 在线播放欧美女士性生活| 国产调教视频在线观看| 91中文精品字幕在线视频| 中文字幕一区二区三区乱码图片| 精品人妻一区二区三| 亚洲最大成人网4388xx| 成人福利小视频| 97免费视频在线| 在线成人动漫av| av无码精品一区二区三区| 亚洲欧洲美洲综合色网| 精品免费久久久| 国内偷自视频区视频综合| 香蕉久久99| 亚洲娇小娇小娇小| 亚洲人成网站色在线观看| 成人毛片视频免费看| 欧美在线视频a| 成人一级毛片| 日韩欧美色视频| 午夜精品福利久久久| 国产青青草在线| 91在线精品视频| 在线日韩欧美| 制服 丝袜 综合 日韩 欧美| 欧美日本一区二区三区四区 | 日韩电影网在线| jizz亚洲女人高潮大叫| 日本精品免费视频| av一二三不卡影片| 国产第一页在线观看| 久久深夜福利免费观看| 国产精品毛片av| 四季av一区二区| 亚洲男女一区二区三区| 亚洲色图 校园春色| 国产日韩在线亚洲字幕中文| 欧美日韩天堂| 中文字幕有码在线播放| 日韩一区二区免费高清| 伊人久久综合一区二区| 青青草原国产免费| 91女人视频在线观看| 97人妻精品一区二区三区| 欧美性视频网站| 围产精品久久久久久久|