パラレルポート入出力クラス
C++を使いたかったのでIOクラスを書いてみた。まだ途中。
かなり適当だけど、前から使ってみたかったproxyクラスを実践できたので良しとしよう。
#ifndef MAD_PARPORTIO_HPP_ #define MAD_PARPORTIO_HPP_ #include <string> #include <stdexcept> #include <fcntl.h> #include <sys/ioctl.h> #include <linux/ppdev.h> #include <linux/parport.h> namespace mad { class parportio { public: class pin_proxy { public: pin_proxy(parportio& ppio, size_t pin) :ppio_(ppio), pin_(pin) {} pin_proxy& operator=(const pin_proxy& other){ ppio_ = other.ppio_; pin_ = other.pin_; return *this; } pin_proxy& operator=(bool on){ char data; if(ioctl(ppio_.device_, PPRDATA, &data) == -1){ throw std::runtime_error("Read error"); } if(on){ data |= (1 << pin_); }else{ data &= ~(1 << pin_); } if(ioctl(ppio_.device_, PPWDATA, &data) == -1){ throw std::runtime_error("Write error"); } return *this; } operator bool() const { char data; if(ioctl(ppio_.device_, PPRDATA, &data) == -1){ throw std::runtime_error("Read error"); } return data & (1 << pin_); } private: parportio& ppio_; size_t pin_; }; // class pin_proxy parportio(const std::string& device) :device_(open(device.c_str(), O_RDWR)) { if(device_ == -1){ throw std::runtime_error("Open error"); } if(ioctl(device_, PPCLAIM)){ throw std::runtime_error("Claim error"); } } ~parportio(){ if(ioctl(device_, PPRELEASE) == -1){ throw std::runtime_error("Release error"); } close(device_); } const pin_proxy operator[](size_t pin) const { if(pin >= 8) throw std::out_of_range(""); return pin_proxy(const_cast<parportio&>(*this), pin); } pin_proxy operator[](size_t pin){ if(pin >= 8) throw std::out_of_range(""); return pin_proxy(*this, pin); } friend class pin_proxy; private: int device_; }; // class parportio } // namespace mad #endif // MAD_PARPORTIO_HPP_
昨晩のエントリのコードは次みたいに書ける。
#include "parportio.hpp" #include <unistd.h> int main(void){ mad::parportio parport("/dev/parport0"); while(1){ //ピン3からピン7を順番に点灯 for(int i = 3; i < 8; ++i){ parport[i] = 1; usleep(100000); parport[i] = 0; } } return 0; }
大分楽になった。
追記
今気づいたけど、pin_proxyの代入演算子を間違えてたので直した。