#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),
   fResRestrict(0)
{
   // normal constructor
}

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

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

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

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

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// 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

   fBuf->Append(TString::Format("%*s<item _name=\"%s\"", fCompact ? 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) {
      fBuf->Append(TString::Format(" %s=\"%s\"", field, value));
   } else {
      fBuf->Append(TString::Format(" %s=\"", field));
      const char *v = value;
      while (*v != 0) {
         switch (*v) {
            case '<' :
               fBuf->Append("&lt;");
               break;
            case '>' :
               fBuf->Append("&gt;");
               break;
            case '&' :
               fBuf->Append("&amp;");
               break;
            case '\'' :
               fBuf->Append("&apos;");
               break;
            case '\"' :
               fBuf->Append("&quot;");
               break;
            default:
               fBuf->Append(*v);
               break;
         }
         v++;
      }

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

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

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

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

   if (numchilds > 0)
      fBuf->Append(TString::Format("%*s</item>%s", fCompact ? 0 : (lvl + 1) * 2, "", (fCompact ? "" : "\n")));
   else
      fBuf->Append(TString::Format("/>%s", (fCompact ? "" : "\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

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

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

   fBuf->Append(",");
   if (!fCompact) fBuf->Append("\n");
   fBuf->Append(TString::Format("%*s\"%s\"%s", fCompact ? 0 : lvl * 4 + 2, "", field, (fCompact ? ":" : " : ")));
   if (!with_quotes) {
      fBuf->Append(value);
   } else {
      fBuf->Append("\"");
      for (const char *v = value; *v != 0; v++)
         switch (*v) {
            case '\n':
               fBuf->Append("\\n");
               break;
            case '\t':
               fBuf->Append("\\t");
               break;
            case '\"':
               fBuf->Append("\\\"");
               break;
            case '\\':
               fBuf->Append("\\\\");
               break;
            case '\b':
               fBuf->Append("\\b");
               break;
            case '\f':
               fBuf->Append("\\f");
               break;
            case '\r':
               fBuf->Append("\\r");
               break;
            case '/':
               fBuf->Append("\\/");
               break;
            default:
               if ((*v > 31) && (*v < 127))
                  fBuf->Append(*v);
               else
                  fBuf->Append(TString::Format("\\u%04x", (unsigned) *v));
         }
      fBuf->Append("\"");
   }
}

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

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

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

   if (numchilds > 0)
      fBuf->Append(TString::Format("%s%*s]", (fCompact ? "" : "\n"), fCompact ? 0 : lvl * 4 + 2, ""));
   fBuf->Append(TString::Format("%s%*s}", (fCompact ? "" : "\n"), fCompact ? 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
 TRootSnifferStore.cxx:177
 TRootSnifferStore.cxx:178
 TRootSnifferStore.cxx:179
 TRootSnifferStore.cxx:180
 TRootSnifferStore.cxx:181
 TRootSnifferStore.cxx:182
 TRootSnifferStore.cxx:183
 TRootSnifferStore.cxx:184
 TRootSnifferStore.cxx:185
 TRootSnifferStore.cxx:186
 TRootSnifferStore.cxx:187
 TRootSnifferStore.cxx:188
 TRootSnifferStore.cxx:189
 TRootSnifferStore.cxx:190
 TRootSnifferStore.cxx:191
 TRootSnifferStore.cxx:192
 TRootSnifferStore.cxx:193
 TRootSnifferStore.cxx:194
 TRootSnifferStore.cxx:195
 TRootSnifferStore.cxx:196
 TRootSnifferStore.cxx:197
 TRootSnifferStore.cxx:198
 TRootSnifferStore.cxx:199
 TRootSnifferStore.cxx:200
 TRootSnifferStore.cxx:201
 TRootSnifferStore.cxx:202
 TRootSnifferStore.cxx:203
 TRootSnifferStore.cxx:204
 TRootSnifferStore.cxx:205
 TRootSnifferStore.cxx:206
 TRootSnifferStore.cxx:207
 TRootSnifferStore.cxx:208
 TRootSnifferStore.cxx:209
 TRootSnifferStore.cxx:210