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
00015
00016 namespace RDKit{
00017
00018
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
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
00102
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
00149 template <typename T>
00150 void streamWrite(std::ostream &ss,const T &val){
00151 ss.write((const char *)&val,sizeof(T));
00152 }
00153
00154 template <typename T>
00155 void streamRead(std::istream &ss,T &loc){
00156 ss.read((char *)&loc,sizeof(T));
00157 }
00158
00159
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
00169 inline std::string getLine(std::istream &inStream) {
00170 return getLine(&inStream);
00171 }
00172 }
00173
00174
00175
00176 #endif