Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members  

OutSerializer.h

00001 #ifndef _STR_OutSerializer_H_  // -*-c++-*-
00002 
00003 /*
00004  * Copyright 1991-2002 Eric M. Hopper <hopper@omnifarious.org>
00005  * 
00006  *     This program is free software; you can redistribute it and/or modify it
00007  *     under the terms of the GNU Lesser General Public License as published
00008  *     by the Free Software Foundation; either version 2 of the License, or
00009  *     (at your option) any later version.
00010  * 
00011  *     This program is distributed in the hope that it will be useful, but
00012  *     WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  *     Lesser General Public License for more details.
00015  * 
00016  *     You should have received a copy of the GNU Lesser General Public
00017  *     License along with this program; if not, write to the Free Software
00018  *     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00019  */
00020 
00021 #ifdef __GNUG__
00022 #  pragma interface
00023 #endif
00024 
00025 /* $Header: /home/hopper/src/cvs/C++/StrMod/StrMod/OutSerializer.h,v 1.9 2002/11/25 05:40:05 hopper Exp $ */
00026 
00027 // For a log, see ../ChangeLog
00028 //
00029 // Revision 1.2  1998/06/02 00:30:53  hopper
00030 // Fixed a small bug that caused adding a 2 bytes value to not work
00031 // correctly.
00032 //
00033 // Revision 1.1  1997/04/11 17:44:15  hopper
00034 // Added OutSerializer class for simple serialization of basic data types.
00035 //
00036 
00037 #include <StrMod/BufferChunk.h>
00038 #include <LCore/GenTypes.h>
00039 #include <cstring>
00040 #include <string>
00041 
00042 #define _STR_OutSerializer_H_
00043 
00044 namespace strmod {
00045 namespace strmod {
00046 
00047 /** \class OutSerializer OutSerializer.h StrMod/OutSerializer.h
00048  * A class that marshals data into a canonical binary format.
00049  *
00050  * This class serializes integers of various sizes and strings into a canonical
00051  * binary format that can be given to an InSerializer on a completely different
00052  * platform to read the data back in.
00053  */
00054 class OutSerializer
00055 {
00056  public:
00057    struct State;
00058 
00059    OutSerializer(size_t suggested_size);
00060    /** \brief Use this as the external state to save into on destruction, only
00061     * use this if you've read the directions.  :-)
00062     *
00063     * This class can be much more efficient if it's always instantiated locally.
00064     * Sometimes though, the state will need to be saved across function calls.
00065     * That's where this constructor comes in.
00066     *
00067     * If the takeChunk function is called, a flag is set in the external state
00068     * (that is also set when the external state is initially constructed) that
00069     * tells this OutSerializer constructor that it needs to reset the state.
00070     */
00071    OutSerializer(State &savedstate);
00072    OutSerializer();
00073    virtual ~OutSerializer();
00074 
00075    inline void addS1Byte(lcore::S1Byte num);
00076    inline void addU1Byte(lcore::U1Byte num);
00077 
00078    inline void addS2Byte(lcore::S2Byte num);
00079    inline void addU2Byte(lcore::U2Byte num);
00080 
00081    inline void addS4Byte(lcore::S4Byte num);
00082    inline void addU4Byte(lcore::U4Byte num);
00083 
00084    void addBool(bool val)                    { addU1Byte(lcore::U1Byte(val)); }
00085 
00086    void addString(const ::std::string &str);
00087    void addString(const char *str);  // C style string.
00088 
00089    inline void addRaw(const void *data, size_t len);
00090 
00091    inline void setMinSuggestedSize(size_t size);
00092 
00093    //: It is an error to call this function more than once.  The chunk you get
00094    //: has exactly the number of bytes you put in.
00095    BufferChunk *takeChunk();
00096 
00097    //: Holds the state of the OutSerializer so it can be saved and restored.
00098    // <p>All inline functions here are defined in the .cxx fileI have heard th
00099    class State {
00100     public:
00101       friend class OutSerializer;
00102       //: Assumes ownership of fact.
00103       inline State(BufferChunk::Factory *fact);
00104 
00105     private:
00106       BufferChunk::Factory * const fact_;
00107       BufferChunk *cur_chunk_;
00108       lcore::U1Byte *buf_;
00109       size_t chnklen_;
00110       size_t cur_pos_;
00111 
00112       inline State(const State &b);
00113       inline const State &operator =(const State &b) ;
00114    };
00115 
00116  private:
00117    struct State state_;
00118    struct State * const external_state_;
00119 
00120    void resizeChunk(size_t newsize);
00121 };
00122 
00123 //-----------------------------inline functions--------------------------------
00124 
00125 inline void OutSerializer::setMinSuggestedSize(size_t size)
00126 {
00127    if (size > state_.chnklen_) {
00128       resizeChunk(size);
00129    }
00130 }
00131 
00132 inline void OutSerializer::addS1Byte(lcore::S1Byte num)
00133 {
00134    setMinSuggestedSize(state_.cur_pos_ + 1);
00135 
00136    lcore::hton(num, state_.buf_ + state_.cur_pos_);
00137    state_.cur_pos_++;
00138 }
00139 
00140 inline void OutSerializer::addU1Byte(lcore::U1Byte num)
00141 {
00142    setMinSuggestedSize(state_.cur_pos_ + 1);
00143 
00144    lcore::hton(num, state_.buf_ + state_.cur_pos_);
00145    state_.cur_pos_++;
00146 }
00147 
00148 inline void OutSerializer::addS2Byte(lcore::S2Byte num)
00149 {
00150    setMinSuggestedSize(state_.cur_pos_ + 2);
00151 
00152    lcore::hton(num, state_.buf_ + state_.cur_pos_);
00153    state_.cur_pos_ += 2;
00154 }
00155 
00156 inline void OutSerializer::addU2Byte(lcore::U2Byte num)
00157 {
00158    setMinSuggestedSize(state_.cur_pos_ + 2);
00159 
00160    lcore::hton(num, state_.buf_ + state_.cur_pos_);
00161    state_.cur_pos_ += 2;
00162 }
00163 
00164 inline void OutSerializer::addS4Byte(lcore::S4Byte num)
00165 {
00166    setMinSuggestedSize(state_.cur_pos_ + 4);
00167 
00168    lcore::hton(num, state_.buf_ + state_.cur_pos_);
00169    state_.cur_pos_ += 4;
00170 }
00171 
00172 inline void OutSerializer::addU4Byte(lcore::U4Byte num)
00173 {
00174    setMinSuggestedSize(state_.cur_pos_ + 4);
00175 
00176    lcore::hton(num, state_.buf_ + state_.cur_pos_);
00177    state_.cur_pos_ += 4;
00178 }
00179 
00180 inline void OutSerializer::addRaw(const void *data, size_t len)
00181 {
00182    setMinSuggestedSize(state_.cur_pos_ + len);
00183 
00184    memcpy(state_.buf_ + state_.cur_pos_, data, len);
00185    state_.cur_pos_ += len;
00186 }
00187 
00188 //---
00189 
00190 inline OutSerializer &operator <<(OutSerializer &os, lcore::S1Byte num)
00191 {
00192    os.addS1Byte(num);
00193    return(os);
00194 }
00195 
00196 inline OutSerializer &operator <<(OutSerializer &os, lcore::U1Byte num)
00197 {
00198    os.addU1Byte(num);
00199    return(os);
00200 }
00201 
00202 inline OutSerializer &operator <<(OutSerializer &os, lcore::S2Byte num)
00203 {
00204    os.addS2Byte(num);
00205    return(os);
00206 }
00207 
00208 inline OutSerializer &operator <<(OutSerializer &os, lcore::U2Byte num)
00209 {
00210    os.addU2Byte(num);
00211    return(os);
00212 }
00213 
00214 inline OutSerializer &operator <<(OutSerializer &os, lcore::S4Byte num)
00215 {
00216    os.addS4Byte(num);
00217    return(os);
00218 }
00219 
00220 inline OutSerializer &operator <<(OutSerializer &os, lcore::U4Byte num)
00221 {
00222    os.addU4Byte(num);
00223    return(os);
00224 }
00225 
00226 inline OutSerializer &operator <<(OutSerializer &os, const ::std::string &str)
00227 {
00228    os.addString(str);
00229    return(os);
00230 }
00231 
00232 inline OutSerializer &operator <<(OutSerializer &os, const char *str)
00233 {
00234    os.addString(str);
00235    return(os);
00236 }
00237 
00238 };  // namespace strmod
00239 };  // namespace strmod
00240 
00241 #endif

Generated on Wed Jan 29 00:32:44 2003 for libNet by doxygen1.3-rc1