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

#include "../LuaScript/LuaFunction.h"
#include "../LuaScript/LuaScriptEventInvoker.h"
#include "../LuaScript/LuaScriptInstance.h"

#include "../DebugNew.h"

namespace Urho3D
{

class EventHandlerCommand
{
public:
    EventHandlerCommand(int type) : type_(type) { }
    virtual ~EventHandlerCommand() { }
    int type_;
};

struct AddOrRemoveEventHandlerCommand : public EventHandlerCommand
{
    enum { Type = 1 };
    AddOrRemoveEventHandlerCommand(bool add, Object* sender, const StringHash& eventType, WeakPtr<LuaFunction> function) :
        EventHandlerCommand(Type), add_(add), sender_(sender), eventType_(eventType), function_(function)
    {
    }

    bool add_;
    Object* sender_;
    StringHash eventType_;
    WeakPtr<LuaFunction> function_;
};

struct RemoveAllEventHandlersCommand : public EventHandlerCommand
{
    enum { Type = 2 };
    RemoveAllEventHandlersCommand(Object* sender) : EventHandlerCommand(Type), sender_(sender)
    {
    }

    Object* sender_;
};

struct RemoveEventHandlersExceptCommand : public EventHandlerCommand
{

    enum { Type = 3 };
    RemoveEventHandlersExceptCommand(const PODVector<StringHash>& exceptionTypes) : EventHandlerCommand(Type), exceptionTypes_(exceptionTypes)
    {
    }
    PODVector<StringHash> exceptionTypes_;
};

LuaScriptEventInvoker::LuaScriptEventInvoker(Context* context) :
    Object(context),
    instance_(0),
    invoking_(false)
{
}

LuaScriptEventInvoker::LuaScriptEventInvoker(LuaScriptInstance* instance) :
    Object(instance->GetContext()),
    instance_(instance),
    invoking_(false)
{
}

LuaScriptEventInvoker::~LuaScriptEventInvoker()
{
}

void LuaScriptEventInvoker::AddEventHandler(Object* sender, const StringHash& eventType, WeakPtr<LuaFunction> function)
{
    if (invoking_)
    {
        eventHandlerCommands_.Push(new AddOrRemoveEventHandlerCommand(true, sender, eventType, function));
        return;
    }

    EventTypeToLuaFunctionVectorMap& eventTypeToFunctionVectorMap = GetEventTypeToLuaFunctionVectorMap(sender);
    EventTypeToLuaFunctionVectorMap::Iterator i = eventTypeToFunctionVectorMap.Find(eventType);

    if (i == eventTypeToFunctionVectorMap.End())
    {
        eventTypeToFunctionVectorMap[eventType].Push(function);

        if (!sender)
            SubscribeToEvent(eventType, HANDLER(LuaScriptEventInvoker, HandleLuaScriptEvent));
        else
            SubscribeToEvent(sender, eventType, HANDLER(LuaScriptEventInvoker, HandleLuaScriptEvent));
    }
    else
    {
        if (!i->second_.Contains(function))
            i->second_.Push(function);
    }
}

void LuaScriptEventInvoker::RemoveEventHandler(Object* sender, const StringHash& eventType, WeakPtr<LuaFunction> function)
{
    if (invoking_)
    {
        eventHandlerCommands_.Push(new AddOrRemoveEventHandlerCommand(false, sender, eventType, function));
        return;
    }

    EventTypeToLuaFunctionVectorMap& eventTypeToLuaFunctionVectorMap = GetEventTypeToLuaFunctionVectorMap(sender);
    EventTypeToLuaFunctionVectorMap::Iterator i = eventTypeToLuaFunctionVectorMap.Find(eventType);
    if (i == eventTypeToLuaFunctionVectorMap.End())
        return;

    if (function)
        i->second_.Remove(function);
    else
        i->second_.Clear();

    if (i->second_.Empty())
    {
        eventTypeToLuaFunctionVectorMap.Erase(i);

        if (!sender)
            UnsubscribeFromEvent(eventType);
        else
            UnsubscribeFromEvent(sender, eventType);
    }
}

void LuaScriptEventInvoker::RemoveAllEventHandlers(Object* sender)
{
    if (invoking_)
    {
        eventHandlerCommands_.Push(new RemoveAllEventHandlersCommand(sender));
        return;
    }

    if (!sender)
    {
        UnsubscribeFromAllEvents();
        eventTypeToLuaFunctionVectorMap.Clear();
        senderEventTypeToLuaFunctionVectorMap.Clear();
    }
    else
    {
        UnsubscribeFromEvents(sender);
        senderEventTypeToLuaFunctionVectorMap.Erase(sender);
    }
}

void LuaScriptEventInvoker::RemoveEventHandlersExcept(const PODVector<StringHash>& exceptionTypes)
{
    if (invoking_)
    {
        eventHandlerCommands_.Push(new RemoveEventHandlersExceptCommand(exceptionTypes));
        return;
    }

    for (unsigned i = 0; i < exceptionTypes.Size(); ++i)
        eventTypeToLuaFunctionVectorMap.Erase(exceptionTypes[i]);

    UnsubscribeFromAllEventsExcept(exceptionTypes, false);
}

void LuaScriptEventInvoker::HandleLuaScriptEvent(StringHash eventType, VariantMap& eventData)
{
    Object* sender = GetEventHandler()->GetSender();
    EventTypeToLuaFunctionVectorMap& eventTypeToLuaFunctionVectorMap = GetEventTypeToLuaFunctionVectorMap(sender);
    EventTypeToLuaFunctionVectorMap::Iterator i = eventTypeToLuaFunctionVectorMap.Find(eventType);
    if (i == eventTypeToLuaFunctionVectorMap.End())
        return;

    invoking_ = true;

    LuaFunctionVector& luaFunctionVector = i->second_;
    if (instance_)
    {
        instance_->AddRef();

        for (unsigned i = 0; i < luaFunctionVector.Size(); ++i)
        {
            WeakPtr<LuaFunction>& function = luaFunctionVector[i];
            if (function && function->BeginCall(instance_))
            {
                function->PushUserType(eventType, "StringHash");
                function->PushUserType(eventData, "VariantMap");
                function->EndCall();
            }
        }

        instance_->ReleaseRef();
    }
    else
    {
        for (unsigned i = 0; i < luaFunctionVector.Size(); ++i)
        {
            WeakPtr<LuaFunction>& function = luaFunctionVector[i];
            if (function && function->BeginCall())
            {
                function->PushUserType(eventType, "StringHash");
                function->PushUserType(eventData, "VariantMap");
                function->EndCall();
            }
        }
    }

    invoking_ = false;

    if (!eventHandlerCommands_.Empty())
    {
        for (unsigned i = 0; i < eventHandlerCommands_.Size(); ++i)
            ExecuteThenDestroyCommand(eventHandlerCommands_[i]);

        eventHandlerCommands_.Clear();
    }
}

void LuaScriptEventInvoker::ExecuteThenDestroyCommand(EventHandlerCommand* command)
{
    if (!command)
        return;

    switch (command->type_)
    {
    case AddOrRemoveEventHandlerCommand::Type:
        {
            AddOrRemoveEventHandlerCommand* theCommand = (AddOrRemoveEventHandlerCommand*)command;
            if (theCommand->add_)
                AddEventHandler(theCommand->sender_, theCommand->eventType_, theCommand->function_);
            else
                RemoveEventHandler(theCommand->sender_, theCommand->eventType_, theCommand->function_);
        }
        break;

    case RemoveAllEventHandlersCommand::Type:
        {
            RemoveAllEventHandlersCommand* theCommand = (RemoveAllEventHandlersCommand*)command;
            RemoveAllEventHandlers(theCommand->sender_);
        }
        break;

    case RemoveEventHandlersExceptCommand::Type:
        {
            RemoveEventHandlersExceptCommand* theCommand = (RemoveEventHandlersExceptCommand*)command;
            RemoveEventHandlersExcept(theCommand->exceptionTypes_);
        }
        break;
    }

    delete command;
}

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

#include "../LuaScript/LuaFunction.h"
#include "../LuaScript/LuaScriptEventInvoker.h"
#include "../LuaScript/LuaScriptInstance.h"

#include "../DebugNew.h"

namespace Urho3D
{

class EventHandlerCommand
{
public:
    EventHandlerCommand(int type) : type_(type) { }
    virtual ~EventHandlerCommand() { }
    int type_;
};

struct AddOrRemoveEventHandlerCommand : public EventHandlerCommand
{
    enum { Type = 1 };
    AddOrRemoveEventHandlerCommand(bool add, Object* sender, const StringHash& eventType, WeakPtr<LuaFunction> function) :
        EventHandlerCommand(Type), add_(add), sender_(sender), eventType_(eventType), function_(function)
    {
    }

    bool add_;
    Object* sender_;
    StringHash eventType_;
    WeakPtr<LuaFunction> function_;
};

struct RemoveAllEventHandlersCommand : public EventHandlerCommand
{
    enum { Type = 2 };
    RemoveAllEventHandlersCommand(Object* sender) : EventHandlerCommand(Type), sender_(sender)
    {
    }

    Object* sender_;
};

struct RemoveEventHandlersExceptCommand : public EventHandlerCommand
{

    enum { Type = 3 };
    RemoveEventHandlersExceptCommand(const PODVector<StringHash>& exceptionTypes) : EventHandlerCommand(Type), exceptionTypes_(exceptionTypes)
    {
    }
    PODVector<StringHash> exceptionTypes_;
};

LuaScriptEventInvoker::LuaScriptEventInvoker(Context* context) :
    Object(context),
    instance_(0),
    invoking_(false)
{
}

LuaScriptEventInvoker::LuaScriptEventInvoker(LuaScriptInstance* instance) :
    Object(instance->GetContext()),
    instance_(instance),
    invoking_(false)
{
}

LuaScriptEventInvoker::~LuaScriptEventInvoker()
{
}

void LuaScriptEventInvoker::AddEventHandler(Object* sender, const StringHash& eventType, WeakPtr<LuaFunction> function)
{
    if (invoking_)
    {
        eventHandlerCommands_.Push(new AddOrRemoveEventHandlerCommand(true, sender, eventType, function));
        return;
    }

    EventTypeToLuaFunctionVectorMap& eventTypeToFunctionVectorMap = GetEventTypeToLuaFunctionVectorMap(sender);
    EventTypeToLuaFunctionVectorMap::Iterator i = eventTypeToFunctionVectorMap.Find(eventType);

    if (i == eventTypeToFunctionVectorMap.End())
    {
        eventTypeToFunctionVectorMap[eventType].Push(function);

        if (!sender)
            SubscribeToEvent(eventType, HANDLER(LuaScriptEventInvoker, HandleLuaScriptEvent));
        else
            SubscribeToEvent(sender, eventType, HANDLER(LuaScriptEventInvoker, HandleLuaScriptEvent));
    }
    else
    {
        if (!i->second_.Contains(function))
            i->second_.Push(function);
    }
}

void LuaScriptEventInvoker::RemoveEventHandler(Object* sender, const StringHash& eventType, WeakPtr<LuaFunction> function)
{
    if (invoking_)
    {
        eventHandlerCommands_.Push(new AddOrRemoveEventHandlerCommand(false, sender, eventType, function));
        return;
    }

    EventTypeToLuaFunctionVectorMap& eventTypeToLuaFunctionVectorMap = GetEventTypeToLuaFunctionVectorMap(sender);
    EventTypeToLuaFunctionVectorMap::Iterator i = eventTypeToLuaFunctionVectorMap.Find(eventType);
    if (i == eventTypeToLuaFunctionVectorMap.End())
        return;

    if (function)
        i->second_.Remove(function);
    else
        i->second_.Clear();

    if (i->second_.Empty())
    {
        eventTypeToLuaFunctionVectorMap.Erase(i);

        if (!sender)
            UnsubscribeFromEvent(eventType);
        else
            UnsubscribeFromEvent(sender, eventType);
    }
}

void LuaScriptEventInvoker::RemoveAllEventHandlers(Object* sender)
{
    if (invoking_)
    {
        eventHandlerCommands_.Push(new RemoveAllEventHandlersCommand(sender));
        return;
    }

    if (!sender)
    {
        UnsubscribeFromAllEvents();
        eventTypeToLuaFunctionVectorMap.Clear();
        senderEventTypeToLuaFunctionVectorMap.Clear();
    }
    else
    {
        UnsubscribeFromEvents(sender);
        senderEventTypeToLuaFunctionVectorMap.Erase(sender);
    }
}

void LuaScriptEventInvoker::RemoveEventHandlersExcept(const PODVector<StringHash>& exceptionTypes)
{
    if (invoking_)
    {
        eventHandlerCommands_.Push(new RemoveEventHandlersExceptCommand(exceptionTypes));
        return;
    }

    for (unsigned i = 0; i < exceptionTypes.Size(); ++i)
        eventTypeToLuaFunctionVectorMap.Erase(exceptionTypes[i]);

    UnsubscribeFromAllEventsExcept(exceptionTypes, false);
}

void LuaScriptEventInvoker::HandleLuaScriptEvent(StringHash eventType, VariantMap& eventData)
{
    Object* sender = GetEventHandler()->GetSender();
    EventTypeToLuaFunctionVectorMap& eventTypeToLuaFunctionVectorMap = GetEventTypeToLuaFunctionVectorMap(sender);
    EventTypeToLuaFunctionVectorMap::Iterator i = eventTypeToLuaFunctionVectorMap.Find(eventType);
    if (i == eventTypeToLuaFunctionVectorMap.End())
        return;

    SharedPtr<LuaScriptInstance> instance(instance_);

    invoking_ = true;

    LuaFunctionVector& luaFunctionVector = i->second_;
    if (instance)
    {
        for (unsigned i = 0; i < luaFunctionVector.Size(); ++i)
        {
            WeakPtr<LuaFunction>& function = luaFunctionVector[i];
            if (function && function->BeginCall(instance))
            {
                function->PushUserType(eventType, "StringHash");
                function->PushUserType(eventData, "VariantMap");
                function->EndCall();
            }
        }
    }
    else
    {
        for (unsigned i = 0; i < luaFunctionVector.Size(); ++i)
        {
            WeakPtr<LuaFunction>& function = luaFunctionVector[i];
            if (function && function->BeginCall())
            {
                function->PushUserType(eventType, "StringHash");
                function->PushUserType(eventData, "VariantMap");
                function->EndCall();
            }
        }
    }

    invoking_ = false;

    if (!eventHandlerCommands_.Empty())
    {
        for (unsigned i = 0; i < eventHandlerCommands_.Size(); ++i)
            ExecuteThenDestroyCommand(eventHandlerCommands_[i]);

        eventHandlerCommands_.Clear();
    }
}

void LuaScriptEventInvoker::ExecuteThenDestroyCommand(EventHandlerCommand* command)
{
    if (!command)
        return;

    switch (command->type_)
    {
    case AddOrRemoveEventHandlerCommand::Type:
        {
            AddOrRemoveEventHandlerCommand* theCommand = (AddOrRemoveEventHandlerCommand*)command;
            if (theCommand->add_)
                AddEventHandler(theCommand->sender_, theCommand->eventType_, theCommand->function_);
            else
                RemoveEventHandler(theCommand->sender_, theCommand->eventType_, theCommand->function_);
        }
        break;

    case RemoveAllEventHandlersCommand::Type:
        {
            RemoveAllEventHandlersCommand* theCommand = (RemoveAllEventHandlersCommand*)command;
            RemoveAllEventHandlers(theCommand->sender_);
        }
        break;

    case RemoveEventHandlersExceptCommand::Type:
        {
            RemoveEventHandlersExceptCommand* theCommand = (RemoveEventHandlersExceptCommand*)command;
            RemoveEventHandlersExcept(theCommand->exceptionTypes_);
        }
        break;
    }

    delete command;
}

}
<|endoftext|>


<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:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * 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.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
 * OWNER OR 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"
#include "modules/donottrack/NavigatorDoNotTrack.h"

#include "core/frame/LocalFrame.h"
#include "core/frame/Navigator.h"
#include "core/loader/FrameLoaderClient.h"

namespace WebCore {

NavigatorDoNotTrack::NavigatorDoNotTrack(LocalFrame* frame)
    : DOMWindowProperty(frame)
{
}

NavigatorDoNotTrack::~NavigatorDoNotTrack()
{
}

const char* NavigatorDoNotTrack::supplementName()
{
    return "NavigatorDoNotTrack";
}

NavigatorDoNotTrack& NavigatorDoNotTrack::from(Navigator& navigator)
{
    NavigatorDoNotTrack* supplement = static_cast<NavigatorDoNotTrack*>(WillBeHeapSupplement<Navigator>::from(navigator, supplementName()));
    if (!supplement) {
        supplement = new NavigatorDoNotTrack(navigator.frame());
        provideTo(navigator, supplementName(), adoptPtrWillBeNoop(supplement));
    }
    return *supplement;
}

String NavigatorDoNotTrack::doNotTrack(Navigator& navigator)
{
    return NavigatorDoNotTrack::from(navigator).doNotTrack();
}

String NavigatorDoNotTrack::doNotTrack()
{
    return frame() ? frame()->loader().client()->doNotTrackValue() : String();
}

} // namespace WebCore
<commit_msg>DNT should return 'null' if there is no client.<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:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * 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.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
 * OWNER OR 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"
#include "modules/donottrack/NavigatorDoNotTrack.h"

#include "core/frame/LocalFrame.h"
#include "core/frame/Navigator.h"
#include "core/loader/FrameLoaderClient.h"

namespace WebCore {

NavigatorDoNotTrack::NavigatorDoNotTrack(LocalFrame* frame)
    : DOMWindowProperty(frame)
{
}

NavigatorDoNotTrack::~NavigatorDoNotTrack()
{
}

const char* NavigatorDoNotTrack::supplementName()
{
    return "NavigatorDoNotTrack";
}

NavigatorDoNotTrack& NavigatorDoNotTrack::from(Navigator& navigator)
{
    NavigatorDoNotTrack* supplement = static_cast<NavigatorDoNotTrack*>(WillBeHeapSupplement<Navigator>::from(navigator, supplementName()));
    if (!supplement) {
        supplement = new NavigatorDoNotTrack(navigator.frame());
        provideTo(navigator, supplementName(), adoptPtrWillBeNoop(supplement));
    }
    return *supplement;
}

String NavigatorDoNotTrack::doNotTrack(Navigator& navigator)
{
    return NavigatorDoNotTrack::from(navigator).doNotTrack();
}

String NavigatorDoNotTrack::doNotTrack()
{
    if (!frame() || !frame()->loader().client())
        return String();
    return frame()->loader().client()->doNotTrackValue();
}

} // namespace WebCore
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: salcolorutils.cxx,v $
 *
 *  $Revision: 1.8 $
 *
 *  last change: $Author: rt $ $Date: 2007-07-05 15:59:28 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_vcl.hxx"

#ifndef _SV_SALCOLORUTILS_HXX
    #include <salcolorutils.hxx>
#endif
#include <vcl/salbtype.hxx>

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

SalColor GetSalColor( const float* pQuartzColor )
{
    return MAKE_SALCOLOR( sal_uInt8( pQuartzColor[0] * 255.0), sal_uInt8(  pQuartzColor[1] * 255.0 ), sal_uInt8( pQuartzColor[2] * 255.0 ) );
}

void SetSalColor( const SalColor& rColor, float* pQuartzColor )
{
    pQuartzColor[0] = (float) SALCOLOR_RED(rColor) / 255.0;
    pQuartzColor[1] = (float) SALCOLOR_GREEN(rColor) / 255.0;
    pQuartzColor[2] = (float) SALCOLOR_BLUE(rColor) / 255.0;
    pQuartzColor[3] = 1.0;
}

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

<commit_msg>INTEGRATION: CWS aquavcl03 (1.8.4); FILE MERGED 2007/09/14 15:44:39 pl 1.8.4.1: header cleanup<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: salcolorutils.cxx,v $
 *
 *  $Revision: 1.9 $
 *
 *  last change: $Author: kz $ $Date: 2007-10-09 15:14:47 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_vcl.hxx"

#include "salcolorutils.hxx"
#include "vcl/salbtype.hxx"

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

SalColor GetSalColor( const float* pQuartzColor )
{
    return MAKE_SALCOLOR( sal_uInt8( pQuartzColor[0] * 255.0), sal_uInt8(  pQuartzColor[1] * 255.0 ), sal_uInt8( pQuartzColor[2] * 255.0 ) );
}

void SetSalColor( const SalColor& rColor, float* pQuartzColor )
{
    pQuartzColor[0] = (float) SALCOLOR_RED(rColor) / 255.0;
    pQuartzColor[1] = (float) SALCOLOR_GREEN(rColor) / 255.0;
    pQuartzColor[2] = (float) SALCOLOR_BLUE(rColor) / 255.0;
    pQuartzColor[3] = 1.0;
}

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

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: gtkobject.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: hr $ $Date: 2004-10-13 08:58:50 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _VCL_GTKOBJECT_HXX
#define _VCL_GTKOBJECT_HXX

#ifndef _SV_SV_H
#include <sv.h>
#endif
#ifndef _SV_SYSDATA_HXX
#include <sysdata.hxx>
#endif
#ifndef _SV_SALOBJ_HXX
#include <salobj.hxx>
#endif
#ifndef _VCL_GTKFRAME_HXX
#include <plugins/gtk/gtkframe.hxx>
#endif

class GtkSalObject : public SalObject
{
    SystemChildData     m_aSystemData;
    GtkWidget*          m_pSocket;
    GdkRegion*          m_pRegion;

    // signals
    static gboolean     signalButton( GtkWidget*, GdkEventButton*, gpointer );
    static gboolean     signalFocus( GtkWidget*, GdkEventFocus*, gpointer );
    static void         signalDestroy( GtkObject*, gpointer );
public:
    GtkSalObject( GtkSalFrame* pParent );
    virtual ~GtkSalObject();

    // overload all pure virtual methods
     virtual void                   ResetClipRegion();
    virtual USHORT                  GetClipRegionType();
    virtual void                    BeginSetClipRegion( ULONG nRects );
    virtual void                    UnionClipRegion( long nX, long nY, long nWidth, long nHeight );
    virtual void                    EndSetClipRegion();

    virtual void                    SetPosSize( long nX, long nY, long nWidth, long nHeight );
    virtual void                    Show( BOOL bVisible );
    virtual void                    Enable( BOOL nEnable );
    virtual void                    GrabFocus();

    virtual void                    SetBackground();
    virtual void                    SetBackground( SalColor nSalColor );

    virtual const SystemEnvData*    GetSystemData() const;

};

#endif // _SV_SALOBJ_H
<commit_msg>INTEGRATION: CWS ooo19126 (1.3.340); FILE MERGED 2005/09/05 14:45:34 rt 1.3.340.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: gtkobject.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-09 12:52:22 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _VCL_GTKOBJECT_HXX
#define _VCL_GTKOBJECT_HXX

#ifndef _SV_SV_H
#include <sv.h>
#endif
#ifndef _SV_SYSDATA_HXX
#include <sysdata.hxx>
#endif
#ifndef _SV_SALOBJ_HXX
#include <salobj.hxx>
#endif
#ifndef _VCL_GTKFRAME_HXX
#include <plugins/gtk/gtkframe.hxx>
#endif

class GtkSalObject : public SalObject
{
    SystemChildData     m_aSystemData;
    GtkWidget*          m_pSocket;
    GdkRegion*          m_pRegion;

    // signals
    static gboolean     signalButton( GtkWidget*, GdkEventButton*, gpointer );
    static gboolean     signalFocus( GtkWidget*, GdkEventFocus*, gpointer );
    static void         signalDestroy( GtkObject*, gpointer );
public:
    GtkSalObject( GtkSalFrame* pParent );
    virtual ~GtkSalObject();

    // overload all pure virtual methods
     virtual void                   ResetClipRegion();
    virtual USHORT                  GetClipRegionType();
    virtual void                    BeginSetClipRegion( ULONG nRects );
    virtual void                    UnionClipRegion( long nX, long nY, long nWidth, long nHeight );
    virtual void                    EndSetClipRegion();

    virtual void                    SetPosSize( long nX, long nY, long nWidth, long nHeight );
    virtual void                    Show( BOOL bVisible );
    virtual void                    Enable( BOOL nEnable );
    virtual void                    GrabFocus();

    virtual void                    SetBackground();
    virtual void                    SetBackground( SalColor nSalColor );

    virtual const SystemEnvData*    GetSystemData() const;

};

#endif // _SV_SALOBJ_H
<|endoftext|>


<commit_before>////////////////////////////////////////////////////////////////////////////////
//
// Test program for The Loki Library
// Copyright (c) 2008 Richard Sposato
// The copyright on this file is protected under the terms of the MIT license.
//
// Permission to use, copy, modify, distribute and sell this software for any
// purpose is hereby granted without fee, provided that the above copyright
// notice appear in all copies and that both that copyright notice and this
// permission notice appear in supporting documentation.
//
// The author makes no representations about the suitability of this software
// for any purpose. It is provided "as is" without express or implied warranty.
//
////////////////////////////////////////////////////////////////////////////////

// $Id$

/// @file main.cpp This provides examples on how to use Loki's Checker facility.

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

#include "../../include/loki/Checker.h"

#include <stdexcept>
#include <vector>

#if !defined( nullptr )
    #define nullptr NULL
#endif

#if !defined( NULL )
    #define NULL 0
#endif

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

/* This class has 2 invariants.  The this pointer may never equal NULL, and the
 value may not equal zero.
 */
class Thingy
{
public:

    static void ChangeThat( void );

    static unsigned int GetThat( void );

    explicit Thingy( unsigned int value );

    Thingy( const Thingy & that );

    Thingy & operator = ( const Thingy & that );

    ~Thingy( void );

    void Swap( Thingy & that );

    bool operator == ( const Thingy & that ) const;

    void DoSomethingEvil( void );

    unsigned int GetValue( void ) const;

    unsigned int DoSomething( bool doThrow ) const;

    void DoSomethingElse( void ) const;

    void AddCount( unsigned int count );

    unsigned int GetCount( unsigned int index ) const;

    void ClearCounts( void );

private:

    /// This is a static validator.
    static bool StaticIsValid( void );

    /// This is a per-instance validator.
    bool IsValid( void ) const;

    /// This can be used to validate pre-conditions and post-conditions.
    bool IsValidEmpty( void ) const;

    /// This can be used to validate pre-conditions and post-conditions.
    bool IsValidFull( void ) const;

    // These lines show how to declare checkers for non-static functions in a host class.
    typedef ::Loki::ContractChecker< Thingy, ::Loki::CheckForNoThrow  > CheckForNoThrow;
    typedef ::Loki::ContractChecker< Thingy, ::Loki::CheckForNoChangeOrThrow > CheckForNoChangeOrThrow;
    typedef ::Loki::ContractChecker< Thingy, ::Loki::CheckForNoChange > CheckForNoChange;
    typedef ::Loki::ContractChecker< Thingy, ::Loki::CheckForEquality > CheckForEquality;
    typedef ::Loki::ContractChecker< Thingy, ::Loki::CheckForNothing  > CheckInvariants;

    // These lines show how to declare checkers for static functions of a host class.
    typedef ::Loki::StaticChecker< ::Loki::CheckStaticForNoThrow  > CheckStaticForNoThrow;
    typedef ::Loki::StaticChecker< ::Loki::CheckStaticForNothing  > CheckStaticInvariants;

    typedef ::std::vector< unsigned int > IntBlock;

    static unsigned int s_value;

    unsigned int m_value;

    IntBlock m_counts;

};

unsigned int Thingy::s_value = 10;

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

// This example shows how static functions can use a no-throw checkers.
void Thingy::ChangeThat( void )
{
    CheckStaticForNoThrow checker( &Thingy::StaticIsValid );
    (void)checker;
    s_value--;
}

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

// This example shows how static functions can use an invariant checkers.
unsigned int Thingy::GetThat( void )
{
    CheckStaticInvariants checker( &Thingy::StaticIsValid );
    (void)checker;
    return s_value;
}

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

// This example shows how ctors can use an invariant checker.
Thingy::Thingy( unsigned int value ) :
    m_value( value ),
    m_counts()
{
    CheckInvariants checker( this, &Thingy::IsValid );
    (void)checker;
}

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

Thingy::Thingy( const Thingy & that ) :
    m_value( that.m_value ),
    m_counts( that.m_counts )
{
    CheckInvariants checker( this, &Thingy::IsValid );
    (void)checker;
}

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

Thingy & Thingy::operator = ( const Thingy & that )
{
    CheckInvariants checker( this, &Thingy::IsValid );
    (void)checker;
    if ( &that != this )
    {
        Thingy temp( that );
        temp.Swap( *this );
    }
    return *this;
}

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

// A destructor really doesn't need a checker, but does need to confirm
// the object is valid at the start of the destructor.
Thingy::~Thingy( void )
{
    assert( IsValid() );
}

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

// A swap function gets 2 checkers - one for this, and another for that.
void Thingy::Swap( Thingy & that )
{
    CheckInvariants checker1( this, &Thingy::IsValid );
    (void)checker1;
    CheckInvariants checker2( &that, &Thingy::IsValid );
    (void)checker2;

    const IntBlock counts( m_counts );
    m_counts = that.m_counts;
    that.m_counts = counts;
    const unsigned int value = m_value;
    m_value = that.m_value;
    that.m_value = value;
}

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

bool Thingy::operator == ( const Thingy & that ) const
{
    return ( m_value == that.m_value );
}

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

void Thingy::DoSomethingEvil( void )
{
    m_value = 0;
}

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

// This example shows how to use the no-throw checker.
unsigned int Thingy::GetValue( void ) const
{
    CheckForNoThrow checker( this, &Thingy::IsValid );
    (void)checker;
    return m_value;
}

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

// This example shows how to use the equality checker.
unsigned int Thingy::DoSomething( bool doThrow ) const
{
    CheckForEquality checker( this, &Thingy::IsValid );
    (void)checker;
    if ( doThrow )
        throw ::std::logic_error( "Test Exception." );
    return m_value;
}

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

// This example shows how to use the no-change checker.
void Thingy::DoSomethingElse( void ) const
{
    CheckForNoChange checker( this, &Thingy::IsValid );
    (void)checker;
}

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

void Thingy::AddCount( unsigned int count )
{
    // This function's checker cares about class invariants and post-conditions,
    // but does not need to check pre-conditions, so it passes in a nullptr for
    // the pre-condition validator.  Ths post-condition validator just makes sure
    // the container has at least 1 element.
    CheckInvariants checker( this, &Thingy::IsValid, nullptr, &Thingy::IsValidFull );
    m_counts.push_back( count );
}

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

unsigned int Thingy::GetCount( unsigned int index ) const
{
    // This function's checker cares about class invariants and both the pre- and
    // post-conditions, so it passes in pointers for all 3 validators.  The pre-
    // and post-conditions are both about making sure the container is not empty.
    CheckForNoChangeOrThrow checker( this, &Thingy::IsValid, &Thingy::IsValidFull, &Thingy::IsValidFull );
    if ( m_counts.size() <= index )
        return 0;
    const unsigned int count = m_counts[ index ];
    return count;
}

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

void Thingy::ClearCounts( void )
{
    // This function's checker cares about class invariants and post-conditions,
    // but does not need to check pre-conditions, so it passes in a nullptr for
    // the pre-condition validator.  Ths post-condition validator just makes sure
    // the container has no elements.
    CheckForNoThrow checker( this, &Thingy::IsValid, nullptr, &Thingy::IsValidEmpty );
    m_counts.clear();
}

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

bool Thingy::StaticIsValid( void )
{
    assert( s_value != 0 );
    return true;
}

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

bool Thingy::IsValid( void ) const
{
    assert( nullptr != this );
    assert( m_value != 0 );
    return true;
}

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

bool Thingy::IsValidEmpty( void ) const
{
    assert( nullptr != this );
    assert( m_counts.size() == 0 );
    return true;
}

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

bool Thingy::IsValidFull( void ) const
{
    assert( nullptr != this );
    assert( m_counts.size() != 0 );
    return true;
}

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

// This is a validator function called by checkers inside standalone functions.
bool AllIsValid( void )
{
    assert( Thingy::GetThat() != 0 );
    return true;
}

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

// These lines show how to declare checkers for standalone functions.
typedef ::Loki::StaticChecker< ::Loki::CheckStaticForNoThrow  > CheckStaticForNoThrow;
typedef ::Loki::StaticChecker< ::Loki::CheckStaticForNothing  > CheckStaticInvariants;

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

void DoSomething( void )
{
    // This example shows how to use a checker in a stand-alone function.
    CheckStaticForNoThrow checker( &AllIsValid );
    (void)checker;
    Thingy::ChangeThat();
}

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

int main( unsigned int argc, const char * const argv[] )
{

    unsigned int count = 0;
    try
    {
        // First do some tests on class member functions.
        Thingy t1( 1 );
        t1.DoSomething( false );
        Thingy t2( 2 );
        t2.DoSomething( true );

        // These lines will exercise the functions with pre- and post-conditions.
        t1.AddCount( 11 );
        t1.AddCount( 13 );
        t1.AddCount( 17 );
        t1.AddCount( 19 );
        count = t1.GetCount( 3 );
        assert( count == 19 );
        count = t1.GetCount( 0 );
        assert( count == 11 );
        t1.ClearCounts();

        // Next do some tests with static member functions.
        Thingy::ChangeThat();
        const unsigned int value = Thingy::GetThat();
        assert( value != 0 );

        // Then do a test with a standalone function.
        DoSomething();
    }
    catch ( ... )
    {
    }

    return 0;
}

// ----------------------------------------------------------------------------
<commit_msg>Added more tests<commit_after>////////////////////////////////////////////////////////////////////////////////
//
// Test program for The Loki Library
// Copyright (c) 2008 Richard Sposato
// The copyright on this file is protected under the terms of the MIT license.
//
// Permission to use, copy, modify, distribute and sell this software for any
// purpose is hereby granted without fee, provided that the above copyright
// notice appear in all copies and that both that copyright notice and this
// permission notice appear in supporting documentation.
//
// The author makes no representations about the suitability of this software
// for any purpose. It is provided "as is" without express or implied warranty.
//
////////////////////////////////////////////////////////////////////////////////

// $Id$

/// @file main.cpp This provides examples on how to use Loki's Checker facility.

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

#include "../../include/loki/Checker.h"

#include <stdexcept>
#include <iostream>
#include <vector>

#if !defined( nullptr )
    #define nullptr NULL
#endif

#if !defined( NULL )
    #define NULL 0
#endif

using namespace std;

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

/* This class has 2 invariants.  The this pointer may never equal NULL, and the
 value may not equal zero.
 */
class Thingy
{
public:

    static void ChangeThat( void );

    static unsigned int GetThat( void );

    explicit Thingy( unsigned int value );

    Thingy( const Thingy & that );

    Thingy & operator = ( const Thingy & that );

    ~Thingy( void );

    void Swap( Thingy & that );

    bool operator == ( const Thingy & that ) const;

    void DoSomethingEvil( void );

    unsigned int GetValue( void ) const;

    unsigned int DoSomething( bool doThrow ) const;

    void DoSomethingElse( void ) const;

    void AddCount( unsigned int count );

    unsigned int GetCount( unsigned int index ) const;

    void ClearCounts( void );

private:

    /// This is a static validator.
    static bool StaticIsValid( void );

    /// This is a per-instance validator.
    bool IsValid( void ) const;

    /// This can be used to validate pre-conditions and post-conditions.
    bool IsValidEmpty( void ) const;

    /// This can be used to validate pre-conditions and post-conditions.
    bool IsValidFull( void ) const;

    // These lines show how to declare checkers for non-static functions in a host class.
    typedef ::Loki::ContractChecker< Thingy, ::Loki::CheckForNoThrow  > CheckForNoThrow;
    typedef ::Loki::ContractChecker< Thingy, ::Loki::CheckForNoChangeOrThrow > CheckForNoChangeOrThrow;
    typedef ::Loki::ContractChecker< Thingy, ::Loki::CheckForNoChange > CheckForNoChange;
    typedef ::Loki::ContractChecker< Thingy, ::Loki::CheckForEquality > CheckForEquality;
    typedef ::Loki::ContractChecker< Thingy, ::Loki::CheckForNothing  > CheckInvariants;

    // These lines show how to declare checkers for static functions of a host class.
    typedef ::Loki::StaticChecker< ::Loki::CheckStaticForNoThrow  > CheckStaticForNoThrow;
    typedef ::Loki::StaticChecker< ::Loki::CheckStaticForNothing  > CheckStaticInvariants;

    typedef ::std::vector< unsigned int > IntBlock;

    static unsigned int s_value;

    unsigned int m_value;

    IntBlock m_counts;

};

unsigned int Thingy::s_value = 10;

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

// This example shows how static functions can use a no-throw checkers.
void Thingy::ChangeThat( void )
{
    CheckStaticForNoThrow checker( &Thingy::StaticIsValid );
    (void)checker;
    s_value--;
}

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

// This example shows how static functions can use an invariant checker.
unsigned int Thingy::GetThat( void )
{
    CheckStaticInvariants checker( &Thingy::StaticIsValid );
    (void)checker;
    return s_value;
}

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

// This example shows how ctors can use an invariant checker.
Thingy::Thingy( unsigned int value ) :
    m_value( value ),
    m_counts()
{
    CheckInvariants checker( this, &Thingy::IsValid );
    (void)checker;
}

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

Thingy::Thingy( const Thingy & that ) :
    m_value( that.m_value ),
    m_counts( that.m_counts )
{
    CheckInvariants checker( this, &Thingy::IsValid );
    (void)checker;
}

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

Thingy & Thingy::operator = ( const Thingy & that )
{
    CheckInvariants checker( this, &Thingy::IsValid );
    (void)checker;
    if ( &that != this )
    {
        Thingy temp( that );
        temp.Swap( *this );
    }
    return *this;
}

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

// A destructor really doesn't need a checker, but does need to confirm
// the object is valid at the start of the destructor.
Thingy::~Thingy( void )
{
    assert( IsValid() );
}

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

// A swap function gets 2 checkers - one for this, and another for that.
void Thingy::Swap( Thingy & that )
{
    CheckInvariants checker1( this, &Thingy::IsValid );
    (void)checker1;
    CheckInvariants checker2( &that, &Thingy::IsValid );
    (void)checker2;

    const IntBlock counts( m_counts );
    m_counts = that.m_counts;
    that.m_counts = counts;
    const unsigned int value = m_value;
    m_value = that.m_value;
    that.m_value = value;
}

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

bool Thingy::operator == ( const Thingy & that ) const
{
    return ( m_value == that.m_value );
}

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

void Thingy::DoSomethingEvil( void )
{
    m_value = 0;
}

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

// This example shows how to use the no-throw checker.
unsigned int Thingy::GetValue( void ) const
{
    CheckForNoThrow checker( this, &Thingy::IsValid );
    (void)checker;
    return m_value;
}

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

// This example shows how to use the equality checker.
unsigned int Thingy::DoSomething( bool doThrow ) const
{
    CheckForEquality checker( this, &Thingy::IsValid );
    (void)checker;
    if ( doThrow )
        throw ::std::logic_error( "Test Exception." );
    return m_value;
}

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

// This example shows how to use the no-change checker.
void Thingy::DoSomethingElse( void ) const
{
    CheckForNoChange checker( this, &Thingy::IsValid );
    (void)checker;
}

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

void Thingy::AddCount( unsigned int count )
{
    // This function's checker cares about class invariants and post-conditions,
    // but does not need to check pre-conditions, so it passes in a nullptr for
    // the pre-condition validator.  Ths post-condition validator just makes sure
    // the container has at least 1 element.
    CheckInvariants checker( this, &Thingy::IsValid, nullptr, &Thingy::IsValidFull );
    m_counts.push_back( count );
}

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

unsigned int Thingy::GetCount( unsigned int index ) const
{
    // This function's checker cares about class invariants and both the pre- and
    // post-conditions, so it passes in pointers for all 3 validators.  The pre-
    // and post-conditions are both about making sure the container is not empty.
    CheckForNoChangeOrThrow checker( this, &Thingy::IsValid, &Thingy::IsValidFull, &Thingy::IsValidFull );
    if ( m_counts.size() <= index )
        return 0;
    const unsigned int count = m_counts[ index ];
    return count;
}

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

void Thingy::ClearCounts( void )
{
    // This function's checker cares about class invariants and post-conditions,
    // but does not need to check pre-conditions, so it passes in a nullptr for
    // the pre-condition validator.  Ths post-condition validator just makes sure
    // the container has no elements.
    CheckForNoThrow checker( this, &Thingy::IsValid, nullptr, &Thingy::IsValidEmpty );
    m_counts.clear();
}

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

// This is a static validator.
bool Thingy::StaticIsValid( void )
{
    assert( s_value != 0 );
    return true;
}

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

// This is a per-instance validator.
bool Thingy::IsValid( void ) const
{
    assert( nullptr != this );
    assert( m_value != 0 );
    return true;
}

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

bool Thingy::IsValidEmpty( void ) const
{
    assert( nullptr != this );
    assert( m_counts.size() == 0 );
    return true;
}

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

bool Thingy::IsValidFull( void ) const
{
    assert( nullptr != this );
    assert( m_counts.size() != 0 );
    return true;
}

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

// This is a validator function called by checkers inside standalone functions.
bool AllIsValid( void )
{
    assert( Thingy::GetThat() != 0 );
    return true;
}

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

// These lines show how to declare checkers for standalone functions.
typedef ::Loki::StaticChecker< ::Loki::CheckStaticForNoThrow  > CheckStaticForNoThrow;
typedef ::Loki::StaticChecker< ::Loki::CheckStaticForNothing  > CheckStaticInvariants;

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

void DoSomething( void )
{
    // This example shows how to use a checker in a stand-alone function.
    CheckStaticForNoThrow checker( &AllIsValid );
    (void)checker;
    Thingy::ChangeThat();
}

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

void ThrowTest( void )
{
    Thingy thingy( 10 );
    throw ::std::logic_error( "Will Thingy assert during an exception?" );
}

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

int main( unsigned int argc, const char * const argv[] )
{

    try
    {
        cout << "Just before call to ThrowTest." << endl;
        ThrowTest();
        cout << "Just after call to ThrowTest." << endl;
    }
    catch ( const ::std::logic_error & ex )
    {
        cout << "Caught an exception!  " << ex.what() << endl;
    }
    catch ( const ::std::exception & ex )
    {
        cout << "Caught an exception!  " << ex.what() << endl;
    }
    catch ( ... )
    {
        cout << "Caught an exception!" << endl;
    }

    unsigned int count = 0;
    try
    {
        cout << "Running basic tests with Thingy." << endl;
        // First do some tests on class member functions.
        Thingy t1( 1 );
        t1.DoSomething( false );
        Thingy t2( 2 );
        t2.DoSomething( true );
        cout << "Done with basic tests with Thingy." << endl;
    }
    catch ( const ::std::logic_error & ex )
    {
        cout << "Caught an exception!  " << ex.what() << endl;
    }
    catch ( const ::std::exception & ex )
    {
        cout << "Caught an exception!  " << ex.what() << endl;
    }
    catch ( ... )
    {
        cout << "Caught an exception!" << endl;
    }

    try
    {
        Thingy t1( 1 );
        cout << "Now running tests with Thingy counts." << endl;
        // These lines will exercise the functions with pre- and post-conditions.
        t1.AddCount( 11 );
        t1.AddCount( 13 );
        t1.AddCount( 17 );
        t1.AddCount( 19 );
        count = t1.GetCount( 3 );
        assert( count == 19 );
        count = t1.GetCount( 0 );
        assert( count == 11 );
        t1.ClearCounts();
        cout << "Done with tests with Thingy counts." << endl;
    }
    catch ( const ::std::logic_error & ex )
    {
        cout << "Caught an exception!  " << ex.what() << endl;
    }
    catch ( const ::std::exception & ex )
    {
        cout << "Caught an exception!  " << ex.what() << endl;
    }
    catch ( ... )
    {
        cout << "Caught an exception!" << endl;
    }

    try
    {
        cout << "Now run tests on static member functions" << endl;
        // Next do some tests with static member functions.
        Thingy::ChangeThat();
        const unsigned int value = Thingy::GetThat();
        assert( value != 0 );
        cout << "Done with tests on static member functions" << endl;
    }
    catch ( const ::std::logic_error & ex )
    {
        cout << "Caught an exception!  " << ex.what() << endl;
    }
    catch ( const ::std::exception & ex )
    {
        cout << "Caught an exception!  " << ex.what() << endl;
    }
    catch ( ... )
    {
        cout << "Caught an exception!" << endl;
    }

    try
    {
        cout << "Now run test on a standalone function." << endl;
        // Then do a test with a standalone function.
        DoSomething();
        cout << "Done with test on a standalone function." << endl;
    }
    catch ( const ::std::exception & ex )
    {
        cout << "Caught an exception!  " << ex.what() << endl;
    }
    catch ( ... )
    {
        cout << "Caught an exception!" << endl;
    }

    cout << "All done!" << endl;
    return 0;
}

// ----------------------------------------------------------------------------
<|endoftext|>


<commit_before>// @(#)root/treeplayer:$Id$
// Author: Axel Naumann, 2011-09-28

/*************************************************************************
 * Copyright (C) 1995-2011, Rene Brun and Fons Rademakers and al.        *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#include "TTreeReaderValue.h"

#include "TTreeReader.h"
#include "TBranchClones.h"
#include "TBranchElement.h"
#include "TBranchRef.h"
#include "TBranchSTL.h"
#include "TBranchProxyDirector.h"
#include "TLeaf.h"
#include "TTreeProxyGenerator.h"
#include "TTreeReaderValue.h"
#include "TRegexp.h"
#include "TStreamerInfo.h"
#include "TStreamerElement.h"

////////////////////////////////////////////////////////////////////////////////
//                                                                            //
// TTreeReaderValue                                                        //
//                                                                            //
// Extracts data from a TTree.                                                //
//                                                                            //
//                                                                            //
//                                                                            //
//                                                                            //
//                                                                            //
//                                                                            //
//                                                                            //
//                                                                            //
//                                                                            //
////////////////////////////////////////////////////////////////////////////////

ClassImp(TTreeReaderValueBase)

//______________________________________________________________________________
ROOT::TTreeReaderValueBase::TTreeReaderValueBase(TTreeReader* reader /*= 0*/,
                                                       const char* branchname /*= 0*/,
                                                       TDictionary* dict /*= 0*/):
   fTreeReader(reader),
   fBranchName(branchname),
   fDict(dict),
   fProxy(0),
   fSetupStatus(kSetupNotSetup),
   fReadStatus(kReadNothingYet),
   fLeaf(NULL),
   fTreeLastOffset(-1)
{
   // Construct a tree value reader and register it with the reader object.
   if (fTreeReader) fTreeReader->RegisterValueReader(this);
}

//______________________________________________________________________________
ROOT::TTreeReaderValueBase::~TTreeReaderValueBase()
{
   // Unregister from tree reader, cleanup.
   if (fTreeReader) fTreeReader->DeregisterValueReader(this);
}

//______________________________________________________________________________
ROOT::TTreeReaderValueBase::EReadStatus
ROOT::TTreeReaderValueBase::ProxyRead() {
   if (!fProxy) return kReadNothingYet;
   if (fProxy->Read()) {
      fReadStatus = kReadSuccess;
   } else {
      fReadStatus = kReadError;
   }
   return fReadStatus;
}

TLeaf* ROOT::TTreeReaderValueBase::GetLeaf() {
   if (fLeafName.Length() > 0){

      Long64_t newChainOffset = fTreeReader->GetTree()->GetChainOffset();

      if (newChainOffset != fTreeLastOffset){
         fTreeLastOffset = newChainOffset;
         fLeaf = fTreeReader->GetTree()->GetBranch(fBranchName)->GetLeaf(fLeafName);
      }
      return fLeaf;
   }
   else {
      Error("GetLeaf()", "We are not reading a leaf");
      return 0;
   }
}

void* ROOT::TTreeReaderValueBase::GetAddress() {
   if (ProxyRead() != kReadSuccess) return 0;

   if (fLeafName.Length() > 0){
      Long64_t newChainOffset = fTreeReader->GetTree()->GetChainOffset();

      if (newChainOffset != fTreeLastOffset){
         fTreeLastOffset = newChainOffset;
         fLeaf = fTreeReader->GetTree()->GetBranch(fBranchName)->GetLeaf(fLeafName);
      }
      return fLeaf->GetValuePointer();
   }
   return fProxy ? (Byte_t*)fProxy->GetWhere() : 0;
}

//______________________________________________________________________________
void ROOT::TTreeReaderValueBase::CreateProxy() {
   // Create the proxy object for our branch.
   if (fProxy) {
      return;
   }
   if (!fTreeReader) {
      Error("CreateProxy()", "TTreeReader object not set / available for branch %s!",
            fBranchName.Data());
      return;
   }
   if (!fDict) {
      TBranch* br = fTreeReader->GetTree()->GetBranch(fBranchName);
      const char* brDataType = "{UNDETERMINED}";
      if (br) {
         TDictionary* brDictUnused = 0;
         brDataType = GetBranchDataType(br, brDictUnused);
      }
      Error("CreateProxy()", "The template argument type T of %s accessing branch %s (which contains data of type %s) is not known to ROOT. You will need to create a dictionary for it.",
            IsA()->GetName() ? IsA()->GetName() : "?", fBranchName.Data(), brDataType);
      return;
   }

   // Search for the branchname, determine what it contains, and wire the
   // TBranchProxy representing it to us so we can access its data.

   ROOT::TNamedBranchProxy* namedProxy
      = (ROOT::TNamedBranchProxy*)fTreeReader->FindObject(fBranchName);
   if (namedProxy && namedProxy->GetDict() == fDict) {
      fProxy = namedProxy->GetProxy();
      return;
   }

   TBranch* branch = fTreeReader->GetTree()->GetBranch(fBranchName);
   TLeaf *myLeaf = NULL;
   TDictionary* branchActualType = 0;

   if (!branch) {
      if (fBranchName.Contains(".")){
         TRegexp leafNameExpression ("\\.[a-zA-Z0-9]+$");
         TString leafName (fBranchName(leafNameExpression));
         TString branchName = fBranchName(0, fBranchName.Length() - leafName.Length());
         branch = fTreeReader->GetTree()->GetBranch(branchName);
         if (!branch){
            Error("CreateProxy()", "The tree does not have a branch called %s. You could check with TTree::Print() for available branches.", fBranchName.Data());
            fProxy = 0;
            return;
         }
         else {
            myLeaf = branch->GetLeaf(TString(leafName(1, leafName.Length())));
            if (!myLeaf){
               Error("CreateProxy()", "The tree does not have a branch, nor a sub-branch called %s. You could check with TTree::Print() for available branches.", fBranchName.Data());
            }
            else {
               TDictionary *tempDict = TDictionary::GetDictionary(myLeaf->GetTypeName());
               if (tempDict && tempDict->IsA() == TDataType::Class() && TDictionary::GetDictionary(((TDataType*)tempDict)->GetTypeName()) == fDict){
                  //fLeafOffset = myLeaf->GetOffset() / 4;
                  branchActualType = fDict;
                  fLeaf = myLeaf;
                  fBranchName = branchName;
                  fLeafName = leafName(1, leafName.Length());
               }
               else {
                  Error("CreateProxy()", "Leaf of type %s cannot be read by TTreeReaderValue<%s>.", myLeaf->GetTypeName(), fDict->GetName());
               }
            }
         }
      }
      else {
         Error("CreateProxy()", "The tree does not have a branch called %s. You could check with TTree::Print() for available branches.", fBranchName.Data());
         fProxy = 0;
         return;
      }
   }

   if (!myLeaf){
      const char* branchActualTypeName = GetBranchDataType(branch, branchActualType);

      if (!branchActualType) {
         Error("CreateProxy()", "The branch %s contains data of type %s, which does not have a dictionary.",
               fBranchName.Data(), branchActualTypeName ? branchActualTypeName : "{UNDETERMINED TYPE}");
         fProxy = 0;
         return;
      }

      if (fDict != branchActualType) {
         Error("CreateProxy()", "The branch %s contains data of type %s. It cannot be accessed by a TTreeReaderValue<%s>",
               fBranchName.Data(), branchActualType->GetName(), fDict->GetName());
         return;
      }
   }

   // Update named proxy's dictionary
   if (namedProxy && !namedProxy->GetDict()) {
      namedProxy->SetDict(fDict);
      fProxy = namedProxy->GetProxy();
      return;
   }

   // Search for the branchname, determine what it contains, and wire the
   // TBranchProxy representing it to us so we can access its data.
   // A proxy for branch must not have been created before (i.e. check
   // fProxies before calling this function!)

   TString membername;

   bool isTopLevel = branch->GetMother() == branch;
   if (!isTopLevel) {
      membername = strrchr(branch->GetName(), '.');
      if (membername.IsNull()) {
         membername = branch->GetName();
      }
   }
   namedProxy = new ROOT::TNamedBranchProxy(fTreeReader->fDirector, branch, membername);
   fTreeReader->GetProxies()->Add(namedProxy);
   fProxy = namedProxy->GetProxy();
}

//______________________________________________________________________________
const char* ROOT::TTreeReaderValueBase::GetBranchDataType(TBranch* branch,
                                           TDictionary* &dict) const
{
   // Retrieve the type of data stored by branch; put its dictionary into
   // dict, return its type name. If no dictionary is available, at least
   // its type name should be returned.

   dict = 0;
   if (branch->IsA() == TBranchElement::Class()) {
      TBranchElement* brElement = (TBranchElement*)branch;
      if (brElement->GetType() == TBranchElement::kSTLNode ||
            brElement->GetType() == TBranchElement::kLeafNode ||
            brElement->GetType() == TBranchElement::kObjectNode) {

         TStreamerInfo *streamerInfo = brElement->GetInfo();
         Int_t id = brElement->GetID();

         if (id >= 0){
            TStreamerElement *element = (TStreamerElement*)streamerInfo->GetElements()->At(id);
            if (element->IsA() == TStreamerSTL::Class()){
               TStreamerSTL *myStl = (TStreamerSTL*)element;
               dict = myStl->GetClass();
               return 0;
            }
         }

         if (brElement->GetTypeName()) dict = TDictionary::GetDictionary(brElement->GetTypeName());
         if (dict && dict->IsA() == TDataType::Class()){
            dict = TDictionary::GetDictionary(((TDataType*)dict)->GetTypeName());
            if (dict != fDict){
               dict = TClass::GetClass(brElement->GetTypeName());
            }
            if (dict != fDict){
               dict = brElement->GetCurrentClass();
            }
         }
         else if (!dict) {
            dict = brElement->GetCurrentClass();
         }

         return brElement->GetTypeName();
      } else if (brElement->GetType() == TBranchElement::kClonesNode) {
         dict = TClonesArray::Class();
         return "TClonesArray";
      } else if (brElement->GetType() == 31
                 || brElement->GetType() == 41) {
         // it's a member, extract from GetClass()'s streamer info
         Error("GetBranchDataType()", "Must use TTreeReaderValueArray to access a member of an object that is stored in a collection.");
      }
      else {
         Error("GetBranchDataType()", "Unknown type and class combination: %i, %s", brElement->GetType(), brElement->GetClassName());
      }
      return 0;
   } else if (branch->IsA() == TBranch::Class()
              || branch->IsA() == TBranchObject::Class()
              || branch->IsA() == TBranchSTL::Class()) {
      const char* dataTypeName = branch->GetClassName();
      if ((!dataTypeName || !dataTypeName[0])
          && branch->IsA() == TBranch::Class()) {
         // leaflist. Can't represent.
         Error("GetBranchDataType()", "The branch %s was created using a leaf list and cannot be represented as a C++ type. Please access one of its siblings using a TTreeReaderValueArray:", branch->GetName());
         TIter iLeaves(branch->GetListOfLeaves());
         TLeaf* leaf = 0;
         while ((leaf = (TLeaf*) iLeaves())) {
            Error("GetBranchDataType()", "   %s.%s", branch->GetName(), leaf->GetName());
         }
         return 0;
      }
      if (dataTypeName) dict = TDictionary::GetDictionary(dataTypeName);
      return dataTypeName;
   } else if (branch->IsA() == TBranchClones::Class()) {
      dict = TClonesArray::Class();
      return "TClonesArray";
   } else if (branch->IsA() == TBranchRef::Class()) {
      // Can't represent.
      Error("GetBranchDataType()", "The branch %s is a TBranchRef and cannot be represented as a C++ type.", branch->GetName());
      return 0;
   } else {
      Error("GetBranchDataType()", "The branch %s is of type %s - something that is not handled yet.", branch->GetName(), branch->IsA()->GetName());
      return 0;
   }

   return 0;
}

<commit_msg>Added comment lines for the documentation generation<commit_after>// @(#)root/treeplayer:$Id$
// Author: Axel Naumann, 2011-09-28

/*************************************************************************
 * Copyright (C) 1995-2011, Rene Brun and Fons Rademakers and al.        *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#include "TTreeReaderValue.h"

#include "TTreeReader.h"
#include "TBranchClones.h"
#include "TBranchElement.h"
#include "TBranchRef.h"
#include "TBranchSTL.h"
#include "TBranchProxyDirector.h"
#include "TLeaf.h"
#include "TTreeProxyGenerator.h"
#include "TTreeReaderValue.h"
#include "TRegexp.h"
#include "TStreamerInfo.h"
#include "TStreamerElement.h"

////////////////////////////////////////////////////////////////////////////////
//                                                                            //
// TTreeReaderValue                                                        //
//                                                                            //
// Extracts data from a TTree.                                                //
//                                                                            //
//                                                                            //
//                                                                            //
//                                                                            //
//                                                                            //
//                                                                            //
//                                                                            //
//                                                                            //
//                                                                            //
////////////////////////////////////////////////////////////////////////////////

ClassImp(TTreeReaderValueBase)

//______________________________________________________________________________
ROOT::TTreeReaderValueBase::TTreeReaderValueBase(TTreeReader* reader /*= 0*/,
                                                       const char* branchname /*= 0*/,
                                                       TDictionary* dict /*= 0*/):
   fTreeReader(reader),
   fBranchName(branchname),
   fDict(dict),
   fProxy(0),
   fSetupStatus(kSetupNotSetup),
   fReadStatus(kReadNothingYet),
   fLeaf(NULL),
   fTreeLastOffset(-1)
{
   // Construct a tree value reader and register it with the reader object.
   if (fTreeReader) fTreeReader->RegisterValueReader(this);
}

//______________________________________________________________________________
ROOT::TTreeReaderValueBase::~TTreeReaderValueBase()
{
   // Unregister from tree reader, cleanup.
   if (fTreeReader) fTreeReader->DeregisterValueReader(this);
}

//______________________________________________________________________________
ROOT::TTreeReaderValueBase::EReadStatus
ROOT::TTreeReaderValueBase::ProxyRead() {
   if (!fProxy) return kReadNothingYet;
   if (fProxy->Read()) {
      fReadStatus = kReadSuccess;
   } else {
      fReadStatus = kReadError;
   }
   return fReadStatus;
}

//______________________________________________________________________________
TLeaf* ROOT::TTreeReaderValueBase::GetLeaf() {
   if (fLeafName.Length() > 0){

      Long64_t newChainOffset = fTreeReader->GetTree()->GetChainOffset();

      if (newChainOffset != fTreeLastOffset){
         fTreeLastOffset = newChainOffset;
         fLeaf = fTreeReader->GetTree()->GetBranch(fBranchName)->GetLeaf(fLeafName);
      }
      return fLeaf;
   }
   else {
      Error("GetLeaf()", "We are not reading a leaf");
      return 0;
   }
}

//______________________________________________________________________________
void* ROOT::TTreeReaderValueBase::GetAddress() {
   if (ProxyRead() != kReadSuccess) return 0;

   if (fLeafName.Length() > 0){
      Long64_t newChainOffset = fTreeReader->GetTree()->GetChainOffset();

      if (newChainOffset != fTreeLastOffset){
         fTreeLastOffset = newChainOffset;
         fLeaf = fTreeReader->GetTree()->GetBranch(fBranchName)->GetLeaf(fLeafName);
      }
      return fLeaf->GetValuePointer();
   }
   return fProxy ? (Byte_t*)fProxy->GetWhere() : 0;
}

//______________________________________________________________________________
void ROOT::TTreeReaderValueBase::CreateProxy() {
   // Create the proxy object for our branch.
   if (fProxy) {
      return;
   }
   if (!fTreeReader) {
      Error("CreateProxy()", "TTreeReader object not set / available for branch %s!",
            fBranchName.Data());
      return;
   }
   if (!fDict) {
      TBranch* br = fTreeReader->GetTree()->GetBranch(fBranchName);
      const char* brDataType = "{UNDETERMINED}";
      if (br) {
         TDictionary* brDictUnused = 0;
         brDataType = GetBranchDataType(br, brDictUnused);
      }
      Error("CreateProxy()", "The template argument type T of %s accessing branch %s (which contains data of type %s) is not known to ROOT. You will need to create a dictionary for it.",
            IsA()->GetName() ? IsA()->GetName() : "?", fBranchName.Data(), brDataType);
      return;
   }

   // Search for the branchname, determine what it contains, and wire the
   // TBranchProxy representing it to us so we can access its data.

   ROOT::TNamedBranchProxy* namedProxy
      = (ROOT::TNamedBranchProxy*)fTreeReader->FindObject(fBranchName);
   if (namedProxy && namedProxy->GetDict() == fDict) {
      fProxy = namedProxy->GetProxy();
      return;
   }

   TBranch* branch = fTreeReader->GetTree()->GetBranch(fBranchName);
   TLeaf *myLeaf = NULL;
   TDictionary* branchActualType = 0;

   if (!branch) {
      if (fBranchName.Contains(".")){
         TRegexp leafNameExpression ("\\.[a-zA-Z0-9]+$");
         TString leafName (fBranchName(leafNameExpression));
         TString branchName = fBranchName(0, fBranchName.Length() - leafName.Length());
         branch = fTreeReader->GetTree()->GetBranch(branchName);
         if (!branch){
            Error("CreateProxy()", "The tree does not have a branch called %s. You could check with TTree::Print() for available branches.", fBranchName.Data());
            fProxy = 0;
            return;
         }
         else {
            myLeaf = branch->GetLeaf(TString(leafName(1, leafName.Length())));
            if (!myLeaf){
               Error("CreateProxy()", "The tree does not have a branch, nor a sub-branch called %s. You could check with TTree::Print() for available branches.", fBranchName.Data());
            }
            else {
               TDictionary *tempDict = TDictionary::GetDictionary(myLeaf->GetTypeName());
               if (tempDict && tempDict->IsA() == TDataType::Class() && TDictionary::GetDictionary(((TDataType*)tempDict)->GetTypeName()) == fDict){
                  //fLeafOffset = myLeaf->GetOffset() / 4;
                  branchActualType = fDict;
                  fLeaf = myLeaf;
                  fBranchName = branchName;
                  fLeafName = leafName(1, leafName.Length());
               }
               else {
                  Error("CreateProxy()", "Leaf of type %s cannot be read by TTreeReaderValue<%s>.", myLeaf->GetTypeName(), fDict->GetName());
               }
            }
         }
      }
      else {
         Error("CreateProxy()", "The tree does not have a branch called %s. You could check with TTree::Print() for available branches.", fBranchName.Data());
         fProxy = 0;
         return;
      }
   }

   if (!myLeaf){
      const char* branchActualTypeName = GetBranchDataType(branch, branchActualType);

      if (!branchActualType) {
         Error("CreateProxy()", "The branch %s contains data of type %s, which does not have a dictionary.",
               fBranchName.Data(), branchActualTypeName ? branchActualTypeName : "{UNDETERMINED TYPE}");
         fProxy = 0;
         return;
      }

      if (fDict != branchActualType) {
         Error("CreateProxy()", "The branch %s contains data of type %s. It cannot be accessed by a TTreeReaderValue<%s>",
               fBranchName.Data(), branchActualType->GetName(), fDict->GetName());
         return;
      }
   }

   // Update named proxy's dictionary
   if (namedProxy && !namedProxy->GetDict()) {
      namedProxy->SetDict(fDict);
      fProxy = namedProxy->GetProxy();
      return;
   }

   // Search for the branchname, determine what it contains, and wire the
   // TBranchProxy representing it to us so we can access its data.
   // A proxy for branch must not have been created before (i.e. check
   // fProxies before calling this function!)

   TString membername;

   bool isTopLevel = branch->GetMother() == branch;
   if (!isTopLevel) {
      membername = strrchr(branch->GetName(), '.');
      if (membername.IsNull()) {
         membername = branch->GetName();
      }
   }
   namedProxy = new ROOT::TNamedBranchProxy(fTreeReader->fDirector, branch, membername);
   fTreeReader->GetProxies()->Add(namedProxy);
   fProxy = namedProxy->GetProxy();
}

//______________________________________________________________________________
const char* ROOT::TTreeReaderValueBase::GetBranchDataType(TBranch* branch,
                                           TDictionary* &dict) const
{
   // Retrieve the type of data stored by branch; put its dictionary into
   // dict, return its type name. If no dictionary is available, at least
   // its type name should be returned.

   dict = 0;
   if (branch->IsA() == TBranchElement::Class()) {
      TBranchElement* brElement = (TBranchElement*)branch;
      if (brElement->GetType() == TBranchElement::kSTLNode ||
            brElement->GetType() == TBranchElement::kLeafNode ||
            brElement->GetType() == TBranchElement::kObjectNode) {

         TStreamerInfo *streamerInfo = brElement->GetInfo();
         Int_t id = brElement->GetID();

         if (id >= 0){
            TStreamerElement *element = (TStreamerElement*)streamerInfo->GetElements()->At(id);
            if (element->IsA() == TStreamerSTL::Class()){
               TStreamerSTL *myStl = (TStreamerSTL*)element;
               dict = myStl->GetClass();
               return 0;
            }
         }

         if (brElement->GetTypeName()) dict = TDictionary::GetDictionary(brElement->GetTypeName());
         if (dict && dict->IsA() == TDataType::Class()){
            dict = TDictionary::GetDictionary(((TDataType*)dict)->GetTypeName());
            if (dict != fDict){
               dict = TClass::GetClass(brElement->GetTypeName());
            }
            if (dict != fDict){
               dict = brElement->GetCurrentClass();
            }
         }
         else if (!dict) {
            dict = brElement->GetCurrentClass();
         }

         return brElement->GetTypeName();
      } else if (brElement->GetType() == TBranchElement::kClonesNode) {
         dict = TClonesArray::Class();
         return "TClonesArray";
      } else if (brElement->GetType() == 31
                 || brElement->GetType() == 41) {
         // it's a member, extract from GetClass()'s streamer info
         Error("GetBranchDataType()", "Must use TTreeReaderValueArray to access a member of an object that is stored in a collection.");
      }
      else {
         Error("GetBranchDataType()", "Unknown type and class combination: %i, %s", brElement->GetType(), brElement->GetClassName());
      }
      return 0;
   } else if (branch->IsA() == TBranch::Class()
              || branch->IsA() == TBranchObject::Class()
              || branch->IsA() == TBranchSTL::Class()) {
      const char* dataTypeName = branch->GetClassName();
      if ((!dataTypeName || !dataTypeName[0])
          && branch->IsA() == TBranch::Class()) {
         // leaflist. Can't represent.
         Error("GetBranchDataType()", "The branch %s was created using a leaf list and cannot be represented as a C++ type. Please access one of its siblings using a TTreeReaderValueArray:", branch->GetName());
         TIter iLeaves(branch->GetListOfLeaves());
         TLeaf* leaf = 0;
         while ((leaf = (TLeaf*) iLeaves())) {
            Error("GetBranchDataType()", "   %s.%s", branch->GetName(), leaf->GetName());
         }
         return 0;
      }
      if (dataTypeName) dict = TDictionary::GetDictionary(dataTypeName);
      return dataTypeName;
   } else if (branch->IsA() == TBranchClones::Class()) {
      dict = TClonesArray::Class();
      return "TClonesArray";
   } else if (branch->IsA() == TBranchRef::Class()) {
      // Can't represent.
      Error("GetBranchDataType()", "The branch %s is a TBranchRef and cannot be represented as a C++ type.", branch->GetName());
      return 0;
   } else {
      Error("GetBranchDataType()", "The branch %s is of type %s - something that is not handled yet.", branch->GetName(), branch->IsA()->GetName());
      return 0;
   }

   return 0;
}

<|endoftext|>