Tomotaka SUWA
t-suw****@users*****
2006年 2月 18日 (土) 02:21:38 JST
Index: AquaSKK/skkserv.cpp diff -u /dev/null AquaSKK/skkserv.cpp:1.1.2.1 --- /dev/null Sat Feb 18 02:21:38 2006 +++ AquaSKK/skkserv.cpp Sat Feb 18 02:21:38 2006 @@ -0,0 +1,138 @@ +/* -*- c++ -*- + $Id: skkserv.cpp,v 1.1.2.1 2006/02/17 17:21:38 t-suwa Exp $ + + MacOS X implementation of the SKK input method. + + Copyright (C) 2002-2004 phonohawk + Copyright (C) 2006 Tomotaka SUWA <t.suw****@mac*****> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include <string> +#include <vector> +#include <unistd.h> +#include "CppCFString.h" +#include "DictionarySet.h" +#include "skkserv.h" + +skkserv::skkserv() : pth_(0), server_(server_stream_socket()), port_(0), localonly_(true) { + // empty +} + +skkserv::~skkserv() { + stop(); +} + +skkserv& skkserv::theInstance() { + static skkserv obj; + return obj; +} + +bool skkserv::start(unsigned short port, bool localonly) { + port_ = port; + localonly_ = localonly; + + stop(); + + if(server_.bind(port_)) { + pthread_create(&pth_, NULL, skkserv::engine, this); + return true; + } + + return false; +} + +void skkserv::stop() { + if(pth_) { + pthread_cancel(pth_); + pthread_join(pth_, NULL); + pth_ = 0; + + if(server_) { + server_.close(); + } + } +} + +void* skkserv::engine(void* param) { + skkserv* obj = static_cast<skkserv*>(param); + + while(true) { + pthread_testcancel(); + int fd = obj->server_.accept(); + if(fd > 0) { + if(obj->localonly_ && ip_address::getpeername(fd) != "127.0.0.1") { + std::cerr << "AquaSKK: connection rejected[" << ip_address::getpeername(fd) << "]" << std::endl; + continue; + } + pthread_t pth; + pthread_create(&pth, NULL, skkserv::session, (void*)fd); + pthread_detach(pth); + } + } + + return NULL; +} + +void* skkserv::session(void* param) { + socket_stream sock((int)param); + std::cerr << "AquaSKK: new skkserv session[" << ip_address::getpeername((int)param) << "]" << std::endl; + + unsigned char cmd; + do { + cmd = sock.get(); + switch(cmd) { + case '0': // Øf + break; + case '1': { // õ + std::string word; + sock >> word; + sock.get(); + + CppCFString query(word.c_str(), kCFStringEncodingEUC_JP); + CppCFString reply(DictionarySet::theInstance().skkserv_style_search(query)); + + // ©Â©Á½H + if(reply.length() > 0) { + char* reply_c = reply.toCString(kCFStringEncodingEUC_JP); + sock << "1" << reply_c << "\n"; + delete[] reply_c; + } else { + sock << "4" << word << "\n"; + } + sock.flush(); + } + break; + case '2': // o[W + sock << "AquaSKKServer (skkserv emulation)" << std::endl; + sock.flush(); + break; + case '3': // zXgîñ + sock << ip_address::getsockname(sock.socket()) << "::" << std::endl; + sock.flush(); + break; + default: + std::cerr << "Unknown command: " << cmd << std::endl; + cmd = '0'; + break; + } + } while(cmd != '0'); + sock.close(); + + std::cerr << "AquaSKK: session closed[" << ip_address::getpeername((int)param) << "]" << std::endl; + + return NULL; +} Index: AquaSKK/skkserv.h diff -u /dev/null AquaSKK/skkserv.h:1.1.2.1 --- /dev/null Sat Feb 18 02:21:38 2006 +++ AquaSKK/skkserv.h Sat Feb 18 02:21:38 2006 @@ -0,0 +1,43 @@ +/* -*- c++ -*- + $Id: skkserv.h,v 1.1.2.1 2006/02/17 17:21:38 t-suwa Exp $ + + MacOS X implementation of the SKK input method. + + Copyright (C) 2002 phonohawk + Copyright (C) 2006 Tomotaka SUWA <t.suw****@mac*****> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include <iostream> +#include "pthread.h" +#include "socketstream.h" + +class skkserv { + pthread_t pth_; + server_stream_socket server_; + unsigned short port_; + bool localonly_; + + skkserv(); + ~skkserv(); + static void* engine(void* param); + static void* session(void* param); + +public: + static skkserv& theInstance(); + bool start(unsigned short port, bool localonly); + void stop(); +};