00001
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifdef _WIN32
00024 #pragma warning(disable:4786)
00025 #endif
00026 #include <stdio.h>
00027 #include <ctype.h>
00028
00029 #include <stdlib.h>
00030 #include <string>
00031 #include <vector>
00032 #include <map>
00033 #include <openssl/sha.h>
00034
00035 #include "BTObject.h"
00036 #include "BTDictionary.h"
00037 #include "BTList.h"
00038 #include "BTInteger.h"
00039 #include "BTString.h"
00040 #include "BString.h"
00041 #include "ParseBT.h"
00042 #include "BTException.h"
00043
00044
00045 #ifdef _DEBUG
00046 #define DEB(x) x
00047 #else
00048 #define DEB(x)
00049 #endif
00050
00051
00052
00053 BString::BString()
00054 :m_bindex(0)
00055 ,m_root(0)
00056 ,m_current(NULL)
00057 ,m_state(0)
00058 ,m_strlen(0)
00059 ,m_str("")
00060 ,m_name("")
00061 ,m_bDictionary(false)
00062 ,m_bList(false)
00063 ,m_bKey(false)
00064 {
00065 m_current = &m_root;
00066 }
00067
00068
00069 BString::~BString()
00070 {
00071 }
00072
00073
00074 void BString::read_file(FILE *fil)
00075 {
00076 char c;
00077
00078 fread(&c,1,1,fil);
00079 while (!feof(fil))
00080 {
00081 if (!reg_char(c))
00082 {
00083 break;
00084 }
00085
00086 fread(&c,1,1,fil);
00087 }
00088 }
00089
00090
00091 void BString::read_buf(const char *p,size_t l)
00092 {
00093 for (size_t i = 0; i < l; i++)
00094 {
00095 if (!reg_char(p[i]))
00096 {
00097 break;
00098 }
00099 }
00100 }
00101
00102
00103 DEB(
00104 int lvl = 0;
00105 char lt[100];
00106
00107 void plvl(int x)
00108 {
00109 for (int i = 0; i < x; i++)
00110 printf(" ");
00111 }
00112 )
00113
00114
00115 bool BString::reg_char(char c)
00116 {
00117 m_bstring += c;
00118 switch (m_state)
00119 {
00120 case 0:
00121 switch (c)
00122 {
00123 case 'd':
00124 DEB( lt[lvl] = c;
00125 lvl++;
00126 plvl(lvl);
00127 printf("Dictionary\n");)
00128
00129 AddDictionary();
00130 break;
00131 case 'l':
00132 DEB( lt[lvl] = c;
00133 lvl++;
00134 plvl(lvl);
00135 printf("List\n");)
00136
00137 AddList();
00138 break;
00139 case 'i':
00140 DEB( plvl(lvl);
00141 printf(" Integer");)
00142
00143 m_state = 1;
00144 m_str = "";
00145 break;
00146 case 'e':
00147 DEB( if (lvl)
00148 {
00149 lvl--;
00150 plvl(lvl + 1);
00151 printf("End of %s\n",(lt[lvl] == 'd') ? "Dictionary" :
00152 (lt[lvl] == 'l') ? "List" : "<err>");
00153 })
00154 End();
00155 break;
00156
00157 default:
00158 if (!isdigit(c))
00159 {
00160
00161 throw(BTException("Digit expected"));
00162 }
00163
00164 DEB( plvl(lvl);
00165 printf(" String");)
00166
00167 m_state = 2;
00168 m_str = c;
00169 }
00170 break;
00171 case 1:
00172 if (c == 'e')
00173 {
00174 DEB( printf(" value '%s'\n",m_str.c_str());)
00175
00176 m_state = 0;
00177 AddInteger( m_str );
00178 }
00179 else
00180 {
00181 m_str += c;
00182 }
00183 break;
00184 case 2:
00185 if (isdigit(c))
00186 {
00187 m_str += c;
00188 }
00189 else
00190 {
00191 m_strlen = atoi(m_str.c_str());
00192 m_str = "";
00193 DEB( printf(" (length %d)",m_strlen);)
00194
00195
00196 if (c != ':')
00197 {
00198 throw(BTException("':' expected"));
00199 }
00200 if (m_strlen)
00201 {
00202 m_state = 3;
00203 }
00204 else
00205 {
00206
00207 DEB( printf(" '%s' (%d)\n",printable(m_str).c_str(),m_str.size());)
00208
00209 m_state = 0;
00210 AddString( m_str );
00211 }
00212 }
00213 break;
00214 case 3:
00215 m_str += c;
00216 m_strlen--;
00217 if (m_strlen <= 0)
00218 {
00219 DEB( printf(" '%s' (%d)\n",printable(m_str).c_str(),m_str.size());)
00220
00221 m_state = 0;
00222 AddString( m_str );
00223 }
00224 break;
00225 }
00226 m_current -> Increase();
00227 m_bindex++;
00228 return true;
00229 }
00230
00231
00232 void BString::AddDictionary()
00233 {
00234 BTDictionary *tmp = new BTDictionary(m_bindex);
00235
00236 tmp -> SetParent(m_current);
00237
00238 switch (m_current -> Type())
00239 {
00240 case 'd':
00241 m_current -> AddObject(m_name, tmp);
00242 m_current = tmp;
00243 m_name = "";
00244 break;
00245 case 'l':
00246 m_current -> AddObject(tmp);
00247 m_current = tmp;
00248 break;
00249 default:
00250
00251 throw(BTException("AddDictionary"));
00252 break;
00253 }
00254 }
00255
00256
00257 void BString::AddList()
00258 {
00259 BTList *tmp = new BTList(m_bindex);
00260
00261 tmp -> SetParent(m_current);
00262
00263 switch (m_current -> Type())
00264 {
00265 case 'd':
00266 m_current -> AddObject(m_name, tmp);
00267 m_current = tmp;
00268 m_name = "";
00269 break;
00270 case 'l':
00271 m_current -> AddObject(tmp);
00272 m_current = tmp;
00273 break;
00274 default:
00275
00276 throw(BTException("AddList"));
00277 break;
00278 }
00279 }
00280
00281
00282 void BString::AddInteger(const std::string &str)
00283 {
00284 BTInteger *tmp = new BTInteger;
00285
00286 tmp -> SetParent(m_current);
00287 tmp -> SetValue(str);
00288
00289 switch (m_current -> Type())
00290 {
00291 case 'd':
00292 m_current -> AddObject(m_name, tmp);
00293 m_name = "";
00294 break;
00295 case 'l':
00296 m_current -> AddObject(tmp);
00297 break;
00298 default:
00299 throw(BTException("AddInteger"));
00300
00301 break;
00302 }
00303 }
00304
00305
00306 void BString::AddString(const std::string &str)
00307 {
00308 if (m_current -> Type() == 'd' && m_name.size() == 0)
00309 {
00310 m_name = str;
00311 return;
00312 }
00313 BTString *tmp = new BTString;
00314
00315 tmp -> SetParent(m_current);
00316 tmp -> SetValue(str);
00317
00318 switch (m_current -> Type())
00319 {
00320 case 'd':
00321 m_current -> AddObject(m_name, tmp);
00322 m_name = "";
00323 break;
00324 case 'l':
00325 m_current -> AddObject(tmp);
00326 break;
00327 default:
00328 throw(BTException("AddString"));
00329
00330 break;
00331 }
00332 }
00333
00334
00335 void BString::End()
00336 {
00337 m_current = m_current -> GetParent();
00338 DEB( printf(" * Current type is '%c'\n",m_current -> Type());)
00339
00340 }
00341
00342
00343 void BString::Show()
00344 {
00345 m_root.Show();
00346 printf("\n");
00347 }
00348
00349
00350 BTObject *BString::GetBTObject(const std::string &path)
00351 {
00352 ParseBT pa( (char *)path.c_str(), ".", 1);
00353 char slask[200];
00354 BTObject *p = &m_root;
00355 BTList *l = dynamic_cast<BTList *>(p);
00356
00357 if (!l || l -> GetSize() != 1)
00358 {
00359 throw(BTException("GetBTObject"));
00360 }
00361 p = l -> GetFirst();
00362 pa.getword(slask);
00363 while (*slask)
00364 {
00365 BTDictionary *d = dynamic_cast<BTDictionary *>(p);
00366
00367 if (!d)
00368 {
00369 throw(BTException("Not Dictionary"));
00370 }
00371 p = d -> Find(slask);
00372 if (!p)
00373 return NULL;
00374 pa.getword(slask);
00375 }
00376 return p;
00377 }
00378
00379
00380 BTInteger *BString::GetInteger(const std::string &str)
00381 {
00382 BTObject *p = GetBTObject(str);
00383 return dynamic_cast<BTInteger *>(p);
00384 }
00385
00386
00387 BTString *BString::GetString(const std::string &str)
00388 {
00389 BTObject *p = GetBTObject(str);
00390 return dynamic_cast<BTString *>(p);
00391 }
00392
00393
00394 std::string BString::GetBString(const std::string& path)
00395 {
00396 BTObject *p = GetBTObject(path);
00397 size_t begin = p -> GetIndex();
00398 size_t length = p -> GetLength() + 1;
00399 std::string str = m_bstring.substr(begin,length);
00400
00401 return str;
00402 }
00403
00404
00405 unsigned char *BString::GetHash(const std::string& node)
00406 {
00407 std::string tmp = GetBString( node );
00408 SHA1( (unsigned char *)tmp.c_str(), tmp.size(), m_hash);
00409 return m_hash;
00410 }
00411
00412
00413 const std::string& BString::GetHashAsString(const std::string& node)
00414 {
00415 std::string tmp = GetBString( node );
00416 char slask[100];
00417 SHA1( (unsigned char *)tmp.c_str(), tmp.size(), m_hash);
00418 *slask = 0;
00419 for (size_t i = 0; i < 20; i++)
00420 sprintf(slask + strlen(slask), "%02x", m_hash[i]);
00421 m_hash_str = slask;
00422 return m_hash_str;
00423 }
00424
00425