<commit_before>// File_Pcm - Info for PCM files
// Copyright (C) 2007-2008 Jerome Martinez, Zen@MediaArea.net
//
// This library is free software: you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU 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, see <http://www.gnu.org/licenses/>.
//
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

//---------------------------------------------------------------------------
// Compilation conditions
#include <MediaInfo/Setup.h>
#ifdef __BORLANDC__
    #pragma hdrstop
#endif
//---------------------------------------------------------------------------

//---------------------------------------------------------------------------
#if defined(MEDIAINFO_PCM_YES)
//---------------------------------------------------------------------------

//---------------------------------------------------------------------------
#include "MediaInfo/Audio/File_Pcm.h"
//---------------------------------------------------------------------------

namespace MediaInfoLib
{

//***************************************************************************
// Format
//***************************************************************************

//---------------------------------------------------------------------------
void File_Pcm::Read_Buffer_Continue()
{
    //It is impossible to detect... Default is no detection, only filling

    //Filling
    Stream_Prepare(Stream_General);
    Fill(Stream_General, 0, General_Format, "PCM");
    Stream_Prepare(Stream_Audio);
    Fill(Stream_Audio, 0, Audio_Format, "PCM");
    Fill(Stream_Audio, 0, Audio_Codec, "PCM");

    Finnished();
}

//---------------------------------------------------------------------------
void File_Pcm::Read_Buffer_Finalize()
{
    //Filling
    Ztring Firm, Endianness, Sign, ITU, Resolution;
    if (0)
        ;
    else if (Codec==_T("EVOB"))             {Firm=_T("");       Endianness=_T("Big");    Sign=_T("Signed");   Resolution=_T("");} //PCM Signed 16 bits Big Endian, Interleavement is for 2 samples*2 channels L0-1/L0-0/R0-1/R0-0/L1-1/L1-0/R1-1/R1-0/L0-2/R0-2/L1-2/R1-2, http://wiki.multimedia.cx/index.php?title=PCM
    else if (Codec==_T("VOB"))              {Firm=_T("");       Endianness=_T("Big");    Sign=_T("Signed");   Resolution=_T("24");} //PCM Signed 16 bits Big Endian, Interleavement is for 2 samples*2 channels L0-1/L0-0/R0-1/R0-0/L1-1/L1-0/R1-1/R1-0/L0-2/R0-2/L1-2/R1-2, http://wiki.multimedia.cx/index.php?title=PCM
    else if (Codec==_T("A_PCM/INT/BIG"))    {Firm=_T("");       Endianness=_T("Big");}
    else if (Codec==_T("A_PCM/INT/LITTLE")) {Firm=_T("");       Endianness=_T("Little");}
    else if (Codec==_T("A_PCM/INT/FLOAT"))  {Firm=_T("");       Endianness=_T("Float");}
    else if (Codec==_T("fl32"))             {                   Endianness=_T("Float");                       Resolution=_T("32");}
    else if (Codec==_T("fl64"))             {                   Endianness=_T("Float");                       Resolution=_T("64");}
    else if (Codec==_T("in24"))             {                   Endianness=_T("Big");    Sign=_T("Unsigned"); Resolution=_T("24");}
    else if (Codec==_T("in32"))             {                   Endianness=_T("Big");    Sign=_T("Unsigned"); Resolution=_T("32");}
    else if (Codec==_T("raw "))             {                   Endianness=_T("Little"); Sign=_T("Unsigned");}
    else if (Codec==_T("twos"))             {                   Endianness=_T("Big");    Sign=_T("Signed");}
    else if (Codec==_T("sowt"))             {                   Endianness=_T("Little"); Sign=_T("Signed");}
    else if (Codec==_T("SWF ADPCM"))        {Firm=_T("SWF");}
    else if (Codec==_T("1"))                {                   Endianness=_T("Little"); Sign=_T("Unsigned");}
    else if (Codec==_T("2"))                {Firm=_T("Microsoft");}
    else if (Codec==_T("3"))                {                   Endianness=_T("Float");}
    else if (Codec==_T("10"))               {Firm=_T("OKI");}
    else if (Codec==_T("11"))               {Firm=_T("Intel");}
    else if (Codec==_T("12"))               {Firm=_T("Mediaspace");}
    else if (Codec==_T("13"))               {Firm=_T("Sierra");}
    else if (Codec==_T("14"))               {Firm=_T("Antex");}
    else if (Codec==_T("17"))               {Firm=_T("Dialogic");}
    else if (Codec==_T("18"))               {Firm=_T("Mediavision");}
    else if (Codec==_T("20"))               {Firm=_T("Yamaha");}
    else if (Codec==_T("33"))               {Firm=_T("Antex");}
    else if (Codec==_T("36"))               {Firm=_T("DSP Solution");}
    else if (Codec==_T("38"))               {Firm=_T("Natural MicroSystems");}
    else if (Codec==_T("39"))               {Firm=_T("Crystal Semiconductor");}
    else if (Codec==_T("3B"))               {Firm=_T("Rockwell");}
    else if (Codec==_T("40"))               {Firm=_T("Antex Electronics");}
    else if (Codec==_T("42"))               {Firm=_T("IBM");}
    else if (Codec==_T("45"))               {Firm=_T("Microsoft"); ITU=_T("G.726");}
    else if (Codec==_T("64"))               {Firm=_T("Apicom"); ITU=_T("G.726");}
    else if (Codec==_T("65"))               {Firm=_T("Apicom"); ITU=_T("G.722");}
    else if (Codec==_T("85"))               {Firm=_T("DataFusion Systems"); ITU=_T("G.726");}
    else if (Codec==_T("8B"))               {Firm=_T("Infocom"); ITU=_T("G.721");}
    else if (Codec==_T("97"))               {Firm=_T("ZyXEL");}
    else if (Codec==_T("100"))              {Firm=_T("Rhetorex");}
    else if (Codec==_T("125"))              {Firm=_T("Sanyo");}
    else if (Codec==_T("140"))              {Firm=_T("Dictaphone"); ITU=_T("G.726");}
    else if (Codec==_T("170"))              {Firm=_T("Unisys");}
    else if (Codec==_T("175"))              {Firm=_T("SyCom"); ITU=_T("G.726");}
    else if (Codec==_T("178"))              {Firm=_T("Knownledge");}
    else if (Codec==_T("200"))              {Firm=_T("Creative");}
    else if (Codec==_T("210"))              {Firm=_T("Uher");}
    else if (Codec==_T("285"))              {Firm=_T("Norcom Voice Systems");}
    else if (Codec==_T("1001"))             {Firm=_T("Olivetti");}
    else if (Codec==_T("1C03"))             {Firm=_T("Lucent"); ITU=_T("G.723");}
    else if (Codec==_T("1C0C"))             {Firm=_T("Lucent"); ITU=_T("G.723");}
    else if (Codec==_T("4243"))             {ITU=_T("G.726");}
    else if (Codec==_T("A105"))             {ITU=_T("G.726");}
    else if (Codec==_T("A107"))             {ITU=_T("G.726");}

    Fill(Stream_Audio, 0, Audio_Codec_String, "PCM");
    Fill(Stream_Audio, 0, Audio_Codec_Family, "PCM");
    if (!Firm.empty())
    {
        Fill(Stream_Audio, 0, Audio_Format_Settings, Firm);
        Fill(Stream_Audio, 0, Audio_Format_Settings_Firm, Firm);
        Fill(Stream_Audio, 0, Audio_Codec_Settings, Firm);
        Fill(Stream_Audio, 0, Audio_Codec_Settings_Firm, Firm);
    }
    if (!Endianness.empty())
    {
        Fill(Stream_Audio, 0, Audio_Format_Settings, Endianness);
        Fill(Stream_Audio, 0, Audio_Format_Settings_Endianness, Endianness);
        Fill(Stream_Audio, 0, Audio_Codec_Settings, Endianness);
        Fill(Stream_Audio, 0, Audio_Codec_Settings_Endianness, Endianness);
    }
    if (!Sign.empty())
    {
        Fill(Stream_Audio, 0, Audio_Format_Settings, Sign);
        Fill(Stream_Audio, 0, Audio_Format_Settings_Sign, Sign);
        Fill(Stream_Audio, 0, Audio_Codec_Settings, Sign);
        Fill(Stream_Audio, 0, Audio_Codec_Settings_Sign, Sign);
    }
    if (!ITU.empty())
    {
        Fill(Stream_Audio, 0, Audio_Format_Settings, ITU);
        Fill(Stream_Audio, 0, Audio_Format_Settings_ITU, ITU);
        Fill(Stream_Audio, 0, Audio_Codec_Settings, ITU);
        Fill(Stream_Audio, 0, Audio_Codec_Settings_ITU, ITU);
    }
    Fill(Stream_Audio, 0, Audio_Resolution, Resolution);
    Fill(Stream_Audio, 0, Audio_BitRate_Mode, "CBR");
}

//***************************************************************************
// Information
//***************************************************************************

//---------------------------------------------------------------------------
void File_Pcm::HowTo(stream_t StreamKind)
{
    switch (StreamKind)
    {
        case (Stream_General) :
            break;
        case (Stream_Video) :
            break;
        case (Stream_Audio) :
            break;
        case (Stream_Text) :
            break;
        case (Stream_Chapters) :
            break;
        case (Stream_Image) :
            break;
        case (Stream_Menu) :
            break;
        case (Stream_Max) :
            break;
    }
}

//***************************************************************************
// C++
//***************************************************************************

} //NameSpace

#endif //MEDIAINFO_PCM_YES
<commit_msg>PCM from VOB can have multiple resolutions!<commit_after>// File_Pcm - Info for PCM files
// Copyright (C) 2007-2008 Jerome Martinez, Zen@MediaArea.net
//
// This library is free software: you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU 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, see <http://www.gnu.org/licenses/>.
//
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

//---------------------------------------------------------------------------
// Compilation conditions
#include <MediaInfo/Setup.h>
#ifdef __BORLANDC__
    #pragma hdrstop
#endif
//---------------------------------------------------------------------------

//---------------------------------------------------------------------------
#if defined(MEDIAINFO_PCM_YES)
//---------------------------------------------------------------------------

//---------------------------------------------------------------------------
#include "MediaInfo/Audio/File_Pcm.h"
//---------------------------------------------------------------------------

namespace MediaInfoLib
{

//***************************************************************************
// Format
//***************************************************************************

//---------------------------------------------------------------------------
void File_Pcm::Read_Buffer_Continue()
{
    //It is impossible to detect... Default is no detection, only filling

    //Filling
    Stream_Prepare(Stream_General);
    Fill(Stream_General, 0, General_Format, "PCM");
    Stream_Prepare(Stream_Audio);
    Fill(Stream_Audio, 0, Audio_Format, "PCM");
    Fill(Stream_Audio, 0, Audio_Codec, "PCM");

    Finnished();
}

//---------------------------------------------------------------------------
void File_Pcm::Read_Buffer_Finalize()
{
    //Filling
    Ztring Firm, Endianness, Sign, ITU, Resolution;
    if (0)
        ;
    else if (Codec==_T("EVOB"))             {Firm=_T("");       Endianness=_T("Big");    Sign=_T("Signed");   Resolution=_T("");} //PCM Signed 16 bits Big Endian, Interleavement is for 2 samples*2 channels L0-1/L0-0/R0-1/R0-0/L1-1/L1-0/R1-1/R1-0/L0-2/R0-2/L1-2/R1-2, http://wiki.multimedia.cx/index.php?title=PCM
    else if (Codec==_T("VOB"))              {Firm=_T("");       Endianness=_T("Big");    Sign=_T("Signed");   Resolution=_T("");} //PCM Signed 16 bits Big Endian, Interleavement is for 2 samples*2 channels L0-1/L0-0/R0-1/R0-0/L1-1/L1-0/R1-1/R1-0/L0-2/R0-2/L1-2/R1-2, http://wiki.multimedia.cx/index.php?title=PCM
    else if (Codec==_T("A_PCM/INT/BIG"))    {Firm=_T("");       Endianness=_T("Big");}
    else if (Codec==_T("A_PCM/INT/LITTLE")) {Firm=_T("");       Endianness=_T("Little");}
    else if (Codec==_T("A_PCM/INT/FLOAT"))  {Firm=_T("");       Endianness=_T("Float");}
    else if (Codec==_T("fl32"))             {                   Endianness=_T("Float");                       Resolution=_T("32");}
    else if (Codec==_T("fl64"))             {                   Endianness=_T("Float");                       Resolution=_T("64");}
    else if (Codec==_T("in24"))             {                   Endianness=_T("Big");    Sign=_T("Unsigned"); Resolution=_T("24");}
    else if (Codec==_T("in32"))             {                   Endianness=_T("Big");    Sign=_T("Unsigned"); Resolution=_T("32");}
    else if (Codec==_T("raw "))             {                   Endianness=_T("Little"); Sign=_T("Unsigned");}
    else if (Codec==_T("twos"))             {                   Endianness=_T("Big");    Sign=_T("Signed");}
    else if (Codec==_T("sowt"))             {                   Endianness=_T("Little"); Sign=_T("Signed");}
    else if (Codec==_T("SWF ADPCM"))        {Firm=_T("SWF");}
    else if (Codec==_T("1"))                {                   Endianness=_T("Little"); Sign=_T("Unsigned");}
    else if (Codec==_T("2"))                {Firm=_T("Microsoft");}
    else if (Codec==_T("3"))                {                   Endianness=_T("Float");}
    else if (Codec==_T("10"))               {Firm=_T("OKI");}
    else if (Codec==_T("11"))               {Firm=_T("Intel");}
    else if (Codec==_T("12"))               {Firm=_T("Mediaspace");}
    else if (Codec==_T("13"))               {Firm=_T("Sierra");}
    else if (Codec==_T("14"))               {Firm=_T("Antex");}
    else if (Codec==_T("17"))               {Firm=_T("Dialogic");}
    else if (Codec==_T("18"))               {Firm=_T("Mediavision");}
    else if (Codec==_T("20"))               {Firm=_T("Yamaha");}
    else if (Codec==_T("33"))               {Firm=_T("Antex");}
    else if (Codec==_T("36"))               {Firm=_T("DSP Solution");}
    else if (Codec==_T("38"))               {Firm=_T("Natural MicroSystems");}
    else if (Codec==_T("39"))               {Firm=_T("Crystal Semiconductor");}
    else if (Codec==_T("3B"))               {Firm=_T("Rockwell");}
    else if (Codec==_T("40"))               {Firm=_T("Antex Electronics");}
    else if (Codec==_T("42"))               {Firm=_T("IBM");}
    else if (Codec==_T("45"))               {Firm=_T("Microsoft"); ITU=_T("G.726");}
    else if (Codec==_T("64"))               {Firm=_T("Apicom"); ITU=_T("G.726");}
    else if (Codec==_T("65"))               {Firm=_T("Apicom"); ITU=_T("G.722");}
    else if (Codec==_T("85"))               {Firm=_T("DataFusion Systems"); ITU=_T("G.726");}
    else if (Codec==_T("8B"))               {Firm=_T("Infocom"); ITU=_T("G.721");}
    else if (Codec==_T("97"))               {Firm=_T("ZyXEL");}
    else if (Codec==_T("100"))              {Firm=_T("Rhetorex");}
    else if (Codec==_T("125"))              {Firm=_T("Sanyo");}
    else if (Codec==_T("140"))              {Firm=_T("Dictaphone"); ITU=_T("G.726");}
    else if (Codec==_T("170"))              {Firm=_T("Unisys");}
    else if (Codec==_T("175"))              {Firm=_T("SyCom"); ITU=_T("G.726");}
    else if (Codec==_T("178"))              {Firm=_T("Knownledge");}
    else if (Codec==_T("200"))              {Firm=_T("Creative");}
    else if (Codec==_T("210"))              {Firm=_T("Uher");}
    else if (Codec==_T("285"))              {Firm=_T("Norcom Voice Systems");}
    else if (Codec==_T("1001"))             {Firm=_T("Olivetti");}
    else if (Codec==_T("1C03"))             {Firm=_T("Lucent"); ITU=_T("G.723");}
    else if (Codec==_T("1C0C"))             {Firm=_T("Lucent"); ITU=_T("G.723");}
    else if (Codec==_T("4243"))             {ITU=_T("G.726");}
    else if (Codec==_T("A105"))             {ITU=_T("G.726");}
    else if (Codec==_T("A107"))             {ITU=_T("G.726");}

    Fill(Stream_Audio, 0, Audio_Codec_String, "PCM");
    Fill(Stream_Audio, 0, Audio_Codec_Family, "PCM");
    if (!Firm.empty())
    {
        Fill(Stream_Audio, 0, Audio_Format_Settings, Firm);
        Fill(Stream_Audio, 0, Audio_Format_Settings_Firm, Firm);
        Fill(Stream_Audio, 0, Audio_Codec_Settings, Firm);
        Fill(Stream_Audio, 0, Audio_Codec_Settings_Firm, Firm);
    }
    if (!Endianness.empty())
    {
        Fill(Stream_Audio, 0, Audio_Format_Settings, Endianness);
        Fill(Stream_Audio, 0, Audio_Format_Settings_Endianness, Endianness);
        Fill(Stream_Audio, 0, Audio_Codec_Settings, Endianness);
        Fill(Stream_Audio, 0, Audio_Codec_Settings_Endianness, Endianness);
    }
    if (!Sign.empty())
    {
        Fill(Stream_Audio, 0, Audio_Format_Settings, Sign);
        Fill(Stream_Audio, 0, Audio_Format_Settings_Sign, Sign);
        Fill(Stream_Audio, 0, Audio_Codec_Settings, Sign);
        Fill(Stream_Audio, 0, Audio_Codec_Settings_Sign, Sign);
    }
    if (!ITU.empty())
    {
        Fill(Stream_Audio, 0, Audio_Format_Settings, ITU);
        Fill(Stream_Audio, 0, Audio_Format_Settings_ITU, ITU);
        Fill(Stream_Audio, 0, Audio_Codec_Settings, ITU);
        Fill(Stream_Audio, 0, Audio_Codec_Settings_ITU, ITU);
    }
    Fill(Stream_Audio, 0, Audio_Resolution, Resolution);
    Fill(Stream_Audio, 0, Audio_BitRate_Mode, "CBR");
}

//***************************************************************************
// Information
//***************************************************************************

//---------------------------------------------------------------------------
void File_Pcm::HowTo(stream_t StreamKind)
{
    switch (StreamKind)
    {
        case (Stream_General) :
            break;
        case (Stream_Video) :
            break;
        case (Stream_Audio) :
            break;
        case (Stream_Text) :
            break;
        case (Stream_Chapters) :
            break;
        case (Stream_Image) :
            break;
        case (Stream_Menu) :
            break;
        case (Stream_Max) :
            break;
    }
}

//***************************************************************************
// C++
//***************************************************************************

} //NameSpace

#endif //MEDIAINFO_PCM_YES
<|endoftext|>


<commit_before>// Copyright 2015 Headcrash Industries LLC. All Rights Reserved.

#include "VlcMediaPCH.h"
#include "Vlc.h"

#define VLC_IMPORT(Name, Func) \
	Func = (FLibvlc##Func##Proc)FPlatformProcess::GetDllExport(LibHandle, TEXT(#Name)); \
	if (Func == nullptr) \
	{ \
		UE_LOG(LogVlcMedia, Warning, TEXT("Failed to import VLC function %s"), TEXT(#Name)); \
		Shutdown(); \
		return false; \
	}

#define VLCCORE_IMPORT(Name, Func) \
	Func = (FLibvlc##Func##Proc)FPlatformProcess::GetDllExport(CoreHandle, TEXT(#Name)); \
	if (Func == nullptr) \
	{ \
		UE_LOG(LogVlcMedia, Warning, TEXT("Failed to import VLC Core function %s"), TEXT(#Name)); \
		Shutdown(); \
		return false; \
	}

#define VLC_DEFINE(Func) \
	FLibvlc##Func##Proc FVlc::Func = nullptr

/* Static initialization
 *****************************************************************************/

void* FVlc::CoreHandle = nullptr;
void* FVlc::LibHandle = nullptr;
FString FVlc::PluginDir;

#if PLATFORM_WINDOWS
	void* FVlc::GccHandle = nullptr;
#endif

VLC_DEFINE(New);
VLC_DEFINE(Release);
VLC_DEFINE(Retain);

VLC_DEFINE(Errmsg);
VLC_DEFINE(Clearerr);

VLC_DEFINE(EventAttach);
VLC_DEFINE(EventDetach);
VLC_DEFINE(EventTypeName);

VLC_DEFINE(LogSet);
VLC_DEFINE(LogUnset);

VLC_DEFINE(Clock);

VLC_DEFINE(MediaEventManager);
VLC_DEFINE(MediaGetStats);
VLC_DEFINE(MediaNewCallbacks);
VLC_DEFINE(MediaNewLocation);
VLC_DEFINE(MediaNewPath);
VLC_DEFINE(MediaParseAsync);
VLC_DEFINE(MediaRelease);
VLC_DEFINE(MediaRetain);
VLC_DEFINE(MediaTracksGet);
VLC_DEFINE(MediaTracksRelease);

VLC_DEFINE(MediaPlayerEventManager);
VLC_DEFINE(MediaPlayerGetMedia);
VLC_DEFINE(MediaPlayerNew);
VLC_DEFINE(MediaPlayerNewFromMedia);
VLC_DEFINE(MediaPlayerRelease);
VLC_DEFINE(MediaPlayerRetain);
VLC_DEFINE(MediaPlayerSetMedia);

VLC_DEFINE(MediaPlayerCanPause);
VLC_DEFINE(MediaPlayerGetFps);
VLC_DEFINE(MediaPlayerGetLength);
VLC_DEFINE(MediaPlayerGetPosition);
VLC_DEFINE(MediaPlayerGetRate);
VLC_DEFINE(MediaPlayerGetState);
VLC_DEFINE(MediaPlayerGetTime);
VLC_DEFINE(MediaPlayerIsSeekable);
VLC_DEFINE(MediaPlayerSetPosition);
VLC_DEFINE(MediaPlayerSetRate);
VLC_DEFINE(MediaPlayerSetTime);

VLC_DEFINE(MediaPlayerIsPlaying);
VLC_DEFINE(MediaPlayerPause);
VLC_DEFINE(MediaPlayerPlay);
VLC_DEFINE(MediaPlayerSetPause);
VLC_DEFINE(MediaPlayerStop);
VLC_DEFINE(MediaPlayerWillPlay);

VLC_DEFINE(AudioSetCallbacks);
VLC_DEFINE(AudioSetFormat);
VLC_DEFINE(AudioSetFormatCallbacks);
VLC_DEFINE(AudioGetTrack);
VLC_DEFINE(AudioSetTrack);

VLC_DEFINE(VideoGetHeight);
VLC_DEFINE(VideoGetWidth);
VLC_DEFINE(VideoSetCallbacks);
VLC_DEFINE(VideoSetFormat);
VLC_DEFINE(VideoSetFormatCallbacks);
VLC_DEFINE(VideoGetSpu);
VLC_DEFINE(VideoGetSpuCount);
VLC_DEFINE(VideoSetSpu);
VLC_DEFINE(VideoGetTrack);
VLC_DEFINE(VideoSetTrack);

VLC_DEFINE(AudioGetTrackDescription);
VLC_DEFINE(VideoGetSpuDescription);
VLC_DEFINE(VideoGetTrackDescription);
VLC_DEFINE(TrackDescriptionListRelease);

VLC_DEFINE(FourccGetChromaDescription);

/* FVlc static functions
 *****************************************************************************/

FString FVlc::GetPluginDir()
{
	return PluginDir;
}

bool FVlc::Initialize()
{
	// determine directory paths
	const FString BaseDir = IPluginManager::Get().FindPlugin("VlcMedia")->GetBaseDir();
	const FString VlcDir = FPaths::Combine(*BaseDir, TEXT("ThirdParty"), TEXT("vlc"));

#if PLATFORM_LINUX
	const FString LibDir = FPaths::Combine(*VlcDir, TEXT("Linux"), TEXT("x86_64-unknown-linux-gnu"));
#elif PLATFORM_MAC
	const FString LibDir = FPaths::Combine(*VlcDir, TEXT("Mac"));
#elif PLATFORM_WINDOWS
	#if PLATFORM_64BITS
		const FString LibDir = FPaths::Combine(*VlcDir, TEXT("Win64"));
	#else
		const FString LibDir = FPaths::Combine(*VlcDir, TEXT("Win32"));
	#endif
#endif

	// load required libraries in the correct order
	if (!LoadDependency(LibDir, TEXT("libvlccore"), CoreHandle) ||
		!LoadDependency(LibDir, TEXT("libvlc"), LibHandle))
	{
		Shutdown();
		return false;
	}

	PluginDir = FPaths::ConvertRelativePathToFull(FPaths::Combine(*LibDir, TEXT("plugins")));

	// import library functions
	VLC_IMPORT(libvlc_new, New);
	VLC_IMPORT(libvlc_release, Release);
	VLC_IMPORT(libvlc_retain, Retain);

	VLC_IMPORT(libvlc_errmsg, Errmsg);
	VLC_IMPORT(libvlc_clearerr, Clearerr);

	VLC_IMPORT(libvlc_event_attach, EventAttach);
	VLC_IMPORT(libvlc_event_detach, EventDetach);
	VLC_IMPORT(libvlc_event_type_name, EventTypeName);

	VLC_IMPORT(libvlc_log_set, LogSet);
	VLC_IMPORT(libvlc_log_unset, LogUnset);

	VLC_IMPORT(libvlc_clock, Clock);

	VLC_IMPORT(libvlc_media_event_manager, MediaEventManager);
	VLC_IMPORT(libvlc_media_get_stats, MediaGetStats);
	VLC_IMPORT(libvlc_media_new_callbacks, MediaNewCallbacks);
	VLC_IMPORT(libvlc_media_new_location, MediaNewLocation);
	VLC_IMPORT(libvlc_media_new_path, MediaNewPath);
	VLC_IMPORT(libvlc_media_parse_async, MediaParseAsync);
	VLC_IMPORT(libvlc_media_release, MediaRelease);
	VLC_IMPORT(libvlc_media_retain, MediaRetain);
	VLC_IMPORT(libvlc_media_tracks_get, MediaTracksGet);
	VLC_IMPORT(libvlc_media_tracks_release, MediaTracksRelease);

	VLC_IMPORT(libvlc_media_player_event_manager, MediaPlayerEventManager);
	VLC_IMPORT(libvlc_media_player_get_media, MediaPlayerGetMedia);
	VLC_IMPORT(libvlc_media_player_new, MediaPlayerNew);
	VLC_IMPORT(libvlc_media_player_new_from_media, MediaPlayerNewFromMedia);
	VLC_IMPORT(libvlc_media_player_release, MediaPlayerRelease);
	VLC_IMPORT(libvlc_media_player_retain, MediaPlayerRetain);
	VLC_IMPORT(libvlc_media_player_set_media, MediaPlayerSetMedia);

	VLC_IMPORT(libvlc_media_player_can_pause, MediaPlayerCanPause);
	VLC_IMPORT(libvlc_media_player_get_fps, MediaPlayerGetFps);
	VLC_IMPORT(libvlc_media_player_get_length, MediaPlayerGetLength);
	VLC_IMPORT(libvlc_media_player_get_position, MediaPlayerGetPosition);
	VLC_IMPORT(libvlc_media_player_get_rate, MediaPlayerGetRate);
	VLC_IMPORT(libvlc_media_player_get_state, MediaPlayerGetState);
	VLC_IMPORT(libvlc_media_player_get_time, MediaPlayerGetTime);
	VLC_IMPORT(libvlc_media_player_is_seekable, MediaPlayerIsSeekable);
	VLC_IMPORT(libvlc_media_player_set_position, MediaPlayerSetPosition);
	VLC_IMPORT(libvlc_media_player_set_rate, MediaPlayerSetRate);
	VLC_IMPORT(libvlc_media_player_set_time, MediaPlayerSetTime);

	VLC_IMPORT(libvlc_media_player_is_playing, MediaPlayerIsPlaying);
	VLC_IMPORT(libvlc_media_player_pause, MediaPlayerPause);
	VLC_IMPORT(libvlc_media_player_play, MediaPlayerPlay);
	VLC_IMPORT(libvlc_media_player_set_pause, MediaPlayerSetPause);
	VLC_IMPORT(libvlc_media_player_stop, MediaPlayerStop);
	VLC_IMPORT(libvlc_media_player_will_play, MediaPlayerWillPlay);

	VLC_IMPORT(libvlc_audio_set_callbacks, AudioSetCallbacks);
	VLC_IMPORT(libvlc_audio_set_format, AudioSetFormat);
	VLC_IMPORT(libvlc_audio_set_format_callbacks, AudioSetFormatCallbacks);
	VLC_IMPORT(libvlc_audio_get_track, AudioGetTrack);
	VLC_IMPORT(libvlc_audio_set_track, AudioSetTrack);

	VLC_IMPORT(libvlc_video_get_height, VideoGetHeight);
	VLC_IMPORT(libvlc_video_get_width, VideoGetWidth);
	VLC_IMPORT(libvlc_video_set_callbacks, VideoSetCallbacks);
	VLC_IMPORT(libvlc_video_set_format, VideoSetFormat);
	VLC_IMPORT(libvlc_video_set_format_callbacks, VideoSetFormatCallbacks);
	VLC_IMPORT(libvlc_video_get_spu, VideoGetSpu);
	VLC_IMPORT(libvlc_video_get_spu_count, VideoGetSpuCount);
	VLC_IMPORT(libvlc_video_set_spu, VideoSetSpu);
	VLC_IMPORT(libvlc_video_get_track, VideoGetTrack);
	VLC_IMPORT(libvlc_video_set_track, VideoSetTrack);

	VLC_IMPORT(libvlc_audio_get_track_description, AudioGetTrackDescription);
	VLC_IMPORT(libvlc_video_get_spu_description, VideoGetSpuDescription);
	VLC_IMPORT(libvlc_video_get_track_description, VideoGetTrackDescription);
	VLC_IMPORT(libvlc_track_description_release, TrackDescriptionListRelease);

	// import core functions
	VLCCORE_IMPORT(vlc_fourcc_GetChromaDescription, FourccGetChromaDescription);

	return true;
}

void FVlc::Shutdown()
{
	PluginDir.Empty();

	FreeDependency(LibHandle);
	FreeDependency(CoreHandle);

#if PLATFORM_WINDOWS
	FreeDependency(GccHandle);
#endif
}

/* FVlc static functions
 *****************************************************************************/

void FVlc::FreeDependency(void*& Handle)
{
	if (Handle != nullptr)
	{
		FPlatformProcess::FreeDllHandle(Handle);
		Handle = nullptr;
	}
}

bool FVlc::LoadDependency(const FString& Dir, const FString& Name, void*& Handle)
{
	FString Lib = Name + TEXT(".") + FPlatformProcess::GetModuleExtension();
	FString Path = Dir.IsEmpty() ? *Lib : FPaths::Combine(*Dir, *Lib);

	Handle = FPlatformProcess::GetDllHandle(*Path);

	if (Handle == nullptr)
	{
		GLog->Logf(ELogVerbosity::Warning, TEXT("VlcMedia: Failed to load required library %s. Plug-in will not be functional."), *Lib);
		return false;
	}

	return true;
}
<commit_msg>Cleaned up dependency loader.<commit_after>// Copyright 2015 Headcrash Industries LLC. All Rights Reserved.

#include "VlcMediaPCH.h"
#include "Vlc.h"

#define VLC_IMPORT(Name, Func) \
	Func = (FLibvlc##Func##Proc)FPlatformProcess::GetDllExport(LibHandle, TEXT(#Name)); \
	if (Func == nullptr) \
	{ \
		UE_LOG(LogVlcMedia, Warning, TEXT("Failed to import VLC function %s"), TEXT(#Name)); \
		Shutdown(); \
		return false; \
	}

#define VLCCORE_IMPORT(Name, Func) \
	Func = (FLibvlc##Func##Proc)FPlatformProcess::GetDllExport(CoreHandle, TEXT(#Name)); \
	if (Func == nullptr) \
	{ \
		UE_LOG(LogVlcMedia, Warning, TEXT("Failed to import VLC Core function %s"), TEXT(#Name)); \
		Shutdown(); \
		return false; \
	}

#define VLC_DEFINE(Func) \
	FLibvlc##Func##Proc FVlc::Func = nullptr

/* Static initialization
 *****************************************************************************/

void* FVlc::CoreHandle = nullptr;
void* FVlc::LibHandle = nullptr;
FString FVlc::PluginDir;

VLC_DEFINE(New);
VLC_DEFINE(Release);
VLC_DEFINE(Retain);

VLC_DEFINE(Errmsg);
VLC_DEFINE(Clearerr);

VLC_DEFINE(EventAttach);
VLC_DEFINE(EventDetach);
VLC_DEFINE(EventTypeName);

VLC_DEFINE(LogSet);
VLC_DEFINE(LogUnset);

VLC_DEFINE(Clock);

VLC_DEFINE(MediaEventManager);
VLC_DEFINE(MediaGetStats);
VLC_DEFINE(MediaNewCallbacks);
VLC_DEFINE(MediaNewLocation);
VLC_DEFINE(MediaNewPath);
VLC_DEFINE(MediaParseAsync);
VLC_DEFINE(MediaRelease);
VLC_DEFINE(MediaRetain);
VLC_DEFINE(MediaTracksGet);
VLC_DEFINE(MediaTracksRelease);

VLC_DEFINE(MediaPlayerEventManager);
VLC_DEFINE(MediaPlayerGetMedia);
VLC_DEFINE(MediaPlayerNew);
VLC_DEFINE(MediaPlayerNewFromMedia);
VLC_DEFINE(MediaPlayerRelease);
VLC_DEFINE(MediaPlayerRetain);
VLC_DEFINE(MediaPlayerSetMedia);

VLC_DEFINE(MediaPlayerCanPause);
VLC_DEFINE(MediaPlayerGetFps);
VLC_DEFINE(MediaPlayerGetLength);
VLC_DEFINE(MediaPlayerGetPosition);
VLC_DEFINE(MediaPlayerGetRate);
VLC_DEFINE(MediaPlayerGetState);
VLC_DEFINE(MediaPlayerGetTime);
VLC_DEFINE(MediaPlayerIsSeekable);
VLC_DEFINE(MediaPlayerSetPosition);
VLC_DEFINE(MediaPlayerSetRate);
VLC_DEFINE(MediaPlayerSetTime);

VLC_DEFINE(MediaPlayerIsPlaying);
VLC_DEFINE(MediaPlayerPause);
VLC_DEFINE(MediaPlayerPlay);
VLC_DEFINE(MediaPlayerSetPause);
VLC_DEFINE(MediaPlayerStop);
VLC_DEFINE(MediaPlayerWillPlay);

VLC_DEFINE(AudioSetCallbacks);
VLC_DEFINE(AudioSetFormat);
VLC_DEFINE(AudioSetFormatCallbacks);
VLC_DEFINE(AudioGetTrack);
VLC_DEFINE(AudioSetTrack);

VLC_DEFINE(VideoGetHeight);
VLC_DEFINE(VideoGetWidth);
VLC_DEFINE(VideoSetCallbacks);
VLC_DEFINE(VideoSetFormat);
VLC_DEFINE(VideoSetFormatCallbacks);
VLC_DEFINE(VideoGetSpu);
VLC_DEFINE(VideoGetSpuCount);
VLC_DEFINE(VideoSetSpu);
VLC_DEFINE(VideoGetTrack);
VLC_DEFINE(VideoSetTrack);

VLC_DEFINE(AudioGetTrackDescription);
VLC_DEFINE(VideoGetSpuDescription);
VLC_DEFINE(VideoGetTrackDescription);
VLC_DEFINE(TrackDescriptionListRelease);

VLC_DEFINE(FourccGetChromaDescription);

/* FVlc static functions
 *****************************************************************************/

FString FVlc::GetPluginDir()
{
	return PluginDir;
}

bool FVlc::Initialize()
{
	// determine directory paths
	const FString BaseDir = IPluginManager::Get().FindPlugin("VlcMedia")->GetBaseDir();
	const FString VlcDir = FPaths::Combine(*BaseDir, TEXT("ThirdParty"), TEXT("vlc"));

#if PLATFORM_LINUX
	const FString LibDir = FPaths::Combine(*VlcDir, TEXT("Linux"), TEXT("x86_64-unknown-linux-gnu"));
#elif PLATFORM_MAC
	const FString LibDir = FPaths::Combine(*VlcDir, TEXT("Mac"));
#elif PLATFORM_WINDOWS
	#if PLATFORM_64BITS
		const FString LibDir = FPaths::Combine(*VlcDir, TEXT("Win64"));
	#else
		const FString LibDir = FPaths::Combine(*VlcDir, TEXT("Win32"));
	#endif
#endif

	// load required libraries in the correct order
	if (!LoadDependency(LibDir, TEXT("libvlccore"), CoreHandle))
	{
		return false;
	}

	if (!LoadDependency(LibDir, TEXT("libvlc"), LibHandle))
	{
		FreeDependency(CoreHandle);

		return false;
	}

	PluginDir = FPaths::ConvertRelativePathToFull(FPaths::Combine(*LibDir, TEXT("plugins")));

	// import library functions
	VLC_IMPORT(libvlc_new, New);
	VLC_IMPORT(libvlc_release, Release);
	VLC_IMPORT(libvlc_retain, Retain);

	VLC_IMPORT(libvlc_errmsg, Errmsg);
	VLC_IMPORT(libvlc_clearerr, Clearerr);

	VLC_IMPORT(libvlc_event_attach, EventAttach);
	VLC_IMPORT(libvlc_event_detach, EventDetach);
	VLC_IMPORT(libvlc_event_type_name, EventTypeName);

	VLC_IMPORT(libvlc_log_set, LogSet);
	VLC_IMPORT(libvlc_log_unset, LogUnset);

	VLC_IMPORT(libvlc_clock, Clock);

	VLC_IMPORT(libvlc_media_event_manager, MediaEventManager);
	VLC_IMPORT(libvlc_media_get_stats, MediaGetStats);
	VLC_IMPORT(libvlc_media_new_callbacks, MediaNewCallbacks);
	VLC_IMPORT(libvlc_media_new_location, MediaNewLocation);
	VLC_IMPORT(libvlc_media_new_path, MediaNewPath);
	VLC_IMPORT(libvlc_media_parse_async, MediaParseAsync);
	VLC_IMPORT(libvlc_media_release, MediaRelease);
	VLC_IMPORT(libvlc_media_retain, MediaRetain);
	VLC_IMPORT(libvlc_media_tracks_get, MediaTracksGet);
	VLC_IMPORT(libvlc_media_tracks_release, MediaTracksRelease);

	VLC_IMPORT(libvlc_media_player_event_manager, MediaPlayerEventManager);
	VLC_IMPORT(libvlc_media_player_get_media, MediaPlayerGetMedia);
	VLC_IMPORT(libvlc_media_player_new, MediaPlayerNew);
	VLC_IMPORT(libvlc_media_player_new_from_media, MediaPlayerNewFromMedia);
	VLC_IMPORT(libvlc_media_player_release, MediaPlayerRelease);
	VLC_IMPORT(libvlc_media_player_retain, MediaPlayerRetain);
	VLC_IMPORT(libvlc_media_player_set_media, MediaPlayerSetMedia);

	VLC_IMPORT(libvlc_media_player_can_pause, MediaPlayerCanPause);
	VLC_IMPORT(libvlc_media_player_get_fps, MediaPlayerGetFps);
	VLC_IMPORT(libvlc_media_player_get_length, MediaPlayerGetLength);
	VLC_IMPORT(libvlc_media_player_get_position, MediaPlayerGetPosition);
	VLC_IMPORT(libvlc_media_player_get_rate, MediaPlayerGetRate);
	VLC_IMPORT(libvlc_media_player_get_state, MediaPlayerGetState);
	VLC_IMPORT(libvlc_media_player_get_time, MediaPlayerGetTime);
	VLC_IMPORT(libvlc_media_player_is_seekable, MediaPlayerIsSeekable);
	VLC_IMPORT(libvlc_media_player_set_position, MediaPlayerSetPosition);
	VLC_IMPORT(libvlc_media_player_set_rate, MediaPlayerSetRate);
	VLC_IMPORT(libvlc_media_player_set_time, MediaPlayerSetTime);

	VLC_IMPORT(libvlc_media_player_is_playing, MediaPlayerIsPlaying);
	VLC_IMPORT(libvlc_media_player_pause, MediaPlayerPause);
	VLC_IMPORT(libvlc_media_player_play, MediaPlayerPlay);
	VLC_IMPORT(libvlc_media_player_set_pause, MediaPlayerSetPause);
	VLC_IMPORT(libvlc_media_player_stop, MediaPlayerStop);
	VLC_IMPORT(libvlc_media_player_will_play, MediaPlayerWillPlay);

	VLC_IMPORT(libvlc_audio_set_callbacks, AudioSetCallbacks);
	VLC_IMPORT(libvlc_audio_set_format, AudioSetFormat);
	VLC_IMPORT(libvlc_audio_set_format_callbacks, AudioSetFormatCallbacks);
	VLC_IMPORT(libvlc_audio_get_track, AudioGetTrack);
	VLC_IMPORT(libvlc_audio_set_track, AudioSetTrack);

	VLC_IMPORT(libvlc_video_get_height, VideoGetHeight);
	VLC_IMPORT(libvlc_video_get_width, VideoGetWidth);
	VLC_IMPORT(libvlc_video_set_callbacks, VideoSetCallbacks);
	VLC_IMPORT(libvlc_video_set_format, VideoSetFormat);
	VLC_IMPORT(libvlc_video_set_format_callbacks, VideoSetFormatCallbacks);
	VLC_IMPORT(libvlc_video_get_spu, VideoGetSpu);
	VLC_IMPORT(libvlc_video_get_spu_count, VideoGetSpuCount);
	VLC_IMPORT(libvlc_video_set_spu, VideoSetSpu);
	VLC_IMPORT(libvlc_video_get_track, VideoGetTrack);
	VLC_IMPORT(libvlc_video_set_track, VideoSetTrack);

	VLC_IMPORT(libvlc_audio_get_track_description, AudioGetTrackDescription);
	VLC_IMPORT(libvlc_video_get_spu_description, VideoGetSpuDescription);
	VLC_IMPORT(libvlc_video_get_track_description, VideoGetTrackDescription);
	VLC_IMPORT(libvlc_track_description_release, TrackDescriptionListRelease);

	// import core functions
	VLCCORE_IMPORT(vlc_fourcc_GetChromaDescription, FourccGetChromaDescription);

	return true;
}

void FVlc::Shutdown()
{
	PluginDir.Empty();

	FreeDependency(LibHandle);
	FreeDependency(CoreHandle);
}

/* FVlc static functions
 *****************************************************************************/

void FVlc::FreeDependency(void*& Handle)
{
	if (Handle != nullptr)
	{
		FPlatformProcess::FreeDllHandle(Handle);
		Handle = nullptr;
	}
}

bool FVlc::LoadDependency(const FString& Dir, const FString& Name, void*& Handle)
{
	FString Lib = Name + TEXT(".") + FPlatformProcess::GetModuleExtension();
	FString Path = Dir.IsEmpty() ? *Lib : FPaths::Combine(*Dir, *Lib);

	Handle = FPlatformProcess::GetDllHandle(*Path);

	if (Handle == nullptr)
	{
		GLog->Logf(ELogVerbosity::Warning, TEXT("VlcMedia: Failed to load required library %s. Plug-in will not be functional."), *Lib);
		return false;
	}

	return true;
}
<|endoftext|>


<commit_before>#ifndef ALEPH_TOPOLOGY_IO_VTK_HH__
#define ALEPH_TOPOLOGY_IO_VTK_HH__

#include <cstddef>

#include <algorithm>
#include <fstream>
#include <regex>
#include <stdexcept>
#include <sstream>
#include <string>
#include <vector>

#include "utilities/String.hh"

namespace aleph
{

namespace topology
{

namespace io
{

/**
  @class VTKStructuredGridReader
  @brief Simple reader class for VTK structured grids

  This class is a simple parser for VTK files in 'legacy format'. It is
  capable of parsing a structured grid and converting it to a simplicial
  complex. Data and weights of the simplicial complex will be taken from
  the VTK file.
*/

class VTKStructuredGridReader
{
public:
  template <class SimplicialComplex> void operator()( const std::string& filename, SimplicialComplex& K )
  {
    using Simplex    = typename SimplicialComplex::ValueType;
    using DataType   = typename Simplex::DataType;

    this->operator()( filename, K, [] ( DataType a, DataType b ) { return std::max(a,b); } );
  }

  template <class SimplicialComplex, class Functor> void operator()( const std::string& filename, SimplicialComplex& K, Functor f )
  {
    std::ifstream in( filename );
    if( !in )
      throw std::runtime_error( "Unable to read input file" );

    this->operator()( in, K, f );
  }

  template <class SimplicialComplex> void operator()( std::ifstream& in, SimplicialComplex& K )
  {
    using Simplex    = typename SimplicialComplex::ValueType;
    using DataType   = typename Simplex::DataType;

    this->operator()( in, K, [] ( DataType a, DataType b ) { return std::max(a,b); } );
  }

  template <class SimplicialComplex, class Functor> void operator()( std::ifstream& in, SimplicialComplex& K, Functor f )
  {
    using namespace aleph::utilities;

    using Simplex    = typename SimplicialComplex::ValueType;
    using DataType   = typename Simplex::DataType;
    using VertexType = typename Simplex::VertexType;

    std::string line;

    // Parse header first ----------------------------------------------

    std::size_t nx, ny, nz,
                n,
                s;

    bool parsedHeader = this->parseHeader( in, nx, ny, nz, n, s );
    if( !parsedHeader )
      return;

    // TODO: Check data type size against 's' and report if there are
    // issues such as insufficient storage space

    // Parse body ------------------------------------------------------
    //
    // The body contains coordinates for each of the points, which are
    // dutifully ignored for now, and attributes. For now, point-based
    // attributes are supported.

    std::regex rePointData( "POINT_DATA[[:space:]]+([[:digit:]]+)" );
    std::regex reScalars( "SCALARS[[:space:]]+([[:alnum:]]+)[[:space:]]+([[:alnum:]]+)[[:space:]]*([[:digit:]]*)" );
    std::regex reLookupTable( "LOOKUP_TABLE[[:space:]]+([[:alnum:]]+)" );

    std::vector<DataType> coordinates;
    coordinates.reserve( n*3 );

    while( std::getline( in, line ) )
    {
      line         = trim( line );
      auto strings = split( line );

      for( auto&& coordinate : strings )
        coordinates.push_back( convert<DataType>( coordinate ) );

      if( coordinates.size() == n*3 )
        break;
    }

    std::vector<DataType> values;
    values.reserve( n );

    {
      std::smatch matches;

      while( std::getline( in, line ) )
      {
        if( std::regex_match( line, matches, rePointData ) )
        {
          auto sn = matches[1];
          if( static_cast<std::size_t>( std::stoull( sn ) ) != n )
            throw std::runtime_error( "Format error: number of point data attributes does not match number of points" );
        }
        else if( std::regex_match( line, matches, reScalars ) )
        {
          auto name       = matches[1];
          auto type       = matches[2];
          auto components = matches[3];

          // TODO:
          //  - Use name
          //  - Check type
          //  - Check number of components (if present)

          (void) name;
          (void) type;
          (void) components;
        }
        else if( std::regex_match( line, matches, reLookupTable ) )
        {
          auto name = matches[1];
          if( name != "default" )
            throw std::runtime_error( "Handling non-default lookup tables is not yet implemented" );
        }
        else
        {
          line         = trim( line );
          auto strings = split( line );

          for( auto&& value : strings )
            values.push_back( convert<DataType>( value ) );
        }
      }
    }

    // Create topology -------------------------------------------------
    //
    // Notice that this class only adds 0-simplices and 1-simplices to
    // the simplicial complex for now. While it is possible to include
    // triangles (i.e. 2-simplices), their creation order is not clear
    // and may subtly influence calculations.

    std::vector<Simplex> simplices;

    // Create 0-simplices ----------------------------------------------

    {
      VertexType v = VertexType();

      for( auto&& value : values )
        simplices.push_back( Simplex(v, value) );
    }

    // Create 1-simplices ----------------------------------------------

    for( std::size_t z = 0; z < nz; z++ )
    {
      for( std::size_t y = 0; y < ny; y++ )
      {
        for( std::size_t x = 0; x < nx; x++ )
        {
          auto i = coordinatesToIndex(nx,ny,x,y,z);
          auto N = neighbours(nx,ny,nz,x,y,z);

          for( auto&& j : N )
          {
            if( j > i )
              continue;

            auto wi = simplices.at(i).data();
            auto wj = simplices.at(j).data();

            // Use the functor specified by the client in order to
            // assign a weight for the new simplex.
            auto w  = f(wi, wj);

            simplices.push_back( Simplex( {i,j}, w ) );
          }
        }
      }
    }

    K = SimplicialComplex( simplices.begin(), simplices.end() );
  }

private:

  /**
    Converts an index in the array of values to the corresponding set of
    coordinates.
  */

  static void indexToCoordinates ( const std::size_t nx, const std::size_t ny,
                                   const std::size_t i,
                                   std::size_t& x,      // out: x
                                   std::size_t& y,      // out: y
                                   std::size_t& z )     // out: z
  {
    x = i % nx;
    y = static_cast<std::size_t>( i / (nx)    ) % ny;
    z = static_cast<std::size_t>( i / (nx*ny) );
  };

  /**
    Converts x,y,z coordinates to the corresponding index in the array
    of values.
  */

  static std::size_t coordinatesToIndex( const std::size_t nx, const std::size_t ny,
                                         const std::size_t x , const std::size_t  y, const std::size_t z ) noexcept
  {
   return z * nx*ny + x % nx + y * nx;
  }

  /**
    Enumerates all valid neighbours of a vertex and returns their
    indices. A valid neighbour is a neighbour whose index doesn't
    exceed the bounds of the grid. At present, the diagonal isn't
    used.
  */

  static std::vector<std::size_t> neighbours( const std::size_t nx, const std::size_t ny, const std::size_t nz,
                                              std::size_t x, std::size_t y, std::size_t z )
  {
    std::vector<std::size_t> neighbours;
    neighbours.reserve( 6 );

    // left
    if( x > 0 )
      neighbours.push_back( coordinatesToIndex(nx, ny, x-1, y, z) );
    // right
    else if( x+1 < nx )
      neighbours.push_back( coordinatesToIndex(nx, ny, x+1, y, z) );

    // bottom
    if( y > 0 )
      neighbours.push_back( coordinatesToIndex(nx, ny, x, y-1, z) );
    // top
    else if( y+1 < ny )
      neighbours.push_back( coordinatesToIndex(nx, ny, x, y+1, z) );

    // back
    if( z > 0 )
      neighbours.push_back( coordinatesToIndex(nx, ny, x, y, z-1) );
    // front
    else if( z+1 < nz )
      neighbours.push_back( coordinatesToIndex(nx, ny, x, y, z+1) );

    return neighbours;
  }

  /**
    Attempts parsing the header of a structured VTK file. If successful,
    returns true and sets all output variables:

    - x: x dimension
    - y: y dimension
    - z: z dimension
    - n: number of data points

    This function expects the header to conform to the VTK legacy file
    format.
  */

  bool parseHeader( std::ifstream& in,
                    std::size_t& x, std::size_t& y, std::size_t& z,
                    std::size_t& n,
                    std::size_t& s )
  {
    using namespace aleph::utilities;

    std::string identifier; // e.g. '# vtk DataFile Version 3.0'
    std::string header;     // e.g. 'VTK Output'
    std::string format;     // e.g. 'ASCII'
    std::string structure;  // e.g. 'DATASET STRUCTURED_GRID'
    std::string dimensions; // e.g. 'DIMENSIONS 100 10 1'
    std::string points;     // e.g. 'POINTS 1000 float'

    std::getline( in, identifier );
    std::getline( in, header );
    std::getline( in, format );

    if( !in )
      return false;

    identifier = trim( identifier );
    format     = trim( format );

    // This identifier is a little bit more lenient than the original
    // documentation requires: it will also accept if some fields are
    // joined by multiple spaces.
    std::regex reIdentifier( "#[[:space:]]+vtk[[:space:]]+DataFile[[:space:]]+Version[[:space:]]+([[:digit:]]+)\\.([[:digit:]]+)" );

    if( !std::regex_match( identifier, reIdentifier ) )
      return false;

    if( format != "ASCII" )
      throw std::runtime_error( "Binary file parsing is not yet supported" );

    std::getline( in, structure );
    std::getline( in, dimensions );
    std::getline( in, points );

    if( !in )
      return false;

    structure  = trim( structure );
    dimensions = trim( dimensions );
    points     = trim( points );

    std::regex reStructure( "DATASET[[:space:]]+STRUCTURED_GRID" );
    if( !std::regex_match( structure, reStructure ) )
      return false;

    std::regex reDimensions( "DIMENSIONS[[:space:]]+([[:digit:]]+)[[:space:]]+([[:digit:]]+)[[:space:]]+([[:digit:]]+)" );
    std::smatch matches;

    if( !std::regex_match( dimensions, matches, reDimensions ) )
      return false;

    auto sx = matches[1];
    auto sy = matches[2];
    auto sz = matches[3];

    x = std::size_t( std::stoull( sx ) );
    y = std::size_t( std::stoull( sy ) );
    z = std::size_t( std::stoull( sz ) );

    std::regex rePoints( "POINTS[[:space:]]+([[:digit:]]+)[[:space:]]+([[:alpha:]]+)" );
    if( !std::regex_match( points, matches, rePoints ) )
      return false;

    auto sn = matches[1];
    auto st = matches[2];

    n = std::size_t( std::stoull( sn ) );

    if( st == "double" )
      s = sizeof(double);
    else if( st == "float" )
      s = sizeof(float);
    else if( st == "long" )
      s = sizeof(long);
    else if( st == "unsigned_long" )
      s = sizeof(unsigned long);
    else if( st == "int" )
      s = sizeof(int);
    else if( st == "unsigned_int" )
      s = sizeof(unsigned int);
    else if( st == "short" )
      s = sizeof(short);
    else if( st == "unsigned_short" )
      s = sizeof(unsigned short);
    else if( st == "char" )
      s = sizeof(char);
    else if( st == "unsigned char" )
      s = sizeof(unsigned char);
    else if( st == "bit" )
      s = sizeof(bool);

    return true;
  }
};

} // namespace io

} // namespace topology

} // namespace aleph

#endif
<commit_msg>Fixed invalid bounds check for neighbour creation<commit_after>#ifndef ALEPH_TOPOLOGY_IO_VTK_HH__
#define ALEPH_TOPOLOGY_IO_VTK_HH__

#include <cstddef>

#include <algorithm>
#include <fstream>
#include <regex>
#include <stdexcept>
#include <sstream>
#include <string>
#include <vector>

#include "utilities/String.hh"

namespace aleph
{

namespace topology
{

namespace io
{

/**
  @class VTKStructuredGridReader
  @brief Simple reader class for VTK structured grids

  This class is a simple parser for VTK files in 'legacy format'. It is
  capable of parsing a structured grid and converting it to a simplicial
  complex. Data and weights of the simplicial complex will be taken from
  the VTK file.
*/

class VTKStructuredGridReader
{
public:
  template <class SimplicialComplex> void operator()( const std::string& filename, SimplicialComplex& K )
  {
    using Simplex    = typename SimplicialComplex::ValueType;
    using DataType   = typename Simplex::DataType;

    this->operator()( filename, K, [] ( DataType a, DataType b ) { return std::max(a,b); } );
  }

  template <class SimplicialComplex, class Functor> void operator()( const std::string& filename, SimplicialComplex& K, Functor f )
  {
    std::ifstream in( filename );
    if( !in )
      throw std::runtime_error( "Unable to read input file" );

    this->operator()( in, K, f );
  }

  template <class SimplicialComplex> void operator()( std::ifstream& in, SimplicialComplex& K )
  {
    using Simplex    = typename SimplicialComplex::ValueType;
    using DataType   = typename Simplex::DataType;

    this->operator()( in, K, [] ( DataType a, DataType b ) { return std::max(a,b); } );
  }

  template <class SimplicialComplex, class Functor> void operator()( std::ifstream& in, SimplicialComplex& K, Functor f )
  {
    using namespace aleph::utilities;

    using Simplex    = typename SimplicialComplex::ValueType;
    using DataType   = typename Simplex::DataType;
    using VertexType = typename Simplex::VertexType;

    std::string line;

    // Parse header first ----------------------------------------------

    std::size_t nx, ny, nz,
                n,
                s;

    bool parsedHeader = this->parseHeader( in, nx, ny, nz, n, s );
    if( !parsedHeader )
      return;

    // TODO: Check data type size against 's' and report if there are
    // issues such as insufficient storage space

    // Parse body ------------------------------------------------------
    //
    // The body contains coordinates for each of the points, which are
    // dutifully ignored for now, and attributes. For now, point-based
    // attributes are supported.

    std::regex rePointData( "POINT_DATA[[:space:]]+([[:digit:]]+)" );
    std::regex reScalars( "SCALARS[[:space:]]+([[:alnum:]]+)[[:space:]]+([[:alnum:]]+)[[:space:]]*([[:digit:]]*)" );
    std::regex reLookupTable( "LOOKUP_TABLE[[:space:]]+([[:alnum:]]+)" );

    std::vector<DataType> coordinates;
    coordinates.reserve( n*3 );

    while( std::getline( in, line ) )
    {
      line         = trim( line );
      auto strings = split( line );

      for( auto&& coordinate : strings )
        coordinates.push_back( convert<DataType>( coordinate ) );

      if( coordinates.size() == n*3 )
        break;
    }

    std::vector<DataType> values;
    values.reserve( n );

    {
      std::smatch matches;

      while( std::getline( in, line ) )
      {
        if( std::regex_match( line, matches, rePointData ) )
        {
          auto sn = matches[1];
          if( static_cast<std::size_t>( std::stoull( sn ) ) != n )
            throw std::runtime_error( "Format error: number of point data attributes does not match number of points" );
        }
        else if( std::regex_match( line, matches, reScalars ) )
        {
          auto name       = matches[1];
          auto type       = matches[2];
          auto components = matches[3];

          // TODO:
          //  - Use name
          //  - Check type
          //  - Check number of components (if present)

          (void) name;
          (void) type;
          (void) components;
        }
        else if( std::regex_match( line, matches, reLookupTable ) )
        {
          auto name = matches[1];
          if( name != "default" )
            throw std::runtime_error( "Handling non-default lookup tables is not yet implemented" );
        }
        else
        {
          line         = trim( line );
          auto strings = split( line );

          for( auto&& value : strings )
            values.push_back( convert<DataType>( value ) );
        }
      }
    }

    // Create topology -------------------------------------------------
    //
    // Notice that this class only adds 0-simplices and 1-simplices to
    // the simplicial complex for now. While it is possible to include
    // triangles (i.e. 2-simplices), their creation order is not clear
    // and may subtly influence calculations.

    std::vector<Simplex> simplices;

    // Create 0-simplices ----------------------------------------------

    {
      VertexType v = VertexType();

      for( auto&& value : values )
        simplices.push_back( Simplex(v, value) );
    }

    // Create 1-simplices ----------------------------------------------

    for( std::size_t z = 0; z < nz; z++ )
    {
      for( std::size_t y = 0; y < ny; y++ )
      {
        for( std::size_t x = 0; x < nx; x++ )
        {
          auto i = coordinatesToIndex(nx,ny,x,y,z);
          auto N = neighbours(nx,ny,nz,x,y,z);

          for( auto&& j : N )
          {
            if( j > i )
              continue;

            auto wi = simplices.at(i).data();
            auto wj = simplices.at(j).data();

            // Use the functor specified by the client in order to
            // assign a weight for the new simplex.
            auto w  = f(wi, wj);

            simplices.push_back( Simplex( {i,j}, w ) );
          }
        }
      }
    }

    K = SimplicialComplex( simplices.begin(), simplices.end() );
  }

private:

  /**
    Converts an index in the array of values to the corresponding set of
    coordinates.
  */

  static void indexToCoordinates ( const std::size_t nx, const std::size_t ny,
                                   const std::size_t i,
                                   std::size_t& x,      // out: x
                                   std::size_t& y,      // out: y
                                   std::size_t& z )     // out: z
  {
    x = i % nx;
    y = static_cast<std::size_t>( i / (nx)    ) % ny;
    z = static_cast<std::size_t>( i / (nx*ny) );
  };

  /**
    Converts x,y,z coordinates to the corresponding index in the array
    of values.
  */

  static std::size_t coordinatesToIndex( const std::size_t nx, const std::size_t ny,
                                         const std::size_t x , const std::size_t  y, const std::size_t z ) noexcept
  {
   return z * nx*ny + x % nx + y * nx;
  }

  /**
    Enumerates all valid neighbours of a vertex and returns their
    indices. A valid neighbour is a neighbour whose index doesn't
    exceed the bounds of the grid. At present, the diagonal isn't
    used.
  */

  static std::vector<std::size_t> neighbours( const std::size_t nx, const std::size_t ny, const std::size_t nz,
                                              std::size_t x, std::size_t y, std::size_t z )
  {
    std::vector<std::size_t> neighbours;
    neighbours.reserve( 6 );

    // left
    if( x > 0 )
      neighbours.push_back( coordinatesToIndex(nx, ny, x-1, y, z) );
    // right
    if( x+1 < nx )
      neighbours.push_back( coordinatesToIndex(nx, ny, x+1, y, z) );

    // bottom
    if( y > 0 )
      neighbours.push_back( coordinatesToIndex(nx, ny, x, y-1, z) );
    // top
    if( y+1 < ny )
      neighbours.push_back( coordinatesToIndex(nx, ny, x, y+1, z) );

    // back
    if( z > 0 )
      neighbours.push_back( coordinatesToIndex(nx, ny, x, y, z-1) );
    // front
    if( z+1 < nz )
      neighbours.push_back( coordinatesToIndex(nx, ny, x, y, z+1) );

    return neighbours;
  }

  /**
    Attempts parsing the header of a structured VTK file. If successful,
    returns true and sets all output variables:

    - x: x dimension
    - y: y dimension
    - z: z dimension
    - n: number of data points

    This function expects the header to conform to the VTK legacy file
    format.
  */

  bool parseHeader( std::ifstream& in,
                    std::size_t& x, std::size_t& y, std::size_t& z,
                    std::size_t& n,
                    std::size_t& s )
  {
    using namespace aleph::utilities;

    std::string identifier; // e.g. '# vtk DataFile Version 3.0'
    std::string header;     // e.g. 'VTK Output'
    std::string format;     // e.g. 'ASCII'
    std::string structure;  // e.g. 'DATASET STRUCTURED_GRID'
    std::string dimensions; // e.g. 'DIMENSIONS 100 10 1'
    std::string points;     // e.g. 'POINTS 1000 float'

    std::getline( in, identifier );
    std::getline( in, header );
    std::getline( in, format );

    if( !in )
      return false;

    identifier = trim( identifier );
    format     = trim( format );

    // This identifier is a little bit more lenient than the original
    // documentation requires: it will also accept if some fields are
    // joined by multiple spaces.
    std::regex reIdentifier( "#[[:space:]]+vtk[[:space:]]+DataFile[[:space:]]+Version[[:space:]]+([[:digit:]]+)\\.([[:digit:]]+)" );

    if( !std::regex_match( identifier, reIdentifier ) )
      return false;

    if( format != "ASCII" )
      throw std::runtime_error( "Binary file parsing is not yet supported" );

    std::getline( in, structure );
    std::getline( in, dimensions );
    std::getline( in, points );

    if( !in )
      return false;

    structure  = trim( structure );
    dimensions = trim( dimensions );
    points     = trim( points );

    std::regex reStructure( "DATASET[[:space:]]+STRUCTURED_GRID" );
    if( !std::regex_match( structure, reStructure ) )
      return false;

    std::regex reDimensions( "DIMENSIONS[[:space:]]+([[:digit:]]+)[[:space:]]+([[:digit:]]+)[[:space:]]+([[:digit:]]+)" );
    std::smatch matches;

    if( !std::regex_match( dimensions, matches, reDimensions ) )
      return false;

    auto sx = matches[1];
    auto sy = matches[2];
    auto sz = matches[3];

    x = std::size_t( std::stoull( sx ) );
    y = std::size_t( std::stoull( sy ) );
    z = std::size_t( std::stoull( sz ) );

    std::regex rePoints( "POINTS[[:space:]]+([[:digit:]]+)[[:space:]]+([[:alpha:]]+)" );
    if( !std::regex_match( points, matches, rePoints ) )
      return false;

    auto sn = matches[1];
    auto st = matches[2];

    n = std::size_t( std::stoull( sn ) );

    if( st == "double" )
      s = sizeof(double);
    else if( st == "float" )
      s = sizeof(float);
    else if( st == "long" )
      s = sizeof(long);
    else if( st == "unsigned_long" )
      s = sizeof(unsigned long);
    else if( st == "int" )
      s = sizeof(int);
    else if( st == "unsigned_int" )
      s = sizeof(unsigned int);
    else if( st == "short" )
      s = sizeof(short);
    else if( st == "unsigned_short" )
      s = sizeof(unsigned short);
    else if( st == "char" )
      s = sizeof(char);
    else if( st == "unsigned char" )
      s = sizeof(unsigned char);
    else if( st == "bit" )
      s = sizeof(bool);

    return true;
  }
};

} // namespace io

} // namespace topology

} // namespace aleph

#endif
<|endoftext|>


<commit_before><?hh // strict

namespace h4cc\HHVMProgressBundle\Services;

use h4cc\HHVMProgressBundle\HHVM;
use Psr\Log\LoggerInterface;
use Psr\Log\NullLogger;
use Symfony\Component\Yaml\Yaml;

class TravisParser
{
    /** @var array available hhvm versions on travis */
    private array<string> $hhvmStrings = ['hhvm', 'hhvm-nightly'];
    private LoggerInterface $logger;

    public function __construct()
    {
        $this->logger = new NullLogger();
    }

    public function setLogger(LoggerInterface $logger)
    {
        $this->logger = $logger;
    }

    public function getHHVMStatus(string $content) : int
    {
        if(!$content) {
            return HHVM::STATUS_NONE;
        }

        try {
            $data = Yaml::parse($content);
        }catch(\Exception $e) {
            $this->logger->info($e->getMessage());
            $this->logger->debug($e);

            return HHVM::STATUS_NONE;
        }

        return $this->parseHHVMStatus($data);
    }

    private function isHHVMString($string) {
        return in_array(strtolower($string), $this->hhvmStrings);
    }

    private function parseHHVMStatus(array $data)
    {
        if(isset($data['language']) && 'php' != $data['language']) {
            // This is NOT a PHP build, so return.
            return HHVM::STATUS_NONE;
        }

        $hhvmBuilds = [];
        $hhvmAllowedFailure = [];

        // Check 'php' part for hhvm enabled builds.
        if(isset($data['php']) && is_array($data['php'])) {
            foreach($data['php'] as $phpVersion) {
                if($this->isHHVMString($phpVersion)) {
                    $hhvmBuilds[] = $phpVersion;
                }
            }
        }

        // Check include matrix for enabled builds.
        if(isset($data['matrix']) && isset($data['matrix']['include'])) {
            foreach($data['matrix']['include'] as $inc) {
                if(is_array($inc) && isset($inc['php'])) {
                    $inc['php'] = (array)$inc['php'];
                    foreach($inc['php'] as $phpString) {
                        if($this->isHHVMString($phpString)) {
                            $hhvmBuilds[] = $phpString;
                        }
                    }
                }
            }
        }

        // Check allowed failure matrix.
        if(isset($data['matrix']) && isset($data['matrix']['allow_failures'])) {
            foreach($data['matrix']['allow_failures'] as $af) {
                if(is_array($af) && isset($af['php'])) {
                    $af['php'] = (array)$af['php'];
                    foreach($af['php'] as $phpString) {
                        if($this->isHHVMString($phpString)) {
                            $hhvmAllowedFailure[] = $phpString;
                        }
                    }
                }
            }
        }

        // array with hhvm string of not allowed hhvm builds
        // for now if at least one hhvm string is not allowed to fail, we'll mark
        // the project as tested.
        $hhvmNonFailureAllowed = array_diff($hhvmBuilds, $hhvmAllowedFailure);
        $returnValue = !empty($hhvmNonFailureAllowed)
            ? HHVM::STATUS_SUPPORTED
            : HHVM::STATUS_ALLOWED_FAILURE;

        return ($hhvmBuilds) ? $returnValue : HHVM::STATUS_NONE;
    }
}
<commit_msg>closing #51<commit_after><?hh // strict

namespace h4cc\HHVMProgressBundle\Services;

use h4cc\HHVMProgressBundle\HHVM;
use Psr\Log\LoggerInterface;
use Psr\Log\NullLogger;
use Symfony\Component\Yaml\Yaml;

class TravisParser
{
    /** @var array available hhvm versions on travis */
    private array<string> $hhvmStrings = ['hhvm', 'hhvm-nightly'];
    private LoggerInterface $logger;

    public function __construct()
    {
        $this->logger = new NullLogger();
    }

    public function setLogger(LoggerInterface $logger)
    {
        $this->logger = $logger;
    }

    public function getHHVMStatus(string $content) : int
    {
        if(!$content) {
            return HHVM::STATUS_NONE;
        }

        try {
            $data = Yaml::parse($content);

            if(is_null($data)) {
                throw new \RuntimeException('Empty Travis content parsed.');
            }

        }catch(\Exception $e) {
            $this->logger->info($e->getMessage());
            $this->logger->debug($e);

            return HHVM::STATUS_NONE;
        }

        return $this->parseHHVMStatus($data);
    }

    private function isHHVMString($string) {
        return in_array(strtolower($string), $this->hhvmStrings);
    }

    private function parseHHVMStatus(array $data)
    {
        if(isset($data['language']) && 'php' != $data['language']) {
            // This is NOT a PHP build, so return.
            return HHVM::STATUS_NONE;
        }

        $hhvmBuilds = [];
        $hhvmAllowedFailure = [];

        // Check 'php' part for hhvm enabled builds.
        if(isset($data['php']) && is_array($data['php'])) {
            foreach($data['php'] as $phpVersion) {
                if($this->isHHVMString($phpVersion)) {
                    $hhvmBuilds[] = $phpVersion;
                }
            }
        }

        // Check include matrix for enabled builds.
        if(isset($data['matrix']) && isset($data['matrix']['include'])) {
            foreach($data['matrix']['include'] as $inc) {
                if(is_array($inc) && isset($inc['php'])) {
                    $inc['php'] = (array)$inc['php'];
                    foreach($inc['php'] as $phpString) {
                        if($this->isHHVMString($phpString)) {
                            $hhvmBuilds[] = $phpString;
                        }
                    }
                }
            }
        }

        // Check allowed failure matrix.
        if(isset($data['matrix']) && isset($data['matrix']['allow_failures'])) {
            foreach($data['matrix']['allow_failures'] as $af) {
                if(is_array($af) && isset($af['php'])) {
                    $af['php'] = (array)$af['php'];
                    foreach($af['php'] as $phpString) {
                        if($this->isHHVMString($phpString)) {
                            $hhvmAllowedFailure[] = $phpString;
                        }
                    }
                }
            }
        }

        // array with hhvm string of not allowed hhvm builds
        // for now if at least one hhvm string is not allowed to fail, we'll mark
        // the project as tested.
        $hhvmNonFailureAllowed = array_diff($hhvmBuilds, $hhvmAllowedFailure);
        $returnValue = !empty($hhvmNonFailureAllowed)
            ? HHVM::STATUS_SUPPORTED
            : HHVM::STATUS_ALLOWED_FAILURE;

        return ($hhvmBuilds) ? $returnValue : HHVM::STATUS_NONE;
    }
}
<|endoftext|>


<commit_before>/*******************************************************************************
 * Copyright 2016 IBM Corp.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *******************************************************************************/

#include "ibmras/monitoring/agent/threads/WorkerThread.h"
#include "ibmras/monitoring/agent/Agent.h"
#include "ibmras/common/logging.h"

namespace ibmras {
namespace monitoring {
namespace agent {
namespace threads {

extern IBMRAS_DECLARE_LOGGER;

WorkerThread::WorkerThread(pullsource* pullSource) : semaphore(0, 1, pullSource->header.name), data(threadEntry, cleanUp), countdown(0) {
	source = pullSource;
	running = false;
	stopped = true;
	data.setArgs(this);
}

void WorkerThread::start() {
	IBMRAS_DEBUG_1(fine, "Starting worker thread for %s", source->header.name);
	running = true;
	stopped = false;
	ibmras::common::port::createThread(&data);
}

void WorkerThread::stop() {
	source->complete(NULL);
	running = false;
	stopped = true;
	semaphore.inc();
	IBMRAS_DEBUG_1(debug, "Worker thread for %s stopped", source->header.name);
}

void* WorkerThread::cleanUp(ibmras::common::port::ThreadData* data) {
	((WorkerThread*) data->getArgs())->stop();
	return NULL;
}

void* WorkerThread::threadEntry(ibmras::common::port::ThreadData* data) {
	((WorkerThread*) data->getArgs())->processLoop();
	ibmras::common::port::exitThread(NULL);
	return NULL;
}

void WorkerThread::process(bool immediate) {
    IBMRAS_DEBUG_2(finest, "Worker thread process for %s, countdown is %d", source->header.name, countdown);
	if ((immediate && countdown > 120) || (countdown == 0)) {
		semaphore.inc();
		countdown = source->pullInterval;
	} else {
		countdown--;
	}
}

bool WorkerThread::isStopped() {
	return stopped;
}

void* WorkerThread::processLoop() {
	IBMRAS_DEBUG_1(finest, "Worker thread started for %s", source->header.name);
	Agent* agent = Agent::getInstance();
	while (running) {
		if (semaphore.wait(1) && running) {
			IBMRAS_DEBUG_1(fine, "Pulling data from source %s", source->header.name);
			monitordata* data = source->callback();
			if (data != NULL) {
				if (data->size > 0) {
					IBMRAS_DEBUG_2(finest, "%d bytes of data pulled from source %s", data->size, source->header.name);
					agent->addData(data); /* put pulled data on queue for processing */
				}
				source->complete(data);
			}
		}
	}

	source->complete(NULL);
	stopped = true;
	IBMRAS_DEBUG_1(finest, "Worker thread for %s exiting process loop", source->header.name);
	return NULL;
}

}
}
}
} /* end of namespace threads */
<commit_msg>Issue #99: Comment out stopped=true in WorkerThread::stop to avoid ThreadPool destructing a WorkerThread while it's in processLoop<commit_after>/*******************************************************************************
 * Copyright 2016 IBM Corp.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *******************************************************************************/

#include "ibmras/monitoring/agent/threads/WorkerThread.h"
#include "ibmras/monitoring/agent/Agent.h"
#include "ibmras/common/logging.h"

namespace ibmras {
namespace monitoring {
namespace agent {
namespace threads {

extern IBMRAS_DECLARE_LOGGER;

WorkerThread::WorkerThread(pullsource* pullSource) : semaphore(0, 1, pullSource->header.name), data(threadEntry, cleanUp), countdown(0) {
	source = pullSource;
	running = false;
	stopped = true;
	data.setArgs(this);
}

void WorkerThread::start() {
	IBMRAS_DEBUG_1(fine, "Starting worker thread for %s", source->header.name);
	running = true;
	stopped = false;
	ibmras::common::port::createThread(&data);
}

void WorkerThread::stop() {
	source->complete(NULL);
	running = false;

	// Issue 99: By setting stopped to true too early, ThreadPool
	// might intermittently destruct us while we're still in processLoop.
	// We've already set running=false, so processLoop will finish the
	// next chance it gets and only then will set stopped=true.
	//stopped = true;

	semaphore.inc();
	IBMRAS_DEBUG_1(debug, "Worker thread for %s stopping", source->header.name);
}

void* WorkerThread::cleanUp(ibmras::common::port::ThreadData* data) {
	((WorkerThread*) data->getArgs())->stop();
	return NULL;
}

void* WorkerThread::threadEntry(ibmras::common::port::ThreadData* data) {
	((WorkerThread*) data->getArgs())->processLoop();
	ibmras::common::port::exitThread(NULL);
	return NULL;
}

void WorkerThread::process(bool immediate) {
    IBMRAS_DEBUG_2(finest, "Worker thread process for %s, countdown is %d", source->header.name, countdown);
	if ((immediate && countdown > 120) || (countdown == 0)) {
		semaphore.inc();
		countdown = source->pullInterval;
	} else {
		countdown--;
	}
}

bool WorkerThread::isStopped() {
	return stopped;
}

void* WorkerThread::processLoop() {
	IBMRAS_DEBUG_1(finest, "Worker thread started for %s", source->header.name);
	Agent* agent = Agent::getInstance();
	while (running) {
		if (semaphore.wait(1) && running) {
			IBMRAS_DEBUG_1(fine, "Pulling data from source %s", source->header.name);
			monitordata* data = source->callback();
			if (data != NULL) {
				if (data->size > 0) {
					IBMRAS_DEBUG_2(finest, "%d bytes of data pulled from source %s", data->size, source->header.name);
					agent->addData(data); /* put pulled data on queue for processing */
				}
				source->complete(data);
			}
		}
	}

	source->complete(NULL);
	stopped = true;
	IBMRAS_DEBUG_1(finest, "Worker thread for %s exiting process loop", source->header.name);
	return NULL;
}

}
}
}
} /* end of namespace threads */
<|endoftext|>


<commit_before>//
// SRTerrain class : a subclass of vtDynTerrainGeom which exposes
//  Stephan Roettger's CLOD algorithm.
//
// utilizes: Roettger's MINI library implementation, version 1.7
// http://wwwvis.informatik.uni-stuttgart.de/~roettger
//
// Copyright (c) 2002 Virtual Terrain Project
// Free for all uses, see license.txt for details.
//

#include "vtlib/vtlib.h"
#include "SRTerrain.h"
#include "LocalGrid.h"

#if ENABLE_SRTERRAIN
  using namespace mini;
  #ifdef _MSC_VER
    #pragma comment( lib, "libMini.lib" )
  #endif
#endif

/////////////////////////////////////////////////////////////////////////////

//
// Constructor/destructor
//
SRTerrain::SRTerrain() : vtDynTerrainGeom()
{
	m_fResolution = 10000.0f;
}

SRTerrain::~SRTerrain()
{
}

/////////////////////////////////////////////////////////////////////////////

//
// Unfortunately the following statics are required because libMini only
// supports some functionality by callback, and the callback is only a
// simple C function which has no context to tell us which terrain.
//
static vtLocalGrid *s_pGrid;
static SRTerrain *s_pSRTerrain;
static int myfancnt, myvtxcnt;

void beginfan_vtp()
{
	if (myfancnt++>0)
		glEnd();
	glBegin(GL_TRIANGLE_FAN);
	myvtxcnt-=2;	// 2 vertices are needed to start each fan
}

void fanvertex_vtp(float x, float y, float z)
{
   glVertex3f(x,y,z);
   myvtxcnt++;
}

void notify_vtp(int i, int j, int size)
{
	// check to see if we need to switch texture
	if (s_pSRTerrain->m_iTPatchDim > 1 && size == s_pSRTerrain->m_iBlockSize)
	{
		int a = i / size;
		int b = j / size;
		s_pSRTerrain->LoadBlockMaterial(a, b);
	}
}

short int getelevation_vtp1(int i, int j, int size)
{
	return s_pGrid->GetValue(i, j);
}

float getelevation_vtp2(int i, int j, int size)
{
	return s_pGrid->GetFValue(i, j);
}

//
// Initialize the terrain data
// fZScale converts from height values (meters) to world coordinates
//
bool SRTerrain::Init(vtLocalGrid *pGrid, float fZScale,
					 float fOceanDepth, int &iError)
{
#if ENABLE_SRTERRAIN
	// Initializes necessary field of the parent class
	BasicInit(pGrid);

	m_fHeightScale = fZScale;

	int size = m_iXPoints;
	float dim = m_fXStep;
	float cellaspect = m_fZStep / m_fXStep;

	s_pGrid = pGrid;

	if (pGrid->IsFloatMode())
	{
		float *image = NULL;
		m_pMini = new ministub(image,
				&size, &dim, fZScale, cellaspect,
				beginfan_vtp, fanvertex_vtp, notify_vtp,
				getelevation_vtp2);
	}
	else
	{
		short *image = NULL;
		m_pMini = new ministub(image,
				&size, &dim, fZScale, cellaspect,
				beginfan_vtp, fanvertex_vtp, notify_vtp,
				getelevation_vtp1);
	}

	m_iDrawnTriangles = -1;
	m_iBlockSize = m_iXPoints / 4;
#endif
	return true;
}

//
// This will be called once per frame, during the culling pass.
//
// However, libMini does not allow you to call the culling pass
// independently of the rendering pass, so we cannot do it here.
//
void SRTerrain::DoCulling(FPoint3 &eyepos_ogl, IPoint2 window_size, float fov)
{
	// store for later
	m_eyepos_ogl = eyepos_ogl;
	m_window_size = window_size;
	m_fFOVY = fov * window_size.y / window_size.x * 180 / PIf;
}

void SRTerrain::DoRender()
{
	// Prepare the render state for our OpenGL usage
	PreRender();

	// Render the triangles
	RenderSurface();

	// Clean up
	PostRender();
}

void SRTerrain::LoadSingleMaterial()
{
	// single texture for the whole terrain
	vtMaterial *pMat = GetMaterial(0);
	if (pMat)
	{
		pMat->Apply();
		SetupTexGen(1.0f);
	}
}

void SRTerrain::LoadBlockMaterial(int a, int b)
{
	// we can't change the texture between glBegin/glEnd
	if (myfancnt++>0)
		glEnd();

	// each block has it's own texture map
	int appidx = a*m_iTPatchDim + (m_iTPatchDim-1-b);
	vtMaterial *pMat = GetMaterial(appidx);
	if (pMat)
	{
		pMat->Apply();
		SetupBlockTexGen(a, b);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	}

	glBegin(GL_TRIANGLE_FAN);
}

void SRTerrain::RenderSurface()
{
	s_pSRTerrain = this;

	if (m_iTPatchDim == 1)
		LoadSingleMaterial();

	RenderPass();

	// here is an example of how to do a second rendering pass
	if (m_bDetailTexture)
	{
		// once again, with the detail texture material
		m_pDetailMat->Apply();

		// the uv tiling is different (usually highly repetitive)
		SetupTexGen(m_fDetailTiling);

		// draw the second pass
		glPolygonOffset(-1.0f, -1.0f);
		glEnable(GL_POLYGON_OFFSET_FILL);
		RenderPass();
		glDisable(GL_POLYGON_OFFSET_FILL);
	}
	DisableTexGen();
}

#define ADAPTION_SPEED	.0001f	// speed at which detail converges

void SRTerrain::RenderPass()
{
#if ENABLE_SRTERRAIN
	// grab necessary values from the VTP Scene framework
	vtScene *pScene = vtGetScene();
	vtCamera *pCamera = pScene->GetCamera();
	float nearp = pCamera->GetHither();
	float farp = pCamera->GetYon();

	float aspect = (float)m_window_size.x / m_window_size.y;

	float ex = m_eyepos_ogl.x;
	float ey = m_eyepos_ogl.y;
	float ez = m_eyepos_ogl.z;

	// Get up vector and direction vector from camera matrix
	FMatrix4 mat;
	pCamera->GetTransform1(mat);
	FPoint3 up(0.0f, 1.0f, 0.0f), eye_up;
	mat.TransformVector(up, eye_up);
	float ux = eye_up.x;
	float uy = eye_up.y;
	float uz = eye_up.z;

	FPoint3 forward(0.0f, 0.0f, -1.0f), eye_forward;
	mat.TransformVector(forward, eye_forward);
	float dx = eye_forward.x;
	float dy = eye_forward.y;
	float dz = eye_forward.z;

	myfancnt = myvtxcnt = 0;
	int size = m_iXPoints;

	// Convert to the strange origin-centered coordinate scheme of libMini.
	// This is what works best so far:
	ex-=(m_iXPoints/2)*m_fXStep;
	ez+=(m_iYPoints/2)*m_fZStep;

	m_pMini->draw(m_fResolution,
				ex, ey, ez,
				dx, dy, dz,
				ux, uy, uz,
				m_fFOVY * 1.05, aspect,		// exaggerate by 5%
				nearp, farp);

	if (myfancnt>0) glEnd();

	// We are drawing fans, so the number of triangles is roughly equal to
	// number of vertices
	m_iDrawnTriangles = myvtxcnt;

	// adaptively adjust resolution threshold up or down to attain
	// the desired polygon (vertex) count target
	int diff = m_iDrawnTriangles - m_iPolygonTarget;
	int iRange = m_iPolygonTarget / 20;		// ensure within 5%
	float adjust = 1.0f;
	if (diff < -iRange) adjust = 1.0f + (-diff * ADAPTION_SPEED);
	if (diff > iRange) adjust = 1.0f + (-diff * ADAPTION_SPEED);

	m_fResolution  *=  adjust;

	// keep the error within reasonable bounds
	if (m_fResolution < 1.0f)
		m_fResolution = 1.0f;
	if (m_fResolution > 4E7)
		m_fResolution = 4E7;
#endif
}

//
// GetLocation is called when the framework needs to know the surface
// position of the terrain at a given grid point.  Supply the height
// value from our own data structures.
//
void SRTerrain::GetLocation(int i, int j, FPoint3 &p)
{
#if ENABLE_SRTERRAIN
	p.Set(m_fXLookup[i],
		  m_pMini->getheight(i, j),
		  m_fZLookup[j]);
#endif
}

<commit_msg>tweaked comments<commit_after>//
// SRTerrain class : a subclass of vtDynTerrainGeom which exposes
//  Stefan Roettger's CLOD algorithm.
//
// utilizes: Roettger's MINI library implementation
// http://wwwvis.informatik.uni-stuttgart.de/~roettger
//
// Copyright (c) 2002 Virtual Terrain Project
// Free for all uses, see license.txt for details.
//

#include "vtlib/vtlib.h"
#include "SRTerrain.h"
#include "LocalGrid.h"

#if ENABLE_SRTERRAIN
  using namespace mini;
  #ifdef _MSC_VER
    #pragma comment( lib, "libMini.lib" )
  #endif
#endif

/////////////////////////////////////////////////////////////////////////////

//
// Constructor/destructor
//
SRTerrain::SRTerrain() : vtDynTerrainGeom()
{
	m_fResolution = 10000.0f;
}

SRTerrain::~SRTerrain()
{
}

/////////////////////////////////////////////////////////////////////////////

//
// Unfortunately the following statics are required because libMini only
// supports some functionality by callback, and the callback is only a
// simple C function which has no context to tell us which terrain.
//
static vtLocalGrid *s_pGrid;
static SRTerrain *s_pSRTerrain;
static int myfancnt, myvtxcnt;

void beginfan_vtp()
{
	if (myfancnt++>0)
		glEnd();
	glBegin(GL_TRIANGLE_FAN);
	myvtxcnt-=2;	// 2 vertices are needed to start each fan
}

void fanvertex_vtp(float x, float y, float z)
{
   glVertex3f(x,y,z);
   myvtxcnt++;
}

void notify_vtp(int i, int j, int size)
{
	// check to see if we need to switch texture
	if (s_pSRTerrain->m_iTPatchDim > 1 && size == s_pSRTerrain->m_iBlockSize)
	{
		int a = i / size;
		int b = j / size;
		s_pSRTerrain->LoadBlockMaterial(a, b);
	}
}

short int getelevation_vtp1(int i, int j, int size)
{
	return s_pGrid->GetValue(i, j);
}

float getelevation_vtp2(int i, int j, int size)
{
	return s_pGrid->GetFValue(i, j);
}

//
// Initialize the terrain data
// fZScale converts from height values (meters) to world coordinates
//
bool SRTerrain::Init(vtLocalGrid *pGrid, float fZScale,
					 float fOceanDepth, int &iError)
{
#if ENABLE_SRTERRAIN
	// Initializes necessary field of the parent class
	BasicInit(pGrid);

	m_fHeightScale = fZScale;

	int size = m_iXPoints;
	float dim = m_fXStep;
	float cellaspect = m_fZStep / m_fXStep;

	s_pGrid = pGrid;

	if (pGrid->IsFloatMode())
	{
		float *image = NULL;
		m_pMini = new ministub(image,
				&size, &dim, fZScale, cellaspect,
				beginfan_vtp, fanvertex_vtp, notify_vtp,
				getelevation_vtp2);
	}
	else
	{
		short *image = NULL;
		m_pMini = new ministub(image,
				&size, &dim, fZScale, cellaspect,
				beginfan_vtp, fanvertex_vtp, notify_vtp,
				getelevation_vtp1);
	}

	m_iDrawnTriangles = -1;
	m_iBlockSize = m_iXPoints / 4;
#endif
	return true;
}

//
// This will be called once per frame, during the culling pass.
//
// However, libMini does not allow you to call the culling pass
// independently of the rendering pass, so we cannot do it here.
//
void SRTerrain::DoCulling(FPoint3 &eyepos_ogl, IPoint2 window_size, float fov)
{
	// store for later
	m_eyepos_ogl = eyepos_ogl;
	m_window_size = window_size;
	m_fFOVY = fov * window_size.y / window_size.x * 180 / PIf;
}

void SRTerrain::DoRender()
{
	// Prepare the render state for our OpenGL usage
	PreRender();

	// Render the triangles
	RenderSurface();

	// Clean up
	PostRender();
}

void SRTerrain::LoadSingleMaterial()
{
	// single texture for the whole terrain
	vtMaterial *pMat = GetMaterial(0);
	if (pMat)
	{
		pMat->Apply();
		SetupTexGen(1.0f);
	}
}

void SRTerrain::LoadBlockMaterial(int a, int b)
{
	// we can't change the texture between glBegin/glEnd
	if (myfancnt++>0)
		glEnd();

	// each block has it's own texture map
	int appidx = a*m_iTPatchDim + (m_iTPatchDim-1-b);
	vtMaterial *pMat = GetMaterial(appidx);
	if (pMat)
	{
		pMat->Apply();
		SetupBlockTexGen(a, b);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	}

	glBegin(GL_TRIANGLE_FAN);
}

void SRTerrain::RenderSurface()
{
	s_pSRTerrain = this;

	if (m_iTPatchDim == 1)
		LoadSingleMaterial();

	RenderPass();

	// here is an example of how to do a second rendering pass
	if (m_bDetailTexture)
	{
		// once again, with the detail texture material
		m_pDetailMat->Apply();

		// the uv tiling is different (usually highly repetitive)
		SetupTexGen(m_fDetailTiling);

		// draw the second pass
		glPolygonOffset(-1.0f, -1.0f);
		glEnable(GL_POLYGON_OFFSET_FILL);
		RenderPass();
		glDisable(GL_POLYGON_OFFSET_FILL);
	}
	DisableTexGen();
}

#define ADAPTION_SPEED	.0001f	// speed at which detail converges

void SRTerrain::RenderPass()
{
#if ENABLE_SRTERRAIN
	// grab necessary values from the VTP Scene framework
	vtScene *pScene = vtGetScene();
	vtCamera *pCamera = pScene->GetCamera();
	float nearp = pCamera->GetHither();
	float farp = pCamera->GetYon();

	float aspect = (float)m_window_size.x / m_window_size.y;

	float ex = m_eyepos_ogl.x;
	float ey = m_eyepos_ogl.y;
	float ez = m_eyepos_ogl.z;

	// Get up vector and direction vector from camera matrix
	FMatrix4 mat;
	pCamera->GetTransform1(mat);
	FPoint3 up(0.0f, 1.0f, 0.0f), eye_up;
	mat.TransformVector(up, eye_up);
	float ux = eye_up.x;
	float uy = eye_up.y;
	float uz = eye_up.z;

	FPoint3 forward(0.0f, 0.0f, -1.0f), eye_forward;
	mat.TransformVector(forward, eye_forward);
	float dx = eye_forward.x;
	float dy = eye_forward.y;
	float dz = eye_forward.z;

	myfancnt = myvtxcnt = 0;
	int size = m_iXPoints;

	// Convert to the strange origin-centered coordinate scheme of libMini.
	// This is what works best so far:
	ex-=(m_iXPoints/2)*m_fXStep;
	ez+=(m_iYPoints/2)*m_fZStep;

	m_pMini->draw(m_fResolution,
				ex, ey, ez,
				dx, dy, dz,
				ux, uy, uz,
				m_fFOVY * 1.05, aspect,		// exaggerate by 5%
				nearp, farp);

	if (myfancnt>0) glEnd();

	// We are drawing fans, so the number of triangles is roughly equal to
	// number of vertices
	m_iDrawnTriangles = myvtxcnt;

	// adaptively adjust resolution threshold up or down to attain
	// the desired polygon (vertex) count target
	int diff = m_iDrawnTriangles - m_iPolygonTarget;
	int iRange = m_iPolygonTarget / 20;		// ensure within 5%
	float adjust = 1.0f;
	if (diff < -iRange) adjust = 1.0f + (-diff * ADAPTION_SPEED);
	if (diff > iRange) adjust = 1.0f + (-diff * ADAPTION_SPEED);

	m_fResolution *= adjust;

	// keep the error within reasonable bounds
	if (m_fResolution < 1.0f)
		m_fResolution = 1.0f;
	if (m_fResolution > 4E7)
		m_fResolution = 4E7;
#endif
}

//
// GetLocation is called when the framework needs to know the surface
// position of the terrain at a given grid point.  Supply the height
// value from our own data structures.
//
void SRTerrain::GetLocation(int i, int j, FPoint3 &p)
{
#if ENABLE_SRTERRAIN
	p.Set(m_fXLookup[i],
		  m_pMini->getheight(i, j),
		  m_fZLookup[j]);
#endif
}

<|endoftext|>