<commit_before>// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "mustache.h"

#include "rapidjson/stringbuffer.h"
#include "rapidjson/writer.h"

#include <iostream>
#include <fstream>
#include <vector>

#include <boost/algorithm/string.hpp>
#include <boost/foreach.hpp>

using namespace rapidjson;
using namespace std;
using namespace boost::algorithm;

namespace mustache {

// TODO:
// # Handle malformed templates better
// # Support array_tag.length?
// # Better support for reading templates from files

enum TagOperator {
  SUBSTITUTION,
  SECTION_START,
  NEGATED_SECTION_START,
  PREDICATE_SECTION_START,
  SECTION_END,
  PARTIAL,
  COMMENT,
  NONE
};

TagOperator GetOperator(const string& tag) {
  if (tag.size() == 0) return SUBSTITUTION;
  switch (tag[0]) {
    case '#': return SECTION_START;
    case '^': return NEGATED_SECTION_START;
    case '?': return PREDICATE_SECTION_START;
    case '/': return SECTION_END;
    case '>': return PARTIAL;
    case '!': return COMMENT;
    default: return SUBSTITUTION;
  }
}

int EvaluateTag(const string& document, const string& document_root, int idx,
    const Value* context, TagOperator tag, const string& tag_name, bool is_triple,
    stringstream* out);

void EscapeHtml(const string& in, stringstream *out) {
  BOOST_FOREACH(const char& c, in) {
    switch (c) {
      case '&': (*out) << "&";
        break;
      case '"': (*out) << """;
        break;
      case '\'': (*out) << "'";
        break;
      case '<': (*out) << "<";
        break;
      case '>': (*out) << ">";
        break;
      default: (*out) << c;
        break;
    }
  }
}

// Breaks a dotted path into individual components. One wrinkle, which stops this from
// being a simple split() is that we allow path components to be quoted, e.g.: "foo".bar,
// and any '.' characters inside those quoted sections aren't considered to be
// delimiters. This is to allow Json keys that contain periods.
void FindJsonPathComponents(const string& path, vector<string>* components) {
  bool in_quote = false;
  bool escape_this_char = false;
  int start = 0;
  for (int i = start; i < path.size(); ++i) {
    if (path[i] == '"' && !escape_this_char) in_quote = !in_quote;
    if (path[i] == '.' && !escape_this_char && !in_quote) {
      // Current char == delimiter and not escaped and not in a quote pair => found a
      // component
      if (i - start > 0) {
        if (path[start] == '"' && path[(i - 1) - start] == '"') {
          if (i - start > 3) {
            components->push_back(path.substr(start + 1, i - (start + 2)));
          }
        } else {
          components->push_back(path.substr(start, i - start));
        }
        start = i + 1;
      }
    }

    escape_this_char = (path[i] == '\\' && !escape_this_char);
  }

  if (path.size() - start > 0) {
    if (path[start] == '"' && path[(path.size() - 1) - start] == '"') {
      if (path.size() - start > 3) {
        components->push_back(path.substr(start + 1, path.size() - (start + 2)));
      }
    } else {
      components->push_back(path.substr(start, path.size() - start));
    }
  }
}

// Looks up the json entity at 'path' in 'parent_context', and places it in 'resolved'. If
// the entity does not exist (i.e. the path is invalid), 'resolved' will be set to NULL.
void ResolveJsonContext(const string& path, const Value& parent_context,
    const Value** resolved) {
  if (path == ".") {
    *resolved = &parent_context;
    return;
  }
  vector<string> components;
  FindJsonPathComponents(path, &components);
  const Value* cur = &parent_context;
  BOOST_FOREACH(const string& c, components) {
    if (cur->IsObject() && cur->HasMember(c.c_str())) {
      cur = &(*cur)[c.c_str()];
    } else {
      *resolved = NULL;
      return;
    }
  }

  *resolved = cur;
}

int FindNextTag(const string& document, int idx, TagOperator* tag_op, string* tag_name,
    bool* is_triple, stringstream* out) {
  *tag_op = NONE;
  while (idx < document.size()) {
    if (document[idx] == '{' && idx < (document.size() - 3) && document[idx + 1] == '{') {
      if (document[idx + 2] == '{') {
        idx += 3;
        *is_triple = true;
      } else {
        *is_triple = false;
        idx += 2; // Now at start of template expression
      }
      stringstream expr;
      while (idx < document.size()) {
        if (document[idx] != '}') {
          expr << document[idx];
          ++idx;
        } else {
          if (!*is_triple && idx < document.size() - 1 && document[idx + 1] == '}') {
            ++idx;
            break;
          } else if (*is_triple && idx < document.size() - 2 && document[idx + 1] == '}'
              && document[idx + 2] == '}') {
            idx += 2;
            break;
          } else {
            expr << '}';
          }
        }
      }

      string key = expr.str();
      trim(key);
      if (key != ".") trim_if(key, is_any_of("."));
      if (key.size() == 0) continue;
      *tag_op = GetOperator(key);
      if (*tag_op != SUBSTITUTION) {
        key = key.substr(1);
        trim(key);
      }
      if (key.size() == 0) continue;
      *tag_name = key;
      return ++idx;
    } else {
      if (out != NULL) (*out) << document[idx];
    }
    ++idx;
  }
  return idx;
}

// Evaluates a [PREDICATE_|NEGATED_]SECTION_START / SECTION_END pair by evaluating the tag
// in 'parent_context'. False or non-existant values cause the entire section to be
// skipped. True values cause the section to be evaluated as though it were a normal
// section, but with the parent context being the root context for that section.
//
// If 'is_negation' is true, the behaviour is the opposite of the above: false values
// cause the section to be normally evaluated etc.
int EvaluateSection(const string& document, const string& document_root, int idx,
    const Value* parent_context, TagOperator op, const string& tag_name,
    stringstream* out) {
  // Precondition: idx is the immedate next character after an opening {{ #tag_name }}
  const Value* context;
  ResolveJsonContext(tag_name, *parent_context, &context);

  // If we a) cannot resolve the context from the tag name or b) the context evaluates to
  // false, we should skip the contents of the template until a closing {{/tag_name}}.
  bool skip_contents = (context == NULL || context->IsFalse());

  // If the tag is a negative block (i.e. {{^tag_name}}), do the opposite: if the context
  // exists and is true, skip the contents, else echo them.
  if (op == NEGATED_SECTION_START) {
    context = parent_context;
    skip_contents = !skip_contents;
  } else if (op == PREDICATE_SECTION_START) {
    context = parent_context;
  }

  vector<const Value*> values;
  if (!skip_contents && context != NULL && context->IsArray()) {
    for (int i = 0; i < context->Size(); ++i) {
      values.push_back(&(*context)[i]);
    }
  } else {
    values.push_back(skip_contents ? NULL : context);
  }
  if (values.size() == 0) {
    skip_contents = true;
    values.push_back(NULL);
  }

  int start_idx = idx;
  BOOST_FOREACH(const Value* v, values) {
    idx = start_idx;
    while (idx < document.size()) {
      TagOperator tag_op;
      string next_tag_name;
      bool is_triple;
      idx = FindNextTag(document, idx, &tag_op, &next_tag_name, &is_triple,
          skip_contents ? NULL : out);

      if (idx > document.size()) return idx;
      if (tag_op == SECTION_END && next_tag_name == tag_name) {
        break;
      }

      // Don't need to evaluate any templates if we're skipping the contents
      if (!skip_contents) {
        idx = EvaluateTag(document, document_root, idx, v, tag_op, next_tag_name,
            is_triple, out);
      }
    }
  }
  return idx;
}

// Evaluates a SUBSTITUTION tag, by replacing its contents with the value of the tag's
// name in 'parent_context'.
int EvaluateSubstitution(const string& document, const int idx,
    const Value* parent_context, const string& tag_name, bool is_triple,
    stringstream* out) {
  const Value* context;
  ResolveJsonContext(tag_name, *parent_context, &context);
  if (context == NULL) return idx;
  if (context->IsString()) {
    if (!is_triple) {
      EscapeHtml(context->GetString(), out);
    } else {
      // TODO: Triple {{{ means don't escape
      (*out) << context->GetString();
    }
  } else if (context->IsInt()) {
    (*out) << context->GetInt();
  } else if (context->IsDouble()) {
    (*out) << context->GetDouble();
  } else if (context->IsBool()) {
    (*out) << context->GetBool();
  }
  return idx;
}

// Evaluates a 'partial' tempalte by reading it fully from disk, then rendering it
// directly into the current output with the current context.
//
// TODO: This could obviously be more efficient (and there are lots of file accesses in a
// long list context).
void EvaluatePartial(const string& tag_name, const string& document_root,
    const Value* parent_context, stringstream* out) {
  stringstream ss;
  ss << document_root << tag_name;
  ifstream tmpl(ss.str().c_str());
  if (!tmpl.is_open()) {
    ss << ".mustache";
    tmpl.open(ss.str().c_str());
    if (!tmpl.is_open()) return;
  }
  stringstream file_ss;
  file_ss << tmpl.rdbuf();
  RenderTemplate(file_ss.str(), document_root, *parent_context, out);
}

// Given a tag name, and its operator, evaluate the tag in the given context and write the
// output to 'out'. The heavy-lifting is delegated to specific Evaluate*()
// methods. Returns the new cursor position within 'document', or -1 on error.
int EvaluateTag(const string& document, const string& document_root, int idx,
    const Value* context, TagOperator tag,
    const string& tag_name, bool is_triple, stringstream* out) {
  if (idx == -1) return idx;
  switch (tag) {
    case SECTION_START:
    case PREDICATE_SECTION_START:
    case NEGATED_SECTION_START:
      return EvaluateSection(document, document_root, idx, context, tag, tag_name, out);
    case SUBSTITUTION:
      return EvaluateSubstitution(document, idx, context, tag_name, is_triple, out);
    case COMMENT:
      return idx; // Ignored
    case PARTIAL:
      EvaluatePartial(tag_name, document_root, context, out);
      return idx;
    case NONE:
      return idx; // No tag was found
    default:
      cout << "Unknown tag: " << tag << endl;
      return -1;
  }
}

void RenderTemplate(const string& document, const string& document_root,
    const Value& context, stringstream* out) {
  int idx = 0;
  while (idx < document.size() && idx != -1) {
    string tag_name;
    TagOperator tag_op;
    bool is_triple;
    idx = FindNextTag(document, idx, &tag_op, &tag_name, &is_triple, out);
    idx = EvaluateTag(document, document_root, idx, &context, tag_op, tag_name, is_triple,
        out);
  }
}

}
<commit_msg>Import small fix for rendering bools in templates<commit_after>// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "mustache.h"

#include "rapidjson/stringbuffer.h"
#include "rapidjson/writer.h"

#include <iostream>
#include <fstream>
#include <vector>

#include <boost/algorithm/string.hpp>
#include <boost/foreach.hpp>

using namespace rapidjson;
using namespace std;
using namespace boost::algorithm;

namespace mustache {

// TODO:
// # Handle malformed templates better
// # Support array_tag.length?
// # Better support for reading templates from files

enum TagOperator {
  SUBSTITUTION,
  SECTION_START,
  NEGATED_SECTION_START,
  PREDICATE_SECTION_START,
  SECTION_END,
  PARTIAL,
  COMMENT,
  NONE
};

TagOperator GetOperator(const string& tag) {
  if (tag.size() == 0) return SUBSTITUTION;
  switch (tag[0]) {
    case '#': return SECTION_START;
    case '^': return NEGATED_SECTION_START;
    case '?': return PREDICATE_SECTION_START;
    case '/': return SECTION_END;
    case '>': return PARTIAL;
    case '!': return COMMENT;
    default: return SUBSTITUTION;
  }
}

int EvaluateTag(const string& document, const string& document_root, int idx,
    const Value* context, TagOperator tag, const string& tag_name, bool is_triple,
    stringstream* out);

void EscapeHtml(const string& in, stringstream *out) {
  BOOST_FOREACH(const char& c, in) {
    switch (c) {
      case '&': (*out) << "&";
        break;
      case '"': (*out) << """;
        break;
      case '\'': (*out) << "'";
        break;
      case '<': (*out) << "<";
        break;
      case '>': (*out) << ">";
        break;
      default: (*out) << c;
        break;
    }
  }
}

// Breaks a dotted path into individual components. One wrinkle, which stops this from
// being a simple split() is that we allow path components to be quoted, e.g.: "foo".bar,
// and any '.' characters inside those quoted sections aren't considered to be
// delimiters. This is to allow Json keys that contain periods.
void FindJsonPathComponents(const string& path, vector<string>* components) {
  bool in_quote = false;
  bool escape_this_char = false;
  int start = 0;
  for (int i = start; i < path.size(); ++i) {
    if (path[i] == '"' && !escape_this_char) in_quote = !in_quote;
    if (path[i] == '.' && !escape_this_char && !in_quote) {
      // Current char == delimiter and not escaped and not in a quote pair => found a
      // component
      if (i - start > 0) {
        if (path[start] == '"' && path[(i - 1) - start] == '"') {
          if (i - start > 3) {
            components->push_back(path.substr(start + 1, i - (start + 2)));
          }
        } else {
          components->push_back(path.substr(start, i - start));
        }
        start = i + 1;
      }
    }

    escape_this_char = (path[i] == '\\' && !escape_this_char);
  }

  if (path.size() - start > 0) {
    if (path[start] == '"' && path[(path.size() - 1) - start] == '"') {
      if (path.size() - start > 3) {
        components->push_back(path.substr(start + 1, path.size() - (start + 2)));
      }
    } else {
      components->push_back(path.substr(start, path.size() - start));
    }
  }
}

// Looks up the json entity at 'path' in 'parent_context', and places it in 'resolved'. If
// the entity does not exist (i.e. the path is invalid), 'resolved' will be set to NULL.
void ResolveJsonContext(const string& path, const Value& parent_context,
    const Value** resolved) {
  if (path == ".") {
    *resolved = &parent_context;
    return;
  }
  vector<string> components;
  FindJsonPathComponents(path, &components);
  const Value* cur = &parent_context;
  BOOST_FOREACH(const string& c, components) {
    if (cur->IsObject() && cur->HasMember(c.c_str())) {
      cur = &(*cur)[c.c_str()];
    } else {
      *resolved = NULL;
      return;
    }
  }

  *resolved = cur;
}

int FindNextTag(const string& document, int idx, TagOperator* tag_op, string* tag_name,
    bool* is_triple, stringstream* out) {
  *tag_op = NONE;
  while (idx < document.size()) {
    if (document[idx] == '{' && idx < (document.size() - 3) && document[idx + 1] == '{') {
      if (document[idx + 2] == '{') {
        idx += 3;
        *is_triple = true;
      } else {
        *is_triple = false;
        idx += 2; // Now at start of template expression
      }
      stringstream expr;
      while (idx < document.size()) {
        if (document[idx] != '}') {
          expr << document[idx];
          ++idx;
        } else {
          if (!*is_triple && idx < document.size() - 1 && document[idx + 1] == '}') {
            ++idx;
            break;
          } else if (*is_triple && idx < document.size() - 2 && document[idx + 1] == '}'
              && document[idx + 2] == '}') {
            idx += 2;
            break;
          } else {
            expr << '}';
          }
        }
      }

      string key = expr.str();
      trim(key);
      if (key != ".") trim_if(key, is_any_of("."));
      if (key.size() == 0) continue;
      *tag_op = GetOperator(key);
      if (*tag_op != SUBSTITUTION) {
        key = key.substr(1);
        trim(key);
      }
      if (key.size() == 0) continue;
      *tag_name = key;
      return ++idx;
    } else {
      if (out != NULL) (*out) << document[idx];
    }
    ++idx;
  }
  return idx;
}

// Evaluates a [PREDICATE_|NEGATED_]SECTION_START / SECTION_END pair by evaluating the tag
// in 'parent_context'. False or non-existant values cause the entire section to be
// skipped. True values cause the section to be evaluated as though it were a normal
// section, but with the parent context being the root context for that section.
//
// If 'is_negation' is true, the behaviour is the opposite of the above: false values
// cause the section to be normally evaluated etc.
int EvaluateSection(const string& document, const string& document_root, int idx,
    const Value* parent_context, TagOperator op, const string& tag_name,
    stringstream* out) {
  // Precondition: idx is the immedate next character after an opening {{ #tag_name }}
  const Value* context;
  ResolveJsonContext(tag_name, *parent_context, &context);

  // If we a) cannot resolve the context from the tag name or b) the context evaluates to
  // false, we should skip the contents of the template until a closing {{/tag_name}}.
  bool skip_contents = (context == NULL || context->IsFalse());

  // If the tag is a negative block (i.e. {{^tag_name}}), do the opposite: if the context
  // exists and is true, skip the contents, else echo them.
  if (op == NEGATED_SECTION_START) {
    context = parent_context;
    skip_contents = !skip_contents;
  } else if (op == PREDICATE_SECTION_START) {
    context = parent_context;
  }

  vector<const Value*> values;
  if (!skip_contents && context != NULL && context->IsArray()) {
    for (int i = 0; i < context->Size(); ++i) {
      values.push_back(&(*context)[i]);
    }
  } else {
    values.push_back(skip_contents ? NULL : context);
  }
  if (values.size() == 0) {
    skip_contents = true;
    values.push_back(NULL);
  }

  int start_idx = idx;
  BOOST_FOREACH(const Value* v, values) {
    idx = start_idx;
    while (idx < document.size()) {
      TagOperator tag_op;
      string next_tag_name;
      bool is_triple;
      idx = FindNextTag(document, idx, &tag_op, &next_tag_name, &is_triple,
          skip_contents ? NULL : out);

      if (idx > document.size()) return idx;
      if (tag_op == SECTION_END && next_tag_name == tag_name) {
        break;
      }

      // Don't need to evaluate any templates if we're skipping the contents
      if (!skip_contents) {
        idx = EvaluateTag(document, document_root, idx, v, tag_op, next_tag_name,
            is_triple, out);
      }
    }
  }
  return idx;
}

// Evaluates a SUBSTITUTION tag, by replacing its contents with the value of the tag's
// name in 'parent_context'.
int EvaluateSubstitution(const string& document, const int idx,
    const Value* parent_context, const string& tag_name, bool is_triple,
    stringstream* out) {
  const Value* context;
  ResolveJsonContext(tag_name, *parent_context, &context);
  if (context == NULL) return idx;
  if (context->IsString()) {
    if (!is_triple) {
      EscapeHtml(context->GetString(), out);
    } else {
      // TODO: Triple {{{ means don't escape
      (*out) << context->GetString();
    }
  } else if (context->IsInt()) {
    (*out) << context->GetInt();
  } else if (context->IsDouble()) {
    (*out) << context->GetDouble();
  } else if (context->IsBool()) {
    (*out) << boolalpha << context->GetBool();
  }
  return idx;
}

// Evaluates a 'partial' tempalte by reading it fully from disk, then rendering it
// directly into the current output with the current context.
//
// TODO: This could obviously be more efficient (and there are lots of file accesses in a
// long list context).
void EvaluatePartial(const string& tag_name, const string& document_root,
    const Value* parent_context, stringstream* out) {
  stringstream ss;
  ss << document_root << tag_name;
  ifstream tmpl(ss.str().c_str());
  if (!tmpl.is_open()) {
    ss << ".mustache";
    tmpl.open(ss.str().c_str());
    if (!tmpl.is_open()) return;
  }
  stringstream file_ss;
  file_ss << tmpl.rdbuf();
  RenderTemplate(file_ss.str(), document_root, *parent_context, out);
}

// Given a tag name, and its operator, evaluate the tag in the given context and write the
// output to 'out'. The heavy-lifting is delegated to specific Evaluate*()
// methods. Returns the new cursor position within 'document', or -1 on error.
int EvaluateTag(const string& document, const string& document_root, int idx,
    const Value* context, TagOperator tag,
    const string& tag_name, bool is_triple, stringstream* out) {
  if (idx == -1) return idx;
  switch (tag) {
    case SECTION_START:
    case PREDICATE_SECTION_START:
    case NEGATED_SECTION_START:
      return EvaluateSection(document, document_root, idx, context, tag, tag_name, out);
    case SUBSTITUTION:
      return EvaluateSubstitution(document, idx, context, tag_name, is_triple, out);
    case COMMENT:
      return idx; // Ignored
    case PARTIAL:
      EvaluatePartial(tag_name, document_root, context, out);
      return idx;
    case NONE:
      return idx; // No tag was found
    default:
      cout << "Unknown tag: " << tag << endl;
      return -1;
  }
}

void RenderTemplate(const string& document, const string& document_root,
    const Value& context, stringstream* out) {
  int idx = 0;
  while (idx < document.size() && idx != -1) {
    string tag_name;
    TagOperator tag_op;
    bool is_triple;
    idx = FindNextTag(document, idx, &tag_op, &tag_name, &is_triple, out);
    idx = EvaluateTag(document, document_root, idx, &context, tag_op, tag_name, is_triple,
        out);
  }
}

}
<|endoftext|>


<commit_before>// @(#)root/tmva/pymva $Id$
// Authors: Omar Zapata, Lorenzo Moneta, Sergei Gleyzer 2015

/**********************************************************************************
 * Project: TMVA - a Root-integrated toolkit for multivariate data analysis       *
 * Package: TMVA                                                                  *
 * Class  : PyMethodBase                                                          *
 *                                                                                *
 * Description:                                                                   *
 *      Virtual base class for all MVA method based on python                     *
 *                                                                                *
 **********************************************************************************/

#include <Python.h>    // Needs to be included first to avoid redefinition of _POSIX_C_SOURCE
#include <TMVA/PyMethodBase.h>

#include "TMVA/DataSet.h"
#include "TMVA/DataSetInfo.h"
#include "TMVA/MsgLogger.h"
#include "TMVA/Results.h"
#include "TMVA/Timer.h"

#include <TApplication.h>

#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
#include <numpy/arrayobject.h>

#include <fstream>
#include <wchar.h>

using namespace TMVA;

ClassImp(PyMethodBase)

// NOTE: Introduce here nothing that breaks if multiple instances
// of the same method share these objects, e.g., the local namespace.
PyObject *PyMethodBase::fModuleBuiltin = NULL;
PyObject *PyMethodBase::fEval = NULL;
PyObject *PyMethodBase::fOpen = NULL;

PyObject *PyMethodBase::fModulePickle = NULL;
PyObject *PyMethodBase::fPickleDumps = NULL;
PyObject *PyMethodBase::fPickleLoads = NULL;

PyObject *PyMethodBase::fMain = NULL;
PyObject *PyMethodBase::fGlobalNS = NULL;

class PyGILRAII {
   PyGILState_STATE m_GILState;
public:
   PyGILRAII():m_GILState(PyGILState_Ensure()){}
   ~PyGILRAII(){PyGILState_Release(m_GILState);}
};

//_______________________________________________________________________
PyMethodBase::PyMethodBase(const TString &jobName,
                           Types::EMVA methodType,
                           const TString &methodTitle,
                           DataSetInfo &dsi,
                           const TString &theOption ): MethodBase(jobName, methodType, methodTitle, dsi, theOption),
   fClassifier(NULL)
{
   if (!PyIsInitialized()) {
      PyInitialize();
   }

   // Set up private local namespace for each method instance
   fLocalNS = PyDict_New();
   if (!fLocalNS) {
      TMVA::MsgLogger Log;
      Log << kFATAL << "Can't init local namespace" << Endl;
   }
}

//_______________________________________________________________________
PyMethodBase::PyMethodBase(Types::EMVA methodType,
                           DataSetInfo &dsi,
                           const TString &weightFile): MethodBase(methodType, dsi, weightFile),
   fClassifier(NULL)
{
   if (!PyIsInitialized()) {
      PyInitialize();
   }

   // Set up private local namespace for each method instance
   fLocalNS = PyDict_New();
   if (!fLocalNS) {
      TMVA::MsgLogger Log;
      Log << kFATAL << "Can't init local namespace" << Endl;
   }
}

//_______________________________________________________________________
PyMethodBase::~PyMethodBase()
{
}

//_______________________________________________________________________
PyObject *PyMethodBase::Eval(TString code)
{
   if(!PyIsInitialized()) PyInitialize();
   PyObject *pycode = Py_BuildValue("(sOO)", code.Data(), fGlobalNS, fLocalNS);
   PyObject *result = PyObject_CallObject(fEval, pycode);
   Py_DECREF(pycode);
   return result;
}

//_______________________________________________________________________
// NOTE: We introduce a shared global namespace fGlobalNS, but using
// a private local namespace fLocalNS. This prohibits the interference
// of instances of the same method with the same factory, e.g., by overriding
// variables in the same local namespace.
void PyMethodBase::PyInitialize()
{
   TMVA::MsgLogger Log;

   bool pyIsInitialized = PyIsInitialized();
   if (!pyIsInitialized) {
      Py_Initialize();
   }

    PyGILRAII thePyGILRAII;

   if (!pyIsInitialized) {
      _import_array();
   }

   fMain = PyImport_AddModule("__main__");
   if (!fMain) {
      Log << kFATAL << "Can't import __main__" << Endl;
      Log << Endl;
   }

   fGlobalNS = PyModule_GetDict(fMain);
   if (!fGlobalNS) {
      Log << kFATAL << "Can't init global namespace" << Endl;
      Log << Endl;
   }

   #if PY_MAJOR_VERSION < 3
   //preparing objects for eval
   PyObject *bName =  PyUnicode_FromString("__builtin__");
   // Import the file as a Python module.
   fModuleBuiltin = PyImport_Import(bName);
   if (!fModuleBuiltin) {
      Log << kFATAL << "Can't import __builtin__" << Endl;
      Log << Endl;
   }
   #else
   //preparing objects for eval
   PyObject *bName =  PyUnicode_FromString("builtins");
   // Import the file as a Python module.
   fModuleBuiltin = PyImport_Import(bName);
   if (!fModuleBuiltin) {
      Log << kFATAL << "Can't import builtins" << Endl;
      Log << Endl;
   }
   #endif

   PyObject *mDict = PyModule_GetDict(fModuleBuiltin);
   fEval = PyDict_GetItemString(mDict, "eval");
   fOpen = PyDict_GetItemString(mDict, "open");

   Py_DECREF(bName);
   Py_DECREF(mDict);
   //preparing objects for pickle
   PyObject *pName = PyUnicode_FromString("pickle");
   // Import the file as a Python module.
   fModulePickle = PyImport_Import(pName);
   if (!fModulePickle) {
      Log << kFATAL << "Can't import pickle" << Endl;
      Log << Endl;
   }
   PyObject *pDict = PyModule_GetDict(fModulePickle);
   fPickleDumps = PyDict_GetItemString(pDict, "dump");
   fPickleLoads = PyDict_GetItemString(pDict, "load");

   Py_DECREF(pName);
   Py_DECREF(pDict);
}

//_______________________________________________________________________
void PyMethodBase::PyFinalize()
{
   Py_Finalize();
   if (fEval) Py_DECREF(fEval);
   if (fModuleBuiltin) Py_DECREF(fModuleBuiltin);
   if (fPickleDumps) Py_DECREF(fPickleDumps);
   if (fPickleLoads) Py_DECREF(fPickleLoads);
   if(fMain) Py_DECREF(fMain);//objects fGlobalNS and fLocalNS will be free here
}
void PyMethodBase::PySetProgramName(TString name)
{
   #if PY_MAJOR_VERSION < 3
   Py_SetProgramName(const_cast<char*>(name.Data()));
   #else
   Py_SetProgramName((wchar_t *)name.Data());
   #endif
}

size_t mystrlen(const char* s) { return strlen(s); }
size_t mystrlen(const wchar_t* s) { return wcslen(s); }

//_______________________________________________________________________
TString PyMethodBase::Py_GetProgramName()
{
auto progName = ::Py_GetProgramName();
return std::string(progName, progName + mystrlen(progName));
}
//_______________________________________________________________________
int  PyMethodBase::PyIsInitialized()
{
   if (!Py_IsInitialized()) return kFALSE;
   if (!fEval) return kFALSE;
   if (!fModuleBuiltin) return kFALSE;
   if (!fPickleDumps) return kFALSE;
   if (!fPickleLoads) return kFALSE;
   return kTRUE;
}

void PyMethodBase::Serialize(TString path,PyObject *obj)
{
 if(!PyIsInitialized()) PyInitialize();
 PyObject *file_arg = Py_BuildValue("(ss)", path.Data(),"wb");
 PyObject *file = PyObject_CallObject(fOpen,file_arg);
 PyObject *model_arg = Py_BuildValue("(OO)", obj,file);
 PyObject *model_data = PyObject_CallObject(fPickleDumps , model_arg);

 Py_DECREF(file_arg);
 Py_DECREF(file);
 Py_DECREF(model_arg);
 Py_DECREF(model_data);
}

void PyMethodBase::UnSerialize(TString path,PyObject **obj)
{
 PyObject *file_arg = Py_BuildValue("(ss)", path.Data(),"rb");
 PyObject *file = PyObject_CallObject(fOpen,file_arg);

 PyObject *model_arg = Py_BuildValue("(O)", file);
 *obj = PyObject_CallObject(fPickleLoads , model_arg);

 Py_DECREF(file_arg);
 Py_DECREF(file);
 Py_DECREF(model_arg);
}

////////////////////////////////////////////////////////////////////////////////
/// get all the MVA values for the events of the current Data type
std::vector<Double_t> PyMethodBase::GetMvaValues(Long64_t firstEvt, Long64_t lastEvt, Bool_t logProgress)
{

   if (!fClassifier) ReadModelFromFile();

   Long64_t nEvents = Data()->GetNEvents();
   if (firstEvt > lastEvt || lastEvt > nEvents) lastEvt = nEvents;
   if (firstEvt < 0) firstEvt = 0;
   std::vector<Double_t> values(lastEvt-firstEvt);

   nEvents = values.size();

   UInt_t nvars = Data()->GetNVariables();

   int dims[2];
   dims[0] = nEvents;
   dims[1] = nvars;
   PyArrayObject *pEvent= (PyArrayObject *)PyArray_FromDims(2, dims, NPY_FLOAT);
   float *pValue = (float *)(PyArray_DATA(pEvent));

//    int dims2[2];
//    dims2[0] = 1;
//    dims2[1] = nvars;

   // use timer
   Timer timer( nEvents, GetName(), kTRUE );
   if (logProgress)
      Log() << kINFO<<Form("Dataset[%s] : ",DataInfo().GetName())<< "Evaluation of " << GetMethodName() << " on "
            << (Data()->GetCurrentType()==Types::kTraining?"training":"testing") << " sample (" << nEvents << " events)" << Endl;

   // fill numpy array with events data
   for (Int_t ievt=0; ievt<nEvents; ievt++) {
     Data()->SetCurrentEvent(ievt);
      const TMVA::Event *e = Data()->GetEvent();
      assert(nvars == e->GetNVariables());
      for (UInt_t i = 0; i < nvars; i++) {
         pValue[ievt * nvars + i] = e->GetValue(i);
      }
      // if (ievt%100 == 0)
      //    std::cout << "Event " << ievt << "  type" << DataInfo().IsSignal(e) << " : " << pValue[ievt*nvars] << "  " << pValue[ievt*nvars+1] << "  " << pValue[ievt*nvars+2] << std::endl;
   }

   // pass all the events to Scikit and evaluate the probabilities
   PyArrayObject *result = (PyArrayObject *)PyObject_CallMethod(fClassifier, const_cast<char *>("predict_proba"), const_cast<char *>("(O)"), pEvent);
   double *proba = (double *)(PyArray_DATA(result));

   // the return probabilities is a vector of pairs of (p_sig,p_backg)
   // we ar einterested only in the signal probability
   std::vector<double> mvaValues(nEvents);
   for (int i = 0; i < nEvents; ++i)
      mvaValues[i] = proba[2*i];

   if (logProgress) {
      Log() << kINFO <<Form("Dataset[%s] : ",DataInfo().GetName())<< "Elapsed time for evaluation of " << nEvents <<  " events: "
            << timer.GetElapsedTime() << "       " << Endl;
   }

   Py_DECREF(result);
   Py_DECREF(pEvent);

   return mvaValues;
}

//_______________________________________________________________________
// Helper function to run python code from string in local namespace with
// error handling
// `start` defines the start symbol defined in PyRun_String (Py_eval_input,
// Py_single_input, Py_file_input)
void PyMethodBase::PyRunString(TString code, TString errorMessage, int start) {
   fPyReturn = PyRun_String(code, start, fGlobalNS, fLocalNS);
   if (!fPyReturn) {
      Log() << kWARNING << "Failed to run python code: " << code << Endl;
      Log() << kWARNING << "Python error message:" << Endl;
      PyErr_Print();
      Log() << kFATAL << errorMessage << Endl;
   }
}
<commit_msg>In TMVA PyMethodBase, use object's own log rather than a local one.<commit_after>// @(#)root/tmva/pymva $Id$
// Authors: Omar Zapata, Lorenzo Moneta, Sergei Gleyzer 2015

/**********************************************************************************
 * Project: TMVA - a Root-integrated toolkit for multivariate data analysis       *
 * Package: TMVA                                                                  *
 * Class  : PyMethodBase                                                          *
 *                                                                                *
 * Description:                                                                   *
 *      Virtual base class for all MVA method based on python                     *
 *                                                                                *
 **********************************************************************************/

#include <Python.h>    // Needs to be included first to avoid redefinition of _POSIX_C_SOURCE
#include <TMVA/PyMethodBase.h>

#include "TMVA/DataSet.h"
#include "TMVA/DataSetInfo.h"
#include "TMVA/MsgLogger.h"
#include "TMVA/Results.h"
#include "TMVA/Timer.h"

#include <TApplication.h>

#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
#include <numpy/arrayobject.h>

#include <fstream>
#include <wchar.h>

using namespace TMVA;

ClassImp(PyMethodBase)

// NOTE: Introduce here nothing that breaks if multiple instances
// of the same method share these objects, e.g., the local namespace.
PyObject *PyMethodBase::fModuleBuiltin = NULL;
PyObject *PyMethodBase::fEval = NULL;
PyObject *PyMethodBase::fOpen = NULL;

PyObject *PyMethodBase::fModulePickle = NULL;
PyObject *PyMethodBase::fPickleDumps = NULL;
PyObject *PyMethodBase::fPickleLoads = NULL;

PyObject *PyMethodBase::fMain = NULL;
PyObject *PyMethodBase::fGlobalNS = NULL;

class PyGILRAII {
   PyGILState_STATE m_GILState;
public:
   PyGILRAII():m_GILState(PyGILState_Ensure()){}
   ~PyGILRAII(){PyGILState_Release(m_GILState);}
};

//_______________________________________________________________________
PyMethodBase::PyMethodBase(const TString &jobName,
                           Types::EMVA methodType,
                           const TString &methodTitle,
                           DataSetInfo &dsi,
                           const TString &theOption ): MethodBase(jobName, methodType, methodTitle, dsi, theOption),
   fClassifier(NULL)
{
   if (!PyIsInitialized()) {
      PyInitialize();
   }

   // Set up private local namespace for each method instance
   fLocalNS = PyDict_New();
   if (!fLocalNS) {
      Log() << kFATAL << "Can't init local namespace" << Endl;
   }
}

//_______________________________________________________________________
PyMethodBase::PyMethodBase(Types::EMVA methodType,
                           DataSetInfo &dsi,
                           const TString &weightFile): MethodBase(methodType, dsi, weightFile),
   fClassifier(NULL)
{
   if (!PyIsInitialized()) {
      PyInitialize();
   }

   // Set up private local namespace for each method instance
   fLocalNS = PyDict_New();
   if (!fLocalNS) {
      Log() << kFATAL << "Can't init local namespace" << Endl;
   }
}

//_______________________________________________________________________
PyMethodBase::~PyMethodBase()
{
}

//_______________________________________________________________________
PyObject *PyMethodBase::Eval(TString code)
{
   if(!PyIsInitialized()) PyInitialize();
   PyObject *pycode = Py_BuildValue("(sOO)", code.Data(), fGlobalNS, fLocalNS);
   PyObject *result = PyObject_CallObject(fEval, pycode);
   Py_DECREF(pycode);
   return result;
}

//_______________________________________________________________________
// NOTE: We introduce a shared global namespace fGlobalNS, but using
// a private local namespace fLocalNS. This prohibits the interference
// of instances of the same method with the same factory, e.g., by overriding
// variables in the same local namespace.
void PyMethodBase::PyInitialize()
{
   TMVA::MsgLogger Log;

   bool pyIsInitialized = PyIsInitialized();
   if (!pyIsInitialized) {
      Py_Initialize();
   }

    PyGILRAII thePyGILRAII;

   if (!pyIsInitialized) {
      _import_array();
   }

   fMain = PyImport_AddModule("__main__");
   if (!fMain) {
      Log << kFATAL << "Can't import __main__" << Endl;
      Log << Endl;
   }

   fGlobalNS = PyModule_GetDict(fMain);
   if (!fGlobalNS) {
      Log << kFATAL << "Can't init global namespace" << Endl;
      Log << Endl;
   }

   #if PY_MAJOR_VERSION < 3
   //preparing objects for eval
   PyObject *bName =  PyUnicode_FromString("__builtin__");
   // Import the file as a Python module.
   fModuleBuiltin = PyImport_Import(bName);
   if (!fModuleBuiltin) {
      Log << kFATAL << "Can't import __builtin__" << Endl;
      Log << Endl;
   }
   #else
   //preparing objects for eval
   PyObject *bName =  PyUnicode_FromString("builtins");
   // Import the file as a Python module.
   fModuleBuiltin = PyImport_Import(bName);
   if (!fModuleBuiltin) {
      Log << kFATAL << "Can't import builtins" << Endl;
      Log << Endl;
   }
   #endif

   PyObject *mDict = PyModule_GetDict(fModuleBuiltin);
   fEval = PyDict_GetItemString(mDict, "eval");
   fOpen = PyDict_GetItemString(mDict, "open");

   Py_DECREF(bName);
   Py_DECREF(mDict);
   //preparing objects for pickle
   PyObject *pName = PyUnicode_FromString("pickle");
   // Import the file as a Python module.
   fModulePickle = PyImport_Import(pName);
   if (!fModulePickle) {
      Log << kFATAL << "Can't import pickle" << Endl;
      Log << Endl;
   }
   PyObject *pDict = PyModule_GetDict(fModulePickle);
   fPickleDumps = PyDict_GetItemString(pDict, "dump");
   fPickleLoads = PyDict_GetItemString(pDict, "load");

   Py_DECREF(pName);
   Py_DECREF(pDict);
}

//_______________________________________________________________________
void PyMethodBase::PyFinalize()
{
   Py_Finalize();
   if (fEval) Py_DECREF(fEval);
   if (fModuleBuiltin) Py_DECREF(fModuleBuiltin);
   if (fPickleDumps) Py_DECREF(fPickleDumps);
   if (fPickleLoads) Py_DECREF(fPickleLoads);
   if(fMain) Py_DECREF(fMain);//objects fGlobalNS and fLocalNS will be free here
}
void PyMethodBase::PySetProgramName(TString name)
{
   #if PY_MAJOR_VERSION < 3
   Py_SetProgramName(const_cast<char*>(name.Data()));
   #else
   Py_SetProgramName((wchar_t *)name.Data());
   #endif
}

size_t mystrlen(const char* s) { return strlen(s); }
size_t mystrlen(const wchar_t* s) { return wcslen(s); }

//_______________________________________________________________________
TString PyMethodBase::Py_GetProgramName()
{
auto progName = ::Py_GetProgramName();
return std::string(progName, progName + mystrlen(progName));
}
//_______________________________________________________________________
int  PyMethodBase::PyIsInitialized()
{
   if (!Py_IsInitialized()) return kFALSE;
   if (!fEval) return kFALSE;
   if (!fModuleBuiltin) return kFALSE;
   if (!fPickleDumps) return kFALSE;
   if (!fPickleLoads) return kFALSE;
   return kTRUE;
}

void PyMethodBase::Serialize(TString path,PyObject *obj)
{
 if(!PyIsInitialized()) PyInitialize();
 PyObject *file_arg = Py_BuildValue("(ss)", path.Data(),"wb");
 PyObject *file = PyObject_CallObject(fOpen,file_arg);
 PyObject *model_arg = Py_BuildValue("(OO)", obj,file);
 PyObject *model_data = PyObject_CallObject(fPickleDumps , model_arg);

 Py_DECREF(file_arg);
 Py_DECREF(file);
 Py_DECREF(model_arg);
 Py_DECREF(model_data);
}

void PyMethodBase::UnSerialize(TString path,PyObject **obj)
{
 PyObject *file_arg = Py_BuildValue("(ss)", path.Data(),"rb");
 PyObject *file = PyObject_CallObject(fOpen,file_arg);

 PyObject *model_arg = Py_BuildValue("(O)", file);
 *obj = PyObject_CallObject(fPickleLoads , model_arg);

 Py_DECREF(file_arg);
 Py_DECREF(file);
 Py_DECREF(model_arg);
}

////////////////////////////////////////////////////////////////////////////////
/// get all the MVA values for the events of the current Data type
std::vector<Double_t> PyMethodBase::GetMvaValues(Long64_t firstEvt, Long64_t lastEvt, Bool_t logProgress)
{

   if (!fClassifier) ReadModelFromFile();

   Long64_t nEvents = Data()->GetNEvents();
   if (firstEvt > lastEvt || lastEvt > nEvents) lastEvt = nEvents;
   if (firstEvt < 0) firstEvt = 0;
   std::vector<Double_t> values(lastEvt-firstEvt);

   nEvents = values.size();

   UInt_t nvars = Data()->GetNVariables();

   int dims[2];
   dims[0] = nEvents;
   dims[1] = nvars;
   PyArrayObject *pEvent= (PyArrayObject *)PyArray_FromDims(2, dims, NPY_FLOAT);
   float *pValue = (float *)(PyArray_DATA(pEvent));

//    int dims2[2];
//    dims2[0] = 1;
//    dims2[1] = nvars;

   // use timer
   Timer timer( nEvents, GetName(), kTRUE );
   if (logProgress)
      Log() << kINFO<<Form("Dataset[%s] : ",DataInfo().GetName())<< "Evaluation of " << GetMethodName() << " on "
            << (Data()->GetCurrentType()==Types::kTraining?"training":"testing") << " sample (" << nEvents << " events)" << Endl;

   // fill numpy array with events data
   for (Int_t ievt=0; ievt<nEvents; ievt++) {
     Data()->SetCurrentEvent(ievt);
      const TMVA::Event *e = Data()->GetEvent();
      assert(nvars == e->GetNVariables());
      for (UInt_t i = 0; i < nvars; i++) {
         pValue[ievt * nvars + i] = e->GetValue(i);
      }
      // if (ievt%100 == 0)
      //    std::cout << "Event " << ievt << "  type" << DataInfo().IsSignal(e) << " : " << pValue[ievt*nvars] << "  " << pValue[ievt*nvars+1] << "  " << pValue[ievt*nvars+2] << std::endl;
   }

   // pass all the events to Scikit and evaluate the probabilities
   PyArrayObject *result = (PyArrayObject *)PyObject_CallMethod(fClassifier, const_cast<char *>("predict_proba"), const_cast<char *>("(O)"), pEvent);
   double *proba = (double *)(PyArray_DATA(result));

   // the return probabilities is a vector of pairs of (p_sig,p_backg)
   // we ar einterested only in the signal probability
   std::vector<double> mvaValues(nEvents);
   for (int i = 0; i < nEvents; ++i)
      mvaValues[i] = proba[2*i];

   if (logProgress) {
      Log() << kINFO <<Form("Dataset[%s] : ",DataInfo().GetName())<< "Elapsed time for evaluation of " << nEvents <<  " events: "
            << timer.GetElapsedTime() << "       " << Endl;
   }

   Py_DECREF(result);
   Py_DECREF(pEvent);

   return mvaValues;
}

//_______________________________________________________________________
// Helper function to run python code from string in local namespace with
// error handling
// `start` defines the start symbol defined in PyRun_String (Py_eval_input,
// Py_single_input, Py_file_input)
void PyMethodBase::PyRunString(TString code, TString errorMessage, int start) {
   fPyReturn = PyRun_String(code, start, fGlobalNS, fLocalNS);
   if (!fPyReturn) {
      Log() << kWARNING << "Failed to run python code: " << code << Endl;
      Log() << kWARNING << "Python error message:" << Endl;
      PyErr_Print();
      Log() << kFATAL << errorMessage << Endl;
   }
}
<|endoftext|>


<commit_before>#include "trainer.hpp" //trainer class

void Trainer::SetLife(float life) //setlife function
{
  //write process memory with the new value
	int stat = WriteProcessMemory(Trainer::memory.hProc, (LPVOID)Trainer::TRAINER_LIFE, &life, (DWORD)sizeof(life), NULL);

	if (stat > 0){ //if it success it says this
		std::clog << "Sucesso ao escrever na memoria com valor: " << life << std::endl;
	}
	else { //if not it says another thing
		std::cerr << "Ocorreu algo inesperado, tente novamente." << std::endl;
	}
}

//same thing as life
void Trainer::SetMoney(int money)
{
	int stat = WriteProcessMemory(Trainer::memory.hProc, (LPVOID)Trainer::TRAINER_MONEY, &money, (DWORD)sizeof(money), NULL);

	if (stat > 0){
		std::clog << "Sucesso ao escrever na memoria com valor: " << money << std::endl;
	}
	else {
		std::cerr << "Ocorreu algo inesperado, tente novamente." << std::endl;
	}
}

//this one is diferent it has dynamic address, i did this way but i will probably use another way so i don't have to create
//multiple variables to declare each dynamic addres
void Trainer::SetArmor(float armor)
{
	unsigned long pointer = 0xB6F5F0; //CPed address
	unsigned long offset = 0x548; //armor address
	unsigned long address = pointer + offset; //the address's combined togther

	//same thing as the life, it writes a new value to the memory
	int stat = WriteProcessMemory(Trainer::memory.hProc, (LPVOID)address, &armor, (DWORD)sizeof(armor), NULL);

	if (stat > 0){
		std::clog << "Sucesso ao escrever na memoria com valor: " << armor << std::endl;
	}
	else {
		std::cerr << "Ocorreu algo inesperado, tente novamente." << std::endl;
	}
}

/* Future functions
void Trainer::SetX(double pos)
{
	int stat = WriteProcessMemory(Trainer::memory.hProc, (LPVOID)Trainer::TRAINER_X, &pos, (DWORD)sizeof(pos), NULL);

	if (stat > 0){
		std::clog << "Sucesso ao escrever na memoria com valor: " << pos << std::endl;
	}
	else {
		std::cerr << "Ocorreu algo inesperado, tente novamente." << std::endl;
	}
}

void Trainer::SetY(double pos)
{
	int stat = WriteProcessMemory(Trainer::memory.hProc, (LPVOID)Trainer::TRAINER_Y, &pos, (DWORD)sizeof(pos), NULL);

	if (stat > 0){
		std::clog << "Sucesso ao escrever na memoria com valor: " << pos << std::endl;
	}
	else {
		std::cerr << "Ocorreu algo inesperado, tente novamente." << std::endl;
	}
}

void Trainer::SetZ(double pos)
{
	int stat = WriteProcessMemory(Trainer::memory.hProc, (LPVOID)Trainer::TRAINER_Z, &pos, (DWORD)sizeof(pos), NULL);

	if (stat > 0){
		std::clog << "Sucesso ao escrever na memoria com valor: " << pos << std::endl;
	}
	else {
		std::cerr << "Ocorreu algo inesperado, tente novamente." << std::endl;
	}
}

void Trainer::SetPos(double x,double y, double z)
{
	Trainer::SetX(x); Trainer::SetY(y); Trainer::SetZ(z);
}*/
<commit_msg>Update trainer.cpp<commit_after>#include "trainer.hpp" //trainer class

void Trainer::SetLife(float life) //setlife function
{
  //write process memory with the new value
	int stat = WriteProcessMemory(Trainer::memory.hProc, (LPVOID)Trainer::TRAINER_LIFE, &life, (DWORD)sizeof(life), NULL);

	if (stat > 0){ //if it success it says this
		std::clog << "Sucesso ao escrever na memoria com valor: " << life << std::endl;
	}
	else { //if not it says another thing
		std::cerr << "Ocorreu algo inesperado, tente novamente." << std::endl;
	}
}

//same thing as life
void Trainer::SetMoney(int money)
{
	int stat = WriteProcessMemory(Trainer::memory.hProc, (LPVOID)Trainer::TRAINER_MONEY, &money, (DWORD)sizeof(money), NULL);

	if (stat > 0){
		std::clog << "Sucesso ao escrever na memoria com valor: " << money << std::endl;
	}
	else {
		std::cerr << "Ocorreu algo inesperado, tente novamente." << std::endl;
	}
}

//this one is diferent it has dynamic address, i did this way but i will probably use another way so i don't have to create
//multiple variables to declare each dynamic addres
void Trainer::SetArmor(float armor)
{
	unsigned long pointer = 0xB6F5F0; //CPed address
	unsigned long offset = 0x548; //armor address
	unsigned long address = pointer + offset; //the address's combined togther

	//same thing as the life, it writes a new value to the memory
	int stat = WriteProcessMemory(Trainer::memory.hProc, (LPVOID)address, &armor, (DWORD)sizeof(armor), NULL);

	if (stat > 0){
		std::clog << "Sucesso ao escrever na memoria com valor: " << armor << std::endl;
	}
	else {
		std::cerr << "Ocorreu algo inesperado, tente novamente." << std::endl;
	}
}
void Trainer::SetWantedLevel(int level)
{
	int stat = WriteProcessMemory(Trainer::memory.hProc, (LPVOID)Trainer::TRAINER_WANTED, &level, (DWORD)sizeof(level), NULL);

	if (stat > 0){
		std::clog << "Sucesso ao escrever na memoria com valor: " << level << std::endl;
	}
	else {
		std::cerr << "Ocorreu algo inesperado, tente novamente." << std::endl;
	}

}

/* Future functions
void Trainer::SetX(double pos)
{
	int stat = WriteProcessMemory(Trainer::memory.hProc, (LPVOID)Trainer::TRAINER_X, &pos, (DWORD)sizeof(pos), NULL);

	if (stat > 0){
		std::clog << "Sucesso ao escrever na memoria com valor: " << pos << std::endl;
	}
	else {
		std::cerr << "Ocorreu algo inesperado, tente novamente." << std::endl;
	}
}

void Trainer::SetY(double pos)
{
	int stat = WriteProcessMemory(Trainer::memory.hProc, (LPVOID)Trainer::TRAINER_Y, &pos, (DWORD)sizeof(pos), NULL);

	if (stat > 0){
		std::clog << "Sucesso ao escrever na memoria com valor: " << pos << std::endl;
	}
	else {
		std::cerr << "Ocorreu algo inesperado, tente novamente." << std::endl;
	}
}

void Trainer::SetZ(double pos)
{
	int stat = WriteProcessMemory(Trainer::memory.hProc, (LPVOID)Trainer::TRAINER_Z, &pos, (DWORD)sizeof(pos), NULL);

	if (stat > 0){
		std::clog << "Sucesso ao escrever na memoria com valor: " << pos << std::endl;
	}
	else {
		std::cerr << "Ocorreu algo inesperado, tente novamente." << std::endl;
	}
}

void Trainer::SetPos(double x,double y, double z)
{
	Trainer::SetX(x); Trainer::SetY(y); Trainer::SetZ(z);
}*/
<|endoftext|>


<commit_before>#include "typeinfo.h"
#include <string.h>
#include <stdlib.h>
#include <stdio.h>

using std::type_info;

type_info::~type_info() {}

bool type_info::operator==(const type_info &other) const
{
	return __type_name == other.__type_name;
}
bool type_info::operator!=(const type_info &other) const
{
	return __type_name != other.__type_name;
}
bool type_info::before(const type_info &other) const
{
	return __type_name < other.__type_name;
}
const char* type_info::name() const
{
	return __type_name;
}
type_info::type_info (const type_info& rhs)
{
	__type_name = rhs.__type_name;
}
type_info& type_info::operator= (const type_info& rhs)
{
	return *new type_info(rhs);
}

ABI_NAMESPACE::__fundamental_type_info::~__fundamental_type_info() {}
ABI_NAMESPACE::__array_type_info::~__array_type_info() {}
ABI_NAMESPACE::__function_type_info::~__function_type_info() {}
ABI_NAMESPACE::__enum_type_info::~__enum_type_info() {}
ABI_NAMESPACE::__class_type_info::~__class_type_info() {}
ABI_NAMESPACE::__si_class_type_info::~__si_class_type_info() {}
ABI_NAMESPACE::__vmi_class_type_info::~__vmi_class_type_info() {}
ABI_NAMESPACE::__pbase_type_info::~__pbase_type_info() {}
ABI_NAMESPACE::__pointer_type_info::~__pointer_type_info() {}
ABI_NAMESPACE::__pointer_to_member_type_info::~__pointer_to_member_type_info() {}

// From libelftc
extern "C" char    *__cxa_demangle_gnu3(const char *);

extern "C" char* __cxa_demangle(const char* mangled_name,
                                char* buf,
                                size_t* n,
                                int* status)
{
	// TODO: We should probably just be linking against libelf-tc, rather than
	// copying their code.  This requires them to do an actual release,
	// however, and for our changes to be pushed upstream.  We also need to
	// call a different demangling function here depending on the ABI (e.g.
	// ARM).
	char *demangled = __cxa_demangle_gnu3(mangled_name);
	if (NULL != demangled)
	{
		size_t len = strlen(demangled);
		buf = (char*)realloc(buf, len+1);
		if (0 != buf)
		{
			memcpy(buf, demangled, len);
			buf[len] = 0;
			*n = len;
			*status = 0;
		}
		else
		{
			*status = -1;
		}
		free(demangled);
	}
	else
	{
		*status = -2;
		return NULL;
	}
	return buf;
}
<commit_msg>am 414b9890: Check for null pointer arguments in demangler.<commit_after>#include "typeinfo.h"
#include <string.h>
#include <stdlib.h>
#include <stdio.h>

using std::type_info;

type_info::~type_info() {}

bool type_info::operator==(const type_info &other) const
{
	return __type_name == other.__type_name;
}
bool type_info::operator!=(const type_info &other) const
{
	return __type_name != other.__type_name;
}
bool type_info::before(const type_info &other) const
{
	return __type_name < other.__type_name;
}
const char* type_info::name() const
{
	return __type_name;
}
type_info::type_info (const type_info& rhs)
{
	__type_name = rhs.__type_name;
}
type_info& type_info::operator= (const type_info& rhs)
{
	return *new type_info(rhs);
}

ABI_NAMESPACE::__fundamental_type_info::~__fundamental_type_info() {}
ABI_NAMESPACE::__array_type_info::~__array_type_info() {}
ABI_NAMESPACE::__function_type_info::~__function_type_info() {}
ABI_NAMESPACE::__enum_type_info::~__enum_type_info() {}
ABI_NAMESPACE::__class_type_info::~__class_type_info() {}
ABI_NAMESPACE::__si_class_type_info::~__si_class_type_info() {}
ABI_NAMESPACE::__vmi_class_type_info::~__vmi_class_type_info() {}
ABI_NAMESPACE::__pbase_type_info::~__pbase_type_info() {}
ABI_NAMESPACE::__pointer_type_info::~__pointer_type_info() {}
ABI_NAMESPACE::__pointer_to_member_type_info::~__pointer_to_member_type_info() {}

// From libelftc
extern "C" char    *__cxa_demangle_gnu3(const char *);

extern "C" char* __cxa_demangle(const char* mangled_name,
                                char* buf,
                                size_t* n,
                                int* status)
{
	// TODO: We should probably just be linking against libelf-tc, rather than
	// copying their code.  This requires them to do an actual release,
	// however, and for our changes to be pushed upstream.  We also need to
	// call a different demangling function here depending on the ABI (e.g.
	// ARM).
	char *demangled = __cxa_demangle_gnu3(mangled_name);
	if (NULL != demangled)
	{
		size_t len = strlen(demangled);
		buf = (char*)realloc(buf, len+1);
		if (0 != buf)
		{
			memcpy(buf, demangled, len);
			buf[len] = 0;
			if (n)
			{
				*n = len;
			}
			if (status)
			{
				*status = 0;
			}
		}
		else
		{
			if (status)
			{
				*status = -1;
			}
		}
		free(demangled);
	}
	else
	{
		if (status)
		{
			*status = -2;
		}
		return NULL;
	}
	return buf;
}
<|endoftext|>


<commit_before>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2006 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

//$Id$

#include <mapnik/unicode.hpp>

#ifdef USE_FRIBIDI
#include <fribidi/fribidi.h>
#endif

#include <string>

#ifdef MAPNIK_DEBUG
#include <iostream>
#endif

namespace mapnik {

/*
** Use FRIBIDI to encode the string.
** The return value must be freed by the caller.
*/

#ifdef USE_FRIBIDI
    inline wchar_t* bidi_string(const wchar_t *logical)
    {
        FriBidiCharType base = FRIBIDI_TYPE_ON;
        size_t len;

        len = wcslen(logical);

        FriBidiChar *visual;

        FriBidiStrIndex *ltov, *vtol;
        FriBidiLevel *levels;
        FriBidiStrIndex new_len;
        fribidi_boolean log2vis;

        visual = (FriBidiChar *) calloc (sizeof (FriBidiChar), len + 1);
        ltov = 0;
        vtol = 0;
        levels = 0;

        /* Create a bidi string. */
        log2vis = fribidi_log2vis ((FriBidiChar *)logical, len, &base,
                /* output */
                visual, ltov, vtol, levels);

        if (!log2vis) {
            return 0;
        }

        new_len = len;

        return (wchar_t *)visual;
    }
#endif

/*
    inline std::wstring to_unicode(std::string const& text)
    {
        std::wstring out;
        unsigned long code = 0;
        int expect = 0;
        std::string::const_iterator itr=text.begin();
        std::string::const_iterator end=text.end();
        while ( itr != end)
        {
            unsigned p = (*itr++) & 0xff;
            if ( p >= 0xc0)
            {
                if ( p < 0xe0)      // U+0080 - U+07ff
                {
                    expect = 1;
                    code = p & 0x1f;
                }
                else if ( p < 0xf0)  // U+0800 - U+ffff
                {
                    expect = 2;
                    code = p & 0x0f;
                }
                else if ( p  < 0xf8) // U+1000 - U+10ffff
                {
                    expect = 3;
                    code = p & 0x07;
                }
                continue;
            }
            else if (p >= 0x80)
            {
                --expect;
                if (expect >= 0)
                {
                    code <<= 6;
                    code += p & 0x3f;
                }
                if (expect > 0)
                    continue;
                expect = 0;
            }
            else
            {
                code = p;            // U+0000 - U+007f (ascii)
            }
            out.push_back(wchar_t(code));
        }
#ifdef USE_FRIBIDI
        wchar_t *bidi_text = bidi_string(out.c_str());
        out = bidi_text;
        free(bidi_text);
#endif

        return out;
    }

   inline std::wstring latin1_to_unicode(std::string const& text)
   {
      std::wstring out;
      std::string::const_iterator itr=text.begin();
      std::string::const_iterator end=text.end();
      while ( itr != end)
      {
         unsigned p = (*itr++) & 0xff;
         out.push_back(wchar_t(p));
      }
      return out;
   }

   inline std::string latin1_to_unicode2(std::string const& text)
   {
      std::string out;
      std::string::const_iterator itr=text.begin();
      std::string::const_iterator end=text.end();
      while ( itr != end)
      {
         out.push_back(0x00);
         out.push_back(*itr++);
      }
      return out;
   }

*/
   transcoder::transcoder (std::string const& encoding)
      : ok_(false),
        conv_(0)
   {
#ifdef MAPNIK_DEBUG
      std::cerr << "ENCODING = " << encoding << "\n";
#endif

//#ifndef WORDS_BIGENDIAN
         //     desc_ = iconv_open("UCS-4LE",encoding.c_str());
//#else
         //     desc_ = iconv_open("UCS-4BE",encoding.c_str());
//#endif

      UErrorCode err = U_ZERO_ERROR;
      conv_ = ucnv_open(encoding.c_str(),&err);
      if (U_SUCCESS(err)) ok_ = true;
      // TODO
   }

   UnicodeString transcoder::transcode(const char* data) const
   {

      UErrorCode err = U_ZERO_ERROR;

      UnicodeString ustr(data,-1,conv_,err);
      if (ustr.isBogus())
      {
         ustr.remove();
      }
      return ustr;
/*
      if (desc_ == iconv_t(-1)) return to_unicode(input);
      size_t inleft = input.size();
      std::wstring output(inleft,0);
      size_t outleft = inleft * sizeof(wchar_t);
#if (!defined(OSX_LEOPARD) && defined(DARWIN)) || defined(SUNOS) || defined(FREEBSD)
      const char * in = input.c_str();
#else
      char * in = const_cast<char*>(input.data());
#endif
      char * out = const_cast<char*>(reinterpret_cast<const char*>(output.data()));
      iconv(desc_,&in,&inleft,&out,&outleft);
      output = output.substr(0,output.size()-(outleft/sizeof(wchar_t)));
#ifdef USE_FRIBIDI
      if (output.length() > 0)
      {
         wchar_t *bidi_text = bidi_string(output.c_str());
         output = bidi_text;
         free(bidi_text);
      }
#endif
      return output;
*/
   }

   transcoder::~transcoder()
   {
      // if (desc_ != iconv_t(-1)) iconv_close(desc_);
      if (conv_)
         ucnv_close(conv_);
   }
}
<commit_msg>Add missing #include to fix GNU/kFreeBSD build<commit_after>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2006 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

//$Id$

#include <cstdlib>
#include <mapnik/unicode.hpp>

#ifdef USE_FRIBIDI
#include <fribidi/fribidi.h>
#endif

#include <string>

#ifdef MAPNIK_DEBUG
#include <iostream>
#endif

namespace mapnik {

/*
** Use FRIBIDI to encode the string.
** The return value must be freed by the caller.
*/

#ifdef USE_FRIBIDI
    inline wchar_t* bidi_string(const wchar_t *logical)
    {
        FriBidiCharType base = FRIBIDI_TYPE_ON;
        size_t len;

        len = wcslen(logical);

        FriBidiChar *visual;

        FriBidiStrIndex *ltov, *vtol;
        FriBidiLevel *levels;
        FriBidiStrIndex new_len;
        fribidi_boolean log2vis;

        visual = (FriBidiChar *) calloc (sizeof (FriBidiChar), len + 1);
        ltov = 0;
        vtol = 0;
        levels = 0;

        /* Create a bidi string. */
        log2vis = fribidi_log2vis ((FriBidiChar *)logical, len, &base,
                /* output */
                visual, ltov, vtol, levels);

        if (!log2vis) {
            return 0;
        }

        new_len = len;

        return (wchar_t *)visual;
    }
#endif

/*
    inline std::wstring to_unicode(std::string const& text)
    {
        std::wstring out;
        unsigned long code = 0;
        int expect = 0;
        std::string::const_iterator itr=text.begin();
        std::string::const_iterator end=text.end();
        while ( itr != end)
        {
            unsigned p = (*itr++) & 0xff;
            if ( p >= 0xc0)
            {
                if ( p < 0xe0)      // U+0080 - U+07ff
                {
                    expect = 1;
                    code = p & 0x1f;
                }
                else if ( p < 0xf0)  // U+0800 - U+ffff
                {
                    expect = 2;
                    code = p & 0x0f;
                }
                else if ( p  < 0xf8) // U+1000 - U+10ffff
                {
                    expect = 3;
                    code = p & 0x07;
                }
                continue;
            }
            else if (p >= 0x80)
            {
                --expect;
                if (expect >= 0)
                {
                    code <<= 6;
                    code += p & 0x3f;
                }
                if (expect > 0)
                    continue;
                expect = 0;
            }
            else
            {
                code = p;            // U+0000 - U+007f (ascii)
            }
            out.push_back(wchar_t(code));
        }
#ifdef USE_FRIBIDI
        wchar_t *bidi_text = bidi_string(out.c_str());
        out = bidi_text;
        free(bidi_text);
#endif

        return out;
    }

   inline std::wstring latin1_to_unicode(std::string const& text)
   {
      std::wstring out;
      std::string::const_iterator itr=text.begin();
      std::string::const_iterator end=text.end();
      while ( itr != end)
      {
         unsigned p = (*itr++) & 0xff;
         out.push_back(wchar_t(p));
      }
      return out;
   }

   inline std::string latin1_to_unicode2(std::string const& text)
   {
      std::string out;
      std::string::const_iterator itr=text.begin();
      std::string::const_iterator end=text.end();
      while ( itr != end)
      {
         out.push_back(0x00);
         out.push_back(*itr++);
      }
      return out;
   }

*/
   transcoder::transcoder (std::string const& encoding)
      : ok_(false),
        conv_(0)
   {
#ifdef MAPNIK_DEBUG
      std::cerr << "ENCODING = " << encoding << "\n";
#endif

//#ifndef WORDS_BIGENDIAN
         //     desc_ = iconv_open("UCS-4LE",encoding.c_str());
//#else
         //     desc_ = iconv_open("UCS-4BE",encoding.c_str());
//#endif

      UErrorCode err = U_ZERO_ERROR;
      conv_ = ucnv_open(encoding.c_str(),&err);
      if (U_SUCCESS(err)) ok_ = true;
      // TODO
   }

   UnicodeString transcoder::transcode(const char* data) const
   {

      UErrorCode err = U_ZERO_ERROR;

      UnicodeString ustr(data,-1,conv_,err);
      if (ustr.isBogus())
      {
         ustr.remove();
      }
      return ustr;
/*
      if (desc_ == iconv_t(-1)) return to_unicode(input);
      size_t inleft = input.size();
      std::wstring output(inleft,0);
      size_t outleft = inleft * sizeof(wchar_t);
#if (!defined(OSX_LEOPARD) && defined(DARWIN)) || defined(SUNOS) || defined(FREEBSD)
      const char * in = input.c_str();
#else
      char * in = const_cast<char*>(input.data());
#endif
      char * out = const_cast<char*>(reinterpret_cast<const char*>(output.data()));
      iconv(desc_,&in,&inleft,&out,&outleft);
      output = output.substr(0,output.size()-(outleft/sizeof(wchar_t)));
#ifdef USE_FRIBIDI
      if (output.length() > 0)
      {
         wchar_t *bidi_text = bidi_string(output.c_str());
         output = bidi_text;
         free(bidi_text);
      }
#endif
      return output;
*/
   }

   transcoder::~transcoder()
   {
      // if (desc_ != iconv_t(-1)) iconv_close(desc_);
      if (conv_)
         ucnv_close(conv_);
   }
}
<|endoftext|>


<commit_before>#include <stdio.h>
#include <queue>
#include <vector>
#include <utility>
#include <iostream>
#include <string>
#include <stack>

using namespace std;

stack<string> lv1;
stack<string> lv2;
stack<string> lv3;

string temp;
int templv;
int temptime=0;
int usernum;
int users=0;
int read(int now){
	if(now < temptime) return 0;

	do{
		printf("test\n");
		if(temp.empty()){

		}else{

			switch(templv){
				case 1:
					lv1.push(temp);break;
				case 2:
					lv2.push(temp);break;
				case 3:
					lv3.push(temp);break;
			}
		}
		if(users<usernum){
			cin >>temptime>>templv>>temp;
			users++;}
		else
			return 0;
	}while(temptime<=now);

}
int main(int argc, char const *argv[])
{
		int time;
		scanf("%d%d",&usernum,&time);
		for (int i = 0; i < time; ++i)
		{
			read(i);
			cout<<i<<"\n"<<lv1.size()<<lv2.size()<<lv3.size()<<endl;

		}

	return 0;
}<commit_msg>update uoj2254<commit_after>#include <stdio.h>
#include <queue>
#include <vector>
#include <utility>
#include <iostream>
#include <string>
#include <stack>

using namespace std;

stack<string> lv1;
stack<string> lv2;
stack<string> lv3;

string temp;
int templv;
int temptime=0;
int usernum;
int users=0;
int read(int now){
	if(now < temptime) return 0;

	do{
		printf("test\n");
		if(temp.empty()){

		}else{

			switch(templv){
				case 1:
					lv1.push(temp);break;
				case 2:
					lv2.push(temp);break;
				case 3:
					lv3.push(temp);break;
			}
		}
		users++;
		if(users<=usernum){
			cin >>temptime>>templv>>temp;
		}
		else
			return 0;
	}while(temptime<=now);

}
int main(int argc, char const *argv[])
{
		int time;
		scanf("%d%d",&usernum,&time);
		for (int i = 0; i < time; ++i)
		{
			read(i);
			cout<<i<<"\n"<<lv1.size()<<lv2.size()<<lv3.size()<<endl;

		}

	return 0;
}<|endoftext|>


<commit_before>#include <stdio.h>

#include <iostream>
#include <vector>
#define OK 1
#define ERROR 0
#define LIST_INIT_SIZE 100
#define LISTINCREMENT 10
#define ElemType int

using namespace std;
int main()
{
	std::vector<ElemType> v;
	int a, i;
	ElemType e, x;
	if(v.empty())    // 判断顺序表是否创建成功
	{
		printf("A Sequence List Has Created.\n");
	}
	while(1)
	{
		printf("1:Insert element\n2:Delete element\n3:Load all elements\n0:Exit\nPlease choose:\n");
		scanf("%d",&a);
		switch(a)
		{
			case 1: scanf("%d%d",&i,&x);

					 v.insert(v.begin()+i,x);
					if(0) printf("Insert Error!\n"); // 判断i值是否合法，请填空
					else printf("The Element %d is Successfully Inserted!\n", x);
					break;
			case 2: scanf("%d",&i);
			v.erase(v.begin()+i);

					if(0) printf("Delete Error!\n"); // 判断i值是否合法，请填空
					else printf("The Element %d is Successfully Deleted!\n", e);
					break;
			case 3:
			vector<ElemType>::iterator tempIterator;
			for( tempIterator = v.begin(); tempIterator != v.end(); tempIterator++ )
    				std::cout << *tempIterator;
    		cout << endl;
					break;
			case 0: return 1;
		}
	}
}<commit_msg>update uoj8576<commit_after>#include <stdio.h>
#include <iterator>
#include <iostream>
#include <vector>
#define OK 1
#define ERROR 0
#define LIST_INIT_SIZE 100
#define LISTINCREMENT 10
#define ElemType int

using namespace std;
int main()
{
	std::vector<ElemType> v;
	int a, i;
	ElemType e, x;
	if(v.empty())    // 判断顺序表是否创建成功
	{
		printf("A Sequence List Has Created.\n");
	}
	while(1)
	{
		printf("1:Insert element\n2:Delete element\n3:Load all elements\n0:Exit\nPlease choose:\n");
		scanf("%d",&a);
		switch(a)
		{
			case 1: scanf("%d%d",&i,&x);

					 v.insert(v.begin()+i,x);
					if(0) printf("Insert Error!\n"); // 判断i值是否合法，请填空
					else printf("The Element %d is Successfully Inserted!\n", x);
					break;
			case 2: scanf("%d",&i);
			v.erase(v.begin()+i);

					if(0) printf("Delete Error!\n"); // 判断i值是否合法，请填空
					else printf("The Element %d is Successfully Deleted!\n", e);
					break;
			case 3:
			vector<ElemType>::iterator tempIterator;
			for( tempIterator = v.begin(); tempIterator != v.end(); tempIterator++ )
    				std::cout << *tempIterator;
    		cout << endl;
					break;
			case 0: return 1;
		}
	}
}<|endoftext|>


<commit_before>/**
* Copyright 2016 BitTorrent Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*    http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <scraps/utility.h>

#include <scraps/format.h>

#include <cctype>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>

#if !SCRAPS_WINDOWS
#include <termios.h>
#include <unistd.h>
#endif

#if __clang__ || __GNUC__
#include <cxxabi.h>
#endif

#include <fcntl.h>

#if SCRAPS_MACOS
// for sysctlbyname
#include <sys/sysctl.h>
#endif

namespace scraps {

std::string JSONEscape(const char* str) {
    std::string ret;
    while (*str) {
        if (*str < 0x20) {
            ret += "\\u";
            ret += Formatf("%04X", (unsigned int)*(uint8_t*)str);
        } else if (*str == '"' || *str == '\\') {
            ret += '\\';
            ret += *str;
        } else {
            ret += *str;
        }
        ++str;
    }
    return ret;
}

std::string URLEncode(const char* str) {
    std::ostringstream ret;

    while (char c = *str) {
        if (isalnum(c) || c == '-' || c == '_' || c == '.') {
            ret << c;
        } else if (c == ' ') {
            ret << '+';
        } else {
            ret << '%' << std::setw(2) << std::setfill('0') << std::hex << std::uppercase << (int)static_cast<unsigned char>(c);
        }
        ++str;
    }

    return ret.str();
}

std::string URLDecode(const char* str) {
    std::ostringstream ret;

    while (char c = *str) {
        if (c == '+') {
            ret << ' ';
        } else if (c == '%' && str[1] && str[2]) {
            char tmp[3];
            tmp[0] = *++str;
            tmp[1] = *++str;
            tmp[2] = '\0';
            ret << (unsigned char)strtoul(tmp, nullptr, 16);
        } else {
            ret << c;
        }
        ++str;
    }

    return ret.str();
}

std::tuple<std::string, uint16_t> ParseAddressAndPort(const std::string& host,
                                                      uint16_t defaultPort) {
    auto sep = host.find(':');
    if (sep == host.npos) {
        return std::make_tuple(host, defaultPort);
    }

    const auto address = host.substr(0, sep);
    const auto port = static_cast<uint16_t>(std::atoi(host.substr(sep + 1).c_str()));
    return std::make_tuple(address, port);
}

size_t PhysicalMemory() {
#if SCRAPS_MACOS
    uint64_t mem = 0;
    size_t len = sizeof(mem);
    return sysctlbyname("hw.memsize", &mem, &len, NULL, 0) == 0 ? mem : 0;
#else
    auto pages = sysconf(_SC_PHYS_PAGES);
    auto pageSize = sysconf(_SC_PAGE_SIZE);
    return (pages > 0 && pageSize > 0) ? pages * pageSize : 0;
#endif
}

stdts::optional<std::vector<Byte>> BytesFromFile(const std::string& path) {
    std::ifstream dataFile{path, std::ifstream::ate | std::ios::binary};
    const auto fileSize = dataFile.tellg();

    if (dataFile.bad() || fileSize <= 0) {
        return {};
    }

    std::vector<Byte> buf;
    buf.resize(fileSize);
    dataFile.seekg(0, std::ios::beg);
    dataFile.read(reinterpret_cast<char*>(buf.data()), fileSize);

    if (dataFile.bad()) {
        return {};
    }

    return buf;
}

bool SetBlocking(int fd, bool blocking) {
#ifdef _WIN32
    unsigned long arg = blocking ? 1 : 0;
    return !ioctlsocket(fd, FIONBIO, &arg);
#else
    int flags = fcntl(fd, F_GETFL, 0);
    if (flags < 0) {
        return false;
    }
    return !fcntl(fd, F_SETFL, blocking ? flags & ~O_NONBLOCK : flags | O_NONBLOCK);
#endif
}

std::string Demangle(const char* mangled) {
#if __clang__ || __GNUC__
    struct FreeDeleter { void operator()(char* p) const { std::free(p); } };
    int status = 0;
    auto demangled = std::unique_ptr<char, FreeDeleter>{abi::__cxa_demangle(mangled, nullptr, nullptr, &status)};
    if (status == 0) {
        return demangled.get();
    }
#endif
    return mangled;
}

} // namespace scraps
<commit_msg>Fix debug android symbols<commit_after>/**
* Copyright 2016 BitTorrent Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*    http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <scraps/utility.h>

#include <scraps/format.h>

#include <cctype>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>

#if !SCRAPS_WINDOWS
#include <termios.h>
#include <unistd.h>
#endif

#if __clang__ || __GNUC__
#include <cxxabi.h>
#endif

#include <fcntl.h>

#if SCRAPS_MACOS
// for sysctlbyname
#include <sys/sysctl.h>
#endif

namespace scraps {

std::string JSONEscape(const char* str) {
    std::string ret;
    while (*str) {
        if (*str < 0x20) {
            ret += "\\u";
            ret += Formatf("%04X", (unsigned int)*(uint8_t*)str);
        } else if (*str == '"' || *str == '\\') {
            ret += '\\';
            ret += *str;
        } else {
            ret += *str;
        }
        ++str;
    }
    return ret;
}

std::string URLEncode(const char* str) {
    std::ostringstream ret;

    while (char c = *str) {
        if (isalnum(c) || c == '-' || c == '_' || c == '.') {
            ret << c;
        } else if (c == ' ') {
            ret << '+';
        } else {
            ret << '%' << std::setw(2) << std::setfill('0') << std::hex << std::uppercase << (int)static_cast<unsigned char>(c);
        }
        ++str;
    }

    return ret.str();
}

std::string URLDecode(const char* str) {
    std::ostringstream ret;

    while (char c = *str) {
        if (c == '+') {
            ret << ' ';
        } else if (c == '%' && str[1] && str[2]) {
            char tmp[3];
            tmp[0] = *++str;
            tmp[1] = *++str;
            tmp[2] = '\0';
            ret << (unsigned char)strtoul(tmp, nullptr, 16);
        } else {
            ret << c;
        }
        ++str;
    }

    return ret.str();
}

std::tuple<std::string, uint16_t> ParseAddressAndPort(const std::string& host,
                                                      uint16_t defaultPort) {
    auto sep = host.find(':');
    if (sep == host.npos) {
        return std::make_tuple(host, defaultPort);
    }

    const auto address = host.substr(0, sep);
    const auto port = static_cast<uint16_t>(std::atoi(host.substr(sep + 1).c_str()));
    return std::make_tuple(address, port);
}

size_t PhysicalMemory() {
#if SCRAPS_MACOS
    uint64_t mem = 0;
    size_t len = sizeof(mem);
    return sysctlbyname("hw.memsize", &mem, &len, NULL, 0) == 0 ? mem : 0;
#else
    auto pages = sysconf(_SC_PHYS_PAGES);
    auto pageSize = sysconf(_SC_PAGE_SIZE);
    return (pages > 0 && pageSize > 0) ? pages * pageSize : 0;
#endif
}

stdts::optional<std::vector<Byte>> BytesFromFile(const std::string& path) {
    std::ifstream dataFile{path, std::ifstream::ate | std::ios::binary};
    const auto fileSize = dataFile.tellg();

    if (dataFile.bad() || fileSize <= 0) {
        return {};
    }

    std::vector<Byte> buf;
    buf.resize(fileSize);
    dataFile.seekg(0, std::ios::beg);
    dataFile.read(reinterpret_cast<char*>(buf.data()), fileSize);

    if (dataFile.bad()) {
        return {};
    }

    return buf;
}

bool SetBlocking(int fd, bool blocking) {
#ifdef SCRAPS_WINDOWS
    unsigned long arg = blocking ? 1 : 0;
    return !ioctlsocket(fd, FIONBIO, &arg);
#else
    int flags = fcntl(fd, F_GETFL, 0);
    if (flags < 0) {
        return false;
    }
    return !fcntl(fd, F_SETFL, blocking ? flags & ~O_NONBLOCK : flags | O_NONBLOCK);
#endif
}

std::string Demangle(const char* mangled) {
#if !SCRAPS_ANDROID && (__clang__ || __GNUC__)
    struct FreeDeleter { void operator()(char* p) const { std::free(p); } };
    int status = 0;
    auto demangled = std::unique_ptr<char, FreeDeleter>{abi::__cxa_demangle(mangled, nullptr, nullptr, &status)};
    if (status == 0) {
        return demangled.get();
    }
#endif
    return mangled;
}

} // namespace scraps
<|endoftext|>


<commit_before>/*
 *   Copyright (c) 2014 Kulykov Oleh <nonamedemail@gmail.com>
 *
 *   Permission is hereby granted, free of charge, to any person obtaining a copy
 *   of this software and associated documentation files (the "Software"), to deal
 *   in the Software without restriction, including without limitation the rights
 *   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 *   copies of the Software, and to permit persons to whom the Software is
 *   furnished to do so, subject to the following conditions:
 *
 *   The above copyright notice and this permission notice shall be included in
 *   all copies or substantial portions of the Software.
 *
 *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 *   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 *   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 *   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 *   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 *   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 *   THE SOFTWARE.
 */

#include "../fayecpp.h"

#if defined(HAVE_FAYECPP_CONFIG_H)
#include "fayecpp_config.h"
#endif

namespace FayeCpp {

	void Variant::clean()
	{
		if (_u.pointerValue)
		{
			switch (_t)
			{
				case TypeString: delete (REString *)_u.pointerValue; break;
				case TypeMap: delete (VariantMap *)_u.pointerValue; break;
				case TypeList: delete (VariantList *)_u.pointerValue; break;
				default: break;
			}
		}
		memset(&_u, 0, sizeof(VariantUnion));
		_t = TypeNone;
	}

	bool Variant::isNULL() const
	{
		return _u.pointerValue ? false : true;
	}

	bool Variant::isNumber() const
	{
		return (_t == VariantType::TypeInteger) || (_t == VariantType::TypeReal);
	}

	Variant::VariantType Variant::type() const
	{
		return _t;
	}

	int Variant::toInt() const
	{
		return (int)this->toInt64();
	}

	int64_t Variant::toInt64() const
	{
		switch (_t)
		{
			case TypeInteger: return _u.int64Value; break;
			case TypeUnsignedInteger: return (int64_t)_u.uint64Value; break;
			case TypeReal: return (int64_t)_u.doubleValue; break;
			case TypeBool: return _u.boolValue ? (int64_t)1 : (int64_t)0; break;
			case TypeString:
			{
				if (this->toString().isDigit())
				{
					REBOOL isOk = false;
					const REInt64 parsedValue = this->toString().integerValue(&isOk);
					if (isOk) return (int64_t)parsedValue;
				}
			}
				break;
			default: break;
		}
		return 0;
	}

	uint64_t Variant::toUInt64() const
	{
		switch (_t)
		{
			case TypeInteger: return (uint64_t)_u.int64Value; break;
			case TypeUnsignedInteger: return _u.uint64Value; break;
			case TypeReal: return (uint64_t)_u.doubleValue; break;
			case TypeBool: return _u.boolValue ? (uint64_t)1 : (uint64_t)0; break;
			case TypeString:
			{
				if (this->toString().isDigit())
				{
					REBOOL isOk = false;
					const REInt64 parsedValue = this->toString().integerValue(&isOk);
					if (isOk) return (uint64_t)parsedValue;
				}
			}
				break;
			default: break;
		}
		return 0;
	}

	double Variant::toDouble() const
	{
		switch (_t)
		{
			case TypeInteger: return (double)_u.int64Value; break;
			case TypeUnsignedInteger: return (double)_u.uint64Value; break;
			case TypeReal: return (double)_u.doubleValue; break;
			case TypeBool: return _u.boolValue ? (double)1 : (double)0; break;
			case TypeString:
			{
				if (this->toString().isDigit())
				{
					REBOOL isOk = false;
					const REFloat64 parsedValue = this->toString().floatValue(&isOk);
					if (isOk) return (double)parsedValue;
				}
			}
				break;
			default: break;
		}
		return 0;
	}

	bool Variant::toBool() const
	{
		switch (_t)
		{
			case TypeInteger: return _u.int64Value == 0 ? false : true; break;
			case TypeUnsignedInteger: return _u.uint64Value == 0 ? false: true; break;
			case TypeReal: return _u.doubleValue == 0 ? false : true; break;
			case TypeBool: return _u.boolValue; break;
			case TypeString:
			{
				REMutableString s = this->toString().mutableString();
				s.toLower();
				if (s.isEqual("true")) return true;
			}
				break;
			default: break;
		}
		return false;
	}

	Variant & Variant::operator=(int v)
	{
		_u.int64Value = v;
		_t = TypeInteger;
		return *this;
	}
	Variant & Variant::operator=(float v)
	{
		_u.doubleValue = v;
		_t = TypeReal;
		return *this;
	}
	Variant & Variant::operator=(double v)
	{
		_u.doubleValue = v;
		_t = TypeReal;
		return *this;
	}

	Variant & Variant::operator=(long long v)
	{
		_u.int64Value = v;
		_t = TypeInteger;
		return *this;
	}
	Variant & Variant::operator=(unsigned long long v)
	{
		_u.uint64Value = v;
		_t = TypeUnsignedInteger;
		return *this;
	}
	Variant & Variant::operator=(long double v)
	{
		_u.doubleValue = v;
		_t = TypeReal;
		return *this;
	}
	Variant & Variant::operator=(bool v)
	{
		_u.boolValue = v;
		_t = TypeBool;
		return *this;
	}
	Variant & Variant::operator=(const REString & s)
	{
		this->clean();
		REString * p = new REString(s);
		if (p)
		{
			_u.pointerValue = p;
			_t = TypeString;
		}
		return *this;
	}
	Variant & Variant::operator=(const char * s)
	{
		this->clean();
		if (s)
		{
			REString * p = new REString(s);
			if (p)
			{
				_u.pointerValue = p;
				_t = TypeString;
			}
		}
		return *this;
	}

	Variant & Variant::operator=(const wchar_t * s)
	{
		this->clean();
		if (s)
		{
			REString * p = new REString(s);
			if (p)
			{
				_u.pointerValue = p;
				_t = TypeString;
			}
		}
		return *this;
	}

	Variant & Variant::operator=(const VariantMap & m)
	{
		this->clean();
		VariantMap * p = new VariantMap(m);
		if (p)
		{
			_u.pointerValue = p;
			_t = TypeMap;
		}
		return *this;
	}
	Variant & Variant::operator=(const VariantList & l)
	{
		this->clean();
		VariantList * p = new VariantList(l);
		if (p)
		{
			_u.pointerValue = p;
			_t = TypeList;
		}
		return *this;
	}

	Variant & Variant::operator=(const Variant & v)
	{
		switch (v._t)
		{
			case TypeString: *this = v.toString(); break;
			case TypeMap: *this = v.toMap(); break;
			case TypeList: *this = v.toList(); break;
			default: _t = v._t; _u = v._u; break;
		}
		return *this;
	}

	bool Variant::isString() const
	{
		return _t == VariantType::TypeString;
	}

	const REString & Variant::toString() const
	{
		return *(const REString *)_u.pointerValue;
	}

	bool Variant::isMap() const
	{
		return _t == VariantType::TypeMap;
	}

	const VariantMap & Variant::toMap() const
	{
		return *(const VariantMap *)_u.pointerValue;
	}

	bool Variant::isList() const
	{
		return _t == VariantType::TypeList;
	}

	const VariantList & Variant::toList() const
	{
		return *((VariantList *)_u.pointerValue);
	}

	REString & Variant::toString()
	{
		return *(REString *)_u.pointerValue;
	}

	VariantMap & Variant::toMap()
	{
		return *(VariantMap *)_u.pointerValue;
	}

	VariantList & Variant::toList()
	{
		return *((VariantList *)_u.pointerValue);
	}

	Variant::Variant() :
		_t(TypeNone)
	{
		memset(&_u, 0, sizeof(VariantUnion));
	}

	Variant::Variant(int v) :
		_t(TypeNone)
	{
		memset(&_u, 0, sizeof(VariantUnion));
		*this = v;
	}

	Variant::Variant(float v) :
		_t(TypeNone)
	{
		memset(&_u, 0, sizeof(VariantUnion));
		*this = v;
	}

	Variant::Variant(double v) :
		_t(TypeNone)
	{
		memset(&_u, 0, sizeof(VariantUnion));
		*this = v;
	}

	Variant::Variant(long long v) :
		_t(TypeNone)
	{
		memset(&_u, 0, sizeof(VariantUnion));
		*this = v;
	}

	Variant::Variant(unsigned long long v) :
		_t(TypeNone)
	{
		memset(&_u, 0, sizeof(VariantUnion));
		*this = v;
	}

	Variant::Variant(long double v) :
		_t(TypeNone)
	{
		memset(&_u, 0, sizeof(VariantUnion));
		*this = v;
	}

	Variant::Variant(bool v) :
		_t(TypeNone)
	{
		memset(&_u, 0, sizeof(VariantUnion));
		*this = v;
	}

	Variant::Variant(const char * v) :
		_t(TypeNone)
	{
		memset(&_u, 0, sizeof(VariantUnion));
		*this = v;
	}

	Variant::Variant(const wchar_t * v) :
		_t(TypeNone)
	{
		memset(&_u, 0, sizeof(VariantUnion));
		*this = v;
	}

	Variant::Variant(const REString & v) :
		_t(TypeNone)
	{
		memset(&_u, 0, sizeof(VariantUnion));
		*this = v;
	}

	Variant::Variant(const VariantMap & v) :
		_t(TypeNone)
	{
		memset(&_u, 0, sizeof(VariantUnion));
		*this = v;
	}

	Variant::Variant(const VariantList & v) :
		_t(TypeNone)
	{
		memset(&_u, 0, sizeof(VariantUnion));
		*this = v;
	}

	Variant::Variant(const Variant & v) :
		_t(TypeNone)
	{
		memset(&_u, 0, sizeof(VariantUnion));
		*this = v;
	}

	Variant::~Variant()
	{
		this->clean();
	}

}

<commit_msg>Varian build fix<commit_after>/*
 *   Copyright (c) 2014 Kulykov Oleh <nonamedemail@gmail.com>
 *
 *   Permission is hereby granted, free of charge, to any person obtaining a copy
 *   of this software and associated documentation files (the "Software"), to deal
 *   in the Software without restriction, including without limitation the rights
 *   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 *   copies of the Software, and to permit persons to whom the Software is
 *   furnished to do so, subject to the following conditions:
 *
 *   The above copyright notice and this permission notice shall be included in
 *   all copies or substantial portions of the Software.
 *
 *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 *   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 *   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 *   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 *   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 *   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 *   THE SOFTWARE.
 */

#include "../fayecpp.h"

#if defined(HAVE_FAYECPP_CONFIG_H)
#include "fayecpp_config.h"
#endif

namespace FayeCpp {

	void Variant::clean()
	{
		if (_u.pointerValue)
		{
			switch (_t)
			{
				case TypeString: delete (REString *)_u.pointerValue; break;
				case TypeMap: delete (VariantMap *)_u.pointerValue; break;
				case TypeList: delete (VariantList *)_u.pointerValue; break;
				default: break;
			}
		}
		memset(&_u, 0, sizeof(VariantUnion));
		_t = TypeNone;
	}

	bool Variant::isNULL() const
	{
		return _u.pointerValue ? false : true;
	}

	bool Variant::isNumber() const
	{
		return (_t == TypeInteger) || (_t == TypeReal);
	}

	Variant::VariantType Variant::type() const
	{
		return _t;
	}

	int Variant::toInt() const
	{
		return (int)this->toInt64();
	}

	int64_t Variant::toInt64() const
	{
		switch (_t)
		{
			case TypeInteger: return _u.int64Value; break;
			case TypeUnsignedInteger: return (int64_t)_u.uint64Value; break;
			case TypeReal: return (int64_t)_u.doubleValue; break;
			case TypeBool: return _u.boolValue ? (int64_t)1 : (int64_t)0; break;
			case TypeString:
			{
				if (this->toString().isDigit())
				{
					REBOOL isOk = false;
					const REInt64 parsedValue = this->toString().integerValue(&isOk);
					if (isOk) return (int64_t)parsedValue;
				}
			}
				break;
			default: break;
		}
		return 0;
	}

	uint64_t Variant::toUInt64() const
	{
		switch (_t)
		{
			case TypeInteger: return (uint64_t)_u.int64Value; break;
			case TypeUnsignedInteger: return _u.uint64Value; break;
			case TypeReal: return (uint64_t)_u.doubleValue; break;
			case TypeBool: return _u.boolValue ? (uint64_t)1 : (uint64_t)0; break;
			case TypeString:
			{
				if (this->toString().isDigit())
				{
					REBOOL isOk = false;
					const REInt64 parsedValue = this->toString().integerValue(&isOk);
					if (isOk) return (uint64_t)parsedValue;
				}
			}
				break;
			default: break;
		}
		return 0;
	}

	double Variant::toDouble() const
	{
		switch (_t)
		{
			case TypeInteger: return (double)_u.int64Value; break;
			case TypeUnsignedInteger: return (double)_u.uint64Value; break;
			case TypeReal: return (double)_u.doubleValue; break;
			case TypeBool: return _u.boolValue ? (double)1 : (double)0; break;
			case TypeString:
			{
				if (this->toString().isDigit())
				{
					REBOOL isOk = false;
					const REFloat64 parsedValue = this->toString().floatValue(&isOk);
					if (isOk) return (double)parsedValue;
				}
			}
				break;
			default: break;
		}
		return 0;
	}

	bool Variant::toBool() const
	{
		switch (_t)
		{
			case TypeInteger: return _u.int64Value == 0 ? false : true; break;
			case TypeUnsignedInteger: return _u.uint64Value == 0 ? false: true; break;
			case TypeReal: return _u.doubleValue == 0 ? false : true; break;
			case TypeBool: return _u.boolValue; break;
			case TypeString:
			{
				REMutableString s = this->toString().mutableString();
				s.toLower();
				if (s.isEqual("true")) return true;
			}
				break;
			default: break;
		}
		return false;
	}

	Variant & Variant::operator=(int v)
	{
		_u.int64Value = v;
		_t = TypeInteger;
		return *this;
	}
	Variant & Variant::operator=(float v)
	{
		_u.doubleValue = v;
		_t = TypeReal;
		return *this;
	}
	Variant & Variant::operator=(double v)
	{
		_u.doubleValue = v;
		_t = TypeReal;
		return *this;
	}

	Variant & Variant::operator=(long long v)
	{
		_u.int64Value = v;
		_t = TypeInteger;
		return *this;
	}
	Variant & Variant::operator=(unsigned long long v)
	{
		_u.uint64Value = v;
		_t = TypeUnsignedInteger;
		return *this;
	}
	Variant & Variant::operator=(long double v)
	{
		_u.doubleValue = v;
		_t = TypeReal;
		return *this;
	}
	Variant & Variant::operator=(bool v)
	{
		_u.boolValue = v;
		_t = TypeBool;
		return *this;
	}
	Variant & Variant::operator=(const REString & s)
	{
		this->clean();
		REString * p = new REString(s);
		if (p)
		{
			_u.pointerValue = p;
			_t = TypeString;
		}
		return *this;
	}
	Variant & Variant::operator=(const char * s)
	{
		this->clean();
		if (s)
		{
			REString * p = new REString(s);
			if (p)
			{
				_u.pointerValue = p;
				_t = TypeString;
			}
		}
		return *this;
	}

	Variant & Variant::operator=(const wchar_t * s)
	{
		this->clean();
		if (s)
		{
			REString * p = new REString(s);
			if (p)
			{
				_u.pointerValue = p;
				_t = TypeString;
			}
		}
		return *this;
	}

	Variant & Variant::operator=(const VariantMap & m)
	{
		this->clean();
		VariantMap * p = new VariantMap(m);
		if (p)
		{
			_u.pointerValue = p;
			_t = TypeMap;
		}
		return *this;
	}
	Variant & Variant::operator=(const VariantList & l)
	{
		this->clean();
		VariantList * p = new VariantList(l);
		if (p)
		{
			_u.pointerValue = p;
			_t = TypeList;
		}
		return *this;
	}

	Variant & Variant::operator=(const Variant & v)
	{
		switch (v._t)
		{
			case TypeString: *this = v.toString(); break;
			case TypeMap: *this = v.toMap(); break;
			case TypeList: *this = v.toList(); break;
			default: _t = v._t; _u = v._u; break;
		}
		return *this;
	}

	bool Variant::isString() const
	{
		return _t == TypeString;
	}

	const REString & Variant::toString() const
	{
		return *(const REString *)_u.pointerValue;
	}

	bool Variant::isMap() const
	{
		return _t == TypeMap;
	}

	const VariantMap & Variant::toMap() const
	{
		return *(const VariantMap *)_u.pointerValue;
	}

	bool Variant::isList() const
	{
		return _t == TypeList;
	}

	const VariantList & Variant::toList() const
	{
		return *((VariantList *)_u.pointerValue);
	}

	REString & Variant::toString()
	{
		return *(REString *)_u.pointerValue;
	}

	VariantMap & Variant::toMap()
	{
		return *(VariantMap *)_u.pointerValue;
	}

	VariantList & Variant::toList()
	{
		return *((VariantList *)_u.pointerValue);
	}

	Variant::Variant() :
		_t(TypeNone)
	{
		memset(&_u, 0, sizeof(VariantUnion));
	}

	Variant::Variant(int v) :
		_t(TypeNone)
	{
		memset(&_u, 0, sizeof(VariantUnion));
		*this = v;
	}

	Variant::Variant(float v) :
		_t(TypeNone)
	{
		memset(&_u, 0, sizeof(VariantUnion));
		*this = v;
	}

	Variant::Variant(double v) :
		_t(TypeNone)
	{
		memset(&_u, 0, sizeof(VariantUnion));
		*this = v;
	}

	Variant::Variant(long long v) :
		_t(TypeNone)
	{
		memset(&_u, 0, sizeof(VariantUnion));
		*this = v;
	}

	Variant::Variant(unsigned long long v) :
		_t(TypeNone)
	{
		memset(&_u, 0, sizeof(VariantUnion));
		*this = v;
	}

	Variant::Variant(long double v) :
		_t(TypeNone)
	{
		memset(&_u, 0, sizeof(VariantUnion));
		*this = v;
	}

	Variant::Variant(bool v) :
		_t(TypeNone)
	{
		memset(&_u, 0, sizeof(VariantUnion));
		*this = v;
	}

	Variant::Variant(const char * v) :
		_t(TypeNone)
	{
		memset(&_u, 0, sizeof(VariantUnion));
		*this = v;
	}

	Variant::Variant(const wchar_t * v) :
		_t(TypeNone)
	{
		memset(&_u, 0, sizeof(VariantUnion));
		*this = v;
	}

	Variant::Variant(const REString & v) :
		_t(TypeNone)
	{
		memset(&_u, 0, sizeof(VariantUnion));
		*this = v;
	}

	Variant::Variant(const VariantMap & v) :
		_t(TypeNone)
	{
		memset(&_u, 0, sizeof(VariantUnion));
		*this = v;
	}

	Variant::Variant(const VariantList & v) :
		_t(TypeNone)
	{
		memset(&_u, 0, sizeof(VariantUnion));
		*this = v;
	}

	Variant::Variant(const Variant & v) :
		_t(TypeNone)
	{
		memset(&_u, 0, sizeof(VariantUnion));
		*this = v;
	}

	Variant::~Variant()
	{
		this->clean();
	}

}

<|endoftext|>