<commit_before>/***************************************************************
 *
 * Copyright (C) 1990-2007, Condor Team, Computer Sciences Department,
 * University of Wisconsin-Madison, WI.
 *
 * 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 "condor_common.h"
#include "condor_classad.h"
#include "condor_config.h"
#include "condor_qmgr.h"
#include "match_prefix.h"
#include "sig_install.h"
#include "get_daemon_name.h"
#include "condor_attributes.h"
#include "condor_distribution.h"
#include "daemon.h"
#include "dc_schedd.h"
#include "MyString.h"

void
usage(char name[])
{
	fprintf(stderr, "Usage: %s [-n schedd-name] [-pool pool-name] { cluster | cluster.proc | owner | -constraint constraint } attribute-name attribute-value ...\n", name);
	exit(1);
}

bool
ProtectedAttribute(char attr[])
{
	return (strcmp(attr, ATTR_OWNER) == 0) ||
		(strcmp(attr, ATTR_CLUSTER_ID) == 0) ||
		(strcmp(attr, ATTR_PROC_ID) == 0) ||
		(strcmp(attr, ATTR_MY_TYPE) == 0) ||
		(strcmp(attr, ATTR_TARGET_TYPE) == 0) ||
		(strcmp(attr, ATTR_JOB_STATUS) == 0);
}

int
main(int argc, char *argv[])
{
	MyString DaemonName;
	MyString constraint;
	Qmgr_connection *q;
	int nextarg = 1, cluster, proc;
	bool UseConstraint = false;
	MyString schedd_name;
	MyString pool_name;

	myDistro->Init( argc, argv );
	config();

#if !defined(WIN32)
	install_sig_handler(SIGPIPE, SIG_IGN );
#endif

	if (argc < 2) {
		usage(argv[0]);
	}

	// if it is present, it must be first
	if (argv[1][0] == '-' && argv[1][1] == 'n') {
		// use the given name as the schedd name to connect to
		if (argc < 3) {
			fprintf(stderr, "%s: -n requires another argument\n",
					argv[0]);
			exit(1);
		}
		schedd_name = argv[2];
		nextarg = 3;
	}

	// if it is present, it must be just after -n flag
	if (argv[3][0] == '-' && argv[3][1] == 'p') {
		if (argc < 5) {
			fprintf(stderr, "%s: -pool requires another argument\n",
					argv[0]);
			exit(1);
		}
		pool_name = argv[4];
		nextarg = 5;
	}

	DCSchedd schedd(schedd_name.GetCStr(), pool_name.GetCStr());
	if ( schedd.locate() == false ) {
		if (schedd_name == "") {
			fprintf( stderr, "%s: ERROR: Can't find address of local schedd\n",
				argv[0] );
			exit(1);
		}

		if (pool_name == "") {
			fprintf( stderr, "%s: No such schedd named %s in local pool\n",
				argv[0], schedd_name.Value() );
		} else {
			fprintf( stderr, "%s: No such schedd named %s in "
				"pool %s\n",
				argv[0], schedd_name.Value(), pool_name.Value() );
		}
		exit(1);
	}

	// Open job queue
	q = ConnectQ( DaemonName.Value() );
	if( !q ) {
		fprintf( stderr, "Failed to connect to queue manager %s\n",
				 DaemonName.Value() );
		exit(1);
	}

	if (argc <= nextarg) {
		usage(argv[0]);
	}

	if (match_prefix(argv[nextarg], "-constraint")) {
		nextarg++;
		if (argc <= nextarg) {
			usage(argv[0]);
		}
		constraint = argv[nextarg];
		nextarg++;
		UseConstraint = true;
	} else if (isdigit(argv[nextarg][0])) {
		char *tmp;
		cluster = strtol(argv[nextarg], &tmp, 10);
		if (cluster <= 0) {
			fprintf( stderr, "Invalid cluster # from %s.\n", argv[nextarg]);
			exit(1);
		}
		if (*tmp == '.') {
			proc = strtol(tmp + 1, &tmp, 10);
			if (cluster <= 0) {
				fprintf( stderr, "Invalid proc # from %s.\n", argv[nextarg]);
				exit(1);
			}
			UseConstraint = false;
		} else {
			constraint.sprintf("(%s == %d)", ATTR_CLUSTER_ID, cluster);
			UseConstraint = true;
		}
		nextarg++;
	} else {
		constraint.sprintf("(%s == \"%s\")", ATTR_OWNER, argv[nextarg]);
		nextarg++;
		UseConstraint = true;
	}

	if (argc <= nextarg) {
		usage(argv[0]);
	}

	for (; nextarg < argc; nextarg += 2) {
		if (argc <= nextarg+1) {
			usage(argv[0]);
		}
		if (ProtectedAttribute(argv[nextarg])) {
			fprintf(stderr, "Update of attribute \"%s\" is not allowed.\n",
					argv[nextarg]);
			exit(1);
		}
		if (UseConstraint) {
			if (SetAttributeByConstraint(constraint.Value(), argv[nextarg],
										 argv[nextarg+1]) < 0) {
				fprintf(stderr,
						"Failed to set attribute \"%s\" by constraint: %s\n",
						argv[nextarg], constraint.Value());
				exit(1);
			}
		} else {
			if (SetAttribute(cluster, proc, argv[nextarg],
							 argv[nextarg+1]) < 0) {
				fprintf(stderr,
						"Failed to set attribute \"%s\" for job %d.%d.\n",
						argv[nextarg], cluster, proc);
				exit(1);
			}
		}
		printf("Set attribute \"%s\".\n", argv[nextarg]);
	}

	if (!DisconnectQ(q)) {
		fprintf(stderr,
				"Queue transaction failed.  No attributes were set.\n");
		exit(1);
	}

	return 0;
}

#include "daemon_core_stubs.h"
<commit_msg>Fix seg faulting argv processing in qedit.C<commit_after>/***************************************************************
 *
 * Copyright (C) 1990-2007, Condor Team, Computer Sciences Department,
 * University of Wisconsin-Madison, WI.
 *
 * 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 "condor_common.h"
#include "condor_classad.h"
#include "condor_config.h"
#include "condor_qmgr.h"
#include "match_prefix.h"
#include "sig_install.h"
#include "get_daemon_name.h"
#include "condor_attributes.h"
#include "condor_distribution.h"
#include "daemon.h"
#include "dc_schedd.h"
#include "MyString.h"

void
usage(char name[])
{
	fprintf(stderr, "Usage: %s [-n schedd-name] [-pool pool-name] { cluster | cluster.proc | owner | -constraint constraint } attribute-name attribute-value ...\n", name);
	exit(1);
}

bool
ProtectedAttribute(char attr[])
{
	return (strcmp(attr, ATTR_OWNER) == 0) ||
		(strcmp(attr, ATTR_CLUSTER_ID) == 0) ||
		(strcmp(attr, ATTR_PROC_ID) == 0) ||
		(strcmp(attr, ATTR_MY_TYPE) == 0) ||
		(strcmp(attr, ATTR_TARGET_TYPE) == 0) ||
		(strcmp(attr, ATTR_JOB_STATUS) == 0);
}

int
main(int argc, char *argv[])
{
	MyString DaemonName;
	MyString constraint;
	Qmgr_connection *q;
	int nextarg = 1, cluster, proc;
	bool UseConstraint = false;
	MyString schedd_name;
	MyString pool_name;

	myDistro->Init( argc, argv );
	config();

#if !defined(WIN32)
	install_sig_handler(SIGPIPE, SIG_IGN );
#endif

	if (argc < 2) {
		usage(argv[0]);
	}

	// if it is present, it must be first
	if (argv[nextarg][0] == '-' && argv[nextarg][1] == 'n') {
		nextarg++;
		// use the given name as the schedd name to connect to
		if (argc <= nextarg) {
			fprintf(stderr, "%s: -n requires another argument\n",
					argv[0]);
			exit(1);
		}
		schedd_name = argv[nextarg];
		nextarg++;
	}

	if (argc <= nextarg) {
		usage(argv[0]);
	}

	// if it is present, it must be just after -n flag
	if (argv[nextarg][0] == '-' && argv[nextarg][1] == 'p') {
		nextarg++;
		if (argc <= nextarg) {
			fprintf(stderr, "%s: -pool requires another argument\n",
					argv[0]);
			exit(1);
		}
		pool_name = argv[nextarg];
		nextarg++;
	}

	DCSchedd schedd(schedd_name.GetCStr(), pool_name.GetCStr());
	if ( schedd.locate() == false ) {
		if (schedd_name == "") {
			fprintf( stderr, "%s: ERROR: Can't find address of local schedd\n",
				argv[0] );
			exit(1);
		}

		if (pool_name == "") {
			fprintf( stderr, "%s: No such schedd named %s in local pool\n",
				argv[0], schedd_name.Value() );
		} else {
			fprintf( stderr, "%s: No such schedd named %s in "
				"pool %s\n",
				argv[0], schedd_name.Value(), pool_name.Value() );
		}
		exit(1);
	}

	// Open job queue
	q = ConnectQ( DaemonName.Value() );
	if( !q ) {
		fprintf( stderr, "Failed to connect to queue manager %s\n",
				 DaemonName.Value() );
		exit(1);
	}

	if (argc <= nextarg) {
		usage(argv[0]);
	}

	if (match_prefix(argv[nextarg], "-constraint")) {
		nextarg++;
		if (argc <= nextarg) {
			usage(argv[0]);
		}
		constraint = argv[nextarg];
		nextarg++;
		UseConstraint = true;
	} else if (isdigit(argv[nextarg][0])) {
		char *tmp;
		cluster = strtol(argv[nextarg], &tmp, 10);
		if (cluster <= 0) {
			fprintf( stderr, "Invalid cluster # from %s.\n", argv[nextarg]);
			exit(1);
		}
		if (*tmp == '.') {
			proc = strtol(tmp + 1, &tmp, 10);
			if (cluster <= 0) {
				fprintf( stderr, "Invalid proc # from %s.\n", argv[nextarg]);
				exit(1);
			}
			UseConstraint = false;
		} else {
			constraint.sprintf("(%s == %d)", ATTR_CLUSTER_ID, cluster);
			UseConstraint = true;
		}
		nextarg++;
	} else {
		constraint.sprintf("(%s == \"%s\")", ATTR_OWNER, argv[nextarg]);
		nextarg++;
		UseConstraint = true;
	}

	if (argc <= nextarg) {
		usage(argv[0]);
	}

	for (; nextarg < argc; nextarg += 2) {
		if (argc <= nextarg+1) {
			usage(argv[0]);
		}
		if (ProtectedAttribute(argv[nextarg])) {
			fprintf(stderr, "Update of attribute \"%s\" is not allowed.\n",
					argv[nextarg]);
			exit(1);
		}
		if (UseConstraint) {
			if (SetAttributeByConstraint(constraint.Value(), argv[nextarg],
										 argv[nextarg+1]) < 0) {
				fprintf(stderr,
						"Failed to set attribute \"%s\" by constraint: %s\n",
						argv[nextarg], constraint.Value());
				exit(1);
			}
		} else {
			if (SetAttribute(cluster, proc, argv[nextarg],
							 argv[nextarg+1]) < 0) {
				fprintf(stderr,
						"Failed to set attribute \"%s\" for job %d.%d.\n",
						argv[nextarg], cluster, proc);
				exit(1);
			}
		}
		printf("Set attribute \"%s\".\n", argv[nextarg]);
	}

	if (!DisconnectQ(q)) {
		fprintf(stderr,
				"Queue transaction failed.  No attributes were set.\n");
		exit(1);
	}

	return 0;
}

#include "daemon_core_stubs.h"
<|endoftext|>


<commit_before>/***************************************************************
 *
 * Copyright (C) 1990-2007, Condor Team, Computer Sciences Department,
 * University of Wisconsin-Madison, WI.
 *
 * 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.
 *
 ***************************************************************/

/*
   This is some wisdom from Cygnus's web page.  If you just try to use
   the "stringify" operator on a preprocessor directive, you'd get
   "PLATFORM", not "Intel Linux" (or whatever the value of PLATFORM
   is).  That's because the stringify operator is a special case, and
   the preprocessor isn't allowed to expand things that are passed to
   it.  However, by defining two layers of macros, you get the right
   behavior, since the first pass converts:

   xstr(PLATFORM) -> str(Intel Linux)

   and the next pass gives:

   str(Intel Linux) -> "Intel Linux"

   This is exactly what we want, so we use it.  -Derek Wright and Jeff
   Ballard, 12/2/99

   Also, because the NT build system is totally different, we have to
   define the correct platform string right in here. :( -Derek 12/3/99
*/

#define xstr(s) str(s)
#define str(s) #s

#if defined(WIN32)
#define PLATFORM INTEL-WINNT50
#endif

/* Via configure, one may have specified a particular buildid string to use
	in the version string. So honor that request here. */
#if defined(BUILDID)
#define BUILDIDSTR " BuildID: " xstr(BUILDID)
#else
#define BUILDIDSTR ""
#endif

/* Here is the version string - update before a public release */
/* --- IMPORTANT!  THE FORMAT OF THE VERSION STRING IS VERY STRICT
   BECAUSE IT IS PARSED AT RUNTIME.  DO NOT ALTER THE FORMAT OR ENTER
   ANYTHING EXTRA BEFORE THE DATE.  IF YOU WISH TO ADD EXTRA INFORMATION,
   DO SO _AFTER_ THE BUILDIDSTR AND BEFORE THE TRAILING '$' CHARACTER.
   EXAMPLES:
       $CondorVersion: 6.9.5 " __DATE__ BUILDIDSTR " WinNTPreview $ [OK]
	   $CondorVersion: 6.9.5 WinNTPreview " __DATE__ BUILDIDSTR " $ [WRONG!!!]
   Any questions?  See Todd or Derek.  Note: if you mess it up, DaemonCore
   will EXCEPT at startup time.
*/

static char* CondorVersionString = "$CondorVersion: 7.0.5 " __DATE__ BUILDIDSTR " PRE-RELEASE-UWCS $";

/* Here is the platform string.  You don't need to edit this */
static char* CondorPlatformString = "$CondorPlatform: " xstr(PLATFORM) " $";

extern "C" {

const char*
CondorVersion( void )
{
	return CondorVersionString;
}

const char*
CondorPlatform( void )
{
	return CondorPlatformString;
}

} /* extern "C" */

<commit_msg>updated version string for 7.0.6<commit_after>/***************************************************************
 *
 * Copyright (C) 1990-2007, Condor Team, Computer Sciences Department,
 * University of Wisconsin-Madison, WI.
 *
 * 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.
 *
 ***************************************************************/

/*
   This is some wisdom from Cygnus's web page.  If you just try to use
   the "stringify" operator on a preprocessor directive, you'd get
   "PLATFORM", not "Intel Linux" (or whatever the value of PLATFORM
   is).  That's because the stringify operator is a special case, and
   the preprocessor isn't allowed to expand things that are passed to
   it.  However, by defining two layers of macros, you get the right
   behavior, since the first pass converts:

   xstr(PLATFORM) -> str(Intel Linux)

   and the next pass gives:

   str(Intel Linux) -> "Intel Linux"

   This is exactly what we want, so we use it.  -Derek Wright and Jeff
   Ballard, 12/2/99

   Also, because the NT build system is totally different, we have to
   define the correct platform string right in here. :( -Derek 12/3/99
*/

#define xstr(s) str(s)
#define str(s) #s

#if defined(WIN32)
#define PLATFORM INTEL-WINNT50
#endif

/* Via configure, one may have specified a particular buildid string to use
	in the version string. So honor that request here. */
#if defined(BUILDID)
#define BUILDIDSTR " BuildID: " xstr(BUILDID)
#else
#define BUILDIDSTR ""
#endif

/* Here is the version string - update before a public release */
/* --- IMPORTANT!  THE FORMAT OF THE VERSION STRING IS VERY STRICT
   BECAUSE IT IS PARSED AT RUNTIME.  DO NOT ALTER THE FORMAT OR ENTER
   ANYTHING EXTRA BEFORE THE DATE.  IF YOU WISH TO ADD EXTRA INFORMATION,
   DO SO _AFTER_ THE BUILDIDSTR AND BEFORE THE TRAILING '$' CHARACTER.
   EXAMPLES:
       $CondorVersion: 6.9.5 " __DATE__ BUILDIDSTR " WinNTPreview $ [OK]
	   $CondorVersion: 6.9.5 WinNTPreview " __DATE__ BUILDIDSTR " $ [WRONG!!!]
   Any questions?  See Todd or Derek.  Note: if you mess it up, DaemonCore
   will EXCEPT at startup time.
*/

static char* CondorVersionString = "$CondorVersion: 7.0.6 " __DATE__ BUILDIDSTR " PRE-RELEASE-UWCS $";

/* Here is the platform string.  You don't need to edit this */
static char* CondorPlatformString = "$CondorPlatform: " xstr(PLATFORM) " $";

extern "C" {

const char*
CondorVersion( void )
{
	return CondorVersionString;
}

const char*
CondorPlatform( void )
{
	return CondorPlatformString;
}

} /* extern "C" */

<|endoftext|>


<commit_before>/***************************Copyright-DO-NOT-REMOVE-THIS-LINE**
  *
  * Condor Software Copyright Notice
  * Copyright (C) 1990-2006, Condor Team, Computer Sciences Department,
  * University of Wisconsin-Madison, WI.
  *
  * This source code is covered by the Condor Public License, which can
  * be found in the accompanying LICENSE.TXT file, or online at
  * www.condorproject.org.
  *
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  * AND THE UNIVERSITY OF WISCONSIN-MADISON "AS IS" AND ANY EXPRESS OR
  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  * WARRANTIES OF MERCHANTABILITY, OF SATISFACTORY QUALITY, AND FITNESS
  * FOR A PARTICULAR PURPOSE OR USE ARE DISCLAIMED. THE COPYRIGHT
  * HOLDERS AND CONTRIBUTORS AND THE UNIVERSITY OF WISCONSIN-MADISON
  * MAKE NO MAKE NO REPRESENTATION THAT THE SOFTWARE, MODIFICATIONS,
  * ENHANCEMENTS OR DERIVATIVE WORKS THEREOF, WILL NOT INFRINGE ANY
  * PATENT, COPYRIGHT, TRADEMARK, TRADE SECRET OR OTHER PROPRIETARY
  * RIGHT.
  *
  ****************************Copyright-DO-NOT-REMOVE-THIS-LINE**/

/* Here is the version string - update before a public release */
/* --- IMPORTANT!  THE FORMAT OF THE VERSION STRING IS VERY STRICT
   BECAUSE IT IS PARSED AT RUNTIME.  DO NOT ALTER THE FORMAT OR ENTER
   ANYTHING EXTRA BEFORE THE DATE.  IF YOU WISH TO ADD EXTRA INFORMATION,
   DO SO _AFTER_ THE DATE AND BEFORE THE TRAILING '$' CHARACTER.
   EXAMPLES:
       $CondorVersion: 6.1.11 " __DATE__ " WinNTPreview $    [OK]
	   $CondorVersion: 6.1.11 WinNTPreview " __DATE__ " $	 [WRONG!!!]
   Any questions?  See Todd or Derek.  Note: if you mess it up, DaemonCore
   will EXCEPT at startup time.
*/

static char* CondorVersionString = "$CondorVersion: 6.8.1 " __DATE__ " PRE-RELEASE-UWCS $";

/*
   This is some wisdom from Cygnus's web page.  If you just try to use
   the "stringify" operator on a preprocessor directive, you'd get
   "PLATFORM", not "Intel Linux" (or whatever the value of PLATFORM
   is).  That's because the stringify operator is a special case, and
   the preprocessor isn't allowed to expand things that are passed to
   it.  However, by defining two layers of macros, you get the right
   behavior, since the first pass converts:

   xstr(PLATFORM) -> str(Intel Linux)

   and the next pass gives:

   str(Intel Linux) -> "Intel Linux"

   This is exactly what we want, so we use it.  -Derek Wright and Jeff
   Ballard, 12/2/99

   Also, because the NT build system is totally different, we have to
   define the correct platform string right in here. :( -Derek 12/3/99
*/

#if defined(WIN32)
#define PLATFORM INTEL-WINNT50
#endif

#define xstr(s) str(s)
#define str(s) #s

/* Here is the platform string.  You don't need to edit this */
static char* CondorPlatformString = "$CondorPlatform: " xstr(PLATFORM) " $";

extern "C" {

const char*
CondorVersion( void )
{
	return CondorVersionString;
}

const char*
CondorPlatform( void )
{
	return CondorPlatformString;
}

} /* extern "C" */

<commit_msg>now that V6_8-branch exists, the trunk is for 6.9.0 pre-release<commit_after>/***************************Copyright-DO-NOT-REMOVE-THIS-LINE**
  *
  * Condor Software Copyright Notice
  * Copyright (C) 1990-2006, Condor Team, Computer Sciences Department,
  * University of Wisconsin-Madison, WI.
  *
  * This source code is covered by the Condor Public License, which can
  * be found in the accompanying LICENSE.TXT file, or online at
  * www.condorproject.org.
  *
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  * AND THE UNIVERSITY OF WISCONSIN-MADISON "AS IS" AND ANY EXPRESS OR
  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  * WARRANTIES OF MERCHANTABILITY, OF SATISFACTORY QUALITY, AND FITNESS
  * FOR A PARTICULAR PURPOSE OR USE ARE DISCLAIMED. THE COPYRIGHT
  * HOLDERS AND CONTRIBUTORS AND THE UNIVERSITY OF WISCONSIN-MADISON
  * MAKE NO MAKE NO REPRESENTATION THAT THE SOFTWARE, MODIFICATIONS,
  * ENHANCEMENTS OR DERIVATIVE WORKS THEREOF, WILL NOT INFRINGE ANY
  * PATENT, COPYRIGHT, TRADEMARK, TRADE SECRET OR OTHER PROPRIETARY
  * RIGHT.
  *
  ****************************Copyright-DO-NOT-REMOVE-THIS-LINE**/

/* Here is the version string - update before a public release */
/* --- IMPORTANT!  THE FORMAT OF THE VERSION STRING IS VERY STRICT
   BECAUSE IT IS PARSED AT RUNTIME.  DO NOT ALTER THE FORMAT OR ENTER
   ANYTHING EXTRA BEFORE THE DATE.  IF YOU WISH TO ADD EXTRA INFORMATION,
   DO SO _AFTER_ THE DATE AND BEFORE THE TRAILING '$' CHARACTER.
   EXAMPLES:
       $CondorVersion: 6.1.11 " __DATE__ " WinNTPreview $    [OK]
	   $CondorVersion: 6.1.11 WinNTPreview " __DATE__ " $	 [WRONG!!!]
   Any questions?  See Todd or Derek.  Note: if you mess it up, DaemonCore
   will EXCEPT at startup time.
*/

static char* CondorVersionString = "$CondorVersion: 6.9.0 " __DATE__ " PRE-RELEASE-UWCS $";

/*
   This is some wisdom from Cygnus's web page.  If you just try to use
   the "stringify" operator on a preprocessor directive, you'd get
   "PLATFORM", not "Intel Linux" (or whatever the value of PLATFORM
   is).  That's because the stringify operator is a special case, and
   the preprocessor isn't allowed to expand things that are passed to
   it.  However, by defining two layers of macros, you get the right
   behavior, since the first pass converts:

   xstr(PLATFORM) -> str(Intel Linux)

   and the next pass gives:

   str(Intel Linux) -> "Intel Linux"

   This is exactly what we want, so we use it.  -Derek Wright and Jeff
   Ballard, 12/2/99

   Also, because the NT build system is totally different, we have to
   define the correct platform string right in here. :( -Derek 12/3/99
*/

#if defined(WIN32)
#define PLATFORM INTEL-WINNT50
#endif

#define xstr(s) str(s)
#define str(s) #s

/* Here is the platform string.  You don't need to edit this */
static char* CondorPlatformString = "$CondorPlatform: " xstr(PLATFORM) " $";

extern "C" {

const char*
CondorVersion( void )
{
	return CondorVersionString;
}

const char*
CondorPlatform( void )
{
	return CondorPlatformString;
}

} /* extern "C" */

<|endoftext|>


<commit_before>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE-CHROMIUM file.

#include "brightray/common/main_delegate.h"

#include <memory>

#include "base/command_line.h"
#include "base/mac/bundle_locations.h"
#include "base/path_service.h"
#include "brightray/browser/browser_client.h"
#include "brightray/common/content_client.h"
#include "content/public/common/content_switches.h"
#include "electron/buildflags/buildflags.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/base/ui_base_switches.h"

namespace brightray {

namespace {

// Returns true if this subprocess type needs the ResourceBundle initialized
// and resources loaded.
bool SubprocessNeedsResourceBundle(const std::string& process_type) {
  return
#if defined(OS_POSIX) && !defined(OS_MACOSX)
      // The zygote process opens the resources for the renderers.
      process_type == switches::kZygoteProcess ||
#endif
#if defined(OS_MACOSX)
      // Mac needs them too for scrollbar related images and for sandbox
      // profiles.
      process_type == switches::kPpapiPluginProcess ||
      process_type == switches::kPpapiBrokerProcess ||
      process_type == switches::kGpuProcess ||
#endif
      process_type == switches::kRendererProcess ||
      process_type == switches::kUtilityProcess;
}

}  // namespace

void LoadResourceBundle(const std::string& locale) {
  const bool initialized = ui::ResourceBundle::HasSharedInstance();
  if (initialized)
    ui::ResourceBundle::CleanupSharedInstance();

  // Load other resource files.
  base::FilePath pak_dir;
#if defined(OS_MACOSX)
  pak_dir =
      base::mac::FrameworkBundlePath().Append(FILE_PATH_LITERAL("Resources"));
#else
  base::PathService::Get(base::DIR_MODULE, &pak_dir);
#endif

  ui::ResourceBundle::InitSharedInstanceWithLocale(
      locale, nullptr, ui::ResourceBundle::LOAD_COMMON_RESOURCES);
  ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance();
  bundle.ReloadLocaleResources(locale);
  bundle.AddDataPackFromPath(pak_dir.Append(FILE_PATH_LITERAL("resources.pak")),
                             ui::SCALE_FACTOR_NONE);
#if BUILDFLAG(ENABLE_PDF_VIEWER)
  NOTIMPLEMENTED()
      << "Hi, whoever's fixing PDF support! Thanks! The pdf "
         "viewer resources haven't been ported over to the GN build yet, so "
         "you'll probably need to change this bit of code.";
  bundle.AddDataPackFromPath(
      pak_dir.Append(FILE_PATH_LITERAL("pdf_viewer_resources.pak")),
      ui::GetSupportedScaleFactors()[0]);
#endif  // BUILDFLAG(ENABLE_PDF_VIEWER)
}

MainDelegate::MainDelegate() {}

MainDelegate::~MainDelegate() {}

std::unique_ptr<ContentClient> MainDelegate::CreateContentClient() {
  return std::unique_ptr<ContentClient>(new ContentClient);
}

bool MainDelegate::BasicStartupComplete(int* exit_code) {
  content_client_ = CreateContentClient();
  SetContentClient(content_client_.get());
#if defined(OS_MACOSX)
  OverrideChildProcessPath();
  OverrideFrameworkBundlePath();
#endif
  return false;
}

void MainDelegate::PreSandboxStartup() {
  auto cmd = *base::CommandLine::ForCurrentProcess();
  std::string process_type = cmd.GetSwitchValueASCII(switches::kProcessType);

  // Initialize ResourceBundle which handles files loaded from external
  // sources. The language should have been passed in to us from the
  // browser process as a command line flag.
  if (SubprocessNeedsResourceBundle(process_type)) {
    std::string locale = cmd.GetSwitchValueASCII(switches::kLang);
    LoadResourceBundle(locale);
  }
}

content::ContentBrowserClient* MainDelegate::CreateContentBrowserClient() {
  browser_client_ = CreateBrowserClient();
  return browser_client_.get();
}

std::unique_ptr<BrowserClient> MainDelegate::CreateBrowserClient() {
  return std::unique_ptr<BrowserClient>(new BrowserClient);
}

}  // namespace brightray
<commit_msg>kZygoteProcess moved into service_manager<commit_after>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE-CHROMIUM file.

#include "brightray/common/main_delegate.h"

#include <memory>

#include "base/command_line.h"
#include "base/mac/bundle_locations.h"
#include "base/path_service.h"
#include "brightray/browser/browser_client.h"
#include "brightray/common/content_client.h"
#include "content/public/common/content_switches.h"
#include "electron/buildflags/buildflags.h"
#include "services/service_manager/embedder/switches.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/base/ui_base_switches.h"

namespace brightray {

namespace {

// Returns true if this subprocess type needs the ResourceBundle initialized
// and resources loaded.
bool SubprocessNeedsResourceBundle(const std::string& process_type) {
  return
#if defined(OS_POSIX) && !defined(OS_MACOSX)
      // The zygote process opens the resources for the renderers.
      process_type == service_manager::switches::kZygoteProcess ||
#endif
#if defined(OS_MACOSX)
      // Mac needs them too for scrollbar related images and for sandbox
      // profiles.
      process_type == switches::kPpapiPluginProcess ||
      process_type == switches::kPpapiBrokerProcess ||
      process_type == switches::kGpuProcess ||
#endif
      process_type == switches::kRendererProcess ||
      process_type == switches::kUtilityProcess;
}

}  // namespace

void LoadResourceBundle(const std::string& locale) {
  const bool initialized = ui::ResourceBundle::HasSharedInstance();
  if (initialized)
    ui::ResourceBundle::CleanupSharedInstance();

  // Load other resource files.
  base::FilePath pak_dir;
#if defined(OS_MACOSX)
  pak_dir =
      base::mac::FrameworkBundlePath().Append(FILE_PATH_LITERAL("Resources"));
#else
  base::PathService::Get(base::DIR_MODULE, &pak_dir);
#endif

  ui::ResourceBundle::InitSharedInstanceWithLocale(
      locale, nullptr, ui::ResourceBundle::LOAD_COMMON_RESOURCES);
  ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance();
  bundle.ReloadLocaleResources(locale);
  bundle.AddDataPackFromPath(pak_dir.Append(FILE_PATH_LITERAL("resources.pak")),
                             ui::SCALE_FACTOR_NONE);
#if BUILDFLAG(ENABLE_PDF_VIEWER)
  NOTIMPLEMENTED()
      << "Hi, whoever's fixing PDF support! Thanks! The pdf "
         "viewer resources haven't been ported over to the GN build yet, so "
         "you'll probably need to change this bit of code.";
  bundle.AddDataPackFromPath(
      pak_dir.Append(FILE_PATH_LITERAL("pdf_viewer_resources.pak")),
      ui::GetSupportedScaleFactors()[0]);
#endif  // BUILDFLAG(ENABLE_PDF_VIEWER)
}

MainDelegate::MainDelegate() {}

MainDelegate::~MainDelegate() {}

std::unique_ptr<ContentClient> MainDelegate::CreateContentClient() {
  return std::unique_ptr<ContentClient>(new ContentClient);
}

bool MainDelegate::BasicStartupComplete(int* exit_code) {
  content_client_ = CreateContentClient();
  SetContentClient(content_client_.get());
#if defined(OS_MACOSX)
  OverrideChildProcessPath();
  OverrideFrameworkBundlePath();
#endif
  return false;
}

void MainDelegate::PreSandboxStartup() {
  auto cmd = *base::CommandLine::ForCurrentProcess();
  std::string process_type = cmd.GetSwitchValueASCII(switches::kProcessType);

  // Initialize ResourceBundle which handles files loaded from external
  // sources. The language should have been passed in to us from the
  // browser process as a command line flag.
  if (SubprocessNeedsResourceBundle(process_type)) {
    std::string locale = cmd.GetSwitchValueASCII(switches::kLang);
    LoadResourceBundle(locale);
  }
}

content::ContentBrowserClient* MainDelegate::CreateContentBrowserClient() {
  browser_client_ = CreateBrowserClient();
  return browser_client_.get();
}

std::unique_ptr<BrowserClient> MainDelegate::CreateBrowserClient() {
  return std::unique_ptr<BrowserClient>(new BrowserClient);
}

}  // namespace brightray
<|endoftext|>


<commit_before>//
// example.hpp
// ***********
//
// Copyright (c) 2019 Sharon W (sharon at aegis dot gg)
//
// Distributed under the MIT License. (See accompanying file LICENSE)
//

#pragma once

#include <aegis.hpp>
#include <string>
#include <stdint.h>
#include <nlohmann/json.hpp>

namespace example_bot
{

using json = nlohmann::json;
using namespace aegis;
using namespace aegis::gateway::events;

class example
{
public:
    example(core & bot) : bot(bot) {};
    ~example() = default;

    core & bot;

    template<typename Out>
    void split(const std::string &s, char delim, Out result)
    {
        std::stringstream ss;
        ss.str(s);
        std::string item;
        while (std::getline(ss, item, delim))
        {
            if (!item.empty())
                *(result++) = item;
        }
    }

    const json make_info_obj(aegis::core & bot, aegis::shards::shard * _shard);

    std::vector<std::string> split(const std::string &s, char delim)
    {
        std::vector<std::string> elems;
        split(s, delim, std::back_inserter(elems));
        return elems;
    }

    // Messages you want to process
    void attach()
    {
        bot.set_on_message_create(std::bind(&example::MessageCreate, this, std::placeholders::_1));
    }

    snowflake get_snowflake(const std::string name, aegis::guild & _guild) const noexcept
    {
        if (name.empty())
            return { 0 };
        try
        {
            if (name[0] == '<')
            {
                //mention param

                std::string::size_type pos = name.find_first_of('>');
                if (pos == std::string::npos)
                    return { 0 };
                if (name[2] == '!')//mobile mention. strip <@!
                    return std::stoull(std::string{ name.substr(3, pos - 1) });
                else  if (name[2] == '&')//role mention. strip <@&
                    return std::stoull(std::string{ name.substr(3, pos - 1) });
                else  if (name[1] == '#')//channel mention. strip <#
                    return std::stoull(std::string{ name.substr(2, pos - 1) });
                else//regular mention. strip <@
                    return std::stoull(std::string{ name.substr(2, pos - 1) });
            }
            else if (std::isdigit(name[0]))
            {
                //snowflake param
                return std::stoull(std::string{ name });
            }
            else
            {
                //most likely username#discriminator param
                std::string::size_type n = name.find('#');
                if (n != std::string::npos)
                {
                    //found # separator
                    for (auto & m : _guild.get_members())
                        if (m.second->get_full_name() == name)
                            return { m.second->get_id() };
                    return { 0 };
                }
                return { 0 };//# not found. unknown parameter. unicode may trigger this.
            }
        }
        catch (std::invalid_argument &)
        {
            return { 0 };
        }
    }

    const snowflake bot_owner_id = 171000788183678976LL;

    std::string prefix = "?";

    // All the hooks in the websocket stream
    void TypingStart(typing_start obj);

    void MessageCreate(message_create msg);

    void MessageCreateDM(message_create msg);

    void MessageUpdate(message_update obj);

    void MessageDelete(message_delete obj);

    void MessageDeleteBulk(message_delete_bulk obj);

    void GuildCreate(guild_create);

    void GuildUpdate(guild_update obj);

    void GuildDelete(guild_delete obj);

    void UserUpdate(user_update obj);

    void Ready(ready obj);

    void Resumed(resumed obj);

    void ChannelCreate(channel_create obj);

    void ChannelUpdate(channel_update obj);

    void ChannelDelete(channel_delete obj);

    void GuildBanAdd(guild_ban_add obj);

    void GuildBanRemove(guild_ban_remove obj);

    void GuildEmojisUpdate(guild_emojis_update obj);

    void GuildIntegrationsUpdate(guild_integrations_update obj);

    void GuildMemberAdd(guild_member_add obj);

    void GuildMemberRemove(guild_member_remove obj);

    void GuildMemberUpdate(guild_member_update obj);

    void GuildMemberChunk(guild_members_chunk obj);

    void GuildRoleCreate(guild_role_create obj);

    void GuildRoleUpdate(guild_role_update obj);

    void GuildRoleDelete(guild_role_delete obj);

    void PresenceUpdate(presence_update obj);

    void VoiceStateUpdate(voice_state_update obj);

    void VoiceServerUpdate(voice_server_update obj);

    const json make_info_obj(shard * _shard, core * bot);
};

}
<commit_msg>Example fix<commit_after>//
// example.hpp
// ***********
//
// Copyright (c) 2019 Sharon W (sharon at aegis dot gg)
//
// Distributed under the MIT License. (See accompanying file LICENSE)
//

#pragma once

#include <aegis.hpp>
#include <string>
#include <stdint.h>
#include <nlohmann/json.hpp>

namespace example_bot
{

using json = nlohmann::json;
using namespace aegis;
using namespace aegis::gateway::events;

class example
{
public:
    example(core & bot) : bot(bot) {};
    ~example() = default;

    core & bot;

    template<typename Out>
    void split(const std::string &s, char delim, Out result)
    {
        std::stringstream ss;
        ss.str(s);
        std::string item;
        while (std::getline(ss, item, delim))
        {
            if (!item.empty())
                *(result++) = item;
        }
    }

    const json make_info_obj(aegis::core & bot, aegis::shards::shard * _shard);

    std::vector<std::string> split(const std::string &s, char delim)
    {
        std::vector<std::string> elems;
        split(s, delim, std::back_inserter(elems));
        return elems;
    }

    // Messages you want to process
    void attach()
    {
        bot.set_on_message_create(std::bind(&example::MessageCreate, this, std::placeholders::_1));
    }

    snowflake get_snowflake(const std::string name, aegis::guild & _guild) const noexcept
    {
        if (name.empty())
            return { 0 };
        try
        {
            if (name[0] == '<')
            {
                //mention param

                std::string::size_type pos = name.find_first_of('>');
                if (pos == std::string::npos)
                    return { 0 };
                if (name[2] == '!')//mobile mention. strip <@!
                    return std::stoull(std::string{ name.substr(3, pos - 1) });
                else  if (name[2] == '&')//role mention. strip <@&
                    return std::stoull(std::string{ name.substr(3, pos - 1) });
                else  if (name[1] == '#')//channel mention. strip <#
                    return std::stoull(std::string{ name.substr(2, pos - 1) });
                else//regular mention. strip <@
                    return std::stoull(std::string{ name.substr(2, pos - 1) });
            }
            else if (std::isdigit(name[0]))
            {
                //snowflake param
                return std::stoull(std::string{ name });
            }
            else
            {
                //most likely username#discriminator param
                std::string::size_type n = name.find('#');
                if (n != std::string::npos)
                {
                    //found # separator
                    for (auto & m : _guild.get_members())
                        if (m.second->get_full_name() == name)
                            return { m.second->get_id() };
                    return 0;
                }
                return 0;//# not found. unknown parameter. unicode may trigger this.
            }
        }
        catch (std::invalid_argument &)
        {
            return 0;
        }
    }

    const snowflake bot_owner_id = 171000788183678976LL;

    std::string prefix = "?";

    // All the hooks in the websocket stream
    void TypingStart(typing_start obj);

    void MessageCreate(message_create msg);

    void MessageCreateDM(message_create msg);

    void MessageUpdate(message_update obj);

    void MessageDelete(message_delete obj);

    void MessageDeleteBulk(message_delete_bulk obj);

    void GuildCreate(guild_create);

    void GuildUpdate(guild_update obj);

    void GuildDelete(guild_delete obj);

    void UserUpdate(user_update obj);

    void Ready(ready obj);

    void Resumed(resumed obj);

    void ChannelCreate(channel_create obj);

    void ChannelUpdate(channel_update obj);

    void ChannelDelete(channel_delete obj);

    void GuildBanAdd(guild_ban_add obj);

    void GuildBanRemove(guild_ban_remove obj);

    void GuildEmojisUpdate(guild_emojis_update obj);

    void GuildIntegrationsUpdate(guild_integrations_update obj);

    void GuildMemberAdd(guild_member_add obj);

    void GuildMemberRemove(guild_member_remove obj);

    void GuildMemberUpdate(guild_member_update obj);

    void GuildMemberChunk(guild_members_chunk obj);

    void GuildRoleCreate(guild_role_create obj);

    void GuildRoleUpdate(guild_role_update obj);

    void GuildRoleDelete(guild_role_delete obj);

    void PresenceUpdate(presence_update obj);

    void VoiceStateUpdate(voice_state_update obj);

    void VoiceServerUpdate(voice_server_update obj);

    const json make_info_obj(shard * _shard, core * bot);
};

}
<|endoftext|>


<commit_before>#include "connection.hpp"
#include <boost/thread.hpp>
#include "general.hpp"
#include <thread>
#include <stdexcept>

using boost::asio::ip::tcp;

namespace irc {

void connection::connect(const std::string &addr, const std::string &port, const bool ssl)
{
    if ( addr.empty() )
        throw std::invalid_argument("adress is empty.");

    else if ( !gen::valid_addr(addr) )
        throw std::invalid_argument("invalid address.");

    if (port.empty()) {
        port_ = (ssl ? "6697" : "6667");
        addr_ = addr;

        connect();

    } else if ( !gen::is_integer(port) )
        throw std::invalid_argument("port is a non-integer");
    else {
        addr_ = addr;
        port_ = port;

        connect();
    }
}

void connection::connect()
{
    /*
     * Resolve the host and generate a list of endpoints.
     * An endpoint is the information used to connect to an address.
     * An address may have more than one endpoint.
     */
    tcp::resolver r(io_service_);
    tcp::resolver::query query(addr_, port_);
    tcp::resolver::iterator endpt_it = r.resolve(query);

    /* Denotes the end of the list of generated endpoints. */
    decltype(endpt_it) end;

    /* Default error */
    boost::system::error_code error = boost::asio::error::host_not_found;

    /* Iterate until we've reached the end of the list. */
    while (endpt_it != end) {
        if (!error)
            break;

        socket_.close();
        socket_.connect(*endpt_it++, error);
    }

    if (error)
        throw error;
}

void connection::run()
{
    std::thread ping_handler_thread(ping_handler);

    /*
     * Start an asynchronous read thread going through connection::read().
     * Pass the arguments (this, _1, _2) to the handler.
     */
    socket_.async_read_some(boost::asio::buffer(buffer_),
        boost::bind(&connection::read,
            this, boost::asio::placeholders::error,
            boost::asio::placeholders::bytes_transferred()));

    io_service_.run();

    /* Remain at this point until we do not need the connection any more. */
    ping_handler_thread.join();
}

void connection::ping()
{
    using namespace std::literals;

    while (do_ping) {

        /*
         * Interval decided by mimicing WeeChat.
         * The standard does not seem to explicitly
         * state a ping inverval. Is it the server's
         * decision?
         */
        std::this_thread::sleep_for(1min + 30s);

        /* For debugging */
        std::cout << "[info] Pinging " << addr_ << '.' << std::endl;
        write("PING " + addr_);
    }
}

void connection::pong()
{
    write("PONG :" + addr_);
}

void connection::write(const std::string &content)
{
    /*
     * The IRC protocol specifies that all messages sent to the server
     * must be terminated with CR-LF (Carriage Return - Line Feed)
     */
    boost::asio::write(socket_, boost::asio::buffer(content + "\r\n"));
}

void connection::read(const boost::system::error_code &error, std::size_t length)
{
    if (error) {
        /* Unable to read from server. */
        throw error;
    } else {

        /*
         * Works in synergy with socket::async_read_some().
         *
         * Copy the data within the buffer and the length of it
         * and pass it to the class' read_handler.
         */
        read_handler(std::string(buffer_.data(), length));

        /*
         * Start an asynchronous recursive read thread.
         *
         * Read data from the IRC server into the buffer, and
         * call this function again.
         *
         * Pass the eventual error and the message length.
         */
        socket_.async_read_some(boost::asio::buffer(buffer_),
            boost::bind(&connection::read,
                this, boost::asio::placeholders::error,
                boost::asio::placeholders::bytes_transferred));
    }
}

void connection::read_handler(const std::string &content)
{
    std::stringstream iss(content);
    std::string command;

    iss >> command;

    if (command == "PING")
        pong();
    else
        ext_read_handler_(content);
}

void connection::stop()
{
    socket_.close();
    io_service_.stop();
}

/* ns irc */
}
<commit_msg>Those spaces didn't look very pleasing.<commit_after>#include "connection.hpp"
#include <boost/thread.hpp>
#include "general.hpp"
#include <thread>
#include <stdexcept>

using boost::asio::ip::tcp;

namespace irc {

void connection::connect(const std::string &addr, const std::string &port, const bool ssl)
{
    if (addr.empty())
        throw std::invalid_argument("adress is empty.");

    else if (!gen::valid_addr(addr))
        throw std::invalid_argument("invalid address.");

    if (port.empty()) {
        port_ = (ssl ? "6697" : "6667");
        addr_ = addr;

        connect();

    } else if (!gen::is_integer(port))
        throw std::invalid_argument("port is a non-integer");
    else {
        addr_ = addr;
        port_ = port;

        connect();
    }
}

void connection::connect()
{
    /*
     * Resolve the host and generate a list of endpoints.
     * An endpoint is the information used to connect to an address.
     * An address may have more than one endpoint.
     */
    tcp::resolver r(io_service_);
    tcp::resolver::query query(addr_, port_);
    tcp::resolver::iterator endpt_it = r.resolve(query);

    /* Denotes the end of the list of generated endpoints. */
    decltype(endpt_it) end;

    /* Default error */
    boost::system::error_code error = boost::asio::error::host_not_found;

    /* Iterate until we've reached the end of the list. */
    while (endpt_it != end) {
        if (!error)
            break;

        socket_.close();
        socket_.connect(*endpt_it++, error);
    }

    if (error)
        throw error;
}

void connection::run()
{
    std::thread ping_handler_thread(ping_handler);

    /*
     * Start an asynchronous read thread going through connection::read().
     * Pass the arguments (this, _1, _2) to the handler.
     */
    socket_.async_read_some(boost::asio::buffer(buffer_),
        boost::bind(&connection::read,
            this, boost::asio::placeholders::error,
            boost::asio::placeholders::bytes_transferred()));

    io_service_.run();

    /* Remain at this point until we do not need the connection any more. */
    ping_handler_thread.join();
}

void connection::ping()
{
    using namespace std::literals;

    while (do_ping) {

        /*
         * Interval decided by mimicing WeeChat.
         * The standard does not seem to explicitly
         * state a ping inverval. Is it the server's
         * decision?
         */
        std::this_thread::sleep_for(1min + 30s);

        /* For debugging */
        std::cout << "[info] Pinging " << addr_ << '.' << std::endl;
        write("PING " + addr_);
    }
}

void connection::pong()
{
    write("PONG :" + addr_);
}

void connection::write(const std::string &content)
{
    /*
     * The IRC protocol specifies that all messages sent to the server
     * must be terminated with CR-LF (Carriage Return - Line Feed)
     */
    boost::asio::write(socket_, boost::asio::buffer(content + "\r\n"));
}

void connection::read(const boost::system::error_code &error, std::size_t length)
{
    if (error) {
        /* Unable to read from server. */
        throw error;
    } else {

        /*
         * Works in synergy with socket::async_read_some().
         *
         * Copy the data within the buffer and the length of it
         * and pass it to the class' read_handler.
         */
        read_handler(std::string(buffer_.data(), length));

        /*
         * Start an asynchronous recursive read thread.
         *
         * Read data from the IRC server into the buffer, and
         * call this function again.
         *
         * Pass the eventual error and the message length.
         */
        socket_.async_read_some(boost::asio::buffer(buffer_),
            boost::bind(&connection::read,
                this, boost::asio::placeholders::error,
                boost::asio::placeholders::bytes_transferred));
    }
}

void connection::read_handler(const std::string &content)
{
    std::stringstream iss(content);
    std::string command;

    iss >> command;

    if (command == "PING")
        pong();
    else
        ext_read_handler_(content);
}

void connection::stop()
{
    socket_.close();
    io_service_.stop();
}

/* ns irc */
}
<|endoftext|>


<commit_before>/**
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

#include "TypeTags.h"

void TypeTags::set_type_tag(const DexType* type, uint32_t type_tag) {
  m_type_to_tag.emplace(type, type_tag);
  m_tag_to_type.emplace(type_tag, type);
}

uint32_t TypeTags::get_type_tag(const DexType* type) const {
  return m_type_to_tag.at(type);
}

const DexType* TypeTags::get_type(uint32_t type_tag) const {
  return m_tag_to_type.at(type_tag);
}
<commit_msg>Actually set type tag in the setters<commit_after>/**
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

#include "TypeTags.h"

void TypeTags::set_type_tag(const DexType* type, uint32_t type_tag) {
  m_type_to_tag[type] = type_tag;
  m_tag_to_type[type_tag] = type;
}

uint32_t TypeTags::get_type_tag(const DexType* type) const {
  return m_type_to_tag.at(type);
}

const DexType* TypeTags::get_type(uint32_t type_tag) const {
  return m_tag_to_type.at(type_tag);
}
<|endoftext|>


<commit_before>#include <ostream>
#include <iostream>
#include <vector>
#include <string>
#include "sevensegment.h"

const static std::vector< std::vector<std::string> > digits {
	{ " - ", "| |", "   ", "| |", " - " }, // 0
	{ "   ", "  |", "   ", "  |", "   " }, // 1
	{ " - ", "  |", " - ", "|  ", " - " }, // 2
	{ " - ", "  |", " - ", "  |", " - " }, // 3
	{ "   ", "| |", " - ", "  |", "   " }, // 4
	{ " - ", "|  ", " - ", "  |", " - " }, // 5
	{ " - ", "|  ", " - ", "| |", " - " }, // 6
	{ " - ", "  |", "   ", "  |", "   " }, // 7
	{ " - ", "| |", " - ", "| |", " - " }, // 8
	{ " - ", "| |", " - ", "  |", " - " }  // 9
};
void printLargeDigit(unsigned i, std::ostream &out) {
	std::vector< std::string> digit = digits.at(i);
	for_each(digit.begin(), digit.end(), [&](std::string line) {
		out << line << '\n';
		out << line << '\n';
	});
}
<commit_msg>remove debugging line<commit_after>#include <ostream>
#include <iostream>
#include <vector>
#include <string>
#include "sevensegment.h"

const static std::vector< std::vector<std::string> > digits {
	{ " - ", "| |", "   ", "| |", " - " }, // 0
	{ "   ", "  |", "   ", "  |", "   " }, // 1
	{ " - ", "  |", " - ", "|  ", " - " }, // 2
	{ " - ", "  |", " - ", "  |", " - " }, // 3
	{ "   ", "| |", " - ", "  |", "   " }, // 4
	{ " - ", "|  ", " - ", "  |", " - " }, // 5
	{ " - ", "|  ", " - ", "| |", " - " }, // 6
	{ " - ", "  |", "   ", "  |", "   " }, // 7
	{ " - ", "| |", " - ", "| |", " - " }, // 8
	{ " - ", "| |", " - ", "  |", " - " }  // 9
};
void printLargeDigit(unsigned i, std::ostream &out) {
	std::vector< std::string> digit = digits.at(i);
	for_each(digit.begin(), digit.end(), [&](std::string line) {
		out << line << '\n';
	});
}
<|endoftext|>


<commit_before>#include "RC.h"
#include "utils/hw/RF4463F30.h"
#include <string>
#include "util/murmurhash.h"

namespace util
{
namespace comms
{

constexpr size_t MTU = 64;
constexpr uint8_t CHANNEL = 0;
constexpr q::Clock::duration MIN_TX_DURATION = std::chrono::milliseconds(5);

struct RC::HW
{
    hw::RF4463F30 chip;
};

RC::RC(bool master)
    : m_is_master(master)
{
    m_hw.reset(new HW);
    set_rate(30);
}

RC::~RC()
{
    m_exit = true;
    if (m_thread.joinable())
    {
        m_thread.join();
    }
}

bool RC::init(std::string const& device, uint32_t speed, uint8_t sdn_gpio, uint8_t nirq_gpio)
{
    if (!m_hw->chip.init(device, speed, sdn_gpio, nirq_gpio))
    {
        return false;
    }

    if (m_is_master)
    {
        m_thread = boost::thread([this]() { master_thread_proc(); });
    }
    else
    {
        m_thread = boost::thread([this]() { slave_thread_proc(); });
    }

    return true;
}

size_t RC::get_mtu() const
{
    return MTU - sizeof(Header);
}

void RC::set_rate(size_t rate)
{
    m_desired_rate = std::max(rate, 1u);
    m_desired_duration = std::chrono::microseconds(1000000 / rate);
    if (m_desired_duration < MIN_TX_DURATION)
    {
        m_desired_duration = MIN_TX_DURATION;
    }
}

void RC::set_tx_data(void const* data, size_t size)
{
    std::lock_guard<std::mutex> lg(m_mutex);
    m_tx_data.resize(size);

    if (size > 0 && data)
    {
        memcpy(m_tx_data.data(), data, size);
    }
}

void RC::get_rx_data(Data& data) const
{
    std::lock_guard<std::mutex> lg(m_mutex);
    data = m_rx_data;
}

void RC::master_thread_proc()
{
    while (!m_exit)
    {
        q::Clock::duration tx_duration;

        {
            auto start_tx_tp = q::Clock::now();
            auto diff = start_tx_tp - m_rx_data.tx_timepoint;
            if (diff < m_desired_duration)
            {
                std::this_thread::sleep_for(diff);
            }

            start_tx_tp = q::Clock::now();

            {
                std::lock_guard<std::mutex> lg(m_mutex);
                m_tx_buffer.resize(1 + sizeof(Header) + m_tx_data.size());
                memcpy(m_tx_buffer.data() + 1 + sizeof(Header), m_tx_data.data(), m_tx_data.size());
                m_tx_buffer[0] = sizeof(Header) + m_tx_data.size();
            }

            Header& header = *reinterpret_cast<Header*>(m_tx_buffer.data() + 1);
            header.crc = 0;
            m_hw->chip.get_dBm(header.dBm);
            header.crc = q::util::compute_murmur_hash16(m_tx_buffer.data() + 1, m_tx_buffer.size() - 1);

            //wait a bit so the other end has time to setup its RX state
            std::this_thread::sleep_for(std::chrono::microseconds(500));

            //The first byte is the length. The rest are payload
            if (m_hw->chip.write_tx_fifo(m_tx_buffer.data(), m_tx_buffer.size()))
            {
                //The first byte is the length. The actual payload is size - 1
                if (m_hw->chip.tx(m_tx_buffer.size() - 1, CHANNEL))
                {

                }
            }

            m_rx_data.tx_timepoint = q::Clock::now();

            tx_duration = q::Clock::now() - start_tx_tp;
        }

        {
            q::Clock::duration rx_duration = m_desired_duration - tx_duration;
            if (rx_duration < m_desired_duration / 2)
            {
                rx_duration = m_desired_duration / 2;
            }

            size_t rx_size = 0;
            if (m_hw->chip.rx(rx_size, CHANNEL, rx_duration))
            {
                read_fifo(rx_size);
                std::this_thread::sleep_for(std::chrono::microseconds(100));
            }
            else
            {
                QLOGW("RX Failure");
            }
        }
    }
}

void RC::slave_thread_proc()
{
    while (!m_exit)
    {
        //wait for a packet indefinitely
        {
            size_t rx_size = 0;
            while (!m_exit)
            {
                if (m_hw->chip.rx(rx_size, CHANNEL, std::chrono::seconds(500)))
                {
                    read_fifo(rx_size);
                    break;
                }
                else
                {
                    QLOGW("RX Failure");
                }
            }
        }

        if (m_exit)
        {
            break;
        }

        //if packet received, respond
        {
            {
                std::lock_guard<std::mutex> lg(m_mutex);
                m_tx_buffer.resize(1 + sizeof(Header) + m_tx_data.size());
                memcpy(m_tx_buffer.data() + 1 + sizeof(Header), m_tx_data.data(), m_tx_data.size());
                m_tx_buffer[0] = sizeof(Header) + m_tx_data.size();
            }

            //auto start_tx_tp = q::Clock::now();

            Header& header = *reinterpret_cast<Header*>(m_tx_buffer.data() + 1);
            header.crc = 0;
            m_hw->chip.get_dBm(header.dBm);
            header.crc = q::util::compute_murmur_hash16(m_tx_buffer.data() + 1, m_tx_buffer.size() - 1);

            //wait a bit so the other end has time to setup its RX state
            std::this_thread::sleep_for(std::chrono::microseconds(500));

            //The first byte is the length. The rest are payload
            if (m_hw->chip.write_tx_fifo(m_tx_buffer.data(), m_tx_buffer.size()))
            {
                //The first byte is the length. The actual payload is size - 1
                if (m_hw->chip.tx(m_tx_buffer.size() - 1, CHANNEL))
                {

                }
            }

            m_rx_data.tx_timepoint = q::Clock::now();
        }
    }
}

bool RC::read_fifo(size_t rx_size)
{
    if (rx_size == 0)
    {
        return true;
    }

    if (rx_size >= sizeof(Header) && rx_size <= MTU)
    {
        m_rx_buffer.resize(rx_size);
        if (m_hw->chip.read_rx_fifo(m_rx_buffer.data(), rx_size))
        {
            Header& header = *reinterpret_cast<Header*>(m_rx_buffer.data());
            uint16_t crc = header.crc;
            header.crc = 0;
            uint16_t computed_crc = q::util::compute_murmur_hash16(m_rx_buffer.data(), m_rx_buffer.size());
            if (crc == computed_crc)
            {
                int8_t dBm = 0;
                m_hw->chip.get_dBm(dBm);

                {
                    std::lock_guard<std::mutex> lg(m_mutex);
                    m_rx_data.tx_dBm = header.dBm;
                    m_rx_data.rx_dBm = dBm;
                    m_rx_data.rx_timepoint = q::Clock::now();
                    m_rx_data.rx_data.resize(m_rx_buffer.size() - sizeof(Header));
                    if (!m_rx_data.rx_data.empty())
                    {
                        memcpy(m_rx_data.rx_data.data(), m_rx_buffer.data() + sizeof(Header), m_rx_data.rx_data.size());
                    }
                }
                return true;
            }
            else
            {
                QLOGW("CRC mismatch: {} vs {}", crc, computed_crc);
                return false;
            }
        }
        else
        {
            QLOGW("Failed to read RX fifo");
            return false;
        }
    }
    else
    {
        QLOGW("Invalid size received: {}", rx_size);
        return false;
    }
}

}
}
<commit_msg>Removed useless sleep<commit_after>#include "RC.h"
#include "utils/hw/RF4463F30.h"
#include <string>
#include "util/murmurhash.h"

namespace util
{
namespace comms
{

constexpr size_t MTU = 64;
constexpr uint8_t CHANNEL = 0;
constexpr q::Clock::duration MIN_TX_DURATION = std::chrono::milliseconds(5);

struct RC::HW
{
    hw::RF4463F30 chip;
};

RC::RC(bool master)
    : m_is_master(master)
{
    m_hw.reset(new HW);
    set_rate(30);
}

RC::~RC()
{
    m_exit = true;
    if (m_thread.joinable())
    {
        m_thread.join();
    }
}

bool RC::init(std::string const& device, uint32_t speed, uint8_t sdn_gpio, uint8_t nirq_gpio)
{
    if (!m_hw->chip.init(device, speed, sdn_gpio, nirq_gpio))
    {
        return false;
    }

    if (m_is_master)
    {
        m_thread = boost::thread([this]() { master_thread_proc(); });
    }
    else
    {
        m_thread = boost::thread([this]() { slave_thread_proc(); });
    }

    return true;
}

size_t RC::get_mtu() const
{
    return MTU - sizeof(Header);
}

void RC::set_rate(size_t rate)
{
    m_desired_rate = std::max(rate, 1u);
    m_desired_duration = std::chrono::microseconds(1000000 / rate);
    if (m_desired_duration < MIN_TX_DURATION)
    {
        m_desired_duration = MIN_TX_DURATION;
    }
}

void RC::set_tx_data(void const* data, size_t size)
{
    std::lock_guard<std::mutex> lg(m_mutex);
    m_tx_data.resize(size);

    if (size > 0 && data)
    {
        memcpy(m_tx_data.data(), data, size);
    }
}

void RC::get_rx_data(Data& data) const
{
    std::lock_guard<std::mutex> lg(m_mutex);
    data = m_rx_data;
}

void RC::master_thread_proc()
{
    while (!m_exit)
    {
        q::Clock::duration tx_duration;

        {
            auto start_tx_tp = q::Clock::now();
            auto diff = start_tx_tp - m_rx_data.tx_timepoint;
            if (diff < m_desired_duration)
            {
                std::this_thread::sleep_for(diff);
            }

            start_tx_tp = q::Clock::now();

            {
                std::lock_guard<std::mutex> lg(m_mutex);
                m_tx_buffer.resize(1 + sizeof(Header) + m_tx_data.size());
                memcpy(m_tx_buffer.data() + 1 + sizeof(Header), m_tx_data.data(), m_tx_data.size());
                m_tx_buffer[0] = sizeof(Header) + m_tx_data.size();
            }

            Header& header = *reinterpret_cast<Header*>(m_tx_buffer.data() + 1);
            header.crc = 0;
            m_hw->chip.get_dBm(header.dBm);
            header.crc = q::util::compute_murmur_hash16(m_tx_buffer.data() + 1, m_tx_buffer.size() - 1);

            //wait a bit so the other end has time to setup its RX state
            std::this_thread::sleep_for(std::chrono::microseconds(500));

            //The first byte is the length. The rest are payload
            if (m_hw->chip.write_tx_fifo(m_tx_buffer.data(), m_tx_buffer.size()))
            {
                //The first byte is the length. The actual payload is size - 1
                if (m_hw->chip.tx(m_tx_buffer.size() - 1, CHANNEL))
                {

                }
            }

            m_rx_data.tx_timepoint = q::Clock::now();

            tx_duration = q::Clock::now() - start_tx_tp;
        }

        {
            q::Clock::duration rx_duration = m_desired_duration - tx_duration;
            if (rx_duration < m_desired_duration / 2)
            {
                rx_duration = m_desired_duration / 2;
            }

            size_t rx_size = 0;
            if (m_hw->chip.rx(rx_size, CHANNEL, rx_duration))
            {
                read_fifo(rx_size);
            }
            else
            {
                QLOGW("RX Failure");
            }
        }
    }
}

void RC::slave_thread_proc()
{
    while (!m_exit)
    {
        //wait for a packet indefinitely
        {
            size_t rx_size = 0;
            while (!m_exit)
            {
                if (m_hw->chip.rx(rx_size, CHANNEL, std::chrono::seconds(500)))
                {
                    read_fifo(rx_size);
                    break;
                }
                else
                {
                    QLOGW("RX Failure");
                }
            }
        }

        if (m_exit)
        {
            break;
        }

        //if packet received, respond
        {
            {
                std::lock_guard<std::mutex> lg(m_mutex);
                m_tx_buffer.resize(1 + sizeof(Header) + m_tx_data.size());
                memcpy(m_tx_buffer.data() + 1 + sizeof(Header), m_tx_data.data(), m_tx_data.size());
                m_tx_buffer[0] = sizeof(Header) + m_tx_data.size();
            }

            //auto start_tx_tp = q::Clock::now();

            Header& header = *reinterpret_cast<Header*>(m_tx_buffer.data() + 1);
            header.crc = 0;
            m_hw->chip.get_dBm(header.dBm);
            header.crc = q::util::compute_murmur_hash16(m_tx_buffer.data() + 1, m_tx_buffer.size() - 1);

            //wait a bit so the other end has time to setup its RX state
            std::this_thread::sleep_for(std::chrono::microseconds(500));

            //The first byte is the length. The rest are payload
            if (m_hw->chip.write_tx_fifo(m_tx_buffer.data(), m_tx_buffer.size()))
            {
                //The first byte is the length. The actual payload is size - 1
                if (m_hw->chip.tx(m_tx_buffer.size() - 1, CHANNEL))
                {

                }
            }

            m_rx_data.tx_timepoint = q::Clock::now();
        }
    }
}

bool RC::read_fifo(size_t rx_size)
{
    if (rx_size == 0)
    {
        return true;
    }

    if (rx_size >= sizeof(Header) && rx_size <= MTU)
    {
        m_rx_buffer.resize(rx_size);
        if (m_hw->chip.read_rx_fifo(m_rx_buffer.data(), rx_size))
        {
            Header& header = *reinterpret_cast<Header*>(m_rx_buffer.data());
            uint16_t crc = header.crc;
            header.crc = 0;
            uint16_t computed_crc = q::util::compute_murmur_hash16(m_rx_buffer.data(), m_rx_buffer.size());
            if (crc == computed_crc)
            {
                int8_t dBm = 0;
                m_hw->chip.get_dBm(dBm);

                {
                    std::lock_guard<std::mutex> lg(m_mutex);
                    m_rx_data.tx_dBm = header.dBm;
                    m_rx_data.rx_dBm = dBm;
                    m_rx_data.rx_timepoint = q::Clock::now();
                    m_rx_data.rx_data.resize(m_rx_buffer.size() - sizeof(Header));
                    if (!m_rx_data.rx_data.empty())
                    {
                        memcpy(m_rx_data.rx_data.data(), m_rx_buffer.data() + sizeof(Header), m_rx_data.rx_data.size());
                    }
                }
                return true;
            }
            else
            {
                QLOGW("CRC mismatch: {} vs {}", crc, computed_crc);
                return false;
            }
        }
        else
        {
            QLOGW("Failed to read RX fifo");
            return false;
        }
    }
    else
    {
        QLOGW("Invalid size received: {}", rx_size);
        return false;
    }
}

}
}
<|endoftext|>


<commit_before>// Copyright 2018-present MongoDB 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 <mongocxx/options/change_stream.hpp>

#include <bsoncxx/builder/basic/document.hpp>
#include <bsoncxx/builder/basic/kvp.hpp>
#include <bsoncxx/builder/core.hpp>
#include <mongocxx/exception/error_code.hpp>
#include <mongocxx/exception/logic_error.hpp>

#include <mongocxx/config/private/prelude.hh>

namespace mongocxx {
MONGOCXX_INLINE_NAMESPACE_BEGIN
namespace options {

change_stream::change_stream() = default;

change_stream& change_stream::full_document(bsoncxx::string::view_or_value full_doc) {
    _full_document = std::move(full_doc);
    return *this;
}

const bsoncxx::stdx::optional<bsoncxx::string::view_or_value>& change_stream::full_document()
    const {
    return _full_document;
}

change_stream& change_stream::batch_size(std::int32_t batch_size) {
    _batch_size = batch_size;
    return *this;
}

const stdx::optional<std::int32_t>& change_stream::batch_size() const {
    return _batch_size;
}

change_stream& change_stream::resume_after(bsoncxx::document::view_or_value resume_after) {
    _resume_after = std::move(resume_after);
    return *this;
}

const stdx::optional<bsoncxx::document::view_or_value>& change_stream::resume_after() const {
    return _resume_after;
}

change_stream& change_stream::collation(bsoncxx::document::view_or_value collation) {
    _collation = std::move(collation);
    return *this;
}

const stdx::optional<bsoncxx::document::view_or_value>& change_stream::collation() const {
    return _collation;
}

change_stream& change_stream::max_await_time(std::chrono::milliseconds max_time) {
    _max_await_time = std::move(max_time);
    return *this;
}

const stdx::optional<std::chrono::milliseconds>& change_stream::max_await_time() const {
    return _max_await_time;
}

change_stream& change_stream::start_at_operation_time(bsoncxx::types::b_timestamp timestamp) {
    _start_at_operation_time = timestamp;
    _start_at_operation_time_set = true;
    return *this;
}

namespace {
template <typename T>
inline void append_if(bsoncxx::builder::basic::document& doc,
                      const std::string& key,
                      const mongocxx::stdx::optional<T>& opt) {
    if (opt) {
        doc.append(bsoncxx::builder::basic::kvp(key, opt.value()));
    }
}
}  // namespace

bsoncxx::document::value change_stream::as_bson() const {
    // Construct new bson rep each time since values may change after this is called.
    bsoncxx::builder::basic::document out{};

    append_if(out, "fullDocument", full_document());
    append_if(out, "resumeAfter", resume_after());
    append_if(out, "batchSize", batch_size());
    append_if(out, "collation", collation());
    if (_start_at_operation_time_set) {
        out.append(bsoncxx::builder::basic::kvp("startAtOperationTime", _start_at_operation_time));
    }

    if (max_await_time()) {
        auto count = max_await_time().value().count();
        if ((count < 0) || (count >= std::numeric_limits<std::uint32_t>::max())) {
            throw mongocxx::logic_error{mongocxx::error_code::k_invalid_parameter};
        }
        out.append(bsoncxx::builder::basic::kvp("maxAwaitTimeMS", count));
    }

    return out.extract();
}

}  // namespace options
MONGOCXX_INLINE_NAMESPACE_END
}  // namespace mongocxx
<commit_msg>Cast maxAwaitTimeMS value to int64_t to avoid ambiguity issues (#641)<commit_after>// Copyright 2018-present MongoDB 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 <mongocxx/options/change_stream.hpp>

#include <bsoncxx/builder/basic/document.hpp>
#include <bsoncxx/builder/basic/kvp.hpp>
#include <bsoncxx/builder/core.hpp>
#include <mongocxx/exception/error_code.hpp>
#include <mongocxx/exception/logic_error.hpp>

#include <mongocxx/config/private/prelude.hh>

namespace mongocxx {
MONGOCXX_INLINE_NAMESPACE_BEGIN
namespace options {

change_stream::change_stream() = default;

change_stream& change_stream::full_document(bsoncxx::string::view_or_value full_doc) {
    _full_document = std::move(full_doc);
    return *this;
}

const bsoncxx::stdx::optional<bsoncxx::string::view_or_value>& change_stream::full_document()
    const {
    return _full_document;
}

change_stream& change_stream::batch_size(std::int32_t batch_size) {
    _batch_size = batch_size;
    return *this;
}

const stdx::optional<std::int32_t>& change_stream::batch_size() const {
    return _batch_size;
}

change_stream& change_stream::resume_after(bsoncxx::document::view_or_value resume_after) {
    _resume_after = std::move(resume_after);
    return *this;
}

const stdx::optional<bsoncxx::document::view_or_value>& change_stream::resume_after() const {
    return _resume_after;
}

change_stream& change_stream::collation(bsoncxx::document::view_or_value collation) {
    _collation = std::move(collation);
    return *this;
}

const stdx::optional<bsoncxx::document::view_or_value>& change_stream::collation() const {
    return _collation;
}

change_stream& change_stream::max_await_time(std::chrono::milliseconds max_time) {
    _max_await_time = std::move(max_time);
    return *this;
}

const stdx::optional<std::chrono::milliseconds>& change_stream::max_await_time() const {
    return _max_await_time;
}

change_stream& change_stream::start_at_operation_time(bsoncxx::types::b_timestamp timestamp) {
    _start_at_operation_time = timestamp;
    _start_at_operation_time_set = true;
    return *this;
}

namespace {
template <typename T>
inline void append_if(bsoncxx::builder::basic::document& doc,
                      const std::string& key,
                      const mongocxx::stdx::optional<T>& opt) {
    if (opt) {
        doc.append(bsoncxx::builder::basic::kvp(key, opt.value()));
    }
}
}  // namespace

bsoncxx::document::value change_stream::as_bson() const {
    // Construct new bson rep each time since values may change after this is called.
    bsoncxx::builder::basic::document out{};

    append_if(out, "fullDocument", full_document());
    append_if(out, "resumeAfter", resume_after());
    append_if(out, "batchSize", batch_size());
    append_if(out, "collation", collation());
    if (_start_at_operation_time_set) {
        out.append(bsoncxx::builder::basic::kvp("startAtOperationTime", _start_at_operation_time));
    }

    if (max_await_time()) {
        auto count = max_await_time().value().count();
        if ((count < 0) || (count >= std::numeric_limits<std::uint32_t>::max())) {
            throw mongocxx::logic_error{mongocxx::error_code::k_invalid_parameter};
        }
        out.append(
            bsoncxx::builder::basic::kvp("maxAwaitTimeMS", static_cast<std::int64_t>(count)));
    }

    return out.extract();
}

}  // namespace options
MONGOCXX_INLINE_NAMESPACE_END
}  // namespace mongocxx
<|endoftext|>


<commit_before>// Copyright 2014 Google Inc. All rights reserved.
//
// 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 <sstream>

#include "mathfu/constants.h"
#include "motive/anim.h"
#include "motive/engine.h"
#include "motive/init.h"
#include "motive/math/angle.h"
#include "motive/math/bulk_spline_evaluator.h"

using fpl::Angle;
using fpl::kPi;
using mathfu::AffineTransform;
using mathfu::mat4;
using mathfu::vec4;

namespace motive {

// static
mathfu::mat4 MatrixInit::kIdentityTransform(mathfu::mat4::Identity());
static const MatrixOpArray kEmptyOps(0);

class RigData {
 public:
  explicit RigData(const RigInit& init, MotiveTime start_time,
                   MotiveEngine* engine)
      : motivators_(nullptr),
        global_transforms_(nullptr),
        defining_anim_(&init.defining_anim()),
        current_anim_(nullptr),
        end_time_(start_time) {
    const BoneIndex num_bones = defining_anim_->NumBones();

    // Visual Studio 2010 does not like std::vectors of mat4, since they are
    // a 16-byte aligned type. Use plain old arrays instead.
    motivators_ = new MatrixMotivator4f[num_bones];
    global_transforms_ = new AffineTransform[num_bones];

    // Initialize the motivators that drive the local transforms.
    for (BoneIndex i = 0; i < num_bones; ++i) {
      const MatrixOpArray& ops = defining_anim_->Anim(i).ops();
      const MatrixInit matrix_init(ops, mat4(init.bone_transforms()[i]));
      motivators_[i].Initialize(matrix_init, engine);
    }

    // Initialize global transforms to default pose.
    // These will get overridden the first time AdvanceFrame() is called, but
    // we initialize them nicely anyway.
    UpdateGlobalTransforms();
  }

  ~RigData() {
    delete[] motivators_;
    motivators_ = nullptr;

    delete[] global_transforms_;
    global_transforms_ = nullptr;
  }

  void BlendToAnim(const RigAnim& anim, const fpl::SplinePlayback& playback,
                   MotiveTime start_time) {
    end_time_ = start_time + anim.end_time();

    // When animation has only one bone, or mesh has only one bone,
    // we simply animate the root node only.
    const int anim_num_bones = anim.NumBones();
    const int defining_num_bones = NumBones();
    assert(defining_num_bones == 1 || anim_num_bones == 1 ||
           RigInit::MatchesHierarchy(anim, *defining_anim_));

    // Update the motivators to blend to our new values.
    for (BoneIndex i = 0; i < defining_num_bones; ++i) {
      const MatrixOpArray& ops =
          i >= anim_num_bones ? kEmptyOps : anim.Anim(i).ops();
      motivators_[i].BlendToOps(ops, playback);
    }

    // Remember the currently playing animation, for debugging purposes.
    current_anim_ = &anim;
  }

  void UpdateGlobalTransforms() {
    CalculateGlobalTransforms(global_transforms_);
  }

  const AffineTransform* GlobalTransforms() const { return global_transforms_; }

  BoneIndex NumBones() const {
    return defining_anim_->NumBones();
  }

  MotiveTime end_time() const { return end_time_; }

  const RigAnim* defining_anim() const { return defining_anim_; }

  void ChildValuesForDebugging(std::vector<float>* values) const {
    values->resize(defining_anim_->NumOps());

    int k = 0;
    const int defining_num_bones = NumBones();
    for (BoneIndex i = 0; i < defining_num_bones; ++i) {
      const MotiveChildIndex num_children = motivators_[i].NumChildren();
      for (MotiveChildIndex j = 0; j < num_children; ++j) {
        (*values)[k++] = motivators_[i].ChildValue1f(j);
      }
    }
  }

  std::string CsvHeaderForDebugging() const {
    std::ostringstream oss;
    oss << "animation name,time," << defining_anim_->CsvHeaderForDebugging(0)
        << std::endl;
    oss << ",," << defining_anim_->CsvHeaderForDebugging(1) << std::endl;
    return oss.str();
  }

  std::string CsvValuesForDebugging(MotiveTime current_time) const {
    std::vector<float> values;
    ChildValuesForDebugging(&values);

    std::ostringstream oss;
    const MotiveTime anim_time =
        current_time - end_time_ + current_anim_->end_time();
    oss << current_anim_->anim_name() << ',' << anim_time << ',';

    int k = 0;
    const int defining_num_bones = NumBones();
    for (BoneIndex i = 0; i < defining_num_bones; ++i) {
      const MatrixOpArray::OpVector& ops = defining_anim_->Anim(i).ops().ops();
      for (size_t j = 0; j < ops.size(); ++j) {
        const float multiplier = RotateOp(ops[j].type) ? 180.0f / kPi : 1.0f;
        oss << multiplier * values[k] << ',';
        k++;
      }
    }

    return oss.str();
  }

 private:
  /// Traverse hierarchy, converting local transforms from `motivators_` into
  /// global transforms. The `parents` are layed out such that the parent
  /// always come before the child.
  // TODO OPT: optimize `parents` layout so that we can parallelize this call.
  void CalculateGlobalTransforms(AffineTransform* out) const {
    const BoneIndex* parents = defining_anim_->bone_parents();
    const int num_bones = NumBones();
    for (int i = 0; i < num_bones; ++i) {
      const mat4& local_transform = motivators_[i].Value();
      const int parent_idx = parents[i];
      if (parent_idx == kInvalidBoneIdx) {
        out[i] = mat4::PackAffine(local_transform);
      } else {
        assert(i > parent_idx);
        out[i] = mat4::PackAffine(mat4(out[parent_idx]) * local_transform);
      }
    }
  }

  MatrixMotivator4f* motivators_;
  AffineTransform* global_transforms_;
  const RigAnim* defining_anim_;
  const RigAnim* current_anim_;

  /// Time that the animation is expected to complete.
  MotiveTime end_time_;
};

// See comments on RigInit for details on this class.
class MotiveRigProcessor : public RigProcessor {
 public:
  MotiveRigProcessor() : time_(0) {}

  virtual ~MotiveRigProcessor() {
    const MotiveIndex num_indices = NumIndices();
    for (MotiveIndex index = 0; index < num_indices; ++index) {
      RemoveIndex(index);
    }
  }

  virtual void AdvanceFrame(MotiveTime delta_time) {
    Defragment();

    // Process the series of matrix operations for each index.
    const MotiveIndex num_indices = NumIndices();
    for (MotiveIndex index = 0; index < num_indices; ++index) {
      RigData& d = Data(index);
      d.UpdateGlobalTransforms();
    }

    // Update our global time. It shouldn't matter if this wraps
    // around, since we only calculate times relative to it.
    time_ += delta_time;
  }

  virtual void BlendToAnim(MotiveIndex index, const RigAnim& anim,
                           const fpl::SplinePlayback& playback) {
    Data(index).BlendToAnim(anim, playback, time_);
  }

  virtual MotivatorType Type() const { return RigInit::kType; }
  virtual int Priority() const { return 3; }

  virtual const AffineTransform* GlobalTransforms(MotiveIndex index) const {
    return Data(index).GlobalTransforms();
  }

  virtual MotiveTime TimeRemaining(MotiveIndex index) const {
    const MotiveTime end_time = Data(index).end_time();
    return end_time == kMotiveTimeEndless ? kMotiveTimeEndless
                                          : end_time - time_;
  }

  virtual const RigAnim* DefiningAnim(MotiveIndex index) const {
    return Data(index).defining_anim();
  }

  virtual std::string CsvHeaderForDebugging(MotiveIndex index) const {
    return Data(index).CsvHeaderForDebugging();
  }

  virtual std::string CsvValuesForDebugging(MotiveIndex index) const {
    return Data(index).CsvValuesForDebugging(time_);
  }

 protected:
  MotiveIndex NumIndices() const {
    return static_cast<MotiveIndex>(data_.size());
  }

  virtual void InitializeIndex(const MotivatorInit& init, MotiveIndex index,
                               MotiveEngine* engine) {
    RemoveIndex(index);
    auto rig_init = static_cast<const RigInit&>(init);
    data_[index] = new RigData(rig_init, time_, engine);
  }

  virtual void RemoveIndex(MotiveIndex index) {
    if (data_[index] != nullptr) {
      delete data_[index];
      data_[index] = nullptr;
    }
  }

  virtual void MoveIndex(MotiveIndex old_index, MotiveIndex new_index) {
    data_[new_index] = data_[old_index];
    data_[old_index] = nullptr;
  }

  virtual void SetNumIndices(MotiveIndex num_indices) {
    const MotiveIndex old_num_indices = NumIndices();

    // Ensure old items are deleted.
    for (MotiveIndex i = num_indices; i < old_num_indices; ++i) {
      RemoveIndex(i);
    }

    // Initialize new items to nullptr.
    data_.resize(num_indices, nullptr);
  }

  const RigData& Data(MotiveIndex index) const {
    assert(ValidIndex(index));
    return *data_[index];
  }

  RigData& Data(MotiveIndex index) {
    assert(ValidIndex(index));
    return *data_[index];
  }

  std::vector<RigData*> data_;
  MotiveTime time_;
};

MOTIVE_INSTANCE(RigInit, MotiveRigProcessor);

}  // namespace motive
<commit_msg>Use new mathfu::AffineTransform conversion functions.<commit_after>// Copyright 2014 Google Inc. All rights reserved.
//
// 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 <sstream>

#include "mathfu/constants.h"
#include "motive/anim.h"
#include "motive/engine.h"
#include "motive/init.h"
#include "motive/math/angle.h"
#include "motive/math/bulk_spline_evaluator.h"

using fpl::Angle;
using fpl::kPi;
using mathfu::AffineTransform;
using mathfu::mat4;
using mathfu::vec4;

namespace motive {

// static
mathfu::mat4 MatrixInit::kIdentityTransform(mathfu::mat4::Identity());
static const MatrixOpArray kEmptyOps(0);

class RigData {
 public:
  explicit RigData(const RigInit& init, MotiveTime start_time,
                   MotiveEngine* engine)
      : motivators_(nullptr),
        global_transforms_(nullptr),
        defining_anim_(&init.defining_anim()),
        current_anim_(nullptr),
        end_time_(start_time) {
    const BoneIndex num_bones = defining_anim_->NumBones();

    // Visual Studio 2010 does not like std::vectors of mat4, since they are
    // a 16-byte aligned type. Use plain old arrays instead.
    motivators_ = new MatrixMotivator4f[num_bones];
    global_transforms_ = new AffineTransform[num_bones];

    // Initialize the motivators that drive the local transforms.
    for (BoneIndex i = 0; i < num_bones; ++i) {
      const MatrixOpArray& ops = defining_anim_->Anim(i).ops();
      const MatrixInit matrix_init(
          ops, mat4::FromAffineTransform(init.bone_transforms()[i]));
      motivators_[i].Initialize(matrix_init, engine);
    }

    // Initialize global transforms to default pose.
    // These will get overridden the first time AdvanceFrame() is called, but
    // we initialize them nicely anyway.
    UpdateGlobalTransforms();
  }

  ~RigData() {
    delete[] motivators_;
    motivators_ = nullptr;

    delete[] global_transforms_;
    global_transforms_ = nullptr;
  }

  void BlendToAnim(const RigAnim& anim, const fpl::SplinePlayback& playback,
                   MotiveTime start_time) {
    end_time_ = start_time + anim.end_time();

    // When animation has only one bone, or mesh has only one bone,
    // we simply animate the root node only.
    const int anim_num_bones = anim.NumBones();
    const int defining_num_bones = NumBones();
    assert(defining_num_bones == 1 || anim_num_bones == 1 ||
           RigInit::MatchesHierarchy(anim, *defining_anim_));

    // Update the motivators to blend to our new values.
    for (BoneIndex i = 0; i < defining_num_bones; ++i) {
      const MatrixOpArray& ops =
          i >= anim_num_bones ? kEmptyOps : anim.Anim(i).ops();
      motivators_[i].BlendToOps(ops, playback);
    }

    // Remember the currently playing animation, for debugging purposes.
    current_anim_ = &anim;
  }

  void UpdateGlobalTransforms() {
    CalculateGlobalTransforms(global_transforms_);
  }

  const AffineTransform* GlobalTransforms() const { return global_transforms_; }

  BoneIndex NumBones() const {
    return defining_anim_->NumBones();
  }

  MotiveTime end_time() const { return end_time_; }

  const RigAnim* defining_anim() const { return defining_anim_; }

  void ChildValuesForDebugging(std::vector<float>* values) const {
    values->resize(defining_anim_->NumOps());

    int k = 0;
    const int defining_num_bones = NumBones();
    for (BoneIndex i = 0; i < defining_num_bones; ++i) {
      const MotiveChildIndex num_children = motivators_[i].NumChildren();
      for (MotiveChildIndex j = 0; j < num_children; ++j) {
        (*values)[k++] = motivators_[i].ChildValue1f(j);
      }
    }
  }

  std::string CsvHeaderForDebugging() const {
    std::ostringstream oss;
    oss << "animation name,time," << defining_anim_->CsvHeaderForDebugging(0)
        << std::endl;
    oss << ",," << defining_anim_->CsvHeaderForDebugging(1) << std::endl;
    return oss.str();
  }

  std::string CsvValuesForDebugging(MotiveTime current_time) const {
    std::vector<float> values;
    ChildValuesForDebugging(&values);

    std::ostringstream oss;
    const MotiveTime anim_time =
        current_time - end_time_ + current_anim_->end_time();
    oss << current_anim_->anim_name() << ',' << anim_time << ',';

    int k = 0;
    const int defining_num_bones = NumBones();
    for (BoneIndex i = 0; i < defining_num_bones; ++i) {
      const MatrixOpArray::OpVector& ops = defining_anim_->Anim(i).ops().ops();
      for (size_t j = 0; j < ops.size(); ++j) {
        const float multiplier = RotateOp(ops[j].type) ? 180.0f / kPi : 1.0f;
        oss << multiplier * values[k] << ',';
        k++;
      }
    }

    return oss.str();
  }

 private:
  /// Traverse hierarchy, converting local transforms from `motivators_` into
  /// global transforms. The `parents` are layed out such that the parent
  /// always come before the child.
  // TODO OPT: optimize `parents` layout so that we can parallelize this call.
  void CalculateGlobalTransforms(AffineTransform* out) const {
    const BoneIndex* parents = defining_anim_->bone_parents();
    const int num_bones = NumBones();
    for (int i = 0; i < num_bones; ++i) {
      const mat4& local_transform = motivators_[i].Value();
      const int parent_idx = parents[i];
      if (parent_idx == kInvalidBoneIdx) {
        out[i] = mat4::ToAffineTransform(local_transform);
      } else {
        assert(i > parent_idx);
        out[i] = mat4::ToAffineTransform(
            mat4::FromAffineTransform(out[parent_idx]) * local_transform);
      }
    }
  }

  MatrixMotivator4f* motivators_;
  AffineTransform* global_transforms_;
  const RigAnim* defining_anim_;
  const RigAnim* current_anim_;

  /// Time that the animation is expected to complete.
  MotiveTime end_time_;
};

// See comments on RigInit for details on this class.
class MotiveRigProcessor : public RigProcessor {
 public:
  MotiveRigProcessor() : time_(0) {}

  virtual ~MotiveRigProcessor() {
    const MotiveIndex num_indices = NumIndices();
    for (MotiveIndex index = 0; index < num_indices; ++index) {
      RemoveIndex(index);
    }
  }

  virtual void AdvanceFrame(MotiveTime delta_time) {
    Defragment();

    // Process the series of matrix operations for each index.
    const MotiveIndex num_indices = NumIndices();
    for (MotiveIndex index = 0; index < num_indices; ++index) {
      RigData& d = Data(index);
      d.UpdateGlobalTransforms();
    }

    // Update our global time. It shouldn't matter if this wraps
    // around, since we only calculate times relative to it.
    time_ += delta_time;
  }

  virtual void BlendToAnim(MotiveIndex index, const RigAnim& anim,
                           const fpl::SplinePlayback& playback) {
    Data(index).BlendToAnim(anim, playback, time_);
  }

  virtual MotivatorType Type() const { return RigInit::kType; }
  virtual int Priority() const { return 3; }

  virtual const AffineTransform* GlobalTransforms(MotiveIndex index) const {
    return Data(index).GlobalTransforms();
  }

  virtual MotiveTime TimeRemaining(MotiveIndex index) const {
    const MotiveTime end_time = Data(index).end_time();
    return end_time == kMotiveTimeEndless ? kMotiveTimeEndless
                                          : end_time - time_;
  }

  virtual const RigAnim* DefiningAnim(MotiveIndex index) const {
    return Data(index).defining_anim();
  }

  virtual std::string CsvHeaderForDebugging(MotiveIndex index) const {
    return Data(index).CsvHeaderForDebugging();
  }

  virtual std::string CsvValuesForDebugging(MotiveIndex index) const {
    return Data(index).CsvValuesForDebugging(time_);
  }

 protected:
  MotiveIndex NumIndices() const {
    return static_cast<MotiveIndex>(data_.size());
  }

  virtual void InitializeIndex(const MotivatorInit& init, MotiveIndex index,
                               MotiveEngine* engine) {
    RemoveIndex(index);
    auto rig_init = static_cast<const RigInit&>(init);
    data_[index] = new RigData(rig_init, time_, engine);
  }

  virtual void RemoveIndex(MotiveIndex index) {
    if (data_[index] != nullptr) {
      delete data_[index];
      data_[index] = nullptr;
    }
  }

  virtual void MoveIndex(MotiveIndex old_index, MotiveIndex new_index) {
    data_[new_index] = data_[old_index];
    data_[old_index] = nullptr;
  }

  virtual void SetNumIndices(MotiveIndex num_indices) {
    const MotiveIndex old_num_indices = NumIndices();

    // Ensure old items are deleted.
    for (MotiveIndex i = num_indices; i < old_num_indices; ++i) {
      RemoveIndex(i);
    }

    // Initialize new items to nullptr.
    data_.resize(num_indices, nullptr);
  }

  const RigData& Data(MotiveIndex index) const {
    assert(ValidIndex(index));
    return *data_[index];
  }

  RigData& Data(MotiveIndex index) {
    assert(ValidIndex(index));
    return *data_[index];
  }

  std::vector<RigData*> data_;
  MotiveTime time_;
};

MOTIVE_INSTANCE(RigInit, MotiveRigProcessor);

}  // namespace motive
<|endoftext|>