From 05fa4b8d771960f3251d766713792b82718750c9 Mon Sep 17 00:00:00 2001 From: William Woodall Date: Thu, 2 Feb 2012 23:35:40 -0600 Subject: [PATCH] Removing serial listener, next make sure I can compile without boost completely. --- Findserial.cmake | 2 +- Makefile | 6 - examples/serial_listener_example.cc | 93 --- include/serial/serial_listener.h | 931 ---------------------------- serial.cmake | 237 ++++--- serial.makefile | 2 +- serial_ros.cmake | 68 +- src/serial_listener.cc | 217 ------- tests/serial_listener_tests.cc | 238 ------- 9 files changed, 137 insertions(+), 1657 deletions(-) delete mode 100644 examples/serial_listener_example.cc delete mode 100644 include/serial/serial_listener.h delete mode 100644 src/serial_listener.cc delete mode 100644 tests/serial_listener_tests.cc diff --git a/Findserial.cmake b/Findserial.cmake index cb839a6..6d27e7e 100644 --- a/Findserial.cmake +++ b/Findserial.cmake @@ -1,4 +1,4 @@ -find_path(serial_INCLUDE_DIRS serial.h serial_listener.h /usr/include/serial +find_path(serial_INCLUDE_DIRS serial.h /usr/include/serial /usr/local/include/serial "$ENV{NAMER_ROOT}") find_library(serial_LIBRARIES serial /usr/lib /usr/local/lib diff --git a/Makefile b/Makefile index c4c5448..5df6eab 100644 --- a/Makefile +++ b/Makefile @@ -1,9 +1,3 @@ -# # ash_gti's dumb downed makefile so I can more easily test stuff -# CXX=clang++ -# CXXFLAGS=-g -I./include -ferror-limit=5 -O3 -Wall -Weffc++ -pedantic -pedantic-errors -Wextra -Wall -Waggregate-return -Wcast-align -Wcast-qual -Wchar-subscripts -Wcomment -Wconversion -Wdisabled-optimization -Wfloat-equal -Wformat -Wformat=2 -Wformat-nonliteral -Wformat-security -Wformat-y2k -Wimplicit -Wimport -Winit-self -Winline -Winvalid-pch -Wlong-long -Wmissing-braces -Wmissing-field-initializers -Wmissing-format-attribute -Wmissing-include-dirs -Wmissing-noreturn -Wpacked -Wparentheses -Wpointer-arith -Wredundant-decls -Wreturn-type -Wsequence-point -Wshadow -Wsign-compare -Wstack-protector -Wstrict-aliasing -Wstrict-aliasing=2 -Wswitch -Wswitch-default -Wswitch-enum -Wtrigraphs -Wuninitialized -Wunknown-pragmas -Wunreachable-code -Wunused -Wunused-function -Wunused-label -Wunused-parameter -Wunused-value -Wunused-variable -Wvariadic-macros -Wvolatile-register-var -Wwrite-strings -# -# test: tests/serial_tests.o src/serial.o src/impl/unix.o -# $(CXX) -o test tests/serial_tests.o src/serial.o src/impl/unix.o ifdef ROS_ROOT include $(shell rospack find mk)/cmake.mk else diff --git a/examples/serial_listener_example.cc b/examples/serial_listener_example.cc deleted file mode 100644 index 0a39854..0000000 --- a/examples/serial_listener_example.cc +++ /dev/null @@ -1,93 +0,0 @@ -#include - -#include -#include - -using namespace serial; - -void default_handler(std::string token) { - std::cout << "default_handler got a: " << token << std::endl; -} - -void callback(std::string token) { - std::cout << "callback got a: " << token << std::endl; -} - -int run() { - // Assuming this device prints the string 'pre-substr-post\r' at 100Hz - Serial serial("/dev/tty.usbserial-A900cfJA", 115200); - - SerialListener listener; - listener.startListening(serial); - - // Set the tokenizer - // This is the same as the default delimeter, so an explicit call to - // setTokenizer is not necessary if your data is \r delimited. - // You can create your own Tokenizer as well. - listener.setTokenizer(SerialListener::delimeter_tokenizer("\r")); - - // Method #1: - // comparator, callback - async - FilterPtr f1 = - listener.createFilter(SerialListener::startsWith("pre"), callback); - SerialListener::sleep(15); // Sleep 15ms, to let the data come in - listener.removeFilter(f1); // Not scoped, must be removed explicity - - // Method #2: - // comparator - blocking - { - BlockingFilterPtr f2 = - listener.createBlockingFilter(SerialListener::endsWith("post")); - for (size_t i = 0; i < 3; i++) { - std::string token = f2->wait(100); // Wait for 100 ms or a matched token - if (token != "") - std::cout << "Found something ending with 'post'" << std::endl; - else - std::cout << "Did not find something ending with 'post'" << std::endl; - } - } - // BlockingFilter is scoped and will remove itself, so no removeFilter - // required, but a call like `listener.removeFilter(BlockingFilter) will - // remove it from the filter list so wait will always timeout. - - // Method #3: - // comparator, token buffer size - blocking - { - // Give it a comparator, then a buffer size of 10 - BufferedFilterPtr f3 = - listener.createBufferedFilter(SerialListener::contains("substr"), 10); - SerialListener::sleep(75); // Sleep 75ms, should have about 7 - std::cout << "Caught " << f3->count(); - std::cout << " tokens containing 'substr'" << std::endl; - for(size_t i = 0; i < 20; ++i) { - std::string token = f3->wait(5); // Pull message from the buffer - if (token == "") // If an empty string is returned, a timeout occured - break; - } - f3->clear(); // Empties the buffer - if (f3->wait(0) == "") // Non-blocking wait - std::cout << "We won the race condition!" << std::endl; - else - std::cout << "We lost the race condition..." << std::endl; - // The buffer is circular, so the oldest matches will be dropped first - } - // BufferedFilter is scoped and will remove itself just like BlockingFilter. - - // Method #4: - // callback - async - // Gets called if a token doesn't match a filter - listener.setDefaultHandler(default_handler); - SerialListener::sleep(25); // Sleep 25 ms, so some default callbacks occur - - return 0; - -} - -int main(void) { - try { - return run(); - } catch (std::exception &e) { - std::cerr << e.what() << std::endl; - return 1; - } -} diff --git a/include/serial/serial_listener.h b/include/serial/serial_listener.h deleted file mode 100644 index 7e85b4c..0000000 --- a/include/serial/serial_listener.h +++ /dev/null @@ -1,931 +0,0 @@ -/*! - * \file serial/serial_listener.h - * \author William Woodall - * \version 0.1 - * - * \section LICENSE - * - * The BSD License - * - * Copyright (c) 2011 William Woodall - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * \section DESCRIPTION - * - * This provides a class that allows for asynchronous serial port reading. - * - */ - -#ifndef SERIAL_LISTENER_H -#define SERIAL_LISTENER_H - -#ifndef SERIAL_LISTENER_DEBUG -#define SERIAL_LISTENER_DEBUG 0 -#endif - -// STL -#include -#include -#include - -// Serial -#include - -// Boost -#include -#include -#include -#include - -#if SERIAL_LISTENER_DEBUG -# warning SerialListener in debug mode -#endif - -namespace serial { - -/*! - * This is an alias to boost::shared_ptr used for tokens. - * - * This is the type used internally and is the type returned in a vector by - * the tokenizer. The shared_ptr allows for the token to be stored and kept - * around long enough to be used by the comparators and callbacks, but no - * longer. This internal storage is passed as a const std::string reference - * to callbacks, like the DataCallback function type, to prevent implicit - * copying. - * - * \see serial::TokenizerType, serial::SerialListener::setTokenizer - */ -typedef boost::shared_ptr TokenPtr; - -/*! - * This is a general function type that is used as the callback prototype - * for asynchronous functions like the default handler callback and the - * listenFor callbacks. - * - * The function takes a std::string reference and returns nothing, it is - * simply passing the resulting line detected by the comparator to the user's - * callback for processing. - * - * \see SerialListener::listenFor, SerialListener::setDefaultHandler - */ -typedef boost::function DataCallback; - -/*! - * This is a general function type that is used as the comparator callback - * prototpe for the listenFor* type functions. - * - * The function takes a std::string reference and returns true if the string - * matches what the comparator is looking for and false if it does not, unless - * otherwise specified. - * - * \see SerialListener::listenFor, SerialListener::listenForOnce - */ -typedef boost::function ComparatorType; - -/*! - * This function type describes the prototype for the tokenizer callback. - * - * The function should take a std::string reference and tokenize it into a - * several TokenPtr's and store them in the given std::vector - * reference. There are some default ones or the user can create their own. - * - * The last element in the std::vector of TokenPtr's should always be - * either an empty string ("") or the last partial message. The last element - * in the std::vector will be put back into the data buffer so that if it is - * incomplete it can be completed when more data is read. - * - * Example: A delimeter tokenizer with a delimeter of "\r". The result would - * be: "msg1\rmsg2\r" -> ["msg1", "msg2", ""] for two complete messages, or: - * "msg1\rpartial_msg2" -> ["msg1","partial_msg2"] for one complete message - * and one partial message. - * - * \see SerialListener::setTokenizer, serial::delimeter_tokenizer, - * serial::TokenPtr - */ -typedef boost::function&)> -TokenizerType; - -/*! - * This function type describes the prototype for the exception callback. - * - * The function takes a std::exception reference and returns nothing. It is - * called from the library when an exception occurs in a library thread. - * This exposes these exceptions to the user so they can to error handling. - * - * \see SerialListener::setExceptionHandler - */ -typedef boost::function ExceptionCallback; - -/*! - * Represents a filter which new data is passed through. - * - * The filter consists of a comparator and a callback. The comparator takes a - * token and returns true if it matches, false if it doesn't. If a match - * occurs the serial listener will dispatch a call of the callback with the - * matched data in a another thread. The comparator should be as short as - * possible, but the callback can be longer since it is executed in a thread - * or thread pool. - * - * \param comparator A ComparatorType that matches incoming data, returns true - * for a match, false othewise. - * - * \param callback A DataCallback that gets called when a match occurs. - * - * \see serial::ComparatorType, serial::DataCallback, serial::FilterPtr - */ -class Filter -{ -public: - Filter (ComparatorType comparator, DataCallback callback) - : comparator_(comparator), callback_(callback) {} - virtual ~Filter () {} - - ComparatorType comparator_; - DataCallback callback_; - -private: - // Disable copy constructors - Filter(const Filter&); - void operator=(const Filter&); - const Filter& operator=(Filter); -}; - -/*! - * This is an alias to boost::shared_ptr used for tokens. - * - * This is used internally and is returned from SerialListener::listenFor like - * functions so that users can later remove those filters by passing the - * FilterPtr. - * - * \see serial::Filter, serial::SerialListener::listenFor, - * serial::SerialListener::listenForOnce - */ -typedef boost::shared_ptr FilterPtr; - -class BlockingFilter; // Forward declaration - -/*! - * Shared Pointer of BlockingFilter, returned by - * SerialListener::createBlockingFilter. - * - * \see serial::BlockingFilter, SerialListener::createBlockingFilter - */ -typedef boost::shared_ptr BlockingFilterPtr; - -class BufferedFilter; // Forward declaration - -/*! - * Shared Pointer of BufferedFilter, returned by - * SerialListener::createBufferedFilter. - * - * \see serial::BufferedFilter, SerialListener::createBufferedFilter - */ -typedef boost::shared_ptr BufferedFilterPtr; - -/*! - * This is a general exception generated by the SerialListener class. - * - * Check the SerialListenerException::what function for the cause. - * - * \param e_what is a std::string that describes the cause of the error. - */ -class SerialListenerException : public std::exception { - const std::string e_what_; -public: - SerialListenerException(const std::string e_what) : e_what_(e_what) {} - ~SerialListenerException() throw() {} - - virtual const char* what() const throw() { - std::stringstream ss; - ss << "SerialListenerException: " << this->e_what_; - return ss.str().c_str(); - } -}; - -// Based on: http://www.justsoftwaresolutions.co.uk/threading/implementing-a-thread-safe-queue-using-condition-variables.html -template -class ConcurrentQueue -{ -private: - std::queue the_queue; - mutable boost::mutex the_mutex; - boost::condition_variable the_condition_variable; -public: - void push(Data const& data) { - boost::mutex::scoped_lock lock(the_mutex); - the_queue.push(data); - lock.unlock(); - the_condition_variable.notify_one(); - } - - bool empty() const { - boost::mutex::scoped_lock lock(the_mutex); - return the_queue.empty(); - } - - bool try_pop(Data& popped_value) { - boost::mutex::scoped_lock lock(the_mutex); - if(the_queue.empty()) { - return false; - } - - popped_value=the_queue.front(); - the_queue.pop(); - return true; - } - - bool timed_wait_and_pop(Data& popped_value, long timeout) { - using namespace boost::posix_time; - bool result; - boost::mutex::scoped_lock lock(the_mutex); - result = !the_queue.empty(); - if (!result) { - result = the_condition_variable.timed_wait(lock, milliseconds(timeout)); - } - - if (result) { - popped_value=the_queue.front(); - the_queue.pop(); - } - return result; - } - - void wait_and_pop(Data& popped_value) { - boost::mutex::scoped_lock lock(the_mutex); - while(the_queue.empty()) { - the_condition_variable.wait(lock); - } - - popped_value=the_queue.front(); - the_queue.pop(); - } - - size_t size() const { - return the_queue.size(); - } - - void cancel() { - the_condition_variable.notify_one(); - } - - void clear() { - boost::mutex::scoped_lock lock(the_mutex); - while (!the_queue.empty()) { - the_queue.pop(); - } - } -}; - -/*! - * Listens to a serial port, facilitates asynchronous reading - */ -class SerialListener -{ -public: - /*! - * Creates a new Serial Listener. - */ - SerialListener (); - - /*! - * Destructor. - */ - virtual ~SerialListener (); - -/***** Configurations ******/ - - /*! - * Sets the tokenizer to be used when tokenizing the data into tokens. - * - * This function is given a std::string of data and is responsible for - * tokenizing that data into a std::vector of data tokens. - * The default tokenizer splits the data by the ascii return carriage. - * The user can create their own tokenizer or use one of the default ones. - * - * \param tokenizer Function for tokenizing the incoming data. - * - * \see serial::TokenizerType, serial::delimeter_tokenizer - */ - void - setTokenizer (TokenizerType tokenizer) { - this->tokenize = tokenizer; - } - - /*! - * Sets the number of bytes to be read at a time by the listener. - * - * \param chunk_size Number of bytes to be read at a time. - */ - void - setChunkSize (size_t chunk_size) { - this->chunk_size_ = chunk_size; - } - -/***** Start and Stop Listening ******/ - - /*! - * Starts a thread to listen for messages and process them through filters. - * - * \param serial_port Pointer to a serial::Serial object that is used to - * retrieve new data. - */ - void - startListening (serial::Serial &serial_port); - - /*! - * Stops the listening thread and blocks until it completely stops. - * - * This function also clears all of the active filters from listenFor and - * similar functions. - */ - void - stopListening (); - -/***** Filter Functions ******/ - - /*! - * Creates a filter that calls a callback when the comparator returns true. - * - * The user provides a comparator and a callback, and every time a line is - * received the comparator is called and the comparator has to evaluate the - * line and return true if it matches and false if it doesn't. If it does - * match, the callback is called with the resulting line. - * - * \param comparator This is a comparator for detecting if a line matches. - * The comparartor receives a std::string reference and must return a true - * if it matches and false if it doesn't. - * - * \param callback This is the handler for when a match occurs. It is given - * a std::string reference of the line that matched your comparator. - * - * \return boost::shared_ptr so you can remove it later. - * - * \see SerialListener::removeFilter - */ - FilterPtr - createFilter (ComparatorType comparator, DataCallback callback); - - /*! - * Creates a BlockingFilter which blocks until the comparator returns true. - * - * The user provides a comparator, and every time a line is - * received the comparator is called and the comparator has to evaluate the - * line and return true if it matches and false if it doesn't. If it does - * match, any threads that have called BlockingFilter::wait will be - * notified. The BlockingFilter will remove itself when its destructor is - * called, i.e. when it leaves the scope, so in those cases an explicit call - * to SerialListener::removeFilter is not needed. - * - * \param comparator This is a comparator for detecting if a line matches. - * The comparartor receives a std::string reference and must return a true - * if it matches and false if it doesn't. - * - * \return BlockingFilterPtr So you can call BlockingFilter::wait on it. - * - * \see SerialListener::removeFilter, serial::BlockingFilter, - * serial::BlockingFilterPtr - */ - BlockingFilterPtr - createBlockingFilter (ComparatorType comparator); - - /*! - * Creates a BlockingFilter blocks until the comparator returns true. - * - * The user provides a comparator, and every time a line is - * received the comparator is called and the comparator has to evaluate the - * line and return true if it matches and false if it doesn't. If it does - * match, any threads that have called BlockingFilter::wait will be - * notified. The BlockingFilter will remove itself when its destructor is - * called, i.e. when it leaves the scope, so in those cases an explicit call - * to SerialListener::removeFilter is not needed. - * - * \param comparator This is a comparator for detecting if a line matches. - * The comparartor receives a std::string reference and must return a true - * if it matches and false if it doesn't. - * - * \param buffer_size This is the number of tokens to be buffered by the - * BufferedFilter, defaults to 1024. - * - * \return BlockingFilter So you can call BlockingFilter::wait on it. - * - * \see SerialListener::removeFilter, serial::BufferedFilter, - * serial::BufferedFilterPtr - */ - BufferedFilterPtr - createBufferedFilter (ComparatorType comparator, size_t buffer_size = 1024); - - /*! - * Removes a filter by a given FilterPtr. - * - * \param filter_ptr A shared pointer to the filter to be removed. - * - * \see SerialListener::createFilter - */ - void - removeFilter (FilterPtr filter_ptr); - - /*! - * Removes a BlockingFilter. - * - * The BlockingFilter will remove itself if the destructor is called. - * - * \param blocking_filter A BlockingFilter to be removed. - * - * \see SerialListener::createBlockingFilter - */ - void - removeFilter (BlockingFilterPtr blocking_filter); - - /*! - * Removes a BufferedFilter. - * - * The BufferedFilter will remove itself if the destructor is called. - * - * \param buffered_filter A BufferedFilter to be removed. - * - * \see SerialListener::createBufferedFilter - */ - void - removeFilter (BufferedFilterPtr buffered_filter); - - /*! - * Removes all filters. - */ - void - removeAllFilters (); - -/***** Hooks and Handlers ******/ - - /*! - * Sets the handler to be called when a lines is not caught by a filter. - * - * This allows you to set a catch all function that will get called - * everytime a line is not matched by a filter and the ttl expires. - * - * Setting the callbacks works just like SerialListener::setInfoHandler. - * - * \param default_handler A function pointer to the callback to handle - * unmatched and expired messages. - * - * \see serial::DataCallback, SerialListener::setInfoHandler - */ - void setDefaultHandler(DataCallback default_handler) { - this->_default_handler = default_handler; - } - - /*! - * Sets the function to be called when an exception occurs internally. - * - * This allows you to hook into the exceptions that occur in threads inside - * the serial listener library. - * - * \param exception_handler A function pointer to the callback to handle new - * interal exceptions. - * - * \see serial::ExceptionCallback - */ - void - setExceptionHandler (ExceptionCallback exception_handler) { - this->handle_exc = exception_handler; - } - -/***** Static Functions ******/ - - /*! - * Sleeps for a given number of milliseconds. - * - * \param milliseconds number of milliseconds to sleep. - */ - static void - sleep (long milliseconds) { - boost::int64_t ms(milliseconds); - boost::this_thread::sleep(boost::posix_time::milliseconds(ms)); - } - - /*! - * This returns a tokenizer that splits on a given delimeter. - * - * The delimeter is passed into the function and a TokenizerType is returned - * that can be passed to SerialListener::setTokenizer. - * - * Example: - *
-   *   my_listener.setTokenizer(SerialListener::delimeter_tokenizer("\r"));
-   * <\pre>
-   *
-   * \param delimeter A std::string that is used as a delimeter when
-   * tokenizing data.
-   *
-   * \return TokenizerType A tokenizer function type that can be passed to
-   * SerialListener::setTokenizer.
-   *
-   * \see SerialListener::setTokenizer, serial::TokenizerType
-   */
-  static TokenizerType
-  delimeter_tokenizer (std::string delimeter) {
-    return boost::bind(&SerialListener::_delimeter_tokenizer,
-                       _1, _2, delimeter);
-  }
-
-  /*!
-   * This returns a comparator that matches only the exact string given.
-   *
-   * This can be used with listenFor or listenForOnce:
-   *
-   * Example:
-   * 
-   *   my_listener.listenFor(SerialListener::exactly("my_string"),
-   *                         my_callback);
-   * <\pre>
-   *
-   * \param exact_str A std::string that is used as the exact string to match
-   * when comparing tokens for matching.
-   *
-   * \return ComparatorType A comparator function type that can be passed to
-   * SerialListener::listenFor or SerialListener::listenForOnce.
-   *
-   * \see SerialListener::listenFor, SerialListener::listenForOnce,
-   * serial::ComparatorType
-   */
-  static ComparatorType
-  exactly (std::string exact_str) {
-    return boost::bind(&SerialListener::_exactly, _1, exact_str);
-  }
-
-  /*!
-   * This returns a comparator that looks for a given prefix.
-   *
-   * This can be used with listenFor or listenForOnce:
-   *
-   * Example:
-   * 
-   *   my_listener.listenFor(SerialListener::startsWith("V="), my_callback);
-   * <\pre>
-   *
-   * \param prefix A std::string that is used as the prefix string to match
-   * when comparing tokens for matching.
-   *
-   * \return ComparatorType A comparator function type that can be passed to
-   * SerialListener::listenFor or SerialListener::listenForOnce.
-   *
-   * \see SerialListener::listenFor, SerialListener::listenForOnce,
-   * serial::ComparatorType
-   */
-  static ComparatorType
-  startsWith (std::string prefix) {
-    return boost::bind(&SerialListener::_startsWith, _1, prefix);
-  }
-
-  /*!
-   * This returns a comparator that looks for a given postfix.
-   *
-   * This can be used with listenFor or listenForOnce:
-   *
-   * Example:
-   * 
-   *   my_listener.listenFor(SerialListener::endsWith(";"), my_callback);
-   * <\pre>
-   *
-   * \param postfix A std::string that is used as the postfix string to match
-   * when comparing tokens for matching.
-   *
-   * \return ComparatorType A comparator function type that can be passed to
-   * SerialListener::listenFor or SerialListener::listenForOnce.
-   *
-   * \see SerialListener::listenFor, SerialListener::listenForOnce,
-   * serial::ComparatorType
-   */
-  static ComparatorType
-  endsWith (std::string postfix) {
-    return boost::bind(&SerialListener::_endsWith, _1, postfix);
-  }
-
-  /*!
-   * This returns a comparator that looks for a given substring in the token.
-   *
-   * This can be used with listenFor or listenForOnce:
-   *
-   * Example:
-   * 
-   *   my_listener.listenFor(SerialListener::contains("some string"),
-   *                         my_callback);
-   * <\pre>
-   *
-   * \param substr A std::string that is used as the search substring to match
-   * when comparing tokens for matching.
-   *
-   * \return ComparatorType A comparator function type that can be passed to
-   * SerialListener::listenFor or SerialListener::listenForOnce.
-   *
-   * \see SerialListener::listenFor, SerialListener::listenForOnce,
-   * serial::ComparatorType
-   */
-  static ComparatorType
-  contains (std::string substr) {
-    return boost::bind(_contains, _1, substr);
-  }
-
-private:
-  // Disable copy constructors
-  SerialListener(const SerialListener&);
-  void operator=(const SerialListener&);
-  const SerialListener& operator=(SerialListener);
-  // delimeter tokenizer function
-  static void
-  _delimeter_tokenizer (const std::string &data,
-                        std::vector &tokens,
-                        std::string delimeter)
-  {
-    typedef std::vector find_vector_type;
-    find_vector_type t;
-    boost::split(t, data, boost::is_any_of(delimeter));
-    for (find_vector_type::iterator it = t.begin(); it != t.end(); it++)
-      tokens.push_back(TokenPtr( new std::string(*it) ));
-  }
-  // exact comparator function
-  static bool
-  _exactly (const std::string& token, std::string exact_str) {
-#if SERIAL_LISTENER_DEBUG
-    std::cerr << "In exactly callback(" << token.length() << "): ";
-    std::cerr << token << " == " << exact_str << ": ";
-    if (token == exact_str)
-      std::cerr << "True";
-    else
-      std::cerr << "False";
-    std::cerr << std::endl;
-#endif
-    return token == exact_str;
-  }
-  // startswith comparator function
-  static bool
-  _startsWith (const std::string& token, std::string prefix) {
-#if SERIAL_LISTENER_DEBUG
-    std::cerr << "In startsWith callback(" << token.length() << "): ";
-    std::cerr << token << " starts with " << prefix;
-    std::cerr << "?: ";
-    if (token.substr(0,prefix.length()) == prefix)
-      std::cerr << "True";
-    else
-      std::cerr << "False";
-    std::cerr << std::endl;
-#endif
-    return token.substr(0,prefix.length()) == prefix;
-  }
-  // endswith comparator function
-  static bool
-  _endsWith (const std::string& token, std::string postfix) {
-#if SERIAL_LISTENER_DEBUG
-    std::cerr << "In endsWith callback(";
-    std::cerr << token.length();
-    std::cerr << "): " << token;
-    std::cerr << " ends with " << postfix << "?: ";
-    if (token.substr(token.length()-postfix.length()) == postfix)
-      std::cerr << "True";
-    else
-      std::cerr << "False";
-    std::cerr << std::endl;
-#endif
-    return token.substr(token.length()-postfix.length()) == postfix;
-  }
-  // contains comparator function
-  static bool
-  _contains (const std::string& token, std::string substr) {
-    return token.find(substr) != std::string::npos;
-  }
-
-  // Gets some data from the serial port
-  void readSomeData (std::string &temp, size_t this_many) {
-    // Make sure there is a serial port
-    if (this->serial_port_ == NULL) {
-      this->handle_exc(SerialListenerException("Invalid serial port."));
-    }
-    // Make sure the serial port is open
-    if (!this->serial_port_->isOpen()) {
-      this->handle_exc(SerialListenerException("Serial port not open."));
-    }
-    temp = this->serial_port_->read(this_many);
-  }
-  // Runs the new_tokens through all the filters
-  void filter (std::vector &tokens);
-  // Function that loops while listening is true
-  void listen ();
-  // Target of callback thread
-  void callback ();
-  // Determines how much to read on each loop of listen
-  size_t determineAmountToRead ();
-
-  // Tokenizer
-  TokenizerType tokenize;
-
-  // Exception handler
-  ExceptionCallback handle_exc;
-
-  // Default handler
-  FilterPtr default_filter;
-  DataCallback _default_handler;
-  ComparatorType default_comparator;
-  void default_handler(const std::string &token);
-
-  // Persistent listening variables
-  bool listening;
-  char serial_port_padding[7];
-  serial::Serial * serial_port_;
-  boost::thread listen_thread;
-  std::string data_buffer;
-  size_t chunk_size_;
-
-  // Callback related variables
-  // filter id, token
-  // filter id == 0 is going to be default handled
-  ConcurrentQueue >
-  callback_queue;
-  boost::thread callback_thread;
-
-  // Mutex for locking use of filters
-  boost::mutex filter_mux;
-  // vector of filter ids
-  std::vector filters;
-
-};
-
-/*!
- * This is the a filter that provides a wait function for blocking until a
- * match is found.
- *
- * This should probably not be created manually, but instead should be
- * constructed using SerialListener::createBlockingFilter(ComparatorType)
- * function which returns a BlockingFilter instance.
- *
- * \see serial::SerialListener::ComparatorType,
- * serial::SerialListener::createBlockingFilter
- */
-class BlockingFilter
-{
-public:
-  BlockingFilter (ComparatorType comparator, SerialListener &listener) {
-    this->listener_ = &listener;
-    DataCallback cb = boost::bind(&BlockingFilter::callback, this, _1);
-    this->filter_ptr = this->listener_->createFilter(comparator, cb);
-  }
-
-  virtual ~BlockingFilter () {
-    this->listener_->removeFilter(filter_ptr);
-    this->result = "";
-    this->cond.notify_all();
-  }
-
-  /*!
-   * Waits a given number of milliseconds or until a token is matched.  If a
-   * token is matched it is returned, otherwise an empty string is returned.
-   *
-   * \param ms Time in milliseconds to wait on a new token.
-   *
-   * \return std::string token that was matched or "" if none were matched.
-   */
- std::string wait(long ms) {
-    this->result = "";
-    boost::unique_lock lock(this->mutex);
-    this->cond.timed_wait(lock, boost::posix_time::milliseconds(ms));
-    return this->result;
-  }
-
-  FilterPtr filter_ptr;
-
-  void callback(const std::string& token) {
-#if SERIAL_LISTENER_DEBUG
-    std::cerr << "In BlockingFilter callback(" << token.length() << "): ";
-    std::cerr << token << std::endl;
-#endif
-    this->cond.notify_all();
-    this->result = token;
-  }
-
-private:
-  SerialListener * listener_;
-  boost::condition_variable cond;
-  boost::mutex mutex;
-  std::string result;
-
-};
-
-/*!
- * This is the a filter that provides a wait function for blocking until a
- * match is found.  It will also buffer up to a given buffer size of tokens so
- * that they can be counted or accessed after they are matched by the filter.
- *
- * This should probably not be created manually, but instead should be
- * constructed using SerialListener::createBufferedFilter(ComparatorType)
- * function which returns a BufferedFilter instance.
- *
- * The internal buffer is a circular queue buffer, so when the buffer is full,
- * the oldest token is dropped and the new one is added.  Additionally, when
- * wait is a called the oldest available token is returned.
- *
- * \see serial::SerialListener::ComparatorType,
- * serial::SerialListener::createBufferedFilter
- */
-class BufferedFilter
-{
-public:
-  BufferedFilter (ComparatorType comparator, size_t buffer_size,
-                  SerialListener &listener)
-  : buffer_size_(buffer_size)
-  {
-    this->listener_ = &listener;
-    DataCallback cb = boost::bind(&BufferedFilter::callback, this, _1);
-    this->filter_ptr = this->listener_->createFilter(comparator, cb);
-  }
-
-  virtual ~BufferedFilter () {
-    this->listener_->removeFilter(filter_ptr);
-    this->queue.clear();
-    this->result = "";
-  }
-
-  /*!
-   * Waits a given number of milliseconds or until a matched token is
-   * available in the buffer.  If a token is matched it is returned, otherwise
-   * an empty string is returned.
-   *
-   * \param ms Time in milliseconds to wait on a new token.  If ms is set to 0
-   * then it will try to get a new token if one is available but will not
-   * block.
-   *
-   * \return std::string token that was matched or "" if none were matched.
-   */
-  std::string wait(long ms) {
-    if (ms == 0) {
-      if (!this->queue.try_pop(this->result)) {
-        this->result = "";
-      }
-    } else {
-      if (!this->queue.timed_wait_and_pop(this->result, ms)) {
-        this->result = "";
-      }
-    }
-    return result;
-  }
-
-  /*!
-   * Clears the buffer of any tokens.
-   */
-  void clear() {
-    queue.clear();
-  }
-
-  /*!
-   * Returns the number of tokens waiting in the buffer.
-   */
-  size_t count() {
-    return queue.size();
-  }
-
-  /*!
-   * Returns the capacity of the buffer.
-   */
-  size_t capacity() {
-    return buffer_size_;
-  }
-
-  FilterPtr filter_ptr;
-
-  void callback(const std::string &token) {
-#if SERIAL_LISTENER_DEBUG
-    std::cerr << "In BufferedFilter callback(" << token.length() << "): ";
-    std::cerr << token << std::endl;
-#endif
-    std::string throw_away;
-    if (this->queue.size() == this->buffer_size_) {
-      this->queue.wait_and_pop(throw_away);
-    }
-    this->queue.push(token);
-  }
-
-private:
-  size_t buffer_size_;
-  SerialListener * listener_;
-  ConcurrentQueue queue;
-  std::string result;
-
-};
-
-} // namespace serial
-
-#endif // SERIAL_LISTENER_H
diff --git a/serial.cmake b/serial.cmake
index 328b91e..7e339aa 100644
--- a/serial.cmake
+++ b/serial.cmake
@@ -1,158 +1,133 @@
 macro(build_serial)
-## Project Setup
-cmake_minimum_required(VERSION 2.4.6)
 
-if(COMMAND cmake_policy)
-    cmake_policy(SET CMP0003 NEW)
-endif(COMMAND cmake_policy)
+  ## Project Setup
+  cmake_minimum_required(VERSION 2.4.6)
 
-project(Serial)
+  if(COMMAND cmake_policy)
+      cmake_policy(SET CMP0003 NEW)
+  endif(COMMAND cmake_policy)
 
-## Configurations
+  project(Serial)
 
-# Use clang if available
-IF(EXISTS /usr/bin/clang)
-  set(CMAKE_CXX_COMPILER /usr/bin/clang++)
-  set(CMAKE_OSX_DEPLOYMENT_TARGET "")
-  # set(CMAKE_CXX_FLAGS "-ferror-limit=5 -std=c++0x -stdlib=libc++")
-  set(CMAKE_CXX_FLAGS "-ferror-limit=5 -Wall -Weffc++ -pedantic -pedantic-errors -Wextra  -Wall -Waggregate-return -Wcast-align -Wcast-qual  -Wchar-subscripts  -Wcomment -Wconversion -Wdisabled-optimization -Wfloat-equal  -Wformat  -Wformat=2 -Wformat-nonliteral -Wformat-security  -Wformat-y2k -Wimplicit  -Wimport  -Winit-self  -Winline -Winvalid-pch   -Wlong-long -Wmissing-braces -Wmissing-field-initializers -Wmissing-format-attribute   -Wmissing-include-dirs -Wmissing-noreturn -Wpacked -Wparentheses  -Wpointer-arith -Wredundant-decls -Wreturn-type -Wsequence-point  -Wshadow -Wsign-compare  -Wstack-protector -Wstrict-aliasing -Wstrict-aliasing=2 -Wswitch  -Wswitch-default -Wswitch-enum -Wtrigraphs  -Wuninitialized -Wunknown-pragmas  -Wunreachable-code -Wunused -Wunused-function  -Wunused-label  -Wunused-parameter -Wunused-value  -Wunused-variable  -Wvariadic-macros -Wvolatile-register-var  -Wwrite-strings")
-  set(CMAKE_BUILD_TYPE Debug)
-ENDIF(EXISTS /usr/bin/clang)
+  ## Configurations
 
-option(SERIAL_BUILD_TESTS "Build all of the Serial tests." OFF)
-option(SERIAL_BUILD_EXAMPLES "Build all of the Serial examples." OFF)
+  # Use clang if available
+  IF(EXISTS /usr/bin/clang)
+    set(CMAKE_CXX_COMPILER /usr/bin/clang++)
+    set(CMAKE_OSX_DEPLOYMENT_TARGET "")
+    set(SERIAL_BUILD_WARNINGS TRUE)
+    IF(SERIAL_BUILD_WARNINGS)
+      set(CMAKE_CXX_FLAGS "-ferror-limit=5 -Wall -Weffc++ -pedantic -pedantic-errors -Wextra  -Wall -Waggregate-return -Wcast-align -Wcast-qual  -Wchar-subscripts  -Wcomment -Wconversion -Wdisabled-optimization -Wfloat-equal  -Wformat  -Wformat=2 -Wformat-nonliteral -Wformat-security  -Wformat-y2k -Wimplicit  -Wimport  -Winit-self  -Winline -Winvalid-pch   -Wlong-long -Wmissing-braces -Wmissing-field-initializers -Wmissing-format-attribute   -Wmissing-include-dirs -Wmissing-noreturn -Wpacked -Wparentheses  -Wpointer-arith -Wredundant-decls -Wreturn-type -Wsequence-point  -Wshadow -Wsign-compare  -Wstack-protector -Wstrict-aliasing -Wstrict-aliasing=2 -Wswitch  -Wswitch-default -Wswitch-enum -Wtrigraphs  -Wuninitialized -Wunknown-pragmas  -Wunreachable-code -Wunused -Wunused-function  -Wunused-label  -Wunused-parameter -Wunused-value  -Wunused-variable  -Wvariadic-macros -Wvolatile-register-var  -Wwrite-strings")
+    ELSE(SERIAL_BUILD_WARNINGS)
+      set(CMAKE_CXX_FLAGS "-ferror-limit=5")
+    ENDIF(SERIAL_BUILD_WARNINGS)
+    set(CMAKE_BUILD_TYPE Debug)
+  ENDIF(EXISTS /usr/bin/clang)
 
-# Allow for building shared libs override
-IF(NOT BUILD_SHARED_LIBS)
-    set(BUILD_SHARED_LIBS OFF)
-ENDIF(NOT BUILD_SHARED_LIBS)
+  option(SERIAL_BUILD_TESTS "Build all of the Serial tests." OFF)
+  option(SERIAL_BUILD_EXAMPLES "Build all of the Serial examples." OFF)
 
-# Set the default path for built executables to the "bin" directory
-IF(NOT DEFINED(EXECUTABLE_OUTPUT_PATH))
-    set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
-ENDIF(NOT DEFINED(EXECUTABLE_OUTPUT_PATH))
-# set the default path for built libraries to the "lib" directory
-IF(NOT DEFINED(LIBRARY_OUTPUT_PATH))
-    set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)
-ENDIF(NOT DEFINED(LIBRARY_OUTPUT_PATH))
+  # Allow for building shared libs override
+  IF(NOT BUILD_SHARED_LIBS)
+      set(BUILD_SHARED_LIBS OFF)
+  ENDIF(NOT BUILD_SHARED_LIBS)
 
-## Configure the build system
+  # Set the default path for built executables to the "bin" directory
+  IF(NOT DEFINED(EXECUTABLE_OUTPUT_PATH))
+      set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
+  ENDIF(NOT DEFINED(EXECUTABLE_OUTPUT_PATH))
+  # set the default path for built libraries to the "lib" directory
+  IF(NOT DEFINED(LIBRARY_OUTPUT_PATH))
+      set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)
+  ENDIF(NOT DEFINED(LIBRARY_OUTPUT_PATH))
 
-# Add the include folder to the include path
-include_directories(${PROJECT_SOURCE_DIR}/include)
+  ## Configure the build system
 
-# Add default source files
-set(SERIAL_SRCS src/serial.cc src/impl/unix.cc src/serial_listener.cc)
-# Add default header files
-set(SERIAL_HEADERS include/serial/serial.h include/serial/serial_listener.h)
+  # Add the include folder to the include path
+  include_directories(${PROJECT_SOURCE_DIR}/include)
 
-IF(UNIX)
-  list(APPEND SERIAL_SRCS src/impl/unix.cc)
-  list(APPEND SERIAL_HEADERS include/serial/impl/unix.h)
-ELSE(UNIX)
-  
-ENDIF(UNIX)
+  # Add default source files
+  set(SERIAL_SRCS src/serial.cc)
+  IF(WIN32)
+    list(APPEND SERIAL_SRCS src/impl/windows.cc)
+  ELSE(WIN32)
+    list(APPEND SERIAL_SRCS src/impl/unix.cc)
+  ENDIF(WIN32)
+  # Add default header files
+  set(SERIAL_HEADERS include/serial/serial.h)
 
-# Find Boost, if it hasn't already been found
-IF(NOT Boost_FOUND OR NOT Boost_SYSTEM_FOUND OR NOT Boost_FILESYSTEM_FOUND OR NOT Boost_THREAD_FOUND)
-    find_package(Boost COMPONENTS system filesystem thread REQUIRED)
-ENDIF(NOT Boost_FOUND OR NOT Boost_SYSTEM_FOUND OR NOT Boost_FILESYSTEM_FOUND OR NOT Boost_THREAD_FOUND)
+  ## Build the Serial Library
 
-link_directories(${Boost_LIBRARY_DIRS})
-include_directories(${Boost_INCLUDE_DIRS})
+  # Compile the Library
+  add_library(serial ${SERIAL_SRCS})
 
-set(SERIAL_LINK_LIBS ${Boost_SYSTEM_LIBRARY}
-                     ${Boost_FILESYSTEM_LIBRARY}
-                     ${Boost_THREAD_LIBRARY})
+  ## Build Examples
 
-## Build the Serial Library
+  # If asked to
+  IF(SERIAL_BUILD_EXAMPLES)
+      # Compile the Serial Test program
+      add_executable(serial_example examples/serial_example.cc)
+      # Link the Test program to the Serial library
+      target_link_libraries(serial_example serial)
+  ENDIF(SERIAL_BUILD_EXAMPLES)
 
-# Compile the Library
-add_library(serial ${SERIAL_SRCS} ${SERIAL_HEADERS})
-target_link_libraries(serial ${SERIAL_LINK_LIBS})
-IF( WIN32 )
-  target_link_libraries(serial wsock32)
-ENDIF( )
+  ## Build tests
 
-## Build Examples
+  # If asked to
+  IF(SERIAL_BUILD_TESTS)
+      # Find Google Test
+      enable_testing()
+      find_package(GTest REQUIRED)
+      include_directories(${GTEST_INCLUDE_DIRS})
 
-# If asked to
-IF(SERIAL_BUILD_EXAMPLES)
-    # Compile the Serial Test program
-    add_executable(serial_example examples/serial_example.cc)
-    # Link the Test program to the Serial library
-    target_link_libraries(serial_example serial)
+      # Compile the Serial Test program
+      add_executable(serial_tests tests/serial_tests.cc)
+      # Link the Test program to the serial library
+      target_link_libraries(serial_tests ${GTEST_BOTH_LIBRARIES}
+                            serial)
+
+      add_test(AllTestsIntest_serial serial_tests)
+  ENDIF(SERIAL_BUILD_TESTS)
+
+  ## Setup install and uninstall
+
+  # Unless asked not to...
+  IF(NOT SERIAL_DONT_CONFIGURE_INSTALL)
+      # Configure make install
+      IF(NOT CMAKE_INSTALL_PREFIX)
+          SET(CMAKE_INSTALL_PREFIX /usr/local)
+      ENDIF(NOT CMAKE_INSTALL_PREFIX)
     
-    # Compile the Serial Listener Test program
-    add_executable(serial_listener_example 
-                   examples/serial_listener_example.cc)
-    # Link the Test program to the Serial library
-    target_link_libraries(serial_listener_example serial)
-ENDIF(SERIAL_BUILD_EXAMPLES)
-
-## Build tests
-
-# If asked to
-IF(SERIAL_BUILD_TESTS)
-    # Find Google Test
-    enable_testing()
-    find_package(GTest REQUIRED)
-    include_directories(${GTEST_INCLUDE_DIRS})
-
-    # Compile the Serial Listener Test program
-    add_executable(serial_listener_tests tests/serial_listener_tests.cc)
-    add_executable(serial_tests tests/serial_tests.cc)
-    # Link the Test program to the serial library
-    target_link_libraries(serial_listener_tests ${GTEST_BOTH_LIBRARIES}
-                          serial)
-    target_link_libraries(serial_tests ${GTEST_BOTH_LIBRARIES}
-                          serial)
-
-    # # See: http://code.google.com/p/googlemock/issues/detail?id=146
-    # add_definitions(-DGTEST_USE_OWN_TR1_TUPLE=1)
-    add_test(AllTestsIntest_serial serial_listener_tests)
-    add_test(AllTestsIntest_serial serial_tests)
-ENDIF(SERIAL_BUILD_TESTS)
-
-## Setup install and uninstall
-
-# Unless asked not to...
-IF(NOT SERIAL_DONT_CONFIGURE_INSTALL)
-    # Configure make install
-    IF(NOT CMAKE_INSTALL_PREFIX)
-        SET(CMAKE_INSTALL_PREFIX /usr/local)
-    ENDIF(NOT CMAKE_INSTALL_PREFIX)
+      INSTALL(TARGETS serial
+        RUNTIME DESTINATION bin
+        LIBRARY DESTINATION lib
+        ARCHIVE DESTINATION lib
+      )
     
-    INSTALL(TARGETS serial
-      RUNTIME DESTINATION bin
-      LIBRARY DESTINATION lib
-      ARCHIVE DESTINATION lib
-    )
+      INSTALL(FILES include/serial/serial.h
+              DESTINATION include/serial)
     
-    INSTALL(FILES include/serial/serial.h
-                  include/serial/serial_listener.h
-            DESTINATION include/serial)
+      IF(NOT CMAKE_FIND_INSTALL_PATH)
+          set(CMAKE_FIND_INSTALL_PATH ${CMAKE_ROOT})
+      ENDIF(NOT CMAKE_FIND_INSTALL_PATH)
     
-    IF(NOT CMAKE_FIND_INSTALL_PATH)
-        set(CMAKE_FIND_INSTALL_PATH ${CMAKE_ROOT})
-    ENDIF(NOT CMAKE_FIND_INSTALL_PATH)
+      INSTALL(FILES Findserial.cmake
+              DESTINATION ${CMAKE_FIND_INSTALL_PATH}/Modules/)
     
-    INSTALL(FILES Findserial.cmake DESTINATION ${CMAKE_FIND_INSTALL_PATH}/Modules/)
+      ADD_CUSTOM_TARGET(uninstall @echo uninstall package)
     
-    ADD_CUSTOM_TARGET(uninstall @echo uninstall package)
-    
-    IF (UNIX)
-      ADD_CUSTOM_COMMAND(
-        COMMENT "uninstall package"
-        COMMAND xargs ARGS rm < install_manifest.txt
+      IF (UNIX)
+        ADD_CUSTOM_COMMAND(
+          COMMENT "uninstall package"
+          COMMAND xargs ARGS rm < install_manifest.txt
         
-        TARGET  uninstall
-      )
-    ELSE(UNIX)
-      ADD_CUSTOM_COMMAND(
-        COMMENT "uninstall only implemented in unix"
-        TARGET  uninstall
-      )
-    ENDIF(UNIX)
-ENDIF(NOT SERIAL_DONT_CONFIGURE_INSTALL)
+          TARGET  uninstall
+        )
+      ELSE(UNIX)
+        ADD_CUSTOM_COMMAND(
+          COMMENT "uninstall only implemented in unix"
+          TARGET  uninstall
+        )
+      ENDIF(UNIX)
+  ENDIF(NOT SERIAL_DONT_CONFIGURE_INSTALL)
 endmacro(build_serial)
diff --git a/serial.makefile b/serial.makefile
index 1667164..7ddb536 100644
--- a/serial.makefile
+++ b/serial.makefile
@@ -37,4 +37,4 @@ ifneq ($(MAKE),)
 else
 	cd build && make
 endif
-	cd bin && ./serial_listener_tests
\ No newline at end of file
+	cd bin && ./serial_tests
\ No newline at end of file
diff --git a/serial_ros.cmake b/serial_ros.cmake
index 029b83a..940721d 100644
--- a/serial_ros.cmake
+++ b/serial_ros.cmake
@@ -1,51 +1,41 @@
 macro(build_serial)
-cmake_minimum_required(VERSION 2.4.6)
-include($ENV{ROS_ROOT}/core/rosbuild/rosbuild.cmake)
 
-# Set the build type.  Options are:
-#  Coverage       : w/ debug symbols, w/o optimization, w/ code-coverage
-#  Debug          : w/ debug symbols, w/o optimization
-#  Release        : w/o debug symbols, w/ optimization
-#  RelWithDebInfo : w/ debug symbols, w/ optimization
-#  MinSizeRel     : w/o debug symbols, w/ optimization, stripped binaries
-set(ROS_BUILD_TYPE RelWithDebInfo)
+  cmake_minimum_required(VERSION 2.4.6)
+  include($ENV{ROS_ROOT}/core/rosbuild/rosbuild.cmake)
 
-rosbuild_init()
+  # Set the build type.  Options are:
+  #  Coverage       : w/ debug symbols, w/o optimization, w/ code-coverage
+  #  Debug          : w/ debug symbols, w/o optimization
+  #  Release        : w/o debug symbols, w/ optimization
+  #  RelWithDebInfo : w/ debug symbols, w/ optimization
+  #  MinSizeRel     : w/o debug symbols, w/ optimization, stripped binaries
+  set(ROS_BUILD_TYPE RelWithDebInfo)
 
-#set the default path for built executables to the "bin" directory
-set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
-#set the default path for built libraries to the "lib" directory
-set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)
+  rosbuild_init()
 
-include_directories(include)
+  #set the default path for built executables to the "bin" directory
+  set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
+  #set the default path for built libraries to the "lib" directory
+  set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)
 
-set(SERIAL_SRCS src/serial.cc)
-if(UNIX)
-  list(APPEND SERIAL_SRCS src/impl/unix.cc)
-else(UNIX)
-  list(APPEND SERIAL_SRCS src/impl/windows.cc)
-endif(UNIX)
-list(APPEND SERIAL_SRCS src/serial_listener.cc)
+  include_directories(include)
 
-# Build the serial library
-rosbuild_add_library(${PROJECT_NAME} ${SERIAL_SRCS})
+  set(SERIAL_SRCS src/serial.cc)
+  if(UNIX)
+    list(APPEND SERIAL_SRCS src/impl/unix.cc)
+  else(UNIX)
+    list(APPEND SERIAL_SRCS src/impl/winows.cc)
+  endif(UNIX)
 
-# Add boost dependencies
-rosbuild_add_boost_directories()
-rosbuild_link_boost(${PROJECT_NAME} system filesystem thread)
+  # Build the serial library
+  rosbuild_add_library(${PROJECT_NAME} ${SERIAL_SRCS})
 
-# Build example
-rosbuild_add_executable(serial_example examples/serial_example.cc)
-target_link_libraries(serial_example ${PROJECT_NAME})
+  # Build example
+  rosbuild_add_executable(serial_example examples/serial_example.cc)
+  target_link_libraries(serial_example ${PROJECT_NAME})
 
-rosbuild_add_executable(serial_listener_example
-  examples/serial_listener_example.cc)
-target_link_libraries(serial_listener_example ${PROJECT_NAME})
-
-# Create unit tests
-rosbuild_add_gtest(serial_tests tests/serial_tests.cc)
-target_link_libraries(serial_tests ${PROJECT_NAME})
-rosbuild_add_gtest(serial_listener_tests tests/serial_listener_tests.cc)
-target_link_libraries(serial_listener_tests ${PROJECT_NAME})
+  # Create unit tests
+  rosbuild_add_gtest(serial_tests tests/serial_tests.cc)
+  target_link_libraries(serial_tests ${PROJECT_NAME})
 
 endmacro(build_serial)
diff --git a/src/serial_listener.cc b/src/serial_listener.cc
deleted file mode 100644
index a7bbe98..0000000
--- a/src/serial_listener.cc
+++ /dev/null
@@ -1,217 +0,0 @@
-/* Copyright 2012 William Woodall and John Harrison */
-
-#include "serial/serial_listener.h"
-
-/***** Inline Functions *****/
-
-inline void defaultExceptionCallback(const std::exception &error) {
-  std::cerr << "SerialListener Unhandled Exception: " << error.what();
-  std::cerr << std::endl;
-}
-
-inline bool defaultComparator(const std::string &token) {
-  return token == token;
-}
-
-using namespace serial;
-
-/***** Listener Class Functions *****/
-
-void
-SerialListener::default_handler(const std::string &token) {
-  if (this->_default_handler)
-    this->_default_handler(token);
-}
-
-SerialListener::SerialListener() : listening(false), chunk_size_(5) {
-  // Set default callbacks
-  this->handle_exc = defaultExceptionCallback;
-
-  // Default handler stuff
-  this->_default_handler = NULL;
-  this->default_comparator = defaultComparator;
-  DataCallback tmp = boost::bind(&SerialListener::default_handler, this, _1);
-  this->default_filter = FilterPtr(new Filter(default_comparator, tmp));
-
-  // Set default tokenizer
-  this->setTokenizer(delimeter_tokenizer("\r"));
-}
-
-SerialListener::~SerialListener() {
-  if (this->listening) {
-    this->stopListening();
-  }
-}
-
-void
-SerialListener::callback() {
-  try {
-    // 
-    std::pair pair;
-    while (this->listening) {
-      if (this->callback_queue.timed_wait_and_pop(pair, 10)) {
-        if (this->listening) {
-          try {
-            if (pair.first != NULL && pair.second != NULL) {
-              pair.first->callback_((*pair.second));
-            }
-          } catch (std::exception &e) {
-            this->handle_exc(e);
-          }// try callback
-        } // if listening
-      } // if popped
-    } // while (this->listening)
-  } catch (std::exception &e) {
-    this->handle_exc(SerialListenerException(e.what()));
-  }
-}
-
-void
-SerialListener::startListening(Serial &serial_port) {
-  if (this->listening) {
-    throw(SerialListenerException("Already listening."));
-    return;
-  }
-  this->listening = true;
-  
-  this->serial_port_ = &serial_port;
-  if (!this->serial_port_->isOpen()) {
-    throw(SerialListenerException("Serial port not open."));
-    return;
-  }
-  
-  listen_thread = boost::thread(boost::bind(&SerialListener::listen, this));
-  
-  // Start the callback thread
-  callback_thread =
-   boost::thread(boost::bind(&SerialListener::callback, this));
-}
-
-void
-SerialListener::stopListening() {
-  // Stop listening and clear buffers
-  listening = false;
-
-  listen_thread.join();
-  callback_thread.join();
-
-  this->data_buffer = "";
-  this->serial_port_ = NULL;
-}
-
-size_t
-SerialListener::determineAmountToRead() {
-  // TODO: Make a more intelligent method based on the length of the things 
-  //  filters are looking for.  e.g.: if the filter is looking for 'V=XX\r' 
-  //  make the read amount at least 5.
-  return this->chunk_size_;
-}
-
-void
-SerialListener::filter(std::vector &tokens) {
-  // Lock the filters while filtering
-  boost::mutex::scoped_lock lock(filter_mux);
-  // Iterate through each new token and filter them
-  std::vector::iterator it;
-  for (it=tokens.begin(); it!=tokens.end(); it++) {
-    TokenPtr token = (*it);
-    // If it is empty then pass it
-    if (token->empty()) {
-      continue;
-    }
-    bool matched = false;
-    // Iterate through each filter
-    std::vector::iterator itt;
-    for (itt=filters.begin(); itt!=filters.end(); itt++) {
-      FilterPtr filter = (*itt);
-      if (filter->comparator_((*token))) {
-        callback_queue.push(std::make_pair(filter,token));
-        matched = true;
-        break;
-      }
-    } // for (itt=filters.begin(); itt!=filters.end(); itt++)
-    // If matched is false then send it to the default handler
-    if (!matched) {
-      callback_queue.push(std::make_pair(default_filter,token));
-    }
-  } // for (it=tokens.begin(); it!=tokens.end(); it++)
-}
-
-void
-SerialListener::listen() {
-  try {
-    while (this->listening) {
-      // Read some data
-      std::string temp;
-      this->readSomeData(temp, determineAmountToRead());
-      // If nothing was read then we
-      //  don't need to iterate through the filters
-      if (temp.length() != 0) {
-        // Add the new data to the buffer
-        this->data_buffer += temp;
-        // Call the tokenizer on the updated buffer
-        std::vector new_tokens;
-        this->tokenize(this->data_buffer, new_tokens);
-        // Put the last token back in the data buffer
-        this->data_buffer = (*new_tokens.back());
-        new_tokens.pop_back();
-        // Run the new tokens through existing filters
-        this->filter(new_tokens);
-      }
-      // Done parsing lines and buffer should now be set to the left overs
-    } // while (this->listening)
-  } catch (std::exception &e) {
-    this->handle_exc(SerialListenerException(e.what()));
-  }
-}
-
-/***** Filter Functions *****/
-
-FilterPtr
-SerialListener::createFilter(ComparatorType comparator, DataCallback callback)
-{
-  FilterPtr filter_ptr(new Filter(comparator, callback));
-
-  boost::mutex::scoped_lock l(filter_mux);
-  this->filters.push_back(filter_ptr);
-
-  return filter_ptr;
-}
-
-BlockingFilterPtr
-SerialListener::createBlockingFilter(ComparatorType comparator) {
-  return BlockingFilterPtr(
-    new BlockingFilter(comparator, (*this)));
-}
-
-BufferedFilterPtr
-SerialListener::createBufferedFilter(ComparatorType comparator,
-                                     size_t buffer_size)
-{
-  return BufferedFilterPtr(
-    new BufferedFilter(comparator, buffer_size, (*this)));
-}
-
-void
-SerialListener::removeFilter(FilterPtr filter_ptr) {
-  boost::mutex::scoped_lock l(filter_mux);
-  filters.erase(std::find(filters.begin(),filters.end(),filter_ptr));
-}
-
-void
-SerialListener::removeFilter(BlockingFilterPtr blocking_filter) {
-  this->removeFilter(blocking_filter->filter_ptr);
-}
-
-void
-SerialListener::removeFilter(BufferedFilterPtr buffered_filter) {
-  this->removeFilter(buffered_filter->filter_ptr);
-}
-
-void
-SerialListener::removeAllFilters() {
-  boost::mutex::scoped_lock l(filter_mux);
-  filters.clear();
-  callback_queue.clear();
-}
-
diff --git a/tests/serial_listener_tests.cc b/tests/serial_listener_tests.cc
deleted file mode 100644
index 52e12f1..0000000
--- a/tests/serial_listener_tests.cc
+++ /dev/null
@@ -1,238 +0,0 @@
-/* To run these tests you need to change the define below to the serial port 
- * with a loop back device attached.
- * 
- * Alternatively you could use an Arduino:
- * 
- *     void setup()
- *     {
- *       Serial.begin(115200);
- *     }
- *     
- *     void loop()
- *     {
- *       while (Serial.available() > 0) {
- *         Serial.write(Serial.read());
- *       }
- *     }
- * 
- */
-
-// #define SERIAL_PORT_NAME "/dev/tty.usbserial-A900cfJA"
-#define SERIAL_PORT_NAME "p0"
-
-#include "gtest/gtest.h"
-
-#include 
-
-// OMG this is so nasty...
-#define private public
-#define protected public
-
-#include "serial/serial_listener.h"
-using namespace serial;
-
-static size_t global_count, global_listen_count;
-static bool matched;
-
-void filter_handler(std::string token) {
-  global_listen_count++;
-  std::cout << "filter_handler got: " << token << std::endl;
-}
-
-void default_handler(std::string line) {
-  global_count++;
-  std::cout << "default_handler got: " << line << std::endl;
-}
-
-namespace {
-
-void my_sleep(long milliseconds) {
-  boost::this_thread::sleep(boost::posix_time::milliseconds(milliseconds));
-}
-
-class SerialListenerTests : public ::testing::Test {
-protected:
-  virtual void SetUp() {
-    port1 = new Serial("/dev/pty"SERIAL_PORT_NAME, 115200, 10);
-    port2 = new Serial("/dev/tty"SERIAL_PORT_NAME, 115200, 250);
-
-    listener.setDefaultHandler(default_handler);
-    listener.startListening((*port1));
-  }
-
-  virtual void TearDown() {
-    listener.stopListening();
-    delete port1;
-    delete port2;
-  }
-
-  SerialListener listener;
-  Serial * port1;
-  Serial * port2;
-
-};
-
-TEST_F(SerialListenerTests, handlesPartialMessage) {
-  global_count = 0;
-  std::string input_str = "?$1E\r$1E=Robo";
-
-  std::cout << "writing: ?$1E$1E=Robo" << std::endl;
-  port2->write(input_str);
-  // Allow time for processing
-  my_sleep(50);
-
-  ASSERT_EQ(1, global_count);
-
-  input_str = "?$1E\r$1E=Roboteq\r";
-  std::cout << "writing: ?$1E$1E=Roboteq" << std::endl;
-  port2->write(input_str);
-  // Allow time for processing
-  my_sleep(50);
-
-  ASSERT_EQ(3, global_count);
-}
-
-TEST_F(SerialListenerTests, normalFilterWorks) {
-  global_count = 0;
-  global_listen_count = 0;
-  std::string input_str = "?$1E\r$1E=Robo\rV=1334:1337\rT=123";
-
-  // Setup filter
-  FilterPtr filt_1 =
-    listener.createFilter(SerialListener::startsWith("V="), filter_handler);
-
-  std::cout << "writing: ?$1E$1E=RoboV=1334:1337T=123";
-  std::cout << std::endl;
-  port2->write(input_str);
-  // Allow time for processing
-  my_sleep(50);
-
-  ASSERT_EQ(2, global_count);
-  ASSERT_EQ(1, global_listen_count);
-}
-
-void run_blocking_filter(BlockingFilterPtr filt_1) {
-  // Wait 100 ms for a match
-  std::string temp = filt_1->wait(100);
-  if (temp.empty()) {
-    return;
-  }
-  std::cout << "blocking filter matched: " << temp << std::endl;
-  global_listen_count++;
-  matched = true;
-}
-
-TEST_F(SerialListenerTests, blockingFilterWorks) {
-  global_count = 0;
-  global_listen_count = 0;
-  matched = false;
-  std::string input_str = "?$1E\r$1E=Robo\rV=1334:1337\rT=123";
-
-  // Setup blocking filter
-  BlockingFilterPtr filt_1 =
-    listener.createBlockingFilter(SerialListener::startsWith("$1E="));
-
-  boost::thread t(boost::bind(run_blocking_filter, filt_1));
-
-  std::cout << "writing: ?$1E$1E=RoboV=1334:1337T=123";
-  std::cout << std::endl;
-  port2->write(input_str);
-  // Allow time for processing
-  my_sleep(50);
-
-  using boost::posix_time::milliseconds;
-  ASSERT_TRUE(t.timed_join(milliseconds(10)));
-  ASSERT_EQ(2, global_count);
-  ASSERT_EQ(1, global_listen_count);
-  ASSERT_TRUE(matched);
-}
-
-TEST_F(SerialListenerTests, blockingFilterTimesOut) {
-  global_count = 0;
-  global_listen_count = 0;
-  matched = false;
-  std::string input_str = "?$1E\r$1E=Robo\rV=1334:1337\rT=123";
-
-  // Setup blocking filter
-  BlockingFilterPtr filt_1 =
-    listener.createBlockingFilter(SerialListener::startsWith("T="));
-
-  boost::thread t(boost::bind(run_blocking_filter, filt_1));
-
-  std::cout << "writing: ?$1E$1E=RoboV=1334:1337T=123";
-  std::cout << std::endl;
-  port2->write(input_str);
-  // Allow time for processing
-  my_sleep(50);
-
-  using boost::posix_time::milliseconds;
-  // First one should not be within timeout, should be false
-  ASSERT_FALSE(t.timed_join(milliseconds(10)));
-  // Second one should capture timeout and return true to join
-  ASSERT_TRUE(t.timed_join(milliseconds(60)));
-  ASSERT_EQ(3, global_count);
-  ASSERT_EQ(0, global_listen_count);
-  ASSERT_FALSE(matched);
-}
-
-void write_later(Serial *port, std::string input_str, long wait_for) {
-  my_sleep(wait_for);
-  port->write(input_str);
-}
-
-TEST_F(SerialListenerTests, bufferedFilterWorks) {
-  global_count = 0;
-  std::string input_str = "?$1E\r+\r$1E=Robo\rV=1334:1337\rT=123";
-
-  // Setup buffered filter, buffer size 3
-  BufferedFilterPtr filt_1 =
-    listener.createBufferedFilter(SerialListener::exactly("+"), 3);
-
-  // Write the string to the port 10 ms in the future
-  boost::thread t(boost::bind(write_later, port2, input_str, 10));
-
-  // This should be empty because of a timeout
-  ASSERT_TRUE(filt_1->wait(2).empty());
-  // Make sure wait works properly
-  ASSERT_EQ("+", filt_1->wait(20));
-  // This should be empty cause there was only one
-  ASSERT_TRUE(filt_1->wait(2).empty());
-  // The queue in the filter should be empty
-  ASSERT_EQ(0, filt_1->queue.size());
-  ASSERT_EQ(3, global_count);
-  t.join();
-}
-
-TEST_F(SerialListenerTests, bufferedFilterQueueWorks) {
-  global_count = 0;
-  std::string input_str = "?$1E$\r+\r$1E=Robo$\rV=1334:1337$\rT=123$\r";
-
-  // Setup buffered filter, buffer size 3
-  BufferedFilterPtr filt_1 =
-    listener.createBufferedFilter(SerialListener::endsWith("$"), 3);
-
-  // write the string
-  port2->write(input_str);
-
-  my_sleep(20); // Let things process
-  // There should have been four matches
-  //   therefore the first one should the second match.
-  ASSERT_EQ("$1E=Robo$", filt_1->wait(1));
-  ASSERT_EQ("V=1334:1337$", filt_1->wait(1));
-  ASSERT_EQ("T=123$", filt_1->wait(1));
-  ASSERT_EQ(0, filt_1->queue.size());
-
-  ASSERT_EQ(1, global_count);
-}
-
-}  // namespace
-
-int main(int argc, char **argv) {
-  try {
-    ::testing::InitGoogleTest(&argc, argv);
-    return RUN_ALL_TESTS();
-  } catch (std::exception &e) {
-    std::cerr << "Unhandled Exception: " << e.what() << std::endl;
-  }
-  return 1;
-}