RDCode: StreamOps.h Source File

# 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