<commit_before>#define MYSQLPP_NOT_HEADER
#include "platform.h"

#include "sql_query.h"

#include "exceptions.h"

using namespace std;

namespace mysqlpp {

SQLQuery::SQLQuery(const SQLQuery& q) :
stringstream(const_cast<SQLQuery&>(q).str()),	// yes, the cast is evil -- got a better idea?
Success(q.Success),
errmsg(q.errmsg),
def(q.def)
{
}

void SQLQuery::reset()
{
	seekg(0);
	seekp(0);
	clear();
	stringstream::str("");

	parsed.clear();
	def.clear();
}

char* SQLQuery::preview_char()
{
	*this << std::ends;
	size_t length = rdbuf()->str().size();
	char *s = new char[length + 1];
	get(s, length, '\0');
	seekg(0, std::ios::beg);
	seekp(-1, std::ios::cur);
	return s;
}

static SQLString* pprepare(char option, SQLString& S,
		bool replace = true)
{
	if (S.processed) {
		return &S;
	}

	if (option == 'r' || (option == 'q' && S.is_string)) {
		char *s = new char[S.size() * 2 + 1];
		mysql_escape_string(s, S.c_str(), (unsigned long) S.size());
		SQLString *ss = new SQLString("'");
		*ss += s;
		*ss += "'";
		delete[] s;

		if (replace) {
			S = *ss;
			S.processed = true;
			return &S;
		}
		else {
			return ss;
		}
	}
	else if (option == 'R' || (option == 'Q' && S.is_string)) {
		SQLString *ss = new SQLString("'" + S + "'");

		if (replace) {
			S = *ss;
			S.processed = true;
			return &S;
		}
		else {
			return ss;
		}
	}
	else {
		if (replace) {
			S.processed = true;
		}
		return &S;
	}
}

void SQLQuery::proc(SQLQueryParms& p)
{
	seekg(0, std::ios::beg);
	seekp(0, std::ios::beg);
	char num;
	SQLString *ss;
	SQLQueryParms *c;

	for (std::vector<SQLParseElement>::iterator i = parsed.begin();
			i != parsed.end(); ++i) {
		*this << i->before;
		num = i->num;
		if (num != -1) {
			if (num < static_cast < int >(p.size()))
				c = &p;
			else if (num < static_cast < int >(def.size()))
				c = &def;
			else {
				*this << " ERROR";
				throw
					SQLQueryNEParms
					("Not enough parameters to fill the template.");
			}
			ss = pprepare(i->option, (*c)[num], c->bound());
			*this << *ss;
			if (ss != &(*c)[num]) {
				delete ss;
			}
		}
	}
}

std::string SQLQuery::str(SQLQueryParms& p)
{
	if (!parsed.empty()) {
		proc(p);
	}

	*this << std::ends;

	return stringstream::str();
}

std::string SQLQuery::str(SQLQueryParms& p, query_reset r)
{
	std::string tmp = str(p);
	if (r == RESET_QUERY) {
		reset();
	}
	return tmp;
}

SQLQueryParms SQLQueryParms::operator +(const SQLQueryParms & other) const
{
	if (other.size() <= size()) {
		return *this;
	}
	SQLQueryParms New = *this;
	size_t i;
	for (i = size(); i < other.size(); i++) {
		New.push_back(other[i]);
	}

	return New;
}

void SQLQuery::parse()
{
	std::string str = "";
	char num[4];
	long int n;
	char option;
	std::string name;
	char *s, *s0;
	s0 = s = preview_char();
	while (*s) {
		if (*s == '%') {
			s++;
			if (*s == '%') {
				str += *s++;
			}
			else if (*s >= '0' && *s <= '9') {
				num[0] = *s;
				s++;
				if (*s >= '0' && *s <= '9') {
					num[1] = *s;
					num[2] = 0;
					s++;
					if (*s >= '0' && *s <= '9') {
						num[2] = *s;
						num[3] = 0;
						s++;
					}
					else {
						num[2] = 0;
					}
				}
				else {
					num[1] = 0;
				}

				n = strtol(num, NULL, 10);
				option = ' ';

				if (*s == 'q' || *s == 'Q' || *s == 'r' || *s == 'R') {
					option = *s++;
				}

				if (*s == ':') {
					s++;
					for ( /* */ ; (*s >= 'A' && *s <= 'Z') ||
						 *s == '_' || (*s >= 'a' && *s <= 'z'); s++) {
						name += *s;
					}

					if (*s == ':') {
						s++;
					}

					if (n >= static_cast <
						long int >(parsed_names.size())) {
						parsed_names.insert(parsed_names.end(),
											static_cast < vector <
											string >::size_type >
											(n + 1) -
											parsed_names.size(),
											string());
					}
					parsed_names[n] = name;
					parsed_nums[name] = n;
				}

				parsed.
					push_back(SQLParseElement(str, option, char (n)));
				str = "";
				name = "";
			}
			else {
				str += '%';
			}
		}
		else {
			str += *s++;
		}
	}

	parsed.push_back(SQLParseElement(str, ' ', -1));
	delete[] s0;
}

} // end namespace mysqlpp
<commit_msg>Changed some C-style casts to static_casts to avoid GCC 4 warnings.<commit_after>#define MYSQLPP_NOT_HEADER
#include "platform.h"

#include "sql_query.h"

#include "exceptions.h"

using namespace std;

namespace mysqlpp {

SQLQuery::SQLQuery(const SQLQuery& q) :
stringstream(const_cast<SQLQuery&>(q).str()),	// yes, the cast is evil -- got a better idea?
Success(q.Success),
errmsg(q.errmsg),
def(q.def)
{
}

void SQLQuery::reset()
{
	seekg(0);
	seekp(0);
	clear();
	stringstream::str("");

	parsed.clear();
	def.clear();
}

char* SQLQuery::preview_char()
{
	*this << std::ends;
	size_t length = rdbuf()->str().size();
	char *s = new char[length + 1];
	get(s, length, '\0');
	seekg(0, std::ios::beg);
	seekp(-1, std::ios::cur);
	return s;
}

static SQLString* pprepare(char option, SQLString& S,
		bool replace = true)
{
	if (S.processed) {
		return &S;
	}

	if (option == 'r' || (option == 'q' && S.is_string)) {
		char *s = new char[S.size() * 2 + 1];
		mysql_escape_string(s, S.c_str(), static_cast <unsigned long> (S.size()));
		SQLString *ss = new SQLString("'");
		*ss += s;
		*ss += "'";
		delete[] s;

		if (replace) {
			S = *ss;
			S.processed = true;
			return &S;
		}
		else {
			return ss;
		}
	}
	else if (option == 'R' || (option == 'Q' && S.is_string)) {
		SQLString *ss = new SQLString("'" + S + "'");

		if (replace) {
			S = *ss;
			S.processed = true;
			return &S;
		}
		else {
			return ss;
		}
	}
	else {
		if (replace) {
			S.processed = true;
		}
		return &S;
	}
}

void SQLQuery::proc(SQLQueryParms& p)
{
	seekg(0, std::ios::beg);
	seekp(0, std::ios::beg);
	char num;
	SQLString *ss;
	SQLQueryParms *c;

	for (std::vector<SQLParseElement>::iterator i = parsed.begin();
			i != parsed.end(); ++i) {
		*this << i->before;
		num = i->num;
		if (num != -1) {
			if (num < static_cast < int >(p.size()))
				c = &p;
			else if (num < static_cast < int >(def.size()))
				c = &def;
			else {
				*this << " ERROR";
				throw
					SQLQueryNEParms
					("Not enough parameters to fill the template.");
			}
			ss = pprepare(i->option, (*c)[num], c->bound());
			*this << *ss;
			if (ss != &(*c)[num]) {
				delete ss;
			}
		}
	}
}

std::string SQLQuery::str(SQLQueryParms& p)
{
	if (!parsed.empty()) {
		proc(p);
	}

	*this << std::ends;

	return stringstream::str();
}

std::string SQLQuery::str(SQLQueryParms& p, query_reset r)
{
	std::string tmp = str(p);
	if (r == RESET_QUERY) {
		reset();
	}
	return tmp;
}

SQLQueryParms SQLQueryParms::operator +(const SQLQueryParms & other) const
{
	if (other.size() <= size()) {
		return *this;
	}
	SQLQueryParms New = *this;
	size_t i;
	for (i = size(); i < other.size(); i++) {
		New.push_back(other[i]);
	}

	return New;
}

void SQLQuery::parse()
{
	std::string str = "";
	char num[4];
	long int n;
	char option;
	std::string name;
	char *s, *s0;
	s0 = s = preview_char();
	while (*s) {
		if (*s == '%') {
			s++;
			if (*s == '%') {
				str += *s++;
			}
			else if (*s >= '0' && *s <= '9') {
				num[0] = *s;
				s++;
				if (*s >= '0' && *s <= '9') {
					num[1] = *s;
					num[2] = 0;
					s++;
					if (*s >= '0' && *s <= '9') {
						num[2] = *s;
						num[3] = 0;
						s++;
					}
					else {
						num[2] = 0;
					}
				}
				else {
					num[1] = 0;
				}

				n = strtol(num, NULL, 10);
				option = ' ';

				if (*s == 'q' || *s == 'Q' || *s == 'r' || *s == 'R') {
					option = *s++;
				}

				if (*s == ':') {
					s++;
					for ( /* */ ; (*s >= 'A' && *s <= 'Z') ||
						 *s == '_' || (*s >= 'a' && *s <= 'z'); s++) {
						name += *s;
					}

					if (*s == ':') {
						s++;
					}

					if (n >= static_cast <
						long int >(parsed_names.size())) {
						parsed_names.insert(parsed_names.end(),
											static_cast < vector <
											string >::size_type >
											(n + 1) -
											parsed_names.size(),
											string());
					}
					parsed_names[n] = name;
					parsed_nums[name] = n;
				}

				parsed.
					push_back(SQLParseElement(str, option, char (n)));
				str = "";
				name = "";
			}
			else {
				str += '%';
			}
		}
		else {
			str += *s++;
		}
	}

	parsed.push_back(SQLParseElement(str, ' ', -1));
	delete[] s0;
}

} // end namespace mysqlpp
<|endoftext|>


<commit_before>/* $Header$ */
// Copyright ***********************************************************
//
// File ecmdMain.C
//
// IBM Confidential
// OCO Source Materials
// 9400 Licensed Internal Code
// (C) COPYRIGHT IBM CORP. 1996
//
// The source code for this program is not published or otherwise
// divested of its trade secrets, irrespective of what has been
// deposited with the U.S. Copyright Office.
//
// End Copyright *******************************************************
/**
 @file ecmdMain.C
 @brief Main Program entry point for ecmdDllClient Application
*/

//----------------------------------------------------------------------
//  Includes
//----------------------------------------------------------------------

#include <stdio.h>
#include <string>

#include <ecmdClientCapi.H>
#include <ecmdInterpreter.H>
#include <ecmdReturnCodes.H>
#include <ecmdCommandUtils.H>
#include <ecmdSharedUtils.H>

int main (int argc, char *argv[])
{
  uint32_t rc = ECMD_SUCCESS;

  std::string cmdSave;
  char errorbuf[200];
  for (int i = 0; i < argc; i++) {
    cmdSave += argv[i];
    cmdSave += " ";
  }
  cmdSave += "\n";

  rc = ecmdLoadDll("");
  if (rc) {
    ecmdLoadDllRecovery(cmdSave, rc);
  }

  // By default, quiet error mode is on.  This means no errors are printing in the dll wrapper code
  // For the command line, turn off quiet error mode so those errors will be reported as the plugin call returns
  rc = ecmdSetGlobalVar(ECMD_GLOBALVAR_QUIETERRORMODE, 0);
  if (rc) return rc;

  if (rc == ECMD_SUCCESS) {
    /* Check to see if we are using stdin to pass in multiple commands */
    bool shellMode = ecmdParseOption(&argc, &argv, "-shell");
    bool stdinMode = ecmdParseOption(&argc, &argv, "-stdin");
    if (stdinMode || shellMode) {

      /* Grab any other args that may be there */
      rc = ecmdCommandArgs(&argc, &argv);
      if (rc) return rc;

      /* There shouldn't be any more args when doing a -stdin/-shell */
      if (argc > 1) {
        ecmdOutputError("ecmd - Invalid args passed to ecmd in -stdin/-shell mode\n");
        return ECMD_INVALID_ARGS;
      }

      /* Let's get things going */
      std::vector<std::string> commands;
      int   c_argc;
      char* c_argv[ECMD_ARG_LIMIT + 1];       ///< A limit of 20 tokens(args) per command
      char* buffer = NULL;
      size_t   bufflen = 0;
      size_t   commlen;
      bool shellAlive = true;

      if (shellMode) {
        ecmdOutput("ecmd> "); fflush(0);
      }

      /* ecmdParseStdInCommands reads from stdin and returns a vector of strings */
      /*  each string contains one command (ie 'ecmdquery version')              */
      /* When Ctrl-D or EOF is reached this function will fail to break out of loop */
      while (shellAlive && (rc = ecmdParseStdinCommands(commands))) {

        rc = 0;

        /* Walk through individual commands from ecmdParseStdInCommands */
        for (std::vector< std::string >::iterator commandIter = commands.begin(); commandIter != commands.end(); commandIter++) {

          c_argc = 0;
          c_argv[0] = NULL;

          /* Check for a comment or empty line, if so delete it */
          if ((*commandIter)[0] == '#') {
            continue;
          } else if (commandIter->length() == 0) {
            continue;
          }
          if (shellMode) {
            if ((*commandIter) == "quit" || (*commandIter) == "exit") {
              ecmdOutput("Leaving ecmd shell at users request... \n");
              shellAlive = false;
              break;
            }
          }

          /* Create a char buffer to hold the whole command, we will use this to create pointers to each token in the command (like argc,argv) */
          commlen = commandIter->length();
          if ( commlen > bufflen) {
            if (buffer != NULL) delete[] buffer;
            buffer = new char[commlen + 20];
            bufflen = commlen + 19;
          }

          // Beam "error" of possible NULL 'buffer' value requires mutually
          // exclusive conditions (need an argument present to enter
          // "commands" FOR loop but commandIter->length = 0 ie. no command).  So
          // tell beam to ignore NULL pointer message for 'buffer' parm via
          // comment on next line.
          //lint -e(668) Ignore passing null, same as above for lint
          strcpy(buffer, commandIter->c_str()); /*passing null object*/

          /* Now start carving this thing up */
          bool lookingForStart = true; /* Are we looking for the start of a word ? */
          for (size_t c = 0; c < commlen; c++) {
            if (lookingForStart) {
              if (buffer[c] != ' ' && buffer[c] != '\t') {
                c_argv[c_argc++] = &buffer[c];
                lookingForStart = false;
              }
            } else {
              /* Looking for the end */
              if (buffer[c] == ' ' || buffer[c] == '\t') {
                buffer[c] = '\0';
                lookingForStart = true;
              }
            }
            if (c_argc > ECMD_ARG_LIMIT) {
              sprintf(errorbuf,"ecmd - Found a command with greater then %d arguments, not supported\n",ECMD_ARG_LIMIT);
              ecmdOutputError(errorbuf);
              rc = ECMD_INVALID_ARGS;
              break;
            }
          }

          // ignore a line if it is only space or tabs -
          // This prevents c_argv[o] being accessed below when still pointing to NULL
          if (c_argc == 0) continue;

          // Before Executing the cmd save it on the Dll side
          ecmdSetCurrentCmdline(c_argc, c_argv);

          /* We now want to call the command interpreter to handle what the user provided us */
          if (!rc) rc = ecmdCallInterpreters(c_argc, c_argv);

          if (rc == ECMD_INT_UNKNOWN_COMMAND) {
            if (strlen(c_argv[0]) < 200)
              sprintf(errorbuf,"ecmd -  Unknown Command specified '%s'\n", c_argv[0]);
            else
              sprintf(errorbuf,"ecmd -  Unknown Command specified \n");
            ecmdOutputError(errorbuf);
          } else if (rc) {
            std::string parse = ecmdGetErrorMsg(ECMD_GET_ALL_REMAINING_ERRORS, false);
            if (parse.length() > 0) {
              /* Display the registered message right away BZ#160 */
              ecmdOutput(parse.c_str());
            }
            parse = ecmdParseReturnCodeHidden(rc);
            if (strlen(c_argv[0]) + parse.length() < 300)
              sprintf(errorbuf,"ecmd - '%s' returned with error code 0x%X (%s)\n", c_argv[0], rc, parse.c_str());
            else
              sprintf(errorbuf,"ecmd - Command returned with error code 0x%X (%s)\n", rc, parse.c_str());
            ecmdOutputError(errorbuf);
            break;
          }

          if (!ecmdGetGlobalVar(ECMD_GLOBALVAR_QUIETMODE)) {
            ecmdOutput((*commandIter + "\n").c_str());
          }
        } /* tokens loop */
        if (rc) break;

        /* Print the prompt again */
        if (shellMode && shellAlive) {
          ecmdOutput("ecmd> "); fflush(0);
        }
      }
      if (buffer != NULL) delete[] buffer;

    } else {
      /* Standard command line command */

      // Before Executing the cmd save it on the Dll side
      ecmdSetCurrentCmdline(argc-1, argv+1);

      /* We now want to call the command interpreter to handle what the user provided us */
      rc = ecmdCallInterpreters(argc - 1, argv + 1);

      if (rc == ECMD_INT_UNKNOWN_COMMAND) {
        if (argv[1] == NULL)
          sprintf(errorbuf,"ecmd - Must specify a command to execute. Run 'ecmd -h' for command list.\n");
        else if (strlen(argv[1]) < 200)
          sprintf(errorbuf,"ecmd - Unknown Command specified '%s'\n", argv[1]);
        else
          sprintf(errorbuf,"ecmd - Unknown Command specified \n");
        ecmdOutputError(errorbuf);
      } else if (rc) {
        std::string parse = ecmdGetErrorMsg(ECMD_GET_ALL_REMAINING_ERRORS, false);
        if (parse.length() > 0) {
          /* Display the registered message right away BZ#160 */
          ecmdOutput(parse.c_str());
        }
        parse = ecmdParseReturnCodeHidden(rc);
        if (strlen(argv[1]) + parse.length() < 300)
          sprintf(errorbuf,"ecmd - '%s' returned with error code 0x%X (%s)\n", argv[1], rc, parse.c_str());
        else
          sprintf(errorbuf,"ecmd - Command returned with error code 0x%X (%s)\n", rc, parse.c_str());
        ecmdOutputError(errorbuf);
      }
    }

    /* Move these outputs into the if !rc to fix BZ#224 - cje */
    if (!ecmdGetGlobalVar(ECMD_GLOBALVAR_QUIETMODE)) {
      ecmdOutput(cmdSave.c_str());
    }

    rc = ecmdUnloadDll();
    if (rc) return rc;
  }

  return rc;
}

// Change Log *********************************************************
//
//  Flag Reason   Vers Date     Coder    Description
//  ---- -------- ---- -------- -------- ------------------------------
//                              CENGEL   Initial Creation
//  none STGC7449      04/18/05 prahl    Clean up Beam messages.
//
// End Change Log *****************************************************
<commit_msg>Moved ecmdSetGlobalVar call into if condition to fix problem where it reset an failing rc from the loaddll<commit_after>/* $Header$ */
// Copyright ***********************************************************
//
// File ecmdMain.C
//
// IBM Confidential
// OCO Source Materials
// 9400 Licensed Internal Code
// (C) COPYRIGHT IBM CORP. 1996
//
// The source code for this program is not published or otherwise
// divested of its trade secrets, irrespective of what has been
// deposited with the U.S. Copyright Office.
//
// End Copyright *******************************************************
/**
 @file ecmdMain.C
 @brief Main Program entry point for ecmdDllClient Application
*/

//----------------------------------------------------------------------
//  Includes
//----------------------------------------------------------------------

#include <stdio.h>
#include <string>

#include <ecmdClientCapi.H>
#include <ecmdInterpreter.H>
#include <ecmdReturnCodes.H>
#include <ecmdCommandUtils.H>
#include <ecmdSharedUtils.H>

int main (int argc, char *argv[])
{
  uint32_t rc = ECMD_SUCCESS;

  std::string cmdSave;
  char errorbuf[200];
  for (int i = 0; i < argc; i++) {
    cmdSave += argv[i];
    cmdSave += " ";
  }
  cmdSave += "\n";

  rc = ecmdLoadDll("");
  if (rc) {
    ecmdLoadDllRecovery(cmdSave, rc);
  }

  if (rc == ECMD_SUCCESS) {

    // By default, quiet error mode is on.  This means no errors are printing in the dll wrapper code
    // For the command line, turn off quiet error mode so those errors will be reported as the plugin call returns
    rc = ecmdSetGlobalVar(ECMD_GLOBALVAR_QUIETERRORMODE, 0);
    if (rc) return rc;

    /* Check to see if we are using stdin to pass in multiple commands */
    bool shellMode = ecmdParseOption(&argc, &argv, "-shell");
    bool stdinMode = ecmdParseOption(&argc, &argv, "-stdin");
    if (stdinMode || shellMode) {

      /* Grab any other args that may be there */
      rc = ecmdCommandArgs(&argc, &argv);
      if (rc) return rc;

      /* There shouldn't be any more args when doing a -stdin/-shell */
      if (argc > 1) {
        ecmdOutputError("ecmd - Invalid args passed to ecmd in -stdin/-shell mode\n");
        return ECMD_INVALID_ARGS;
      }

      /* Let's get things going */
      std::vector<std::string> commands;
      int   c_argc;
      char* c_argv[ECMD_ARG_LIMIT + 1];       ///< A limit of 20 tokens(args) per command
      char* buffer = NULL;
      size_t   bufflen = 0;
      size_t   commlen;
      bool shellAlive = true;

      if (shellMode) {
        ecmdOutput("ecmd> "); fflush(0);
      }

      /* ecmdParseStdInCommands reads from stdin and returns a vector of strings */
      /*  each string contains one command (ie 'ecmdquery version')              */
      /* When Ctrl-D or EOF is reached this function will fail to break out of loop */
      while (shellAlive && (rc = ecmdParseStdinCommands(commands))) {

        rc = 0;

        /* Walk through individual commands from ecmdParseStdInCommands */
        for (std::vector< std::string >::iterator commandIter = commands.begin(); commandIter != commands.end(); commandIter++) {

          c_argc = 0;
          c_argv[0] = NULL;

          /* Check for a comment or empty line, if so delete it */
          if ((*commandIter)[0] == '#') {
            continue;
          } else if (commandIter->length() == 0) {
            continue;
          }
          if (shellMode) {
            if ((*commandIter) == "quit" || (*commandIter) == "exit") {
              ecmdOutput("Leaving ecmd shell at users request... \n");
              shellAlive = false;
              break;
            }
          }

          /* Create a char buffer to hold the whole command, we will use this to create pointers to each token in the command (like argc,argv) */
          commlen = commandIter->length();
          if ( commlen > bufflen) {
            if (buffer != NULL) delete[] buffer;
            buffer = new char[commlen + 20];
            bufflen = commlen + 19;
          }

          // Beam "error" of possible NULL 'buffer' value requires mutually
          // exclusive conditions (need an argument present to enter
          // "commands" FOR loop but commandIter->length = 0 ie. no command).  So
          // tell beam to ignore NULL pointer message for 'buffer' parm via
          // comment on next line.
          //lint -e(668) Ignore passing null, same as above for lint
          strcpy(buffer, commandIter->c_str()); /*passing null object*/

          /* Now start carving this thing up */
          bool lookingForStart = true; /* Are we looking for the start of a word ? */
          for (size_t c = 0; c < commlen; c++) {
            if (lookingForStart) {
              if (buffer[c] != ' ' && buffer[c] != '\t') {
                c_argv[c_argc++] = &buffer[c];
                lookingForStart = false;
              }
            } else {
              /* Looking for the end */
              if (buffer[c] == ' ' || buffer[c] == '\t') {
                buffer[c] = '\0';
                lookingForStart = true;
              }
            }
            if (c_argc > ECMD_ARG_LIMIT) {
              sprintf(errorbuf,"ecmd - Found a command with greater then %d arguments, not supported\n",ECMD_ARG_LIMIT);
              ecmdOutputError(errorbuf);
              rc = ECMD_INVALID_ARGS;
              break;
            }
          }

          // ignore a line if it is only space or tabs -
          // This prevents c_argv[o] being accessed below when still pointing to NULL
          if (c_argc == 0) continue;

          // Before Executing the cmd save it on the Dll side
          ecmdSetCurrentCmdline(c_argc, c_argv);

          /* We now want to call the command interpreter to handle what the user provided us */
          if (!rc) rc = ecmdCallInterpreters(c_argc, c_argv);

          if (rc == ECMD_INT_UNKNOWN_COMMAND) {
            if (strlen(c_argv[0]) < 200)
              sprintf(errorbuf,"ecmd -  Unknown Command specified '%s'\n", c_argv[0]);
            else
              sprintf(errorbuf,"ecmd -  Unknown Command specified \n");
            ecmdOutputError(errorbuf);
          } else if (rc) {
            std::string parse = ecmdGetErrorMsg(ECMD_GET_ALL_REMAINING_ERRORS, false);
            if (parse.length() > 0) {
              /* Display the registered message right away BZ#160 */
              ecmdOutput(parse.c_str());
            }
            parse = ecmdParseReturnCodeHidden(rc);
            if (strlen(c_argv[0]) + parse.length() < 300)
              sprintf(errorbuf,"ecmd - '%s' returned with error code 0x%X (%s)\n", c_argv[0], rc, parse.c_str());
            else
              sprintf(errorbuf,"ecmd - Command returned with error code 0x%X (%s)\n", rc, parse.c_str());
            ecmdOutputError(errorbuf);
            break;
          }

          if (!ecmdGetGlobalVar(ECMD_GLOBALVAR_QUIETMODE)) {
            ecmdOutput((*commandIter + "\n").c_str());
          }
        } /* tokens loop */
        if (rc) break;

        /* Print the prompt again */
        if (shellMode && shellAlive) {
          ecmdOutput("ecmd> "); fflush(0);
        }
      }
      if (buffer != NULL) delete[] buffer;

    } else {
      /* Standard command line command */

      // Before Executing the cmd save it on the Dll side
      ecmdSetCurrentCmdline(argc-1, argv+1);

      /* We now want to call the command interpreter to handle what the user provided us */
      rc = ecmdCallInterpreters(argc - 1, argv + 1);

      if (rc == ECMD_INT_UNKNOWN_COMMAND) {
        if (argv[1] == NULL)
          sprintf(errorbuf,"ecmd - Must specify a command to execute. Run 'ecmd -h' for command list.\n");
        else if (strlen(argv[1]) < 200)
          sprintf(errorbuf,"ecmd - Unknown Command specified '%s'\n", argv[1]);
        else
          sprintf(errorbuf,"ecmd - Unknown Command specified \n");
        ecmdOutputError(errorbuf);
      } else if (rc) {
        std::string parse = ecmdGetErrorMsg(ECMD_GET_ALL_REMAINING_ERRORS, false);
        if (parse.length() > 0) {
          /* Display the registered message right away BZ#160 */
          ecmdOutput(parse.c_str());
        }
        parse = ecmdParseReturnCodeHidden(rc);
        if (strlen(argv[1]) + parse.length() < 300)
          sprintf(errorbuf,"ecmd - '%s' returned with error code 0x%X (%s)\n", argv[1], rc, parse.c_str());
        else
          sprintf(errorbuf,"ecmd - Command returned with error code 0x%X (%s)\n", rc, parse.c_str());
        ecmdOutputError(errorbuf);
      }
    }

    /* Move these outputs into the if !rc to fix BZ#224 - cje */
    if (!ecmdGetGlobalVar(ECMD_GLOBALVAR_QUIETMODE)) {
      ecmdOutput(cmdSave.c_str());
    }

    rc = ecmdUnloadDll();
    if (rc) return rc;
  }

  return rc;
}

// Change Log *********************************************************
//
//  Flag Reason   Vers Date     Coder    Description
//  ---- -------- ---- -------- -------- ------------------------------
//                              CENGEL   Initial Creation
//  none STGC7449      04/18/05 prahl    Clean up Beam messages.
//
// End Change Log *****************************************************
<|endoftext|>


<commit_before>
// Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
//
// Use of this source code is governed by a BSD-style license
// that can be found in the LICENSE file in the root of the source
// tree. An additional intellectual property rights grant can be found
// in the file PATENTS.  All contributing project authors may
// be found in the AUTHORS file in the root of the source tree.

// Class1.cpp
#include <ppltasks.h>
#include <vector>

#include "GlobalObserver.h"
#include "PeerConnectionInterface.h"
#include "Marshalling.h"
#include "Media.h"
#include "DataChannel.h"
#include "webrtc/common_video/video_common_winuwp.h"

using Platform::Collections::Vector;

namespace Org {
	namespace WebRtc {
		namespace Internal {

#define POST_PC_EVENT(fn, evt) \
  auto pc = _pc;\
  Windows::UI::Core::CoreDispatcher^ _windowDispatcher = webrtc::VideoCommonWinUWP::GetCoreDispatcher();\
  if (_windowDispatcher != nullptr) {\
    _windowDispatcher->RunAsync(\
      Windows::UI::Core::CoreDispatcherPriority::Normal, \
      ref new Windows::UI::Core::DispatchedHandler([pc, evt] {\
      if (pc != nullptr) {\
        pc->##fn(evt);\
      }\
    }));\
  } else {\
    if (pc != nullptr) {\
      pc->##fn(evt);\
    }\
  }

#define POST_PC_ACTION(fn) \
  auto pc = _pc;\
  Windows::UI::Core::CoreDispatcher^ _windowDispatcher = webrtc::VideoCommonWinUWP::GetCoreDispatcher();\
  if (_windowDispatcher != nullptr) {\
    _windowDispatcher->RunAsync(\
      Windows::UI::Core::CoreDispatcherPriority::Normal, \
      ref new Windows::UI::Core::DispatchedHandler([pc] {\
      if (pc != nullptr) {\
        pc->##fn();\
      }\
    }));\
  } else {\
    if (pc != nullptr) {\
      pc->##fn();\
    }\
  }

			GlobalObserver::GlobalObserver() {
				ResetStatsConfig();
			}

			void GlobalObserver::SetPeerConnection(
				Org::WebRtc::RTCPeerConnection^ pc) {
				_pc = pc;
				if (_pc == nullptr) {
					_stats_observer = nullptr;
				}
				ResetStatsConfig();
			}

			void GlobalObserver::ResetStatsConfig() {
				_etwStatsEnabled = false;
				_connectionHealthStatsEnabled = false;
				_rtcStatsEnabled = false;
				_sendRtcStatsToRemoteHostEnabled = false;
				_rtcStatsDestinationHost = "localhost";
				_rtcStatsDestinationPort = 47005;
			}

			void GlobalObserver::EnableETWStats(bool enable) {
				_etwStatsEnabled = enable;
				if (_stats_observer) {
					_stats_observer->ToggleETWStats(enable);
				}
			}

			bool GlobalObserver::AreETWStatsEnabled() {
				return _etwStatsEnabled;
			}

			void GlobalObserver::EnableConnectionHealthStats(bool enable) {
				_connectionHealthStatsEnabled = enable;
				if (_stats_observer) {
					_stats_observer->ToggleConnectionHealthStats(enable ? this : NULL);
				}
			}

			bool GlobalObserver::AreConnectionHealthStatsEnabled() {
				return _connectionHealthStatsEnabled;
			}

			void GlobalObserver::EnableRTCStats(bool enable) {
				_rtcStatsEnabled = enable;
				if (_stats_observer) {
					_stats_observer->ToggleRTCStats(enable ? this : NULL);
				}
			}

			bool GlobalObserver::AreRTCStatsEnabled() {
				return _rtcStatsEnabled;
			}

			void GlobalObserver::EnableSendRtcStatsToRemoteHost(bool enable) {
				_sendRtcStatsToRemoteHostEnabled = enable;
				if (_stats_observer) {
					if (enable) {
						_stats_observer->SetStatsNetworkDestination(
							_rtcStatsDestinationHost, _rtcStatsDestinationPort);
					}
					_stats_observer->ToggleStatsSendToRemoteHost(enable);
				}
			}

			bool GlobalObserver::IsSendRtcStatsToRemoteHostEnabled() {
				return _sendRtcStatsToRemoteHostEnabled;
			}

			void GlobalObserver::SetRtcStatsDestinationHost(std::string value) {
				_rtcStatsDestinationHost = value;
			}

			std::string GlobalObserver::GetRtcStatsDestinationHost() {
				return _rtcStatsDestinationHost;
			}

			void GlobalObserver::SetRtcStatsDestinationPort(int port) {
				_rtcStatsDestinationPort = port;
			}
			int GlobalObserver::GetRtcStatsDestinationPort() {
				return _rtcStatsDestinationPort;
			}

			// Triggered when the SignalingState changed.
			void GlobalObserver::OnSignalingChange(
				webrtc::PeerConnectionInterface::SignalingState new_state) {
				POST_PC_ACTION(OnSignalingStateChange);
			}

			// Triggered when SignalingState or IceState have changed.
			// TODO(bemasc): Remove once callers transition to OnSignalingChange.
			void GlobalObserver::OnStateChange(StateType state_changed) {
			}

			// Triggered when media is received on a new stream from remote peer.
			void GlobalObserver::OnAddStream(rtc::scoped_refptr<webrtc::MediaStreamInterface> stream) {
				auto evt = ref new Org::WebRtc::MediaStreamEvent();
				evt->Stream = ref new Org::WebRtc::MediaStream(stream);
				POST_PC_EVENT(OnAddStream, evt);
			}

			// Triggered when a remote peer close a stream.
			void GlobalObserver::OnRemoveStream(rtc::scoped_refptr<webrtc::MediaStreamInterface> stream) {
				auto evt = ref new Org::WebRtc::MediaStreamEvent();
				evt->Stream = ref new Org::WebRtc::MediaStream(stream);
				POST_PC_EVENT(OnRemoveStream, evt);
			}

			// Triggered when a remote peer open a data channel.
			void GlobalObserver::OnDataChannel(rtc::scoped_refptr<webrtc::DataChannelInterface> data_channel) {
				auto evt = ref new Org::WebRtc::RTCDataChannelEvent();
				evt->Channel = ref new Org::WebRtc::RTCDataChannel(data_channel);
				// This observer is deleted when the channel closes.
				// See DataChannelObserver::OnStateChange().
				data_channel->RegisterObserver(new DataChannelObserver(evt->Channel));
				POST_PC_EVENT(OnDataChannel, evt);
			}

			// Triggered when renegotiation is needed, for example the ICE has restarted.
			void GlobalObserver::OnRenegotiationNeeded() {
				POST_PC_ACTION(OnNegotiationNeeded);
			}

			// Called any time the IceConnectionState changes
			void GlobalObserver::OnIceConnectionChange(
				webrtc::PeerConnectionInterface::IceConnectionState new_state) {
				if (new_state == webrtc::PeerConnectionInterface::kIceConnectionConnected) {
					if (!_stats_observer.get()) {
						auto temp_impl = _pc->_impl;
						_stats_observer =
							new rtc::RefCountedObject<webrtc::WebRTCStatsObserver>(temp_impl);
					}
					_stats_observer->ToggleETWStats(_etwStatsEnabled);
					_stats_observer->ToggleConnectionHealthStats(
						_connectionHealthStatsEnabled ? this : NULL);
					_stats_observer->ToggleRTCStats(
						_rtcStatsEnabled ? this : NULL);
					if (_sendRtcStatsToRemoteHostEnabled) {
						_stats_observer->SetStatsNetworkDestination(
							_rtcStatsDestinationHost, _rtcStatsDestinationPort);
					}
					_stats_observer->ToggleStatsSendToRemoteHost(_sendRtcStatsToRemoteHostEnabled);
				}
				auto evt = ref new Org::WebRtc::RTCPeerConnectionIceStateChangeEvent();
				Org::WebRtc::RTCIceConnectionState cxNewState;
				ToCx(new_state, &cxNewState);
				evt->State = cxNewState;
				POST_PC_EVENT(OnIceConnectionChange, evt);
			}

			// Called any time the IceGatheringState changes
			void GlobalObserver::OnIceGatheringChange(
				webrtc::PeerConnectionInterface::IceGatheringState new_state) {
				LOG(LS_INFO) << "OnIceGatheringChange";
			}

			// New Ice candidate have been found.
			void GlobalObserver::OnIceCandidate(
				const webrtc::IceCandidateInterface* candidate) {
				std::string c;
				candidate->ToString(&c);
				LOG(LS_INFO) << "Ice candidate = " << c;
				auto evt = ref new Org::WebRtc::RTCPeerConnectionIceEvent();
				Org::WebRtc::RTCIceCandidate^ cxCandidate;
				if (candidate == nullptr) {
					evt->Candidate = nullptr;
				}
				else {
					ToCx(*candidate, &cxCandidate);
					evt->Candidate = cxCandidate;
				}
				POST_PC_EVENT(OnIceCandidate, evt);
			}

			// TODO(bemasc): Remove this once callers transition to OnIceGatheringChange.
			// All Ice candidates have been found.
			void GlobalObserver::OnIceComplete() {
				auto evt = ref new Org::WebRtc::RTCPeerConnectionIceEvent();
				evt->Candidate = nullptr;
				POST_PC_EVENT(OnIceCandidate, evt);
			}

			void GlobalObserver::OnConnectionHealthStats(
				const webrtc::ConnectionHealthStats& stats) {
				auto evt = ref new Org::WebRtc::RTCPeerConnectionHealthStats();
				evt->ReceivedBytes = stats.received_bytes;
				evt->ReceivedKpbs = stats.received_kbps;
				evt->SentBytes = stats.sent_bytes;
				evt->SentKbps = stats.sent_kbps;
				evt->RTT = stats.rtt;
				evt->LocalCandidateType = ToCx(stats.local_candidate_type);
				evt->RemoteCandidateType = ToCx(stats.remote_candidate_type);
				POST_PC_EVENT(OnConnectionHealthStats, evt);
			}

			void GlobalObserver::OnRTCStatsReportsReady(
				const Org::WebRtc::RTCStatsReports& rtcStatsReports) {
				auto evt = ref new Org::WebRtc::RTCStatsReportsReadyEvent();
				evt->rtcStatsReports = rtcStatsReports;
				POST_PC_EVENT(OnRTCStatsReportsReady, evt);
			}

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

			CreateSdpObserver::CreateSdpObserver(
				Concurrency::task_completion_event<webrtc::SessionDescriptionInterface*> tce)
				: _tce(tce) {
			}

			void CreateSdpObserver::OnSuccess(webrtc::SessionDescriptionInterface* desc) {
				_tce.set(desc);
			}

			void CreateSdpObserver::OnFailure(const std::string& error) {
				_tce.set_exception(error);
			}

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

			SetSdpObserver::SetSdpObserver(Concurrency::task_completion_event<void> tce)
				: _tce(tce) {
			}

			void SetSdpObserver::OnSuccess() {
				_tce.set();
			}

			void SetSdpObserver::OnFailure(const std::string& error) {
				_tce.set_exception(error);
			}

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

			DataChannelObserver::DataChannelObserver(
				Org::WebRtc::RTCDataChannel^ channel)
				: _channel(channel) {
			}

			void DataChannelObserver::OnStateChange() {
				Windows::UI::Core::CoreDispatcher^ _windowDispatcher = webrtc::VideoCommonWinUWP::GetCoreDispatcher();
				switch (_channel->GetImpl()->state()) {
				case webrtc::DataChannelInterface::kOpen:
					if (_windowDispatcher != nullptr) {
						_windowDispatcher->RunAsync(
							Windows::UI::Core::CoreDispatcherPriority::Normal,
							ref new Windows::UI::Core::DispatchedHandler([this] {
							_channel->OnOpen();
						}));
					}
					else {
						_channel->OnOpen();
					}
					break;
				case webrtc::DataChannelInterface::kClosed:
					_channel->_impl->UnregisterObserver();
					if (_windowDispatcher != nullptr) {
						_windowDispatcher->RunAsync(
							Windows::UI::Core::CoreDispatcherPriority::Normal,
							ref new Windows::UI::Core::DispatchedHandler([this] {
							_channel->OnClose();
							delete this;
						}));
					}
					else {
						_channel->OnClose();
						delete this;
					}
					break;
				}
			}

			void DataChannelObserver::OnMessage(const webrtc::DataBuffer& buffer) {
				auto evt = ref new Org::WebRtc::RTCDataChannelMessageEvent();

				if (!buffer.binary) {
					// convert buffer data from uint_8[] to char*
					String^ receivedString = ToCx(std::string(
						reinterpret_cast<const char*>(buffer.data.data()),
						buffer.size()));

					evt->Data = ref new Org::WebRtc::StringDataChannelMessage(
						receivedString);
				}
				else {
					// convert byte[] from buffer to Vector
					std::vector<byte> bytesFromBuffer = std::vector<byte>();
					bytesFromBuffer.insert(bytesFromBuffer.end(), buffer.data.data(),
						buffer.data.data() + buffer.size());
					Vector<byte>^ convertedBytes = ref new Vector<byte>();
					ToCx(&bytesFromBuffer, convertedBytes);

					evt->Data = ref new Org::WebRtc::BinaryDataChannelMessage(
						convertedBytes);
				}

				Windows::UI::Core::CoreDispatcher^ _windowDispatcher = webrtc::VideoCommonWinUWP::GetCoreDispatcher();
				if (_windowDispatcher != nullptr) {
					_windowDispatcher->RunAsync(
						Windows::UI::Core::CoreDispatcherPriority::Normal,
						ref new Windows::UI::Core::DispatchedHandler([this, evt] {
						_channel->OnMessage(evt);
					}));
				}
				else {
					_channel->OnMessage(evt);
				}
			}
		}
	}
}  // namespace Org.WebRtc.Internal

<commit_msg>don't delete DataChannerlObserver in OnStateChange<commit_after>
// Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
//
// Use of this source code is governed by a BSD-style license
// that can be found in the LICENSE file in the root of the source
// tree. An additional intellectual property rights grant can be found
// in the file PATENTS.  All contributing project authors may
// be found in the AUTHORS file in the root of the source tree.

// Class1.cpp
#include <ppltasks.h>
#include <vector>

#include "GlobalObserver.h"
#include "PeerConnectionInterface.h"
#include "Marshalling.h"
#include "Media.h"
#include "DataChannel.h"
#include "webrtc/common_video/video_common_winuwp.h"

using Platform::Collections::Vector;

namespace Org {
	namespace WebRtc {
		namespace Internal {

#define POST_PC_EVENT(fn, evt) \
  auto pc = _pc;\
  Windows::UI::Core::CoreDispatcher^ _windowDispatcher = webrtc::VideoCommonWinUWP::GetCoreDispatcher();\
  if (_windowDispatcher != nullptr) {\
    _windowDispatcher->RunAsync(\
      Windows::UI::Core::CoreDispatcherPriority::Normal, \
      ref new Windows::UI::Core::DispatchedHandler([pc, evt] {\
      if (pc != nullptr) {\
        pc->##fn(evt);\
      }\
    }));\
  } else {\
    if (pc != nullptr) {\
      pc->##fn(evt);\
    }\
  }

#define POST_PC_ACTION(fn) \
  auto pc = _pc;\
  Windows::UI::Core::CoreDispatcher^ _windowDispatcher = webrtc::VideoCommonWinUWP::GetCoreDispatcher();\
  if (_windowDispatcher != nullptr) {\
    _windowDispatcher->RunAsync(\
      Windows::UI::Core::CoreDispatcherPriority::Normal, \
      ref new Windows::UI::Core::DispatchedHandler([pc] {\
      if (pc != nullptr) {\
        pc->##fn();\
      }\
    }));\
  } else {\
    if (pc != nullptr) {\
      pc->##fn();\
    }\
  }

			GlobalObserver::GlobalObserver() {
				ResetStatsConfig();
			}

			void GlobalObserver::SetPeerConnection(
				Org::WebRtc::RTCPeerConnection^ pc) {
				_pc = pc;
				if (_pc == nullptr) {
					_stats_observer = nullptr;
				}
				ResetStatsConfig();
			}

			void GlobalObserver::ResetStatsConfig() {
				_etwStatsEnabled = false;
				_connectionHealthStatsEnabled = false;
				_rtcStatsEnabled = false;
				_sendRtcStatsToRemoteHostEnabled = false;
				_rtcStatsDestinationHost = "localhost";
				_rtcStatsDestinationPort = 47005;
			}

			void GlobalObserver::EnableETWStats(bool enable) {
				_etwStatsEnabled = enable;
				if (_stats_observer) {
					_stats_observer->ToggleETWStats(enable);
				}
			}

			bool GlobalObserver::AreETWStatsEnabled() {
				return _etwStatsEnabled;
			}

			void GlobalObserver::EnableConnectionHealthStats(bool enable) {
				_connectionHealthStatsEnabled = enable;
				if (_stats_observer) {
					_stats_observer->ToggleConnectionHealthStats(enable ? this : NULL);
				}
			}

			bool GlobalObserver::AreConnectionHealthStatsEnabled() {
				return _connectionHealthStatsEnabled;
			}

			void GlobalObserver::EnableRTCStats(bool enable) {
				_rtcStatsEnabled = enable;
				if (_stats_observer) {
					_stats_observer->ToggleRTCStats(enable ? this : NULL);
				}
			}

			bool GlobalObserver::AreRTCStatsEnabled() {
				return _rtcStatsEnabled;
			}

			void GlobalObserver::EnableSendRtcStatsToRemoteHost(bool enable) {
				_sendRtcStatsToRemoteHostEnabled = enable;
				if (_stats_observer) {
					if (enable) {
						_stats_observer->SetStatsNetworkDestination(
							_rtcStatsDestinationHost, _rtcStatsDestinationPort);
					}
					_stats_observer->ToggleStatsSendToRemoteHost(enable);
				}
			}

			bool GlobalObserver::IsSendRtcStatsToRemoteHostEnabled() {
				return _sendRtcStatsToRemoteHostEnabled;
			}

			void GlobalObserver::SetRtcStatsDestinationHost(std::string value) {
				_rtcStatsDestinationHost = value;
			}

			std::string GlobalObserver::GetRtcStatsDestinationHost() {
				return _rtcStatsDestinationHost;
			}

			void GlobalObserver::SetRtcStatsDestinationPort(int port) {
				_rtcStatsDestinationPort = port;
			}
			int GlobalObserver::GetRtcStatsDestinationPort() {
				return _rtcStatsDestinationPort;
			}

			// Triggered when the SignalingState changed.
			void GlobalObserver::OnSignalingChange(
				webrtc::PeerConnectionInterface::SignalingState new_state) {
				POST_PC_ACTION(OnSignalingStateChange);
			}

			// Triggered when SignalingState or IceState have changed.
			// TODO(bemasc): Remove once callers transition to OnSignalingChange.
			void GlobalObserver::OnStateChange(StateType state_changed) {
			}

			// Triggered when media is received on a new stream from remote peer.
			void GlobalObserver::OnAddStream(rtc::scoped_refptr<webrtc::MediaStreamInterface> stream) {
				auto evt = ref new Org::WebRtc::MediaStreamEvent();
				evt->Stream = ref new Org::WebRtc::MediaStream(stream);
				POST_PC_EVENT(OnAddStream, evt);
			}

			// Triggered when a remote peer close a stream.
			void GlobalObserver::OnRemoveStream(rtc::scoped_refptr<webrtc::MediaStreamInterface> stream) {
				auto evt = ref new Org::WebRtc::MediaStreamEvent();
				evt->Stream = ref new Org::WebRtc::MediaStream(stream);
				POST_PC_EVENT(OnRemoveStream, evt);
			}

			// Triggered when a remote peer open a data channel.
			void GlobalObserver::OnDataChannel(rtc::scoped_refptr<webrtc::DataChannelInterface> data_channel) {
				auto evt = ref new Org::WebRtc::RTCDataChannelEvent();
				evt->Channel = ref new Org::WebRtc::RTCDataChannel(data_channel);
				// This observer is deleted when the channel closes.
				// See DataChannelObserver::OnStateChange().
				data_channel->RegisterObserver(new DataChannelObserver(evt->Channel));
				POST_PC_EVENT(OnDataChannel, evt);
			}

			// Triggered when renegotiation is needed, for example the ICE has restarted.
			void GlobalObserver::OnRenegotiationNeeded() {
				POST_PC_ACTION(OnNegotiationNeeded);
			}

			// Called any time the IceConnectionState changes
			void GlobalObserver::OnIceConnectionChange(
				webrtc::PeerConnectionInterface::IceConnectionState new_state) {
				if (new_state == webrtc::PeerConnectionInterface::kIceConnectionConnected) {
					if (!_stats_observer.get()) {
						auto temp_impl = _pc->_impl;
						_stats_observer =
							new rtc::RefCountedObject<webrtc::WebRTCStatsObserver>(temp_impl);
					}
					_stats_observer->ToggleETWStats(_etwStatsEnabled);
					_stats_observer->ToggleConnectionHealthStats(
						_connectionHealthStatsEnabled ? this : NULL);
					_stats_observer->ToggleRTCStats(
						_rtcStatsEnabled ? this : NULL);
					if (_sendRtcStatsToRemoteHostEnabled) {
						_stats_observer->SetStatsNetworkDestination(
							_rtcStatsDestinationHost, _rtcStatsDestinationPort);
					}
					_stats_observer->ToggleStatsSendToRemoteHost(_sendRtcStatsToRemoteHostEnabled);
				}
				auto evt = ref new Org::WebRtc::RTCPeerConnectionIceStateChangeEvent();
				Org::WebRtc::RTCIceConnectionState cxNewState;
				ToCx(new_state, &cxNewState);
				evt->State = cxNewState;
				POST_PC_EVENT(OnIceConnectionChange, evt);
			}

			// Called any time the IceGatheringState changes
			void GlobalObserver::OnIceGatheringChange(
				webrtc::PeerConnectionInterface::IceGatheringState new_state) {
				LOG(LS_INFO) << "OnIceGatheringChange";
			}

			// New Ice candidate have been found.
			void GlobalObserver::OnIceCandidate(
				const webrtc::IceCandidateInterface* candidate) {
				std::string c;
				candidate->ToString(&c);
				LOG(LS_INFO) << "Ice candidate = " << c;
				auto evt = ref new Org::WebRtc::RTCPeerConnectionIceEvent();
				Org::WebRtc::RTCIceCandidate^ cxCandidate;
				if (candidate == nullptr) {
					evt->Candidate = nullptr;
				}
				else {
					ToCx(*candidate, &cxCandidate);
					evt->Candidate = cxCandidate;
				}
				POST_PC_EVENT(OnIceCandidate, evt);
			}

			// TODO(bemasc): Remove this once callers transition to OnIceGatheringChange.
			// All Ice candidates have been found.
			void GlobalObserver::OnIceComplete() {
				auto evt = ref new Org::WebRtc::RTCPeerConnectionIceEvent();
				evt->Candidate = nullptr;
				POST_PC_EVENT(OnIceCandidate, evt);
			}

			void GlobalObserver::OnConnectionHealthStats(
				const webrtc::ConnectionHealthStats& stats) {
				auto evt = ref new Org::WebRtc::RTCPeerConnectionHealthStats();
				evt->ReceivedBytes = stats.received_bytes;
				evt->ReceivedKpbs = stats.received_kbps;
				evt->SentBytes = stats.sent_bytes;
				evt->SentKbps = stats.sent_kbps;
				evt->RTT = stats.rtt;
				evt->LocalCandidateType = ToCx(stats.local_candidate_type);
				evt->RemoteCandidateType = ToCx(stats.remote_candidate_type);
				POST_PC_EVENT(OnConnectionHealthStats, evt);
			}

			void GlobalObserver::OnRTCStatsReportsReady(
				const Org::WebRtc::RTCStatsReports& rtcStatsReports) {
				auto evt = ref new Org::WebRtc::RTCStatsReportsReadyEvent();
				evt->rtcStatsReports = rtcStatsReports;
				POST_PC_EVENT(OnRTCStatsReportsReady, evt);
			}

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

			CreateSdpObserver::CreateSdpObserver(
				Concurrency::task_completion_event<webrtc::SessionDescriptionInterface*> tce)
				: _tce(tce) {
			}

			void CreateSdpObserver::OnSuccess(webrtc::SessionDescriptionInterface* desc) {
				_tce.set(desc);
			}

			void CreateSdpObserver::OnFailure(const std::string& error) {
				_tce.set_exception(error);
			}

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

			SetSdpObserver::SetSdpObserver(Concurrency::task_completion_event<void> tce)
				: _tce(tce) {
			}

			void SetSdpObserver::OnSuccess() {
				_tce.set();
			}

			void SetSdpObserver::OnFailure(const std::string& error) {
				_tce.set_exception(error);
			}

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

			DataChannelObserver::DataChannelObserver(
				Org::WebRtc::RTCDataChannel^ channel)
				: _channel(channel) {
			}

			void DataChannelObserver::OnStateChange() {
				Windows::UI::Core::CoreDispatcher^ _windowDispatcher = webrtc::VideoCommonWinUWP::GetCoreDispatcher();
				switch (_channel->GetImpl()->state()) {
				case webrtc::DataChannelInterface::kOpen:
					if (_windowDispatcher != nullptr) {
						_windowDispatcher->RunAsync(
							Windows::UI::Core::CoreDispatcherPriority::Normal,
							ref new Windows::UI::Core::DispatchedHandler([this] {
							_channel->OnOpen();
						}));
					}
					else {
						_channel->OnOpen();
					}
					break;
				case webrtc::DataChannelInterface::kClosed:
					_channel->_impl->UnregisterObserver();
					if (_windowDispatcher != nullptr) {
						_windowDispatcher->RunAsync(
							Windows::UI::Core::CoreDispatcherPriority::Normal,
							ref new Windows::UI::Core::DispatchedHandler([this] {
							_channel->OnClose();
							//delete this;
						}));
					}
					else {
						_channel->OnClose();
						//delete this;
					}
					break;
				}
			}

			void DataChannelObserver::OnMessage(const webrtc::DataBuffer& buffer) {
				auto evt = ref new Org::WebRtc::RTCDataChannelMessageEvent();

				if (!buffer.binary) {
					// convert buffer data from uint_8[] to char*
					String^ receivedString = ToCx(std::string(
						reinterpret_cast<const char*>(buffer.data.data()),
						buffer.size()));

					evt->Data = ref new Org::WebRtc::StringDataChannelMessage(
						receivedString);
				}
				else {
					// convert byte[] from buffer to Vector
					std::vector<byte> bytesFromBuffer = std::vector<byte>();
					bytesFromBuffer.insert(bytesFromBuffer.end(), buffer.data.data(),
						buffer.data.data() + buffer.size());
					Vector<byte>^ convertedBytes = ref new Vector<byte>();
					ToCx(&bytesFromBuffer, convertedBytes);

					evt->Data = ref new Org::WebRtc::BinaryDataChannelMessage(
						convertedBytes);
				}

				Windows::UI::Core::CoreDispatcher^ _windowDispatcher = webrtc::VideoCommonWinUWP::GetCoreDispatcher();
				if (_windowDispatcher != nullptr) {
					_windowDispatcher->RunAsync(
						Windows::UI::Core::CoreDispatcherPriority::Normal,
						ref new Windows::UI::Core::DispatchedHandler([this, evt] {
						_channel->OnMessage(evt);
					}));
				}
				else {
					_channel->OnMessage(evt);
				}
			}
		}
	}
}  // namespace Org.WebRtc.Internal

<|endoftext|>


<commit_before>// -*- c-basic-offset: 2; related-file-name: "task.h" -*-
/*
 * @(#)$Id$
 *
 * Modified from the Click Task class by Eddie Kohler and Benjie Chen
 *
 * Copyright (c) 1999-2000 Massachusetts Institute of Technology
 * Copyright (c) 2004 Regents of the University of California
 * Copyright (c) 2004 Intel Corporation
 *
 * 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, subject to the conditions
 * listed in the Click LICENSE file. These conditions include: you must
 * preserve this copyright notice, and you cannot mention the copyright
 * holders in advertising related to the Software without their permission.
 * The Software is provided WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. This
 * notice is a summary of the Click LICENSE file; the license in that file is
 * legally binding.
 *
 * This file is distributed under the terms in the attached INTEL-LICENSE file.
 * If you do not find these files, copies can be found by writing to:
 * Intel Research Berkeley, 2150 Shattuck Avenue, Suite 1300,
 * Berkeley, CA, 94704.  Attention:  Intel License Inquiry.
 *
 * DESCRIPTION: A linked list of schedulable entities
 */

#include <master.h>
#include <router.h>
#include <routerthread.h>
#include <task.h>

// - Changes to _thread are protected by _thread->lock.
// - Changes to _thread_preference are protected by
//   _router->master()->task_lock.
// - If _pending is nonzero, then _pending_next is nonnull.
// - Either _thread_preference == _thread->thread_id(), or
//   _thread->thread_id() == -1.

REMOVABLE_INLINE Task::Task()
  : _prev(0),
    _next(0),
    _thread(0),
    _router(0),
    _pending(0),
    _pending_next(0)
{
}

Master * Task::master() const
{
  assert(_thread);
  return _thread->master();
}

void Task::initialize(Router* router,
                      bool join)
{
  assert(!initialized() && !scheduled());

  _router = router;

  _thread = router->master()->thread();

  if (join)
    add_pending(RESCHEDULE);
}

void Task::add_pending(int p)
{
  Master *m = _router->master();
  m->_task_lock.acquire();
  _pending |= p;
  if (!_pending_next && _pending) {
    _pending_next = m->_task_list._pending_next;
    m->_task_list._pending_next = this;
  }
  if (_pending)
    _thread->add_pending();
  m->_task_lock.release();
}

bool Task::error_hook(Task *, void *)
{
  assert(0);
  return false;
}

void Task::make_list()
{
  _pending_next = this;
}

Task::~Task()
{
  if (scheduled() || _pending)
    cleanup();
}

void Task::cleanup()
{
  if (initialized()) {
    strong_unschedule();

    if (_pending) {
      Master *m = _router->master();
      m->_task_lock.acquire();
      Task *prev = &m->_task_list;
      for (Task *t = prev->_pending_next; t != &m->_task_list; prev = t, t = t->_pending_next)
        if (t == this) {
          prev->_pending_next = t->_pending_next;
          break;
        }
      _pending = 0;
      _pending_next = 0;
      m->_task_lock.release();
    }

    _router = 0;
    _thread = 0;
  }
}

inline void
Task::lock_tasks()
{
  while (1) {
    RouterThread *t = _thread;
    t->lock_tasks();
    if (t == _thread)
      return;
    t->unlock_tasks();
  }
}

inline bool
Task::attempt_lock_tasks()
{
  RouterThread *t = _thread;
  if (t->attempt_lock_tasks()) {
    if (t == _thread)
      return true;
    t->unlock_tasks();
  }
  return false;
}

void
Task::unschedule()
{
  // Thanksgiving 2001: unschedule() will always unschedule the task. This
  // seems more reliable, since some people depend on unschedule() ensuring
  // that the task is not scheduled any more, no way, no how. Possible
  // problem: calling unschedule() from run_task() will hang!
  if (_thread) {
    lock_tasks();
    fast_unschedule();
    _pending &= ~RESCHEDULE;
    _thread->unlock_tasks();
  }
}

void Task::true_reschedule()
{
  assert(_thread);
  bool done = false;
  // If I can lock the queue
  if (attempt_lock_tasks()) {
    if (!scheduled()) {
      // I've already locked, so call the fast_ version
      fast_schedule();
      _thread->unsleep();
    }
    done = true;
    _thread->unlock_tasks();
  }

  // Wasn't able to lock the queue.  Try later
  if (!done)
    add_pending(RESCHEDULE);
}

void Task::strong_unschedule()
{
  // unschedule() and move to the quiescent thread, so that subsequent
  // reschedule()s won't have any effect
  if (_thread) {
    lock_tasks();
    fast_unschedule();
    RouterThread *old_thread = _thread;
    _pending &= ~RESCHEDULE;
    _thread = _router->master()->thread();
    old_thread->unlock_tasks();
  }
}

void Task::strong_reschedule()
{
  assert(_thread);
  lock_tasks();
  fast_unschedule();
  RouterThread *old_thread = _thread;
  _thread = _router->master()->thread();
  add_pending(RESCHEDULE);
  old_thread->unlock_tasks();
}

void Task::process_pending(RouterThread *thread)
{
  // must be called with thread->lock held
  if (_thread == thread) {
    if (_pending & RESCHEDULE) {
      _pending &= ~RESCHEDULE;
      if (!scheduled())
        fast_schedule();
    }
  }

  if (_pending)
    add_pending(0);
}

REMOVABLE_INLINE int Task::fast_unschedule()
{
  if (_prev) {
    _next->_prev = _prev;
    _prev->_next = _next;
    _next = _prev = 0;
  }
  return 0;
}

REMOVABLE_INLINE void Task::fast_reschedule()
{
  assert(_thread);
  if (!scheduled()) {
    _prev = _thread->_taskList._prev;
    _next = &_thread->_taskList;
    _thread->_taskList._prev = this;
    _thread->_taskList._next = this;
  }
}

REMOVABLE_INLINE void Task::reschedule()
{
  assert(_thread);
  if (!scheduled())
    true_reschedule();
}

REMOVABLE_INLINE void Task::fast_schedule()
{
    fast_reschedule();
}

<commit_msg>syntax protection<commit_after>// -*- c-basic-offset: 2; related-file-name: "task.h" -*-
/*
 * @(#)$Id$
 *
 * Modified from the Click Task class by Eddie Kohler and Benjie Chen
 *
 * Copyright (c) 1999-2000 Massachusetts Institute of Technology
 * Copyright (c) 2004 Regents of the University of California
 * Copyright (c) 2004 Intel Corporation
 *
 * 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, subject to the conditions
 * listed in the Click LICENSE file. These conditions include: you must
 * preserve this copyright notice, and you cannot mention the copyright
 * holders in advertising related to the Software without their permission.
 * The Software is provided WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. This
 * notice is a summary of the Click LICENSE file; the license in that file is
 * legally binding.
 *
 * This file is distributed under the terms in the attached INTEL-LICENSE file.
 * If you do not find these files, copies can be found by writing to:
 * Intel Research Berkeley, 2150 Shattuck Avenue, Suite 1300,
 * Berkeley, CA, 94704.  Attention:  Intel License Inquiry.
 *
 * DESCRIPTION: A linked list of schedulable entities
 */

#include <master.h>
#include <router.h>
#include <routerthread.h>
#include <task.h>

// - Changes to _thread are protected by _thread->lock.
// - Changes to _thread_preference are protected by
//   _router->master()->task_lock.
// - If _pending is nonzero, then _pending_next is nonnull.
// - Either _thread_preference == _thread->thread_id(), or
//   _thread->thread_id() == -1.

REMOVABLE_INLINE Task::Task()
  : _prev(0),
    _next(0),
    _thread(0),
    _router(0),
    _pending(0),
    _pending_next(0)
{
}

Master * Task::master() const
{
  assert(_thread);
  return _thread->master();
}

void Task::initialize(Router* router,
                      bool join)
{
  assert(!initialized() && !scheduled());

  _router = router;

  _thread = router->master()->thread();

  if (join)
    add_pending(RESCHEDULE);
}

void Task::add_pending(int p)
{
  Master *m = _router->master();
  m->_task_lock.acquire();
  _pending |= p;
  if (!_pending_next && _pending) {
    _pending_next = m->_task_list._pending_next;
    m->_task_list._pending_next = this;
  }
  if (_pending) {
    _thread->add_pending();
  }
  m->_task_lock.release();
}

bool Task::error_hook(Task *, void *)
{
  assert(0);
  return false;
}

void Task::make_list()
{
  _pending_next = this;
}

Task::~Task()
{
  if (scheduled() || _pending) {
    cleanup();
  }
}

void Task::cleanup()
{
  if (initialized()) {
    strong_unschedule();

    if (_pending) {
      Master *m = _router->master();
      m->_task_lock.acquire();
      Task *prev = &m->_task_list;
      for (Task *t = prev->_pending_next; t != &m->_task_list; prev = t, t = t->_pending_next)
        if (t == this) {
          prev->_pending_next = t->_pending_next;
          break;
        }
      _pending = 0;
      _pending_next = 0;
      m->_task_lock.release();
    }

    _router = 0;
    _thread = 0;
  }
}

inline void
Task::lock_tasks()
{
  while (1) {
    RouterThread *t = _thread;
    t->lock_tasks();
    if (t == _thread)
      return;
    t->unlock_tasks();
  }
}

inline bool
Task::attempt_lock_tasks()
{
  RouterThread *t = _thread;
  if (t->attempt_lock_tasks()) {
    if (t == _thread)
      return true;
    t->unlock_tasks();
  }
  return false;
}

void
Task::unschedule()
{
  // Thanksgiving 2001: unschedule() will always unschedule the task. This
  // seems more reliable, since some people depend on unschedule() ensuring
  // that the task is not scheduled any more, no way, no how. Possible
  // problem: calling unschedule() from run_task() will hang!
  if (_thread) {
    lock_tasks();
    fast_unschedule();
    _pending &= ~RESCHEDULE;
    _thread->unlock_tasks();
  }
}

void Task::true_reschedule()
{
  assert(_thread);
  bool done = false;
  // If I can lock the queue
  if (attempt_lock_tasks()) {
    if (!scheduled()) {
      // I've already locked, so call the fast_ version
      fast_schedule();
      _thread->unsleep();
    }
    done = true;
    _thread->unlock_tasks();
  }

  // Wasn't able to lock the queue.  Try later
  if (!done)
    add_pending(RESCHEDULE);
}

void Task::strong_unschedule()
{
  // unschedule() and move to the quiescent thread, so that subsequent
  // reschedule()s won't have any effect
  if (_thread) {
    lock_tasks();
    fast_unschedule();
    RouterThread *old_thread = _thread;
    _pending &= ~RESCHEDULE;
    _thread = _router->master()->thread();
    old_thread->unlock_tasks();
  }
}

void Task::strong_reschedule()
{
  assert(_thread);
  lock_tasks();
  fast_unschedule();
  RouterThread *old_thread = _thread;
  _thread = _router->master()->thread();
  add_pending(RESCHEDULE);
  old_thread->unlock_tasks();
}

void Task::process_pending(RouterThread *thread)
{
  // must be called with thread->lock held
  if (_thread == thread) {
    if (_pending & RESCHEDULE) {
      _pending &= ~RESCHEDULE;
      if (!scheduled())
        fast_schedule();
    }
  }

  if (_pending)
    add_pending(0);
}

REMOVABLE_INLINE int Task::fast_unschedule()
{
  if (_prev) {
    _next->_prev = _prev;
    _prev->_next = _next;
    _next = _prev = 0;
  }
  return 0;
}

REMOVABLE_INLINE void Task::fast_reschedule()
{
  assert(_thread);
  if (!scheduled()) {
    _prev = _thread->_taskList._prev;
    _next = &_thread->_taskList;
    _thread->_taskList._prev = this;
    _thread->_taskList._next = this;
  }
}

REMOVABLE_INLINE void Task::reschedule()
{
  assert(_thread);
  if (!scheduled())
    true_reschedule();
}

REMOVABLE_INLINE void Task::fast_schedule()
{
    fast_reschedule();
}

<|endoftext|>


<commit_before>#include "BluPrivatePCH.h"

class FBlu : public IBlu
{

	/** IModuleInterface implementation */
	virtual void StartupModule() override
	{

		FString GameDir = FPaths::ConvertRelativePathToFull(FPaths::GameDir() + "BluCache");
		CefString GameDirCef = *GameDir;

		// Setup the default settings for BluManager
		BluManager::settings.windowless_rendering_enabled = true;
		BluManager::settings.no_sandbox = true;
		BluManager::settings.multi_threaded_message_loop = 1;
		BluManager::settings.remote_debugging_port = 7777;

#if PLATFORM_LINUX
		CefString(&BluManager::settings.browser_subprocess_path).FromASCII("./blu_ue4_process");
#endif
#if PLATFORM_WINDOWS
		CefString(&BluManager::settings.browser_subprocess_path).FromASCII("./blu_ue4_process.exe");
#endif
		CefString(&BluManager::settings.cache_path).FromString(GameDirCef);

		CefExecuteProcess(BluManager::main_args, NULL, NULL);
		CefInitialize(BluManager::main_args, BluManager::settings, NULL, NULL);

		UE_LOG(LogBlu, Log, TEXT(" STATUS: Loaded"));
	}

	virtual void ShutdownModule() override
	{
		UE_LOG(LogBlu, Log, TEXT(" STATUS: Shutdown"));
		CefShutdown();
	}

};

IMPLEMENT_MODULE( FBlu, Blu )
DEFINE_LOG_CATEGORY(LogBlu);<commit_msg>Revert "Allow multi-thread message loop"<commit_after>#include "BluPrivatePCH.h"

class FBlu : public IBlu
{

	/** IModuleInterface implementation */
	virtual void StartupModule() override
	{

		FString GameDir = FPaths::ConvertRelativePathToFull(FPaths::GameDir() + "BluCache");
		CefString GameDirCef = *GameDir;

		// Setup the default settings for BluManager
		BluManager::settings.windowless_rendering_enabled = true;
		BluManager::settings.no_sandbox = true;

		BluManager::settings.remote_debugging_port = 7777;

#if PLATFORM_LINUX
		CefString(&BluManager::settings.browser_subprocess_path).FromASCII("./blu_ue4_process");
#endif
#if PLATFORM_WINDOWS
		CefString(&BluManager::settings.browser_subprocess_path).FromASCII("./blu_ue4_process.exe");
#endif
		CefString(&BluManager::settings.cache_path).FromString(GameDirCef);

		CefExecuteProcess(BluManager::main_args, NULL, NULL);
		CefInitialize(BluManager::main_args, BluManager::settings, NULL, NULL);

		UE_LOG(LogBlu, Log, TEXT(" STATUS: Loaded"));
	}

	virtual void ShutdownModule() override
	{
		UE_LOG(LogBlu, Log, TEXT(" STATUS: Shutdown"));
		CefShutdown();
	}

};

IMPLEMENT_MODULE( FBlu, Blu )
DEFINE_LOG_CATEGORY(LogBlu);<|endoftext|>


<commit_before>// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.

#include <vespa/fastos/fastos.h>
#include <vespa/log/log.h>
LOG_SETUP(".proton.metrics.legacy_documentdb_metrics");
#include "legacy_documentdb_metrics.h"
#include <vespa/vespalib/util/stringfmt.h>

using vespalib::asciistream;
using vespalib::make_string;
using metrics::MetricSet;

namespace proton {

using matching::MatchingStats;

LegacyDocumentDBMetrics::IndexMetrics::IndexMetrics(MetricSet *parent)
    : MetricSet("index", "", "Index metrics", parent),
      memoryUsage("memoryusage", "", "Memory usage for memory indexes", this),
      docsInMemory("docsinmemory", "", "Number of documents in memory", this),
      diskUsage("diskusage", "", "Disk usage for disk indexes", this)
{
}

LegacyDocumentDBMetrics::DocstoreMetrics::DocstoreMetrics(MetricSet *parent)
    : MetricSet("docstore", "", "Document store metrics", parent),
      memoryUsage("memoryusage", "", "Memory usage for docstore", this),
      cacheLookups("cachelookups", "", "Number of lookups in summary cache",
                   this),
      hits(0),
      cacheHitRate("cachehitrate", "", "Rate of cache hits in summary cache",
                   this),
      cacheElements("cacheelements", "", "Number of elements in summary cache",
                    this),
      cacheMemoryUsed("cachememoryused", "", "Memory used by summary cache",
                      this)
{
}

void
LegacyDocumentDBMetrics::MatchingMetrics::update(const MatchingStats &stats)
{
    docsMatched.inc(stats.docsMatched());
    docsRanked.inc(stats.docsRanked());
    docsReRanked.inc(stats.docsReRanked());
    queries.inc(stats.queries());
    queryCollateralTime.addValueBatch(stats.queryCollateralTimeAvg(),
                                      stats.queryCollateralTimeCount());
    queryLatency.addValueBatch(stats.queryLatencyAvg(),
                               stats.queryLatencyCount());
}

LegacyDocumentDBMetrics::MatchingMetrics::MatchingMetrics(MetricSet *parent)
    : MetricSet("matching", "", "Matching metrics", parent),
      docsMatched("docsmatched", "", "Number of documents matched", this),
      docsRanked("docsranked", "", "Number of documents ranked (first phase)", this),
      docsReRanked("docsreranked", "",
                   "Number of documents re-ranked (second phase)", this),
      queries("queries", "", "Number of queries executed", this),
      queryCollateralTime("querycollateraltime", "", "Average time spent setting up and tearing down queries", this),
      queryLatency("querylatency", "", "Average latency when matching a query", this)
{
}

LegacyDocumentDBMetrics::MatchingMetrics::RankProfileMetrics::RankProfileMetrics(
        const std::string &name, size_t numDocIdPartitions, MetricSet *parent)
    : MetricSet(name, "", "Rank profile metrics", parent),
      queries("queries", "", "Number of queries executed", this),
      limited_queries("limitedqueries", "", "Number of queries limited in match phase", this),
      matchTime("match_time", "", "Average time for matching a query", this),
      groupingTime("grouping_time", "", "Average time spent on grouping", this),
      rerankTime("rerank_time", "", "Average time spent on 2nd phase ranking", this)
{
    for (size_t i=0; i < numDocIdPartitions; i++) {
        vespalib::string s(make_string("docid_part%02ld", i));
        partitions.push_back(DocIdPartition::LP(new DocIdPartition(s, this)));
    }
}

LegacyDocumentDBMetrics::MatchingMetrics::RankProfileMetrics::DocIdPartition::DocIdPartition(const std::string &name, MetricSet *parent) :
    MetricSet(name, "", "DocId Partition profile metrics", parent),
    docsMatched("docsmatched", "", "Number of documents matched", this),
    docsRanked("docsranked", "", "Number of documents ranked (first phase)", this),
    docsReRanked("docsreranked", "",
                 "Number of documents re-ranked (second phase)", this),
    active_time("activetime", "", "Time spent doing actual work", this),
    wait_time("waittime", "", "Time spent waiting for other external threads and resources", this)
{
}

void
LegacyDocumentDBMetrics::MatchingMetrics::RankProfileMetrics::DocIdPartition::update(const MatchingStats::Partition &stats)
{
    docsMatched.inc(stats.docsMatched());
    docsRanked.inc(stats.docsRanked());
    docsReRanked.inc(stats.docsReRanked());
    active_time.addValueBatch(stats.active_time_avg(), stats.active_time_count());
    wait_time.addValueBatch(stats.wait_time_avg(), stats.wait_time_count());
}

void
LegacyDocumentDBMetrics::MatchingMetrics::RankProfileMetrics::update(const MatchingStats &stats)
{
    queries.inc(stats.queries());
    limited_queries.inc(stats.limited_queries());
    matchTime.addValueBatch(stats.matchTimeAvg(), stats.matchTimeCount());
    groupingTime.addValueBatch(stats.groupingTimeAvg(),
                               stats.groupingTimeCount());
    rerankTime.addValueBatch(stats.rerankTimeAvg(), stats.rerankTimeCount());
    if (stats.getNumPartitions() > 0) {
        if (stats.getNumPartitions() == partitions.size()) {
            for (size_t i(0), m(stats.getNumPartitions()); i < m; i++) {
                DocIdPartition & partition(*partitions[i]);
                const MatchingStats::Partition & s(stats.getPartition(i));
                partition.update(s);
            }
        } else {
            vespalib::string msg(make_string("Num partitions use '%ld' is not equal to number of partitions '%ld' configured.",
                                             stats.getNumPartitions(),
                                             partitions.size()));
            throw vespalib::IllegalStateException(msg, VESPA_STRLOC);
        }
    }
}

LegacyDocumentDBMetrics::SubDBMetrics::DocumentMetaStoreMetrics::
DocumentMetaStoreMetrics(MetricSet *parent)
    : MetricSet("docmetastore", "", "Document meta store metrics", parent),
      lidLimit("lidlimit", "", "The size of the allocated lid space", this),
      usedLids("usedlids", "", "The number of lids used", this),
      lowestFreeLid("lowestfreelid", "", "The lowest free lid", this),
      highestUsedLid("highestusedlid", "", "The highest used lid", this),
      lidBloatFactor("lidbloatfactor", "", "The bloat factor of this lid space, indicating the total amount of holes in the allocated lid space "
              "((lidlimit - usedlids) / lidlimit)", this),
      lidFragmentationFactor("lid_fragmentation_factor", "",
              "The fragmentation factor of this lid space, indicating the amount of holes in the currently used part of the lid space "
              "((highestusedlid - usedlids) / highestusedlid)", this)
{
}

LegacyDocumentDBMetrics::SubDBMetrics::SubDBMetrics(const vespalib::string &name,
                                              MetricSet *parent)
    : MetricSet(name, "", "Sub database metrics", parent),
      attributes(this),
      docMetaStore(this)
{
}

LegacyDocumentDBMetrics::LegacyDocumentDBMetrics(const std::string &docTypeName, size_t maxNumThreads)
    : MetricSet(make_string("%s", docTypeName.c_str()), "", "Document DB Metrics", 0),
      index(this),
      attributes(this),
      docstore(this),
      matching(this),
      executor("executor", this),
      indexExecutor("indexexecutor", this),
      feed(this),
      sessionManager(this),
      ready("ready", this),
      notReady("notready", this),
      removed("removed", this),
      memoryUsage("memoryusage", "", "Memory usage for this Document DB",
                  this),
      numDocs("numdocs", "",
              "Number of ready/indexed documents in this Document DB (aka number of documents in the 'ready' sub db)", this),
      numActiveDocs("numactivedocs", "",
                    "Number of active/searchable documents in this Document DB (aka number of active/searchable documents in the 'ready' sub db)", this),
      numIndexedDocs("numindexeddocs", "",
                     "Number of ready/indexed documents in this Document DB (aka number of documents in the 'ready' sub db)", this),
      numStoredDocs("numstoreddocs", "",
                    "Total number of documents stored in this Document DB (aka number of documents in the 'ready' and 'notready' sub dbs)", this),
      numRemovedDocs("numremoveddocs", "",
                    "Number of removed documents in this Document DB (aka number of documents in the 'removed' sub db)", this),
      numBadConfigs("numBadConfigs", "",
                    "Number of bad configs for this Document DB", this),
      _maxNumThreads(maxNumThreads)
{
    memoryUsage.addMetricToSum(index.memoryUsage);
    memoryUsage.addMetricToSum(attributes.memoryUsage);
    memoryUsage.addMetricToSum(docstore.memoryUsage);
}

} // namespace proton
<commit_msg>Allow to update metrics even if you have actually used less partitions.<commit_after>// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.

#include <vespa/fastos/fastos.h>
#include <vespa/log/log.h>
LOG_SETUP(".proton.metrics.legacy_documentdb_metrics");
#include "legacy_documentdb_metrics.h"
#include <vespa/vespalib/util/stringfmt.h>

using vespalib::asciistream;
using vespalib::make_string;
using metrics::MetricSet;

namespace proton {

using matching::MatchingStats;

LegacyDocumentDBMetrics::IndexMetrics::IndexMetrics(MetricSet *parent)
    : MetricSet("index", "", "Index metrics", parent),
      memoryUsage("memoryusage", "", "Memory usage for memory indexes", this),
      docsInMemory("docsinmemory", "", "Number of documents in memory", this),
      diskUsage("diskusage", "", "Disk usage for disk indexes", this)
{
}

LegacyDocumentDBMetrics::DocstoreMetrics::DocstoreMetrics(MetricSet *parent)
    : MetricSet("docstore", "", "Document store metrics", parent),
      memoryUsage("memoryusage", "", "Memory usage for docstore", this),
      cacheLookups("cachelookups", "", "Number of lookups in summary cache",
                   this),
      hits(0),
      cacheHitRate("cachehitrate", "", "Rate of cache hits in summary cache",
                   this),
      cacheElements("cacheelements", "", "Number of elements in summary cache",
                    this),
      cacheMemoryUsed("cachememoryused", "", "Memory used by summary cache",
                      this)
{
}

void
LegacyDocumentDBMetrics::MatchingMetrics::update(const MatchingStats &stats)
{
    docsMatched.inc(stats.docsMatched());
    docsRanked.inc(stats.docsRanked());
    docsReRanked.inc(stats.docsReRanked());
    queries.inc(stats.queries());
    queryCollateralTime.addValueBatch(stats.queryCollateralTimeAvg(),
                                      stats.queryCollateralTimeCount());
    queryLatency.addValueBatch(stats.queryLatencyAvg(),
                               stats.queryLatencyCount());
}

LegacyDocumentDBMetrics::MatchingMetrics::MatchingMetrics(MetricSet *parent)
    : MetricSet("matching", "", "Matching metrics", parent),
      docsMatched("docsmatched", "", "Number of documents matched", this),
      docsRanked("docsranked", "", "Number of documents ranked (first phase)", this),
      docsReRanked("docsreranked", "",
                   "Number of documents re-ranked (second phase)", this),
      queries("queries", "", "Number of queries executed", this),
      queryCollateralTime("querycollateraltime", "", "Average time spent setting up and tearing down queries", this),
      queryLatency("querylatency", "", "Average latency when matching a query", this)
{
}

LegacyDocumentDBMetrics::MatchingMetrics::RankProfileMetrics::RankProfileMetrics(
        const std::string &name, size_t numDocIdPartitions, MetricSet *parent)
    : MetricSet(name, "", "Rank profile metrics", parent),
      queries("queries", "", "Number of queries executed", this),
      limited_queries("limitedqueries", "", "Number of queries limited in match phase", this),
      matchTime("match_time", "", "Average time for matching a query", this),
      groupingTime("grouping_time", "", "Average time spent on grouping", this),
      rerankTime("rerank_time", "", "Average time spent on 2nd phase ranking", this)
{
    for (size_t i=0; i < numDocIdPartitions; i++) {
        vespalib::string s(make_string("docid_part%02ld", i));
        partitions.push_back(DocIdPartition::LP(new DocIdPartition(s, this)));
    }
}

LegacyDocumentDBMetrics::MatchingMetrics::RankProfileMetrics::DocIdPartition::DocIdPartition(const std::string &name, MetricSet *parent) :
    MetricSet(name, "", "DocId Partition profile metrics", parent),
    docsMatched("docsmatched", "", "Number of documents matched", this),
    docsRanked("docsranked", "", "Number of documents ranked (first phase)", this),
    docsReRanked("docsreranked", "",
                 "Number of documents re-ranked (second phase)", this),
    active_time("activetime", "", "Time spent doing actual work", this),
    wait_time("waittime", "", "Time spent waiting for other external threads and resources", this)
{
}

void
LegacyDocumentDBMetrics::MatchingMetrics::RankProfileMetrics::DocIdPartition::update(const MatchingStats::Partition &stats)
{
    docsMatched.inc(stats.docsMatched());
    docsRanked.inc(stats.docsRanked());
    docsReRanked.inc(stats.docsReRanked());
    active_time.addValueBatch(stats.active_time_avg(), stats.active_time_count());
    wait_time.addValueBatch(stats.wait_time_avg(), stats.wait_time_count());
}

void
LegacyDocumentDBMetrics::MatchingMetrics::RankProfileMetrics::update(const MatchingStats &stats)
{
    queries.inc(stats.queries());
    limited_queries.inc(stats.limited_queries());
    matchTime.addValueBatch(stats.matchTimeAvg(), stats.matchTimeCount());
    groupingTime.addValueBatch(stats.groupingTimeAvg(),
                               stats.groupingTimeCount());
    rerankTime.addValueBatch(stats.rerankTimeAvg(), stats.rerankTimeCount());
    if (stats.getNumPartitions() > 0) {
        if (stats.getNumPartitions() <= partitions.size()) {
            for (size_t i(0), m(stats.getNumPartitions()); i < m; i++) {
                DocIdPartition & partition(*partitions[i]);
                const MatchingStats::Partition & s(stats.getPartition(i));
                partition.update(s);
            }
        } else {
            vespalib::string msg(make_string("Num partitions used '%ld' is larger than number of partitions '%ld' configured.",
                                             stats.getNumPartitions(),
                                             partitions.size()));
            throw vespalib::IllegalStateException(msg, VESPA_STRLOC);
        }
    }
}

LegacyDocumentDBMetrics::SubDBMetrics::DocumentMetaStoreMetrics::
DocumentMetaStoreMetrics(MetricSet *parent)
    : MetricSet("docmetastore", "", "Document meta store metrics", parent),
      lidLimit("lidlimit", "", "The size of the allocated lid space", this),
      usedLids("usedlids", "", "The number of lids used", this),
      lowestFreeLid("lowestfreelid", "", "The lowest free lid", this),
      highestUsedLid("highestusedlid", "", "The highest used lid", this),
      lidBloatFactor("lidbloatfactor", "", "The bloat factor of this lid space, indicating the total amount of holes in the allocated lid space "
              "((lidlimit - usedlids) / lidlimit)", this),
      lidFragmentationFactor("lid_fragmentation_factor", "",
              "The fragmentation factor of this lid space, indicating the amount of holes in the currently used part of the lid space "
              "((highestusedlid - usedlids) / highestusedlid)", this)
{
}

LegacyDocumentDBMetrics::SubDBMetrics::SubDBMetrics(const vespalib::string &name,
                                              MetricSet *parent)
    : MetricSet(name, "", "Sub database metrics", parent),
      attributes(this),
      docMetaStore(this)
{
}

LegacyDocumentDBMetrics::LegacyDocumentDBMetrics(const std::string &docTypeName, size_t maxNumThreads)
    : MetricSet(make_string("%s", docTypeName.c_str()), "", "Document DB Metrics", 0),
      index(this),
      attributes(this),
      docstore(this),
      matching(this),
      executor("executor", this),
      indexExecutor("indexexecutor", this),
      feed(this),
      sessionManager(this),
      ready("ready", this),
      notReady("notready", this),
      removed("removed", this),
      memoryUsage("memoryusage", "", "Memory usage for this Document DB",
                  this),
      numDocs("numdocs", "",
              "Number of ready/indexed documents in this Document DB (aka number of documents in the 'ready' sub db)", this),
      numActiveDocs("numactivedocs", "",
                    "Number of active/searchable documents in this Document DB (aka number of active/searchable documents in the 'ready' sub db)", this),
      numIndexedDocs("numindexeddocs", "",
                     "Number of ready/indexed documents in this Document DB (aka number of documents in the 'ready' sub db)", this),
      numStoredDocs("numstoreddocs", "",
                    "Total number of documents stored in this Document DB (aka number of documents in the 'ready' and 'notready' sub dbs)", this),
      numRemovedDocs("numremoveddocs", "",
                    "Number of removed documents in this Document DB (aka number of documents in the 'removed' sub db)", this),
      numBadConfigs("numBadConfigs", "",
                    "Number of bad configs for this Document DB", this),
      _maxNumThreads(maxNumThreads)
{
    memoryUsage.addMetricToSum(index.memoryUsage);
    memoryUsage.addMetricToSum(attributes.memoryUsage);
    memoryUsage.addMetricToSum(docstore.memoryUsage);
}

} // namespace proton
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: CharacterPropertyItemConverter.hxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: bm $ $Date: 2003-11-25 13:07:19 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  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., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2003 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
#ifndef CHART_CHARACTERPROPERTYITEMCONVERTER_HXX
#define CHART_CHARACTERPROPERTYITEMCONVERTER_HXX

#include "ItemConverter.hxx"

#ifndef _COM_SUN_STAR_UNO_ANY_HXX_
#include <com/sun/star/uno/Any.hxx>
#endif
#ifndef _COM_SUN_STAR_BEANS_PROPERTYSTATE_HPP_
#include <com/sun/star/beans/PropertyState.hpp>
#endif
#ifndef _COM_SUN_STAR_AWT_SIZE_HPP_
#include <com/sun/star/awt/Size.hpp>
#endif

#include <memory>

namespace chart
{
namespace wrapper
{

class CharacterPropertyItemConverter :
        public ::comphelper::ItemConverter
{
public:
    CharacterPropertyItemConverter(
        const ::com::sun::star::uno::Reference<
        ::com::sun::star::beans::XPropertySet > & rPropertySet,
        SfxItemPool& rItemPool,
        ::std::auto_ptr< ::com::sun::star::awt::Size > pRefSize =
            ::std::auto_ptr< ::com::sun::star::awt::Size >(),
        const ::rtl::OUString & rRefSizePropertyName =
            ::rtl::OUString() );
    virtual ~CharacterPropertyItemConverter();

protected:
    virtual const USHORT * GetWhichPairs() const;
    virtual bool GetItemPropertyName( USHORT nWhichId, ::rtl::OUString & rOutName ) const;

    virtual void FillSpecialItem( USHORT nWhichId, SfxItemSet & rOutItemSet ) const
        throw( ::com::sun::star::uno::Exception );
    virtual bool ApplySpecialItem( USHORT nWhichId, const SfxItemSet & rItemSet )
        throw( ::com::sun::star::uno::Exception );

private:
    ::std::auto_ptr< ::com::sun::star::awt::Size > m_pRefSize;
    ::rtl::OUString                                m_aRefSizePropertyName;
};

} //  namespace wrapper
} //  namespace chart

// CHART_CHARACTERPROPERTYITEMCONVERTER_HXX
#endif
<commit_msg>INTEGRATION: CWS ooo19126 (1.5.110); FILE MERGED 2005/09/05 18:42:31 rt 1.5.110.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: CharacterPropertyItemConverter.hxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 00:21:11 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    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., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#ifndef CHART_CHARACTERPROPERTYITEMCONVERTER_HXX
#define CHART_CHARACTERPROPERTYITEMCONVERTER_HXX

#include "ItemConverter.hxx"

#ifndef _COM_SUN_STAR_UNO_ANY_HXX_
#include <com/sun/star/uno/Any.hxx>
#endif
#ifndef _COM_SUN_STAR_BEANS_PROPERTYSTATE_HPP_
#include <com/sun/star/beans/PropertyState.hpp>
#endif
#ifndef _COM_SUN_STAR_AWT_SIZE_HPP_
#include <com/sun/star/awt/Size.hpp>
#endif

#include <memory>

namespace chart
{
namespace wrapper
{

class CharacterPropertyItemConverter :
        public ::comphelper::ItemConverter
{
public:
    CharacterPropertyItemConverter(
        const ::com::sun::star::uno::Reference<
        ::com::sun::star::beans::XPropertySet > & rPropertySet,
        SfxItemPool& rItemPool,
        ::std::auto_ptr< ::com::sun::star::awt::Size > pRefSize =
            ::std::auto_ptr< ::com::sun::star::awt::Size >(),
        const ::rtl::OUString & rRefSizePropertyName =
            ::rtl::OUString() );
    virtual ~CharacterPropertyItemConverter();

protected:
    virtual const USHORT * GetWhichPairs() const;
    virtual bool GetItemPropertyName( USHORT nWhichId, ::rtl::OUString & rOutName ) const;

    virtual void FillSpecialItem( USHORT nWhichId, SfxItemSet & rOutItemSet ) const
        throw( ::com::sun::star::uno::Exception );
    virtual bool ApplySpecialItem( USHORT nWhichId, const SfxItemSet & rItemSet )
        throw( ::com::sun::star::uno::Exception );

private:
    ::std::auto_ptr< ::com::sun::star::awt::Size > m_pRefSize;
    ::rtl::OUString                                m_aRefSizePropertyName;
};

} //  namespace wrapper
} //  namespace chart

// CHART_CHARACTERPROPERTYITEMCONVERTER_HXX
#endif
<|endoftext|>