src/Network/Buffer.hh
author Tero Marttila <terom@fixme.fi>
Fri, 16 Jan 2009 21:24:45 +0200
changeset 399 c7295b72731a
parent 380 d193dd1d8a7e
child 400 d64bf28c4340
permissions -rw-r--r--
documentation work on Network
200
2dbf40661580 better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff changeset
     1
#ifndef NETWORK_BUFFER_HH
2dbf40661580 better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff changeset
     2
#define NETWORK_BUFFER_HH
2dbf40661580 better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff changeset
     3
399
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
     4
/**
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
     5
 * @file
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
     6
 *
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
     7
 * Buffering of network streams
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
     8
 */
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
     9
200
2dbf40661580 better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff changeset
    10
#include "Socket.hh"
2dbf40661580 better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff changeset
    11
#include "../Error.hh"
2dbf40661580 better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff changeset
    12
2dbf40661580 better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff changeset
    13
#include <cassert>
2dbf40661580 better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff changeset
    14
284
27ce69fd1e06 work on Network doxygen docs
terom
parents: 200
diff changeset
    15
/**
200
2dbf40661580 better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff changeset
    16
 * Minimum chunk size to avoid handling single bytes at a time (for resize, mainly)
2dbf40661580 better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff changeset
    17
 */
2dbf40661580 better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff changeset
    18
const size_t NETWORK_BUFFER_CHUNK_SIZE = 1024;
2dbf40661580 better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff changeset
    19
284
27ce69fd1e06 work on Network doxygen docs
terom
parents: 200
diff changeset
    20
/**
27ce69fd1e06 work on Network doxygen docs
terom
parents: 200
diff changeset
    21
 * Base class of errors thrown by NetworkBuffer* methods
27ce69fd1e06 work on Network doxygen docs
terom
parents: 200
diff changeset
    22
 */
200
2dbf40661580 better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff changeset
    23
class NetworkBufferError : public Error {
2dbf40661580 better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff changeset
    24
    public:
2dbf40661580 better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff changeset
    25
        NetworkBufferError (const std::string &message) : Error(message) { }
2dbf40661580 better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff changeset
    26
};
2dbf40661580 better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff changeset
    27
284
27ce69fd1e06 work on Network doxygen docs
terom
parents: 200
diff changeset
    28
/**
399
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
    29
 * Base buffer-manipulation operations for buffered socket send/recv.
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
    30
 *
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
    31
 * This implements a simple linear in-memory buffer which can contain data that must be buffered for send/recv.
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
    32
 * New data can be written to the end of the buffer, and data can be read/discarded from the beginning.
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
    33
 *
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
    34
 * A buffer is associated with a NetworkSocket, and takes care of all send/recv activity.
200
2dbf40661580 better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff changeset
    35
 */
2dbf40661580 better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff changeset
    36
class NetworkBufferBase {
2dbf40661580 better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff changeset
    37
    protected:
284
27ce69fd1e06 work on Network doxygen docs
terom
parents: 200
diff changeset
    38
        /** The socket that we use */
378
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 365
diff changeset
    39
        NetworkSocket *socket;
284
27ce69fd1e06 work on Network doxygen docs
terom
parents: 200
diff changeset
    40
        
27ce69fd1e06 work on Network doxygen docs
terom
parents: 200
diff changeset
    41
        /** The buffer itself */
27ce69fd1e06 work on Network doxygen docs
terom
parents: 200
diff changeset
    42
        char *buf;
200
2dbf40661580 better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff changeset
    43
399
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
    44
        /** Buffer size and current write offset */
200
2dbf40661580 better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff changeset
    45
        size_t size, offset;
2dbf40661580 better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff changeset
    46
    
2dbf40661580 better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff changeset
    47
    public:
284
27ce69fd1e06 work on Network doxygen docs
terom
parents: 200
diff changeset
    48
        /**
27ce69fd1e06 work on Network doxygen docs
terom
parents: 200
diff changeset
    49
         * Allocate buf using the given initial size, and set offset to zero
27ce69fd1e06 work on Network doxygen docs
terom
parents: 200
diff changeset
    50
         */
378
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 365
diff changeset
    51
        NetworkBufferBase (NetworkSocket *socket, size_t size_hint);
284
27ce69fd1e06 work on Network doxygen docs
terom
parents: 200
diff changeset
    52
27ce69fd1e06 work on Network doxygen docs
terom
parents: 200
diff changeset
    53
        /**
27ce69fd1e06 work on Network doxygen docs
terom
parents: 200
diff changeset
    54
         * Free()'s the buf
27ce69fd1e06 work on Network doxygen docs
terom
parents: 200
diff changeset
    55
         */
200
2dbf40661580 better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff changeset
    56
        ~NetworkBufferBase (void);
2dbf40661580 better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff changeset
    57
    
2dbf40661580 better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff changeset
    58
    private:
284
27ce69fd1e06 work on Network doxygen docs
terom
parents: 200
diff changeset
    59
        /**
27ce69fd1e06 work on Network doxygen docs
terom
parents: 200
diff changeset
    60
         * No copying, these are undefined
27ce69fd1e06 work on Network doxygen docs
terom
parents: 200
diff changeset
    61
         */
200
2dbf40661580 better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff changeset
    62
        NetworkBufferBase (const NetworkBufferBase &copy);
2dbf40661580 better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff changeset
    63
        NetworkBufferBase& operator= (const NetworkBufferBase &copy);
2dbf40661580 better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff changeset
    64
    
2dbf40661580 better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff changeset
    65
    protected:
284
27ce69fd1e06 work on Network doxygen docs
terom
parents: 200
diff changeset
    66
        /**
27ce69fd1e06 work on Network doxygen docs
terom
parents: 200
diff changeset
    67
         * Resize the buffer, allocating enough new space to hold <item_size> bytes at the end, and leaving any
399
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
    68
         * existing data at the beginning in-place.
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
    69
         *
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
    70
         * This is done by doubling the buffer size until item_size fits, and then reallocing (if needed).
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
    71
         * Currently, the buffer is never shrunk, although it probably should be to adapt better to peak load (e.g.
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
    72
         * when a player joins and the map data is transmitted...).
284
27ce69fd1e06 work on Network doxygen docs
terom
parents: 200
diff changeset
    73
         *
27ce69fd1e06 work on Network doxygen docs
terom
parents: 200
diff changeset
    74
         * @param item_size the number of bytes that must fit at the end of the buffer
27ce69fd1e06 work on Network doxygen docs
terom
parents: 200
diff changeset
    75
         */
200
2dbf40661580 better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff changeset
    76
        void resize (size_t item_size);
284
27ce69fd1e06 work on Network doxygen docs
terom
parents: 200
diff changeset
    77
27ce69fd1e06 work on Network doxygen docs
terom
parents: 200
diff changeset
    78
        /**
27ce69fd1e06 work on Network doxygen docs
terom
parents: 200
diff changeset
    79
         * Trim the buffer, discarding <prefix_size> bytes at the beginning. Updates offset to match.
27ce69fd1e06 work on Network doxygen docs
terom
parents: 200
diff changeset
    80
         *
399
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
    81
         * Currently, this is implemented as a simple memmove() of all the remaining data in the buffer, which may be
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
    82
         * slow under some load patterns.
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
    83
         *
284
27ce69fd1e06 work on Network doxygen docs
terom
parents: 200
diff changeset
    84
         * @param prefix_size the number of bytes to discard
27ce69fd1e06 work on Network doxygen docs
terom
parents: 200
diff changeset
    85
         */
200
2dbf40661580 better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff changeset
    86
        void trim (size_t prefix_size);
2dbf40661580 better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff changeset
    87
};
2dbf40661580 better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff changeset
    88
284
27ce69fd1e06 work on Network doxygen docs
terom
parents: 200
diff changeset
    89
/**
200
2dbf40661580 better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff changeset
    90
 * Buffered prefix-len socket input
399
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
    91
 *
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
    92
 * This handles calling recv() on the socket, and is specialized to handle a stream of messages prefixed with a length
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
    93
 * header (uint16_t or uint32_t). Use the peek_data() method to receive these messages when NetworkSocket::sig_read() 
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
    94
 * indicates that more data is available.
200
2dbf40661580 better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff changeset
    95
 */
2dbf40661580 better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff changeset
    96
class NetworkBufferInput : public NetworkBufferBase {
2dbf40661580 better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff changeset
    97
    public:
284
27ce69fd1e06 work on Network doxygen docs
terom
parents: 200
diff changeset
    98
        /**
27ce69fd1e06 work on Network doxygen docs
terom
parents: 200
diff changeset
    99
         * @see NetworkBufferBase
27ce69fd1e06 work on Network doxygen docs
terom
parents: 200
diff changeset
   100
         */
378
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 365
diff changeset
   101
        NetworkBufferInput (NetworkSocket *socket, size_t size_hint);
200
2dbf40661580 better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff changeset
   102
2dbf40661580 better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff changeset
   103
    private:
284
27ce69fd1e06 work on Network doxygen docs
terom
parents: 200
diff changeset
   104
        /**
27ce69fd1e06 work on Network doxygen docs
terom
parents: 200
diff changeset
   105
         * Attempts to recv the given number of bytes into our buf, returning true on success
27ce69fd1e06 work on Network doxygen docs
terom
parents: 200
diff changeset
   106
         *
27ce69fd1e06 work on Network doxygen docs
terom
parents: 200
diff changeset
   107
         * @param item_size minimum number of bytes of data that we need in the buffer
27ce69fd1e06 work on Network doxygen docs
terom
parents: 200
diff changeset
   108
         * @return bool true if the buffer now contains at least item_size bytes
200
2dbf40661580 better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff changeset
   109
         */
2dbf40661580 better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff changeset
   110
        bool try_read (size_t item_size);
2dbf40661580 better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff changeset
   111
284
27ce69fd1e06 work on Network doxygen docs
terom
parents: 200
diff changeset
   112
        /**
27ce69fd1e06 work on Network doxygen docs
terom
parents: 200
diff changeset
   113
         * Tests if the buffer contains at least the given amount of data, but doesn't recv or anything
27ce69fd1e06 work on Network doxygen docs
terom
parents: 200
diff changeset
   114
         *
27ce69fd1e06 work on Network doxygen docs
terom
parents: 200
diff changeset
   115
         * @param data_size number of bytes that we are expecting
27ce69fd1e06 work on Network doxygen docs
terom
parents: 200
diff changeset
   116
         * @return bool true if the buffer contains at least data_size bytes
200
2dbf40661580 better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff changeset
   117
         */
2dbf40661580 better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff changeset
   118
        bool have_data (size_t data_size);
2dbf40661580 better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff changeset
   119
    
2dbf40661580 better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff changeset
   120
    public:
284
27ce69fd1e06 work on Network doxygen docs
terom
parents: 200
diff changeset
   121
        // @{
27ce69fd1e06 work on Network doxygen docs
terom
parents: 200
diff changeset
   122
        /**
27ce69fd1e06 work on Network doxygen docs
terom
parents: 200
diff changeset
   123
         *
27ce69fd1e06 work on Network doxygen docs
terom
parents: 200
diff changeset
   124
         * Attempts to read the length prefix into val_ref, returning true on success, false if there's not enough data
27ce69fd1e06 work on Network doxygen docs
terom
parents: 200
diff changeset
   125
         * in the buffer
27ce69fd1e06 work on Network doxygen docs
terom
parents: 200
diff changeset
   126
         *
27ce69fd1e06 work on Network doxygen docs
terom
parents: 200
diff changeset
   127
         * @param val_ref stores the value read here if we have it
27ce69fd1e06 work on Network doxygen docs
terom
parents: 200
diff changeset
   128
         * @return bool was val_ref set
200
2dbf40661580 better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff changeset
   129
         */
2dbf40661580 better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff changeset
   130
        bool peek_prefix (uint16_t &val_ref);
2dbf40661580 better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff changeset
   131
        bool peek_prefix (uint32_t &val_ref);
284
27ce69fd1e06 work on Network doxygen docs
terom
parents: 200
diff changeset
   132
        // @} 
200
2dbf40661580 better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff changeset
   133
        
284
27ce69fd1e06 work on Network doxygen docs
terom
parents: 200
diff changeset
   134
        /**
399
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
   135
         * This attempts to locate a full message in the buffer (calling recv as nessecary), prefixed with a length
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
   136
         * prefix of the given type (using peek_prefix). If succesfull (we have a full message in the buffer), 
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
   137
         * \a prefix will be updated to the length of the message (not including the prefix), and \a buf_ref will be
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
   138
         * updated to point at the message of \a prefix bytes (not including the prefix) in our internal buffer memory.
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
   139
         * If a full message could not be received (recv would block), this will return false.
284
27ce69fd1e06 work on Network doxygen docs
terom
parents: 200
diff changeset
   140
         *
399
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
   141
         * Once you have processed the message, call flush_data() to remove the unused message from the buffer.
284
27ce69fd1e06 work on Network doxygen docs
terom
parents: 200
diff changeset
   142
         *
399
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
   143
         * @param prefix updated to the message length
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
   144
         * @param buf_ref updated to point at the message data
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
   145
         * @return bool true if we have a full message, false if we need to wait for more data on the socket
284
27ce69fd1e06 work on Network doxygen docs
terom
parents: 200
diff changeset
   146
         *
27ce69fd1e06 work on Network doxygen docs
terom
parents: 200
diff changeset
   147
         * @see peek_prefix
27ce69fd1e06 work on Network doxygen docs
terom
parents: 200
diff changeset
   148
         * @see flush_data
200
2dbf40661580 better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff changeset
   149
         */
399
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
   150
        template <typename PrefixType> bool peek_data (PrefixType &prefix, char *&buf_ref);
284
27ce69fd1e06 work on Network doxygen docs
terom
parents: 200
diff changeset
   151
          
27ce69fd1e06 work on Network doxygen docs
terom
parents: 200
diff changeset
   152
        /**
399
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
   153
         * This flushes the current message from the buffer, as returned when peek_data returns true. It is a bug to
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
   154
         * call flush_data when there is no full message present, the behaviour is unspecified (most likely an
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
   155
         * assert()).
284
27ce69fd1e06 work on Network doxygen docs
terom
parents: 200
diff changeset
   156
         *
27ce69fd1e06 work on Network doxygen docs
terom
parents: 200
diff changeset
   157
         * @see peek_data
27ce69fd1e06 work on Network doxygen docs
terom
parents: 200
diff changeset
   158
         */
399
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
   159
        template <typename PrefixType> void flush_data (void);
200
2dbf40661580 better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff changeset
   160
};
2dbf40661580 better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff changeset
   161
284
27ce69fd1e06 work on Network doxygen docs
terom
parents: 200
diff changeset
   162
/**
399
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
   163
 * Buffered prefix-len socket output.
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
   164
 *
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
   165
 * This handles calling send() on the socket, and is specialized to handle a stream of message prefixed with a length
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
   166
 * header (uint16_t or uint32_t). You can write messages using write_prefix(), and they will be buffered if needed.
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
   167
 * If write_prefix() returns true (socket buffer full), then you must register the socket for
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
   168
 * NetworkSocket::set_poll_write(), and call flush_write() once NetworkSocket::sig_write() is triggered. The socket's
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
   169
 * poll_write should be unregistered once flush_write returns false (no more buffered data remaining to be sent), or
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
   170
 * an many processor cycles will be wasted, for the socket will remain ready for write until its buffer fills up again.
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
   171
 *
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
   172
 * Data is not buffered needlessly; if the socket's buffer has room, write_prefix will not have to touch our internal
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
   173
 * buffer. In fact, write_prefix will rarely return false except under heavy network congestion with high levels of
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
   174
 * traffic on the socket.
200
2dbf40661580 better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff changeset
   175
 */
2dbf40661580 better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff changeset
   176
class NetworkBufferOutput : public NetworkBufferBase {
2dbf40661580 better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff changeset
   177
    public:
284
27ce69fd1e06 work on Network doxygen docs
terom
parents: 200
diff changeset
   178
        /**
27ce69fd1e06 work on Network doxygen docs
terom
parents: 200
diff changeset
   179
         * @see NetworkBufferBase
27ce69fd1e06 work on Network doxygen docs
terom
parents: 200
diff changeset
   180
         */
378
5589abf5e61b break the network code. Too late to set up a branch for this now
terom
parents: 365
diff changeset
   181
        NetworkBufferOutput (NetworkSocket *socket, size_t size_hint);
200
2dbf40661580 better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff changeset
   182
2dbf40661580 better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff changeset
   183
    private:
284
27ce69fd1e06 work on Network doxygen docs
terom
parents: 200
diff changeset
   184
        /**
399
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
   185
         * Write the given data to the socket, either now or later. 
284
27ce69fd1e06 work on Network doxygen docs
terom
parents: 200
diff changeset
   186
         *
27ce69fd1e06 work on Network doxygen docs
terom
parents: 200
diff changeset
   187
         * If our buffer is empty, fast-path the given buf_ptr directly to send(), then copy the remaining portion to
27ce69fd1e06 work on Network doxygen docs
terom
parents: 200
diff changeset
   188
         * our buffer for later use with flush_write.
27ce69fd1e06 work on Network doxygen docs
terom
parents: 200
diff changeset
   189
         *
27ce69fd1e06 work on Network doxygen docs
terom
parents: 200
diff changeset
   190
         * @param buf_ptr the data that we need to send
27ce69fd1e06 work on Network doxygen docs
terom
parents: 200
diff changeset
   191
         * @param buf_size number of bytes in buf_ptr
200
2dbf40661580 better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff changeset
   192
         */
2dbf40661580 better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff changeset
   193
        void push_write (char *buf_ptr, size_t buf_size);
2dbf40661580 better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff changeset
   194
   
2dbf40661580 better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff changeset
   195
    public:    
284
27ce69fd1e06 work on Network doxygen docs
terom
parents: 200
diff changeset
   196
        /**
399
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
   197
         * If we have data in our buffer, flush it out using send(). This should be called once the socket indicates it
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
   198
         * is ready for write again after a call to write_prefix that returned false. Once this returns false, the
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
   199
         * NetworkSocket::set_poll_write() flag should be unset again to avoid needless calls to this.
380
d193dd1d8a7e new NetworkReactor, fix everything to actually work
terom
parents: 378
diff changeset
   200
         *
399
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
   201
         * @return true if there's still buffered data left to write, false otherwise (buffer is empty)
200
2dbf40661580 better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff changeset
   202
         */
380
d193dd1d8a7e new NetworkReactor, fix everything to actually work
terom
parents: 378
diff changeset
   203
        bool flush_write (void);
200
2dbf40661580 better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff changeset
   204
        
284
27ce69fd1e06 work on Network doxygen docs
terom
parents: 200
diff changeset
   205
        // @{
27ce69fd1e06 work on Network doxygen docs
terom
parents: 200
diff changeset
   206
        /**
399
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
   207
         * Write out the given message, writing first the prefix, and then the data itself, using push_write.
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
   208
         *
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
   209
         * Returns true if the data was passed on to the socket API directly, false if a portion of it had to be
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
   210
         * buffered (if there is already data buffered, all subsequent write_prefix's will buffer the full message
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
   211
         * until our buffer is empty again). If this method returns false, you must register the socket for
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
   212
         * poll_write and call flush_write later.
380
d193dd1d8a7e new NetworkReactor, fix everything to actually work
terom
parents: 378
diff changeset
   213
         * 
284
27ce69fd1e06 work on Network doxygen docs
terom
parents: 200
diff changeset
   214
         * @param buf the data to write
27ce69fd1e06 work on Network doxygen docs
terom
parents: 200
diff changeset
   215
         * @param prefix the amount of data
380
d193dd1d8a7e new NetworkReactor, fix everything to actually work
terom
parents: 378
diff changeset
   216
         * @return true if we had to buffer data, false otherwise
200
2dbf40661580 better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff changeset
   217
         */
380
d193dd1d8a7e new NetworkReactor, fix everything to actually work
terom
parents: 378
diff changeset
   218
        bool write_prefix (char *buf, uint16_t prefix);
d193dd1d8a7e new NetworkReactor, fix everything to actually work
terom
parents: 378
diff changeset
   219
        bool write_prefix (char *buf, uint32_t prefix);
284
27ce69fd1e06 work on Network doxygen docs
terom
parents: 200
diff changeset
   220
        // @}
200
2dbf40661580 better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff changeset
   221
};
2dbf40661580 better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff changeset
   222
399
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
   223
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
   224
/*
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
   225
 * NetworkBufferInput template method implementation
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
   226
 */
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
   227
template <typename PrefixType> bool NetworkBufferOutput::peek_data (PrefixType &prefix, char *&buf_ref) {
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
   228
    size_t missing = 0;
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
   229
    
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
   230
    do {    
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
   231
        // do we have the prefix?
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
   232
        if (peek_prefix(prefix)) {
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
   233
            // do we already have the payload?
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
   234
            if (offset >= sizeof(PrefixType) + prefix) {
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
   235
                break;
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
   236
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
   237
            } else {
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
   238
                missing = (sizeof(PrefixType) + prefix) - offset;
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
   239
            }
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
   240
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
   241
        } else {
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
   242
            missing = sizeof(PrefixType);
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
   243
        }
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
   244
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
   245
        // sanity-check (above >= and - should never happen like this)
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
   246
        assert(missing);
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
   247
        
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
   248
        // try and read the missing data
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
   249
        if (try_read(missing) == false) {
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
   250
            // if unable to read what we need, return zero.
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
   251
            return false;
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
   252
        }
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
   253
        
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
   254
        // assess the situation again
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
   255
    } while (true);
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
   256
    
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
   257
    // update the buf_ref to point past the prefix-length
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
   258
    buf_ref = buf + sizeof(PrefixType);
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
   259
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
   260
    // return message
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
   261
    return true;
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
   262
}
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
   263
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
   264
template <typename PrefixType> void NetworkBufferOutput::flush_data (void) {
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
   265
    PrefixType prefix;
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
   266
    
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
   267
    // we *must* have a valid prefix
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
   268
    if (!peek_prefix(prefix))
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
   269
        assert(false);
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
   270
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
   271
    // ensure that we have the data to trim...
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
   272
    assert(offset >= sizeof(PrefixType) + prefix);
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
   273
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
   274
    // trim the bytes out
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
   275
    trim(sizeof(PrefixType) + prefix);
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
   276
}
c7295b72731a documentation work on Network
Tero Marttila <terom@fixme.fi>
parents: 380
diff changeset
   277
200
2dbf40661580 better NetworkBuffer/Packet stuff + some additional Physics+Network stuff + random fixes
terom
parents:
diff changeset
   278
#endif