<commit_before>#include <stdio.h>
#include <string>
#include <vector>
#include <limits>
#include "Halide.h"

using namespace Halide;

std::vector<std::string> messages;

extern "C" void halide_print(void *user_context, const char *message) {
    //printf("%s", message);
    messages.push_back(message);
}

#ifdef _MSC_VER
#define snprintf _snprintf
#endif

int main(int argc, char **argv) {
    Var x;

    {
        Func f;

        f(x) = print(x * x, "the answer is", 42.0f, "unsigned", cast<uint32_t>(145));
        f.set_custom_print(halide_print);
        Image<int32_t> result = f.realize(10);

        for (int32_t i = 0; i < 10; i++) {
            if (result(i) != i * i) {
                return -1;
            }
        }

        assert(messages.size() == 10);
        for (size_t i = 0; i < messages.size(); i++) {
            long long square;
            float forty_two;
            unsigned long long one_forty_five;

            int scan_count = sscanf(messages[i].c_str(), "%lld the answer is %f unsigned %llu",
                                    &square, &forty_two, &one_forty_five);
            assert(scan_count == 3);
            assert(square == static_cast<long long>(i * i));
            assert(forty_two == 42.0f);
            assert(one_forty_five == 145);
        }
    }

    messages.clear();

    {
        Func f;
        Param<int> param;
        param.set(127);

        // Test a string containing a printf format specifier (It should print it as-is).
        f(x) = print_when(x == 3, x * x, "g", 42.0f, "%s", param);
        f.set_custom_print(halide_print);
        Image<int32_t> result = f.realize(10);

        for (int32_t i = 0; i < 10; i++) {
            if (result(i) != i * i) {
                return -1;
            }
        }

        assert(messages.size() == 1);
        long long nine;
        float forty_two;
        long long p;

        int scan_count = sscanf(messages[0].c_str(), "%lld g %f %%s %lld",
                                &nine, &forty_two, &p);
        assert(scan_count == 3);
        assert(nine == 9);
        assert(forty_two == 42.0f);
        assert(p == 127);

    }

    messages.clear();

    {
        Func f;

        // Test a single message longer than 8K.
        std::vector<Expr> args;
        for (int i = 0; i < 500; i++) {
            uint64_t n = i;
            n *= n;
            n *= n;
            n *= n;
            n *= n;
            n += 100;
            int32_t hi = n >> 32;
            int32_t lo = n & 0xffffffff;
            args.push_back((cast<uint64_t>(hi) << 32) | lo);
            Expr dn = cast<double>((float)(n));
            args.push_back(dn);
        }
        f(x) = print(args);
        f.set_custom_print(halide_print);
        Image<uint64_t> result = f.realize(1);

        if (result(0) != 100) {
            return -1;
        }

        assert(messages.back().size() == 8191);
    }

    messages.clear();

    // Check that Halide's stringification of floats and doubles
    // matches %f and %e respectively.

    #ifndef _MSC_VER
    // msvc's library has different ideas about how %f and %e should come out.
    {
        Func f, g;

        const int N = 1000000;

        Expr e = reinterpret(Float(32), random_int());
        // Make sure we cover some special values.
        e = select(x == 0, 0.0f,
                   x == 1, -0.0f,
                   x == 2, std::numeric_limits<float>::infinity(),
                   x == 3, -std::numeric_limits<float>::infinity(),
                   x == 4, std::numeric_limits<float>::quiet_NaN(),
                   x == 5, -std::numeric_limits<float>::quiet_NaN(),
                   e);
        e = select(x == 5, std::numeric_limits<float>::denorm_min(),
                   x == 6, -std::numeric_limits<float>::denorm_min(),
                   x == 7, std::numeric_limits<float>::min(),
                   x == 8, -std::numeric_limits<float>::min(),
                   x == 9, std::numeric_limits<float>::max(),
                   x == 10, -std::numeric_limits<float>::max(),
                   e);

        f(x) = print(e);

        f.set_custom_print(halide_print);
        Image<float> imf = f.realize(N);

        assert(messages.size() == N);

        char correct[1024];
        for (int i = 0; i < N; i++) {
            snprintf(correct, sizeof(correct), "%f\n", imf(i));
            // OS X prints -nan as nan
            #ifdef __APPLE__
            if (messages[i] == "-nan\n") messages[i] = "nan\n";
            #endif
            if (messages[i] != correct) {
                printf("float %d: %s vs %s for %10.20e\n", i, messages[i].c_str(), correct, imf(i));
                return -1;
            }
        }

        messages.clear();

        g(x) = print(reinterpret(Float(64), (cast<uint64_t>(random_int()) << 32) | random_int()));
        g.set_custom_print(halide_print);
        Image<double> img = g.realize(N);

        assert(messages.size() == N);

        for (int i = 0; i < N; i++) {
            snprintf(correct, sizeof(correct), "%e\n", img(i));
            #ifdef __APPLE__
            if (messages[i] == "-nan\n") messages[i] = "nan\n";
            #endif
            if (messages[i] != correct) {
                printf("double %d: %s vs %s for %10.20e\n", i, messages[i].c_str(), correct, img(i));
                return -1;
            }
        }

    }
    #endif

    printf("Success!\n");
    return 0;
}
<commit_msg>Fix warning<commit_after>#include <stdio.h>
#include <string>
#include <vector>
#include <limits>
#include "Halide.h"

using namespace Halide;

std::vector<std::string> messages;

extern "C" void halide_print(void *user_context, const char *message) {
    //printf("%s", message);
    messages.push_back(message);
}

#ifdef _MSC_VER
#define snprintf _snprintf
#endif

int main(int argc, char **argv) {
    Var x;

    {
        Func f;

        f(x) = print(x * x, "the answer is", 42.0f, "unsigned", cast<uint32_t>(145));
        f.set_custom_print(halide_print);
        Image<int32_t> result = f.realize(10);

        for (int32_t i = 0; i < 10; i++) {
            if (result(i) != i * i) {
                return -1;
            }
        }

        assert(messages.size() == 10);
        for (size_t i = 0; i < messages.size(); i++) {
            long long square;
            float forty_two;
            unsigned long long one_forty_five;

            int scan_count = sscanf(messages[i].c_str(), "%lld the answer is %f unsigned %llu",
                                    &square, &forty_two, &one_forty_five);
            assert(scan_count == 3);
            assert(square == static_cast<long long>(i * i));
            assert(forty_two == 42.0f);
            assert(one_forty_five == 145);
        }
    }

    messages.clear();

    {
        Func f;
        Param<int> param;
        param.set(127);

        // Test a string containing a printf format specifier (It should print it as-is).
        f(x) = print_when(x == 3, x * x, "g", 42.0f, "%s", param);
        f.set_custom_print(halide_print);
        Image<int32_t> result = f.realize(10);

        for (int32_t i = 0; i < 10; i++) {
            if (result(i) != i * i) {
                return -1;
            }
        }

        assert(messages.size() == 1);
        long long nine;
        float forty_two;
        long long p;

        int scan_count = sscanf(messages[0].c_str(), "%lld g %f %%s %lld",
                                &nine, &forty_two, &p);
        assert(scan_count == 3);
        assert(nine == 9);
        assert(forty_two == 42.0f);
        assert(p == 127);

    }

    messages.clear();

    {
        Func f;

        // Test a single message longer than 8K.
        std::vector<Expr> args;
        for (int i = 0; i < 500; i++) {
            uint64_t n = i;
            n *= n;
            n *= n;
            n *= n;
            n *= n;
            n += 100;
            int32_t hi = n >> 32;
            int32_t lo = n & 0xffffffff;
            args.push_back((cast<uint64_t>(hi) << 32) | lo);
            Expr dn = cast<double>((float)(n));
            args.push_back(dn);
        }
        f(x) = print(args);
        f.set_custom_print(halide_print);
        Image<uint64_t> result = f.realize(1);

        if (result(0) != 100) {
            return -1;
        }

        assert(messages.back().size() == 8191);
    }

    messages.clear();

    // Check that Halide's stringification of floats and doubles
    // matches %f and %e respectively.

    #ifndef _MSC_VER
    // msvc's library has different ideas about how %f and %e should come out.
    {
        Func f, g;

        const int N = 1000000;

        Expr e = reinterpret(Float(32), random_int());
        // Make sure we cover some special values.
        e = select(x == 0, 0.0f,
                   x == 1, -0.0f,
                   x == 2, std::numeric_limits<float>::infinity(),
                   x == 3, -std::numeric_limits<float>::infinity(),
                   x == 4, std::numeric_limits<float>::quiet_NaN(),
                   x == 5, -std::numeric_limits<float>::quiet_NaN(),
                   e);
        e = select(x == 5, std::numeric_limits<float>::denorm_min(),
                   x == 6, -std::numeric_limits<float>::denorm_min(),
                   x == 7, std::numeric_limits<float>::min(),
                   x == 8, -std::numeric_limits<float>::min(),
                   x == 9, std::numeric_limits<float>::max(),
                   x == 10, -std::numeric_limits<float>::max(),
                   e);

        f(x) = print(e);

        f.set_custom_print(halide_print);
        Image<float> imf = f.realize(N);

        assert(messages.size() == (size_t)N);

        char correct[1024];
        for (int i = 0; i < N; i++) {
            snprintf(correct, sizeof(correct), "%f\n", imf(i));
            // OS X prints -nan as nan
            #ifdef __APPLE__
            if (messages[i] == "-nan\n") messages[i] = "nan\n";
            #endif
            if (messages[i] != correct) {
                printf("float %d: %s vs %s for %10.20e\n", i, messages[i].c_str(), correct, imf(i));
                return -1;
            }
        }

        messages.clear();

        g(x) = print(reinterpret(Float(64), (cast<uint64_t>(random_int()) << 32) | random_int()));
        g.set_custom_print(halide_print);
        Image<double> img = g.realize(N);

        assert(messages.size() == (size_t)N);

        for (int i = 0; i < N; i++) {
            snprintf(correct, sizeof(correct), "%e\n", img(i));
            #ifdef __APPLE__
            if (messages[i] == "-nan\n") messages[i] = "nan\n";
            #endif
            if (messages[i] != correct) {
                printf("double %d: %s vs %s for %10.20e\n", i, messages[i].c_str(), correct, img(i));
                return -1;
            }
        }

    }
    #endif

    printf("Success!\n");
    return 0;
}
<|endoftext|>


<commit_before>/*
Copyright(c) Microsoft Open Technologies, Inc. All rights reserved.

The MIT License(MIT)

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions :

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

#include "pch.h"
#include "Util.h"
#include <Windows.h>
#include <filesystem>
#include <sstream>
#include "unzip.h"
#include <direct.h>

#define WRITEBUFFERSIZE 8192
#define NODE_MODULE_MAX_PATH 1024
#define MD5HASHSIZE 16

using namespace Platform;
using namespace std::tr2::sys;
using namespace concurrency;

namespace nodeuwputil
{
	shared_ptr<char> WCharToChar(const wchar_t* str, int strSize)
	{
		// Calculate the needed buffer size
		DWORD bufferSize = WideCharToMultiByte(CP_UTF8,
			0,
			str,
			strSize,
			nullptr,
			0,
			nullptr,
			nullptr);

		if (bufferSize == 0)
		{
			throw ref new ::Platform::Exception(GetLastError(), L"nodeuwputil::WCharToChar failed");
		}

		shared_ptr<char> buffer(new char[bufferSize + 1], [](char* ptr) { delete[] ptr; });
		buffer.get()[bufferSize] = '\0';
		// Do the actual conversion
		WideCharToMultiByte(CP_UTF8,
			0,
			str,
			strSize,
			buffer.get(),
			bufferSize,
			nullptr,
			nullptr);

		return buffer;
	}

	shared_ptr<wchar_t> CharToWChar(const char* str, int strSize)
	{
		// Calculate the needed buffer size
		DWORD bufferSize = MultiByteToWideChar(CP_UTF8,
			0,
			str,
			strSize,
			nullptr,
			0);

		if (bufferSize == 0)
		{
			throw ref new ::Platform::Exception(GetLastError(), L"nodeuwputil::CharToWChar failed");
		}

		shared_ptr<wchar_t> buffer(new wchar_t[bufferSize + 1], [](wchar_t* ptr) { delete[] ptr; });
		buffer.get()[bufferSize] = '\0';
		// Do the actual conversion
		MultiByteToWideChar(CP_UTF8,
			0,
			str,
			strSize,
			buffer.get(),
			bufferSize);

		return buffer;
	}

	void PopulateArgsVector(vector<shared_ptr<char>> &argVector,
		String^ startStr, bool &useLogger)
	{
		if (startStr != nullptr)
		{
			wstring localFolder(ApplicationData::Current->LocalFolder->Path->Data());
			localFolder.append(L"\\");
			wstring args(startStr->Data());
			args.erase(0, args.find_first_not_of(L" \n\r\t")); // Trim leading whitespace
			wstring arg;
			shared_ptr<char> in;
			bool insert = false;
			bool scriptFound = false;

			for (size_t i = 0; i < args.length(); i++) {

				wchar_t c = args[i];
				if (c == ' ')
				{
					insert = true;
				}
				else if (c == '\"')
				{
					i++;
					while (args[i] != '\"' && i < args.size())
					{
						arg += args[i];
						i++;
					}
					i++;
					insert = true;
				}
				else
				{
					arg += args[i];
				}

				// We insert an argument into the vector if we see a space or we've reached the
				// end of the string.
				if ((insert == true || args.size() - 1 == i) && arg.size() != 0)
				{
					insert = false;

					// 'node' will usually be the first argument if the package.json file is also
					// used with the console version of node. We'll ignore it if it exists.
					if (_wcsicmp(arg.c_str(), L"node") == 0 && argVector.size() == 1)
					{
						arg.clear();
						continue;
					}

					// Update the script path.
					// The script to start will be the first argument that doesn't start with '-'.
					// Node usage: node [options] [v8 options] [script.js | -e "script"] [arguments]
					// 'options' and 'v8 options' start with '-'
					if (arg[0] != '-' && scriptFound == false)
					{
						scriptFound = true;
						arg = localFolder + arg;
					}

					if (arg.compare(L"--use-logger") == 0)
					{
						useLogger = true;
						arg.clear();
						continue;
					}

					in = WCharToChar(arg.c_str(), arg.size());
					argVector.push_back(in);
					arg.clear();
				}
			}
		}
	}

	void CopyFolderSync(StorageFolder^ source, StorageFolder^ destination)
	{
		path from(source->Path->Data());
		path to(destination->Path->Data());
		copy_options opts = copy_options::recursive | copy_options::overwrite_existing;
		copy(from, to, opts);
	}

	int MakePath(String^ newDir)
	{
		wstring newdir(newDir->Data());
		vector<String^> subdirs;
		wchar_t *nextTok = NULL;
		StorageFolder^ storagefolder;

		wchar_t* tok = wcstok_s((wchar_t*)newDir->Data(), L"\\", &nextTok);

		while (tok != NULL)
		{
			subdirs.push_back(ref new String(tok));
			tok = wcstok_s(NULL, L"\\", &nextTok);
		}

		// Walk the path until we get a valid StorageFolder object.
		// This function will fail if path provided isn't abosolute.
		// In future if needed this can be modified.
		newDir = subdirs.at(0);
		subdirs.erase(subdirs.begin());
		vector<String^>::iterator it = subdirs.begin();

		for (; it != subdirs.end(); ++it)
		{
			newDir = newDir + "\\" + *it;

			try
			{
				storagefolder = create_task(StorageFolder::GetFolderFromPathAsync(newDir)).get();
				break;
			}
			catch (Exception^ e)
			{
				if (e->HResult != HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED))
				{
					throw;
				}
				else
				{
					continue;
				}
			}

		}

		if (storagefolder == nullptr)
		{
			return UNZ_INTERNALERROR;
		}

		// Create the folders that don't exist
		advance(it, 1);
		for (; it != subdirs.end(); ++it)
		{
			String^ temp = *it;
			try
			{
				storagefolder = create_task(storagefolder->CreateFolderAsync(*it)).get();
			}
			catch (Exception^ e)
			{
				if (e->HResult != HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS))
				{
					throw;
				}
				else
				{
					storagefolder = create_task(storagefolder->GetFolderAsync(*it)).get();
				}
			}
		}
	}

	// Based on https://github.com/ms-iot/node/blob/chakra-uwp/deps/zlib/contrib/minizip/miniunz.c#L312
	int DoExtractCurrentfile(unzFile uf, String^ dest)
	{
		char filename_inzip[NODE_MODULE_MAX_PATH];
		char* filename_withoutpath;
		char* p;
		FILE *fout = NULL;
		unz_file_info64 file_info;
		uLong ratio = 0;

		int err = unzGetCurrentFileInfo64(uf, &file_info, filename_inzip, sizeof(filename_inzip), NULL, 0, NULL, 0);
		if (err != UNZ_OK)
		{
			return err;
		}

		// Prepend the destination to the path (filename_inzip)
		char temp[NODE_MODULE_MAX_PATH];
		strcpy_s(temp, NODE_MODULE_MAX_PATH, filename_inzip);
		strcpy_s(filename_inzip, NODE_MODULE_MAX_PATH, WCharToChar(dest->Data(), dest->Length()).get());
		strcat_s(filename_inzip, NODE_MODULE_MAX_PATH, "\\");
		strcat_s(filename_inzip, NODE_MODULE_MAX_PATH, temp);

		p = filename_withoutpath = filename_inzip;
		while ((*p) != '\0')
		{
			if (((*p) == '/') || ((*p) == '\\'))
			{
				filename_withoutpath = p + 1;
			}
			p++;
		}

		if ((*filename_withoutpath) == '\0')
		{
			err = _mkdir(filename_inzip);
			if (0 != err)
			{
				return err;
			}
		}
		else
		{
			const char* write_filename = filename_inzip;

			// Needs to be called even when zip has no password
			err = unzOpenCurrentFilePassword(uf, 0);
			if (err == UNZ_OK)
			{
				fopen_s(&fout, write_filename, "wb");
				/* some zipfile don't contain directory alone before file */
				if ((fout == NULL) && (filename_withoutpath != (char*)filename_inzip))
				{
					char c = *(filename_withoutpath - 1);
					*(filename_withoutpath - 1) = '\0';
					MakePath(ref new String(CharToWChar(write_filename, sizeof(filename_inzip)).get()));
					*(filename_withoutpath - 1) = c;
					fopen_s(&fout, write_filename, "wb");
				}
			}

			if (fout != NULL)
			{
				shared_ptr<byte> buf(new byte[WRITEBUFFERSIZE], [](byte* ptr) { delete[] ptr; });

				do
				{
					err = unzReadCurrentFile(uf, buf.get(), WRITEBUFFERSIZE);
					if (err < 0)
					{
						break;
					}
					if (err > 0)
					{
						if (fwrite(buf.get(), err, 1, fout) != 1)
						{
							err = UNZ_ERRNO;
							break;
						}
					}
				}
				while (err > 0);

				if (fout)
				{
					fclose(fout);
				}

			}

			if (err == UNZ_OK)
			{
				err = unzCloseCurrentFile(uf);
			}
			else
			{
				unzCloseCurrentFile(uf); /* don't lose the error */
			}
		}

		return err;
	}

	// Based on https://github.com/ms-iot/node/blob/chakra-uwp/deps/zlib/contrib/minizip/miniunz.c#L475
	int DoExtract(unzFile uf, String^ dest)
	{
		unz_global_info64 gi;

		int err = unzGetGlobalInfo64(uf, &gi);
		if (err != UNZ_OK)
		{
			throw ref new ::Platform::Exception(err, L"nodeuwputil::DoExtract unzGetGlobalInfo failed");
		}

		for (uLong i = 0; i < gi.number_entry; i++)
		{
			err = DoExtractCurrentfile(uf, dest);
			if (err != UNZ_OK)
			{
				return err;
			}

			if ((i + 1) < gi.number_entry)
			{
				err = unzGoToNextFile(uf);
				if (err != UNZ_OK)
				{
					return err;
				}
			}
		}

		return err;
	}

	int CompareHashFiles(char* file1, int file1Size, char* file2, int file2Size, bool& isEqual)
	{
		FILE* f1 = NULL;
		FILE* f2 = NULL;
		int err;
		isEqual = false;

		err = fopen_s(&f1, file1, "r");
		if (err != 0)
		{
			return err;
		}

		err = fopen_s(&f2, file2, "r");
		if (err != 0)
		{
			if (f1)
			{
				fclose(f1);
			}
			return err;
		}

		char b1[MD5HASHSIZE];
		char b2[MD5HASHSIZE];

		int bytesRead = fread(b1, 1, MD5HASHSIZE, f1);
		if (bytesRead != MD5HASHSIZE)
		{
			err = UNZ_INTERNALERROR;
		}
		else
		{
			bytesRead = fread(b2, 1, MD5HASHSIZE, f2);
			if (bytesRead != MD5HASHSIZE)
			{
				err = UNZ_INTERNALERROR;
			}
			else
			{
				if (0 == memcmp(b1, b2, MD5HASHSIZE))
				{
					isEqual = true;
				}
			}
		}

		if (f1)
		{
			fclose(f1);
		}
		if (f2)
		{
			fclose(f2);
		}
		return err;
	}

	bool ModuleUpdateRequired()
	{
		StorageFolder^ appFolder = Windows::ApplicationModel::Package::Current->InstalledLocation;
		StorageFolder^ localFolder = ApplicationData::Current->LocalFolder;

		String^ currHashFile;
		bool hashesAreEqual;
		int err;

		try
		{
			currHashFile = create_task(localFolder->GetFileAsync("node_modules.hash")).get()->Path;
		}
		catch (Exception^ e)
		{
			if (e->HResult != HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND))
			{
				throw;
			}
			else
			{
				return true;
			}
		}

		String^ newHashFile = create_task(appFolder->GetFileAsync("node_modules.hash")).get()->Path;

		err = CompareHashFiles(WCharToChar(newHashFile->Data(), newHashFile->Length()).get(), newHashFile->Length(),
			WCharToChar(currHashFile->Data(), currHashFile->Length()).get(), currHashFile->Length(), hashesAreEqual);

		if (err != UNZ_OK)
		{
			return false;
		}
		else
		{
			if (hashesAreEqual)
			{
				// No update required if the hashes match
				return false;
			}
			else
			{
				return true;
			}
		}
	}

	void Extract(StorageFile^ zipFile, String^ destination)
	{
		shared_ptr<char> zipFileCharStr = WCharToChar(zipFile->Path->Data(), zipFile->Path->Length());
		unzFile uf = unzOpen64(zipFileCharStr.get());
		int err;

		if (uf)
		{
			err = DoExtract(uf, destination);

			unzClose(uf);

			if (err != UNZ_OK)
			{
				throw ref new ::Platform::Exception(err, L"nodeuwputil::Extract error");
			}
		}
		else
		{
			throw ref new ::Platform::Exception(ERROR_INVALID_PARAMETER, L"nodeuwputil::Extract Invalid zip file");
		}
	}
}
<commit_msg>Rolling back to win32 implementation of MakePath<commit_after>/*
Copyright(c) Microsoft Open Technologies, Inc. All rights reserved.

The MIT License(MIT)

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions :

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

#include "pch.h"
#include "Util.h"
#include <Windows.h>
#include <filesystem>
#include <sstream>
#include "unzip.h"
#include <direct.h>

#define WRITEBUFFERSIZE 8192
#define NODE_MODULE_MAX_PATH 1024
#define MD5HASHSIZE 16

using namespace Platform;
using namespace std::tr2::sys;
using namespace concurrency;

namespace nodeuwputil
{
	shared_ptr<char> WCharToChar(const wchar_t* str, int strSize)
	{
		// Calculate the needed buffer size
		DWORD bufferSize = WideCharToMultiByte(CP_UTF8,
			0,
			str,
			strSize,
			nullptr,
			0,
			nullptr,
			nullptr);

		if (bufferSize == 0)
		{
			throw ref new ::Platform::Exception(GetLastError(), L"nodeuwputil::WCharToChar failed");
		}

		shared_ptr<char> buffer(new char[bufferSize + 1], [](char* ptr) { delete[] ptr; });
		buffer.get()[bufferSize] = '\0';
		// Do the actual conversion
		WideCharToMultiByte(CP_UTF8,
			0,
			str,
			strSize,
			buffer.get(),
			bufferSize,
			nullptr,
			nullptr);

		return buffer;
	}

	shared_ptr<wchar_t> CharToWChar(const char* str, int strSize)
	{
		// Calculate the needed buffer size
		DWORD bufferSize = MultiByteToWideChar(CP_UTF8,
			0,
			str,
			strSize,
			nullptr,
			0);

		if (bufferSize == 0)
		{
			throw ref new ::Platform::Exception(GetLastError(), L"nodeuwputil::CharToWChar failed");
		}

		shared_ptr<wchar_t> buffer(new wchar_t[bufferSize + 1], [](wchar_t* ptr) { delete[] ptr; });
		buffer.get()[bufferSize] = '\0';
		// Do the actual conversion
		MultiByteToWideChar(CP_UTF8,
			0,
			str,
			strSize,
			buffer.get(),
			bufferSize);

		return buffer;
	}

	void PopulateArgsVector(vector<shared_ptr<char>> &argVector,
		String^ startStr, bool &useLogger)
	{
		if (startStr != nullptr)
		{
			wstring localFolder(ApplicationData::Current->LocalFolder->Path->Data());
			localFolder.append(L"\\");
			wstring args(startStr->Data());
			args.erase(0, args.find_first_not_of(L" \n\r\t")); // Trim leading whitespace
			wstring arg;
			shared_ptr<char> in;
			bool insert = false;
			bool scriptFound = false;

			for (size_t i = 0; i < args.length(); i++) {

				wchar_t c = args[i];
				if (c == ' ')
				{
					insert = true;
				}
				else if (c == '\"')
				{
					i++;
					while (args[i] != '\"' && i < args.size())
					{
						arg += args[i];
						i++;
					}
					i++;
					insert = true;
				}
				else
				{
					arg += args[i];
				}

				// We insert an argument into the vector if we see a space or we've reached the
				// end of the string.
				if ((insert == true || args.size() - 1 == i) && arg.size() != 0)
				{
					insert = false;

					// 'node' will usually be the first argument if the package.json file is also
					// used with the console version of node. We'll ignore it if it exists.
					if (_wcsicmp(arg.c_str(), L"node") == 0 && argVector.size() == 1)
					{
						arg.clear();
						continue;
					}

					// Update the script path.
					// The script to start will be the first argument that doesn't start with '-'.
					// Node usage: node [options] [v8 options] [script.js | -e "script"] [arguments]
					// 'options' and 'v8 options' start with '-'
					if (arg[0] != '-' && scriptFound == false)
					{
						scriptFound = true;
						arg = localFolder + arg;
					}

					if (arg.compare(L"--use-logger") == 0)
					{
						useLogger = true;
						arg.clear();
						continue;
					}

					in = WCharToChar(arg.c_str(), arg.size());
					argVector.push_back(in);
					arg.clear();
				}
			}
		}
	}

	void CopyFolderSync(StorageFolder^ source, StorageFolder^ destination)
	{
		path from(source->Path->Data());
		path to(destination->Path->Data());
		copy_options opts = copy_options::recursive | copy_options::overwrite_existing;
		copy(from, to, opts);
	}

	// Based on https://github.com/ms-iot/node/blob/chakra-uwp/deps/zlib/contrib/minizip/miniunz.c#L138
	int MakePath(char* newdir, int len)
	{
		char *buffer;
		char *p;

		if (len <= 0)
		{
			return 0;
		}

		buffer = (char*)malloc(len + 1);
		if (buffer == NULL)
		{
			return UNZ_INTERNALERROR;
		}
		strcpy_s(buffer, len, newdir);

		if (buffer[len - 1] == '/') {
			buffer[len - 1] = '\0';
		}
		if (_mkdir(buffer) == 0)
		{
			free(buffer);
			return 1;
		}

		p = buffer + 1;
		while (1)
		{
			char hold;

			while (*p && *p != '\\' && *p != '/')
				p++;
			hold = *p;
			*p = 0;
			if ((_mkdir(buffer) == -1) && (errno == ENOENT))
			{
				free(buffer);
				return 0;
			}
			if (hold == 0)
				break;
			*p++ = hold;
		}
		free(buffer);
		return 1;
	}

	// Based on https://github.com/ms-iot/node/blob/chakra-uwp/deps/zlib/contrib/minizip/miniunz.c#L312
	int DoExtractCurrentfile(unzFile uf, String^ dest)
	{
		char filename_inzip[NODE_MODULE_MAX_PATH];
		char* filename_withoutpath;
		char* p;
		FILE *fout = NULL;
		unz_file_info64 file_info;
		uLong ratio = 0;

		int err = unzGetCurrentFileInfo64(uf, &file_info, filename_inzip, sizeof(filename_inzip), NULL, 0, NULL, 0);
		if (err != UNZ_OK)
		{
			return err;
		}

		// Prepend the destination to the path (filename_inzip)
		char temp[NODE_MODULE_MAX_PATH];
		strcpy_s(temp, NODE_MODULE_MAX_PATH, filename_inzip);
		strcpy_s(filename_inzip, NODE_MODULE_MAX_PATH, WCharToChar(dest->Data(), dest->Length()).get());
		strcat_s(filename_inzip, NODE_MODULE_MAX_PATH, "\\");
		strcat_s(filename_inzip, NODE_MODULE_MAX_PATH, temp);

		p = filename_withoutpath = filename_inzip;
		while ((*p) != '\0')
		{
			if (((*p) == '/') || ((*p) == '\\'))
			{
				filename_withoutpath = p + 1;
			}
			p++;
		}

		if ((*filename_withoutpath) == '\0')
		{
			_mkdir(filename_inzip);
		}
		else
		{
			const char* write_filename = filename_inzip;

			// Needs to be called even when zip has no password
			err = unzOpenCurrentFilePassword(uf, 0);
			if (err == UNZ_OK)
			{
				fopen_s(&fout, write_filename, "wb");
				/* some zipfile don't contain directory alone before file */
				if ((fout == NULL) && (filename_withoutpath != (char*)filename_inzip))
				{
					char c = *(filename_withoutpath - 1);
					*(filename_withoutpath - 1) = '\0';
					MakePath(filename_inzip, sizeof(filename_inzip));
					*(filename_withoutpath - 1) = c;
					fopen_s(&fout, write_filename, "wb");
				}
			}

			if (fout != NULL)
			{
				shared_ptr<byte> buf(new byte[WRITEBUFFERSIZE], [](byte* ptr) { delete[] ptr; });

				do
				{
					err = unzReadCurrentFile(uf, buf.get(), WRITEBUFFERSIZE);
					if (err < 0)
					{
						break;
					}
					if (err > 0)
					{
						if (fwrite(buf.get(), err, 1, fout) != 1)
						{
							err = UNZ_ERRNO;
							break;
						}
					}
				}
				while (err > 0);

				if (fout)
				{
					fclose(fout);
				}

			}

			if (err == UNZ_OK)
			{
				err = unzCloseCurrentFile(uf);
			}
			else
			{
				unzCloseCurrentFile(uf); /* don't lose the error */
			}
		}

		return err;
	}

	// Based on https://github.com/ms-iot/node/blob/chakra-uwp/deps/zlib/contrib/minizip/miniunz.c#L475
	int DoExtract(unzFile uf, String^ dest)
	{
		unz_global_info64 gi;

		int err = unzGetGlobalInfo64(uf, &gi);
		if (err != UNZ_OK)
		{
			throw ref new ::Platform::Exception(err, L"nodeuwputil::DoExtract unzGetGlobalInfo failed");
		}

		for (uLong i = 0; i < gi.number_entry; i++)
		{
			if (DoExtractCurrentfile(uf, dest) != UNZ_OK)
			{
				break;
			}

			if ((i + 1) < gi.number_entry)
			{
				if (unzGoToNextFile(uf) != UNZ_OK)
				{
					break;
				}
			}
		}

		return 0;
	}

	int CompareHashFiles(char* file1, int file1Size, char* file2, int file2Size, bool& isEqual)
	{
		FILE* f1 = NULL;
		FILE* f2 = NULL;
		int err;
		isEqual = false;

		err = fopen_s(&f1, file1, "r");
		if (err != 0)
		{
			return err;
		}

		err = fopen_s(&f2, file2, "r");
		if (err != 0)
		{
			if (f1)
			{
				fclose(f1);
			}
			return err;
		}

		char b1[MD5HASHSIZE];
		char b2[MD5HASHSIZE];

		int bytesRead = fread(b1, 1, MD5HASHSIZE, f1);
		if (bytesRead != MD5HASHSIZE)
		{
			err = UNZ_INTERNALERROR;
		}
		else
		{
			bytesRead = fread(b2, 1, MD5HASHSIZE, f2);
			if (bytesRead != MD5HASHSIZE)
			{
				err = UNZ_INTERNALERROR;
			}
			else
			{
				if (0 == memcmp(b1, b2, MD5HASHSIZE))
				{
					isEqual = true;
				}
			}
		}

		if (f1)
		{
			fclose(f1);
		}
		if (f2)
		{
			fclose(f2);
		}
		return err;
	}

	bool ModuleUpdateRequired()
	{
		StorageFolder^ appFolder = Windows::ApplicationModel::Package::Current->InstalledLocation;
		StorageFolder^ localFolder = ApplicationData::Current->LocalFolder;

		String^ currHashFile;
		bool hashesAreEqual;
		int err;

		try
		{
			currHashFile = create_task(localFolder->GetFileAsync("node_modules.hash")).get()->Path;
		}
		catch (Exception^ e)
		{
			if (e->HResult != HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND))
			{
				throw;
			}
			else
			{
				return true;
			}
		}

		String^ newHashFile = create_task(appFolder->GetFileAsync("node_modules.hash")).get()->Path;

		err = CompareHashFiles(WCharToChar(newHashFile->Data(), newHashFile->Length()).get(), newHashFile->Length(),
			WCharToChar(currHashFile->Data(), currHashFile->Length()).get(), currHashFile->Length(), hashesAreEqual);

		if (err != UNZ_OK)
		{
			return false;
		}
		else
		{
			if (hashesAreEqual)
			{
				// No update required if the hashes match
				return false;
			}
			else
			{
				return true;
			}
		}
	}

	void Extract(StorageFile^ zipFile, String^ destination)
	{
		shared_ptr<char> zipFileCharStr = WCharToChar(zipFile->Path->Data(), zipFile->Path->Length());
		unzFile uf = unzOpen64(zipFileCharStr.get());
		int err;

		if (uf)
		{
			err = DoExtract(uf, destination);

			unzClose(uf);

			if (err != UNZ_OK)
			{
				throw ref new ::Platform::Exception(err, L"nodeuwputil::Extract error");
			}
		}
		else
		{
			throw ref new ::Platform::Exception(ERROR_INVALID_PARAMETER, L"nodeuwputil::Extract Invalid zip file");
		}
	}
}
<|endoftext|>


<commit_before>#include<iostream>
using namespace std;

//   Creating a NODE Structure
struct node
{
    int data;
    struct node *next;
};

// Creating a class STACK
class stack
{
    struct node *top;
    public:
    stack() // constructure
    {
        top=NULL;
    }
    void push(); // to insert an element
    void pop();  // to delete an element
    void show(); // to show the stack
};
// PUSH Operation
void stack::push()
{
    int value;
    struct node *ptr;
    cout<<"\nPUSH Operationn";
    cout<<"Enter a number to insert: ";
    cin>>value;
    ptr=new node;
    ptr->data=value;
    ptr->next=NULL;
    if(top!=NULL)
        ptr->next=top;
    top=ptr;
    cout<<"\nNew item is inserted to the stack!!!";

}

// POP Operation
void stack::pop()
{
    struct node *temp;
    if(top==NULL)
    {
        cout<<"\nThe stack is empty!!!";
    }
    temp=top;
    top=top->next;
    cout<<"\nPOP Operation........nPoped value is "<<temp->data;
    delete temp;
}

// Show stack
void stack::show()
{
    struct node *ptr1=top;
    cout<<"\nThe stack is\n";
    while(ptr1!=NULL)
    {
        cout<<ptr1->data<<" ->";
        ptr1=ptr1->next;
    }
    cout<<"NULL\n";
}

// Main function
int main()
{
    stack s;
    int choice;
    while(1)
    {
        cout<<"\n-----------------------------------------------------------";
        cout<<"\n\t\tSTACK USING LINKED LIST\n\n";
        cout<<"1:PUSH\n2:POP\n3:DISPLAY STACK\n4:EXIT";
        cout<<"\nEnter your choice(1-4): ";
        cin>>choice;
        switch(choice)
        {
            case 1:
                s.push();
                break;
            case 2:
                s.pop();
                break;
            case 3:
                s.show();
                break;
            case 4:
                return 0;
                break;
            default:
                cout<<"\nPlease enter correct choice(1-4)!!";
                break;
        }
    }
    return 0;
}<commit_msg>fixes #1 core dump in pop operation<commit_after>#include<iostream>
using namespace std;

//   Creating a NODE Structure
struct node
{
    int data;
    struct node *next;
};

// Creating a class STACK
class stack
{
    struct node *top;
    public:
    stack() // constructure
    {
        top=NULL;
    }
    void push(); // to insert an element
    void pop();  // to delete an element
    void show(); // to show the stack
};
// PUSH Operation
void stack::push()
{
    int value;
    struct node *ptr;
    cout<<"\nPUSH Operation\n";
    cout<<"Enter a number to insert: ";
    cin>>value;
    ptr=new node;
    ptr->data=value;
    ptr->next=NULL;
    if(top!=NULL)
        ptr->next=top;
    top=ptr;
    cout<<"\nNew item is inserted to the stack!!!";

}

// POP Operation
void stack::pop()
{
    struct node *temp;
    if(top==NULL)
    {
        cout<<"\nThe stack is empty!!!";
    }else{
        temp=top;
    top=top->next;
    cout<<"\nPOP Operation........nPoped value is "<<temp->data;
    delete temp;
    }
}

// Show stack
void stack::show()
{
    struct node *ptr1=top;
    cout<<"\nThe stack is\n";
    while(ptr1!=NULL)
    {
        cout<<ptr1->data<<" ->";
        ptr1=ptr1->next;
    }
    cout<<"NULL\n";
}

// Main function
int main()
{
    stack s;
    int choice;
    while(1)
    {
        cout<<"\n-----------------------------------------------------------";
        cout<<"\n\t\tSTACK USING LINKED LIST\n\n";
        cout<<"1:PUSH\n2:POP\n3:DISPLAY STACK\n4:EXIT";
        cout<<"\nEnter your choice(1-4): ";
        cin>>choice;
        switch(choice)
        {
            case 1:
                s.push();
                break;
            case 2:
                s.pop();
                break;
            case 3:
                s.show();
                break;
            case 4:
                return 0;
                break;
            default:
                cout<<"\nPlease enter correct choice(1-4)!!";
                break;
        }
    }
    return 0;
}<|endoftext|>


<commit_before>/**************************************************************************
 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

/*
$Log: AliT0Preprocessor.cxx,v $
Revision 1.8  2007/12/07 15:22:51  alla
bug fixed by Alberto

Revision 1.7  2007/12/06 16:35:24  alla
new bugs fixed by Tomek

Revision 1.5  2007/11/23 19:28:52  alla
bug fixed

Version 2.1  2007/11/21
Preprocessor storing data to OCDB (T.Malkiewicz)

Version 1.1  2006/10
Preliminary test version (T.Malkiewicz)
*/
// T0 preprocessor:
// 1) takes data from DCS and passes it to the class AliTOFDataDCS
// for processing and writes the result to the Reference DB.
// 2) takes data form DAQ (both from Laser Calibration and Physics runs),
// processes it, and stores either to OCDB or to Reference DB.

#include "AliT0Preprocessor.h"
#include "AliT0DataDCS.h"
#include "AliT0CalibWalk.h"
#include "AliT0CalibTimeEq.h"

#include "AliCDBMetaData.h"
#include "AliDCSValue.h"
#include "AliLog.h"

#include <TTimeStamp.h>
#include <TFile.h>
#include <TObjString.h>
#include <TNamed.h>
#include "AliT0Dqclass.h"

ClassImp(AliT0Preprocessor)

//____________________________________________________
AliT0Preprocessor::AliT0Preprocessor(AliShuttleInterface* shuttle) :
  AliPreprocessor("T00", shuttle),
  fData(0)
{
  //constructor
  AddRunType("PHYSICS");
  AddRunType("STANDALONE");
}
//____________________________________________________

AliT0Preprocessor::~AliT0Preprocessor()
{
  //destructor
  delete fData;
  fData = 0;
}
//____________________________________________________

void AliT0Preprocessor::Initialize(Int_t run, UInt_t startTime, UInt_t endTime)
{
  // Creates AliT0DataDCS object
  AliPreprocessor::Initialize(run, startTime, endTime);
  AliInfo(Form("\n\tRun %d \n\tStartTime %s \n\tEndTime %s", run, TTimeStamp(startTime).AsString(), TTimeStamp(endTime).AsString()));
  fData = new AliT0DataDCS(fRun, fStartTime, fEndTime);
}
//____________________________________________________

Bool_t AliT0Preprocessor::ProcessDCS(){
	// Check whether DCS should be processed or not...
	TString runType = GetRunType();
	Log(Form("ProcessDCS - RunType: %s",runType.Data()));

	if((runType == "STANDALONE")||(runType == "PHYSICS")){
	  //		return kFALSE;
		return kTRUE;
	}else{
	return kFALSE;
	}
}
//____________________________________________________

UInt_t AliT0Preprocessor::ProcessDCSDataPoints(TMap* dcsAliasMap){
	// Fills data into AliT0DataDCS object
	Log("Processing DCS DP");
	Bool_t resultDCSMap=kFALSE;
	Bool_t resultDCSStore=kFALSE;

        if(!dcsAliasMap)
        {
          Log("No DCS input data");
          return 1;
        }
        else
        {
          resultDCSMap=fData->ProcessData(*dcsAliasMap);
          if(!resultDCSMap)
          {
            Log("Error when processing DCS data");
            return 2;// return error Code for processed DCS data not stored
          }
          else
          {
            AliCDBMetaData metaDataDCS;
            metaDataDCS.SetBeamPeriod(0);
            metaDataDCS.SetResponsible("Tomasz Malkiewicz");
            metaDataDCS.SetComment("This preprocessor fills an AliTODataDCS object.");
            AliInfo("Storing DCS Data");
            resultDCSStore = StoreReferenceData("Calib","DCSData",fData, &metaDataDCS);
            if (!resultDCSStore)
            {
              Log("Some problems occurred while storing DCS data results in ReferenceDB");
              return 2;// return error Code for processed DCS data not stored
            }
          }
        }
	return 0;
}
//____________________________________________________

UInt_t AliT0Preprocessor::ProcessLaser(){
	// Processing data from DAQ Standalone run
	Log("Processing Laser calibration - Walk Correction");

	Bool_t resultLaser=kFALSE;
	//processing DAQ
        TList* list = GetFileSources(kDAQ, "LASER");
        if (list)
        {
            TIter iter(list);
            TObjString *source;
            while ((source = dynamic_cast<TObjString *> (iter.Next())))
            {
              const char *laserFile = GetFile(kDAQ, "LASER", source->GetName());
              if (laserFile)
              {
                Log(Form("File with Id LASER found in source %s!", source->GetName()));
                AliT0CalibWalk *laser = new AliT0CalibWalk();
                laser->MakeWalkCorrGraph(laserFile);
                AliCDBMetaData metaData;
                metaData.SetBeamPeriod(0);
                metaData.SetResponsible("Tomek&Michal");
                metaData.SetComment("Walk correction from laser runs.");
		resultLaser=Store("Calib","Slewing_Walk", laser, &metaData, 0, 1);
                delete laser;
		Log(Form("resultLaser = %d",resultLaser));
              }
              else
              {
                Log(Form("Could not find file with Id LASER in source %s!", source->GetName()));
                return 1;
              }
            }
            if (!resultLaser)
            {
              Log("No Laser Data stored");
              return 3;//return error code for failure in storing Laser Data
            }
          } else {
	  	Log("No sources found for id LASER!");
		return 1;
	  }
	return 0;
}
//____________________________________________________

UInt_t AliT0Preprocessor::ProcessPhysics(){
	//Processing data from DAQ Physics run
	Log("Processing Physics");

	Bool_t resultOnline=kFALSE;
	//processing DAQ
	TList* listPhys = GetFileSources(kDAQ, "PHYSICS");
        if (listPhys)
          {
            TIter iter(listPhys);
            TObjString *sourcePhys;
            while ((sourcePhys = dynamic_cast<TObjString *> (iter.Next())))
            {
              const char *filePhys = GetFile(kDAQ, "PHYSICS", sourcePhys->GetName());
              if (filePhys)
              {
                AliT0CalibTimeEq *online = new AliT0CalibTimeEq();
                online->Reset();
                online->ComputeOnlineParams(filePhys);
                AliCDBMetaData metaData;
                metaData.SetBeamPeriod(0);
                metaData.SetResponsible("Tomek&Michal");
                metaData.SetComment("Time equalizing result.");
                resultOnline = Store("Calib","TimeDelay", online, &metaData, 0, 1);
		Log(Form("resultOnline = %d",resultOnline));
                delete online;
              }
		else
              {
                Log(Form("Could not find file with Id PHYSICS in source %s!", sourcePhys->GetName()));
                return 1;
              }

            }
            if (!resultOnline)
            {
              Log("No Data stored");
              return 4;//return error code for failure in storing OCDB Data
            }
          } else {
	  	Log("No sources found for id PHYSICS!");
		return 1;
	  }
	return 0;
}
//____________________________________________________

UInt_t AliT0Preprocessor::ProcessCosmic(){
	//Processing data from DAQ Physics run
	Log("Processing Laser Physics");

	Bool_t resultLaserOnline=kFALSE;
	//processing DAQ
	TList* listLaser = GetFileSources(kDAQ, "COSMIC");
        if (listLaser)
          {
            TIter iter(listLaser);
            TObjString *sourceLaser;
            while ((sourceLaser = dynamic_cast<TObjString *> (iter.Next())))
            {
              const char *fileLaser = GetFile(kDAQ, "COSMIC", sourceLaser->GetName());
              if (fileLaser)
              {
                AliT0CalibTimeEq *onlineLaser = new AliT0CalibTimeEq();
                onlineLaser->Reset();
                onlineLaser->ComputeOnlineParams(fileLaser);
                AliCDBMetaData metaData;
                metaData.SetBeamPeriod(0);
                metaData.SetResponsible("Tomek&Michal");
                metaData.SetComment("Time equalizing result.");
                resultLaserOnline = Store("Calib","LaserTimeDelay", onlineLaser, &metaData, 0, 1);
		Log(Form("resultLaserOnline = %d",resultLaserOnline));
                delete onlineLaser;
              }
		else
              {
                Log(Form("Could not find file with Id COSMIC in source %s!", sourceLaser->GetName()));
                return 0;
              }

            }
            if (!resultLaserOnline)
            {
              Log("No Laser Data stored");
              return 0;//return error code for failure in storing OCDB Data
            }
          } else {
	  	Log("No sources found for id COSMIC!");
		return 0;
	  }
	return 0;
}
//____________________________________________________

UInt_t AliT0Preprocessor::Process(TMap* dcsAliasMap )
{
  // T0 preprocessor return codes:
  // return=0 : all ok
  // return=1 : no DCS input data
  // return=2 : failed to store DCS data
  // return=3 : no Laser data (Walk correction)
  // return=4 : failed to store OCDB time equalized data
  // return=5 : no DAQ input for OCDB
  // return=6 : failed to retrieve DAQ data from OCDB
  // return=7 : failed to store T0 OCDB data
	Bool_t dcsDP = ProcessDCS();
	Log(Form("dcsDP = %d",dcsDP));
        TString runType = GetRunType();
	Log(Form("RunType: %s",runType.Data()));
	//processing
 	if(runType == "STANDALONE"){
		Int_t iresultLaser = ProcessLaser();
	 		if(dcsDP==1){
			Int_t iresultDCS = ProcessDCSDataPoints(dcsAliasMap);
			return iresultDCS;
		}
		Log(Form("iresultLaser = %d",iresultLaser));
		return iresultLaser;
	}
       else if(runType == "PHYSICS"){
	 Int_t iresultPhysics = ProcessPhysics();
	 //	 Int_t iresultCosmic = ProcessCosmic();
		if(dcsDP==1){
			Int_t iresultDCS = ProcessDCSDataPoints(dcsAliasMap);
			return iresultDCS;
		}
		Log(Form("iresultPhysics = %d",iresultPhysics));
		return iresultPhysics;
		//		Log(Form("iresultPhysics =iresultCosmic %d",iresultCosmic));
		//	return iresultCosmic;
      }

  return 0;
}
<commit_msg> new run type LASER implemented<commit_after>/**************************************************************************
 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

/*
$Log: AliT0Preprocessor.cxx,v $
Revision 1.8  2007/12/07 15:22:51  alla
bug fixed by Alberto

Revision 1.7  2007/12/06 16:35:24  alla
new bugs fixed by Tomek

Revision 1.5  2007/11/23 19:28:52  alla
bug fixed

Version 2.1  2007/11/21
Preprocessor storing data to OCDB (T.Malkiewicz)

Version 1.1  2006/10
Preliminary test version (T.Malkiewicz)
*/
// T0 preprocessor:
// 1) takes data from DCS and passes it to the class AliTOFDataDCS
// for processing and writes the result to the Reference DB.
// 2) takes data form DAQ (both from Laser Calibration and Physics runs),
// processes it, and stores either to OCDB or to Reference DB.

#include "AliT0Preprocessor.h"
#include "AliT0DataDCS.h"
#include "AliT0CalibWalk.h"
#include "AliT0CalibTimeEq.h"

#include "AliCDBMetaData.h"
#include "AliDCSValue.h"
#include "AliLog.h"

#include <TTimeStamp.h>
#include <TFile.h>
#include <TObjString.h>
#include <TNamed.h>
#include "AliT0Dqclass.h"

ClassImp(AliT0Preprocessor)

//____________________________________________________
AliT0Preprocessor::AliT0Preprocessor(AliShuttleInterface* shuttle) :
  AliPreprocessor("T00", shuttle),
  fData(0)
{
  //constructor
  AddRunType("PHYSICS");
  AddRunType("STANDALONE");
  AddRunType("LASER");
}
//____________________________________________________

AliT0Preprocessor::~AliT0Preprocessor()
{
  //destructor
  delete fData;
  fData = 0;
}
//____________________________________________________

void AliT0Preprocessor::Initialize(Int_t run, UInt_t startTime, UInt_t endTime)
{
  // Creates AliT0DataDCS object
  AliPreprocessor::Initialize(run, startTime, endTime);
  AliInfo(Form("\n\tRun %d \n\tStartTime %s \n\tEndTime %s", run, TTimeStamp(startTime).AsString(), TTimeStamp(endTime).AsString()));
  fData = new AliT0DataDCS(fRun, fStartTime, fEndTime);
}
//____________________________________________________

Bool_t AliT0Preprocessor::ProcessDCS(){
	// Check whether DCS should be processed or not...
	TString runType = GetRunType();
	Log(Form("ProcessDCS - RunType: %s",runType.Data()));

	if((runType == "STANDALONE")||(runType == "PHYSICS")){
	  //		return kFALSE;
		return kTRUE;
	}else{
	return kFALSE;
	}
}
//____________________________________________________

UInt_t AliT0Preprocessor::ProcessDCSDataPoints(TMap* dcsAliasMap){
	// Fills data into AliT0DataDCS object
	Log("Processing DCS DP");
	Bool_t resultDCSMap=kFALSE;
	Bool_t resultDCSStore=kFALSE;

        if(!dcsAliasMap)
        {
          Log("No DCS input data");
          return 1;
        }
        else
        {
          resultDCSMap=fData->ProcessData(*dcsAliasMap);
          if(!resultDCSMap)
          {
            Log("Error when processing DCS data");
            return 2;// return error Code for processed DCS data not stored
          }
          else
          {
            AliCDBMetaData metaDataDCS;
            metaDataDCS.SetBeamPeriod(0);
            metaDataDCS.SetResponsible("Tomasz Malkiewicz");
            metaDataDCS.SetComment("This preprocessor fills an AliTODataDCS object.");
            AliInfo("Storing DCS Data");
            resultDCSStore = StoreReferenceData("Calib","DCSData",fData, &metaDataDCS);
            if (!resultDCSStore)
            {
              Log("Some problems occurred while storing DCS data results in ReferenceDB");
              return 2;// return error Code for processed DCS data not stored
            }
          }
        }
	return 0;
}
//____________________________________________________

UInt_t AliT0Preprocessor::ProcessLaser(){
	// Processing data from DAQ Standalone run
	Log("Processing Laser calibration - Walk Correction");

	Bool_t resultLaser=kFALSE;
	//processing DAQ
        TList* list = GetFileSources(kDAQ, "LASER");
        if (list)
        {
            TIter iter(list);
            TObjString *source;
            while ((source = dynamic_cast<TObjString *> (iter.Next())))
            {
              const char *laserFile = GetFile(kDAQ, "LASER", source->GetName());
              if (laserFile)
              {
                Log(Form("File with Id LASER found in source %s!", source->GetName()));
                AliT0CalibWalk *laser = new AliT0CalibWalk();
                laser->MakeWalkCorrGraph(laserFile);
                AliCDBMetaData metaData;
                metaData.SetBeamPeriod(0);
                metaData.SetResponsible("Tomek&Michal");
                metaData.SetComment("Walk correction from laser runs.");
		resultLaser=Store("Calib","Slewing_Walk", laser, &metaData, 0, 1);
                delete laser;
		Log(Form("resultLaser = %d",resultLaser));
              }
              else
              {
                Log(Form("Could not find file with Id LASER in source %s!", source->GetName()));
                return 1;
              }
            }
            if (!resultLaser)
            {
              Log("No Laser Data stored");
              return 3;//return error code for failure in storing Laser Data
            }
          } else {
	  	Log("No sources found for id LASER!");
		return 1;
	  }
	return 0;
}
//____________________________________________________

UInt_t AliT0Preprocessor::ProcessPhysics(){
	//Processing data from DAQ Physics run
	Log("Processing Physics");

	Bool_t resultOnline=kFALSE;
	//processing DAQ
	TList* listPhys = GetFileSources(kDAQ, "PHYSICS");
        if (listPhys)
          {
            TIter iter(listPhys);
            TObjString *sourcePhys;
            while ((sourcePhys = dynamic_cast<TObjString *> (iter.Next())))
            {
              const char *filePhys = GetFile(kDAQ, "PHYSICS", sourcePhys->GetName());
              if (filePhys)
              {
                AliT0CalibTimeEq *online = new AliT0CalibTimeEq();
                online->Reset();
                online->ComputeOnlineParams(filePhys);
                AliCDBMetaData metaData;
                metaData.SetBeamPeriod(0);
                metaData.SetResponsible("Tomek&Michal");
                metaData.SetComment("Time equalizing result.");
                resultOnline = Store("Calib","TimeDelay", online, &metaData, 0, 1);
		Log(Form("resultOnline = %d",resultOnline));
                delete online;
              }
		else
              {
                Log(Form("Could not find file with Id PHYSICS in source %s!", sourcePhys->GetName()));
                return 1;
              }

            }
            if (!resultOnline)
            {
              Log("No Data stored");
              return 4;//return error code for failure in storing OCDB Data
            }
          } else {
	  	Log("No sources found for id PHYSICS!");
		return 1;
	  }
	return 0;
}
//____________________________________________________

UInt_t AliT0Preprocessor::ProcessCosmic(){
	//Processing data from DAQ Physics run
	Log("Processing Laser Physics");

	Bool_t resultLaserOnline=kFALSE;
	//processing DAQ
	TList* listLaser = GetFileSources(kDAQ, "COSMIC");
        if (listLaser)
          {
            TIter iter(listLaser);
            TObjString *sourceLaser;
            while ((sourceLaser = dynamic_cast<TObjString *> (iter.Next())))
            {
              const char *fileLaser = GetFile(kDAQ, "COSMIC", sourceLaser->GetName());
              if (fileLaser)
              {
                AliT0CalibTimeEq *onlineLaser = new AliT0CalibTimeEq();
                onlineLaser->Reset();
                onlineLaser->ComputeOnlineParams(fileLaser);
                AliCDBMetaData metaData;
                metaData.SetBeamPeriod(0);
                metaData.SetResponsible("Tomek&Michal");
                metaData.SetComment("Time equalizing result.");
                resultLaserOnline = Store("Calib","LaserTimeDelay", onlineLaser, &metaData, 0, 1);
		Log(Form("resultLaserOnline = %d",resultLaserOnline));
                delete onlineLaser;
              }
		else
              {
                Log(Form("Could not find file with Id COSMIC in source %s!", sourceLaser->GetName()));
                return 0;
              }

            }
            if (!resultLaserOnline)
            {
              Log("No Laser Data stored");
              return 0;//return error code for failure in storing OCDB Data
            }
          } else {
	  	Log("No sources found for id COSMIC!");
		return 0;
	  }
	return 0;
}
//____________________________________________________

UInt_t AliT0Preprocessor::Process(TMap* dcsAliasMap )
{
  // T0 preprocessor return codes:
  // return=0 : all ok
  // return=1 : no DCS input data
  // return=2 : failed to store DCS data
  // return=3 : no Laser data (Walk correction)
  // return=4 : failed to store OCDB time equalized data
  // return=5 : no DAQ input for OCDB
  // return=6 : failed to retrieve DAQ data from OCDB
  // return=7 : failed to store T0 OCDB data
	Bool_t dcsDP = ProcessDCS();
	Log(Form("dcsDP = %d",dcsDP));
        TString runType = GetRunType();
	Log(Form("RunType: %s",runType.Data()));
	//processing
 	if(runType == "STANDALONE"){
	  if(dcsDP==1){
	    Int_t iresultDCS = ProcessDCSDataPoints(dcsAliasMap);
	    return iresultDCS;
	  }
	}
 	if(runType == "LASER"){
	  Int_t iresultLaser = ProcessLaser();
	  Log(Form("iresultLaser = %d",iresultLaser));
	  return iresultLaser;
	}
	else if(runType == "PHYSICS"){
	  Int_t iresultPhysics = ProcessPhysics();
	 //	 Int_t iresultCosmic = ProcessCosmic();
	  if(dcsDP==1){
	    Int_t iresultDCS = ProcessDCSDataPoints(dcsAliasMap);
	    return iresultDCS;
	  }
	  Log(Form("iresultPhysics = %d",iresultPhysics));
	  return iresultPhysics;
	  //		Log(Form("iresultPhysics =iresultCosmic %d",iresultCosmic));
	  //	return iresultCosmic;
	}

	return 0;
}
<|endoftext|>


<commit_before>/*
 * Software License Agreement (BSD License)
 *
 *  Copyright (c) 2009, Willow Garage, Inc.
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials provided
 *     with the distribution.
 *   * Neither the name of Willow Garage, Inc. nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 */

#include "ros/init.h"
#include "ros/names.h"
#include "ros/xmlrpc_manager.h"
#include "ros/poll_manager.h"
#include "ros/connection_manager.h"
#include "ros/topic_manager.h"
#include "ros/service_manager.h"
#include "ros/this_node.h"
#include "ros/network.h"
#include "ros/file_log.h"
#include "ros/callback_queue.h"
#include "ros/param.h"
#include "ros/rosout_appender.h"

#include "roscpp/GetLoggers.h"
#include "roscpp/SetLoggerLevel.h"

#include <ros/console.h>
#include <ros/time.h>
#include <roslib/Time.h>
#include <roslib/Clock.h>

#include <algorithm>

#include <signal.h>

#include <cstdlib>

namespace ros
{

namespace master
{
void init(const M_string& remappings);
}

namespace this_node
{
void init(const std::string& names, const M_string& remappings, uint32_t options);
}

namespace network
{
void init(const M_string& remappings);
}

namespace param
{
void init(const M_string& remappings);
}

namespace file_log
{
void init(const M_string& remappings);
}

CallbackQueue g_global_queue;
ROSOutAppenderPtr g_rosout_appender;

static bool g_initialized = false;
static bool g_started = false;
static bool g_atexit_registered = false;
static boost::mutex g_start_mutex;
static bool g_ok = false;
static uint32_t g_init_options = 0;
static bool g_shutdown_requested = false;
static volatile bool g_shutting_down = false;
static boost::mutex g_shutting_down_mutex;
static boost::thread g_internal_queue_thread;

bool isInitialized()
{
  return g_initialized;
}

bool isShuttingDown()
{
  return g_shutting_down;
}

void checkForShutdown()
{
  if (g_shutdown_requested)
  {
    shutdown();
  }
}

void requestShutdown()
{
  g_shutdown_requested = true;
}

void atexitCallback()
{
  if (ok() && !isShuttingDown())
  {
    ROS_INFO("shutting down due to exit() or end of main() without cleanup of all NodeHandles");
    shutdown();
  }
}

void shutdownCallback(XmlRpc::XmlRpcValue& params, XmlRpc::XmlRpcValue& result)
{
  int num_params = 0;
  if (params.getType() == XmlRpc::XmlRpcValue::TypeArray)
    num_params = params.size();
  if (num_params > 1)
  {
    std::string reason = params[1];
    ROS_WARN("Shutdown request received.");
    ROS_WARN("Reason given for shutdown: [%s]", reason.c_str());
    requestShutdown();
  }

  result = xmlrpc::responseInt(1, "", 0);
}

bool getLoggers(roscpp::GetLoggers::Request&, roscpp::GetLoggers::Response& resp)
{
  log4cxx::spi::LoggerRepositoryPtr repo = log4cxx::Logger::getLogger(ROSCONSOLE_ROOT_LOGGER_NAME)->getLoggerRepository();

  log4cxx::LoggerList loggers = repo->getCurrentLoggers();
  log4cxx::LoggerList::iterator it = loggers.begin();
  log4cxx::LoggerList::iterator end = loggers.end();
  for (; it != end; ++it)
  {
    roscpp::Logger logger;
    logger.name = (*it)->getName();
    const log4cxx::LevelPtr& level = (*it)->getEffectiveLevel();
    if (level)
    {
      logger.level = level->toString();
    }
    resp.loggers.push_back(logger);
  }

  return true;
}

bool setLoggerLevel(roscpp::SetLoggerLevel::Request& req, roscpp::SetLoggerLevel::Response&)
{
  log4cxx::LoggerPtr logger = log4cxx::Logger::getLogger(req.logger);
  log4cxx::LevelPtr level;

  std::transform(req.level.begin(), req.level.end(), req.level.begin(), (int(*)(int))std::toupper);

  if (req.level == "DEBUG")
  {
    level = log4cxx::Level::getDebug();
  }
  else if (req.level == "INFO")
  {
    level = log4cxx::Level::getInfo();
  }
  else if (req.level == "WARN")
  {
    level = log4cxx::Level::getWarn();
  }
  else if (req.level == "ERROR")
  {
    level = log4cxx::Level::getError();
  }
  else if (req.level == "FATAL")
  {
    level = log4cxx::Level::getFatal();
  }

  if (level)
  {
    logger->setLevel(level);
    console::notifyLoggerLevelsChanged();
    return true;
  }

  return false;
}

void timeCallback(const roslib::Time::ConstPtr& msg)
{
  Time::setNow(msg->rostime);
}

void clockCallback(const roslib::Clock::ConstPtr& msg)
{
  Time::setNow(msg->clock);
}

CallbackQueuePtr getInternalCallbackQueue()
{
  static CallbackQueuePtr queue;
  if (!queue)
  {
    queue.reset(new CallbackQueue);
  }

  return queue;
}

void basicSigintHandler(int sig)
{
  ros::requestShutdown();
}

void internalCallbackQueueThreadFunc()
{
  disableAllSignalsInThisThread();

  CallbackQueuePtr queue = getInternalCallbackQueue();

  while (!g_shutting_down)
  {
    queue->callAvailable(WallDuration(0.05));
  }
}

bool isStarted()
{
  return g_started;
}

void start()
{
  boost::mutex::scoped_lock lock(g_start_mutex);
  if (g_started)
  {
    return;
  }

  g_shutdown_requested = false;
  g_shutting_down = false;
  g_started = true;
  g_ok = true;

  PollManager::instance()->addPollThreadListener(checkForShutdown);
  XMLRPCManager::instance()->bind("shutdown", shutdownCallback);

  TopicManager::instance()->start();
  ServiceManager::instance()->start();
  ConnectionManager::instance()->start();
  PollManager::instance()->start();
  XMLRPCManager::instance()->start();

  if (!(g_init_options & init_options::NoSigintHandler))
  {
    signal(SIGINT, basicSigintHandler);
  }

  if (!(g_init_options & init_options::NoRosout))
  {
    g_rosout_appender = new ROSOutAppender;
    const log4cxx::LoggerPtr& logger = log4cxx::Logger::getLogger(ROSCONSOLE_ROOT_LOGGER_NAME);
    logger->addAppender(g_rosout_appender);
  }

  if (!g_shutting_down)
  {
    {
      ros::AdvertiseServiceOptions ops;
      ops.init<roscpp::GetLoggers>(names::resolve("~get_loggers"), getLoggers);
      ops.callback_queue = getInternalCallbackQueue().get();
      ServiceManager::instance()->advertiseService(ops);
    }

    if (!g_shutting_down)
    {
      {
        ros::AdvertiseServiceOptions ops;
        ops.init<roscpp::SetLoggerLevel>(names::resolve("~set_logger_level"), setLoggerLevel);
        ops.callback_queue = getInternalCallbackQueue().get();
        ServiceManager::instance()->advertiseService(ops);
      }

      if (!g_shutting_down)
      {
        bool use_sim_time = false;
        param::param("/use_sim_time", use_sim_time, use_sim_time);
        if (use_sim_time)
        {
          Time::setNow(ros::Time());
        }

        if (!g_shutting_down)
        {
          {
            ros::SubscribeOptions ops;
            ops.init<roslib::Time>("/time", 1, timeCallback);
            ops.callback_queue = getInternalCallbackQueue().get();
            TopicManager::instance()->subscribe(ops);
          }

          {
            ros::SubscribeOptions ops;
            ops.init<roslib::Clock>("/clock", 1, clockCallback);
            ops.callback_queue = getInternalCallbackQueue().get();
            TopicManager::instance()->subscribe(ops);
          }

          g_internal_queue_thread = boost::thread(internalCallbackQueueThreadFunc);
          g_global_queue.enable();
          getGlobalCallbackQueue()->enable();

          ROS_DEBUG("Started node [%s], pid [%d], bound on [%s], xmlrpc port [%d], tcpros port [%d], logging to [%s], using [%s] time", this_node::getName().c_str(), getpid(), network::getHost().c_str(), XMLRPCManager::instance()->getServerPort(), ConnectionManager::instance()->getTCPPort(), file_log::getLogFilename().c_str(), Time::useSystemTime() ? "real" : "sim");
        }
      }
    }
  }

  // If we received a shutdown request while initializing, wait until we've shutdown to continue
  if (g_shutting_down)
  {
    boost::mutex::scoped_lock lock(g_shutting_down_mutex);
  }
}

void init(const M_string& remappings, const std::string& name, uint32_t options)
{
  if (!g_atexit_registered)
  {
    g_atexit_registered = true;
    atexit(atexitCallback);
  }

  if (!g_initialized)
  {
    g_init_options = options;
    g_ok = true;

    ROSCONSOLE_AUTOINIT;
    ros::Time::init();
    network::init(remappings);
    master::init(remappings);
    // names:: namespace is initialized by this_node
    this_node::init(name, remappings, options);
    param::init(remappings);
    file_log::init(remappings);

    g_initialized = true;
  }
}

void init(int& argc, char** argv, const std::string& name, uint32_t options)
{
  M_string remappings;

  int full_argc = argc;
  // now, move the remapping argv's to the end, and decrement argc as needed
  for (int i = 0; i < argc; )
  {
    std::string arg = argv[i];
    size_t pos = arg.find(":=");
    if (pos != std::string::npos)
    {
      std::string local_name = arg.substr(0, pos);
      std::string external_name = arg.substr(pos + 2);

      remappings[local_name] = external_name;

      // shuffle everybody down and stuff this guy at the end of argv
      char *tmp = argv[i];
      for (int j = i; j < full_argc - 1; j++)
        argv[j] = argv[j+1];
      argv[argc-1] = tmp;
      argc--;
    }
    else
    {
      i++; // move on, since we didn't shuffle anybody here to replace it
    }
  }

  init(remappings, name, options);
}

void init(const VP_string& remappings, const std::string& name, uint32_t options)
{
  M_string remappings_map;
  VP_string::const_iterator it = remappings.begin();
  VP_string::const_iterator end = remappings.end();
  for (; it != end; ++it)
  {
    remappings_map[it->first] = it->second;
  }

  init(remappings_map, name, options);
}

void spin()
{
  SingleThreadedSpinner s;
  spin(s);
}

void spin(Spinner& s)
{
  s.spin();
}

void spinOnce()
{
  g_global_queue.callAvailable(ros::WallDuration());
}

CallbackQueue* getGlobalCallbackQueue()
{
  return &g_global_queue;
}

bool ok()
{
  return g_ok;
}

void shutdown()
{
  boost::mutex::scoped_lock lock(g_shutting_down_mutex);
  if (g_shutting_down)
  {
    return;
  }

  g_shutting_down = true;

  g_global_queue.disable();
  g_global_queue.clear();

  getGlobalCallbackQueue()->disable();
  getGlobalCallbackQueue()->clear();

  if (g_internal_queue_thread.get_id() != boost::this_thread::get_id())
  {
    g_internal_queue_thread.join();
    ROS_DEBUG("internal callback queue thread shut down");
  }

  const log4cxx::LoggerPtr& logger = log4cxx::Logger::getLogger(ROSCONSOLE_ROOT_LOGGER_NAME);
  logger->removeAppender(g_rosout_appender);
  g_rosout_appender = 0;

  if (g_started)
  {
    XMLRPCManager::instance()->shutdown();
    TopicManager::instance()->shutdown();
    ServiceManager::instance()->shutdown();
    ConnectionManager::instance()->shutdown();
    PollManager::instance()->shutdown();
  }

  g_started = false;
  g_ok = false;
  Time::shutdown();
}

}
<commit_msg>info->debug<commit_after>/*
 * Software License Agreement (BSD License)
 *
 *  Copyright (c) 2009, Willow Garage, Inc.
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials provided
 *     with the distribution.
 *   * Neither the name of Willow Garage, Inc. nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 */

#include "ros/init.h"
#include "ros/names.h"
#include "ros/xmlrpc_manager.h"
#include "ros/poll_manager.h"
#include "ros/connection_manager.h"
#include "ros/topic_manager.h"
#include "ros/service_manager.h"
#include "ros/this_node.h"
#include "ros/network.h"
#include "ros/file_log.h"
#include "ros/callback_queue.h"
#include "ros/param.h"
#include "ros/rosout_appender.h"

#include "roscpp/GetLoggers.h"
#include "roscpp/SetLoggerLevel.h"

#include <ros/console.h>
#include <ros/time.h>
#include <roslib/Time.h>
#include <roslib/Clock.h>

#include <algorithm>

#include <signal.h>

#include <cstdlib>

namespace ros
{

namespace master
{
void init(const M_string& remappings);
}

namespace this_node
{
void init(const std::string& names, const M_string& remappings, uint32_t options);
}

namespace network
{
void init(const M_string& remappings);
}

namespace param
{
void init(const M_string& remappings);
}

namespace file_log
{
void init(const M_string& remappings);
}

CallbackQueue g_global_queue;
ROSOutAppenderPtr g_rosout_appender;

static bool g_initialized = false;
static bool g_started = false;
static bool g_atexit_registered = false;
static boost::mutex g_start_mutex;
static bool g_ok = false;
static uint32_t g_init_options = 0;
static bool g_shutdown_requested = false;
static volatile bool g_shutting_down = false;
static boost::mutex g_shutting_down_mutex;
static boost::thread g_internal_queue_thread;

bool isInitialized()
{
  return g_initialized;
}

bool isShuttingDown()
{
  return g_shutting_down;
}

void checkForShutdown()
{
  if (g_shutdown_requested)
  {
    shutdown();
  }
}

void requestShutdown()
{
  g_shutdown_requested = true;
}

void atexitCallback()
{
  if (ok() && !isShuttingDown())
  {
    ROS_DEBUG("shutting down due to exit() or end of main() without cleanup of all NodeHandles");
    shutdown();
  }
}

void shutdownCallback(XmlRpc::XmlRpcValue& params, XmlRpc::XmlRpcValue& result)
{
  int num_params = 0;
  if (params.getType() == XmlRpc::XmlRpcValue::TypeArray)
    num_params = params.size();
  if (num_params > 1)
  {
    std::string reason = params[1];
    ROS_WARN("Shutdown request received.");
    ROS_WARN("Reason given for shutdown: [%s]", reason.c_str());
    requestShutdown();
  }

  result = xmlrpc::responseInt(1, "", 0);
}

bool getLoggers(roscpp::GetLoggers::Request&, roscpp::GetLoggers::Response& resp)
{
  log4cxx::spi::LoggerRepositoryPtr repo = log4cxx::Logger::getLogger(ROSCONSOLE_ROOT_LOGGER_NAME)->getLoggerRepository();

  log4cxx::LoggerList loggers = repo->getCurrentLoggers();
  log4cxx::LoggerList::iterator it = loggers.begin();
  log4cxx::LoggerList::iterator end = loggers.end();
  for (; it != end; ++it)
  {
    roscpp::Logger logger;
    logger.name = (*it)->getName();
    const log4cxx::LevelPtr& level = (*it)->getEffectiveLevel();
    if (level)
    {
      logger.level = level->toString();
    }
    resp.loggers.push_back(logger);
  }

  return true;
}

bool setLoggerLevel(roscpp::SetLoggerLevel::Request& req, roscpp::SetLoggerLevel::Response&)
{
  log4cxx::LoggerPtr logger = log4cxx::Logger::getLogger(req.logger);
  log4cxx::LevelPtr level;

  std::transform(req.level.begin(), req.level.end(), req.level.begin(), (int(*)(int))std::toupper);

  if (req.level == "DEBUG")
  {
    level = log4cxx::Level::getDebug();
  }
  else if (req.level == "INFO")
  {
    level = log4cxx::Level::getInfo();
  }
  else if (req.level == "WARN")
  {
    level = log4cxx::Level::getWarn();
  }
  else if (req.level == "ERROR")
  {
    level = log4cxx::Level::getError();
  }
  else if (req.level == "FATAL")
  {
    level = log4cxx::Level::getFatal();
  }

  if (level)
  {
    logger->setLevel(level);
    console::notifyLoggerLevelsChanged();
    return true;
  }

  return false;
}

void timeCallback(const roslib::Time::ConstPtr& msg)
{
  Time::setNow(msg->rostime);
}

void clockCallback(const roslib::Clock::ConstPtr& msg)
{
  Time::setNow(msg->clock);
}

CallbackQueuePtr getInternalCallbackQueue()
{
  static CallbackQueuePtr queue;
  if (!queue)
  {
    queue.reset(new CallbackQueue);
  }

  return queue;
}

void basicSigintHandler(int sig)
{
  ros::requestShutdown();
}

void internalCallbackQueueThreadFunc()
{
  disableAllSignalsInThisThread();

  CallbackQueuePtr queue = getInternalCallbackQueue();

  while (!g_shutting_down)
  {
    queue->callAvailable(WallDuration(0.05));
  }
}

bool isStarted()
{
  return g_started;
}

void start()
{
  boost::mutex::scoped_lock lock(g_start_mutex);
  if (g_started)
  {
    return;
  }

  g_shutdown_requested = false;
  g_shutting_down = false;
  g_started = true;
  g_ok = true;

  PollManager::instance()->addPollThreadListener(checkForShutdown);
  XMLRPCManager::instance()->bind("shutdown", shutdownCallback);

  TopicManager::instance()->start();
  ServiceManager::instance()->start();
  ConnectionManager::instance()->start();
  PollManager::instance()->start();
  XMLRPCManager::instance()->start();

  if (!(g_init_options & init_options::NoSigintHandler))
  {
    signal(SIGINT, basicSigintHandler);
  }

  if (!(g_init_options & init_options::NoRosout))
  {
    g_rosout_appender = new ROSOutAppender;
    const log4cxx::LoggerPtr& logger = log4cxx::Logger::getLogger(ROSCONSOLE_ROOT_LOGGER_NAME);
    logger->addAppender(g_rosout_appender);
  }

  if (!g_shutting_down)
  {
    {
      ros::AdvertiseServiceOptions ops;
      ops.init<roscpp::GetLoggers>(names::resolve("~get_loggers"), getLoggers);
      ops.callback_queue = getInternalCallbackQueue().get();
      ServiceManager::instance()->advertiseService(ops);
    }

    if (!g_shutting_down)
    {
      {
        ros::AdvertiseServiceOptions ops;
        ops.init<roscpp::SetLoggerLevel>(names::resolve("~set_logger_level"), setLoggerLevel);
        ops.callback_queue = getInternalCallbackQueue().get();
        ServiceManager::instance()->advertiseService(ops);
      }

      if (!g_shutting_down)
      {
        bool use_sim_time = false;
        param::param("/use_sim_time", use_sim_time, use_sim_time);
        if (use_sim_time)
        {
          Time::setNow(ros::Time());
        }

        if (!g_shutting_down)
        {
          {
            ros::SubscribeOptions ops;
            ops.init<roslib::Time>("/time", 1, timeCallback);
            ops.callback_queue = getInternalCallbackQueue().get();
            TopicManager::instance()->subscribe(ops);
          }

          {
            ros::SubscribeOptions ops;
            ops.init<roslib::Clock>("/clock", 1, clockCallback);
            ops.callback_queue = getInternalCallbackQueue().get();
            TopicManager::instance()->subscribe(ops);
          }

          g_internal_queue_thread = boost::thread(internalCallbackQueueThreadFunc);
          g_global_queue.enable();
          getGlobalCallbackQueue()->enable();

          ROS_DEBUG("Started node [%s], pid [%d], bound on [%s], xmlrpc port [%d], tcpros port [%d], logging to [%s], using [%s] time", this_node::getName().c_str(), getpid(), network::getHost().c_str(), XMLRPCManager::instance()->getServerPort(), ConnectionManager::instance()->getTCPPort(), file_log::getLogFilename().c_str(), Time::useSystemTime() ? "real" : "sim");
        }
      }
    }
  }

  // If we received a shutdown request while initializing, wait until we've shutdown to continue
  if (g_shutting_down)
  {
    boost::mutex::scoped_lock lock(g_shutting_down_mutex);
  }
}

void init(const M_string& remappings, const std::string& name, uint32_t options)
{
  if (!g_atexit_registered)
  {
    g_atexit_registered = true;
    atexit(atexitCallback);
  }

  if (!g_initialized)
  {
    g_init_options = options;
    g_ok = true;

    ROSCONSOLE_AUTOINIT;
    ros::Time::init();
    network::init(remappings);
    master::init(remappings);
    // names:: namespace is initialized by this_node
    this_node::init(name, remappings, options);
    param::init(remappings);
    file_log::init(remappings);

    g_initialized = true;
  }
}

void init(int& argc, char** argv, const std::string& name, uint32_t options)
{
  M_string remappings;

  int full_argc = argc;
  // now, move the remapping argv's to the end, and decrement argc as needed
  for (int i = 0; i < argc; )
  {
    std::string arg = argv[i];
    size_t pos = arg.find(":=");
    if (pos != std::string::npos)
    {
      std::string local_name = arg.substr(0, pos);
      std::string external_name = arg.substr(pos + 2);

      remappings[local_name] = external_name;

      // shuffle everybody down and stuff this guy at the end of argv
      char *tmp = argv[i];
      for (int j = i; j < full_argc - 1; j++)
        argv[j] = argv[j+1];
      argv[argc-1] = tmp;
      argc--;
    }
    else
    {
      i++; // move on, since we didn't shuffle anybody here to replace it
    }
  }

  init(remappings, name, options);
}

void init(const VP_string& remappings, const std::string& name, uint32_t options)
{
  M_string remappings_map;
  VP_string::const_iterator it = remappings.begin();
  VP_string::const_iterator end = remappings.end();
  for (; it != end; ++it)
  {
    remappings_map[it->first] = it->second;
  }

  init(remappings_map, name, options);
}

void spin()
{
  SingleThreadedSpinner s;
  spin(s);
}

void spin(Spinner& s)
{
  s.spin();
}

void spinOnce()
{
  g_global_queue.callAvailable(ros::WallDuration());
}

CallbackQueue* getGlobalCallbackQueue()
{
  return &g_global_queue;
}

bool ok()
{
  return g_ok;
}

void shutdown()
{
  boost::mutex::scoped_lock lock(g_shutting_down_mutex);
  if (g_shutting_down)
  {
    return;
  }

  g_shutting_down = true;

  g_global_queue.disable();
  g_global_queue.clear();

  getGlobalCallbackQueue()->disable();
  getGlobalCallbackQueue()->clear();

  if (g_internal_queue_thread.get_id() != boost::this_thread::get_id())
  {
    g_internal_queue_thread.join();
    ROS_DEBUG("internal callback queue thread shut down");
  }

  const log4cxx::LoggerPtr& logger = log4cxx::Logger::getLogger(ROSCONSOLE_ROOT_LOGGER_NAME);
  logger->removeAppender(g_rosout_appender);
  g_rosout_appender = 0;

  if (g_started)
  {
    XMLRPCManager::instance()->shutdown();
    TopicManager::instance()->shutdown();
    ServiceManager::instance()->shutdown();
    ConnectionManager::instance()->shutdown();
    PollManager::instance()->shutdown();
  }

  g_started = false;
  g_ok = false;
  Time::shutdown();
}

}
<|endoftext|>