<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: KServices.cxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: obo $ $Date: 2006-01-19 15:31:29 $
 *
 *  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
 *
 ************************************************************************/

#include "KDriver.hxx"

#ifndef _CPPUHELPER_FACTORY_HXX_
#include <cppuhelper/factory.hxx>
#endif
#ifndef _OSL_DIAGNOSE_H_
#include <osl/diagnose.h>
#endif

using namespace connectivity::kab;
using ::rtl::OUString;
using ::com::sun::star::uno::Reference;
using ::com::sun::star::uno::Sequence;
using ::com::sun::star::registry::XRegistryKey;
using ::com::sun::star::lang::XSingleServiceFactory;
using ::com::sun::star::lang::XMultiServiceFactory;

typedef Reference< XSingleServiceFactory > (SAL_CALL *createFactoryFunc)
        (
            const Reference< XMultiServiceFactory > & rServiceManager,
            const OUString & rComponentName,
            ::cppu::ComponentInstantiation pCreateFunction,
            const Sequence< OUString > & rServiceNames,
            rtl_ModuleCount* _pTemp
        );

//***************************************************************************************
//
// The following C Api must be provided!
// It consists in three functions that must be exported by the module
//

//---------------------------------------------------------------------------------------
void REGISTER_PROVIDER(
        const OUString& aServiceImplName,
        const Sequence< OUString>& Services,
        const Reference< ::com::sun::star::registry::XRegistryKey > & xKey)
{
    OUString aMainKeyName;
    aMainKeyName = OUString::createFromAscii("/");
    aMainKeyName += aServiceImplName;
    aMainKeyName += OUString::createFromAscii("/UNO/SERVICES");

    Reference< ::com::sun::star::registry::XRegistryKey >  xNewKey( xKey->createKey(aMainKeyName) );
    OSL_ENSURE(xNewKey.is(), "KAB::component_writeInfo : could not create a registry key !");

    for (sal_uInt32 i=0; i<Services.getLength(); ++i)
        xNewKey->createKey(Services[i]);
}

//---------------------------------------------------------------------------------------
struct ProviderRequest
{
    Reference< XSingleServiceFactory > xRet;
    Reference< XMultiServiceFactory > const xServiceManager;
    OUString const sImplementationName;

    ProviderRequest(
        void* pServiceManager,
        sal_Char const* pImplementationName
    )
    : xServiceManager(reinterpret_cast<XMultiServiceFactory*>(pServiceManager))
    , sImplementationName(OUString::createFromAscii(pImplementationName))
    {
    }

    inline
    sal_Bool CREATE_PROVIDER(
                const OUString& Implname,
                const Sequence< OUString > & Services,
                ::cppu::ComponentInstantiation Factory,
                createFactoryFunc creator
            )
    {
        if (!xRet.is() && (Implname == sImplementationName))
        try
        {
            xRet = creator( xServiceManager, sImplementationName,Factory, Services,0);
        }
        catch(...)
        {
        }
        return xRet.is();
    }

    void* getProvider() const { return xRet.get(); }
};

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

extern "C" void SAL_CALL component_getImplementationEnvironment(
                const sal_Char  **ppEnvTypeName,
                uno_Environment **ppEnv
            )
{
    *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
}

//---------------------------------------------------------------------------------------
extern "C" sal_Bool SAL_CALL component_writeInfo(
                void* pServiceManager,
                void* pRegistryKey
            )
{
    if (pRegistryKey)
    try
    {
        Reference< ::com::sun::star::registry::XRegistryKey > xKey(reinterpret_cast< ::com::sun::star::registry::XRegistryKey*>(pRegistryKey));

        REGISTER_PROVIDER(
            KabDriver::getImplementationName_Static(),
            KabDriver::getSupportedServiceNames_Static(), xKey);

        return sal_True;
    }
    catch (::com::sun::star::registry::InvalidRegistryException& )
    {
        OSL_ENSURE(sal_False, "KAB::component_writeInfo : could not create a registry key ! ## InvalidRegistryException !");
    }

    return sal_False;
}

//---------------------------------------------------------------------------------------
extern "C" void* SAL_CALL component_getFactory(
                    const sal_Char* pImplementationName,
                    void* pServiceManager,
                    void* pRegistryKey)
{
    void* pRet = 0;
    if (pServiceManager)
    {
        ProviderRequest aReq(pServiceManager,pImplementationName);

        aReq.CREATE_PROVIDER(
            KabDriver::getImplementationName_Static(),
            KabDriver::getSupportedServiceNames_Static(),
            &KabDriver::Create,
            ::cppu::createSingleFactory)
        ;

        if (aReq.xRet.is())
            aReq.xRet->acquire();

        pRet = aReq.getProvider();
    }

    return pRet;
};

<commit_msg>INTEGRATION: CWS warnings01 (1.3.4); FILE MERGED 2006/01/30 14:18:54 sb 1.3.4.1: #i53898# Made code warning-free.<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: KServices.cxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: hr $ $Date: 2006-06-20 01:39:51 $
 *
 *  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
 *
 ************************************************************************/

#include "KDriver.hxx"

#ifndef _CPPUHELPER_FACTORY_HXX_
#include <cppuhelper/factory.hxx>
#endif
#ifndef _OSL_DIAGNOSE_H_
#include <osl/diagnose.h>
#endif

using namespace connectivity::kab;
using ::rtl::OUString;
using ::com::sun::star::uno::Reference;
using ::com::sun::star::uno::Sequence;
using ::com::sun::star::registry::XRegistryKey;
using ::com::sun::star::lang::XSingleServiceFactory;
using ::com::sun::star::lang::XMultiServiceFactory;

typedef Reference< XSingleServiceFactory > (SAL_CALL *createFactoryFunc)
        (
            const Reference< XMultiServiceFactory > & rServiceManager,
            const OUString & rComponentName,
            ::cppu::ComponentInstantiation pCreateFunction,
            const Sequence< OUString > & rServiceNames,
            rtl_ModuleCount* _pTemp
        );

//***************************************************************************************
//
// The following C Api must be provided!
// It consists in three functions that must be exported by the module
//

//---------------------------------------------------------------------------------------
void REGISTER_PROVIDER(
        const OUString& aServiceImplName,
        const Sequence< OUString>& Services,
        const Reference< ::com::sun::star::registry::XRegistryKey > & xKey)
{
    OUString aMainKeyName;
    aMainKeyName = OUString::createFromAscii("/");
    aMainKeyName += aServiceImplName;
    aMainKeyName += OUString::createFromAscii("/UNO/SERVICES");

    Reference< ::com::sun::star::registry::XRegistryKey >  xNewKey( xKey->createKey(aMainKeyName) );
    OSL_ENSURE(xNewKey.is(), "KAB::component_writeInfo : could not create a registry key !");

    for (sal_Int32 i=0; i<Services.getLength(); ++i)
        xNewKey->createKey(Services[i]);
}

//---------------------------------------------------------------------------------------
struct ProviderRequest
{
    Reference< XSingleServiceFactory > xRet;
    Reference< XMultiServiceFactory > const xServiceManager;
    OUString const sImplementationName;

    ProviderRequest(
        void* pServiceManager,
        sal_Char const* pImplementationName
    )
    : xServiceManager(reinterpret_cast<XMultiServiceFactory*>(pServiceManager))
    , sImplementationName(OUString::createFromAscii(pImplementationName))
    {
    }

    inline
    sal_Bool CREATE_PROVIDER(
                const OUString& Implname,
                const Sequence< OUString > & Services,
                ::cppu::ComponentInstantiation Factory,
                createFactoryFunc creator
            )
    {
        if (!xRet.is() && (Implname == sImplementationName))
        try
        {
            xRet = creator( xServiceManager, sImplementationName,Factory, Services,0);
        }
        catch(...)
        {
        }
        return xRet.is();
    }

    void* getProvider() const { return xRet.get(); }
};

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

extern "C" void SAL_CALL component_getImplementationEnvironment(
                const sal_Char  **ppEnvTypeName,
                uno_Environment **
            )
{
    *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
}

//---------------------------------------------------------------------------------------
extern "C" sal_Bool SAL_CALL component_writeInfo(
                void*,
                void* pRegistryKey
            )
{
    if (pRegistryKey)
    try
    {
        Reference< ::com::sun::star::registry::XRegistryKey > xKey(reinterpret_cast< ::com::sun::star::registry::XRegistryKey*>(pRegistryKey));

        REGISTER_PROVIDER(
            KabDriver::getImplementationName_Static(),
            KabDriver::getSupportedServiceNames_Static(), xKey);

        return sal_True;
    }
    catch (::com::sun::star::registry::InvalidRegistryException& )
    {
        OSL_ENSURE(sal_False, "KAB::component_writeInfo : could not create a registry key ! ## InvalidRegistryException !");
    }

    return sal_False;
}

//---------------------------------------------------------------------------------------
extern "C" void* SAL_CALL component_getFactory(
                    const sal_Char* pImplementationName,
                    void* pServiceManager,
                    void*)
{
    void* pRet = 0;
    if (pServiceManager)
    {
        ProviderRequest aReq(pServiceManager,pImplementationName);

        aReq.CREATE_PROVIDER(
            KabDriver::getImplementationName_Static(),
            KabDriver::getSupportedServiceNames_Static(),
            &KabDriver::Create,
            ::cppu::createSingleFactory)
        ;

        if (aReq.xRet.is())
            aReq.xRet->acquire();

        pRet = aReq.getProvider();
    }

    return pRet;
};

<|endoftext|>


<commit_before><commit_msg>refactor indescribable wall of code into reusable hunks<commit_after><|endoftext|>


<commit_before><commit_msg>wrap vcl::Window* in VclPtr<commit_after><|endoftext|>


<commit_before><commit_msg>probable intent is the other way around<commit_after><|endoftext|>


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

#include "webrtc/video_engine/vie_base_impl.h"

#include <sstream>
#include <string>
#include <utility>

#include "webrtc/engine_configurations.h"
#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h"
#include "webrtc/modules/video_coding/main/interface/video_coding.h"
#include "webrtc/modules/video_processing/main/interface/video_processing.h"
#include "webrtc/modules/video_render/include/video_render.h"
#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
#include "webrtc/system_wrappers/interface/logging.h"
#include "webrtc/video_engine/include/vie_errors.h"
#include "webrtc/video_engine/vie_capturer.h"
#include "webrtc/video_engine/vie_channel.h"
#include "webrtc/video_engine/vie_channel_manager.h"
#include "webrtc/video_engine/vie_defines.h"
#include "webrtc/video_engine/vie_encoder.h"
#include "webrtc/video_engine/vie_impl.h"
#include "webrtc/video_engine/vie_input_manager.h"
#include "webrtc/video_engine/vie_shared_data.h"

namespace webrtc {

ViEBase* ViEBase::GetInterface(VideoEngine* video_engine) {
  if (!video_engine) {
    return NULL;
  }
  VideoEngineImpl* vie_impl = static_cast<VideoEngineImpl*>(video_engine);
  ViEBaseImpl* vie_base_impl = vie_impl;
  (*vie_base_impl)++;  // Increase ref count.

  return vie_base_impl;
}

int ViEBaseImpl::Release() {
  (*this)--;  // Decrease ref count.

  int32_t ref_count = GetCount();
  if (ref_count < 0) {
    LOG(LS_WARNING) << "ViEBase released too many times.";
    return -1;
  }
  return ref_count;
}

ViEBaseImpl::ViEBaseImpl(const Config& config)
    : shared_data_(config) {}

ViEBaseImpl::~ViEBaseImpl() {}

int ViEBaseImpl::Init() {
  return 0;
}

int ViEBaseImpl::SetVoiceEngine(VoiceEngine* voice_engine) {
  LOG_F(LS_INFO) << "SetVoiceEngine";
  if (shared_data_.channel_manager()->SetVoiceEngine(voice_engine) != 0) {
    shared_data_.SetLastError(kViEBaseVoEFailure);
    return -1;
  }
  return 0;
}

int ViEBaseImpl::RegisterCpuOveruseObserver(int video_channel,
                                            CpuOveruseObserver* observer) {
  LOG_F(LS_INFO) << "RegisterCpuOveruseObserver on channel " << video_channel;
  ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
  ViEChannel* vie_channel = cs.Channel(video_channel);
  if (!vie_channel) {
    shared_data_.SetLastError(kViEBaseInvalidChannelId);
    return -1;
  }
  ViEEncoder* vie_encoder = cs.Encoder(video_channel);
  assert(vie_encoder);

  ViEInputManagerScoped is(*(shared_data_.input_manager()));
  ViEFrameProviderBase* provider = is.FrameProvider(vie_encoder);
  if (provider) {
    ViECapturer* capturer = is.Capture(provider->Id());
    assert(capturer);
    capturer->RegisterCpuOveruseObserver(observer);
  }

  shared_data_.overuse_observers()->insert(
      std::pair<int, CpuOveruseObserver*>(video_channel, observer));
  return 0;
}

int ViEBaseImpl::SetCpuOveruseOptions(int video_channel,
                                      const CpuOveruseOptions& options) {
  ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
  ViEChannel* vie_channel = cs.Channel(video_channel);
  if (!vie_channel) {
    shared_data_.SetLastError(kViEBaseInvalidChannelId);
    return -1;
  }
  ViEEncoder* vie_encoder = cs.Encoder(video_channel);
  assert(vie_encoder);

  ViEInputManagerScoped is(*(shared_data_.input_manager()));
  ViEFrameProviderBase* provider = is.FrameProvider(vie_encoder);
  if (provider) {
    ViECapturer* capturer = is.Capture(provider->Id());
    if (capturer) {
      capturer->SetCpuOveruseOptions(options);
      return 0;
    }
  }
  return -1;
}

int ViEBaseImpl::CpuOveruseMeasures(int video_channel,
                                    int* capture_jitter_ms,
                                    int* avg_encode_time_ms,
                                    int* encode_usage_percent,
                                    int* capture_queue_delay_ms_per_s) {
  ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
  ViEChannel* vie_channel = cs.Channel(video_channel);
  if (!vie_channel) {
    shared_data_.SetLastError(kViEBaseInvalidChannelId);
    return -1;
  }
  ViEEncoder* vie_encoder = cs.Encoder(video_channel);
  assert(vie_encoder);

  ViEInputManagerScoped is(*(shared_data_.input_manager()));
  ViEFrameProviderBase* provider = is.FrameProvider(vie_encoder);
  if (provider) {
    ViECapturer* capturer = is.Capture(provider->Id());
    if (capturer) {
      capturer->CpuOveruseMeasures(capture_jitter_ms,
                                   avg_encode_time_ms,
                                   encode_usage_percent,
                                   capture_queue_delay_ms_per_s);
      return 0;
    }
  }
  return -1;
}

int ViEBaseImpl::CreateChannel(int& video_channel) {  // NOLINT
  return CreateChannel(video_channel, static_cast<const Config*>(NULL));
}

int ViEBaseImpl::CreateChannel(int& video_channel,  // NOLINT
                               const Config* config) {
  if (shared_data_.channel_manager()->CreateChannel(&video_channel,
                                                    config) == -1) {
    video_channel = -1;
    shared_data_.SetLastError(kViEBaseChannelCreationFailed);
    return -1;
  }
  LOG(LS_INFO) << "Video channel created: " << video_channel;
  return 0;
}

int ViEBaseImpl::CreateChannel(int& video_channel,  // NOLINT
                               int original_channel) {
  return CreateChannel(video_channel, original_channel, true);
}

int ViEBaseImpl::CreateReceiveChannel(int& video_channel,  // NOLINT
                                      int original_channel) {
  return CreateChannel(video_channel, original_channel, false);
}

int ViEBaseImpl::DeleteChannel(const int video_channel) {
  {
    ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
    ViEChannel* vie_channel = cs.Channel(video_channel);
    if (!vie_channel) {
      shared_data_.SetLastError(kViEBaseInvalidChannelId);
      return -1;
    }

    // Deregister the ViEEncoder if no other channel is using it.
    ViEEncoder* vie_encoder = cs.Encoder(video_channel);
    if (cs.ChannelUsingViEEncoder(video_channel) == false) {
      ViEInputManagerScoped is(*(shared_data_.input_manager()));
      ViEFrameProviderBase* provider = is.FrameProvider(vie_encoder);
      if (provider) {
        provider->DeregisterFrameCallback(vie_encoder);
      }
    }
  }

  if (shared_data_.channel_manager()->DeleteChannel(video_channel) == -1) {
    shared_data_.SetLastError(kViEBaseUnknownError);
    return -1;
  }
  LOG(LS_INFO) << "Channel deleted " << video_channel;
  return 0;
}

int ViEBaseImpl::ConnectAudioChannel(const int video_channel,
                                     const int audio_channel) {
  LOG_F(LS_INFO) << "ConnectAudioChannel, video channel " << video_channel
                 << ", audio channel " << audio_channel;
  ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
  if (!cs.Channel(video_channel)) {
    shared_data_.SetLastError(kViEBaseInvalidChannelId);
    return -1;
  }

  if (shared_data_.channel_manager()->ConnectVoiceChannel(video_channel,
                                                          audio_channel) != 0) {
    shared_data_.SetLastError(kViEBaseVoEFailure);
    return -1;
  }
  return 0;
}

int ViEBaseImpl::DisconnectAudioChannel(const int video_channel) {
  LOG_F(LS_INFO) << "DisconnectAudioChannel " << video_channel;
  ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
  if (!cs.Channel(video_channel)) {
    shared_data_.SetLastError(kViEBaseInvalidChannelId);
    return -1;
  }

  if (shared_data_.channel_manager()->DisconnectVoiceChannel(
      video_channel) != 0) {
    shared_data_.SetLastError(kViEBaseVoEFailure);
    return -1;
  }
  return 0;
}

int ViEBaseImpl::StartSend(const int video_channel) {
  LOG_F(LS_INFO) << "StartSend: " << video_channel;
  ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
  ViEChannel* vie_channel = cs.Channel(video_channel);
  if (!vie_channel) {
    shared_data_.SetLastError(kViEBaseInvalidChannelId);
    return -1;
  }

  ViEEncoder* vie_encoder = cs.Encoder(video_channel);
  assert(vie_encoder != NULL);
  if (vie_encoder->Owner() != video_channel) {
    LOG_F(LS_ERROR) <<  "Can't start send on a receive only channel.";
    shared_data_.SetLastError(kViEBaseReceiveOnlyChannel);
    return -1;
  }

  // Pause and trigger a key frame.
  vie_encoder->Pause();
  int32_t error = vie_channel->StartSend();
  if (error != 0) {
    vie_encoder->Restart();
    if (error == kViEBaseAlreadySending) {
      shared_data_.SetLastError(kViEBaseAlreadySending);
    }
    LOG_F(LS_ERROR) << "Could not start sending " << video_channel;
    shared_data_.SetLastError(kViEBaseUnknownError);
    return -1;
  }
  vie_encoder->SendKeyFrame();
  vie_encoder->Restart();
  return 0;
}

int ViEBaseImpl::StopSend(const int video_channel) {
  LOG_F(LS_INFO) << "StopSend " << video_channel;

  ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
  ViEChannel* vie_channel = cs.Channel(video_channel);
  if (!vie_channel) {
    shared_data_.SetLastError(kViEBaseInvalidChannelId);
    return -1;
  }

  int32_t error = vie_channel->StopSend();
  if (error != 0) {
    if (error == kViEBaseNotSending) {
      shared_data_.SetLastError(kViEBaseNotSending);
    } else {
      LOG_F(LS_ERROR) << "Could not stop sending " << video_channel;
      shared_data_.SetLastError(kViEBaseUnknownError);
    }
    return -1;
  }
  return 0;
}

int ViEBaseImpl::StartReceive(const int video_channel) {
  LOG_F(LS_INFO) << "StartReceive " << video_channel;

  ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
  ViEChannel* vie_channel = cs.Channel(video_channel);
  if (!vie_channel) {
    shared_data_.SetLastError(kViEBaseInvalidChannelId);
    return -1;
  }
  if (vie_channel->StartReceive() != 0) {
    shared_data_.SetLastError(kViEBaseUnknownError);
    return -1;
  }
  return 0;
}

int ViEBaseImpl::StopReceive(const int video_channel) {
  LOG_F(LS_INFO) << "StopReceive " << video_channel;
  ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
  ViEChannel* vie_channel = cs.Channel(video_channel);
  if (!vie_channel) {
    shared_data_.SetLastError(kViEBaseInvalidChannelId);
    return -1;
  }
  if (vie_channel->StopReceive() != 0) {
    shared_data_.SetLastError(kViEBaseUnknownError);
    return -1;
  }
  return 0;
}

int ViEBaseImpl::GetVersion(char version[1024]) {
  assert(kViEVersionMaxMessageSize == 1024);
  if (!version) {
    shared_data_.SetLastError(kViEBaseInvalidArgument);
    return -1;
  }

  // Add WebRTC Version.
  std::stringstream version_stream;
  version_stream << "VideoEngine 3.51.0" << std::endl;

  // Add build info.
  version_stream << "Build: " << BUILDINFO << std::endl;

  int version_length = version_stream.tellp();
  assert(version_length < 1024);
  memcpy(version, version_stream.str().c_str(), version_length);
  version[version_length] = '\0';
  return 0;
}

int ViEBaseImpl::LastError() {
  return shared_data_.LastErrorInternal();
}

int ViEBaseImpl::CreateChannel(int& video_channel,  // NOLINT
                               int original_channel, bool sender) {
  ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
  if (!cs.Channel(original_channel)) {
    shared_data_.SetLastError(kViEBaseInvalidChannelId);
    return -1;
  }

  if (shared_data_.channel_manager()->CreateChannel(&video_channel,
                                                    original_channel,
                                                    sender) == -1) {
    video_channel = -1;
    shared_data_.SetLastError(kViEBaseChannelCreationFailed);
    return -1;
  }
  LOG_F(LS_INFO) << "VideoChannel created: " << video_channel
                 << ", base channel " << original_channel
                 << ", is send channel : " << sender;
  return 0;
}

}  // namespace webrtc
<commit_msg>Updated WebRTC version to 3.52 TBR=wu@webrtc.org<commit_after>/*
 *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "webrtc/video_engine/vie_base_impl.h"

#include <sstream>
#include <string>
#include <utility>

#include "webrtc/engine_configurations.h"
#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h"
#include "webrtc/modules/video_coding/main/interface/video_coding.h"
#include "webrtc/modules/video_processing/main/interface/video_processing.h"
#include "webrtc/modules/video_render/include/video_render.h"
#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
#include "webrtc/system_wrappers/interface/logging.h"
#include "webrtc/video_engine/include/vie_errors.h"
#include "webrtc/video_engine/vie_capturer.h"
#include "webrtc/video_engine/vie_channel.h"
#include "webrtc/video_engine/vie_channel_manager.h"
#include "webrtc/video_engine/vie_defines.h"
#include "webrtc/video_engine/vie_encoder.h"
#include "webrtc/video_engine/vie_impl.h"
#include "webrtc/video_engine/vie_input_manager.h"
#include "webrtc/video_engine/vie_shared_data.h"

namespace webrtc {

ViEBase* ViEBase::GetInterface(VideoEngine* video_engine) {
  if (!video_engine) {
    return NULL;
  }
  VideoEngineImpl* vie_impl = static_cast<VideoEngineImpl*>(video_engine);
  ViEBaseImpl* vie_base_impl = vie_impl;
  (*vie_base_impl)++;  // Increase ref count.

  return vie_base_impl;
}

int ViEBaseImpl::Release() {
  (*this)--;  // Decrease ref count.

  int32_t ref_count = GetCount();
  if (ref_count < 0) {
    LOG(LS_WARNING) << "ViEBase released too many times.";
    return -1;
  }
  return ref_count;
}

ViEBaseImpl::ViEBaseImpl(const Config& config)
    : shared_data_(config) {}

ViEBaseImpl::~ViEBaseImpl() {}

int ViEBaseImpl::Init() {
  return 0;
}

int ViEBaseImpl::SetVoiceEngine(VoiceEngine* voice_engine) {
  LOG_F(LS_INFO) << "SetVoiceEngine";
  if (shared_data_.channel_manager()->SetVoiceEngine(voice_engine) != 0) {
    shared_data_.SetLastError(kViEBaseVoEFailure);
    return -1;
  }
  return 0;
}

int ViEBaseImpl::RegisterCpuOveruseObserver(int video_channel,
                                            CpuOveruseObserver* observer) {
  LOG_F(LS_INFO) << "RegisterCpuOveruseObserver on channel " << video_channel;
  ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
  ViEChannel* vie_channel = cs.Channel(video_channel);
  if (!vie_channel) {
    shared_data_.SetLastError(kViEBaseInvalidChannelId);
    return -1;
  }
  ViEEncoder* vie_encoder = cs.Encoder(video_channel);
  assert(vie_encoder);

  ViEInputManagerScoped is(*(shared_data_.input_manager()));
  ViEFrameProviderBase* provider = is.FrameProvider(vie_encoder);
  if (provider) {
    ViECapturer* capturer = is.Capture(provider->Id());
    assert(capturer);
    capturer->RegisterCpuOveruseObserver(observer);
  }

  shared_data_.overuse_observers()->insert(
      std::pair<int, CpuOveruseObserver*>(video_channel, observer));
  return 0;
}

int ViEBaseImpl::SetCpuOveruseOptions(int video_channel,
                                      const CpuOveruseOptions& options) {
  ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
  ViEChannel* vie_channel = cs.Channel(video_channel);
  if (!vie_channel) {
    shared_data_.SetLastError(kViEBaseInvalidChannelId);
    return -1;
  }
  ViEEncoder* vie_encoder = cs.Encoder(video_channel);
  assert(vie_encoder);

  ViEInputManagerScoped is(*(shared_data_.input_manager()));
  ViEFrameProviderBase* provider = is.FrameProvider(vie_encoder);
  if (provider) {
    ViECapturer* capturer = is.Capture(provider->Id());
    if (capturer) {
      capturer->SetCpuOveruseOptions(options);
      return 0;
    }
  }
  return -1;
}

int ViEBaseImpl::CpuOveruseMeasures(int video_channel,
                                    int* capture_jitter_ms,
                                    int* avg_encode_time_ms,
                                    int* encode_usage_percent,
                                    int* capture_queue_delay_ms_per_s) {
  ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
  ViEChannel* vie_channel = cs.Channel(video_channel);
  if (!vie_channel) {
    shared_data_.SetLastError(kViEBaseInvalidChannelId);
    return -1;
  }
  ViEEncoder* vie_encoder = cs.Encoder(video_channel);
  assert(vie_encoder);

  ViEInputManagerScoped is(*(shared_data_.input_manager()));
  ViEFrameProviderBase* provider = is.FrameProvider(vie_encoder);
  if (provider) {
    ViECapturer* capturer = is.Capture(provider->Id());
    if (capturer) {
      capturer->CpuOveruseMeasures(capture_jitter_ms,
                                   avg_encode_time_ms,
                                   encode_usage_percent,
                                   capture_queue_delay_ms_per_s);
      return 0;
    }
  }
  return -1;
}

int ViEBaseImpl::CreateChannel(int& video_channel) {  // NOLINT
  return CreateChannel(video_channel, static_cast<const Config*>(NULL));
}

int ViEBaseImpl::CreateChannel(int& video_channel,  // NOLINT
                               const Config* config) {
  if (shared_data_.channel_manager()->CreateChannel(&video_channel,
                                                    config) == -1) {
    video_channel = -1;
    shared_data_.SetLastError(kViEBaseChannelCreationFailed);
    return -1;
  }
  LOG(LS_INFO) << "Video channel created: " << video_channel;
  return 0;
}

int ViEBaseImpl::CreateChannel(int& video_channel,  // NOLINT
                               int original_channel) {
  return CreateChannel(video_channel, original_channel, true);
}

int ViEBaseImpl::CreateReceiveChannel(int& video_channel,  // NOLINT
                                      int original_channel) {
  return CreateChannel(video_channel, original_channel, false);
}

int ViEBaseImpl::DeleteChannel(const int video_channel) {
  {
    ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
    ViEChannel* vie_channel = cs.Channel(video_channel);
    if (!vie_channel) {
      shared_data_.SetLastError(kViEBaseInvalidChannelId);
      return -1;
    }

    // Deregister the ViEEncoder if no other channel is using it.
    ViEEncoder* vie_encoder = cs.Encoder(video_channel);
    if (cs.ChannelUsingViEEncoder(video_channel) == false) {
      ViEInputManagerScoped is(*(shared_data_.input_manager()));
      ViEFrameProviderBase* provider = is.FrameProvider(vie_encoder);
      if (provider) {
        provider->DeregisterFrameCallback(vie_encoder);
      }
    }
  }

  if (shared_data_.channel_manager()->DeleteChannel(video_channel) == -1) {
    shared_data_.SetLastError(kViEBaseUnknownError);
    return -1;
  }
  LOG(LS_INFO) << "Channel deleted " << video_channel;
  return 0;
}

int ViEBaseImpl::ConnectAudioChannel(const int video_channel,
                                     const int audio_channel) {
  LOG_F(LS_INFO) << "ConnectAudioChannel, video channel " << video_channel
                 << ", audio channel " << audio_channel;
  ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
  if (!cs.Channel(video_channel)) {
    shared_data_.SetLastError(kViEBaseInvalidChannelId);
    return -1;
  }

  if (shared_data_.channel_manager()->ConnectVoiceChannel(video_channel,
                                                          audio_channel) != 0) {
    shared_data_.SetLastError(kViEBaseVoEFailure);
    return -1;
  }
  return 0;
}

int ViEBaseImpl::DisconnectAudioChannel(const int video_channel) {
  LOG_F(LS_INFO) << "DisconnectAudioChannel " << video_channel;
  ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
  if (!cs.Channel(video_channel)) {
    shared_data_.SetLastError(kViEBaseInvalidChannelId);
    return -1;
  }

  if (shared_data_.channel_manager()->DisconnectVoiceChannel(
      video_channel) != 0) {
    shared_data_.SetLastError(kViEBaseVoEFailure);
    return -1;
  }
  return 0;
}

int ViEBaseImpl::StartSend(const int video_channel) {
  LOG_F(LS_INFO) << "StartSend: " << video_channel;
  ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
  ViEChannel* vie_channel = cs.Channel(video_channel);
  if (!vie_channel) {
    shared_data_.SetLastError(kViEBaseInvalidChannelId);
    return -1;
  }

  ViEEncoder* vie_encoder = cs.Encoder(video_channel);
  assert(vie_encoder != NULL);
  if (vie_encoder->Owner() != video_channel) {
    LOG_F(LS_ERROR) <<  "Can't start send on a receive only channel.";
    shared_data_.SetLastError(kViEBaseReceiveOnlyChannel);
    return -1;
  }

  // Pause and trigger a key frame.
  vie_encoder->Pause();
  int32_t error = vie_channel->StartSend();
  if (error != 0) {
    vie_encoder->Restart();
    if (error == kViEBaseAlreadySending) {
      shared_data_.SetLastError(kViEBaseAlreadySending);
    }
    LOG_F(LS_ERROR) << "Could not start sending " << video_channel;
    shared_data_.SetLastError(kViEBaseUnknownError);
    return -1;
  }
  vie_encoder->SendKeyFrame();
  vie_encoder->Restart();
  return 0;
}

int ViEBaseImpl::StopSend(const int video_channel) {
  LOG_F(LS_INFO) << "StopSend " << video_channel;

  ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
  ViEChannel* vie_channel = cs.Channel(video_channel);
  if (!vie_channel) {
    shared_data_.SetLastError(kViEBaseInvalidChannelId);
    return -1;
  }

  int32_t error = vie_channel->StopSend();
  if (error != 0) {
    if (error == kViEBaseNotSending) {
      shared_data_.SetLastError(kViEBaseNotSending);
    } else {
      LOG_F(LS_ERROR) << "Could not stop sending " << video_channel;
      shared_data_.SetLastError(kViEBaseUnknownError);
    }
    return -1;
  }
  return 0;
}

int ViEBaseImpl::StartReceive(const int video_channel) {
  LOG_F(LS_INFO) << "StartReceive " << video_channel;

  ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
  ViEChannel* vie_channel = cs.Channel(video_channel);
  if (!vie_channel) {
    shared_data_.SetLastError(kViEBaseInvalidChannelId);
    return -1;
  }
  if (vie_channel->StartReceive() != 0) {
    shared_data_.SetLastError(kViEBaseUnknownError);
    return -1;
  }
  return 0;
}

int ViEBaseImpl::StopReceive(const int video_channel) {
  LOG_F(LS_INFO) << "StopReceive " << video_channel;
  ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
  ViEChannel* vie_channel = cs.Channel(video_channel);
  if (!vie_channel) {
    shared_data_.SetLastError(kViEBaseInvalidChannelId);
    return -1;
  }
  if (vie_channel->StopReceive() != 0) {
    shared_data_.SetLastError(kViEBaseUnknownError);
    return -1;
  }
  return 0;
}

int ViEBaseImpl::GetVersion(char version[1024]) {
  assert(kViEVersionMaxMessageSize == 1024);
  if (!version) {
    shared_data_.SetLastError(kViEBaseInvalidArgument);
    return -1;
  }

  // Add WebRTC Version.
  std::stringstream version_stream;
  version_stream << "VideoEngine 3.52.0" << std::endl;

  // Add build info.
  version_stream << "Build: " << BUILDINFO << std::endl;

  int version_length = version_stream.tellp();
  assert(version_length < 1024);
  memcpy(version, version_stream.str().c_str(), version_length);
  version[version_length] = '\0';
  return 0;
}

int ViEBaseImpl::LastError() {
  return shared_data_.LastErrorInternal();
}

int ViEBaseImpl::CreateChannel(int& video_channel,  // NOLINT
                               int original_channel, bool sender) {
  ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
  if (!cs.Channel(original_channel)) {
    shared_data_.SetLastError(kViEBaseInvalidChannelId);
    return -1;
  }

  if (shared_data_.channel_manager()->CreateChannel(&video_channel,
                                                    original_channel,
                                                    sender) == -1) {
    video_channel = -1;
    shared_data_.SetLastError(kViEBaseChannelCreationFailed);
    return -1;
  }
  LOG_F(LS_INFO) << "VideoChannel created: " << video_channel
                 << ", base channel " << original_channel
                 << ", is send channel : " << sender;
  return 0;
}

}  // namespace webrtc
<|endoftext|>


<commit_before>/*
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 2001 The Apache Software Foundation.  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.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xalan" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 APACHE SOFTWARE FOUNDATION 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.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

#if !defined(XPATHALLOCATOR_INCLUDE_GUARD_135792455)
#define XPATHALLOCATOR_INCLUDE_GUARD_135792455

// Base include file.  Must be first.
#include <XPath/XPathDefinitions.hpp>

#include <PlatformSupport/ArenaAllocator.hpp>

#include <XPath/XPath.hpp>

class XALAN_XPATH_EXPORT XPathAllocator
{
public:

	typedef XPath							object_type;

	typedef ArenaAllocator<object_type>		ArenaAllocatorType;
	typedef ArenaAllocatorType::size_type	size_type;

	/**
	 * Construct an instance that will allocate blocks of the specified size.
	 *
	 * @param theBlockSize The block size.
	 */
	XPathAllocator(size_type	theBlockCount);

	~XPathAllocator();

	/**
	 * Create an XPath object using the allocator.
	 *
	 * @return a pointer to an XPath
	 */
	object_type*
	create();

	/**
	 * Determine if an object is owned by the allocator...
	 */
	bool
	ownsObject(const object_type*	theObject)
	{
		return m_allocator.ownsObject(theObject);
	}

	/**
	 * Delete all XPath objects allocated.
	 */
	void
	reset();

	/**
	 * Get the number of objects in each block.
	 *
	 * @return The size of the block
	 */
	size_type
	getBlockCount() const
	{
		return m_allocator.getBlockCount();
	}

	/**
	 * Get the number of blocks currently allocated.
	 *
	 * @return The number of blocks.
	 */
	size_type
	getBlockSize() const
	{
		return m_allocator.getBlockSize();
	}

private:

	// Not implemented...
	XPathAllocator(const XPathAllocator&);

	XPathAllocator&
	operator=(const XPathAllocator&);

	// Data members...
	ArenaAllocatorType	m_allocator;
};

#endif	// XNUMBERALLOCATOR_INCLUDE_GUARD_135792455
<commit_msg>Added #ifdef.<commit_after>/*
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 2001 The Apache Software Foundation.  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.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xalan" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 APACHE SOFTWARE FOUNDATION 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.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

#if !defined(XPATHALLOCATOR_INCLUDE_GUARD_135792455)
#define XPATHALLOCATOR_INCLUDE_GUARD_135792455

// Base include file.  Must be first.
#include <XPath/XPathDefinitions.hpp>

#include <PlatformSupport/ArenaAllocator.hpp>

#include <XPath/XPath.hpp>

class XALAN_XPATH_EXPORT XPathAllocator
{
public:

	typedef XPath							object_type;

#if defined(XALAN_NO_DEFAULT_TEMPLATE_ARGUMENTS)
	typedef ArenaBlock<object_type>			ArenaBlockType;

	typedef ArenaAllocator<object_type,
						   ArenaBlockType>	ArenaAllocatorType;
#else
	typedef ArenaAllocator<object_type>		ArenaAllocatorType;
#endif

	typedef ArenaAllocatorType::size_type	size_type;

	/**
	 * Construct an instance that will allocate blocks of the specified size.
	 *
	 * @param theBlockSize The block size.
	 */
	XPathAllocator(size_type	theBlockCount);

	~XPathAllocator();

	/**
	 * Create an XPath object using the allocator.
	 *
	 * @return a pointer to an XPath
	 */
	object_type*
	create();

	/**
	 * Determine if an object is owned by the allocator...
	 */
	bool
	ownsObject(const object_type*	theObject)
	{
		return m_allocator.ownsObject(theObject);
	}

	/**
	 * Delete all XPath objects allocated.
	 */
	void
	reset();

	/**
	 * Get the number of objects in each block.
	 *
	 * @return The size of the block
	 */
	size_type
	getBlockCount() const
	{
		return m_allocator.getBlockCount();
	}

	/**
	 * Get the number of blocks currently allocated.
	 *
	 * @return The number of blocks.
	 */
	size_type
	getBlockSize() const
	{
		return m_allocator.getBlockSize();
	}

private:

	// Not implemented...
	XPathAllocator(const XPathAllocator&);

	XPathAllocator&
	operator=(const XPathAllocator&);

	// Data members...
	ArenaAllocatorType	m_allocator;
};

#endif	// XNUMBERALLOCATOR_INCLUDE_GUARD_135792455
<|endoftext|>


<commit_before>/*
 *  Copyright (c) 2014, Facebook, Inc.
 *  All rights reserved.
 *
 *  This source code is licensed under the BSD-style license found in the
 *  LICENSE file in the root directory of this source tree. An additional grant
 *  of patent rights can be found in the PATENTS file in the same directory.
 *
 */

#include <boost/algorithm/string/join.hpp>
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/path.hpp>

#include <osquery/core.h>
#include <osquery/filesystem.h>
#include <osquery/logger.h>
#include <osquery/tables.h>
#include <osquery/sql.h>

namespace pt = boost::property_tree;

namespace osquery {
namespace tables {

const std::map<std::string, std::string> kAppsInfoPlistTopLevelStringKeys = {
    {"CFBundleExecutable", "bundle_executable"},
    {"CFBundleIdentifier", "bundle_identifier"},
    {"CFBundleName", "bundle_name"},
    {"CFBundleShortVersionString", "bundle_short_version"},
    {"CFBundleVersion", "bundle_version"},
    {"CFBundlePackageType", "bundle_package_type"},
    {"CFBundleDevelopmentRegion", "development_region"},
    {"CFBundleDisplayName", "display_name"},
    {"CFBundleGetInfoString", "info_string"},
    {"DTCompiler", "compiler"},
    {"LSMinimumSystemVersion", "minimum_system_version"},
    {"LSApplicationCategoryType", "category"},
    {"NSAppleScriptEnabled", "applescript_enabled"},
    {"NSHumanReadableCopyright", "copyright"},
};

const std::vector<std::string> kHomeDirSearchPaths = {
    "Applications", "Desktop", "Downloads",
};

std::vector<std::string> getSystemApplications() {
  std::vector<std::string> results;
  std::vector<std::string> sys_apps;
  auto status = osquery::listFilesInDirectory("/Applications", sys_apps);
  if (status.ok()) {
    for (const auto& app_path : sys_apps) {
      std::string plist_path = app_path + "/Contents/Info.plist";
      if (boost::filesystem::exists(plist_path)) {
        results.push_back(plist_path);
      }
    }
  } else {
    VLOG(1) << "Error listing /Applications: " << status.toString();
  }
  return results;
}

std::vector<std::string> getUserApplications(const std::string& home_dir) {
  std::vector<std::string> results;
  for (const auto& dir_to_check : kHomeDirSearchPaths) {
    boost::filesystem::path apps_path = home_dir;
    apps_path /= dir_to_check;

    std::vector<std::string> user_apps;
    auto status = osquery::listFilesInDirectory(apps_path, user_apps);
    if (status.ok()) {
      for (const auto& user_app : user_apps) {
        std::string plist_path = user_app + "/Contents/Info.plist";
        if (boost::filesystem::exists(plist_path)) {
          results.push_back(plist_path);
        }
      }
    } else {
      VLOG(1) << "Error listing " << apps_path << ": " << status.toString();
    }
  }
  return results;
}

std::string getNameFromInfoPlistPath(const std::string& path) {
  boost::filesystem::path full = path;
  return full.parent_path().parent_path().filename().string();
}

std::string getPathFromInfoPlistPath(const std::string& path) {
  boost::filesystem::path full = path;
  return full.parent_path().parent_path().string();
}

Row parseInfoPlist(const std::string& path, const pt::ptree& tree) {
  Row r;

  boost::filesystem::path full = path;
  r["name"] = getNameFromInfoPlistPath(path);
  r["path"] = getPathFromInfoPlistPath(path);
  for (const auto& it : kAppsInfoPlistTopLevelStringKeys) {
    try {
      r[it.second] = tree.get<std::string>(it.first);
    } catch (const pt::ptree_error& e) {
      VLOG(1) << "Error retrieving " << it.first << " from " << path << ": "
              << e.what();
      r[it.second] = "";
    }
  }
  return r;
}

QueryData genApps(QueryContext& context) {
  QueryData results;
  pt::ptree tree;

  // Enumerate and parse applications in / (system applications).
  for (const auto& path : getSystemApplications()) {
    if (osquery::parsePlist(path, tree).ok()) {
      results.push_back(parseInfoPlist(path, tree));
    } else {
      VLOG(1) << "Error parsing system applications: " << path;
    }
  }

  auto users = SQL::selectAllFrom("users");

  // Enumerate apps for each user (several paths).
  for (const auto& user : users) {
    for (const auto& path : getUserApplications(user.at("directory"))) {
      if (osquery::parsePlist(path, tree).ok()) {
        Row r = parseInfoPlist(path, tree);
        results.push_back(r);
      } else {
        VLOG(1) << "Error parsing user applications: " << path;
      }
    }
  }

  return results;
}
}
}
<commit_msg>[Fix #733] Use directories instead of files in apps<commit_after>/*
 *  Copyright (c) 2014, Facebook, Inc.
 *  All rights reserved.
 *
 *  This source code is licensed under the BSD-style license found in the
 *  LICENSE file in the root directory of this source tree. An additional grant
 *  of patent rights can be found in the PATENTS file in the same directory.
 *
 */

#include <boost/algorithm/string/join.hpp>
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/path.hpp>

#include <osquery/core.h>
#include <osquery/filesystem.h>
#include <osquery/logger.h>
#include <osquery/tables.h>
#include <osquery/sql.h>

namespace pt = boost::property_tree;

namespace osquery {
namespace tables {

const std::map<std::string, std::string> kAppsInfoPlistTopLevelStringKeys = {
    {"CFBundleExecutable", "bundle_executable"},
    {"CFBundleIdentifier", "bundle_identifier"},
    {"CFBundleName", "bundle_name"},
    {"CFBundleShortVersionString", "bundle_short_version"},
    {"CFBundleVersion", "bundle_version"},
    {"CFBundlePackageType", "bundle_package_type"},
    {"CFBundleDevelopmentRegion", "development_region"},
    {"CFBundleDisplayName", "display_name"},
    {"CFBundleGetInfoString", "info_string"},
    {"DTCompiler", "compiler"},
    {"LSMinimumSystemVersion", "minimum_system_version"},
    {"LSApplicationCategoryType", "category"},
    {"NSAppleScriptEnabled", "applescript_enabled"},
    {"NSHumanReadableCopyright", "copyright"},
};

const std::vector<std::string> kHomeDirSearchPaths = {
    "Applications", "Desktop", "Downloads",
};

std::vector<std::string> getSystemApplications() {
  std::vector<std::string> results;
  std::vector<std::string> sys_apps;
  auto status = osquery::listDirectoriesInDirectory("/Applications", sys_apps);

  if (status.ok()) {
    for (const auto& app_path : sys_apps) {
      std::string plist_path = app_path + "/Contents/Info.plist";
      if (boost::filesystem::exists(plist_path)) {
        results.push_back(plist_path);
      }
    }
  } else {
    VLOG(1) << "Error listing /Applications: " << status.toString();
  }
  return results;
}

std::vector<std::string> getUserApplications(const std::string& home_dir) {
  std::vector<std::string> results;
  for (const auto& dir_to_check : kHomeDirSearchPaths) {
    boost::filesystem::path apps_path = home_dir;
    apps_path /= dir_to_check;

    std::vector<std::string> user_apps;
    auto status = osquery::listDirectoriesInDirectory(apps_path, user_apps);
    if (status.ok()) {
      for (const auto& user_app : user_apps) {
        std::string plist_path = user_app + "/Contents/Info.plist";
        if (boost::filesystem::exists(plist_path)) {
          results.push_back(plist_path);
        }
      }
    } else {
      VLOG(1) << "Error listing " << apps_path << ": " << status.toString();
    }
  }
  return results;
}

std::string getNameFromInfoPlistPath(const std::string& path) {
  boost::filesystem::path full = path;
  return full.parent_path().parent_path().filename().string();
}

std::string getPathFromInfoPlistPath(const std::string& path) {
  boost::filesystem::path full = path;
  return full.parent_path().parent_path().string();
}

Row parseInfoPlist(const std::string& path, const pt::ptree& tree) {
  Row r;

  boost::filesystem::path full = path;
  r["name"] = getNameFromInfoPlistPath(path);
  r["path"] = getPathFromInfoPlistPath(path);
  for (const auto& it : kAppsInfoPlistTopLevelStringKeys) {
    try {
      r[it.second] = tree.get<std::string>(it.first);
    } catch (const pt::ptree_error& e) {
      VLOG(1) << "Error retrieving " << it.first << " from " << path << ": "
              << e.what();
      r[it.second] = "";
    }
  }
  return r;
}

QueryData genApps(QueryContext& context) {
  QueryData results;
  pt::ptree tree;

  // Enumerate and parse applications in / (system applications).
  for (const auto& path : getSystemApplications()) {
    if (osquery::parsePlist(path, tree).ok()) {
      results.push_back(parseInfoPlist(path, tree));
    } else {
      VLOG(1) << "Error parsing system applications: " << path;
    }
  }

  auto users = SQL::selectAllFrom("users");

  // Enumerate apps for each user (several paths).
  for (const auto& user : users) {
    for (const auto& path : getUserApplications(user.at("directory"))) {
      if (osquery::parsePlist(path, tree).ok()) {
        Row r = parseInfoPlist(path, tree);
        results.push_back(r);
      } else {
        VLOG(1) << "Error parsing user applications: " << path;
      }
    }
  }

  return results;
}
}
}
<|endoftext|>


<commit_before>/**
* Copyright (C) Mellanox Technologies Ltd. 2001-2014.  ALL RIGHTS RESERVED.
* See file LICENSE for terms.
*/

#include "ucp_test.h"

#include <ucs/gtest/test_helpers.h>
extern "C" {
#include <ucs/arch/atomic.h>
}

const ucs::ptr_vector<ucp_test::entity>& ucp_test::entities() const {
    return m_entities;
}

void ucp_test::cleanup() {
    m_entities.clear();
}

ucp_test::entity* ucp_test::create_entity() {
    entity *e = new entity(*this);
    m_entities.push_back(e);
    return e;
}

void ucp_test::get_params(ucp_params_t& params) const {
    params.features        = 0;
    params.request_size    = 0;
    params.request_init    = NULL;
    params.request_cleanup = NULL;
}

void ucp_test::progress() const {
    for (ucs::ptr_vector<entity>::const_iterator iter = entities().begin();
         iter != entities().end(); ++iter)
    {
        (*iter)->progress();
    }
}

void ucp_test::short_progress_loop() const {
    for (unsigned i = 0; i < 100; ++i) {
        progress();
        usleep(100);
    }
}

ucp_test::entity::entity(const ucp_test& test) : m_test(test), m_inprogress(0) {
    ucs::handle<ucp_config_t*> config;

    UCS_TEST_CREATE_HANDLE(ucp_config_t*, config, ucp_config_release,
                           ucp_config_read, NULL, NULL);

    ucp_params_t params;
    test.get_params(params);

    UCS_TEST_CREATE_HANDLE(ucp_context_h, m_ucph, ucp_cleanup, ucp_init,
                           &params, config);

    UCS_TEST_CREATE_HANDLE(ucp_worker_h, m_worker, ucp_worker_destroy,
                           ucp_worker_create, m_ucph, UCS_THREAD_MODE_MULTI);

    ucp_worker_progress_register(m_worker, progress_cb, this);
}

ucp_test::entity::~entity() {
    ucp_worker_progress_unregister(m_worker, progress_cb, this);
}

void ucp_test::entity::connect(const ucp_test::entity* other) {
    ucs_status_t status;
    ucp_address_t *address;
    size_t address_length;

    status = ucp_worker_get_address(other->worker(), &address, &address_length);
    ASSERT_UCS_OK(status);

    ucp_ep_h ep;
    status = ucp_ep_create(m_worker, address, &ep);
    if (status == UCS_ERR_UNREACHABLE) {
        UCS_TEST_SKIP_R("could not find a valid transport");
    }

    ASSERT_UCS_OK(status);
    m_ep.reset(ep, ucp_ep_destroy);

    ucp_worker_release_address(other->worker(), address);
}

void ucp_test::entity::flush() const {
    ucs_status_t status = ucp_worker_flush(worker());
    ASSERT_UCS_OK(status);
}

void ucp_test::entity::disconnect() {
    m_ep.reset();
}

ucp_ep_h ucp_test::entity::ep() const {
    return m_ep;
}

ucp_worker_h ucp_test::entity::worker() const {
    return m_worker;
}

ucp_context_h ucp_test::entity::ucph() const {
    return m_ucph;
}

void ucp_test::entity::progress()
{
    if (ucs_atomic_cswap32(&m_inprogress, 0, 1) != 0) {
        return;
    }

    ucp_worker_progress(m_worker);
    m_inprogress = 0;
}

void ucp_test::entity::progress_cb(void *arg)
{
    entity *e = reinterpret_cast<entity*>(arg);
    e->progress_test();
}

void ucp_test::entity::progress_test()
{
    if (ucs_atomic_cswap32(&m_inprogress, 0, 1) != 0) {
        return;
    }
    m_test.progress();
    m_inprogress = 0;
}
<commit_msg>TEST: Disconnect entities before destroying them, to ensure flush.<commit_after>/**
* Copyright (C) Mellanox Technologies Ltd. 2001-2014.  ALL RIGHTS RESERVED.
* See file LICENSE for terms.
*/

#include "ucp_test.h"

#include <ucs/gtest/test_helpers.h>
extern "C" {
#include <ucs/arch/atomic.h>
}

const ucs::ptr_vector<ucp_test::entity>& ucp_test::entities() const {
    return m_entities;
}

void ucp_test::cleanup() {
    /* disconnect before destroying the entities */
    for (ucs::ptr_vector<entity>::const_iterator iter = entities().begin();
         iter != entities().end(); ++iter)
    {
        (*iter)->disconnect();
    }
    m_entities.clear();
}

ucp_test::entity* ucp_test::create_entity() {
    entity *e = new entity(*this);
    m_entities.push_back(e);
    return e;
}

void ucp_test::get_params(ucp_params_t& params) const {
    params.features        = 0;
    params.request_size    = 0;
    params.request_init    = NULL;
    params.request_cleanup = NULL;
}

void ucp_test::progress() const {
    for (ucs::ptr_vector<entity>::const_iterator iter = entities().begin();
         iter != entities().end(); ++iter)
    {
        (*iter)->progress();
    }
}

void ucp_test::short_progress_loop() const {
    for (unsigned i = 0; i < 100; ++i) {
        progress();
        usleep(100);
    }
}

ucp_test::entity::entity(const ucp_test& test) : m_test(test), m_inprogress(0) {
    ucs::handle<ucp_config_t*> config;

    UCS_TEST_CREATE_HANDLE(ucp_config_t*, config, ucp_config_release,
                           ucp_config_read, NULL, NULL);

    ucp_params_t params;
    test.get_params(params);

    UCS_TEST_CREATE_HANDLE(ucp_context_h, m_ucph, ucp_cleanup, ucp_init,
                           &params, config);

    UCS_TEST_CREATE_HANDLE(ucp_worker_h, m_worker, ucp_worker_destroy,
                           ucp_worker_create, m_ucph, UCS_THREAD_MODE_MULTI);

    ucp_worker_progress_register(m_worker, progress_cb, this);
}

ucp_test::entity::~entity() {
    ucp_worker_progress_unregister(m_worker, progress_cb, this);
}

void ucp_test::entity::connect(const ucp_test::entity* other) {
    ucs_status_t status;
    ucp_address_t *address;
    size_t address_length;

    status = ucp_worker_get_address(other->worker(), &address, &address_length);
    ASSERT_UCS_OK(status);

    ucp_ep_h ep;
    status = ucp_ep_create(m_worker, address, &ep);
    if (status == UCS_ERR_UNREACHABLE) {
        UCS_TEST_SKIP_R("could not find a valid transport");
    }

    ASSERT_UCS_OK(status);
    m_ep.reset(ep, ucp_ep_destroy);

    ucp_worker_release_address(other->worker(), address);
}

void ucp_test::entity::flush() const {
    ucs_status_t status = ucp_worker_flush(worker());
    ASSERT_UCS_OK(status);
}

void ucp_test::entity::disconnect() {
    m_ep.reset();
}

ucp_ep_h ucp_test::entity::ep() const {
    return m_ep;
}

ucp_worker_h ucp_test::entity::worker() const {
    return m_worker;
}

ucp_context_h ucp_test::entity::ucph() const {
    return m_ucph;
}

void ucp_test::entity::progress()
{
    if (ucs_atomic_cswap32(&m_inprogress, 0, 1) != 0) {
        return;
    }

    ucp_worker_progress(m_worker);
    m_inprogress = 0;
}

void ucp_test::entity::progress_cb(void *arg)
{
    entity *e = reinterpret_cast<entity*>(arg);
    e->progress_test();
}

void ucp_test::entity::progress_test()
{
    if (ucs_atomic_cswap32(&m_inprogress, 0, 1) != 0) {
        return;
    }
    m_test.progress();
    m_inprogress = 0;
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: ByteGrabber.cxx,v $
 *
 *  $Revision: 1.8 $
 *
 *  last change: $Author: mtg $ $Date: 2001-05-28 12:52:33 $
 *
 *  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): Martin Gallwey (gallwey@sun.com)
 *
 *
 ************************************************************************/
#ifndef _BYTE_GRABBER_HXX_
#include "ByteGrabber.hxx"
#endif

using namespace ::com::sun::star;

/** ByteGrabber implements the >> operators on an XOutputStream. This is
 *  potentially quite slow and may need to be optimised
 */

ByteGrabber::ByteGrabber(uno::Reference  < io::XInputStream > xIstream)
: xStream(xIstream)
, xSeek (xIstream, uno::UNO_QUERY )
{
}
ByteGrabber::~ByteGrabber()
{
}
void ByteGrabber::setInputStream (uno::Reference < io::XInputStream > xNewStream)
{
    xStream = xNewStream;
    xSeek = uno::Reference < io::XSeekable > (xNewStream, uno::UNO_QUERY);
}

// XInputStream chained
sal_Int32 SAL_CALL ByteGrabber::readBytes( uno::Sequence< sal_Int8 >& aData,
                                        sal_Int32 nBytesToRead )
    throw(io::NotConnectedException, io::BufferSizeExceededException, io::IOException, uno::RuntimeException)
{
    return xStream->readBytes(aData, nBytesToRead );
}
sal_Int32 SAL_CALL ByteGrabber::readSomeBytes( uno::Sequence< sal_Int8 >& aData,
                                                sal_Int32 nMaxBytesToRead )
    throw(io::NotConnectedException, io::BufferSizeExceededException, io::IOException, uno::RuntimeException)
{
    return xStream->readSomeBytes( aData, nMaxBytesToRead );
}
void SAL_CALL ByteGrabber::skipBytes( sal_Int32 nBytesToSkip )
    throw(io::NotConnectedException, io::BufferSizeExceededException, io::IOException, uno::RuntimeException)
{
    xStream->skipBytes( nBytesToSkip );
}
sal_Int32 SAL_CALL ByteGrabber::available(  )
    throw(io::NotConnectedException, io::IOException, uno::RuntimeException)
{
    return xStream->available();
}
void SAL_CALL ByteGrabber::closeInput(  )
    throw(io::NotConnectedException, io::IOException, uno::RuntimeException)
{
    xStream->closeInput();
}

// XSeekable chained...
sal_Int64 SAL_CALL ByteGrabber::seek( sal_Int64 location )
    throw(lang::IllegalArgumentException, io::IOException, uno::RuntimeException)
{
    if (xSeek.is() )
    {
        sal_Int64 nLen = xSeek->getLength();
        if (location > nLen )
            location = nLen;
        xSeek->seek( location );
        return location;
    }
    else
        throw io::IOException();
}
sal_Int64 SAL_CALL ByteGrabber::getPosition(  )
        throw(io::IOException, uno::RuntimeException)
{
    if (xSeek.is() )
        return xSeek->getPosition();
    else
        throw io::IOException();
}
sal_Int64 SAL_CALL ByteGrabber::getLength(  )
        throw(io::IOException, uno::RuntimeException)
{
    if (xSeek.is() )
        return xSeek->getLength();
    else
        throw io::IOException();
}
ByteGrabber& ByteGrabber::operator >> (sal_Int8& rInt8)
{
    uno::Sequence< sal_Int8 > aSequence (1);

    if (xStream->readBytes(aSequence,1) != 1)
    {
        rInt8 = 0;
        return *this;
    }
    const sal_Int8 *pArray = aSequence.getArray();
    rInt8 = *(pArray) & 0xFF;
    return *this;
}
ByteGrabber& ByteGrabber::operator >> (sal_Int16& rInt16)
{
    uno::Sequence< sal_Int8 > aSequence (2);

    if (xStream->readBytes(aSequence, 2) != 2)
    {
        rInt16 = 0;
        return *this;
    }
    const sal_Int8 *pArray = aSequence.getArray();
    rInt16 = static_cast <sal_Int16>
            ((* pArray   & 0xFF)
           | (*(pArray+1)& 0xFF) << 8);
    return *this;
}
ByteGrabber& ByteGrabber::operator >> (sal_Int32& rInt32)
{
    uno::Sequence< sal_Int8 > aSequence (4);

    if (xStream->readBytes(aSequence, 4) != 4)
    {
        rInt32 = 0;
        return *this;
    }
    const sal_Int8 *pArray = aSequence.getArray();
    rInt32 = static_cast < sal_Int32 >
            ((* (pArray  ) & 0xFF)
           | (* (pArray+1) & 0xFF) << 8
           | (* (pArray+2) & 0xFF) << 16
           | (* (pArray+3) & 0xFF) << 24 );
    return *this;
}

ByteGrabber& ByteGrabber::operator >> (sal_uInt8& ruInt8)
{
    uno::Sequence< sal_Int8 > aSequence (1);

    if (xStream->readBytes(aSequence,1) != 1)
    {
        ruInt8 = 0;
        return *this;
    }
    const sal_Int8 *pArray = aSequence.getArray();
    ruInt8 = static_cast <sal_uInt8> (* (pArray  ) & 0xFF);
    return *this;
}
ByteGrabber& ByteGrabber::operator >> (sal_uInt16& ruInt16)
{
    uno::Sequence< sal_Int8 > aSequence (2);

    if (xStream->readBytes(aSequence, 2) != 2)
    {
        ruInt16 = 0;
        return *this;
    }
    const sal_Int8 *pArray = aSequence.getArray();
    ruInt16 = static_cast <sal_uInt16>
             ((* pArray   & 0xFF)
            | (*(pArray+1)& 0xFF) << 8);
    return *this;
}
ByteGrabber& ByteGrabber::operator >> (sal_uInt32& ruInt32)
{
    uno::Sequence< sal_Int8 > aSequence (4);

    if (xStream->readBytes(aSequence, 4) != 4)
    {
        ruInt32 = 0;
        return *this;
    }
    const sal_Int8 *pArray = aSequence.getArray();
    ruInt32 = static_cast < sal_uInt32 >
            ((* (pArray  ) & 0xFF)
           | (* (pArray+1) & 0xFF) << 8
           | (* (pArray+2) & 0xFF) << 16
           | (* (pArray+3) & 0xFF) << 24 );
    return *this;
}
<commit_msg>#87099# OPtimise the stream operators<commit_after>/*************************************************************************
 *
 *  $RCSfile: ByteGrabber.cxx,v $
 *
 *  $Revision: 1.9 $
 *
 *  last change: $Author: mtg $ $Date: 2001-05-31 09:46:36 $
 *
 *  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): Martin Gallwey (gallwey@sun.com)
 *
 *
 ************************************************************************/
#ifndef _BYTE_GRABBER_HXX_
#include "ByteGrabber.hxx"
#endif

using namespace ::com::sun::star;

/** ByteGrabber implements the >> operators on an XOutputStream. This is
 *  potentially quite slow and may need to be optimised
 */

ByteGrabber::ByteGrabber(uno::Reference  < io::XInputStream > xIstream)
: xStream(xIstream)
, xSeek (xIstream, uno::UNO_QUERY )
, aSequence ( 4 )
{
    pSequence = aSequence.getArray();
}

ByteGrabber::~ByteGrabber()
{
}
void ByteGrabber::setInputStream (uno::Reference < io::XInputStream > xNewStream)
{
    xStream = xNewStream;
    xSeek = uno::Reference < io::XSeekable > (xNewStream, uno::UNO_QUERY);
}

// XInputStream chained
sal_Int32 SAL_CALL ByteGrabber::readBytes( uno::Sequence< sal_Int8 >& aData,
                                        sal_Int32 nBytesToRead )
    throw(io::NotConnectedException, io::BufferSizeExceededException, io::IOException, uno::RuntimeException)
{
    return xStream->readBytes(aData, nBytesToRead );
}
sal_Int32 SAL_CALL ByteGrabber::readSomeBytes( uno::Sequence< sal_Int8 >& aData,
                                                sal_Int32 nMaxBytesToRead )
    throw(io::NotConnectedException, io::BufferSizeExceededException, io::IOException, uno::RuntimeException)
{
    return xStream->readSomeBytes( aData, nMaxBytesToRead );
}
void SAL_CALL ByteGrabber::skipBytes( sal_Int32 nBytesToSkip )
    throw(io::NotConnectedException, io::BufferSizeExceededException, io::IOException, uno::RuntimeException)
{
    xStream->skipBytes( nBytesToSkip );
}
sal_Int32 SAL_CALL ByteGrabber::available(  )
    throw(io::NotConnectedException, io::IOException, uno::RuntimeException)
{
    return xStream->available();
}
void SAL_CALL ByteGrabber::closeInput(  )
    throw(io::NotConnectedException, io::IOException, uno::RuntimeException)
{
    xStream->closeInput();
}

// XSeekable chained...
sal_Int64 SAL_CALL ByteGrabber::seek( sal_Int64 location )
    throw(lang::IllegalArgumentException, io::IOException, uno::RuntimeException)
{
    if (xSeek.is() )
    {
        sal_Int64 nLen = xSeek->getLength();
        if (location > nLen )
            location = nLen;
        xSeek->seek( location );
        return location;
    }
    else
        throw io::IOException();
}
sal_Int64 SAL_CALL ByteGrabber::getPosition(  )
        throw(io::IOException, uno::RuntimeException)
{
    if (xSeek.is() )
        return xSeek->getPosition();
    else
        throw io::IOException();
}
sal_Int64 SAL_CALL ByteGrabber::getLength(  )
        throw(io::IOException, uno::RuntimeException)
{
    if (xSeek.is() )
        return xSeek->getLength();
    else
        throw io::IOException();
}
ByteGrabber& ByteGrabber::operator >> (sal_Int8& rInt8)
{
    if (xStream->readBytes(aSequence,1) != 1)
        rInt8 = 0;
    else
        rInt8 = pSequence[0] & 0xFF;
    return *this;
}
ByteGrabber& ByteGrabber::operator >> (sal_Int16& rInt16)
{
    if (xStream->readBytes ( aSequence, 2) != 2)
        rInt16 = 0;
    else
        rInt16 = static_cast <sal_Int16>
               ( pSequence[0] & 0xFF
              | (pSequence[1] & 0xFF) << 8);
    return *this;
}
ByteGrabber& ByteGrabber::operator >> (sal_Int32& rInt32)
{
    if (xStream->readBytes(aSequence, 4) != 4)
        rInt32 = 0;
    else
        rInt32 = static_cast < sal_Int32 >
                ( pSequence[0] & 0xFF
              | ( pSequence[1] & 0xFF ) << 8
              | ( pSequence[2] & 0xFF ) << 16
              | ( pSequence[3] & 0xFF ) << 24 );
    return *this;
}

ByteGrabber& ByteGrabber::operator >> (sal_uInt8& rInt8)
{
    if (xStream->readBytes(aSequence,1) != 1)
        rInt8 = 0;
    else
        rInt8 = static_cast < sal_uInt8 > (pSequence[0] & 0xFF );
    return *this;
}
ByteGrabber& ByteGrabber::operator >> (sal_uInt16& rInt16)
{
    if (xStream->readBytes(aSequence, 2) != 2)
        rInt16 = 0;
    else
        rInt16 = static_cast <sal_uInt16>
               ( pSequence[0] & 0xFF
              | (pSequence[1] & 0xFF) << 8);
    return *this;
}
ByteGrabber& ByteGrabber::operator >> (sal_uInt32& ruInt32)
{
    if (xStream->readBytes(aSequence, 4) != 4)
        ruInt32 = 0;
    else
        ruInt32 = static_cast < sal_uInt32 >
                ( pSequence[0] & 0xFF
              | ( pSequence[1] & 0xFF ) << 8
              | ( pSequence[2] & 0xFF ) << 16
              | ( pSequence[3] & 0xFF ) << 24 );
    return *this;
}
<|endoftext|>


<commit_before>#include <iostream>
#include <algorithm>
#include <iterator>
#include <ctime>
#include <typeinfo>
#include <cstdlib>
#include <fstream>

//#include <boost/random.hpp>
//#include <boost/generator_iterator.hpp>
//#include <boost/date_time/gregorian/gregorian.hpp>
//#include <boost/date_time/posix_time/posix_time.hpp>
//#include <boost/algorithm/string.hpp>

#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/serialization/vector.hpp>
#include <boost/serialization/list.hpp>

#include "mongoose.h"
#include "json.hpp"

#include "topology/persistence.h"
#include "geometry/covertree.h"
#include "topology/sparse_rips_filtration.h"
#include "topology/rips_filtration.h"

using json = nlohmann::json;

static const char *s_http_port = "8800";
static struct mg_serve_http_opts s_http_server_opts;

void read_points_from_json(json& data, Points& points)
{
    for(auto it = data.begin(); it != data.end(); it ++) {
        json t = *it;
        vector<double> p;
        p.push_back(t["px"]);
        p.push_back(t["py"]);
        points.push_back(Vector(p));
    }
}

json persistence_homology_split(json data)
{
	Points points;
	read_points_from_json(data, points);

	int max_d = 2;

    //Filtration* full_filtration = new RipsFiltration(points, max_d);
    //PersistentHomology sparse_rips_homology(full_filtration);
    Filtration* sparse_filtration = new SparseRipsFiltration(points, max_d, 1.0/3);
    PersistentHomology ph(sparse_filtration);

    std::vector<PHCycle> reduction;
    Filtration* filtration;
    int loaded_max_d;
    // TODO load these from saved data

    ph.compute_matrix(reduction);

    // serialize vector
    {
        std::ofstream ofs("reduction.dat");
        boost::archive::text_oarchive oa(ofs);
        oa & reduction;
    }

    std::vector<PHCycle> new_reduction;

    // load serialized vector
    {
        std::ifstream ifs("reduction.dat");
        boost::archive::text_iarchive ia(ifs);
        ia & new_reduction;
    }

	PersistenceDiagram *sparse_rips_pd = ph.compute_persistence(new_reduction, filtration, loaded_max_d);

	sparse_rips_pd->sort_pairs_by_persistence();

    std::stringstream result;
	for(unsigned i = 0; i < sparse_rips_pd->num_pairs(); i++)  {
		PersistentPair pairing = sparse_rips_pd->get_pair(i);
		//printf("%u %.7f %.7f\n", pairing.dim(), pairing.birth_time(), pairing.death_time());
        result << pairing.dim() << " "
            << pairing.birth_time() << " "
            << pairing.death_time() << "\n";
	}

    delete sparse_rips_pd;
    return result.str();
}

static void handle_query_call(struct mg_connection *c, struct http_message *hm) {

  json q = json::parse(string(hm->body.p, hm->body.len));
  json result = persistence_homology_split(q);

  /* Send result */
  std::string msg_content = result.dump();
  const std::string sep = "\r\n";

  std::stringstream ss;
  ss << "HTTP/1.1 200 OK"             << sep
    << "Content-Type: application/json" << sep
    << "Access-Control-Allow-Origin: *" << sep
    << "Content-Length: %d"             << sep << sep
    << "%s";

  mg_printf(c, ss.str().c_str(), (int) msg_content.size(), msg_content.c_str());
}

static void ev_handler(struct mg_connection *c, int ev, void *ev_data) {
  struct http_message *hm = (struct http_message *) ev_data;

  switch (ev) {
    case MG_EV_HTTP_REQUEST:
      if (mg_vcmp(&hm->uri, "/query") == 0) {
        handle_query_call(c, hm); /* Handle RESTful call */
      }
      else {
        mg_serve_http(c, hm, s_http_server_opts); /* Serve static content */
      }
      break;
    default:
      break;
  }
}

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

  struct mg_mgr mgr;
  struct mg_connection *c;

  mg_mgr_init(&mgr, NULL);
  c = mg_bind(&mgr, s_http_port, ev_handler);
  mg_set_protocol_http_websocket(c);

  s_http_server_opts.document_root = "../../webui";
  s_http_server_opts.enable_directory_listing = "yes";

  printf("Starting server on port %s\n", s_http_port);

  for (;;) {
    mg_mgr_poll(&mgr, 1000);
  }

  mg_mgr_free(&mgr);

  return 0;
}
<commit_msg>use full rips filtration<commit_after>#include <iostream>
#include <algorithm>
#include <iterator>
#include <ctime>
#include <typeinfo>
#include <cstdlib>
#include <fstream>

//#include <boost/random.hpp>
//#include <boost/generator_iterator.hpp>
//#include <boost/date_time/gregorian/gregorian.hpp>
//#include <boost/date_time/posix_time/posix_time.hpp>
//#include <boost/algorithm/string.hpp>

#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/serialization/vector.hpp>
#include <boost/serialization/list.hpp>

#include "mongoose.h"
#include "json.hpp"

#include "topology/persistence.h"
#include "geometry/covertree.h"
#include "topology/sparse_rips_filtration.h"
#include "topology/rips_filtration.h"

using json = nlohmann::json;

static const char *s_http_port = "8800";
static struct mg_serve_http_opts s_http_server_opts;

void read_points_from_json(json& data, Points& points)
{
    for(auto it = data.begin(); it != data.end(); it ++) {
        json t = *it;
        vector<double> p;
        p.push_back(t["px"]);
        p.push_back(t["py"]);
        points.push_back(Vector(p));
    }
}

json persistence_homology_split(json data)
{
	Points points;
	read_points_from_json(data, points);

	int max_d = 2;

    Filtration* full_filtration = new RipsFiltration(points, max_d);
    PersistentHomology ph(full_filtration);
    //Filtration* sparse_filtration = new SparseRipsFiltration(points, max_d, 1.0/3);
    //PersistentHomology ph(sparse_filtration);

    std::vector<PHCycle> reduction;
    Filtration* filtration;
    int loaded_max_d;
    // TODO load these from saved data

    ph.compute_matrix(reduction);

    // serialize vector
    {
        std::ofstream ofs("reduction.dat");
        boost::archive::text_oarchive oa(ofs);
        oa & reduction;
    }

    std::vector<PHCycle> new_reduction;

    // load serialized vector
    {
        std::ifstream ifs("reduction.dat");
        boost::archive::text_iarchive ia(ifs);
        ia & new_reduction;
    }

	PersistenceDiagram *sparse_rips_pd = ph.compute_persistence(new_reduction, filtration, loaded_max_d);

	sparse_rips_pd->sort_pairs_by_persistence();

    std::stringstream result;
	for(unsigned i = 0; i < sparse_rips_pd->num_pairs(); i++)  {
		PersistentPair pairing = sparse_rips_pd->get_pair(i);
		//printf("%u %.7f %.7f\n", pairing.dim(), pairing.birth_time(), pairing.death_time());
        result << pairing.dim() << " "
            << pairing.birth_time() << " "
            << pairing.death_time() << "\n";
	}

    delete sparse_rips_pd;
    return result.str();
}

static void handle_query_call(struct mg_connection *c, struct http_message *hm) {

  json q = json::parse(string(hm->body.p, hm->body.len));
  json result = persistence_homology_split(q);

  /* Send result */
  std::string msg_content = result.dump();
  const std::string sep = "\r\n";

  std::stringstream ss;
  ss << "HTTP/1.1 200 OK"             << sep
    << "Content-Type: application/json" << sep
    << "Access-Control-Allow-Origin: *" << sep
    << "Content-Length: %d"             << sep << sep
    << "%s";

  mg_printf(c, ss.str().c_str(), (int) msg_content.size(), msg_content.c_str());
}

static void ev_handler(struct mg_connection *c, int ev, void *ev_data) {
  struct http_message *hm = (struct http_message *) ev_data;

  switch (ev) {
    case MG_EV_HTTP_REQUEST:
      if (mg_vcmp(&hm->uri, "/query") == 0) {
        handle_query_call(c, hm); /* Handle RESTful call */
      }
      else {
        mg_serve_http(c, hm, s_http_server_opts); /* Serve static content */
      }
      break;
    default:
      break;
  }
}

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

  struct mg_mgr mgr;
  struct mg_connection *c;

  mg_mgr_init(&mgr, NULL);
  c = mg_bind(&mgr, s_http_port, ev_handler);
  mg_set_protocol_http_websocket(c);

  s_http_server_opts.document_root = "../../webui";
  s_http_server_opts.enable_directory_listing = "yes";

  printf("Starting server on port %s\n", s_http_port);

  for (;;) {
    mg_mgr_poll(&mgr, 1000);
  }

  mg_mgr_free(&mgr);

  return 0;
}
<|endoftext|>


<commit_before>// Copyright 2014 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 "config.h"
#include "bindings/core/v8/V8DOMActivityLogger.h"

#include "bindings/core/v8/V8Binding.h"
#include "platform/weborigin/KURL.h"
#include "wtf/HashMap.h"
#include "wtf/MainThread.h"
#include "wtf/text/StringHash.h"

namespace blink {

typedef HashMap<String, OwnPtr<V8DOMActivityLogger> > DOMActivityLoggerMapForMainWorld;
typedef HashMap<int, OwnPtr<V8DOMActivityLogger>, WTF::IntHash<int>, WTF::UnsignedWithZeroKeyHashTraits<int> > DOMActivityLoggerMapForIsolatedWorld;

static DOMActivityLoggerMapForMainWorld& domActivityLoggersForMainWorld()
{
    ASSERT(isMainThread());
    DEFINE_STATIC_LOCAL(DOMActivityLoggerMapForMainWorld, map, ());
    return map;
}

static DOMActivityLoggerMapForIsolatedWorld& domActivityLoggersForIsolatedWorld()
{
    ASSERT(isMainThread());
    DEFINE_STATIC_LOCAL(DOMActivityLoggerMapForIsolatedWorld, map, ());
    return map;
}

void V8DOMActivityLogger::setActivityLogger(int worldId, const String& extensionId, PassOwnPtr<V8DOMActivityLogger> logger)
{
    if (worldId)
        domActivityLoggersForIsolatedWorld().set(worldId, logger);
    else
        domActivityLoggersForMainWorld().set(extensionId, logger);
}

V8DOMActivityLogger* V8DOMActivityLogger::activityLogger(int worldId, const String& extensionId)
{
    if (worldId) {
        DOMActivityLoggerMapForIsolatedWorld& loggers = domActivityLoggersForIsolatedWorld();
        DOMActivityLoggerMapForIsolatedWorld::iterator it = loggers.find(worldId);
        return it == loggers.end() ? 0 : it->value.get();
    }

    if (extensionId.isEmpty())
        return 0;

    DOMActivityLoggerMapForMainWorld& loggers = domActivityLoggersForMainWorld();
    DOMActivityLoggerMapForMainWorld::iterator it = loggers.find(extensionId);
    return it == loggers.end() ? 0 : it->value.get();
}

V8DOMActivityLogger* V8DOMActivityLogger::activityLogger(int worldId, const KURL& url)
{
    // extension ID is ignored for worldId != 0.
    if (worldId)
        return activityLogger(worldId, String());

    // To find an activity logger that corresponds to the main world of an
    // extension, we need to obtain the extension ID. Extension ID is a hostname
    // of a background page's URL.
    if (!url.protocolIs("chrome-extension"))
        return 0;

    return activityLogger(worldId, url.host());
}

V8DOMActivityLogger* V8DOMActivityLogger::currentActivityLogger()
{
    v8::Isolate* isolate = v8::Isolate::GetCurrent();
    if (!isolate->InContext())
        return 0;

    v8::Handle<v8::Context> context = isolate->GetCurrentContext();
    if (context.IsEmpty() || !toDOMWindow(context))
        return 0;

    V8PerContextData* contextData = ScriptState::from(context)->perContextData();
    if (!contextData)
        return 0;

    return contextData->activityLogger();
}

V8DOMActivityLogger* V8DOMActivityLogger::currentActivityLoggerIfIsolatedWorld()
{
    v8::Isolate* isolate = v8::Isolate::GetCurrent();
    if (!isolate->InContext())
        return 0;

    v8::Handle<v8::Context> context = isolate->GetCurrentContext();
    if (context.IsEmpty() || !toDOMWindow(context))
        return 0;

    ScriptState* scriptState = ScriptState::from(context);
    if (!scriptState->world().isIsolatedWorld())
        return 0;

    V8PerContextData* contextData = scriptState->perContextData();
    if (!contextData)
        return 0;

    return contextData->activityLogger();
}

} // namespace blink
<commit_msg>Add HandleScopes to V8DOMActivityLogger's methods<commit_after>// Copyright 2014 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 "config.h"
#include "bindings/core/v8/V8DOMActivityLogger.h"

#include "bindings/core/v8/V8Binding.h"
#include "platform/weborigin/KURL.h"
#include "wtf/HashMap.h"
#include "wtf/MainThread.h"
#include "wtf/text/StringHash.h"

namespace blink {

typedef HashMap<String, OwnPtr<V8DOMActivityLogger> > DOMActivityLoggerMapForMainWorld;
typedef HashMap<int, OwnPtr<V8DOMActivityLogger>, WTF::IntHash<int>, WTF::UnsignedWithZeroKeyHashTraits<int> > DOMActivityLoggerMapForIsolatedWorld;

static DOMActivityLoggerMapForMainWorld& domActivityLoggersForMainWorld()
{
    ASSERT(isMainThread());
    DEFINE_STATIC_LOCAL(DOMActivityLoggerMapForMainWorld, map, ());
    return map;
}

static DOMActivityLoggerMapForIsolatedWorld& domActivityLoggersForIsolatedWorld()
{
    ASSERT(isMainThread());
    DEFINE_STATIC_LOCAL(DOMActivityLoggerMapForIsolatedWorld, map, ());
    return map;
}

void V8DOMActivityLogger::setActivityLogger(int worldId, const String& extensionId, PassOwnPtr<V8DOMActivityLogger> logger)
{
    if (worldId)
        domActivityLoggersForIsolatedWorld().set(worldId, logger);
    else
        domActivityLoggersForMainWorld().set(extensionId, logger);
}

V8DOMActivityLogger* V8DOMActivityLogger::activityLogger(int worldId, const String& extensionId)
{
    if (worldId) {
        DOMActivityLoggerMapForIsolatedWorld& loggers = domActivityLoggersForIsolatedWorld();
        DOMActivityLoggerMapForIsolatedWorld::iterator it = loggers.find(worldId);
        return it == loggers.end() ? 0 : it->value.get();
    }

    if (extensionId.isEmpty())
        return 0;

    DOMActivityLoggerMapForMainWorld& loggers = domActivityLoggersForMainWorld();
    DOMActivityLoggerMapForMainWorld::iterator it = loggers.find(extensionId);
    return it == loggers.end() ? 0 : it->value.get();
}

V8DOMActivityLogger* V8DOMActivityLogger::activityLogger(int worldId, const KURL& url)
{
    // extension ID is ignored for worldId != 0.
    if (worldId)
        return activityLogger(worldId, String());

    // To find an activity logger that corresponds to the main world of an
    // extension, we need to obtain the extension ID. Extension ID is a hostname
    // of a background page's URL.
    if (!url.protocolIs("chrome-extension"))
        return 0;

    return activityLogger(worldId, url.host());
}

V8DOMActivityLogger* V8DOMActivityLogger::currentActivityLogger()
{
    v8::Isolate* isolate = v8::Isolate::GetCurrent();
    if (!isolate->InContext())
        return 0;

    v8::HandleScope handleScope(isolate);
    v8::Handle<v8::Context> context = isolate->GetCurrentContext();
    if (context.IsEmpty() || !toDOMWindow(context))
        return 0;

    V8PerContextData* contextData = ScriptState::from(context)->perContextData();
    if (!contextData)
        return 0;

    return contextData->activityLogger();
}

V8DOMActivityLogger* V8DOMActivityLogger::currentActivityLoggerIfIsolatedWorld()
{
    v8::Isolate* isolate = v8::Isolate::GetCurrent();
    if (!isolate->InContext())
        return 0;

    v8::HandleScope handleScope(isolate);
    v8::Handle<v8::Context> context = isolate->GetCurrentContext();
    if (context.IsEmpty() || !toDOMWindow(context))
        return 0;

    ScriptState* scriptState = ScriptState::from(context);
    if (!scriptState->world().isIsolatedWorld())
        return 0;

    V8PerContextData* contextData = scriptState->perContextData();
    if (!contextData)
        return 0;

    return contextData->activityLogger();
}

} // namespace blink
<|endoftext|>