/*

    Copyright (C) 2009  Matthew William Coan

    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 3 of the License, or
    (at your option) 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, see <http://www.gnu.org/licenses/>.

TCP/IP IOStreams like class.

Use a template member function with a data stream class as the template
type. pipe_stream, iostream, fstream, tcp_stream and others.

Author: Matthew W. Coan
Date: Fri Jun 18 14:04:57 EDT 2010
 
*/

#ifndef _TCP_STREAM_H
#define _TCP_STREAM_H

//#define OS_UNIX
#define OS_WINDOWS

#ifdef OS_UNIX
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>

#include <netinet/in.h>
#include <arpa/inet.h>

#include <netdb.h>
#endif 

#ifdef OS_WINDOWS
#include <winsock2.h>
#include <stdio.h>
#include <assert.h>
#endif

#include <iostream>
#include <string>
#include <cstdlib>
#include <cstring>

namespace net_tools {

using namespace std;

static const size_t IO_BUFFER_SIZE = 1024;

class tcp_stream {
   bool _error;
   int _fd;
   char _buffer[IO_BUFFER_SIZE];
   const char * _ip_address;
   int _port;
   bool _open;

public:
   tcp_stream(int fd);

   tcp_stream(const char * ip_address, 
              const int port);

   virtual ~tcp_stream();

   void clearerr();

   operator void*();

   tcp_stream & operator<<(int i);

   tcp_stream & operator<<(const char * str);

   tcp_stream & operator<<(const string & str);

   tcp_stream & operator>>(string & str);

   tcp_stream & operator>>(int & i);

   char get();

   void write(const char * ptr, size_t sz) {
      send(_fd, ptr, sz, 0);
   }

   string read_line(size_t max = 1024) {
      string line;

      char ch = get();

      while(*this) {
         if(ch == '\n')
            break;

         line += ch;

         if(line.size() >= max)
            break;

         ch = get();
      }
  
      return line;
   }

   void close();
};

}

#endif /* _TCP_STREAM_H */
