#include "TRootSnifferStore.h"

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TRootSnifferStore                                                    //
//                                                                      //
// Used to store different results of objects scanning by TRootSniffer  //
//                                                                      //
//////////////////////////////////////////////////////////////////////////


//______________________________________________________________________________
TRootSnifferStore::TRootSnifferStore() :
   TObject(),
   fResPtr(0),
   fResClass(0),
   fResMember(0),
   fResNumChilds(-1)
{
   // normal constructor
}

//______________________________________________________________________________
TRootSnifferStore::~TRootSnifferStore()
{
   // destructor
}

//______________________________________________________________________________
void TRootSnifferStore::SetResult(void *_res, TClass *_rescl,
                                  TDataMember *_resmemb, Int_t _res_chld)
{
   // set pointer on found element, class and number of childs

   fResPtr = _res;
   fResClass = _rescl;
   fResMember = _resmemb;
   fResNumChilds = _res_chld;
}

// =================================================================================

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TRootSnifferStoreXml                                                 //
//                                                                      //
// Used to store scanned objects hierarchy in XML form                  //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

//______________________________________________________________________________
void TRootSnifferStoreXml::CreateNode(Int_t lvl, const char *nodename)
{
   // starts new xml node, will be closed by CloseNode

   buf->Append(TString::Format("%*s<%s", compact ? 0 : (lvl+1) * 2, "", nodename));
}

//______________________________________________________________________________
void TRootSnifferStoreXml::SetField(Int_t, const char *field, const char *value,
                                    Bool_t)
{
   // set field (xml attribute) in current node

   if (strpbrk(value, "<>&\'\"") == 0) {
      buf->Append(TString::Format(" %s=\"%s\"", field, value));
   } else {
      buf->Append(TString::Format(" %s=\"", field));
      const char *v = value;
      while (*v != 0) {
         switch (*v) {
            case '<' :
               buf->Append("&lt;");
               break;
            case '>' :
               buf->Append("&gt;");
               break;
            case '&' :
               buf->Append("&amp;");
               break;
            case '\'' :
               buf->Append("&apos;");
               break;
            case '\"' :
               buf->Append("&quot;");
               break;
            default:
               buf->Append(*v);
               break;
         }
         v++;
      }

      buf->Append("\"");
   }
}

//______________________________________________________________________________
void TRootSnifferStoreXml::BeforeNextChild(Int_t, Int_t nchld, Int_t)
{
   // called before next child node created

   if (nchld == 0) buf->Append(TString::Format(">%s", (compact ? "" : "\n")));
}

//______________________________________________________________________________
void TRootSnifferStoreXml::CloseNode(Int_t lvl, const char *nodename,
                                     Int_t numchilds)
{
   // called when node should be closed
   // depending from number of childs different xml format is applied

   if (numchilds > 0)
      buf->Append(TString::Format("%*s</%s>%s", compact ? 0 : (lvl+1) * 2, "", nodename, (compact ? "" : "\n")));
   else
      buf->Append(TString::Format("/>%s", (compact ? "" : "\n")));
}

// ============================================================================

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TRootSnifferStoreXml                                                 //
//                                                                      //
// Used to store scanned objects hierarchy in JSON form                 //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

//______________________________________________________________________________
void TRootSnifferStoreJson::CreateNode(Int_t lvl, const char *nodename)
{
   // starts new json object, will be closed by CloseNode

   buf->Append(TString::Format("%*s{", compact ? 0 : lvl * 4, ""));
   if (!compact) buf->Append("\n");
   buf->Append(TString::Format("%*s\"_name\"%s\"%s\"", compact ? 0 : lvl * 4 + 2, "", (compact ? ":" : " : "), nodename));
}

//______________________________________________________________________________
void TRootSnifferStoreJson::SetField(Int_t lvl, const char *field,
                                     const char *value, Bool_t with_quotes)
{
   // set field (json field) in current node

   buf->Append(",");
   if (!compact) buf->Append("\n");
   buf->Append(TString::Format("%*s\"%s\"%s", compact ? 0 : lvl * 4 + 2, "", field, (compact ? ":" : " : ")));
   if (with_quotes) {
      buf->Append(TString::Format("\"%s\"", value));
   } else {
      buf->Append(value);
   }
}

//______________________________________________________________________________
void TRootSnifferStoreJson::BeforeNextChild(Int_t lvl, Int_t nchld, Int_t)
{
   // called before next child node created

   buf->Append(",");
   if (!compact) buf->Append("\n");
   if (nchld == 0)
      buf->Append(TString::Format("%*s\"_childs\"%s", (compact ? 0 : lvl * 4 + 2), "", (compact ? ":[" : " : [\n")));
}

//______________________________________________________________________________
void TRootSnifferStoreJson::CloseNode(Int_t lvl, const char *, Int_t numchilds)
{
   // called when node should be closed
   // depending from number of childs different xml format is applied

   if (numchilds > 0)
      buf->Append(TString::Format("%s%*s]", (compact ? "" : "\n"), compact ? 0 : lvl * 4 + 2, ""));
   buf->Append(TString::Format("%s%*s}", (compact ? "" : "\n"), compact ? 0 : lvl * 4, ""));
}

 TRootSnifferStore.cxx:1
 TRootSnifferStore.cxx:2
 TRootSnifferStore.cxx:3
 TRootSnifferStore.cxx:4
 TRootSnifferStore.cxx:5
 TRootSnifferStore.cxx:6
 TRootSnifferStore.cxx:7
 TRootSnifferStore.cxx:8
 TRootSnifferStore.cxx:9
 TRootSnifferStore.cxx:10
 TRootSnifferStore.cxx:11
 TRootSnifferStore.cxx:12
 TRootSnifferStore.cxx:13
 TRootSnifferStore.cxx:14
 TRootSnifferStore.cxx:15
 TRootSnifferStore.cxx:16
 TRootSnifferStore.cxx:17
 TRootSnifferStore.cxx:18
 TRootSnifferStore.cxx:19
 TRootSnifferStore.cxx:20
 TRootSnifferStore.cxx:21
 TRootSnifferStore.cxx:22
 TRootSnifferStore.cxx:23
 TRootSnifferStore.cxx:24
 TRootSnifferStore.cxx:25
 TRootSnifferStore.cxx:26
 TRootSnifferStore.cxx:27
 TRootSnifferStore.cxx:28
 TRootSnifferStore.cxx:29
 TRootSnifferStore.cxx:30
 TRootSnifferStore.cxx:31
 TRootSnifferStore.cxx:32
 TRootSnifferStore.cxx:33
 TRootSnifferStore.cxx:34
 TRootSnifferStore.cxx:35
 TRootSnifferStore.cxx:36
 TRootSnifferStore.cxx:37
 TRootSnifferStore.cxx:38
 TRootSnifferStore.cxx:39
 TRootSnifferStore.cxx:40
 TRootSnifferStore.cxx:41
 TRootSnifferStore.cxx:42
 TRootSnifferStore.cxx:43
 TRootSnifferStore.cxx:44
 TRootSnifferStore.cxx:45
 TRootSnifferStore.cxx:46
 TRootSnifferStore.cxx:47
 TRootSnifferStore.cxx:48
 TRootSnifferStore.cxx:49
 TRootSnifferStore.cxx:50
 TRootSnifferStore.cxx:51
 TRootSnifferStore.cxx:52
 TRootSnifferStore.cxx:53
 TRootSnifferStore.cxx:54
 TRootSnifferStore.cxx:55
 TRootSnifferStore.cxx:56
 TRootSnifferStore.cxx:57
 TRootSnifferStore.cxx:58
 TRootSnifferStore.cxx:59
 TRootSnifferStore.cxx:60
 TRootSnifferStore.cxx:61
 TRootSnifferStore.cxx:62
 TRootSnifferStore.cxx:63
 TRootSnifferStore.cxx:64
 TRootSnifferStore.cxx:65
 TRootSnifferStore.cxx:66
 TRootSnifferStore.cxx:67
 TRootSnifferStore.cxx:68
 TRootSnifferStore.cxx:69
 TRootSnifferStore.cxx:70
 TRootSnifferStore.cxx:71
 TRootSnifferStore.cxx:72
 TRootSnifferStore.cxx:73
 TRootSnifferStore.cxx:74
 TRootSnifferStore.cxx:75
 TRootSnifferStore.cxx:76
 TRootSnifferStore.cxx:77
 TRootSnifferStore.cxx:78
 TRootSnifferStore.cxx:79
 TRootSnifferStore.cxx:80
 TRootSnifferStore.cxx:81
 TRootSnifferStore.cxx:82
 TRootSnifferStore.cxx:83
 TRootSnifferStore.cxx:84
 TRootSnifferStore.cxx:85
 TRootSnifferStore.cxx:86
 TRootSnifferStore.cxx:87
 TRootSnifferStore.cxx:88
 TRootSnifferStore.cxx:89
 TRootSnifferStore.cxx:90
 TRootSnifferStore.cxx:91
 TRootSnifferStore.cxx:92
 TRootSnifferStore.cxx:93
 TRootSnifferStore.cxx:94
 TRootSnifferStore.cxx:95
 TRootSnifferStore.cxx:96
 TRootSnifferStore.cxx:97
 TRootSnifferStore.cxx:98
 TRootSnifferStore.cxx:99
 TRootSnifferStore.cxx:100
 TRootSnifferStore.cxx:101
 TRootSnifferStore.cxx:102
 TRootSnifferStore.cxx:103
 TRootSnifferStore.cxx:104
 TRootSnifferStore.cxx:105
 TRootSnifferStore.cxx:106
 TRootSnifferStore.cxx:107
 TRootSnifferStore.cxx:108
 TRootSnifferStore.cxx:109
 TRootSnifferStore.cxx:110
 TRootSnifferStore.cxx:111
 TRootSnifferStore.cxx:112
 TRootSnifferStore.cxx:113
 TRootSnifferStore.cxx:114
 TRootSnifferStore.cxx:115
 TRootSnifferStore.cxx:116
 TRootSnifferStore.cxx:117
 TRootSnifferStore.cxx:118
 TRootSnifferStore.cxx:119
 TRootSnifferStore.cxx:120
 TRootSnifferStore.cxx:121
 TRootSnifferStore.cxx:122
 TRootSnifferStore.cxx:123
 TRootSnifferStore.cxx:124
 TRootSnifferStore.cxx:125
 TRootSnifferStore.cxx:126
 TRootSnifferStore.cxx:127
 TRootSnifferStore.cxx:128
 TRootSnifferStore.cxx:129
 TRootSnifferStore.cxx:130
 TRootSnifferStore.cxx:131
 TRootSnifferStore.cxx:132
 TRootSnifferStore.cxx:133
 TRootSnifferStore.cxx:134
 TRootSnifferStore.cxx:135
 TRootSnifferStore.cxx:136
 TRootSnifferStore.cxx:137
 TRootSnifferStore.cxx:138
 TRootSnifferStore.cxx:139
 TRootSnifferStore.cxx:140
 TRootSnifferStore.cxx:141
 TRootSnifferStore.cxx:142
 TRootSnifferStore.cxx:143
 TRootSnifferStore.cxx:144
 TRootSnifferStore.cxx:145
 TRootSnifferStore.cxx:146
 TRootSnifferStore.cxx:147
 TRootSnifferStore.cxx:148
 TRootSnifferStore.cxx:149
 TRootSnifferStore.cxx:150
 TRootSnifferStore.cxx:151
 TRootSnifferStore.cxx:152
 TRootSnifferStore.cxx:153
 TRootSnifferStore.cxx:154
 TRootSnifferStore.cxx:155
 TRootSnifferStore.cxx:156
 TRootSnifferStore.cxx:157
 TRootSnifferStore.cxx:158
 TRootSnifferStore.cxx:159
 TRootSnifferStore.cxx:160
 TRootSnifferStore.cxx:161
 TRootSnifferStore.cxx:162
 TRootSnifferStore.cxx:163
 TRootSnifferStore.cxx:164
 TRootSnifferStore.cxx:165
 TRootSnifferStore.cxx:166
 TRootSnifferStore.cxx:167
 TRootSnifferStore.cxx:168
 TRootSnifferStore.cxx:169
 TRootSnifferStore.cxx:170
 TRootSnifferStore.cxx:171
 TRootSnifferStore.cxx:172
 TRootSnifferStore.cxx:173
 TRootSnifferStore.cxx:174
 TRootSnifferStore.cxx:175
 TRootSnifferStore.cxx:176