<commit_before>/***********************************************************************************************************************
 **
 ** Copyright (c) 2011, 2015 ETH Zurich
 ** 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 the ETH Zurich 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 HOLDER 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 "CppExporter.h"

#include "OOModel/src/declarations/Project.h"

#include "Export/src/writer/Exporter.h"
#include "Export/src/writer/FragmentLayouter.h"
#include "Export/src/tree/CompositeFragment.h"
#include "ModelBase/src/model/TreeManager.h"

#include "../CodeUnit.h"
#include "../CodeComposite.h"
#include "../Config.h"

namespace CppExport {

QList<Export::ExportError> CppExporter::exportTree(Model::TreeManager* treeManager,
																	const QString& pathToProjectContainerDirectory)
{
	QList<CodeUnit*> codeUnits;
	units(treeManager->root(), "", codeUnits);

	QList<CodeUnitPart*> allHeaderParts;
	for (auto unit : codeUnits)
	{
		unit->calculateSourceFragments();
		allHeaderParts.append(unit->headerPart());
	}
	for (auto unit : codeUnits) unit->calculateDependencies(allHeaderParts);

	auto directory = new Export::SourceDir(nullptr, pathToProjectContainerDirectory + "/src");
	for (auto codeComposite : mergeUnits(codeUnits))
		createFilesFromComposite(directory, codeComposite);

	auto layout = layouter();
	Export::Exporter::exportToFileSystem("", directory, &layout);

	return {};

}

void CppExporter::createFilesFromComposite(Export::SourceDir* directory, CodeComposite* codeComposite)
{
	Export::SourceFragment* headerFragment{};
	Export::SourceFragment* sourceFragment{};
	codeComposite->fragments(headerFragment, sourceFragment);

	if (headerFragment) directory->file(codeComposite->name() + ".h").append(headerFragment);
	if (sourceFragment) directory->file(codeComposite->name() + ".cpp").append(sourceFragment);
}

void CppExporter::units(Model::Node* current, QString namespaceName, QList<CodeUnit*>& result)
{
	if (auto ooModule = DCast<OOModel::Module>(current))
	{
		if (ooModule->classes()->size() > 0)
			namespaceName = ooModule->name();
		else
		{
			// macro file
			// TODO: handle non class units
			//result.append(new CodeUnit((namespaceName.isEmpty() ? "" : namespaceName + "/") + ooModule->name(), current));
			return;
		}
	}
	else if (auto ooClass = DCast<OOModel::Class>(current))
	{
		result.append(new CodeUnit((namespaceName.isEmpty() ? "" : namespaceName + "/") + ooClass->name(), current));
		return;
	}

	for (auto child : current->children())
		units(child, namespaceName, result);
}

QList<CodeComposite*> CppExporter::mergeUnits(QList<CodeUnit*>& units)
{
	QHash<QString, QString> mergeMap = Config::instance().dependencyUnitMergeMap();

	QHash<QString, CodeComposite*> nameToCompositeMap;
	for (auto unit : units)
	{
		auto it = mergeMap.find(unit->name());
		auto compositeName = it != mergeMap.end() ? *it : unit->name();

		auto cIt = nameToCompositeMap.find(compositeName);
		if (cIt != nameToCompositeMap.end())
			// case A: the composite that unit is a part of already exists => merge
			(*cIt)->addUnit(unit);
		else
		{
			// case B: the composite that unit is a part of does not yet exist
			auto composite = new CodeComposite(compositeName);
			composite->addUnit(unit);
			nameToCompositeMap.insert(composite->name(), composite);
		}
	}

	return nameToCompositeMap.values();
}

Export::FragmentLayouter CppExporter::layouter()
{
	auto result = Export::FragmentLayouter{"\t"};
	result.addRule("enumerators", Export::FragmentLayouter::SpaceAfterSeparator, "", ",", "");
	result.addRule("vertical", Export::FragmentLayouter::NoIndentation, "", "\n", "");
	result.addRule("sections", Export::FragmentLayouter::NoIndentation, "", "\n", "");
	result.addRule("declarationComment", Export::FragmentLayouter::NoIndentation
							| Export::FragmentLayouter::NewLineAfterPostfix, "", "\n", "");
	result.addRule("spacedSections", Export::FragmentLayouter::NoIndentation, "", "\n\n", "");
	result.addRule("accessorSections", Export::FragmentLayouter::IndentChildFragments, "", "\n", "");
	result.addRule("bodySections", Export::FragmentLayouter::NewLineBefore
						  | Export::FragmentLayouter::IndentChildFragments | Export::FragmentLayouter::NewLineAfterPrefix
						  | Export::FragmentLayouter::NewLineBeforePostfix, "{", "\n", "}");
	result.addRule("space", Export::FragmentLayouter::SpaceAtEnd, "", " ", "");
	result.addRule("comma", Export::FragmentLayouter::SpaceAfterSeparator, "", ",", "");
	result.addRule("baseClasses", Export::FragmentLayouter::SpaceAfterSeparator, " : public ", ",", "");
	result.addRule("initializerList", Export::FragmentLayouter::SpaceAfterSeparator, "{", ",", "}");
	result.addRule("argsList", Export::FragmentLayouter::SpaceAfterSeparator, "(", ",", ")");
	result.addRule("typeArgsList", Export::FragmentLayouter::SpaceAfterSeparator, "<", ",", ">");
	result.addRule("templateArgsList", Export::FragmentLayouter::SpaceAfterSeparator
							| Export::FragmentLayouter::NewLineAfterPostfix, "template<", ",", ">");

	result.addRule("body", Export::FragmentLayouter::NewLineBefore | Export::FragmentLayouter::IndentChildFragments
							| Export::FragmentLayouter::NewLineAfterPrefix | Export::FragmentLayouter::NewLineBeforePostfix,
							"{", "\n", "}");

	return result;
}

Export::ExportMapContainer& CppExporter::exportMaps()
{
	static Export::ExportMapContainer* container = new Export::ExportMapContainer();
	return *container;
}

}
<commit_msg>add macro layouts<commit_after>/***********************************************************************************************************************
 **
 ** Copyright (c) 2011, 2015 ETH Zurich
 ** 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 the ETH Zurich 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 HOLDER 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 "CppExporter.h"

#include "OOModel/src/declarations/Project.h"

#include "Export/src/writer/Exporter.h"
#include "Export/src/writer/FragmentLayouter.h"
#include "Export/src/tree/CompositeFragment.h"
#include "ModelBase/src/model/TreeManager.h"

#include "../CodeUnit.h"
#include "../CodeComposite.h"
#include "../Config.h"

namespace CppExport {

QList<Export::ExportError> CppExporter::exportTree(Model::TreeManager* treeManager,
																	const QString& pathToProjectContainerDirectory)
{
	QList<CodeUnit*> codeUnits;
	units(treeManager->root(), "", codeUnits);

	QList<CodeUnitPart*> allHeaderParts;
	for (auto unit : codeUnits)
	{
		unit->calculateSourceFragments();
		allHeaderParts.append(unit->headerPart());
	}
	for (auto unit : codeUnits) unit->calculateDependencies(allHeaderParts);

	auto directory = new Export::SourceDir(nullptr, pathToProjectContainerDirectory + "/src");
	for (auto codeComposite : mergeUnits(codeUnits))
		createFilesFromComposite(directory, codeComposite);

	auto layout = layouter();
	Export::Exporter::exportToFileSystem("", directory, &layout);

	return {};

}

void CppExporter::createFilesFromComposite(Export::SourceDir* directory, CodeComposite* codeComposite)
{
	Export::SourceFragment* headerFragment{};
	Export::SourceFragment* sourceFragment{};
	codeComposite->fragments(headerFragment, sourceFragment);

	if (headerFragment) directory->file(codeComposite->name() + ".h").append(headerFragment);
	if (sourceFragment) directory->file(codeComposite->name() + ".cpp").append(sourceFragment);
}

void CppExporter::units(Model::Node* current, QString namespaceName, QList<CodeUnit*>& result)
{
	if (auto ooModule = DCast<OOModel::Module>(current))
	{
		if (ooModule->classes()->size() > 0)
			namespaceName = ooModule->name();
		else
		{
			// macro file
			// TODO: handle non class units
			//result.append(new CodeUnit((namespaceName.isEmpty() ? "" : namespaceName + "/") + ooModule->name(), current));
			return;
		}
	}
	else if (auto ooClass = DCast<OOModel::Class>(current))
	{
		result.append(new CodeUnit((namespaceName.isEmpty() ? "" : namespaceName + "/") + ooClass->name(), current));
		return;
	}

	for (auto child : current->children())
		units(child, namespaceName, result);
}

QList<CodeComposite*> CppExporter::mergeUnits(QList<CodeUnit*>& units)
{
	QHash<QString, QString> mergeMap = Config::instance().dependencyUnitMergeMap();

	QHash<QString, CodeComposite*> nameToCompositeMap;
	for (auto unit : units)
	{
		auto it = mergeMap.find(unit->name());
		auto compositeName = it != mergeMap.end() ? *it : unit->name();

		auto cIt = nameToCompositeMap.find(compositeName);
		if (cIt != nameToCompositeMap.end())
			// case A: the composite that unit is a part of already exists => merge
			(*cIt)->addUnit(unit);
		else
		{
			// case B: the composite that unit is a part of does not yet exist
			auto composite = new CodeComposite(compositeName);
			composite->addUnit(unit);
			nameToCompositeMap.insert(composite->name(), composite);
		}
	}

	return nameToCompositeMap.values();
}

Export::FragmentLayouter CppExporter::layouter()
{
	auto result = Export::FragmentLayouter{"\t"};
	result.addRule("enumerators", Export::FragmentLayouter::SpaceAfterSeparator, "", ",", "");
	result.addRule("vertical", Export::FragmentLayouter::NoIndentation, "", "\n", "");
	result.addRule("sections", Export::FragmentLayouter::NoIndentation, "", "\n", "");
	result.addRule("declarationComment", Export::FragmentLayouter::NoIndentation
							| Export::FragmentLayouter::NewLineAfterPostfix, "", "\n", "");
	result.addRule("spacedSections", Export::FragmentLayouter::NoIndentation, "", "\n\n", "");
	result.addRule("accessorSections", Export::FragmentLayouter::IndentChildFragments, "", "\n", "");
	result.addRule("bodySections", Export::FragmentLayouter::NewLineBefore
						  | Export::FragmentLayouter::IndentChildFragments | Export::FragmentLayouter::NewLineAfterPrefix
						  | Export::FragmentLayouter::NewLineBeforePostfix, "{", "\n", "}");
	result.addRule("space", Export::FragmentLayouter::SpaceAtEnd, "", " ", "");
	result.addRule("comma", Export::FragmentLayouter::SpaceAfterSeparator, "", ",", "");
	result.addRule("baseClasses", Export::FragmentLayouter::SpaceAfterSeparator, " : public ", ",", "");
	result.addRule("initializerList", Export::FragmentLayouter::SpaceAfterSeparator, "{", ",", "}");
	result.addRule("argsList", Export::FragmentLayouter::SpaceAfterSeparator, "(", ",", ")");
	result.addRule("typeArgsList", Export::FragmentLayouter::SpaceAfterSeparator, "<", ",", ">");
	result.addRule("templateArgsList", Export::FragmentLayouter::SpaceAfterSeparator
							| Export::FragmentLayouter::NewLineAfterPostfix, "template<", ",", ">");

	result.addRule("body", Export::FragmentLayouter::NewLineBefore | Export::FragmentLayouter::IndentChildFragments
							| Export::FragmentLayouter::NewLineAfterPrefix | Export::FragmentLayouter::NewLineBeforePostfix,
							"{", "\n", "}");
	result.addRule("bodyNoBraces", Export::FragmentLayouter::NewLineBefore
							| Export::FragmentLayouter::IndentChildFragments | Export::FragmentLayouter::NewLineAfterPrefix
							| Export::FragmentLayouter::NewLineBeforePostfix, "", "\n", "");
	result.addRule("macroBody", Export::FragmentLayouter::NewLineBefore | Export::FragmentLayouter::IndentChildFragments
							| Export::FragmentLayouter::NewLineAfterPrefix | Export::FragmentLayouter::NewLineBeforePostfix,
							"", "\n", "");
	result.addRule("macro", Export::FragmentLayouter::BackslashAfterLines
						| Export::FragmentLayouter::NewLineAfterPrefix | Export::FragmentLayouter::NewLineBeforePostfix);
	result.addRule("emptyLineAtEnd", Export::FragmentLayouter::EmptyLineAtEnd);

	return result;
}

Export::ExportMapContainer& CppExporter::exportMaps()
{
	static Export::ExportMapContainer* container = new Export::ExportMapContainer();
	return *container;
}

}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2016 Shanghai Jiao Tong University.
 *     All rights reserved.
 *
 *  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.
 *
 * For more about this software visit:
 *
 *      http://ipads.se.sjtu.edu.cn/projects/wukong.html
 *
 */

#pragma once

#include "config.hpp"
#include "query.hpp"
#include "tcp_adaptor.hpp"
#include "rdma_adaptor.hpp"

/// TODO: define adaptor as a C++ interface and make tcp and rdma implement it
class Adaptor {
public:
    int tid; // thread id

    TCP_Adaptor *tcp;   // communicaiton by TCP/IP
    RDMA_Adaptor *rdma; // communicaiton by RDMA

    Adaptor(int tid, TCP_Adaptor *tcp, RDMA_Adaptor *rdma)
        : tid(tid), tcp(tcp), rdma(rdma) { }

    ~Adaptor() { }

    void send(int dst_sid, int dst_tid, request_or_reply &r) {
        std::stringstream ss;
        boost::archive::binary_oarchive oa(ss);

        oa << r;
        if (global_use_rdma) {
            if (!rdma) {
                rdma->rbfSend(tid, dst_sid, dst_tid, ss.str().c_str(), ss.str().size());
            } else {
                cout << "ERORR: attempting to use RDMA adaptor, "
                     << "but Wukong was built without RDMA."
                     << endl;
            }
        } else {
            tcp->send(dst_sid, dst_tid, ss.str());
        }
    }

    request_or_reply recv() {
        std::string str;
        if (global_use_rdma) {
            if (rdma != NULL) {
                str = rdma->rbfRecv(tid);
            } else {
                cout << "ERORR: attempting to use RDMA adaptor, "
                     << "but Wukong was built without RDMA."
                     << endl;
            }
        } else {
            str = tcp->recv(tid);
        }

        std::stringstream s;
        s << str;

        boost::archive::binary_iarchive ia(s);
        request_or_reply r;
        ia >> r;
        return r;
    }

    bool tryrecv(request_or_reply &r) {
        std::string str;
        if (global_use_rdma) {
            if (rdma != NULL) {
                if (!rdma->rbfTryRecv(tid, str)) return false;
            } else {
                cout << "ERORR: attempting to use RDMA adaptor, "
                     << "but Wukong was built without RDMA."
                     << endl;
            }
        } else {
            if (!tcp->tryrecv(tid, str)) return false;
        }

        std::stringstream s;
        s << str;

        boost::archive::binary_iarchive ia(s);
        ia >> r;
        return true;
    }

    template<typename T>
    void send_object(int dst_sid, int dst_tid, T &r) {
        std::stringstream ss;
        boost::archive::binary_oarchive oa(ss);
        oa << r;
        tcp->send(dst_sid, dst_tid, ss.str());
    }

    template<typename T>
    T recv_object() {
        std::string str;
        str = tcp->recv(tid);

        std::stringstream s;
        s << str;

        boost::archive::binary_iarchive ia(s);
        T r;
        ia >> r;
        return r;
    }
};
<commit_msg>fix bug<commit_after>/*
 * Copyright (c) 2016 Shanghai Jiao Tong University.
 *     All rights reserved.
 *
 *  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.
 *
 * For more about this software visit:
 *
 *      http://ipads.se.sjtu.edu.cn/projects/wukong.html
 *
 */

#pragma once

#include "config.hpp"
#include "query.hpp"
#include "tcp_adaptor.hpp"
#include "rdma_adaptor.hpp"

/// TODO: define adaptor as a C++ interface and make tcp and rdma implement it
class Adaptor {
public:
    int tid; // thread id

    TCP_Adaptor *tcp = NULL;   // communicaiton by TCP/IP
    RDMA_Adaptor *rdma = NULL; // communicaiton by RDMA

    Adaptor(int tid, TCP_Adaptor *tcp = NULL, RDMA_Adaptor *rdma = NULL)
        : tid(tid), tcp(tcp), rdma(rdma) { }

    ~Adaptor() { }

    void send(int dst_sid, int dst_tid, request_or_reply &r) {
        std::stringstream ss;
        boost::archive::binary_oarchive oa(ss);

        oa << r;
        if (global_use_rdma) {
            if (rdma) {
                rdma->rbfSend(tid, dst_sid, dst_tid, ss.str().c_str(), ss.str().size());
            } else {
                cout << "ERORR: attempting to use RDMA adaptor, "
                     << "but Wukong was built without RDMA."
                     << endl;
            }
        } else {
            tcp->send(dst_sid, dst_tid, ss.str());
        }
    }

    request_or_reply recv() {
        std::string str;
        if (global_use_rdma) {
            if (rdma) {
                str = rdma->rbfRecv(tid);
            } else {
                cout << "ERORR: attempting to use RDMA adaptor, "
                     << "but Wukong was built without RDMA."
                     << endl;
            }
        } else {
            str = tcp->recv(tid);
        }

        std::stringstream s;
        s << str;

        boost::archive::binary_iarchive ia(s);
        request_or_reply r;
        ia >> r;
        return r;
    }

    bool tryrecv(request_or_reply &r) {
        std::string str;
        if (global_use_rdma) {
            if (rdma) {
                if (!rdma->rbfTryRecv(tid, str)) return false;
            } else {
                cout << "ERORR: attempting to use RDMA adaptor, "
                     << "but Wukong was built without RDMA."
                     << endl;
            }
        } else {
            if (!tcp->tryrecv(tid, str)) return false;
        }

        std::stringstream s;
        s << str;

        boost::archive::binary_iarchive ia(s);
        ia >> r;
        return true;
    }

    template<typename T>
    void send_object(int dst_sid, int dst_tid, T &r) {
        std::stringstream ss;
        boost::archive::binary_oarchive oa(ss);
        oa << r;
        tcp->send(dst_sid, dst_tid, ss.str());
    }

    template<typename T>
    T recv_object() {
        std::string str;
        str = tcp->recv(tid);

        std::stringstream s;
        s << str;

        boost::archive::binary_iarchive ia(s);
        T r;
        ia >> r;
        return r;
    }
};
<|endoftext|>


<commit_before>// Copyright (c) 2016 Greenheart Games Pty. Ltd. All rights reserved.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.

#include <map>
#include <sstream>

#include "nan.h"
#include "steam/steam_api.h"
#include "v8.h"

#include "greenworks_async_workers.h"
#include "greenworks_utils.h"
#include "greenworks_version.h"
#include "steam_api_registry.h"
#include "steam_client.h"
#include "steam_event.h"
#include "steam_id.h"

namespace greenworks {
namespace api {
namespace {

#define MAKE_ENUM_PAIR(name) \
    { name, #name }

void FreeCallback(char* data, void* hint) {
  delete data;
}

v8::Local<v8::Object> GetSteamUserCountType(int type_id) {
  if (type_id > k_EAccountTypeMax) {
    Nan::ThrowTypeError("Bad argument");
    return Nan::New<v8::Object>();
  }
  auto type = static_cast<EAccountType>(type_id);
  std::map<EAccountType, std::string> account_types = {
    MAKE_ENUM_PAIR(k_EAccountTypeInvalid),
    MAKE_ENUM_PAIR(k_EAccountTypeIndividual),
    MAKE_ENUM_PAIR(k_EAccountTypeMultiseat),
    MAKE_ENUM_PAIR(k_EAccountTypeGameServer),
    MAKE_ENUM_PAIR(k_EAccountTypeAnonGameServer),
    MAKE_ENUM_PAIR(k_EAccountTypePending),
    MAKE_ENUM_PAIR(k_EAccountTypeContentServer),
    MAKE_ENUM_PAIR(k_EAccountTypeClan),
    MAKE_ENUM_PAIR(k_EAccountTypeChat),
    MAKE_ENUM_PAIR(k_EAccountTypeConsoleUser),
    MAKE_ENUM_PAIR(k_EAccountTypeAnonUser),
    MAKE_ENUM_PAIR(k_EAccountTypeMax)
  };
  std::string name = account_types[type];
  v8::Local<v8::Object> account_type = Nan::New<v8::Object>();
  Nan::Set(account_type, Nan::New("name").ToLocalChecked(),
           Nan::New(name).ToLocalChecked());
  Nan::Set(account_type, Nan::New("value").ToLocalChecked(), Nan::New(type_id));
  return account_type;
}

NAN_METHOD(RestartAppIfNecessary) {
  Nan::HandleScope scope;

  if (info.Length() < 1) {
    Nan::ThrowTypeError("You must pass your app ID to RestartAppIfNecessary");
    return;
  }

  if (!info[0]->IsUint32()) {
    Nan::ThrowTypeError("Your app ID argument should be an integer");
    return;
  }

  uint32 arg0 = info[0]->Uint32Value();

  bool restarting = SteamAPI_RestartAppIfNecessary(arg0);
  info.GetReturnValue().Set(Nan::New(restarting));
}

NAN_METHOD(IsSteamRunning) {
  Nan::HandleScope scope;

  bool running = SteamAPI_IsSteamRunning();
  info.GetReturnValue().Set(Nan::New(running));
}

NAN_METHOD(GetSteamId) {
  Nan::HandleScope scope;
  CSteamID user_id = SteamUser()->GetSteamID();
  v8::Local<v8::Object> flags = Nan::New<v8::Object>();
  Nan::Set(flags, Nan::New("anonymous").ToLocalChecked(),
           Nan::New(user_id.BAnonAccount()));
  Nan::Set(flags, Nan::New("anonymousGameServer").ToLocalChecked(),
           Nan::New(user_id.BAnonGameServerAccount()));
  Nan::Set(flags, Nan::New("anonymousGameServerLogin").ToLocalChecked(),
           Nan::New(user_id.BBlankAnonAccount()));
  Nan::Set(flags, Nan::New("anonymousUser").ToLocalChecked(),
           Nan::New(user_id.BAnonUserAccount()));
  Nan::Set(flags, Nan::New("chat").ToLocalChecked(),
           Nan::New(user_id.BChatAccount()));
  Nan::Set(flags, Nan::New("clan").ToLocalChecked(),
           Nan::New(user_id.BClanAccount()));
  Nan::Set(flags, Nan::New("consoleUser").ToLocalChecked(),
           Nan::New(user_id.BConsoleUserAccount()));
  Nan::Set(flags, Nan::New("contentServer").ToLocalChecked(),
           Nan::New(user_id.BContentServerAccount()));
  Nan::Set(flags, Nan::New("gameServer").ToLocalChecked(),
           Nan::New(user_id.BGameServerAccount()));
  Nan::Set(flags, Nan::New("individual").ToLocalChecked(),
           Nan::New(user_id.BIndividualAccount()));
  Nan::Set(flags, Nan::New("gameServerPersistent").ToLocalChecked(),
           Nan::New(user_id.BPersistentGameServerAccount()));
  Nan::Set(flags, Nan::New("lobby").ToLocalChecked(),
           Nan::New(user_id.IsLobby()));

  v8::Local<v8::Object> result = greenworks::SteamID::Create(user_id);
  // For backwards compatiblilty.
  Nan::Set(result, Nan::New("flags").ToLocalChecked(), flags);
  Nan::Set(result, Nan::New("type").ToLocalChecked(),
           GetSteamUserCountType(user_id.GetEAccountType()));
  Nan::Set(result, Nan::New("accountId").ToLocalChecked(),
           Nan::New<v8::Integer>(user_id.GetAccountID()));
  Nan::Set(result, Nan::New("steamId").ToLocalChecked(),
           Nan::New(utils::uint64ToString(user_id.ConvertToUint64()))
               .ToLocalChecked());
  Nan::Set(result, Nan::New("staticAccountId").ToLocalChecked(),
           Nan::New(utils::uint64ToString(user_id.GetStaticAccountKey()))
               .ToLocalChecked());
  Nan::Set(result, Nan::New("isValid").ToLocalChecked(),
           Nan::New<v8::Integer>(user_id.IsValid()));
  Nan::Set(result, Nan::New("level").ToLocalChecked(),
           Nan::New<v8::Integer>(SteamUser()->GetPlayerSteamLevel()));

  if (!SteamFriends()->RequestUserInformation(user_id, true)) {
    Nan::Set(result, Nan::New("screenName").ToLocalChecked(),
             Nan::New(SteamFriends()->GetFriendPersonaName(user_id))
                 .ToLocalChecked());
  } else {
    std::ostringstream sout;
    sout << user_id.GetAccountID();
    Nan::Set(result, Nan::New("screenName").ToLocalChecked(),
             Nan::New(sout.str()).ToLocalChecked());
  }
  info.GetReturnValue().Set(result);
}

NAN_METHOD(GetAppId) {
  Nan::HandleScope scope;
  info.GetReturnValue().Set(
      Nan::New(SteamUtils()->GetAppID()));
}

NAN_METHOD(GetCurrentGameLanguage) {
  Nan::HandleScope scope;
  info.GetReturnValue().Set(
      Nan::New(SteamApps()->GetCurrentGameLanguage()).ToLocalChecked());
}

NAN_METHOD(GetCurrentUILanguage) {
  Nan::HandleScope scope;
  info.GetReturnValue().Set(
      Nan::New(SteamUtils()->GetSteamUILanguage()).ToLocalChecked());
}

// TODO(hokein): Implement get game install directory.
NAN_METHOD(GetCurrentGameInstallDir) {
  Nan::HandleScope scope;
  info.GetReturnValue().Set(Nan::New("NOT IMPLEMENTED").ToLocalChecked());
}

NAN_METHOD(GetAppInstallDir) {
  Nan::HandleScope scope;

  if (info.Length() < 1 || !info[0]->IsUint32()) {
    THROW_BAD_ARGS("Bad arguments; expected: appid [uint32]");
  }

  AppId_t app_id = static_cast<AppId_t>(info[0]->Uint32Value());
  const int buffer_size = 260;  // MAX_PATH on 32bit Windows according to MSDN documentation
  char buffer[buffer_size];
  uint32 length = SteamApps()->GetAppInstallDir(app_id, buffer, buffer_size);

  // The length takes \0 termination into account; return length-1 to remove it since Javascript has trouble handling it
  info.GetReturnValue().Set(Nan::New(buffer, length - 1).ToLocalChecked());
}

NAN_METHOD(GetNumberOfPlayers) {
  Nan::HandleScope scope;
  if (info.Length() < 1 || !info[0]->IsFunction()) {
    THROW_BAD_ARGS("Bad arguments");
  }
  Nan::Callback* success_callback =
      new Nan::Callback(info[0].As<v8::Function>());
  Nan::Callback* error_callback = nullptr;

  if (info.Length() > 1 && info[1]->IsFunction())
    error_callback = new Nan::Callback(info[1].As<v8::Function>());

  Nan::AsyncQueueWorker(new greenworks::GetNumberOfPlayersWorker(
      success_callback, error_callback));
  info.GetReturnValue().Set(Nan::Undefined());
}

NAN_METHOD(IsGameOverlayEnabled) {
  Nan::HandleScope scope;
  info.GetReturnValue().Set(Nan::New(SteamUtils()->IsOverlayEnabled()));
}

NAN_METHOD(ActivateGameOverlay) {
  Nan::HandleScope scope;
  if (info.Length() < 1 || !info[0]->IsString()) {
    THROW_BAD_ARGS("Bad arguments");
  }
  std::string option(*(v8::String::Utf8Value(info[0])));
  SteamFriends()->ActivateGameOverlay(option.c_str());
  info.GetReturnValue().Set(Nan::Undefined());
}

NAN_METHOD(ActivateGameOverlayToWebPage) {
  Nan::HandleScope scope;
  if (info.Length() < 1 || !info[0]->IsString()) {
    THROW_BAD_ARGS("bad arguments");
  }
  std::string url = *(v8::String::Utf8Value(info[0]));
  SteamFriends()->ActivateGameOverlayToWebPage(url.c_str());
  info.GetReturnValue().Set(Nan::Undefined());
}

NAN_METHOD(IsSubscribedApp) {
  Nan::HandleScope scope;
  if (info.Length() < 1) {
    Nan::ThrowTypeError("You must pass an app ID to IsSubscribedApp");
    return;
  }

  if (!info[0]->IsUint32()) {
    Nan::ThrowTypeError("Your app ID argument should be an integer");
    return;
  }

  uint32 arg0 = info[0]->Uint32Value();

  bool subscribed = SteamApps()->BIsSubscribedApp(arg0);
  info.GetReturnValue().Set(Nan::New(subscribed));
}

NAN_METHOD(GetImageSize) {
  Nan::HandleScope scope;
  if (info.Length() < 1 && !info[0]->IsInt32()) {
    THROW_BAD_ARGS("Bad arguments");
  }
  int image_handle = info[0]->Int32Value();
  uint32 width = 0;
  uint32 height = 0;
  if (!SteamUtils()->GetImageSize(image_handle, &width, &height)) {
    THROW_BAD_ARGS("Fail to get image size");
  }
  v8::Local<v8::Object> result = Nan::New<v8::Object>();
  Nan::Set(result, Nan::New("width").ToLocalChecked(), Nan::New(width));
  Nan::Set(result, Nan::New("height").ToLocalChecked(), Nan::New(height));
  info.GetReturnValue().Set(result);
}

NAN_METHOD(GetImageRGBA) {
  Nan::HandleScope scope;
  if (info.Length() < 1 && !info[0]->IsInt32()) {
    THROW_BAD_ARGS("Bad arguments");
  }
  int image_handle = info[0]->Int32Value();
  uint32 width = 0;
  uint32 height = 0;
  if (!SteamUtils()->GetImageSize(image_handle, &width, &height)) {
    THROW_BAD_ARGS("Fail to get image size");
  }
  int buffer_size = 4 * width * height;
  auto* image_buffer = new char[buffer_size];
  if (!SteamUtils()->GetImageRGBA(image_handle,
                                  reinterpret_cast<uint8*>(image_buffer),
                                  buffer_size)) {
    THROW_BAD_ARGS("Fail to get image");
  }
  info.GetReturnValue().Set(
      Nan::NewBuffer(image_buffer, buffer_size, FreeCallback, nullptr)
          .ToLocalChecked());
}

void RegisterAPIs(v8::Local<v8::Object> target) {
  Nan::Set(target,
           Nan::New("_version").ToLocalChecked(),
           Nan::New(GREENWORKS_VERSION).ToLocalChecked());

  SET_FUNCTION("restartAppIfNecessary", RestartAppIfNecessary);
  SET_FUNCTION("isSteamRunning", IsSteamRunning);
  SET_FUNCTION("getSteamId", GetSteamId);
  SET_FUNCTION("getAppId", GetAppId);
  SET_FUNCTION("getCurrentGameLanguage", GetCurrentGameLanguage);
  SET_FUNCTION("getCurrentUILanguage", GetCurrentUILanguage);
  SET_FUNCTION("getCurrentGameInstallDir", GetCurrentGameInstallDir);
  SET_FUNCTION("getAppInstallDir", GetAppInstallDir);
  SET_FUNCTION("getNumberOfPlayers", GetNumberOfPlayers);
  SET_FUNCTION("isGameOverlayEnabled", IsGameOverlayEnabled);
  SET_FUNCTION("activateGameOverlay", ActivateGameOverlay);
  SET_FUNCTION("activateGameOverlayToWebPage", ActivateGameOverlayToWebPage);
  SET_FUNCTION("isSubscribedApp", IsSubscribedApp);
  SET_FUNCTION("getImageSize", GetImageSize);
  SET_FUNCTION("getImageRGBA", GetImageRGBA);
}

SteamAPIRegistry::Add X(RegisterAPIs);

}  // namespace
}  // namespace api
}  // namespace greenworks
<commit_msg>some tweaks.<commit_after>// Copyright (c) 2016 Greenheart Games Pty. Ltd. All rights reserved.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.

#include <map>
#include <sstream>

#include "nan.h"
#include "steam/steam_api.h"
#include "v8.h"

#include "greenworks_async_workers.h"
#include "greenworks_utils.h"
#include "greenworks_version.h"
#include "steam_api_registry.h"
#include "steam_client.h"
#include "steam_event.h"
#include "steam_id.h"

namespace greenworks {
namespace api {
namespace {

#define MAKE_ENUM_PAIR(name) \
    { name, #name }

void FreeCallback(char* data, void* hint) {
  delete data;
}

v8::Local<v8::Object> GetSteamUserCountType(int type_id) {
  if (type_id > k_EAccountTypeMax) {
    Nan::ThrowTypeError("Bad argument");
    return Nan::New<v8::Object>();
  }
  auto type = static_cast<EAccountType>(type_id);
  std::map<EAccountType, std::string> account_types = {
    MAKE_ENUM_PAIR(k_EAccountTypeInvalid),
    MAKE_ENUM_PAIR(k_EAccountTypeIndividual),
    MAKE_ENUM_PAIR(k_EAccountTypeMultiseat),
    MAKE_ENUM_PAIR(k_EAccountTypeGameServer),
    MAKE_ENUM_PAIR(k_EAccountTypeAnonGameServer),
    MAKE_ENUM_PAIR(k_EAccountTypePending),
    MAKE_ENUM_PAIR(k_EAccountTypeContentServer),
    MAKE_ENUM_PAIR(k_EAccountTypeClan),
    MAKE_ENUM_PAIR(k_EAccountTypeChat),
    MAKE_ENUM_PAIR(k_EAccountTypeConsoleUser),
    MAKE_ENUM_PAIR(k_EAccountTypeAnonUser),
    MAKE_ENUM_PAIR(k_EAccountTypeMax)
  };
  std::string name = account_types[type];
  v8::Local<v8::Object> account_type = Nan::New<v8::Object>();
  Nan::Set(account_type, Nan::New("name").ToLocalChecked(),
           Nan::New(name).ToLocalChecked());
  Nan::Set(account_type, Nan::New("value").ToLocalChecked(), Nan::New(type_id));
  return account_type;
}

NAN_METHOD(RestartAppIfNecessary) {
  Nan::HandleScope scope;

  if (info.Length() < 1) {
    Nan::ThrowTypeError("You must pass your app ID to RestartAppIfNecessary");
    return;
  }

  if (!info[0]->IsUint32()) {
    Nan::ThrowTypeError("Your app ID argument should be an integer");
    return;
  }

  uint32 arg0 = info[0]->Uint32Value();

  bool restarting = SteamAPI_RestartAppIfNecessary(arg0);
  info.GetReturnValue().Set(Nan::New(restarting));
}

NAN_METHOD(IsSteamRunning) {
  Nan::HandleScope scope;

  bool running = SteamAPI_IsSteamRunning();
  info.GetReturnValue().Set(Nan::New(running));
}

NAN_METHOD(GetSteamId) {
  Nan::HandleScope scope;
  CSteamID user_id = SteamUser()->GetSteamID();
  v8::Local<v8::Object> flags = Nan::New<v8::Object>();
  Nan::Set(flags, Nan::New("anonymous").ToLocalChecked(),
           Nan::New(user_id.BAnonAccount()));
  Nan::Set(flags, Nan::New("anonymousGameServer").ToLocalChecked(),
           Nan::New(user_id.BAnonGameServerAccount()));
  Nan::Set(flags, Nan::New("anonymousGameServerLogin").ToLocalChecked(),
           Nan::New(user_id.BBlankAnonAccount()));
  Nan::Set(flags, Nan::New("anonymousUser").ToLocalChecked(),
           Nan::New(user_id.BAnonUserAccount()));
  Nan::Set(flags, Nan::New("chat").ToLocalChecked(),
           Nan::New(user_id.BChatAccount()));
  Nan::Set(flags, Nan::New("clan").ToLocalChecked(),
           Nan::New(user_id.BClanAccount()));
  Nan::Set(flags, Nan::New("consoleUser").ToLocalChecked(),
           Nan::New(user_id.BConsoleUserAccount()));
  Nan::Set(flags, Nan::New("contentServer").ToLocalChecked(),
           Nan::New(user_id.BContentServerAccount()));
  Nan::Set(flags, Nan::New("gameServer").ToLocalChecked(),
           Nan::New(user_id.BGameServerAccount()));
  Nan::Set(flags, Nan::New("individual").ToLocalChecked(),
           Nan::New(user_id.BIndividualAccount()));
  Nan::Set(flags, Nan::New("gameServerPersistent").ToLocalChecked(),
           Nan::New(user_id.BPersistentGameServerAccount()));
  Nan::Set(flags, Nan::New("lobby").ToLocalChecked(),
           Nan::New(user_id.IsLobby()));

  v8::Local<v8::Object> result = greenworks::SteamID::Create(user_id);
  // For backwards compatiblilty.
  Nan::Set(result, Nan::New("flags").ToLocalChecked(), flags);
  Nan::Set(result, Nan::New("type").ToLocalChecked(),
           GetSteamUserCountType(user_id.GetEAccountType()));
  Nan::Set(result, Nan::New("accountId").ToLocalChecked(),
           Nan::New<v8::Integer>(user_id.GetAccountID()));
  Nan::Set(result, Nan::New("steamId").ToLocalChecked(),
           Nan::New(utils::uint64ToString(user_id.ConvertToUint64()))
               .ToLocalChecked());
  Nan::Set(result, Nan::New("staticAccountId").ToLocalChecked(),
           Nan::New(utils::uint64ToString(user_id.GetStaticAccountKey()))
               .ToLocalChecked());
  Nan::Set(result, Nan::New("isValid").ToLocalChecked(),
           Nan::New<v8::Integer>(user_id.IsValid()));
  Nan::Set(result, Nan::New("level").ToLocalChecked(),
           Nan::New<v8::Integer>(SteamUser()->GetPlayerSteamLevel()));

  if (!SteamFriends()->RequestUserInformation(user_id, true)) {
    Nan::Set(result, Nan::New("screenName").ToLocalChecked(),
             Nan::New(SteamFriends()->GetFriendPersonaName(user_id))
                 .ToLocalChecked());
  } else {
    std::ostringstream sout;
    sout << user_id.GetAccountID();
    Nan::Set(result, Nan::New("screenName").ToLocalChecked(),
             Nan::New(sout.str()).ToLocalChecked());
  }
  info.GetReturnValue().Set(result);
}

NAN_METHOD(GetAppId) {
  Nan::HandleScope scope;
  info.GetReturnValue().Set(
      Nan::New(SteamUtils()->GetAppID()));
}

NAN_METHOD(GetCurrentGameLanguage) {
  Nan::HandleScope scope;
  info.GetReturnValue().Set(
      Nan::New(SteamApps()->GetCurrentGameLanguage()).ToLocalChecked());
}

NAN_METHOD(GetCurrentUILanguage) {
  Nan::HandleScope scope;
  info.GetReturnValue().Set(
      Nan::New(SteamUtils()->GetSteamUILanguage()).ToLocalChecked());
}

// TODO(hokein): Implement get game install directory.
NAN_METHOD(GetCurrentGameInstallDir) {
  Nan::HandleScope scope;
  info.GetReturnValue().Set(Nan::New("NOT IMPLEMENTED").ToLocalChecked());
}

NAN_METHOD(GetAppInstallDir) {
  Nan::HandleScope scope;

  if (info.Length() < 1 || !info[0]->IsUint32()) {
    THROW_BAD_ARGS("Bad arguments; expected: appid [uint32]");
  }

  AppId_t app_id = static_cast<AppId_t>(info[0]->Uint32Value());
  const int buffer_size =
      260;  // MAX_PATH on 32bit Windows according to MSDN documentation
  char buffer[buffer_size];
  uint32 length = SteamApps()->GetAppInstallDir(app_id, buffer, buffer_size);

  // The length takes \0 termination into account, we don't need it in JS.
  info.GetReturnValue().Set(Nan::New(buffer, length - 1).ToLocalChecked());
}

NAN_METHOD(GetNumberOfPlayers) {
  Nan::HandleScope scope;
  if (info.Length() < 1 || !info[0]->IsFunction()) {
    THROW_BAD_ARGS("Bad arguments");
  }
  Nan::Callback* success_callback =
      new Nan::Callback(info[0].As<v8::Function>());
  Nan::Callback* error_callback = nullptr;

  if (info.Length() > 1 && info[1]->IsFunction())
    error_callback = new Nan::Callback(info[1].As<v8::Function>());

  Nan::AsyncQueueWorker(new greenworks::GetNumberOfPlayersWorker(
      success_callback, error_callback));
  info.GetReturnValue().Set(Nan::Undefined());
}

NAN_METHOD(IsGameOverlayEnabled) {
  Nan::HandleScope scope;
  info.GetReturnValue().Set(Nan::New(SteamUtils()->IsOverlayEnabled()));
}

NAN_METHOD(ActivateGameOverlay) {
  Nan::HandleScope scope;
  if (info.Length() < 1 || !info[0]->IsString()) {
    THROW_BAD_ARGS("Bad arguments");
  }
  std::string option(*(v8::String::Utf8Value(info[0])));
  SteamFriends()->ActivateGameOverlay(option.c_str());
  info.GetReturnValue().Set(Nan::Undefined());
}

NAN_METHOD(ActivateGameOverlayToWebPage) {
  Nan::HandleScope scope;
  if (info.Length() < 1 || !info[0]->IsString()) {
    THROW_BAD_ARGS("bad arguments");
  }
  std::string url = *(v8::String::Utf8Value(info[0]));
  SteamFriends()->ActivateGameOverlayToWebPage(url.c_str());
  info.GetReturnValue().Set(Nan::Undefined());
}

NAN_METHOD(IsSubscribedApp) {
  Nan::HandleScope scope;
  if (info.Length() < 1) {
    Nan::ThrowTypeError("You must pass an app ID to IsSubscribedApp");
    return;
  }

  if (!info[0]->IsUint32()) {
    Nan::ThrowTypeError("Your app ID argument should be an integer");
    return;
  }

  uint32 arg0 = info[0]->Uint32Value();

  bool subscribed = SteamApps()->BIsSubscribedApp(arg0);
  info.GetReturnValue().Set(Nan::New(subscribed));
}

NAN_METHOD(GetImageSize) {
  Nan::HandleScope scope;
  if (info.Length() < 1 && !info[0]->IsInt32()) {
    THROW_BAD_ARGS("Bad arguments");
  }
  int image_handle = info[0]->Int32Value();
  uint32 width = 0;
  uint32 height = 0;
  if (!SteamUtils()->GetImageSize(image_handle, &width, &height)) {
    THROW_BAD_ARGS("Fail to get image size");
  }
  v8::Local<v8::Object> result = Nan::New<v8::Object>();
  Nan::Set(result, Nan::New("width").ToLocalChecked(), Nan::New(width));
  Nan::Set(result, Nan::New("height").ToLocalChecked(), Nan::New(height));
  info.GetReturnValue().Set(result);
}

NAN_METHOD(GetImageRGBA) {
  Nan::HandleScope scope;
  if (info.Length() < 1 && !info[0]->IsInt32()) {
    THROW_BAD_ARGS("Bad arguments");
  }
  int image_handle = info[0]->Int32Value();
  uint32 width = 0;
  uint32 height = 0;
  if (!SteamUtils()->GetImageSize(image_handle, &width, &height)) {
    THROW_BAD_ARGS("Fail to get image size");
  }
  int buffer_size = 4 * width * height;
  auto* image_buffer = new char[buffer_size];
  if (!SteamUtils()->GetImageRGBA(image_handle,
                                  reinterpret_cast<uint8*>(image_buffer),
                                  buffer_size)) {
    THROW_BAD_ARGS("Fail to get image");
  }
  info.GetReturnValue().Set(
      Nan::NewBuffer(image_buffer, buffer_size, FreeCallback, nullptr)
          .ToLocalChecked());
}

void RegisterAPIs(v8::Local<v8::Object> target) {
  Nan::Set(target,
           Nan::New("_version").ToLocalChecked(),
           Nan::New(GREENWORKS_VERSION).ToLocalChecked());

  SET_FUNCTION("restartAppIfNecessary", RestartAppIfNecessary);
  SET_FUNCTION("isSteamRunning", IsSteamRunning);
  SET_FUNCTION("getSteamId", GetSteamId);
  SET_FUNCTION("getAppId", GetAppId);
  SET_FUNCTION("getCurrentGameLanguage", GetCurrentGameLanguage);
  SET_FUNCTION("getCurrentUILanguage", GetCurrentUILanguage);
  SET_FUNCTION("getCurrentGameInstallDir", GetCurrentGameInstallDir);
  SET_FUNCTION("getAppInstallDir", GetAppInstallDir);
  SET_FUNCTION("getNumberOfPlayers", GetNumberOfPlayers);
  SET_FUNCTION("isGameOverlayEnabled", IsGameOverlayEnabled);
  SET_FUNCTION("activateGameOverlay", ActivateGameOverlay);
  SET_FUNCTION("activateGameOverlayToWebPage", ActivateGameOverlayToWebPage);
  SET_FUNCTION("isSubscribedApp", IsSubscribedApp);
  SET_FUNCTION("getImageSize", GetImageSize);
  SET_FUNCTION("getImageRGBA", GetImageRGBA);
}

SteamAPIRegistry::Add X(RegisterAPIs);

}  // namespace
}  // namespace api
}  // namespace greenworks
<|endoftext|>


<commit_before>/*
 * Copyright 2017 WebAssembly Community Group participants
 *
 * 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 <array>
#include <cassert>
#include <shared_mutex>
#include <sstream>
#include <unordered_map>

#include "compiler-support.h"
#include "support/hash.h"
#include "wasm-features.h"
#include "wasm-type.h"

template<> class std::hash<std::vector<wasm::Type>> {
public:
  size_t operator()(const std::vector<wasm::Type>& types) const {
    uint64_t res = wasm::rehash(0, uint32_t(types.size()));
    for (auto t : types) {
      res = wasm::rehash(res, t.getID());
    }
    return res;
  }
};

size_t std::hash<wasm::Type>::operator()(const wasm::Type& type) const {
  return std::hash<uint64_t>{}(type.getID());
}

size_t std::hash<wasm::Signature>::
operator()(const wasm::Signature& sig) const {
  return wasm::rehash(uint64_t(std::hash<uint64_t>{}(sig.params.getID())),
                      uint64_t(std::hash<uint64_t>{}(sig.results.getID())));
}

namespace wasm {

namespace {

std::mutex mutex;

std::array<std::vector<Type>, Type::_last_value_type + 1> basicTypes = {
  std::vector<Type>{},
  {Type::unreachable},
  {Type::i32},
  {Type::i64},
  {Type::f32},
  {Type::f64},
  {Type::v128},
  {Type::funcref},
  {Type::anyref},
  {Type::nullref},
  {Type::exnref}};

// Track unique_ptrs for constructed types to avoid leaks
std::vector<std::unique_ptr<std::vector<Type>>> constructedTypes;

// Maps from type vectors to the canonical Type ID
std::unordered_map<std::vector<Type>, uintptr_t> indices = {
  {{}, Type::none},
  {{Type::unreachable}, Type::unreachable},
  {{Type::i32}, Type::i32},
  {{Type::i64}, Type::i64},
  {{Type::f32}, Type::f32},
  {{Type::f64}, Type::f64},
  {{Type::v128}, Type::v128},
  {{Type::funcref}, Type::funcref},
  {{Type::anyref}, Type::anyref},
  {{Type::nullref}, Type::nullref},
  {{Type::exnref}, Type::exnref},
};

} // anonymous namespace

void Type::init(const std::vector<Type>& types) {
#ifndef NDEBUG
  for (Type t : types) {
    assert(t.isSingle() && t.isConcrete());
  }
#endif

  if (types.size() == 0) {
    id = none;
    return;
  }
  if (types.size() == 1) {
    *this = types[0];
    return;
  }

  // Add a new type if it hasn't been added concurrently
  std::lock_guard<std::mutex> lock(mutex);
  auto indexIt = indices.find(types);
  if (indexIt != indices.end()) {
    id = indexIt->second;
  } else {
    auto vec = std::make_unique<std::vector<Type>>(types);
    id = uintptr_t(vec.get());
    constructedTypes.push_back(std::move(vec));
    assert(id > _last_value_type);
    indices[types] = id;
  }
}

Type::Type(std::initializer_list<Type> types) { init(types); }

Type::Type(const std::vector<Type>& types) { init(types); }

size_t Type::size() const { return expand().size(); }

const std::vector<Type>& Type::expand() const {
  if (id <= _last_value_type) {
    return basicTypes[id];
  } else {
    return *(std::vector<Type>*)id;
  }
}

bool Type::operator<(const Type& other) const {
  const std::vector<Type>& these = expand();
  const std::vector<Type>& others = other.expand();
  return std::lexicographical_compare(
    these.begin(),
    these.end(),
    others.begin(),
    others.end(),
    [](const Type& a, const Type& b) { return a.getSingle() < b.getSingle(); });
}

unsigned Type::getByteSize() const {
  // TODO: alignment?
  auto getSingleByteSize = [](Type t) {
    switch (t.getSingle()) {
      case Type::i32:
      case Type::f32:
        return 4;
      case Type::i64:
      case Type::f64:
        return 8;
      case Type::v128:
        return 16;
      case Type::funcref:
      case Type::anyref:
      case Type::nullref:
      case Type::exnref:
      case Type::none:
      case Type::unreachable:
        break;
    }
    WASM_UNREACHABLE("invalid type");
  };

  if (isSingle()) {
    return getSingleByteSize(*this);
  }

  unsigned size = 0;
  for (auto t : expand()) {
    size += getSingleByteSize(t);
  }
  return size;
}

Type Type::reinterpret() const {
  assert(isSingle() && "reinterpretType only works with single types");
  Type singleType = *expand().begin();
  switch (singleType.getSingle()) {
    case Type::i32:
      return f32;
    case Type::i64:
      return f64;
    case Type::f32:
      return i32;
    case Type::f64:
      return i64;
    case Type::v128:
    case Type::funcref:
    case Type::anyref:
    case Type::nullref:
    case Type::exnref:
    case Type::none:
    case Type::unreachable:
      WASM_UNREACHABLE("invalid type");
  }
  WASM_UNREACHABLE("invalid type");
}

FeatureSet Type::getFeatures() const {
  auto getSingleFeatures = [](Type t) {
    switch (t.getSingle()) {
      case Type::v128:
        return FeatureSet::SIMD;
      case Type::anyref:
        return FeatureSet::ReferenceTypes;
      case Type::exnref:
        return FeatureSet::ExceptionHandling;
      default:
        return FeatureSet::MVP;
    }
  };

  if (isSingle()) {
    return getSingleFeatures(*this);
  }

  FeatureSet feats = FeatureSet::Multivalue;
  for (Type t : expand()) {
    feats |= getSingleFeatures(t);
  }
  return feats;
}

Type Type::get(unsigned byteSize, bool float_) {
  if (byteSize < 4) {
    return Type::i32;
  }
  if (byteSize == 4) {
    return float_ ? Type::f32 : Type::i32;
  }
  if (byteSize == 8) {
    return float_ ? Type::f64 : Type::i64;
  }
  if (byteSize == 16) {
    return Type::v128;
  }
  WASM_UNREACHABLE("invalid size");
}

bool Type::isSubType(Type left, Type right) {
  if (left == right) {
    return true;
  }
  if (left.isRef() && right.isRef() &&
      (right == Type::anyref || left == Type::nullref)) {
    return true;
  }
  if (left.isMulti() && right.isMulti()) {
    const auto& leftElems = left.expand();
    const auto& rightElems = right.expand();
    if (leftElems.size() != rightElems.size()) {
      return false;
    }
    for (size_t i = 0; i < leftElems.size(); ++i) {
      if (!isSubType(leftElems[i], rightElems[i])) {
        return false;
      }
    }
    return true;
  }
  return false;
}

Type Type::getLeastUpperBound(Type a, Type b) {
  if (a == b) {
    return a;
  }
  if (a == Type::unreachable) {
    return b;
  }
  if (b == Type::unreachable) {
    return a;
  }
  if (a.size() != b.size()) {
    return Type::none; // a poison value that must not be consumed
  }
  if (a.isMulti()) {
    std::vector<Type> types;
    types.resize(a.size());
    const auto& as = a.expand();
    const auto& bs = b.expand();
    for (size_t i = 0; i < types.size(); ++i) {
      types[i] = getLeastUpperBound(as[i], bs[i]);
      if (types[i] == Type::none) {
        return Type::none;
      }
    }
    return Type(types);
  }
  if (!a.isRef() || !b.isRef()) {
    return Type::none;
  }
  if (a == Type::nullref) {
    return b;
  }
  if (b == Type::nullref) {
    return a;
  }
  return Type::anyref;
}

namespace {

std::ostream&
printPrefixedTypes(std::ostream& os, const char* prefix, Type type) {
  os << '(' << prefix;
  for (auto t : type.expand()) {
    os << " " << t;
  }
  os << ')';
  return os;
}

template<typename T> std::string genericToString(const T& t) {
  std::ostringstream ss;
  ss << t;
  return ss.str();
}

} // anonymous namespace

std::string Type::toString() const { return genericToString(*this); }

std::string ParamType::toString() const { return genericToString(*this); }

std::string ResultType::toString() const { return genericToString(*this); }

bool Signature::operator<(const Signature& other) const {
  if (results < other.results) {
    return true;
  } else if (other.results < results) {
    return false;
  } else {
    return params < other.params;
  }
}

std::ostream& operator<<(std::ostream& os, Type type) {
  if (type.isMulti()) {
    os << '(';
    const std::vector<Type>& types = type.expand();
    for (size_t i = 0; i < types.size(); ++i) {
      os << types[i];
      if (i < types.size() - 1) {
        os << ", ";
      }
    }
    os << ')';
  } else {
    switch (type.getSingle()) {
      case Type::none:
        os << "none";
        break;
      case Type::unreachable:
        os << "unreachable";
        break;
      case Type::i32:
        os << "i32";
        break;
      case Type::i64:
        os << "i64";
        break;
      case Type::f32:
        os << "f32";
        break;
      case Type::f64:
        os << "f64";
        break;
      case Type::v128:
        os << "v128";
        break;
      case Type::funcref:
        os << "funcref";
        break;
      case Type::anyref:
        os << "anyref";
        break;
      case Type::nullref:
        os << "nullref";
        break;
      case Type::exnref:
        os << "exnref";
        break;
    }
  }
  return os;
}

std::ostream& operator<<(std::ostream& os, ParamType param) {
  return printPrefixedTypes(os, "param", param.type);
}

std::ostream& operator<<(std::ostream& os, ResultType param) {
  return printPrefixedTypes(os, "result", param.type);
}

std::ostream& operator<<(std::ostream& os, Signature sig) {
  return os << "Signature(" << sig.params << " => " << sig.results << ")";
}

} // namespace wasm
<commit_msg>Fix build with a sprinkling of braces (#2766)<commit_after>/*
 * Copyright 2017 WebAssembly Community Group participants
 *
 * 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 <array>
#include <cassert>
#include <shared_mutex>
#include <sstream>
#include <unordered_map>

#include "compiler-support.h"
#include "support/hash.h"
#include "wasm-features.h"
#include "wasm-type.h"

template<> class std::hash<std::vector<wasm::Type>> {
public:
  size_t operator()(const std::vector<wasm::Type>& types) const {
    uint64_t res = wasm::rehash(0, uint32_t(types.size()));
    for (auto t : types) {
      res = wasm::rehash(res, t.getID());
    }
    return res;
  }
};

size_t std::hash<wasm::Type>::operator()(const wasm::Type& type) const {
  return std::hash<uint64_t>{}(type.getID());
}

size_t std::hash<wasm::Signature>::
operator()(const wasm::Signature& sig) const {
  return wasm::rehash(uint64_t(std::hash<uint64_t>{}(sig.params.getID())),
                      uint64_t(std::hash<uint64_t>{}(sig.results.getID())));
}

namespace wasm {

namespace {

std::mutex mutex;

std::array<std::vector<Type>, Type::_last_value_type + 1> basicTypes = {
  {{},
   {Type::unreachable},
   {Type::i32},
   {Type::i64},
   {Type::f32},
   {Type::f64},
   {Type::v128},
   {Type::funcref},
   {Type::anyref},
   {Type::nullref},
   {Type::exnref}}};

// Track unique_ptrs for constructed types to avoid leaks
std::vector<std::unique_ptr<std::vector<Type>>> constructedTypes;

// Maps from type vectors to the canonical Type ID
std::unordered_map<std::vector<Type>, uintptr_t> indices = {
  {{}, Type::none},
  {{Type::unreachable}, Type::unreachable},
  {{Type::i32}, Type::i32},
  {{Type::i64}, Type::i64},
  {{Type::f32}, Type::f32},
  {{Type::f64}, Type::f64},
  {{Type::v128}, Type::v128},
  {{Type::funcref}, Type::funcref},
  {{Type::anyref}, Type::anyref},
  {{Type::nullref}, Type::nullref},
  {{Type::exnref}, Type::exnref},
};

} // anonymous namespace

void Type::init(const std::vector<Type>& types) {
#ifndef NDEBUG
  for (Type t : types) {
    assert(t.isSingle() && t.isConcrete());
  }
#endif

  if (types.size() == 0) {
    id = none;
    return;
  }
  if (types.size() == 1) {
    *this = types[0];
    return;
  }

  // Add a new type if it hasn't been added concurrently
  std::lock_guard<std::mutex> lock(mutex);
  auto indexIt = indices.find(types);
  if (indexIt != indices.end()) {
    id = indexIt->second;
  } else {
    auto vec = std::make_unique<std::vector<Type>>(types);
    id = uintptr_t(vec.get());
    constructedTypes.push_back(std::move(vec));
    assert(id > _last_value_type);
    indices[types] = id;
  }
}

Type::Type(std::initializer_list<Type> types) { init(types); }

Type::Type(const std::vector<Type>& types) { init(types); }

size_t Type::size() const { return expand().size(); }

const std::vector<Type>& Type::expand() const {
  if (id <= _last_value_type) {
    return basicTypes[id];
  } else {
    return *(std::vector<Type>*)id;
  }
}

bool Type::operator<(const Type& other) const {
  const std::vector<Type>& these = expand();
  const std::vector<Type>& others = other.expand();
  return std::lexicographical_compare(
    these.begin(),
    these.end(),
    others.begin(),
    others.end(),
    [](const Type& a, const Type& b) { return a.getSingle() < b.getSingle(); });
}

unsigned Type::getByteSize() const {
  // TODO: alignment?
  auto getSingleByteSize = [](Type t) {
    switch (t.getSingle()) {
      case Type::i32:
      case Type::f32:
        return 4;
      case Type::i64:
      case Type::f64:
        return 8;
      case Type::v128:
        return 16;
      case Type::funcref:
      case Type::anyref:
      case Type::nullref:
      case Type::exnref:
      case Type::none:
      case Type::unreachable:
        break;
    }
    WASM_UNREACHABLE("invalid type");
  };

  if (isSingle()) {
    return getSingleByteSize(*this);
  }

  unsigned size = 0;
  for (auto t : expand()) {
    size += getSingleByteSize(t);
  }
  return size;
}

Type Type::reinterpret() const {
  assert(isSingle() && "reinterpretType only works with single types");
  Type singleType = *expand().begin();
  switch (singleType.getSingle()) {
    case Type::i32:
      return f32;
    case Type::i64:
      return f64;
    case Type::f32:
      return i32;
    case Type::f64:
      return i64;
    case Type::v128:
    case Type::funcref:
    case Type::anyref:
    case Type::nullref:
    case Type::exnref:
    case Type::none:
    case Type::unreachable:
      WASM_UNREACHABLE("invalid type");
  }
  WASM_UNREACHABLE("invalid type");
}

FeatureSet Type::getFeatures() const {
  auto getSingleFeatures = [](Type t) {
    switch (t.getSingle()) {
      case Type::v128:
        return FeatureSet::SIMD;
      case Type::anyref:
        return FeatureSet::ReferenceTypes;
      case Type::exnref:
        return FeatureSet::ExceptionHandling;
      default:
        return FeatureSet::MVP;
    }
  };

  if (isSingle()) {
    return getSingleFeatures(*this);
  }

  FeatureSet feats = FeatureSet::Multivalue;
  for (Type t : expand()) {
    feats |= getSingleFeatures(t);
  }
  return feats;
}

Type Type::get(unsigned byteSize, bool float_) {
  if (byteSize < 4) {
    return Type::i32;
  }
  if (byteSize == 4) {
    return float_ ? Type::f32 : Type::i32;
  }
  if (byteSize == 8) {
    return float_ ? Type::f64 : Type::i64;
  }
  if (byteSize == 16) {
    return Type::v128;
  }
  WASM_UNREACHABLE("invalid size");
}

bool Type::isSubType(Type left, Type right) {
  if (left == right) {
    return true;
  }
  if (left.isRef() && right.isRef() &&
      (right == Type::anyref || left == Type::nullref)) {
    return true;
  }
  if (left.isMulti() && right.isMulti()) {
    const auto& leftElems = left.expand();
    const auto& rightElems = right.expand();
    if (leftElems.size() != rightElems.size()) {
      return false;
    }
    for (size_t i = 0; i < leftElems.size(); ++i) {
      if (!isSubType(leftElems[i], rightElems[i])) {
        return false;
      }
    }
    return true;
  }
  return false;
}

Type Type::getLeastUpperBound(Type a, Type b) {
  if (a == b) {
    return a;
  }
  if (a == Type::unreachable) {
    return b;
  }
  if (b == Type::unreachable) {
    return a;
  }
  if (a.size() != b.size()) {
    return Type::none; // a poison value that must not be consumed
  }
  if (a.isMulti()) {
    std::vector<Type> types;
    types.resize(a.size());
    const auto& as = a.expand();
    const auto& bs = b.expand();
    for (size_t i = 0; i < types.size(); ++i) {
      types[i] = getLeastUpperBound(as[i], bs[i]);
      if (types[i] == Type::none) {
        return Type::none;
      }
    }
    return Type(types);
  }
  if (!a.isRef() || !b.isRef()) {
    return Type::none;
  }
  if (a == Type::nullref) {
    return b;
  }
  if (b == Type::nullref) {
    return a;
  }
  return Type::anyref;
}

namespace {

std::ostream&
printPrefixedTypes(std::ostream& os, const char* prefix, Type type) {
  os << '(' << prefix;
  for (auto t : type.expand()) {
    os << " " << t;
  }
  os << ')';
  return os;
}

template<typename T> std::string genericToString(const T& t) {
  std::ostringstream ss;
  ss << t;
  return ss.str();
}

} // anonymous namespace

std::string Type::toString() const { return genericToString(*this); }

std::string ParamType::toString() const { return genericToString(*this); }

std::string ResultType::toString() const { return genericToString(*this); }

bool Signature::operator<(const Signature& other) const {
  if (results < other.results) {
    return true;
  } else if (other.results < results) {
    return false;
  } else {
    return params < other.params;
  }
}

std::ostream& operator<<(std::ostream& os, Type type) {
  if (type.isMulti()) {
    os << '(';
    const std::vector<Type>& types = type.expand();
    for (size_t i = 0; i < types.size(); ++i) {
      os << types[i];
      if (i < types.size() - 1) {
        os << ", ";
      }
    }
    os << ')';
  } else {
    switch (type.getSingle()) {
      case Type::none:
        os << "none";
        break;
      case Type::unreachable:
        os << "unreachable";
        break;
      case Type::i32:
        os << "i32";
        break;
      case Type::i64:
        os << "i64";
        break;
      case Type::f32:
        os << "f32";
        break;
      case Type::f64:
        os << "f64";
        break;
      case Type::v128:
        os << "v128";
        break;
      case Type::funcref:
        os << "funcref";
        break;
      case Type::anyref:
        os << "anyref";
        break;
      case Type::nullref:
        os << "nullref";
        break;
      case Type::exnref:
        os << "exnref";
        break;
    }
  }
  return os;
}

std::ostream& operator<<(std::ostream& os, ParamType param) {
  return printPrefixedTypes(os, "param", param.type);
}

std::ostream& operator<<(std::ostream& os, ResultType param) {
  return printPrefixedTypes(os, "result", param.type);
}

std::ostream& operator<<(std::ostream& os, Signature sig) {
  return os << "Signature(" << sig.params << " => " << sig.results << ")";
}

} // namespace wasm
<|endoftext|>


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

#pragma hdrstop

#ifndef _SFXAPP_HXX //autogen
#include <sfx2/app.hxx>
#endif
#ifndef _SV_VIRDEV_HXX //autogen
#include <vcl/virdev.hxx>
#endif
#ifndef _STRING_HXX
#include <tools/string.hxx>
#endif
#ifndef _TOOLS_TENCCVT_HXX
#include <tools/tenccvt.hxx>
#endif
#ifndef _OSL_THREAD_H_
#include <osl/thread.h>
#endif

#include <tools/stream.hxx>

#include "starmath.hrc"

#include "utility.hxx"
#include "dialog.hxx"
#include "view.hxx"
#include "smdll.hxx"

// return pointer to active SmViewShell, if this is not possible
// return 0 instead.
//!! Since this method is based on the current focus it is somewhat
//!! unreliable and may return unexpected 0 pointers!
SmViewShell * SmGetActiveView()
{
    SfxViewShell *pView = SfxViewShell::Current();
    return PTR_CAST(SmViewShell, pView);
}

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

/**************************************************************************/

SmPickList::SmPickList(USHORT nInitSize, USHORT nMaxSize) :
    SfxPtrArr((BYTE) nInitSize, 1)
{
    nSize = nMaxSize;
}

SmPickList::~SmPickList()
{
    Clear();
}

SmPickList& SmPickList::operator=(const SmPickList& rList)
{
    USHORT  nPos;

    Clear();
    nSize = rList.nSize;
    for (nPos = 0; nPos < rList.Count(); nPos++)
        InsertPtr(nPos, CreateItem(rList.Get(nPos)));

    return *this;
}

void SmPickList::Insert(const void *pItem)
{
    Remove(pItem);
    InsertPtr(0, CreateItem(pItem));

    if (Count() > nSize)
    {
        DestroyItem(GetPtr(nSize));
        RemovePtr(nSize, 1);
    }
}

void SmPickList::Update(const void *pItem, const void *pNewItem)
{
    USHORT  nPos;

    for (nPos = 0; nPos < Count(); nPos++)
        if (CompareItem(GetPtr(nPos), pItem))
        {
            DestroyItem(GetPtr(nPos));
            GetPtr(nPos) = CreateItem(pNewItem);
            break;
        }
}

void SmPickList::Remove(const void *pItem)
{
    USHORT  nPos;

    for (nPos = 0; nPos < Count(); nPos++)
        if (CompareItem(GetPtr(nPos), pItem))
        {
            DestroyItem(GetPtr(nPos));
            RemovePtr(nPos, 1);
            break;
        }
}

void SmPickList::SetSize(USHORT nNewSize)
{
    nSize = nNewSize;

    while (Count() > nSize)
    {
        DestroyItem(GetPtr(Count() - 1));
        RemovePtr(Count() - 1, 1);
    }
}

BOOL SmPickList::Contains(const void *pItem) const
{
    USHORT  nPos;

    for (nPos = 0; nPos < Count(); nPos++)
        if (CompareItem(GetPtr(nPos), pItem))
            return TRUE;

    return FALSE;
}

void SmPickList::Clear()
{
    USHORT  nPos;

    for (nPos = 0; nPos < Count(); nPos++)
        DestroyItem(GetPtr(nPos));

    RemovePtr(0, Count());
}

/**************************************************************************/
/**************************************************************************/

void * SmFontPickList::CreateItem(const String& rString)
{
    return new Font();
}

void * SmFontPickList::CreateItem(const void *pItem)
{
    return new Font(*((Font *) pItem));
}

void SmFontPickList::DestroyItem(void *pItem)
{
    delete (Font *)pItem;
}

BOOL SmFontPickList::CompareItem(const void *pFirstItem, const void *pSecondItem) const
{
    Font    *pFirstFont, *pSecondFont;

    pFirstFont  = (Font *)pFirstItem;
    pSecondFont = (Font *)pSecondItem;

    if (pFirstFont->GetName() == pSecondFont->GetName())
        if ((pFirstFont->GetFamily()  == pSecondFont->GetFamily())  &&
            (pFirstFont->GetCharSet() == pSecondFont->GetCharSet()) &&
            (pFirstFont->GetWeight()  == pSecondFont->GetWeight())  &&
            (pFirstFont->GetItalic()  == pSecondFont->GetItalic()))
            return (TRUE);

    return FALSE;
}

String SmFontPickList::GetStringItem(void *pItem)
{
    Font   *pFont;
    String  aString;
    const sal_Char *pDelim = ", ";

    pFont = (Font *)pItem;

    aString = pFont->GetName();

    if (IsItalic( *pFont ))
    {
        aString.AppendAscii( pDelim );
        aString += String(SmResId(RID_FONTITALIC));
    }
    if (IsBold( *pFont ))    // bold?
    {
        aString.AppendAscii( pDelim );
        aString += String(SmResId(RID_FONTBOLD));
    }

    return (aString);
}

void SmFontPickList::Insert(const Font &rFont)
{
    SmPickList::Insert((void *)&rFont);
}

void SmFontPickList::Update(const Font &rFont, const Font &rNewFont)
{
    SmPickList::Update((void *)&rFont, (void *)&rNewFont);
}

void SmFontPickList::Remove(const Font &rFont)
{
    SmPickList::Remove((void *)&rFont);
}

void SmFontPickList::ReadFrom(const SmFontDialog& rDialog)
{
    Insert(rDialog.GetFont());
}

void SmFontPickList::WriteTo(SmFontDialog& rDialog) const
{
    rDialog.SetFont(Get());
}

/**************************************************************************/

/**************************************************************************/

IMPL_LINK( SmFontPickListBox, SelectHdl, ListBox *, pListBox )
{
    USHORT  nPos;
    String  aString;

    nPos = GetSelectEntryPos();

    if (nPos != 0)
    {
        SmFontPickList::Insert(Get(nPos));
        aString = GetEntry(nPos);
        RemoveEntry(nPos);
        InsertEntry(aString, 0);
    }

    SelectEntryPos(0);

    return 0;
}

SmFontPickListBox::SmFontPickListBox(Window* pParent, WinBits nWinStyle, USHORT nMax) :
    SmFontPickList(nMax, nMax),
    ListBox(pParent, nWinStyle)
{
    SetSelectHdl(LINK(this, SmFontPickListBox, SelectHdl));
}

SmFontPickListBox::SmFontPickListBox(Window* pParent, const ResId& rResId, USHORT nMax) :
    SmFontPickList(nMax, nMax),
    ListBox(pParent, rResId)
{
    SetSelectHdl(LINK(this, SmFontPickListBox, SelectHdl));
}

SmFontPickListBox& SmFontPickListBox::operator=(const SmFontPickList& rList)
{
    USHORT nPos;

    *(SmFontPickList *)this = rList;

    for (nPos = 0; nPos < Count(); nPos++)
        InsertEntry(GetStringItem(GetPtr(nPos)), nPos);

    if (Count() > 0)
        SelectEntry(GetStringItem(GetPtr(0)));

    return *this;
}

void SmFontPickListBox::Insert(const Font &rFont)
{
    SmFontPickList::Insert(rFont);

    RemoveEntry(GetStringItem(GetPtr(0)));
    InsertEntry(GetStringItem(GetPtr(0)), 0);
    SelectEntry(GetStringItem(GetPtr(0)));

    while (GetEntryCount() > nSize)
        RemoveEntry(GetEntryCount() - 1);

    return;
}

void SmFontPickListBox::Update(const Font &rFont, const Font &rNewFont)
{
    SmFontPickList::Update(rFont, rNewFont);

    // ********************** hier fehlt noch was

    return;
}

void SmFontPickListBox::Remove(const Font &rFont)
{
    SmFontPickList::Remove(rFont);

    // ********************** hier fehlt noch was

    return;
}

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

BOOL IsItalic( const Font &rFont )
{
    FontItalic eItalic = rFont.GetItalic();
    // the code below leaves only _NONE and _DONTKNOW as not italic
    return eItalic == ITALIC_OBLIQUE  ||  eItalic == ITALIC_NORMAL;
}

BOOL IsBold( const Font &rFont )
{
    FontWeight eWeight = rFont.GetWeight();
    return eWeight != WEIGHT_DONTKNOW && eWeight > WEIGHT_NORMAL;
}

void SmFace::Impl_Init()
{
    SetSize( GetSize() );
    SetTransparent( TRUE );
    SetAlign( ALIGN_BASELINE );
    SetColor( COL_AUTO );
}

void SmFace::SetSize(const Size& rSize)
{
    Size  aSize (rSize);

    // check the requested size against minimum value
    static int __READONLY_DATA  nMinVal = SmPtsTo100th_mm(2);

    if (aSize.Height() < nMinVal)
        aSize.Height() = nMinVal;

    //! we don't force a maximum value here because this may prevent eg the
    //! parentheses in "left ( ... right )" from matching up with large
    //! bodies (eg stack{...} with many entries).
    //! Of course this is holds only if characters are used and not polygons.

    Font::SetSize(aSize);
}

long SmFace::GetBorderWidth() const
{
    if (nBorderWidth < 0)
        return GetDefaultBorderWidth();
    else
        return nBorderWidth;
}

SmFace & SmFace::operator = (const SmFace &rFace)
{
    Font::operator = (rFace);
    nBorderWidth = -1;
    return *this;
}

SmFace & operator *= (SmFace &rFace, const Fraction &rFrac)
    // scales the width and height of 'rFace' by 'rFrac' and returns a
    // reference to 'rFace'.
    // It's main use is to make scaling fonts look easier.
{   const Size &rFaceSize = rFace.GetSize();

    rFace.SetSize(Size(Fraction(rFaceSize.Width())  *= rFrac,
                       Fraction(rFaceSize.Height()) *= rFrac));
    return rFace;
}

<commit_msg>INTEGRATION: CWS pchfix02 (1.16.46); FILE MERGED 2006/09/01 17:40:46 kaib 1.16.46.1: #i68856# Added header markers and pch files<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: utility.cxx,v $
 *
 *  $Revision: 1.17 $
 *
 *  last change: $Author: obo $ $Date: 2006-09-17 07:56:54 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

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

#ifndef _SFXAPP_HXX //autogen
#include <sfx2/app.hxx>
#endif
#ifndef _SV_VIRDEV_HXX //autogen
#include <vcl/virdev.hxx>
#endif
#ifndef _STRING_HXX
#include <tools/string.hxx>
#endif
#ifndef _TOOLS_TENCCVT_HXX
#include <tools/tenccvt.hxx>
#endif
#ifndef _OSL_THREAD_H_
#include <osl/thread.h>
#endif

#include <tools/stream.hxx>

#include "starmath.hrc"

#include "utility.hxx"
#include "dialog.hxx"
#include "view.hxx"
#include "smdll.hxx"

// return pointer to active SmViewShell, if this is not possible
// return 0 instead.
//!! Since this method is based on the current focus it is somewhat
//!! unreliable and may return unexpected 0 pointers!
SmViewShell * SmGetActiveView()
{
    SfxViewShell *pView = SfxViewShell::Current();
    return PTR_CAST(SmViewShell, pView);
}

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

/**************************************************************************/

SmPickList::SmPickList(USHORT nInitSize, USHORT nMaxSize) :
    SfxPtrArr((BYTE) nInitSize, 1)
{
    nSize = nMaxSize;
}

SmPickList::~SmPickList()
{
    Clear();
}

SmPickList& SmPickList::operator=(const SmPickList& rList)
{
    USHORT  nPos;

    Clear();
    nSize = rList.nSize;
    for (nPos = 0; nPos < rList.Count(); nPos++)
        InsertPtr(nPos, CreateItem(rList.Get(nPos)));

    return *this;
}

void SmPickList::Insert(const void *pItem)
{
    Remove(pItem);
    InsertPtr(0, CreateItem(pItem));

    if (Count() > nSize)
    {
        DestroyItem(GetPtr(nSize));
        RemovePtr(nSize, 1);
    }
}

void SmPickList::Update(const void *pItem, const void *pNewItem)
{
    USHORT  nPos;

    for (nPos = 0; nPos < Count(); nPos++)
        if (CompareItem(GetPtr(nPos), pItem))
        {
            DestroyItem(GetPtr(nPos));
            GetPtr(nPos) = CreateItem(pNewItem);
            break;
        }
}

void SmPickList::Remove(const void *pItem)
{
    USHORT  nPos;

    for (nPos = 0; nPos < Count(); nPos++)
        if (CompareItem(GetPtr(nPos), pItem))
        {
            DestroyItem(GetPtr(nPos));
            RemovePtr(nPos, 1);
            break;
        }
}

void SmPickList::SetSize(USHORT nNewSize)
{
    nSize = nNewSize;

    while (Count() > nSize)
    {
        DestroyItem(GetPtr(Count() - 1));
        RemovePtr(Count() - 1, 1);
    }
}

BOOL SmPickList::Contains(const void *pItem) const
{
    USHORT  nPos;

    for (nPos = 0; nPos < Count(); nPos++)
        if (CompareItem(GetPtr(nPos), pItem))
            return TRUE;

    return FALSE;
}

void SmPickList::Clear()
{
    USHORT  nPos;

    for (nPos = 0; nPos < Count(); nPos++)
        DestroyItem(GetPtr(nPos));

    RemovePtr(0, Count());
}

/**************************************************************************/
/**************************************************************************/

void * SmFontPickList::CreateItem(const String& rString)
{
    return new Font();
}

void * SmFontPickList::CreateItem(const void *pItem)
{
    return new Font(*((Font *) pItem));
}

void SmFontPickList::DestroyItem(void *pItem)
{
    delete (Font *)pItem;
}

BOOL SmFontPickList::CompareItem(const void *pFirstItem, const void *pSecondItem) const
{
    Font    *pFirstFont, *pSecondFont;

    pFirstFont  = (Font *)pFirstItem;
    pSecondFont = (Font *)pSecondItem;

    if (pFirstFont->GetName() == pSecondFont->GetName())
        if ((pFirstFont->GetFamily()  == pSecondFont->GetFamily())  &&
            (pFirstFont->GetCharSet() == pSecondFont->GetCharSet()) &&
            (pFirstFont->GetWeight()  == pSecondFont->GetWeight())  &&
            (pFirstFont->GetItalic()  == pSecondFont->GetItalic()))
            return (TRUE);

    return FALSE;
}

String SmFontPickList::GetStringItem(void *pItem)
{
    Font   *pFont;
    String  aString;
    const sal_Char *pDelim = ", ";

    pFont = (Font *)pItem;

    aString = pFont->GetName();

    if (IsItalic( *pFont ))
    {
        aString.AppendAscii( pDelim );
        aString += String(SmResId(RID_FONTITALIC));
    }
    if (IsBold( *pFont ))    // bold?
    {
        aString.AppendAscii( pDelim );
        aString += String(SmResId(RID_FONTBOLD));
    }

    return (aString);
}

void SmFontPickList::Insert(const Font &rFont)
{
    SmPickList::Insert((void *)&rFont);
}

void SmFontPickList::Update(const Font &rFont, const Font &rNewFont)
{
    SmPickList::Update((void *)&rFont, (void *)&rNewFont);
}

void SmFontPickList::Remove(const Font &rFont)
{
    SmPickList::Remove((void *)&rFont);
}

void SmFontPickList::ReadFrom(const SmFontDialog& rDialog)
{
    Insert(rDialog.GetFont());
}

void SmFontPickList::WriteTo(SmFontDialog& rDialog) const
{
    rDialog.SetFont(Get());
}

/**************************************************************************/

/**************************************************************************/

IMPL_LINK( SmFontPickListBox, SelectHdl, ListBox *, pListBox )
{
    USHORT  nPos;
    String  aString;

    nPos = GetSelectEntryPos();

    if (nPos != 0)
    {
        SmFontPickList::Insert(Get(nPos));
        aString = GetEntry(nPos);
        RemoveEntry(nPos);
        InsertEntry(aString, 0);
    }

    SelectEntryPos(0);

    return 0;
}

SmFontPickListBox::SmFontPickListBox(Window* pParent, WinBits nWinStyle, USHORT nMax) :
    SmFontPickList(nMax, nMax),
    ListBox(pParent, nWinStyle)
{
    SetSelectHdl(LINK(this, SmFontPickListBox, SelectHdl));
}

SmFontPickListBox::SmFontPickListBox(Window* pParent, const ResId& rResId, USHORT nMax) :
    SmFontPickList(nMax, nMax),
    ListBox(pParent, rResId)
{
    SetSelectHdl(LINK(this, SmFontPickListBox, SelectHdl));
}

SmFontPickListBox& SmFontPickListBox::operator=(const SmFontPickList& rList)
{
    USHORT nPos;

    *(SmFontPickList *)this = rList;

    for (nPos = 0; nPos < Count(); nPos++)
        InsertEntry(GetStringItem(GetPtr(nPos)), nPos);

    if (Count() > 0)
        SelectEntry(GetStringItem(GetPtr(0)));

    return *this;
}

void SmFontPickListBox::Insert(const Font &rFont)
{
    SmFontPickList::Insert(rFont);

    RemoveEntry(GetStringItem(GetPtr(0)));
    InsertEntry(GetStringItem(GetPtr(0)), 0);
    SelectEntry(GetStringItem(GetPtr(0)));

    while (GetEntryCount() > nSize)
        RemoveEntry(GetEntryCount() - 1);

    return;
}

void SmFontPickListBox::Update(const Font &rFont, const Font &rNewFont)
{
    SmFontPickList::Update(rFont, rNewFont);

    // ********************** hier fehlt noch was

    return;
}

void SmFontPickListBox::Remove(const Font &rFont)
{
    SmFontPickList::Remove(rFont);

    // ********************** hier fehlt noch was

    return;
}

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

BOOL IsItalic( const Font &rFont )
{
    FontItalic eItalic = rFont.GetItalic();
    // the code below leaves only _NONE and _DONTKNOW as not italic
    return eItalic == ITALIC_OBLIQUE  ||  eItalic == ITALIC_NORMAL;
}

BOOL IsBold( const Font &rFont )
{
    FontWeight eWeight = rFont.GetWeight();
    return eWeight != WEIGHT_DONTKNOW && eWeight > WEIGHT_NORMAL;
}

void SmFace::Impl_Init()
{
    SetSize( GetSize() );
    SetTransparent( TRUE );
    SetAlign( ALIGN_BASELINE );
    SetColor( COL_AUTO );
}

void SmFace::SetSize(const Size& rSize)
{
    Size  aSize (rSize);

    // check the requested size against minimum value
    static int __READONLY_DATA  nMinVal = SmPtsTo100th_mm(2);

    if (aSize.Height() < nMinVal)
        aSize.Height() = nMinVal;

    //! we don't force a maximum value here because this may prevent eg the
    //! parentheses in "left ( ... right )" from matching up with large
    //! bodies (eg stack{...} with many entries).
    //! Of course this is holds only if characters are used and not polygons.

    Font::SetSize(aSize);
}

long SmFace::GetBorderWidth() const
{
    if (nBorderWidth < 0)
        return GetDefaultBorderWidth();
    else
        return nBorderWidth;
}

SmFace & SmFace::operator = (const SmFace &rFace)
{
    Font::operator = (rFace);
    nBorderWidth = -1;
    return *this;
}

SmFace & operator *= (SmFace &rFace, const Fraction &rFrac)
    // scales the width and height of 'rFace' by 'rFrac' and returns a
    // reference to 'rFace'.
    // It's main use is to make scaling fonts look easier.
{   const Size &rFaceSize = rFace.GetSize();

    rFace.SetSize(Size(Fraction(rFaceSize.Width())  *= rFrac,
                       Fraction(rFaceSize.Height()) *= rFrac));
    return rFace;
}

<|endoftext|>


<commit_before>#ifdef WINDOWS

#include <windows.h>
#include <fstream>
#include "util/system.h"

namespace System{

bool isDirectory(const std::string & path){
    return GetFileAttributes(path.c_str()) & FILE_ATTRIBUTE_DIRECTORY;
}

bool readableFile(const std::string & path){
    return !isDirectory(path) && readable(path);
}

bool readable(const std::string & path){
    if (isDirectory(path)){
        return true;
    }

	std::ifstream stream(path.c_str());
    bool ok = stream.good();
    if (stream.is_open()){
        stream.close();
    }
    return ok;
}

uint64_t currentMicroseconds(){
    LARGE_INTEGER ticksPerSecond;
    LARGE_INTEGER tick;
    QueryPerformanceFrequency(&ticksPerSecond);
    QueryPerformanceCounter(&tick);
    return (tick.QuadPart)/(ticksPerSecond.QuadPart/1000000);
}

}

#endif
<commit_msg>Corrected isDirectory<commit_after>#ifdef WINDOWS

#include <windows.h>
#include <fstream>
#include "util/system.h"

namespace System{

bool isDirectory(const std::string & path){
    unsigned int f = GetFileAttributes(path.c_str());
    if (f == INVALID_FILE_ATTRIBUTES){
        return false;
    }
    return f & FILE_ATTRIBUTE_DIRECTORY;
}

bool readableFile(const std::string & path){
    return !isDirectory(path) && readable(path);
}

bool readable(const std::string & path){
    if (isDirectory(path)){
        return true;
    }

	std::ifstream stream(path.c_str());
    bool ok = stream.good();
    if (stream.is_open()){
        stream.close();
    }
    return ok;
}

uint64_t currentMicroseconds(){
    LARGE_INTEGER ticksPerSecond;
    LARGE_INTEGER tick;
    QueryPerformanceFrequency(&ticksPerSecond);
    QueryPerformanceCounter(&tick);
    return (tick.QuadPart)/(ticksPerSecond.QuadPart/1000000);
}

}

#endif
<|endoftext|>


<commit_before>/*
    Copyright (C) 2009 Maia Kozheva <sikon@ubuntu.com>

    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 2.1 of the License, or (at your option) any later version.

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

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/

#include "xdgenvironment.h"

namespace
{
    inline QList<QDir> splitDirList(const QString& str)
    {
        QList<QDir> list;

        foreach(QString str, str.split(QLatin1Char(':')))
            list.append(QDir(str));

        return list;
    }

    inline QString getValue(const char *varName, const QString &defValue)
    {
        QByteArray env = qgetenv(varName);
        return env.isEmpty() ? defValue : QString::fromLocal8Bit(env.constData(), env.size());
    }
}

XdgEnvironment::XdgEnvironment()
{
}

XdgEnvironment::~XdgEnvironment()
{
}

QDir XdgEnvironment::dataHome()
{
    return QDir(getValue("XDG_DATA_HOME",
                         QDir::home().absoluteFilePath(QLatin1String(".share/locale"))));
}

QDir XdgEnvironment::configHome()
{
    return QDir(getValue("XDG_CONFIG_HOME",
                         QDir::home().absoluteFilePath(QLatin1String(".config"))));
}

QList<QDir> XdgEnvironment::dataDirs()
{
    return splitDirList(getValue("XDG_DATA_DIRS",
                                 QLatin1String("/usr/local/share:/usr/share")));
}

QList<QDir> XdgEnvironment::configDirs()
{
    return splitDirList(getValue("XDG_CONFIG_DIRS",
                                 QDir::home().absoluteFilePath(QLatin1String(".share/locale"))));
}
<commit_msg>Corrected basedirs<commit_after>/*
    Copyright (C) 2009 Maia Kozheva <sikon@ubuntu.com>

    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 2.1 of the License, or (at your option) any later version.

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

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/

#include "xdgenvironment.h"

namespace
{
    inline QList<QDir> splitDirList(const QString& str)
    {
        QList<QDir> list;

        foreach(QString str, str.split(QLatin1Char(':')))
            list.append(QDir(str));

        return list;
    }

    inline QString getValue(const char *varName, const QString &defValue)
    {
        QByteArray env = qgetenv(varName);
        return env.isEmpty() ? defValue : QString::fromLocal8Bit(env.constData(), env.size());
    }
}

XdgEnvironment::XdgEnvironment()
{
}

XdgEnvironment::~XdgEnvironment()
{
}

QDir XdgEnvironment::dataHome()
{
    return QDir(getValue("XDG_DATA_HOME",
                         QDir::home().absoluteFilePath(QLatin1String(".local/share"))));
}

QDir XdgEnvironment::configHome()
{
    return QDir(getValue("XDG_CONFIG_HOME",
                         QDir::home().absoluteFilePath(QLatin1String(".config"))));
}

QList<QDir> XdgEnvironment::dataDirs()
{
    return splitDirList(getValue("XDG_DATA_DIRS",
                                 QLatin1String("/usr/local/share:/usr/share")));
}

QList<QDir> XdgEnvironment::configDirs()
{
    return splitDirList(getValue("XDG_CONFIG_DIRS",
                                 QDir::home().absoluteFilePath(QLatin1String("/etc/xdg"))));
}
<|endoftext|>