RDCode: StreamOps.h Source File

- Main Page
- Namespaces
- Classes
- Files
- Directories

# StreamOps.h

Go to the documentation of this file.

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