Logo
~Apps~
~Projects~
~Contact~


BString.cpp

Go to the documentation of this file.
00001 
00006 /*
00007 Copyright (C) 2005  Anders Hedstrom
00008 
00009 This program is free software; you can redistribute it and/or
00010 modify it under the terms of the GNU General Public License
00011 as published by the Free Software Foundation; either version 2
00012 of the License, or (at your option) any later version.
00013 
00014 This program is distributed in the hope that it will be useful,
00015 but WITHOUT ANY WARRANTY; without even the implied warranty of
00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017 GNU General Public License for more details.
00018 
00019 You should have received a copy of the GNU General Public License
00020 along with this program; if not, write to the Free Software
00021 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00022 */
00023 #ifdef _WIN32
00024 #pragma warning(disable:4786)
00025 #endif
00026 #include <stdio.h>
00027 #include <ctype.h>
00028 //#include <assert.h>
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) // key-value pairs
00062 ,m_bList(false) // values
00063 ,m_bKey(false) // used when m_bDictionary is true
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': // dictionary
00124 DEB(                    lt[lvl] = c;
00125                         lvl++;
00126                         plvl(lvl);
00127                         printf("Dictionary\n");)
00128 
00129                         AddDictionary();
00130                         break;
00131                 case 'l': // list
00132 DEB(                    lt[lvl] = c;
00133                         lvl++;
00134                         plvl(lvl);
00135                         printf("List\n");)
00136 
00137                         AddList();
00138                         break;
00139                 case 'i': // integer
00140 DEB(                    plvl(lvl);
00141                         printf(" Integer");)
00142 
00143                         m_state = 1;
00144                         m_str = "";
00145                         break;
00146                 case 'e': // lvl end
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 //                              assert(!"no good");
00161                                 throw(BTException("Digit expected"));
00162                         }
00163                         // string
00164 DEB(                    plvl(lvl);
00165                         printf(" String");)
00166 
00167                         m_state = 2;
00168                         m_str = c;
00169                 }
00170                 break;
00171         case 1: // read integer
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: // read string length
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 //                      assert(c == ':');
00196                         if (c != ':')
00197                         {
00198                                 throw(BTException("':' expected"));
00199                         }
00200                         if (m_strlen)
00201                         {
00202                                 m_state = 3;
00203                         }
00204                         else
00205                         {
00206                                 // add empty string
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: // read string
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': // dictionary
00241                 m_current -> AddObject(m_name, tmp);
00242                 m_current = tmp;
00243                 m_name = "";
00244                 break;
00245         case 'l': // list
00246                 m_current -> AddObject(tmp);
00247                 m_current = tmp;
00248                 break;
00249         default:
00250 //              assert(!"no good");
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': // dictionary
00266                 m_current -> AddObject(m_name, tmp);
00267                 m_current = tmp;
00268                 m_name = "";
00269                 break;
00270         case 'l': // list
00271                 m_current -> AddObject(tmp);
00272                 m_current = tmp;
00273                 break;
00274         default:
00275 //              assert(!"no good");
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': // dictionary
00292                 m_current -> AddObject(m_name, tmp);
00293                 m_name = "";
00294                 break;
00295         case 'l': // list
00296                 m_current -> AddObject(tmp);
00297                 break;
00298         default:
00299                 throw(BTException("AddInteger"));
00300 //              assert(!"no good");
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': // dictionary
00321                 m_current -> AddObject(m_name, tmp);
00322                 m_name = "";
00323                 break;
00324         case 'l': // list
00325                 m_current -> AddObject(tmp);
00326                 break;
00327         default:
00328                 throw(BTException("AddString"));
00329 //              assert(!"no good");
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 //      assert(l && l -> GetSize() == 1);
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 //              assert(d);
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 //      printf("%s\n",printable(str).c_str());
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 
Page, code, and content Copyright (C) 2006 by Anders Hedström
Generated on Mon Aug 29 20:21:47 2005 for C++ Sockets by  doxygen 1.4.4