00001
00002
00003
00004
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
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
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
00103
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
00150 template <typename T>
00151 void streamWrite(std::ostream &ss,const T &val){
00152 ss.write((const char *)&val,sizeof(T));
00153 }
00154
00155 template <typename T>
00156 void streamRead(std::istream &ss,T &loc){
00157 ss.read((char *)&loc,sizeof(T));
00158 }
00159
00160
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
00170 inline std::string getLine(std::istream &inStream) {
00171 return getLine(&inStream);
00172 }
00173 }
00174
00175
00176
00177 #endif