StreamOps.h

Go to the documentation of this file.
00001 //
00002 //  Copyright (C) 2002-2008 Greg Landrum and Rational Discovery LLC
00003 //
00004 //  @@ All Rights Reserved @@
00005 //
00006 //
00007 #ifndef _RD_STREAMOPS_H
00008 #define _RD_STREAMOPS_H
00009 
00010 #include "types.h"
00011 #include <string>
00012 #include <sstream>
00013 #include <iostream>
00014 #include <boost/cstdint.hpp>
00015 
00016 
00017 namespace RDKit{
00018     
00019   //! Packs an integer and outputs it to a stream
00020   inline void appendPackedIntToStream(std::stringstream &ss, boost::uint32_t num) {
00021     int nbytes, bix;
00022     unsigned int val, res;
00023     char tc;
00024     
00025     CHECK_INVARIANT(num >= 0, "");
00026     res = num;
00027     while (1) {
00028       if (res < (1<<7)) {
00029         val = (res<<1);
00030         nbytes = 1;
00031         break;
00032       }
00033       res -= (1<<7);
00034       if (res < (1<<14)) {
00035         val = ((res<<2) | 1);
00036         nbytes = 2;
00037         break;
00038       }
00039       res -= (1<<14);
00040       if (res < (1<<21)) {
00041         val = ((res<<3) | 3);
00042         nbytes = 3;
00043         break;
00044       }
00045       res -= (1<<21);
00046       if ( res < (1<<29)) {
00047         val = ((res<<3) | 7);
00048         nbytes = 4;
00049         break;
00050       }
00051       else {
00052         CHECK_INVARIANT(0, "ERROR: Integer to big to pack\n");
00053       }
00054     }
00055     
00056     for (bix = 0; bix < nbytes; bix++) {
00057       tc = (char) (val & 255);
00058       ss.write(&tc, 1);
00059       val >>= 8;
00060     }
00061   }
00062   
00063   //! Reads an integer from a stream in packed format and returns the result.
00064   inline boost::uint32_t readPackedIntFromStream(std::stringstream &ss) {
00065     boost::uint32_t val, num;
00066     int shift, offset;
00067     char tmp;
00068     ss.read(&tmp, sizeof(tmp));
00069     val = UCHAR(tmp);
00070     offset = 0;
00071     if ((val&1) == 0) {
00072       shift = 1;
00073     }
00074     else if ((val&3) == 1) {
00075       ss.read((char *)&tmp, sizeof(tmp));
00076       val |= (UCHAR(tmp) << 8);
00077       shift = 2;
00078       offset = (1<<7);
00079     }
00080     else if ((val&7) == 3) {
00081       ss.read((char *)&tmp, sizeof(tmp));
00082       val |= (UCHAR(tmp) << 8);
00083       ss.read((char *)&tmp, sizeof(tmp));
00084       val |= (UCHAR(tmp) << 16);
00085       shift = 3;
00086       offset = (1<<7) + (1<<14);
00087     }
00088     else {
00089       ss.read((char *)&tmp, sizeof(tmp));
00090       val |= (UCHAR(tmp) << 8);
00091       ss.read((char *)&tmp, sizeof(tmp));
00092       val |= (UCHAR(tmp) << 16);
00093       ss.read((char *)&tmp, sizeof(tmp));
00094       val |= (UCHAR(tmp) << 24);
00095       shift = 3;
00096       offset = (1<<7) + (1<<14) + (1<<21);
00097     }
00098     num = (val >> shift) + offset;
00099     return num;
00100   }
00101 
00102   //! Reads an integer from a char * in packed format and returns the result.
00103   //!  The argument is advanced
00104   inline boost::uint32_t pullPackedIntFromString(const char *&text) {
00105     boost::uint32_t val, num;
00106     int shift, offset;
00107     char tmp;
00108     tmp = *text;
00109     text++;
00110     val = UCHAR(tmp);
00111     offset = 0;
00112     if ((val&1) == 0) {
00113       shift = 1;
00114     }
00115     else if ((val&3) == 1) {
00116       tmp = *text;
00117       text++;
00118       val |= (UCHAR(tmp) << 8);
00119       shift = 2;
00120       offset = (1<<7);
00121     }
00122     else if ((val&7) == 3) {
00123       tmp = *text;
00124       text++;
00125       val |= (UCHAR(tmp) << 8);
00126       tmp = *text;
00127       text++;
00128       val |= (UCHAR(tmp) << 16);
00129       shift = 3;
00130       offset = (1<<7) + (1<<14);
00131     }
00132     else {
00133       tmp = *text;
00134       text++;
00135       val |= (UCHAR(tmp) << 8);
00136       tmp = *text;
00137       text++;
00138       val |= (UCHAR(tmp) << 16);
00139       tmp = *text;
00140       text++;
00141       val |= (UCHAR(tmp) << 24);
00142       shift = 3;
00143       offset = (1<<7) + (1<<14) + (1<<21);
00144     }
00145     num = (val >> shift) + offset;
00146     return num;
00147   }
00148   
00149   //! does a binary write of an object to a stream
00150   template <typename T>
00151     void streamWrite(std::ostream &ss,const T &val){
00152     ss.write((const char *)&val,sizeof(T));
00153   }
00154   //! does a binary read of an object from a stream
00155   template <typename T>
00156     void streamRead(std::istream &ss,T &loc){
00157     ss.read((char *)&loc,sizeof(T));
00158   }
00159  
00160   //! grabs the next line from an instream and returns it.
00161   inline std::string getLine(std::istream *inStream) {
00162     std::string res;
00163     std::getline(*inStream,res);
00164     if ((res.length() > 0) && (res[res.length()-1]=='\r')){
00165       res.erase(res.length()-1);
00166     }
00167     return res;
00168   }
00169   //! grabs the next line from an instream and returns it.
00170   inline std::string getLine(std::istream &inStream) {
00171     return getLine(&inStream);
00172   }
00173 }
00174 
00175 
00176 
00177 #endif

Generated on Tue Oct 7 06:10:11 2008 for RDCode by  doxygen 1.5.5