<commit_before>/*
 * Copyright (C) 2013 Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1.  Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 * 2.  Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"

#if ENABLE(WEBGL)

#include "EXTDrawBuffers.h"

#include "Extensions3D.h"

namespace WebCore {

EXTDrawBuffers::EXTDrawBuffers(WebGLRenderingContext* context)
    : WebGLExtension(context)
{
}

EXTDrawBuffers::~EXTDrawBuffers()
{
}

WebGLExtension::ExtensionName EXTDrawBuffers::getName() const
{
    return WebGLExtension::EXTDrawBuffersName;
}

PassOwnPtr<EXTDrawBuffers> EXTDrawBuffers::create(WebGLRenderingContext* context)
{
    return adoptPtr(new EXTDrawBuffers(context));
}

// static
bool EXTDrawBuffers::supported(WebGLRenderingContext* context)
{
#if OS(DARWIN)
    // https://bugs.webkit.org/show_bug.cgi?id=112486
    return false;
#endif
    Extensions3D* extensions = context->graphicsContext3D()->getExtensions();
    return (extensions->supports("GL_EXT_draw_buffers")
        && satisfiesWebGLRequirements(context));
}

void EXTDrawBuffers::drawBuffersEXT(const Vector<GC3Denum>& buffers)
{
    if (m_context->isContextLost())
        return;
    GC3Dsizei n = buffers.size();
    const GC3Denum* bufs = buffers.data();
    if (!m_context->m_framebufferBinding) {
        if (n != 1) {
            m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "drawBuffersEXT", "more than one buffer");
            return;
        }
        if (bufs[0] != GraphicsContext3D::BACK && bufs[0] != GraphicsContext3D::NONE) {
            m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "drawBuffersEXT", "BACK or NONE");
            return;
        }
        // Because the backbuffer is simulated on all current WebKit ports, we need to change BACK to COLOR_ATTACHMENT0.
        GC3Denum value = (bufs[0] == GraphicsContext3D::BACK) ? GraphicsContext3D::COLOR_ATTACHMENT0 : GraphicsContext3D::NONE;
        m_context->graphicsContext3D()->getExtensions()->drawBuffersEXT(1, &value);
        m_context->setBackDrawBuffer(bufs[0]);
    } else {
        if (n > m_context->getMaxDrawBuffers()) {
            m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "drawBuffersEXT", "more than max draw buffers");
            return;
        }
        for (GC3Dsizei i = 0; i < n; ++i) {
            if (bufs[i] != GraphicsContext3D::NONE && bufs[i] != static_cast<GC3Denum>(Extensions3D::COLOR_ATTACHMENT0_EXT + i)) {
                m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "drawBuffersEXT", "COLOR_ATTACHMENTi_EXT or NONE");
                return;
            }
        }
        m_context->m_framebufferBinding->drawBuffers(buffers);
    }
}

// static
bool EXTDrawBuffers::satisfiesWebGLRequirements(WebGLRenderingContext* webglContext)
{
    GraphicsContext3D* context = webglContext->graphicsContext3D();

    // This is called after we make sure GL_EXT_draw_buffers is supported.
    GC3Dint maxDrawBuffers = 0;
    GC3Dint maxColorAttachments = 0;
    context->getIntegerv(Extensions3D::MAX_DRAW_BUFFERS_EXT, &maxDrawBuffers);
    context->getIntegerv(Extensions3D::MAX_COLOR_ATTACHMENTS_EXT, &maxColorAttachments);
    if (maxDrawBuffers < 4 || maxColorAttachments < 4)
        return false;

    Platform3DObject fbo = context->createFramebuffer();
    context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, fbo);

#if PLATFORM(CHROMIUM)
    const unsigned char* buffer = 0; // Chromium doesn't allow init data for depth/stencil tetxures.
#else
    const unsigned char buffer[4] = { 0, 0, 0, 0 }; // textures are required to be initialized for other ports.
#endif
    bool supportsDepth = (context->getExtensions()->supports("GL_CHROMIUM_depth_texture")
        || context->getExtensions()->supports("GL_OES_depth_texture")
        || context->getExtensions()->supports("GL_ARB_depth_texture"));
    bool supportsDepthStencil = (context->getExtensions()->supports("GL_EXT_packed_depth_stencil")
        || context->getExtensions()->supports("GL_OES_packed_depth_stencil"));
    Platform3DObject depthStencil = 0;
    if (supportsDepthStencil) {
        depthStencil = context->createTexture();
        context->bindTexture(GraphicsContext3D::TEXTURE_2D, depthStencil);
        context->texImage2D(GraphicsContext3D::TEXTURE_2D, 0, GraphicsContext3D::DEPTH_STENCIL, 1, 1, 0, GraphicsContext3D::DEPTH_STENCIL, GraphicsContext3D::UNSIGNED_INT_24_8, buffer);
    }
    Platform3DObject depth = 0;
    if (supportsDepth) {
        depth = context->createTexture();
        context->bindTexture(GraphicsContext3D::TEXTURE_2D, depth);
        context->texImage2D(GraphicsContext3D::TEXTURE_2D, 0, GraphicsContext3D::DEPTH_COMPONENT, 1, 1, 0, GraphicsContext3D::DEPTH_COMPONENT, GraphicsContext3D::UNSIGNED_INT, buffer);
    }

    Vector<Platform3DObject> colors;
    bool ok = true;
    GC3Dint maxAllowedBuffers = std::min(maxDrawBuffers, maxColorAttachments);
    for (GC3Dint i = 0; i < maxAllowedBuffers; ++i) {
        Platform3DObject color = context->createTexture();
        colors.append(color);
        context->bindTexture(GraphicsContext3D::TEXTURE_2D, color);
        context->texImage2D(GraphicsContext3D::TEXTURE_2D, 0, GraphicsContext3D::RGBA, 1, 1, 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, buffer);
        context->framebufferTexture2D(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::COLOR_ATTACHMENT0 + i, GraphicsContext3D::TEXTURE_2D, color, 0);
        if (context->checkFramebufferStatus(GraphicsContext3D::FRAMEBUFFER) != GraphicsContext3D::FRAMEBUFFER_COMPLETE) {
            ok = false;
            break;
        }
        if (supportsDepth) {
            context->framebufferTexture2D(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::DEPTH_ATTACHMENT, GraphicsContext3D::TEXTURE_2D, depth, 0);
            if (context->checkFramebufferStatus(GraphicsContext3D::FRAMEBUFFER) != GraphicsContext3D::FRAMEBUFFER_COMPLETE) {
                ok = false;
                break;
            }
            context->framebufferTexture2D(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::DEPTH_ATTACHMENT, GraphicsContext3D::TEXTURE_2D, 0, 0);
        }
        if (supportsDepthStencil) {
            context->framebufferTexture2D(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::DEPTH_ATTACHMENT, GraphicsContext3D::TEXTURE_2D, depthStencil, 0);
            context->framebufferTexture2D(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::STENCIL_ATTACHMENT, GraphicsContext3D::TEXTURE_2D, depthStencil, 0);
            if (context->checkFramebufferStatus(GraphicsContext3D::FRAMEBUFFER) != GraphicsContext3D::FRAMEBUFFER_COMPLETE) {
                ok = false;
                break;
            }
            context->framebufferTexture2D(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::DEPTH_ATTACHMENT, GraphicsContext3D::TEXTURE_2D, 0, 0);
            context->framebufferTexture2D(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::STENCIL_ATTACHMENT, GraphicsContext3D::TEXTURE_2D, 0, 0);
        }
    }

    webglContext->restoreCurrentFramebuffer();
    context->deleteFramebuffer(fbo);
    webglContext->restoreCurrentTexture2D();
    if (supportsDepth)
        context->deleteTexture(depth);
    if (supportsDepthStencil)
        context->deleteTexture(depthStencil);
    for (size_t i = 0; i < colors.size(); ++i)
        context->deleteTexture(colors[i]);
    return ok;
}

} // namespace WebCore

#endif // ENABLE(WEBGL)
<commit_msg>Enable EXT_draw_buffers on Mac.<commit_after>/*
 * Copyright (C) 2013 Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1.  Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 * 2.  Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"

#if ENABLE(WEBGL)

#include "EXTDrawBuffers.h"

#include "Extensions3D.h"

namespace WebCore {

EXTDrawBuffers::EXTDrawBuffers(WebGLRenderingContext* context)
    : WebGLExtension(context)
{
}

EXTDrawBuffers::~EXTDrawBuffers()
{
}

WebGLExtension::ExtensionName EXTDrawBuffers::getName() const
{
    return WebGLExtension::EXTDrawBuffersName;
}

PassOwnPtr<EXTDrawBuffers> EXTDrawBuffers::create(WebGLRenderingContext* context)
{
    return adoptPtr(new EXTDrawBuffers(context));
}

// static
bool EXTDrawBuffers::supported(WebGLRenderingContext* context)
{
    Extensions3D* extensions = context->graphicsContext3D()->getExtensions();
    return (extensions->supports("GL_EXT_draw_buffers")
        && satisfiesWebGLRequirements(context));
}

void EXTDrawBuffers::drawBuffersEXT(const Vector<GC3Denum>& buffers)
{
    if (m_context->isContextLost())
        return;
    GC3Dsizei n = buffers.size();
    const GC3Denum* bufs = buffers.data();
    if (!m_context->m_framebufferBinding) {
        if (n != 1) {
            m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "drawBuffersEXT", "more than one buffer");
            return;
        }
        if (bufs[0] != GraphicsContext3D::BACK && bufs[0] != GraphicsContext3D::NONE) {
            m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "drawBuffersEXT", "BACK or NONE");
            return;
        }
        // Because the backbuffer is simulated on all current WebKit ports, we need to change BACK to COLOR_ATTACHMENT0.
        GC3Denum value = (bufs[0] == GraphicsContext3D::BACK) ? GraphicsContext3D::COLOR_ATTACHMENT0 : GraphicsContext3D::NONE;
        m_context->graphicsContext3D()->getExtensions()->drawBuffersEXT(1, &value);
        m_context->setBackDrawBuffer(bufs[0]);
    } else {
        if (n > m_context->getMaxDrawBuffers()) {
            m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "drawBuffersEXT", "more than max draw buffers");
            return;
        }
        for (GC3Dsizei i = 0; i < n; ++i) {
            if (bufs[i] != GraphicsContext3D::NONE && bufs[i] != static_cast<GC3Denum>(Extensions3D::COLOR_ATTACHMENT0_EXT + i)) {
                m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "drawBuffersEXT", "COLOR_ATTACHMENTi_EXT or NONE");
                return;
            }
        }
        m_context->m_framebufferBinding->drawBuffers(buffers);
    }
}

// static
bool EXTDrawBuffers::satisfiesWebGLRequirements(WebGLRenderingContext* webglContext)
{
    GraphicsContext3D* context = webglContext->graphicsContext3D();

    // This is called after we make sure GL_EXT_draw_buffers is supported.
    GC3Dint maxDrawBuffers = 0;
    GC3Dint maxColorAttachments = 0;
    context->getIntegerv(Extensions3D::MAX_DRAW_BUFFERS_EXT, &maxDrawBuffers);
    context->getIntegerv(Extensions3D::MAX_COLOR_ATTACHMENTS_EXT, &maxColorAttachments);
    if (maxDrawBuffers < 4 || maxColorAttachments < 4)
        return false;

    Platform3DObject fbo = context->createFramebuffer();
    context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, fbo);

#if PLATFORM(CHROMIUM)
    const unsigned char* buffer = 0; // Chromium doesn't allow init data for depth/stencil tetxures.
#else
    const unsigned char buffer[4] = { 0, 0, 0, 0 }; // textures are required to be initialized for other ports.
#endif
    bool supportsDepth = (context->getExtensions()->supports("GL_CHROMIUM_depth_texture")
        || context->getExtensions()->supports("GL_OES_depth_texture")
        || context->getExtensions()->supports("GL_ARB_depth_texture"));
    bool supportsDepthStencil = (context->getExtensions()->supports("GL_EXT_packed_depth_stencil")
        || context->getExtensions()->supports("GL_OES_packed_depth_stencil"));
    Platform3DObject depthStencil = 0;
    if (supportsDepthStencil) {
        depthStencil = context->createTexture();
        context->bindTexture(GraphicsContext3D::TEXTURE_2D, depthStencil);
        context->texImage2D(GraphicsContext3D::TEXTURE_2D, 0, GraphicsContext3D::DEPTH_STENCIL, 1, 1, 0, GraphicsContext3D::DEPTH_STENCIL, GraphicsContext3D::UNSIGNED_INT_24_8, buffer);
    }
    Platform3DObject depth = 0;
    if (supportsDepth) {
        depth = context->createTexture();
        context->bindTexture(GraphicsContext3D::TEXTURE_2D, depth);
        context->texImage2D(GraphicsContext3D::TEXTURE_2D, 0, GraphicsContext3D::DEPTH_COMPONENT, 1, 1, 0, GraphicsContext3D::DEPTH_COMPONENT, GraphicsContext3D::UNSIGNED_INT, buffer);
    }

    Vector<Platform3DObject> colors;
    bool ok = true;
    GC3Dint maxAllowedBuffers = std::min(maxDrawBuffers, maxColorAttachments);
    for (GC3Dint i = 0; i < maxAllowedBuffers; ++i) {
        Platform3DObject color = context->createTexture();
        colors.append(color);
        context->bindTexture(GraphicsContext3D::TEXTURE_2D, color);
        context->texImage2D(GraphicsContext3D::TEXTURE_2D, 0, GraphicsContext3D::RGBA, 1, 1, 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, buffer);
        context->framebufferTexture2D(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::COLOR_ATTACHMENT0 + i, GraphicsContext3D::TEXTURE_2D, color, 0);
        if (context->checkFramebufferStatus(GraphicsContext3D::FRAMEBUFFER) != GraphicsContext3D::FRAMEBUFFER_COMPLETE) {
            ok = false;
            break;
        }
        if (supportsDepth) {
            context->framebufferTexture2D(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::DEPTH_ATTACHMENT, GraphicsContext3D::TEXTURE_2D, depth, 0);
            if (context->checkFramebufferStatus(GraphicsContext3D::FRAMEBUFFER) != GraphicsContext3D::FRAMEBUFFER_COMPLETE) {
                ok = false;
                break;
            }
            context->framebufferTexture2D(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::DEPTH_ATTACHMENT, GraphicsContext3D::TEXTURE_2D, 0, 0);
        }
        if (supportsDepthStencil) {
            context->framebufferTexture2D(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::DEPTH_ATTACHMENT, GraphicsContext3D::TEXTURE_2D, depthStencil, 0);
            context->framebufferTexture2D(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::STENCIL_ATTACHMENT, GraphicsContext3D::TEXTURE_2D, depthStencil, 0);
            if (context->checkFramebufferStatus(GraphicsContext3D::FRAMEBUFFER) != GraphicsContext3D::FRAMEBUFFER_COMPLETE) {
                ok = false;
                break;
            }
            context->framebufferTexture2D(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::DEPTH_ATTACHMENT, GraphicsContext3D::TEXTURE_2D, 0, 0);
            context->framebufferTexture2D(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::STENCIL_ATTACHMENT, GraphicsContext3D::TEXTURE_2D, 0, 0);
        }
    }

    webglContext->restoreCurrentFramebuffer();
    context->deleteFramebuffer(fbo);
    webglContext->restoreCurrentTexture2D();
    if (supportsDepth)
        context->deleteTexture(depth);
    if (supportsDepthStencil)
        context->deleteTexture(depthStencil);
    for (size_t i = 0; i < colors.size(); ++i)
        context->deleteTexture(colors[i]);
    return ok;
}

} // namespace WebCore

#endif // ENABLE(WEBGL)
<|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.
 *
 ***************************************************************/

#include "classad/common.h"
#include "classad/source.h"
#include "classad/matchClassad.h"

using namespace std;

static char const *ATTR_UNOPTIMIZED_REQUIREMENTS = "UnoptimizedRequirements";

namespace classad {

MatchClassAd::
MatchClassAd()
{
	lCtx = rCtx = NULL;
	lad = rad = NULL;
	ladParent = radParent = NULL;
	symmetric_match = NULL;
	right_matches_left = NULL;
	left_matches_right = NULL;
	InitMatchClassAd( NULL, NULL );
}

MatchClassAd::
MatchClassAd( ClassAd *adl, ClassAd *adr ) : ClassAd()
{
	lad = rad = lCtx = rCtx = NULL;
	ladParent = radParent = NULL;
	InitMatchClassAd( adl, adr );
}

MatchClassAd::
~MatchClassAd()
{
}

MatchClassAd* MatchClassAd::
MakeMatchClassAd( ClassAd *adl, ClassAd *adr )
{
	return( new MatchClassAd( adl, adr ) );
}

bool MatchClassAd::
InitMatchClassAd( ClassAd *adl, ClassAd *adr )
{
	ClassAdParser parser;

		// clear out old info
	Clear( );
	lad = rad = NULL;
	lCtx = rCtx = NULL;

		// convenience expressions
	ClassAd *upd;
	if( !( upd = parser.ParseClassAd(
			"[symmetricMatch = RIGHT.requirements && LEFT.requirements ;"
			"leftMatchesRight = RIGHT.requirements ;"
			"rightMatchesLeft = LEFT.requirements ;"
			"leftRankValue = LEFT.rank ;"
			"rightRankValue = RIGHT.rank]" ) ) ) {
		Clear( );
		lCtx = NULL;
		rCtx = NULL;
		return( false );
	}
	Update( *upd );
	delete upd;

		// In the following, global-scope references to LEFT and RIGHT
		// are used to make things slightly more efficient.  That means
		// that this match ad should not be nested inside other ads.
		// Also for effiency, the left and right ads are actually
		// inserted as .LEFT and .RIGHT (ie at the top level) but
		// their parent scope is set to the lCtx and rCtx ads as
		// though they were inserted as lCtx.ad and rCtx.ad.  This way,
		// the most direct way to reference the ads is through the
		// top-level global names .LEFT and .RIGHT.

		// the left context
	if( !( lCtx = parser.ParseClassAd(
			"[other=.RIGHT;target=.RIGHT;my=.LEFT;ad=.LEFT]" ) ) ) {
		Clear( );
		lCtx = NULL;
		rCtx = NULL;
		return( false );
	}

		// the right context
	if( !( rCtx = parser.ParseClassAd(
			"[other=.LEFT;target=.LEFT;my=.RIGHT;ad=.RIGHT]" ) ) ) {
		delete lCtx;
		lCtx = rCtx = NULL;
		return( false );
	}

	// Insert the Ad resolver but also lookup before using b/c
	// there are no gaurentees not to collide.
	Insert( "lCtx", lCtx, false );
	Insert( "rCtx", rCtx, false );

	symmetric_match = Lookup("symmetricMatch");
	right_matches_left = Lookup("rightMatchesLeft");
	left_matches_right = Lookup("leftMatchesRight");

	if( !adl ) {
		adl = new ClassAd();
	}
	if( !adr ) {
		adr = new ClassAd();
	}
	ReplaceLeftAd( adl );
	ReplaceRightAd( adr );

	return( true );
}

bool MatchClassAd::
ReplaceLeftAd( ClassAd *ad )
{
	lad = ad;
	ladParent = ad ? ad->GetParentScope( ) : (ClassAd*)NULL;
	if( ad ) {
		if( !Insert( "LEFT", ad, false ) ) {
			lad = NULL;
			ladParent = NULL;
			Delete( "LEFT" );
			return false;
		}

		// For the ability to efficiently reference the ad via
		// .LEFT, it is inserted in the top match ad, but we want
		// its parent scope to be the context ad.
		lCtx->SetParentScope(this);
		lad->SetParentScope(lCtx);
	} else {
		Delete( "LEFT" );
	}
	return true;
}

bool MatchClassAd::
ReplaceRightAd( ClassAd *ad )
{
	rad = ad;
	radParent = ad ? ad->GetParentScope( ) : (ClassAd*)NULL;
	if( ad ) {
		if( !Insert( "RIGHT", ad , false ) ) {
			rad = NULL;
			radParent = NULL;
			Delete( "RIGHT" );
			return false;
		}

		// For the ability to efficiently reference the ad via
		// .RIGHT, it is inserted in the top match ad, but we want
		// its parent scope to be the context ad.
		rCtx->SetParentScope(this);
		rad->SetParentScope(rCtx);
	} else {
		Delete( "RIGHT" );
	}
	return true;
}

ClassAd *MatchClassAd::
GetLeftAd()
{
	return( lad );
}

ClassAd *MatchClassAd::
GetRightAd()
{
	return( rad );
}

ClassAd *MatchClassAd::
GetLeftContext( )
{
	return( lCtx );
}

ClassAd *MatchClassAd::
GetRightContext( )
{
	return( rCtx );
}

ClassAd *MatchClassAd::
RemoveLeftAd( )
{
	ClassAd *ad = lad;
	Remove( "LEFT" );
	if( lad ) {
		lad->SetParentScope( ladParent );
	}
	ladParent = NULL;
	lad = NULL;
	return( ad );
}

ClassAd *MatchClassAd::
RemoveRightAd( )
{
	ClassAd	*ad = rad;
	Remove( "RIGHT" );
	if( rad ) {
		rad->SetParentScope( radParent );
	}
	radParent = NULL;
	rad = NULL;
	return( ad );
}

bool MatchClassAd::
OptimizeRightAdForMatchmaking( ClassAd *ad, std::string *error_msg )
{
	return MatchClassAd::OptimizeAdForMatchmaking( ad, true, error_msg );
}

bool MatchClassAd::
OptimizeLeftAdForMatchmaking( ClassAd *ad, std::string *error_msg )
{
	return MatchClassAd::OptimizeAdForMatchmaking( ad, false, error_msg );
}

bool MatchClassAd::
OptimizeAdForMatchmaking( ClassAd *ad, bool is_right, std::string *error_msg )
{
	if( ad->Lookup("my") ||
		ad->Lookup("target") ||
		ad->Lookup("other") ||
		ad->Lookup(ATTR_UNOPTIMIZED_REQUIREMENTS) )
	{
		if( error_msg ) {
			*error_msg = "Optimization of matchmaking requirements failed, because ad already contains one of my, target, other, or UnoptimizedRequirements.";
		}
		return false;
	}

	ExprTree *requirements = ad->Lookup(ATTR_REQUIREMENTS);
	if( !requirements ) {
		if( error_msg ) {
			*error_msg = "No requirements found in ad to be optimized.";
		}
		return false;
	}

		// insert "my" into this ad so that references that use it
		// can be flattened
	if ( !_useOldClassAdSemantics ) {
		Value me;
		ExprTree * pLit;
		me.SetClassAdValue( ad );
		ad->Insert("my",(pLit=Literal::MakeLiteral(me)));
	}

		// insert "target" and "other" into this ad so references can be
		// _partially_ flattened to the more efficient .RIGHT or .LEFT
	char const *other = is_right ? "LEFT" : "RIGHT";
	ExprTree *target = AttributeReference::MakeAttributeReference(NULL,other,true);
	ExprTree *t2 = AttributeReference::MakeAttributeReference(NULL,other,true);

	ad->Insert("target",target);
	ad->Insert("other",t2);

	ExprTree *flat_requirements = NULL;
	Value flat_val;

	if( ad->FlattenAndInline(requirements,flat_val,flat_requirements) ) {
		if( !flat_requirements ) {
				// flattened to a value
			flat_requirements = Literal::MakeLiteral(flat_val);
		}
		if( flat_requirements ) {
				// save original requirements
			ExprTree *orig_requirements = ad->Remove(ATTR_REQUIREMENTS);
			if( orig_requirements ) {
				if( !ad->Insert(ATTR_UNOPTIMIZED_REQUIREMENTS,orig_requirements) )
				{
						// Now we have no requirements.  Very bad!
					if( error_msg ) {
						*error_msg = "Failed to rename original requirements.";
					}
					delete orig_requirements;
					delete flat_requirements;
					return false;
				}
			}

				// insert new flattened requirements
			if( !ad->Insert(ATTR_REQUIREMENTS,flat_requirements) ) {
				if( error_msg ) {
					*error_msg = "Failed to insert optimized requirements.";
				}
				delete flat_requirements;
				return false;
			}
		}
	}

		// After flatenning, no references should remain to MY or TARGET.
		// Even if there are, those can be resolved by the context ads, so
		// we don't need to leave these attributes in the ad.
	if ( !_useOldClassAdSemantics ) {
		ad->Delete("my");
	}
	ad->Delete("other");
	ad->Delete("target");

	return true;
}

bool MatchClassAd::
UnoptimizeAdForMatchmaking( ClassAd *ad )
{
	ExprTree *orig_requirements = ad->Remove(ATTR_UNOPTIMIZED_REQUIREMENTS);
	if( orig_requirements ) {
		if( !ad->Insert(ATTR_REQUIREMENTS,orig_requirements) ) {
			return false;
		}
	}
	return true;
}

bool MatchClassAd::
EvalMatchExpr(ExprTree *match_expr)
{
	Value val;
	if( !match_expr ) {
		return false;
	}

	if( EvaluateExpr( match_expr, val ) ) {
		bool result = false;
		if( val.IsBooleanValueEquiv( result ) ) {
			return result;
		}
		long long int_result = 0;
		if( val.IsIntegerValue( int_result ) ) {
			return int_result != 0;
		}
	}
	return false;
}

bool MatchClassAd::
symmetricMatch()
{
	return EvalMatchExpr( symmetric_match );
}

bool MatchClassAd::
rightMatchesLeft()
{
	return EvalMatchExpr( right_matches_left );
}

bool MatchClassAd::
leftMatchesRight()
{
	return EvalMatchExpr( left_matches_right );
}

} // classad
<commit_msg>Make Target scoping option in MatchClassAd with old semantics. #5550<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 "classad/common.h"
#include "classad/source.h"
#include "classad/matchClassad.h"

using namespace std;

static char const *ATTR_UNOPTIMIZED_REQUIREMENTS = "UnoptimizedRequirements";

namespace classad {

MatchClassAd::
MatchClassAd()
{
	lCtx = rCtx = NULL;
	lad = rad = NULL;
	ladParent = radParent = NULL;
	symmetric_match = NULL;
	right_matches_left = NULL;
	left_matches_right = NULL;
	InitMatchClassAd( NULL, NULL );
}

MatchClassAd::
MatchClassAd( ClassAd *adl, ClassAd *adr ) : ClassAd()
{
	lad = rad = lCtx = rCtx = NULL;
	ladParent = radParent = NULL;
	InitMatchClassAd( adl, adr );
}

MatchClassAd::
~MatchClassAd()
{
}

MatchClassAd* MatchClassAd::
MakeMatchClassAd( ClassAd *adl, ClassAd *adr )
{
	return( new MatchClassAd( adl, adr ) );
}

bool MatchClassAd::
InitMatchClassAd( ClassAd *adl, ClassAd *adr )
{
	ClassAdParser parser;

		// clear out old info
	Clear( );
	lad = rad = NULL;
	lCtx = rCtx = NULL;

		// convenience expressions
	ClassAd *upd;
	if( !( upd = parser.ParseClassAd(
			"[symmetricMatch = RIGHT.requirements && LEFT.requirements ;"
			"leftMatchesRight = RIGHT.requirements ;"
			"rightMatchesLeft = LEFT.requirements ;"
			"leftRankValue = LEFT.rank ;"
			"rightRankValue = RIGHT.rank]" ) ) ) {
		Clear( );
		lCtx = NULL;
		rCtx = NULL;
		return( false );
	}
	Update( *upd );
	delete upd;

		// In the following, global-scope references to LEFT and RIGHT
		// are used to make things slightly more efficient.  That means
		// that this match ad should not be nested inside other ads.
		// Also for effiency, the left and right ads are actually
		// inserted as .LEFT and .RIGHT (ie at the top level) but
		// their parent scope is set to the lCtx and rCtx ads as
		// though they were inserted as lCtx.ad and rCtx.ad.  This way,
		// the most direct way to reference the ads is through the
		// top-level global names .LEFT and .RIGHT.

		// the left context
	if( !( lCtx = parser.ParseClassAd(
			"[other=.RIGHT;target=.RIGHT;my=.LEFT;ad=.LEFT]" ) ) ) {
		Clear( );
		lCtx = NULL;
		rCtx = NULL;
		return( false );
	}

		// the right context
	if( !( rCtx = parser.ParseClassAd(
			"[other=.LEFT;target=.LEFT;my=.RIGHT;ad=.RIGHT]" ) ) ) {
		delete lCtx;
		lCtx = rCtx = NULL;
		return( false );
	}

	// Insert the Ad resolver but also lookup before using b/c
	// there are no gaurentees not to collide.
	Insert( "lCtx", lCtx, false );
	Insert( "rCtx", rCtx, false );

	symmetric_match = Lookup("symmetricMatch");
	right_matches_left = Lookup("rightMatchesLeft");
	left_matches_right = Lookup("leftMatchesRight");

	if( !adl ) {
		adl = new ClassAd();
	}
	if( !adr ) {
		adr = new ClassAd();
	}
	ReplaceLeftAd( adl );
	ReplaceRightAd( adr );

	return( true );
}

bool MatchClassAd::
ReplaceLeftAd( ClassAd *ad )
{
	lad = ad;
	ladParent = ad ? ad->GetParentScope( ) : (ClassAd*)NULL;
	if( ad ) {
		if( !Insert( "LEFT", ad, false ) ) {
			lad = NULL;
			ladParent = NULL;
			Delete( "LEFT" );
			return false;
		}

		// For the ability to efficiently reference the ad via
		// .LEFT, it is inserted in the top match ad, but we want
		// its parent scope to be the context ad.
		lCtx->SetParentScope(this);
		lad->SetParentScope(lCtx);

		if ( _useOldClassAdSemantics ) {
			lad->alternateScope = rad;
		}
	} else {
		Delete( "LEFT" );
	}
	if ( rad && _useOldClassAdSemantics ) {
		rad->alternateScope = lad;
	}
	return true;
}

bool MatchClassAd::
ReplaceRightAd( ClassAd *ad )
{
	rad = ad;
	radParent = ad ? ad->GetParentScope( ) : (ClassAd*)NULL;
	if( ad ) {
		if( !Insert( "RIGHT", ad , false ) ) {
			rad = NULL;
			radParent = NULL;
			Delete( "RIGHT" );
			return false;
		}

		// For the ability to efficiently reference the ad via
		// .RIGHT, it is inserted in the top match ad, but we want
		// its parent scope to be the context ad.
		rCtx->SetParentScope(this);
		rad->SetParentScope(rCtx);

		if ( _useOldClassAdSemantics ) {
			rad->alternateScope = lad;
		}
	} else {
		Delete( "RIGHT" );
	}
	if ( lad && _useOldClassAdSemantics ) {
		lad->alternateScope = rad;
	}
	return true;
}

ClassAd *MatchClassAd::
GetLeftAd()
{
	return( lad );
}

ClassAd *MatchClassAd::
GetRightAd()
{
	return( rad );
}

ClassAd *MatchClassAd::
GetLeftContext( )
{
	return( lCtx );
}

ClassAd *MatchClassAd::
GetRightContext( )
{
	return( rCtx );
}

ClassAd *MatchClassAd::
RemoveLeftAd( )
{
	ClassAd *ad = lad;
	Remove( "LEFT" );
	if( lad ) {
		lad->SetParentScope( ladParent );
		if ( _useOldClassAdSemantics && rad ) {
			lad->alternateScope = NULL;
			rad->alternateScope = NULL;
		}
	}
	ladParent = NULL;
	lad = NULL;
	return( ad );
}

ClassAd *MatchClassAd::
RemoveRightAd( )
{
	ClassAd	*ad = rad;
	Remove( "RIGHT" );
	if( rad ) {
		rad->SetParentScope( radParent );
		if ( _useOldClassAdSemantics && lad ) {
			lad->alternateScope = NULL;
			rad->alternateScope = NULL;
		}
	}
	radParent = NULL;
	rad = NULL;
	return( ad );
}

bool MatchClassAd::
OptimizeRightAdForMatchmaking( ClassAd *ad, std::string *error_msg )
{
	return MatchClassAd::OptimizeAdForMatchmaking( ad, true, error_msg );
}

bool MatchClassAd::
OptimizeLeftAdForMatchmaking( ClassAd *ad, std::string *error_msg )
{
	return MatchClassAd::OptimizeAdForMatchmaking( ad, false, error_msg );
}

bool MatchClassAd::
OptimizeAdForMatchmaking( ClassAd *ad, bool is_right, std::string *error_msg )
{
	if( ad->Lookup("my") ||
		ad->Lookup("target") ||
		ad->Lookup("other") ||
		ad->Lookup(ATTR_UNOPTIMIZED_REQUIREMENTS) )
	{
		if( error_msg ) {
			*error_msg = "Optimization of matchmaking requirements failed, because ad already contains one of my, target, other, or UnoptimizedRequirements.";
		}
		return false;
	}

	ExprTree *requirements = ad->Lookup(ATTR_REQUIREMENTS);
	if( !requirements ) {
		if( error_msg ) {
			*error_msg = "No requirements found in ad to be optimized.";
		}
		return false;
	}

		// insert "my" into this ad so that references that use it
		// can be flattened
	if ( !_useOldClassAdSemantics ) {
		Value me;
		ExprTree * pLit;
		me.SetClassAdValue( ad );
		ad->Insert("my",(pLit=Literal::MakeLiteral(me)));
	}

		// insert "target" and "other" into this ad so references can be
		// _partially_ flattened to the more efficient .RIGHT or .LEFT
	char const *other = is_right ? "LEFT" : "RIGHT";
	ExprTree *target = AttributeReference::MakeAttributeReference(NULL,other,true);
	ExprTree *t2 = AttributeReference::MakeAttributeReference(NULL,other,true);

	ad->Insert("target",target);
	ad->Insert("other",t2);

	ExprTree *flat_requirements = NULL;
	Value flat_val;

	if( ad->FlattenAndInline(requirements,flat_val,flat_requirements) ) {
		if( !flat_requirements ) {
				// flattened to a value
			flat_requirements = Literal::MakeLiteral(flat_val);
		}
		if( flat_requirements ) {
				// save original requirements
			ExprTree *orig_requirements = ad->Remove(ATTR_REQUIREMENTS);
			if( orig_requirements ) {
				if( !ad->Insert(ATTR_UNOPTIMIZED_REQUIREMENTS,orig_requirements) )
				{
						// Now we have no requirements.  Very bad!
					if( error_msg ) {
						*error_msg = "Failed to rename original requirements.";
					}
					delete orig_requirements;
					delete flat_requirements;
					return false;
				}
			}

				// insert new flattened requirements
			if( !ad->Insert(ATTR_REQUIREMENTS,flat_requirements) ) {
				if( error_msg ) {
					*error_msg = "Failed to insert optimized requirements.";
				}
				delete flat_requirements;
				return false;
			}
		}
	}

		// After flatenning, no references should remain to MY or TARGET.
		// Even if there are, those can be resolved by the context ads, so
		// we don't need to leave these attributes in the ad.
	if ( !_useOldClassAdSemantics ) {
		ad->Delete("my");
	}
	ad->Delete("other");
	ad->Delete("target");

	return true;
}

bool MatchClassAd::
UnoptimizeAdForMatchmaking( ClassAd *ad )
{
	ExprTree *orig_requirements = ad->Remove(ATTR_UNOPTIMIZED_REQUIREMENTS);
	if( orig_requirements ) {
		if( !ad->Insert(ATTR_REQUIREMENTS,orig_requirements) ) {
			return false;
		}
	}
	return true;
}

bool MatchClassAd::
EvalMatchExpr(ExprTree *match_expr)
{
	Value val;
	if( !match_expr ) {
		return false;
	}

	if( EvaluateExpr( match_expr, val ) ) {
		bool result = false;
		if( val.IsBooleanValueEquiv( result ) ) {
			return result;
		}
		long long int_result = 0;
		if( val.IsIntegerValue( int_result ) ) {
			return int_result != 0;
		}
	}
	return false;
}

bool MatchClassAd::
symmetricMatch()
{
	return EvalMatchExpr( symmetric_match );
}

bool MatchClassAd::
rightMatchesLeft()
{
	return EvalMatchExpr( right_matches_left );
}

bool MatchClassAd::
leftMatchesRight()
{
	return EvalMatchExpr( left_matches_right );
}

} // classad
<|endoftext|>


<commit_before>#include "ship_instance.h"

ShipCarrier::ShipCarrier(int id, std::vector<float> d) : Ship(id, 1000, 400, d, 9.5, 100, .5, .5) {}
ShipScout::ShipScout(int id, std::vector<float> d) : Ship(id, 200, 100, d, .2, 500, 1, 1) {}
ShipFighter::ShipFighter(int id, std::vector<float> d) : Ship(id, 400, 200, d, .4, 200, 5, 5) {}
<commit_msg>Changed presets<commit_after>#include "ship_instance.h"

ShipCarrier::ShipCarrier(int id, std::vector<float> d) : Ship(id, 1000, 400, d, 9.5, 100, .5, .5) {}
ShipScout::ShipScout(int id, std::vector<float> d) : Ship(id, 200, 100, d, .2, 500, .5, .5) {}
ShipFighter::ShipFighter(int id, std::vector<float> d) : Ship(id, 400, 200, d, .4, 200, .5, .5) {}
<|endoftext|>


<commit_before>#ifndef MJOLNIR_READ_OBSERVER_HPP
#define MJOLNIR_READ_OBSERVER_HPP
#include <extlib/toml/toml.hpp>
#include <mjolnir/core/ObserverContainer.hpp>
#include <mjolnir/core/EnergyObserver.hpp>
#include <mjolnir/core/XYZObserver.hpp>
#include <mjolnir/core/DCDObserver.hpp>
#include <mjolnir/util/logger.hpp>
#include <mjolnir/util/make_unique.hpp>

namespace mjolnir
{

template<typename traitsT>
ObserverContainer<traitsT>
read_observer(const toml::table& root)
{
    MJOLNIR_GET_DEFAULT_LOGGER();
    MJOLNIR_LOG_FUNCTION();

    const auto& files  = toml::find<toml::value>(root, "files");
    const auto& output = toml::find<toml::value>(files, "output");

    const auto progress_bar_enabled = toml::expect<bool>(output, "progress_bar")
                                                        .unwrap_or(true);

    std::string output_path("./");
    if(toml::get<toml::table>(output).count("path") == 1)
    {
        output_path = toml::find<std::string>(output, "path");
        if(output_path.back() != '/') {output_path += '/';}
    }
    const auto output_prefix = toml::find<std::string>(output, "prefix");
    MJOLNIR_LOG_NOTICE("output files are `", output_path, output_prefix, ".*`");

    const std::string file_prefix = output_path + output_prefix;

    ObserverContainer<traitsT> observers(progress_bar_enabled);

    // Energy is always written to "prefix.ene".
    observers.push_back(make_unique<EnergyObserver<traitsT>>(file_prefix));

    const auto& format = toml::find<std::string>(output, "format");
    if(format == "xyz")
    {
        using observer_type = XYZObserver<traitsT>;
        MJOLNIR_LOG_NOTICE("output format is xyz.");
        observers.push_back(make_unique<observer_type>(file_prefix));
        return observers;
    }
    if(format == "dcd")
    {
        using observer_type = DCDObserver<traitsT>;
        MJOLNIR_LOG_NOTICE("output format is dcd.");
        observers.push_back(make_unique<observer_type>(file_prefix));
        return observers;
    }
    else
    {
        throw_exception<std::runtime_error>(toml::format_error("[error] "
            "mjolnir::read_observer: output format not supported",
            toml::find(output, "format"), "here", {
            "expected one of the following.",
            "- \"xyz\": the simplest ascii format",
            "- \"dcd\": widely used DCD format"
            }));
    }
}

} // mjolnir
#endif// MJOLNIR_READ_OBSERVER_HPP
<commit_msg>feat: allow array for `files.output.format`<commit_after>#ifndef MJOLNIR_READ_OBSERVER_HPP
#define MJOLNIR_READ_OBSERVER_HPP
#include <extlib/toml/toml.hpp>
#include <mjolnir/core/ObserverContainer.hpp>
#include <mjolnir/core/EnergyObserver.hpp>
#include <mjolnir/core/XYZObserver.hpp>
#include <mjolnir/core/DCDObserver.hpp>
#include <mjolnir/util/logger.hpp>
#include <mjolnir/util/make_unique.hpp>

namespace mjolnir
{

template<typename traitsT>
void add_observer(ObserverContainer<traitsT>& observers,
                  const toml::value& format, const std::string& file_prefix)
{
    MJOLNIR_GET_DEFAULT_LOGGER();
    MJOLNIR_LOG_FUNCTION();

    // To show the informative error message, here it uses toml::value that
    // contains file location. But this function assumes that the `format`
    // contains `toml::string`.
    assert(format.is(toml::value_t::String));

    if(format == "xyz")
    {
        using observer_type = XYZObserver<traitsT>;
        MJOLNIR_LOG_NOTICE("output xyz format.");
        observers.push_back(make_unique<observer_type>(file_prefix));
        return;
    }
    if(format == "dcd")
    {
        using observer_type = DCDObserver<traitsT>;
        MJOLNIR_LOG_NOTICE("output dcd format.");
        observers.push_back(make_unique<observer_type>(file_prefix));
        return;
    }
    else
    {
        throw_exception<std::runtime_error>(toml::format_error("[error] "
            "mjolnir::read_observer: output format not supported", format,
            "here", {
                "expected one of the following.",
                "- \"xyz\": the simplest ascii format",
                "- \"dcd\": widely used binary format"
            }));
    }
    return ;
}

template<typename traitsT>
ObserverContainer<traitsT>
read_observer(const toml::table& root)
{
    MJOLNIR_GET_DEFAULT_LOGGER();
    MJOLNIR_LOG_FUNCTION();

    const auto& files  = toml::find<toml::value>(root, "files");
    const auto& output = toml::find<toml::value>(files, "output");

    const auto progress_bar_enabled = toml::expect<bool>(output, "progress_bar")
                                                        .unwrap_or(true);
    std::string output_path("./");
    if(toml::get<toml::table>(output).count("path") == 1)
    {
        output_path = toml::find<std::string>(output, "path");
        if(output_path.back() != '/') {output_path += '/';}
    }
    const auto output_prefix = toml::find<std::string>(output, "prefix");
    MJOLNIR_LOG_NOTICE("output file prefix is `", output_path, output_prefix, '`');

    const std::string file_prefix = output_path + output_prefix;

    // ------------------------------------------------------------------------

    ObserverContainer<traitsT> observers(progress_bar_enabled);

    // Energy is always written to "prefix.ene".
    observers.push_back(make_unique<EnergyObserver<traitsT>>(file_prefix));

    const auto& format = toml::find(output, "format");

    if(format.is(toml::value_t::String))
    {
        add_observer(observers, format, file_prefix);
    }
    else if(format.is(toml::value_t::Array))
    {
        const auto fmts = toml::get<toml::array>(format);
        for(const auto& fmt : fmts)
        {
            add_observer(observers, fmt, file_prefix);
        }
    }
    return observers;
}

} // mjolnir
#endif// MJOLNIR_READ_OBSERVER_HPP
<|endoftext|>


<commit_before>/*
    Copyright (C) 2003 by Frank Richter

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public
    License along with this library; if not, write to the Free
    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#include "cssysdef.h"
#include "cssys/sysfunc.h"
#include "cssys/syspath.h"
#include "csutil/cstring.h"
#include "csutil/util.h"
#include <string.h>

char* csGetAppDir (const char* argv0)
{
  char* appdir = 0;
  char* apppath = csGetAppPath(argv0);
  if (apppath != 0)
  {
    char* slash = strrchr (apppath, PATH_SEPARATOR);
    if (slash != 0)
      *slash = '\0';
    appdir = csStrNew (apppath);
    delete[] apppath;
  }
  return appdir;
}
<commit_msg>Removed '#include "csutil/string.h"', which does not exist from appdir.cpp.<commit_after>/*
    Copyright (C) 2003 by Frank Richter

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public
    License along with this library; if not, write to the Free
    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#include "cssysdef.h"
#include "cssys/sysfunc.h"
#include "cssys/syspath.h"
#include "csutil/util.h"
#include <string.h>

char* csGetAppDir (const char* argv0)
{
  char* appdir = 0;
  char* apppath = csGetAppPath(argv0);
  if (apppath != 0)
  {
    char* slash = strrchr (apppath, PATH_SEPARATOR);
    if (slash != 0)
      *slash = '\0';
    appdir = csStrNew (apppath);
    delete[] apppath;
  }
  return appdir;
}
<|endoftext|>


<commit_before>#include "statistics.h"

TI_NAMESPACE_BEGIN

Statistics stat;

void Statistics::add(std::string key, Statistics::value_type value) {
  counters[key] += value;
}

void Statistics::print(std::string *output) {
  std::vector<std::string> keys;
  for (auto const &item : counters)
    keys.push_back(item.first);

  std::sort(keys.begin(), keys.end());

  std::stringstream ss;
  for (auto const &k : keys)
    ss << fmt::format("{:20}: {:.2f}\n", k, counters[k]);

  if (output) {
    *output = ss.str();
  } else {
    fmt::print(ss.str());
  }
}

void Statistics::clear() {
  counters.clear();
}

TI_NAMESPACE_END
<commit_msg>[misc] Avoid printing empty logs (#848)<commit_after>#include "statistics.h"

TI_NAMESPACE_BEGIN

Statistics stat;

void Statistics::add(std::string key, Statistics::value_type value) {
  counters[key] += value;
}

void Statistics::print(std::string *output) {
  std::vector<std::string> keys;
  for (auto const &item : counters)
    keys.push_back(item.first);

  std::sort(keys.begin(), keys.end());

  std::stringstream ss;
  for (auto const &k : keys)
    ss << fmt::format("{:20}: {:.2f}\n", k, counters[k]);

  if (output) {
    *output = ss.str();
  } else {
    fmt::print(ss.str());
  }
}

void Statistics::clear() {
  counters.clear();
  counters["codegen_statements"] = 0;
  counters["codegen_offloaded_tasks"] = 0;
}

TI_NAMESPACE_END
<|endoftext|>


<commit_before>#include "SVM_VirtualMachine.h"
#include "SVM_Opcodes.h"
#include "ShogunVM.h"

#include <fstream>
#include <iomanip>

namespace Shogun
{
	VirtualMachine::VirtualMachine(Memory::MemSize initialMemory)
		: memory(initialMemory)
	{
	}

	VirtualMachine::~VirtualMachine()
	{
	}

	Memory& VirtualMachine::getMemory()
	{
		return this->memory;
	}

	Stack& VirtualMachine::getStack()
	{
		return this->stack;
	}

	VMCallMap& VirtualMachine::getCallMap()
	{
		return this->callMap;
	}

	void VirtualMachine::loadProgram(const Program& program)
	{
		memory.resize(program.size() + 3);
		setRegMmx(program.size() + 2);

		stack.clear();

		UInt32 i = 1;
		for (auto it = program.cbegin(); it != program.cend(); ++it)
		{
			memory.set(i, *it);
			i++;
		}

		setRegPri(1);
	}

	void VirtualMachine::importProgram(const Program& program)
	{
		memory.resize(memory.getSize() + program.size());

		UInt32 i = getRegMmx();
		setRegMmx(memory.getSize());

		for (auto it = program.cbegin(); it != program.cend(); ++it)
		{
			memory.set(i, *it);
			i++;
		}
	}

	void VirtualMachine::run()
	{
		this->running = true;
		while (this->running)
		{
			UInt32 opcode = memory.get(getRegPri())->getAddress();
			executeOperation(this, (Opcode)opcode);
			this->setRegPri(this->getRegPri() + 1);
		}
	}

	void VirtualMachine::dump()
	{
		dumpStack(std::cerr);

		std::ofstream dump;
		dump.open("shogun.dump", std::ios::out | std::ios::trunc);
		if (!dump.is_open()) {
			std::cerr << "Unable to open shogun.dump to output dump." << std::endl;
			return;
		}

		dumpStack(dump);
		dumpHeap(dump);

		std::cerr << "Full dump at shogun.dump" << std::endl;
	}

	void VirtualMachine::dumpStack(std::ostream& stream)
	{
		auto t = std::time(nullptr);
		auto tm = *std::localtime(&t);

		stream << "ShogunVM version " << Shogun::version_string() << "-" << Shogun::version() << std::endl;
		stream << "dump time - " << std::put_time(&tm, "%Y-%m-%d %H-%M-%S") << std::endl;
		stream << "----------" << std::endl;
		stream << "Registers:" << std::endl;
		stream << "  PRI = " << this->getRegPri() << std::endl;
		stream << "  MMX = " << this->getRegMmx() << std::endl;
		stream << "----------" << std::endl;
		stream << "Stack:" << std::endl;

		for (Stack::iterator it = stack.begin(); it != stack.end(); ++it)
		{
			stream << "> " << (*it)->getReadableString() << std::endl;
		}

		stream << "----------" << std::endl;
		stream << "- end of stack dump" << std::endl;
	}

	void VirtualMachine::dumpHeap(std::ostream& stream)
	{
		auto t = std::time(nullptr);
		auto tm = *std::localtime(&t);

		stream << "ShogunVM version " << Shogun::version_string() << "-" << Shogun::version() << std::endl;
		stream << "dump time - " << std::put_time(&tm, "%Y-%m-%d %H-%M-%S") << std::endl;
		stream << "----------" << std::endl;
		stream << "Registers:" << std::endl;
		stream << "  PRI = " << this->getRegPri() << std::endl;
		stream << "  MMX = " << this->getRegMmx() << std::endl;
		stream << "----------" << std::endl;
		stream << "Heap:" << std::endl;

		for (Memory::MemSize i = 0; i < memory.getSize(); ++i)
		{
			stream << "[" << i << "] " << memory.get(i)->getReadableString() << std::endl;
		}

		stream << "- end of heap dump" << std::endl;
	}
}<commit_msg>show pri and mmx in heap dump<commit_after>#include "SVM_VirtualMachine.h"
#include "SVM_Opcodes.h"
#include "ShogunVM.h"

#include <fstream>
#include <iomanip>

namespace Shogun
{
	VirtualMachine::VirtualMachine(Memory::MemSize initialMemory)
		: memory(initialMemory)
	{
	}

	VirtualMachine::~VirtualMachine()
	{
	}

	Memory& VirtualMachine::getMemory()
	{
		return this->memory;
	}

	Stack& VirtualMachine::getStack()
	{
		return this->stack;
	}

	VMCallMap& VirtualMachine::getCallMap()
	{
		return this->callMap;
	}

	void VirtualMachine::loadProgram(const Program& program)
	{
		memory.resize(program.size() + 3);
		setRegMmx(program.size() + 2);

		stack.clear();

		UInt32 i = 1;
		for (auto it = program.cbegin(); it != program.cend(); ++it)
		{
			memory.set(i, *it);
			i++;
		}

		setRegPri(1);
	}

	void VirtualMachine::importProgram(const Program& program)
	{
		memory.resize(memory.getSize() + program.size());

		UInt32 i = getRegMmx();
		setRegMmx(memory.getSize());

		for (auto it = program.cbegin(); it != program.cend(); ++it)
		{
			memory.set(i, *it);
			i++;
		}
	}

	void VirtualMachine::run()
	{
		this->running = true;
		while (this->running)
		{
			UInt32 opcode = memory.get(getRegPri())->getAddress();
			executeOperation(this, (Opcode)opcode);
			this->setRegPri(this->getRegPri() + 1);
		}
	}

	void VirtualMachine::dump()
	{
		dumpStack(std::cerr);

		std::ofstream dump;
		dump.open("shogun.dump", std::ios::out | std::ios::trunc);
		if (!dump.is_open()) {
			std::cerr << "Unable to open shogun.dump to output dump." << std::endl;
			return;
		}

		dumpStack(dump);
		dumpHeap(dump);

		std::cerr << "Full dump at shogun.dump" << std::endl;
	}

	void VirtualMachine::dumpStack(std::ostream& stream)
	{
		auto t = std::time(nullptr);
		auto tm = *std::localtime(&t);

		stream << "ShogunVM version " << Shogun::version_string() << "-" << Shogun::version() << std::endl;
		stream << "dump time - " << std::put_time(&tm, "%Y-%m-%d %H-%M-%S") << std::endl;
		stream << "----------" << std::endl;
		stream << "Registers:" << std::endl;
		stream << "  PRI = " << this->getRegPri() << std::endl;
		stream << "  MMX = " << this->getRegMmx() << std::endl;
		stream << "----------" << std::endl;
		stream << "Stack:" << std::endl;

		for (Stack::iterator it = stack.begin(); it != stack.end(); ++it)
		{
			stream << "> " << (*it)->getReadableString() << std::endl;
		}

		stream << "----------" << std::endl;
		stream << "- end of stack dump" << std::endl;
	}

	void VirtualMachine::dumpHeap(std::ostream& stream)
	{
		auto t = std::time(nullptr);
		auto tm = *std::localtime(&t);

		stream << "ShogunVM version " << Shogun::version_string() << "-" << Shogun::version() << std::endl;
		stream << "dump time - " << std::put_time(&tm, "%Y-%m-%d %H-%M-%S") << std::endl;
		stream << "----------" << std::endl;
		stream << "Registers:" << std::endl;
		stream << "  PRI = " << this->getRegPri() << std::endl;
		stream << "  MMX = " << this->getRegMmx() << std::endl;
		stream << "----------" << std::endl;
		stream << "Heap:" << std::endl;

		for (Memory::MemSize i = 0; i < memory.getSize(); ++i)
		{
			stream << "[" << i << "] " << memory.get(i)->getReadableString();
			if (i == this->getRegPri())
			{
				stream << " !PRI!";
			}

			if (i == this->getRegMmx())
			{
				stream << " !MMX!";
			}

			stream << std::endl;
		}

		stream << "- end of heap dump" << std::endl;
	}
}<|endoftext|>


<commit_before>/**
 * @file   SocketAddress.hpp
 * @brief  SocketAddress class prototype.
 * @author zer0
 * @date   2017-06-18
 * @date   2019-01-19 (Move: libtbag/network -> libtbag/net)
 */

#ifndef __INCLUDE_LIBTBAG__LIBTBAG_NETWORK_SOCKETADDRESS_HPP__
#define __INCLUDE_LIBTBAG__LIBTBAG_NETWORK_SOCKETADDRESS_HPP__

// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
#pragma once
#endif

#include <libtbag/config.h>
#include <libtbag/predef.hpp>
#include <libtbag/Err.hpp>
#include <libtbag/net/Uri.hpp>

#include <string>

#if defined(TBAG_PLATFORM_WINDOWS)
# include <winsock2.h>
# include <WS2tcpip.h> // sockaddr_in6, addrinfo
# include <Windows.h>
#else
# include <netinet/in.h>
# include <netdb.h> // addrinfo
#endif

// -------------------
NAMESPACE_LIBTBAG_OPEN
// -------------------

namespace net {

/**
 * SocketAddress class prototype.
 *
 * @author zer0
 * @date   2017-06-18
 * @date   2019-01-19 (Move: libtbag/network -> libtbag/net)
 */
class TBAG_API SocketAddress
{
private:
    union {
        sockaddr     common;
        sockaddr_in  ipv4;
        sockaddr_in6 ipv6;
    } _addr;

public:
    SocketAddress();
    explicit SocketAddress(struct sockaddr     const * addr);
    explicit SocketAddress(struct sockaddr_in  const * addr);
    explicit SocketAddress(struct sockaddr_in6 const * addr);
    SocketAddress(SocketAddress const & obj);
    SocketAddress(SocketAddress && obj) TBAG_NOEXCEPT;
    virtual ~SocketAddress();

public:
    SocketAddress & operator =(SocketAddress const & obj);
    SocketAddress & operator =(SocketAddress && obj) TBAG_NOEXCEPT;

public:
    Err init(struct sockaddr     const * addr);
    Err init(struct sockaddr_in  const * addr);
    Err init(struct sockaddr_in6 const * addr);

public:
    Err initIpv4(std::string const & ip, int port = 0);
    Err initIpv6(std::string const & ip, int port = 0);
    Err initName(std::string const & host, std::string const & service = "", int port = 0);

public:
    Err init(std::string const & host, int port);
    Err init(Uri const & uri);

public:
    inline struct sockaddr     const * getCommon() const TBAG_NOEXCEPT { return &_addr.common; }
    inline struct sockaddr_in  const * getIpv4  () const TBAG_NOEXCEPT { return &_addr.ipv4; }
    inline struct sockaddr_in6 const * getIpv6  () const TBAG_NOEXCEPT { return &_addr.ipv6; }

    inline bool isIpv4() const TBAG_NOEXCEPT { return _addr.ipv4.sin_port  == AF_INET;  }
    inline bool isIpv6() const TBAG_NOEXCEPT { return _addr.ipv6.sin6_port == AF_INET6; }

public:
    std::string getIpName() const;
    int getPortNumber() const;
};

// -----------------------
// Miscellaneous utilities
// -----------------------

/**
 * Find the network interface that the client IP is connected to and return the hostname of that interface.
 *
 * @param[in] client_ip
 *      Client IP address.
 * @param[in] client_ip
 *      Flag values for getnameinfo(). (e.g. NI_NUMERICHOST)
 * @param[out] result_host
 *      Result host name.
 *
 * @return Result error code.
 */
TBAG_API Err requestHostNameByClientIp(std::string const & client_ip, int flags, std::string & result_host);
TBAG_API std::string requestHostNameByClientIp(std::string const & client_ip, int flags);

/**
 * Find the network interface that the client IP is connected to and return the hostname of that interface.
 *
 * Flag value is NI_NUMERICHOST.
 *
 * @param[in] client_ip
 *      Client IP address.
 *
 * @return Result host name.
 */
TBAG_API std::string requestHostNameByClientIp(std::string const & client_ip);

} // namespace net

// --------------------
NAMESPACE_LIBTBAG_CLOSE
// --------------------

#endif // __INCLUDE_LIBTBAG__LIBTBAG_NETWORK_SOCKETADDRESS_HPP__

<commit_msg>Fixed doxygen warnings.<commit_after>/**
 * @file   SocketAddress.hpp
 * @brief  SocketAddress class prototype.
 * @author zer0
 * @date   2017-06-18
 * @date   2019-01-19 (Move: libtbag/network -> libtbag/net)
 */

#ifndef __INCLUDE_LIBTBAG__LIBTBAG_NETWORK_SOCKETADDRESS_HPP__
#define __INCLUDE_LIBTBAG__LIBTBAG_NETWORK_SOCKETADDRESS_HPP__

// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
#pragma once
#endif

#include <libtbag/config.h>
#include <libtbag/predef.hpp>
#include <libtbag/Err.hpp>
#include <libtbag/net/Uri.hpp>

#include <string>

#if defined(TBAG_PLATFORM_WINDOWS)
# include <winsock2.h>
# include <WS2tcpip.h> // sockaddr_in6, addrinfo
# include <Windows.h>
#else
# include <netinet/in.h>
# include <netdb.h> // addrinfo
#endif

// -------------------
NAMESPACE_LIBTBAG_OPEN
// -------------------

namespace net {

/**
 * SocketAddress class prototype.
 *
 * @author zer0
 * @date   2017-06-18
 * @date   2019-01-19 (Move: libtbag/network -> libtbag/net)
 */
class TBAG_API SocketAddress
{
private:
    union {
        sockaddr     common;
        sockaddr_in  ipv4;
        sockaddr_in6 ipv6;
    } _addr;

public:
    SocketAddress();
    explicit SocketAddress(struct sockaddr     const * addr);
    explicit SocketAddress(struct sockaddr_in  const * addr);
    explicit SocketAddress(struct sockaddr_in6 const * addr);
    SocketAddress(SocketAddress const & obj);
    SocketAddress(SocketAddress && obj) TBAG_NOEXCEPT;
    virtual ~SocketAddress();

public:
    SocketAddress & operator =(SocketAddress const & obj);
    SocketAddress & operator =(SocketAddress && obj) TBAG_NOEXCEPT;

public:
    Err init(struct sockaddr     const * addr);
    Err init(struct sockaddr_in  const * addr);
    Err init(struct sockaddr_in6 const * addr);

public:
    Err initIpv4(std::string const & ip, int port = 0);
    Err initIpv6(std::string const & ip, int port = 0);
    Err initName(std::string const & host, std::string const & service = "", int port = 0);

public:
    Err init(std::string const & host, int port);
    Err init(Uri const & uri);

public:
    inline struct sockaddr     const * getCommon() const TBAG_NOEXCEPT { return &_addr.common; }
    inline struct sockaddr_in  const * getIpv4  () const TBAG_NOEXCEPT { return &_addr.ipv4; }
    inline struct sockaddr_in6 const * getIpv6  () const TBAG_NOEXCEPT { return &_addr.ipv6; }

    inline bool isIpv4() const TBAG_NOEXCEPT { return _addr.ipv4.sin_port  == AF_INET;  }
    inline bool isIpv6() const TBAG_NOEXCEPT { return _addr.ipv6.sin6_port == AF_INET6; }

public:
    std::string getIpName() const;
    int getPortNumber() const;
};

// -----------------------
// Miscellaneous utilities
// -----------------------

/**
 * Find the network interface that the client IP is connected to and return the hostname of that interface.
 *
 * @param[in] client_ip
 *      Client IP address.
 * @param[in] flags
 *      Flag values for getnameinfo(). (e.g. NI_NUMERICHOST)
 * @param[out] result_host
 *      Result host name.
 *
 * @return Result error code.
 */
TBAG_API Err requestHostNameByClientIp(std::string const & client_ip, int flags, std::string & result_host);
TBAG_API std::string requestHostNameByClientIp(std::string const & client_ip, int flags);

/**
 * Find the network interface that the client IP is connected to and return the hostname of that interface.
 *
 * Flag value is NI_NUMERICHOST.
 *
 * @param[in] client_ip
 *      Client IP address.
 *
 * @return Result host name.
 */
TBAG_API std::string requestHostNameByClientIp(std::string const & client_ip);

} // namespace net

// --------------------
NAMESPACE_LIBTBAG_CLOSE
// --------------------

#endif // __INCLUDE_LIBTBAG__LIBTBAG_NETWORK_SOCKETADDRESS_HPP__

<|endoftext|>


<commit_before>/******************************************************************************
 *                    _   _____   __________                                  *
 *                   | | / / _ | / __/_  __/     Visibility                   *
 *                   | |/ / __ |_\ \  / /          Across                     *
 *                   |___/_/ |_/___/ /_/       Space and Time                 *
 *                                                                            *
 * This file is part of VAST. It is subject to the license terms in the       *
 * LICENSE file found in the top-level directory of this distribution and at  *
 * http://vast.io/license. No part of VAST, including this file, may be       *
 * copied, modified, propagated, or distributed except according to the terms *
 * contained in the LICENSE file.                                             *
 ******************************************************************************/

#define SUITE community_id

#include "vast/test/test.hpp"

#include "vast/community_id.hpp"
#include "vast/concept/parseable/to.hpp"
#include "vast/concept/parseable/vast/address.hpp"

using namespace vast;
using namespace community_id;

namespace {

#define FLOW_FACTORY(protocol)                                                 \
  flow make_##protocol##_flow(std::string_view orig_h, uint16_t orig_p,        \
                              std::string_view resp_h, uint16_t resp_p) {      \
    constexpr auto proto = port::port_type::protocol;                          \
    auto x = make_flow<proto>(orig_h, orig_p, resp_h, resp_p);                 \
    REQUIRE(x);                                                                \
    return *x;                                                                 \
  }

FLOW_FACTORY(icmp)
FLOW_FACTORY(tcp)
FLOW_FACTORY(udp)
FLOW_FACTORY(icmp6)

#undef FLOW_FACTORY

} // namespace

// Ground truth established with Christian Kreibich's Python module, e.g.:
//
//     from communityid import *
//     commid = CommunityID(seed=0, use_base64=False)
//     commid.calc(flow)
//     flow = FlowTuple(PROTO_UDP, "192.168.1.102", "192.168.1.1", 68, 67)

TEST(UDP IPv4) {
  auto x = make_udp_flow("192.168.1.102", 68, "192.168.1.1", 67);
  auto hex = compute<policy::ascii>(x);
  auto b64 = compute<policy::base64>(x);
  CHECK_EQUAL(hex, "1:69665f2c8aae6250b1286b89eb67d01a5805cc02");
  CHECK_EQUAL(b64, "1:aWZfLIquYlCxKGuJ62fQGlgFzAI=");
}

TEST(UDP IPv6) {
  auto x = make_udp_flow("fe80::2c23:b96c:78d:e116", 58544, "ff02::c", 3702);
  auto hex = compute<policy::ascii>(x);
  auto b64 = compute<policy::base64>(x);
  CHECK_EQUAL(hex, "1:662f40748c18bd99d8bee39b4cf806582052611b");
  CHECK_EQUAL(b64, "1:Zi9AdIwYvZnYvuObTPgGWCBSYRs=");
}

TEST(TCP IPv4) {
  auto x = make_tcp_flow("192.168.1.102", 1180, "68.216.79.113", 37);
  auto hex = compute<policy::ascii>(x);
  auto b64 = compute<policy::base64>(x);
  CHECK_EQUAL(hex, "1:f4bfed67579b1f395687307fa49c92f405495b2f");
  CHECK_EQUAL(b64, "1:9L/tZ1ebHzlWhzB/pJyS9AVJWy8=");
}

TEST(TCP IPv6) {
  auto x = make_tcp_flow("fe80::219:e3ff:fee7:5d23", 5353, "ff02::fb", 53);
  auto hex = compute<policy::ascii>(x);
  auto b64 = compute<policy::base64>(x);
  CHECK_EQUAL(hex, "1:03aaaffe2842910257a2fdf52f863395cb8a4769");
  CHECK_EQUAL(b64, "1:A6qv/ihCkQJXov31L4YzlcuKR2k=");
}

TEST(ICMPv4) {
  auto x = make_icmp_flow("1.2.3.4", 0, "5.6.7.8", 8);
  auto hex = compute<policy::ascii>(x);
  auto b64 = compute<policy::base64>(x);
  CHECK_EQUAL(hex, "1:d6f36bf9c570edbcd9fad1ac8761fbbe807069a6");
  CHECK_EQUAL(b64, "1:1vNr+cVw7bzZ+tGsh2H7voBwaaY=");
}

TEST(ICMPv4 oneway) {
  auto x = make_icmp_flow("192.168.0.89", 128, "192.168.0.1", 129);
  auto hex = compute<policy::ascii>(x);
  auto b64 = compute<policy::base64>(x);
  CHECK_EQUAL(hex, "1:86459c1ce1ea4c65aaffe7f01c48a6e5efa0d5f1");
  CHECK_EQUAL(b64, "1:hkWcHOHqTGWq/+fwHEim5e+g1fE=");
}

TEST(ICMPv6) {
  auto x = make_icmp6_flow("fe80::200:86ff:fe05:80da", 135, "fe80::260", 136);
  auto hex = compute<policy::ascii>(x);
  auto b64 = compute<policy::base64>(x);
  CHECK_EQUAL(hex, "1:ffb2d8321708804a883ac02fe6c76655499b3ff5");
  CHECK_EQUAL(b64, "1:/7LYMhcIgEqIOsAv5sdmVUmbP/U=");
}

TEST(ICMPv6 oneway) {
  auto x = make_icmp6_flow("fe80::dead", 42, "fe80::beef", 84);
  auto hex = compute<policy::ascii>(x);
  auto b64 = compute<policy::base64>(x);
  CHECK_EQUAL(hex, "1:118a3bbf175529a3d55dca55c4364ec47f1c4152");
  CHECK_EQUAL(b64, "1:EYo7vxdVKaPVXcpVxDZOxH8cQVI=");
}
<commit_msg>Simplify flow factory<commit_after>/******************************************************************************
 *                    _   _____   __________                                  *
 *                   | | / / _ | / __/_  __/     Visibility                   *
 *                   | |/ / __ |_\ \  / /          Across                     *
 *                   |___/_/ |_/___/ /_/       Space and Time                 *
 *                                                                            *
 * This file is part of VAST. It is subject to the license terms in the       *
 * LICENSE file found in the top-level directory of this distribution and at  *
 * http://vast.io/license. No part of VAST, including this file, may be       *
 * copied, modified, propagated, or distributed except according to the terms *
 * contained in the LICENSE file.                                             *
 ******************************************************************************/

#define SUITE community_id

#include "vast/test/test.hpp"

#include "vast/community_id.hpp"
#include "vast/concept/parseable/to.hpp"
#include "vast/concept/parseable/vast/address.hpp"

using namespace vast;
using namespace community_id;

namespace {

#define FLOW_FACTORY(protocol)                                                 \
  flow make_##protocol##_flow(std::string_view orig_h, uint16_t orig_p,        \
                              std::string_view resp_h, uint16_t resp_p) {      \
    constexpr auto proto = port::port_type::protocol;                          \
    return unbox(make_flow<proto>(orig_h, orig_p, resp_h, resp_p));            \
  }

FLOW_FACTORY(icmp)
FLOW_FACTORY(tcp)
FLOW_FACTORY(udp)
FLOW_FACTORY(icmp6)

#undef FLOW_FACTORY

} // namespace

// Ground truth established with Christian Kreibich's Python module, e.g.:
//
//     from communityid import *
//     commid = CommunityID(seed=0, use_base64=False)
//     commid.calc(flow)
//     flow = FlowTuple(PROTO_UDP, "192.168.1.102", "192.168.1.1", 68, 67)

TEST(UDP IPv4) {
  auto x = make_udp_flow("192.168.1.102", 68, "192.168.1.1", 67);
  auto hex = compute<policy::ascii>(x);
  auto b64 = compute<policy::base64>(x);
  CHECK_EQUAL(hex, "1:69665f2c8aae6250b1286b89eb67d01a5805cc02");
  CHECK_EQUAL(b64, "1:aWZfLIquYlCxKGuJ62fQGlgFzAI=");
}

TEST(UDP IPv6) {
  auto x = make_udp_flow("fe80::2c23:b96c:78d:e116", 58544, "ff02::c", 3702);
  auto hex = compute<policy::ascii>(x);
  auto b64 = compute<policy::base64>(x);
  CHECK_EQUAL(hex, "1:662f40748c18bd99d8bee39b4cf806582052611b");
  CHECK_EQUAL(b64, "1:Zi9AdIwYvZnYvuObTPgGWCBSYRs=");
}

TEST(TCP IPv4) {
  auto x = make_tcp_flow("192.168.1.102", 1180, "68.216.79.113", 37);
  auto hex = compute<policy::ascii>(x);
  auto b64 = compute<policy::base64>(x);
  CHECK_EQUAL(hex, "1:f4bfed67579b1f395687307fa49c92f405495b2f");
  CHECK_EQUAL(b64, "1:9L/tZ1ebHzlWhzB/pJyS9AVJWy8=");
}

TEST(TCP IPv6) {
  auto x = make_tcp_flow("fe80::219:e3ff:fee7:5d23", 5353, "ff02::fb", 53);
  auto hex = compute<policy::ascii>(x);
  auto b64 = compute<policy::base64>(x);
  CHECK_EQUAL(hex, "1:03aaaffe2842910257a2fdf52f863395cb8a4769");
  CHECK_EQUAL(b64, "1:A6qv/ihCkQJXov31L4YzlcuKR2k=");
}

TEST(ICMPv4) {
  auto x = make_icmp_flow("1.2.3.4", 0, "5.6.7.8", 8);
  auto hex = compute<policy::ascii>(x);
  auto b64 = compute<policy::base64>(x);
  CHECK_EQUAL(hex, "1:d6f36bf9c570edbcd9fad1ac8761fbbe807069a6");
  CHECK_EQUAL(b64, "1:1vNr+cVw7bzZ+tGsh2H7voBwaaY=");
}

TEST(ICMPv4 oneway) {
  auto x = make_icmp_flow("192.168.0.89", 128, "192.168.0.1", 129);
  auto hex = compute<policy::ascii>(x);
  auto b64 = compute<policy::base64>(x);
  CHECK_EQUAL(hex, "1:86459c1ce1ea4c65aaffe7f01c48a6e5efa0d5f1");
  CHECK_EQUAL(b64, "1:hkWcHOHqTGWq/+fwHEim5e+g1fE=");
}

TEST(ICMPv6) {
  auto x = make_icmp6_flow("fe80::200:86ff:fe05:80da", 135, "fe80::260", 136);
  auto hex = compute<policy::ascii>(x);
  auto b64 = compute<policy::base64>(x);
  CHECK_EQUAL(hex, "1:ffb2d8321708804a883ac02fe6c76655499b3ff5");
  CHECK_EQUAL(b64, "1:/7LYMhcIgEqIOsAv5sdmVUmbP/U=");
}

TEST(ICMPv6 oneway) {
  auto x = make_icmp6_flow("fe80::dead", 42, "fe80::beef", 84);
  auto hex = compute<policy::ascii>(x);
  auto b64 = compute<policy::base64>(x);
  CHECK_EQUAL(hex, "1:118a3bbf175529a3d55dca55c4364ec47f1c4152");
  CHECK_EQUAL(b64, "1:EYo7vxdVKaPVXcpVxDZOxH8cQVI=");
}
<|endoftext|>


<commit_before>// Copyright (c) 2009 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 file.

#include "chrome/browser/chromeos/preferences.h"

#include "base/string_util.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/chromeos/cros/cros_library.h"
#include "chrome/browser/chromeos/cros/language_library.h"
#include "chrome/browser/chromeos/cros/synaptics_library.h"
#include "chrome/browser/chromeos/language_preferences.h"
#include "chrome/browser/pref_member.h"
#include "chrome/browser/pref_service.h"
#include "chrome/common/notification_service.h"
#include "chrome/common/pref_names.h"
#include "unicode/timezone.h"

namespace {

// Section and config names for the IBus configuration daemon.
const char kGeneralSectionName[] = "general";
const char kHotKeySectionName[] = "general/hotkey";
const char kHangulSectionName[] = "engine/Hangul";

const char kUseGlobalEngineConfigName[] = "use_global_engine";
const char kNextEngineConfigName[] = "next_engine";
const char kTriggerConfigName[] = "trigger";
const char kHangulKeyboardConfigName[] = "HangulKeyboard";

}  // namespace

namespace chromeos {

// static
void Preferences::RegisterUserPrefs(PrefService* prefs) {
  prefs->RegisterStringPref(prefs::kTimeZone, L"US/Pacific");
  prefs->RegisterBooleanPref(prefs::kTapToClickEnabled, false);
  prefs->RegisterBooleanPref(prefs::kVertEdgeScrollEnabled, false);
  prefs->RegisterIntegerPref(prefs::kTouchpadSpeedFactor, 5);
  prefs->RegisterIntegerPref(prefs::kTouchpadSensitivity, 5);
  prefs->RegisterBooleanPref(prefs::kLanguageUseGlobalEngine, true);
  prefs->RegisterStringPref(prefs::kLanguageHotkeyNextEngine,
                            kHotkeyNextEngine);
  prefs->RegisterStringPref(prefs::kLanguageHotkeyTrigger, kHotkeyTrigger);
  prefs->RegisterStringPref(prefs::kLanguagePreloadEngines,
                            UTF8ToWide(kFallbackInputMethodId));  // EN layout
  prefs->RegisterStringPref(prefs::kLanguageHangulKeyboard,
                            kHangulKeyboardNameIDPairs[0].keyboard_id);
}

void Preferences::Init(PrefService* prefs) {
  timezone_.Init(prefs::kTimeZone, prefs, this);
  tap_to_click_enabled_.Init(prefs::kTapToClickEnabled, prefs, this);
  vert_edge_scroll_enabled_.Init(prefs::kVertEdgeScrollEnabled, prefs, this);
  speed_factor_.Init(prefs::kTouchpadSpeedFactor, prefs, this);
  sensitivity_.Init(prefs::kTouchpadSensitivity, prefs, this);
  language_use_global_engine_.Init(
      prefs::kLanguageUseGlobalEngine, prefs, this);
  language_hotkey_next_engine_.Init(
      prefs::kLanguageHotkeyNextEngine, prefs, this);
  language_hotkey_trigger_.Init(prefs::kLanguageHotkeyTrigger, prefs, this);
  language_preload_engines_.Init(prefs::kLanguagePreloadEngines, prefs, this);
  language_hangul_keyboard_.Init(prefs::kLanguageHangulKeyboard, prefs, this);

  // Initialize touchpad settings to what's saved in user preferences.
  NotifyPrefChanged(NULL);
}

void Preferences::Observe(NotificationType type,
                          const NotificationSource& source,
                          const NotificationDetails& details) {
  if (type == NotificationType::PREF_CHANGED)
    NotifyPrefChanged(Details<std::wstring>(details).ptr());
}

void Preferences::NotifyPrefChanged(const std::wstring* pref_name) {
  if (!pref_name || *pref_name == prefs::kTimeZone)
    SetTimeZone(timezone_.GetValue());
  if (!pref_name || *pref_name == prefs::kTapToClickEnabled)
    CrosLibrary::Get()->GetSynapticsLibrary()->SetBoolParameter(
        PARAM_BOOL_TAP_TO_CLICK,
        tap_to_click_enabled_.GetValue());
  if (!pref_name || *pref_name == prefs::kVertEdgeScrollEnabled)
    CrosLibrary::Get()->GetSynapticsLibrary()->SetBoolParameter(
        PARAM_BOOL_VERTICAL_EDGE_SCROLLING,
        vert_edge_scroll_enabled_.GetValue());
  if (!pref_name || *pref_name == prefs::kTouchpadSpeedFactor)
    CrosLibrary::Get()->GetSynapticsLibrary()->SetRangeParameter(
        PARAM_RANGE_SPEED_SENSITIVITY,
        speed_factor_.GetValue());
  if (!pref_name || *pref_name == prefs::kTouchpadSensitivity)
    CrosLibrary::Get()->GetSynapticsLibrary()->SetRangeParameter(
          PARAM_RANGE_TOUCH_SENSITIVITY,
          sensitivity_.GetValue());
  if (!pref_name || *pref_name == prefs::kLanguageUseGlobalEngine)
    SetLanguageConfigBoolean(kGeneralSectionName, kUseGlobalEngineConfigName,
                             language_use_global_engine_.GetValue());
  if (!pref_name || *pref_name == prefs::kLanguageHotkeyNextEngine)
    SetHotkeys(kNextEngineConfigName, language_hotkey_next_engine_.GetValue());
  if (!pref_name || *pref_name == prefs::kLanguageHotkeyTrigger)
    SetHotkeys(kTriggerConfigName, language_hotkey_trigger_.GetValue());
  if (!pref_name || *pref_name == prefs::kLanguagePreloadEngines)
    SetPreloadEngines(language_preload_engines_.GetValue());
  if (!pref_name || *pref_name == prefs::kLanguageHangulKeyboard)
    SetLanguageConfigString(kHangulSectionName, kHangulKeyboardConfigName,
                            language_hangul_keyboard_.GetValue());
}

void Preferences::SetTimeZone(const std::wstring& id) {
  icu::TimeZone* timezone = icu::TimeZone::createTimeZone(
      icu::UnicodeString::fromUTF8(WideToASCII(id)));
  icu::TimeZone::adoptDefault(timezone);
}

void Preferences::SetLanguageConfigBoolean(const char* section,
                                           const char* name,
                                           bool value) {
  ImeConfigValue config;
  config.type = ImeConfigValue::kValueTypeBool;
  config.bool_value = value;
  CrosLibrary::Get()->GetLanguageLibrary()->SetImeConfig(section, name, config);
}

void Preferences::SetLanguageConfigString(const char* section,
                                          const char* name,
                                          const std::wstring& value) {
  ImeConfigValue config;
  config.type = ImeConfigValue::kValueTypeString;
  config.string_value = WideToUTF8(value);
  CrosLibrary::Get()->GetLanguageLibrary()->SetImeConfig(section, name, config);
}

void Preferences::SetLanguageConfigStringList(
    const char* section,
    const char* name,
    const std::vector<std::wstring>& values) {
  ImeConfigValue config;
  config.type = ImeConfigValue::kValueTypeStringList;
  for (size_t i = 0; i < values.size(); ++i) {
    config.string_list_value.push_back(WideToUTF8(values[i]));
  }
  CrosLibrary::Get()->GetLanguageLibrary()->SetImeConfig(section, name, config);
}

void Preferences::SetHotkeys(const char* name, const std::wstring& value) {
  std::vector<std::wstring> hotkeys;
  if (!value.empty()) {
    SplitString(value, L',', &hotkeys);
  }
  // We should call the cros API even when |value| is empty, to disable default
  // hot-keys.
  SetLanguageConfigStringList(kHotKeySectionName, name, hotkeys);
}

void Preferences::SetPreloadEngines(const std::wstring& value) {
  // TODO(yusukes): might be better to change the cros API signature so it
  // could accept the comma separated |value| as-is.

  LanguageLibrary* library = CrosLibrary::Get()->GetLanguageLibrary();
  std::vector<std::wstring> input_method_ids;
  SplitString(value, L',', &input_method_ids);
  LOG(INFO) << "Setting preload_engines to '" << value << "'";

  // Activate languages in |value|.
  for (size_t i = 0; i < input_method_ids.size(); ++i) {
    library->SetInputMethodActivated(WideToUTF8(input_method_ids[i]), true);
  }

  // Deactivate languages that are currently active, but are not in |value|.
  const std::set<std::wstring> input_method_id_set(input_method_ids.begin(),
                                                   input_method_ids.end());
  scoped_ptr<InputMethodDescriptors> active_input_methods(
      library->GetActiveInputMethods());
  for (size_t i = 0; i < active_input_methods->size(); ++i) {
    const InputMethodDescriptor& active_input_method
        = active_input_methods->at(i);
    if (input_method_id_set.count(UTF8ToWide(active_input_method.id)) == 0) {
      library->SetInputMethodActivated(active_input_method.id, false);
    }
  }
}

}  // namespace chromeos
<commit_msg>Fix build break (browser_test failure on Chromium OS bot). This is partial revert of r44072.<commit_after>// Copyright (c) 2009 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 file.

#include "chrome/browser/chromeos/preferences.h"

#include "base/string_util.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/chromeos/cros/cros_library.h"
#include "chrome/browser/chromeos/cros/language_library.h"
#include "chrome/browser/chromeos/cros/synaptics_library.h"
#include "chrome/browser/chromeos/language_preferences.h"
#include "chrome/browser/pref_member.h"
#include "chrome/browser/pref_service.h"
#include "chrome/common/notification_service.h"
#include "chrome/common/pref_names.h"
#include "unicode/timezone.h"

namespace {

// Section and config names for the IBus configuration daemon.
const char kGeneralSectionName[] = "general";
const char kHotKeySectionName[] = "general/hotkey";
const char kHangulSectionName[] = "engine/Hangul";

const char kUseGlobalEngineConfigName[] = "use_global_engine";
const char kNextEngineConfigName[] = "next_engine";
const char kTriggerConfigName[] = "trigger";
const char kHangulKeyboardConfigName[] = "HangulKeyboard";

}  // namespace

namespace chromeos {

// static
void Preferences::RegisterUserPrefs(PrefService* prefs) {
  prefs->RegisterStringPref(prefs::kTimeZone, L"US/Pacific");
  prefs->RegisterBooleanPref(prefs::kTapToClickEnabled, false);
  prefs->RegisterBooleanPref(prefs::kVertEdgeScrollEnabled, false);
  prefs->RegisterIntegerPref(prefs::kTouchpadSpeedFactor, 5);
  prefs->RegisterIntegerPref(prefs::kTouchpadSensitivity, 5);
  prefs->RegisterBooleanPref(prefs::kLanguageUseGlobalEngine, true);
  prefs->RegisterStringPref(prefs::kLanguageHotkeyNextEngine,
                            kHotkeyNextEngine);
  prefs->RegisterStringPref(prefs::kLanguageHotkeyTrigger, kHotkeyTrigger);
  prefs->RegisterStringPref(prefs::kLanguagePreloadEngines,
                            UTF8ToWide(kFallbackInputMethodId));  // EN layout
  prefs->RegisterStringPref(prefs::kLanguageHangulKeyboard,
                            kHangulKeyboardNameIDPairs[0].keyboard_id);
}

void Preferences::Init(PrefService* prefs) {
  timezone_.Init(prefs::kTimeZone, prefs, this);
  tap_to_click_enabled_.Init(prefs::kTapToClickEnabled, prefs, this);
  vert_edge_scroll_enabled_.Init(prefs::kVertEdgeScrollEnabled, prefs, this);
  speed_factor_.Init(prefs::kTouchpadSpeedFactor, prefs, this);
  sensitivity_.Init(prefs::kTouchpadSensitivity, prefs, this);
  language_use_global_engine_.Init(
      prefs::kLanguageUseGlobalEngine, prefs, this);
  language_hotkey_next_engine_.Init(
      prefs::kLanguageHotkeyNextEngine, prefs, this);
  language_hotkey_trigger_.Init(prefs::kLanguageHotkeyTrigger, prefs, this);
  language_preload_engines_.Init(prefs::kLanguagePreloadEngines, prefs, this);
  language_hangul_keyboard_.Init(prefs::kLanguageHangulKeyboard, prefs, this);

  // Initialize touchpad settings to what's saved in user preferences.
  NotifyPrefChanged(NULL);
}

void Preferences::Observe(NotificationType type,
                          const NotificationSource& source,
                          const NotificationDetails& details) {
  if (type == NotificationType::PREF_CHANGED)
    NotifyPrefChanged(Details<std::wstring>(details).ptr());
}

void Preferences::NotifyPrefChanged(const std::wstring* pref_name) {
  if (!pref_name || *pref_name == prefs::kTimeZone)
    SetTimeZone(timezone_.GetValue());
  if (!pref_name || *pref_name == prefs::kTapToClickEnabled)
    CrosLibrary::Get()->GetSynapticsLibrary()->SetBoolParameter(
        PARAM_BOOL_TAP_TO_CLICK,
        tap_to_click_enabled_.GetValue());
  if (!pref_name || *pref_name == prefs::kVertEdgeScrollEnabled)
    CrosLibrary::Get()->GetSynapticsLibrary()->SetBoolParameter(
        PARAM_BOOL_VERTICAL_EDGE_SCROLLING,
        vert_edge_scroll_enabled_.GetValue());
  if (!pref_name || *pref_name == prefs::kTouchpadSpeedFactor)
    CrosLibrary::Get()->GetSynapticsLibrary()->SetRangeParameter(
        PARAM_RANGE_SPEED_SENSITIVITY,
        speed_factor_.GetValue());
  if (!pref_name || *pref_name == prefs::kTouchpadSensitivity)
    CrosLibrary::Get()->GetSynapticsLibrary()->SetRangeParameter(
          PARAM_RANGE_TOUCH_SENSITIVITY,
          sensitivity_.GetValue());
  if (!pref_name || *pref_name == prefs::kLanguageUseGlobalEngine)
    SetLanguageConfigBoolean(kGeneralSectionName, kUseGlobalEngineConfigName,
                             language_use_global_engine_.GetValue());
  if (!pref_name || *pref_name == prefs::kLanguageHotkeyNextEngine)
    SetHotkeys(kNextEngineConfigName, language_hotkey_next_engine_.GetValue());
  if (!pref_name || *pref_name == prefs::kLanguageHotkeyTrigger)
    SetHotkeys(kTriggerConfigName, language_hotkey_trigger_.GetValue());
  if (!pref_name || *pref_name == prefs::kLanguagePreloadEngines)
    SetPreloadEngines(language_preload_engines_.GetValue());
  if (!pref_name || *pref_name == prefs::kLanguageHangulKeyboard)
    SetLanguageConfigString(kHangulSectionName, kHangulKeyboardConfigName,
                            language_hangul_keyboard_.GetValue());
}

void Preferences::SetTimeZone(const std::wstring& id) {
  icu::TimeZone* timezone = icu::TimeZone::createTimeZone(
      icu::UnicodeString::fromUTF8(WideToASCII(id)));
  icu::TimeZone::adoptDefault(timezone);
}

void Preferences::SetLanguageConfigBoolean(const char* section,
                                           const char* name,
                                           bool value) {
  ImeConfigValue config;
  config.type = ImeConfigValue::kValueTypeBool;
  config.bool_value = value;
  CrosLibrary::Get()->GetLanguageLibrary()->SetImeConfig(section, name, config);
}

void Preferences::SetLanguageConfigString(const char* section,
                                          const char* name,
                                          const std::wstring& value) {
  ImeConfigValue config;
  config.type = ImeConfigValue::kValueTypeString;
  config.string_value = WideToUTF8(value);
  CrosLibrary::Get()->GetLanguageLibrary()->SetImeConfig(section, name, config);
}

void Preferences::SetLanguageConfigStringList(
    const char* section,
    const char* name,
    const std::vector<std::wstring>& values) {
  ImeConfigValue config;
  config.type = ImeConfigValue::kValueTypeStringList;
  for (size_t i = 0; i < values.size(); ++i) {
    config.string_list_value.push_back(WideToUTF8(values[i]));
  }
  // TODO(yusukes): Re-enable this line.
  // CrosLibrary::Get()->GetLanguageLibrary()->SetImeConfig(
  //    section, name, config);
}

void Preferences::SetHotkeys(const char* name, const std::wstring& value) {
  std::vector<std::wstring> hotkeys;
  if (!value.empty()) {
    SplitString(value, L',', &hotkeys);
  }
  // We should call the cros API even when |value| is empty, to disable default
  // hot-keys.
  SetLanguageConfigStringList(kHotKeySectionName, name, hotkeys);
}

void Preferences::SetPreloadEngines(const std::wstring& value) {
  // TODO(yusukes): might be better to change the cros API signature so it
  // could accept the comma separated |value| as-is.

  LanguageLibrary* library = CrosLibrary::Get()->GetLanguageLibrary();
  std::vector<std::wstring> input_method_ids;
  SplitString(value, L',', &input_method_ids);
  LOG(INFO) << "Setting preload_engines to '" << value << "'";

  // Activate languages in |value|.
  for (size_t i = 0; i < input_method_ids.size(); ++i) {
    library->SetInputMethodActivated(WideToUTF8(input_method_ids[i]), true);
  }

  // Deactivate languages that are currently active, but are not in |value|.
  const std::set<std::wstring> input_method_id_set(input_method_ids.begin(),
                                                   input_method_ids.end());
  scoped_ptr<InputMethodDescriptors> active_input_methods(
      library->GetActiveInputMethods());
  for (size_t i = 0; i < active_input_methods->size(); ++i) {
    const InputMethodDescriptor& active_input_method
        = active_input_methods->at(i);
    if (input_method_id_set.count(UTF8ToWide(active_input_method.id)) == 0) {
      library->SetInputMethodActivated(active_input_method.id, false);
    }
  }
}

}  // namespace chromeos
<|endoftext|>