<commit_before>/* -------------------------------------------------------------------------- */
/* Copyright 2002-2018, OpenNebula Project, OpenNebula Systems                */
/*                                                                            */
/* 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 "Quota.h"
#include "NebulaUtil.h"

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

const int Quota::DEFAULT        = -1;
const string Quota::DEFAULT_STR = "-1";
const int Quota::UNLIMITED      = -2;

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

int Quota::get_quota(
        const string& id,
        VectorAttribute ** va,
        map<string, Attribute *>::iterator& it)
{
    VectorAttribute * q;

    istringstream iss(id);
    int           id_i;

    *va = 0;

    if ( id.empty() )
    {
        return -1;
    }

    iss >> id_i;

    if (iss.fail() || !iss.eof())
    {
        return -1;
    }

    for ( it = attributes.begin(); it != attributes.end(); it++)
    {
        q = static_cast<VectorAttribute *>(it->second);

        if (q->vector_value("ID") == id)
        {
            *va = q;
            return 0;
        }
    }

    return 0;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

void Quota::add_to_quota(VectorAttribute * attr, const string& va_name, float num)
{
    istringstream iss;
    float         total;

    iss.str(attr->vector_value(va_name.c_str()));

    iss >> total;

    total += num;

    attr->replace(va_name, one_util::float_to_str(total));
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

int Quota::set(vector<VectorAttribute*> * new_quotas, string& error)
{
    vector<VectorAttribute *>::iterator  it;

    VectorAttribute * tq;
    string            id;

    for ( it = new_quotas->begin(); it != new_quotas->end(); it++)
    {
        id = (*it)->vector_value("ID");

        if ( get_quota(id, &tq) == -1 )
        {
            goto error_limits;
        }

        if ( tq == 0 )
        {
            VectorAttribute * nq;

            if ((nq = new_quota(*it)) == 0)
            {
                goto error_limits;
            }

            add(nq);
        }
        else
        {
            if (update_limits(tq, *it) != 0)
            {
                goto error_limits;
            }
        }

        cleanup_quota(id);
    }

    return 0;

error_limits:
    ostringstream oss;

    oss <<  "Negative limits or bad format in quota " << template_name;

    string * quota_str = (*it)->marshall(",");

    oss << " = [ " << *quota_str << " ]";

    delete quota_str;

    error = oss.str();

    return -1;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

bool Quota::check_quota(const string& qid,
                        map<string, float>& usage_req,
                        Quotas& default_quotas,
                        string& error)
{
    VectorAttribute * q;
    VectorAttribute * default_q;
    map<string, float>::iterator it;

    bool check;
    float limit;
    float usage;

    if ( get_quota(qid, &q) == -1 )
    {
        ostringstream oss;
        oss << "String '" << qid << "' is not a valid ID";

        error = oss.str();

        return false;
    }

    if ( get_default_quota(qid, default_quotas, &default_q) == -1 )
    {
        default_q = 0;
    }

    // -------------------------------------------------------------------------
    //  Quota does not exist, create a new one
    // -------------------------------------------------------------------------
    if ( q == 0 )
    {
        map<string, string> values;

        for (int i=0; i < num_metrics; i++)
        {
            string metrics_used = metrics[i];

            metrics_used += "_USED";

            values.insert(make_pair(metrics[i], DEFAULT_STR));
            values.insert(make_pair(metrics_used, "0"));
        }

        if (!qid.empty())
        {
            values.insert(make_pair("ID", qid));
        }

        q = new VectorAttribute(template_name, values);

        add(q);
    }

    // -------------------------------------------------------------------------
    //  Check the quotas for each usage request
    // -------------------------------------------------------------------------
    for (int i=0; i < num_metrics; i++)
    {
        string metrics_used = metrics[i];

        metrics_used += "_USED";

        it = usage_req.find(metrics[i]);

        if (it == usage_req.end())
        {
            continue;
        }

        q->vector_value(metrics[i],   limit);
        q->vector_value(metrics_used.c_str(), usage);

        if ( limit == DEFAULT )
        {
            if ( default_q != 0 )
            {
                default_q->vector_value(metrics[i], limit);
            }
            else
            {
                limit = UNLIMITED;
            }
        }

        check = ( limit == UNLIMITED ) || ( ( usage + it->second ) <= limit );

        if ( !check )
        {
            ostringstream oss;

            oss << "limit of " << limit << " reached for " << metrics[i]
                << " quota in " << template_name;

            if ( !qid.empty() )
            {
                oss << " with ID: " << qid;
            }

            error = oss.str();

            return false;
        }
    }

    // -------------------------------------------------------------------------
    //  Add resource usage to quotas
    // -------------------------------------------------------------------------
    for (int i=0; i < num_metrics; i++)
    {
        string metrics_used = metrics[i];

        metrics_used += "_USED";

        it = usage_req.find(metrics[i]);

        if (it == usage_req.end())
        {
            continue;
        }

        add_to_quota(q, metrics_used, it->second);
    }

    return true;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

void Quota::del_quota(const string& qid, map<string, float>& usage_req)
{
    VectorAttribute * q;
    map<string, float>::iterator it;

    if ( get_quota(qid, &q) == -1)
    {
        return;
    }

    if ( q == 0 )
    {
        return;
    }

    for (int i=0; i < num_metrics; i++)
    {
        string metrics_used = metrics[i];

        metrics_used += "_USED";

        it = usage_req.find(metrics[i]);

        if (it == usage_req.end())
        {
            continue;
        }

        add_to_quota(q, metrics_used, -it->second);
    }

    cleanup_quota(qid);
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

void Quota::cleanup_quota(const string& qid)
{
    VectorAttribute * q;
    map<string, Attribute *>::iterator q_it;

    float usage, limit, implicit_limit;

    if ( get_quota(qid, &q, q_it) == -1)
    {
        return;
    }

    if ( q == 0 )
    {
        return;
    }

    if ( is_default )
    {
        implicit_limit = UNLIMITED;
    }
    else
    {
        implicit_limit = DEFAULT;
    }

    for (int i=0; i < num_metrics; i++)
    {
        string metrics_used = metrics[i];

        metrics_used += "_USED";

        q->vector_value(metrics[i], limit);
        q->vector_value(metrics_used.c_str(), usage);

        if ( usage != 0 || limit != implicit_limit )
        {
            return;
        }
    }

    delete static_cast<Attribute *>(q_it->second);

    attributes.erase(q_it);
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

int Quota::update_limits(
        VectorAttribute *       quota,
        const VectorAttribute * va)
{
    string  limit;
    float   limit_f;

    for (int i=0; i < num_metrics; i++)
    {
        limit = va->vector_value_str(metrics[i], limit_f);

        if (limit == "")
        {
            limit_f = DEFAULT;
        }

            // Negative. Default & unlimited allowed
        if (( !is_default && limit_f < 0 && limit_f != UNLIMITED && limit_f != DEFAULT )
            ||
            // Negative. Unlimited allowed
            ( is_default && limit_f < 0 && limit_f != UNLIMITED )
           )
        {
            return -1;
        }

        quota->replace(metrics[i], one_util::float_to_str(limit_f));
    }

    return 0;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

VectorAttribute * Quota::new_quota(VectorAttribute * va)
{
    map<string,string> limits;

    string limit;
    float  limit_f;

    for (int i=0; i < num_metrics; i++)
    {
        string metrics_used = metrics[i];

        metrics_used += "_USED";

        limit = va->vector_value_str(metrics[i], limit_f);

        if (limit == "")
        {
            limit_f = DEFAULT;
            limit = DEFAULT_STR;
        }
            // Negative. Default & unlimited allowed
        if (( !is_default && limit_f < 0 && limit_f != UNLIMITED && limit_f != DEFAULT )
            ||
            // Negative. Unlimited allowed
            ( is_default && limit_f < 0 && limit_f != UNLIMITED )
           )
        {
            return 0;
        }

        limits.insert(make_pair(metrics[i], one_util::float_to_str(limit_f)));
        limits.insert(make_pair(metrics_used, "0"));
    }

    string id = va->vector_value("ID");

    if ( !id.empty() )
    {
        limits.insert(make_pair("ID", id));
    }

    return new VectorAttribute(template_name,limits);
}
<commit_msg>F #2228: Fixed problem with defualt quotas <commit_after>/* -------------------------------------------------------------------------- */
/* Copyright 2002-2018, OpenNebula Project, OpenNebula Systems                */
/*                                                                            */
/* 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 "Quota.h"
#include "NebulaUtil.h"

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

const int Quota::DEFAULT        = -1;
const string Quota::DEFAULT_STR = "-1";
const int Quota::UNLIMITED      = -2;

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

int Quota::get_quota(
        const string& id,
        VectorAttribute ** va,
        map<string, Attribute *>::iterator& it)
{
    VectorAttribute * q;

    istringstream iss(id);
    int           id_i;

    *va = 0;

    if ( id.empty() )
    {
        return -1;
    }

    iss >> id_i;

    if (iss.fail() || !iss.eof())
    {
        return -1;
    }

    for ( it = attributes.begin(); it != attributes.end(); it++)
    {
        q = static_cast<VectorAttribute *>(it->second);

        if (q->vector_value("ID") == id)
        {
            *va = q;
            return 0;
        }
    }

    return 0;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

void Quota::add_to_quota(VectorAttribute * attr, const string& va_name, float num)
{
    istringstream iss;
    float         total;

    iss.str(attr->vector_value(va_name.c_str()));

    iss >> total;

    total += num;

    attr->replace(va_name, one_util::float_to_str(total));
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

int Quota::set(vector<VectorAttribute*> * new_quotas, string& error)
{
    vector<VectorAttribute *>::iterator  it;

    VectorAttribute * tq;
    string            id;

    for ( it = new_quotas->begin(); it != new_quotas->end(); it++)
    {
        id = (*it)->vector_value("ID");

        if ( get_quota(id, &tq) == -1 )
        {
            goto error_limits;
        }

        if ( tq == 0 )
        {
            VectorAttribute * nq;

            if ((nq = new_quota(*it)) == 0)
            {
                goto error_limits;
            }

            add(nq);
        }
        else
        {
            if (update_limits(tq, *it) != 0)
            {
                goto error_limits;
            }
        }

        cleanup_quota(id);
    }

    return 0;

error_limits:
    ostringstream oss;

    oss <<  "Negative limits or bad format in quota " << template_name;

    string * quota_str = (*it)->marshall(",");

    oss << " = [ " << *quota_str << " ]";

    delete quota_str;

    error = oss.str();

    return -1;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

bool Quota::check_quota(const string& qid,
                        map<string, float>& usage_req,
                        Quotas& default_quotas,
                        string& error)
{
    VectorAttribute * q;
    VectorAttribute * default_q;
    map<string, float>::iterator it;

    bool check;
    float limit;
    float usage;

    if ( get_quota(qid, &q) == -1 )
    {
        ostringstream oss;
        oss << "String '" << qid << "' is not a valid ID";

        error = oss.str();

        return false;
    }

    if ( get_default_quota(qid, default_quotas, &default_q) == -1 )
    {
        default_q = 0;
    }

    // -------------------------------------------------------------------------
    //  Quota does not exist, create a new one
    // -------------------------------------------------------------------------
    if ( q == 0 )
    {
        map<string, string> values;

        for (int i=0; i < num_metrics; i++)
        {
            string metrics_used = metrics[i];

            metrics_used += "_USED";

            values.insert(make_pair(metrics[i], DEFAULT_STR));
            values.insert(make_pair(metrics_used, "0"));
        }

        if (!qid.empty())
        {
            values.insert(make_pair("ID", qid));
        }

        q = new VectorAttribute(template_name, values);

        add(q);
    }

    // -------------------------------------------------------------------------
    //  Check the quotas for each usage request
    // -------------------------------------------------------------------------
    for (int i=0; i < num_metrics; i++)
    {
        string metrics_used = metrics[i];

        metrics_used += "_USED";

        it = usage_req.find(metrics[i]);

        if (it == usage_req.end())
        {
            continue;
        }

        q->vector_value(metrics[i],   limit);
        q->vector_value(metrics_used.c_str(), usage);

        if ( limit == DEFAULT )
        {
            if ( default_q != 0 )
            {
                default_q->vector_value(metrics[i], limit);
            }
            else
            {
                limit = UNLIMITED;
            }
        }

        check = ( limit == UNLIMITED ) || ( ( usage + it->second ) <= limit );

        if ( !check )
        {
            ostringstream oss;

            oss << "limit of " << limit << " reached for " << metrics[i]
                << " quota in " << template_name;

            if ( !qid.empty() )
            {
                oss << " with ID: " << qid;
            }

            error = oss.str();

            return false;
        }
    }

    // -------------------------------------------------------------------------
    //  Add resource usage to quotas
    // -------------------------------------------------------------------------
    for (int i=0; i < num_metrics; i++)
    {
        string metrics_used = metrics[i];

        metrics_used += "_USED";

        it = usage_req.find(metrics[i]);

        if (it == usage_req.end())
        {
            continue;
        }

        add_to_quota(q, metrics_used, it->second);
    }

    return true;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

void Quota::del_quota(const string& qid, map<string, float>& usage_req)
{
    VectorAttribute * q;
    map<string, float>::iterator it;

    if ( get_quota(qid, &q) == -1)
    {
        return;
    }

    if ( q == 0 )
    {
        return;
    }

    for (int i=0; i < num_metrics; i++)
    {
        string metrics_used = metrics[i];

        metrics_used += "_USED";

        it = usage_req.find(metrics[i]);

        if (it == usage_req.end())
        {
            continue;
        }

        add_to_quota(q, metrics_used, -it->second);
    }

    cleanup_quota(qid);
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

void Quota::cleanup_quota(const string& qid)
{
    VectorAttribute * q;
    map<string, Attribute *>::iterator q_it;

    float usage, limit, implicit_limit;

    if ( get_quota(qid, &q, q_it) == -1)
    {
        return;
    }

    if ( q == 0 )
    {
        return;
    }

    if ( is_default )
    {
        implicit_limit = UNLIMITED;
    }
    else
    {
        implicit_limit = DEFAULT;
    }

    for (int i=0; i < num_metrics; i++)
    {
        string metrics_used = metrics[i];

        metrics_used += "_USED";

        q->vector_value(metrics[i], limit);
        q->vector_value(metrics_used.c_str(), usage);

        if ( usage != 0 || limit != implicit_limit )
        {
            return;
        }
    }

    delete static_cast<Attribute *>(q_it->second);

    attributes.erase(q_it);
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

int Quota::update_limits(
        VectorAttribute *       quota,
        const VectorAttribute * va)
{
    string  limit;
    float   limit_f;

    for (int i=0; i < num_metrics; i++)
    {
        limit = va->vector_value_str(metrics[i], limit_f);

        if (limit == "")
        {
            if ( is_default )
            {
                limit_f = UNLIMITED;
            }
            else
            {
                limit_f = DEFAULT;
            }
        }

            // Negative. Default & unlimited allowed
        if (( !is_default && limit_f < 0 && limit_f != UNLIMITED && limit_f != DEFAULT )
            ||
            // Negative. Unlimited allowed
            ( is_default && limit_f < 0 && limit_f != UNLIMITED )
           )
        {
            return -1;
        }

        quota->replace(metrics[i], one_util::float_to_str(limit_f));
    }

    return 0;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

VectorAttribute * Quota::new_quota(VectorAttribute * va)
{
    map<string,string> limits;

    string limit;
    float  limit_f;

    for (int i=0; i < num_metrics; i++)
    {
        string metrics_used = metrics[i];

        metrics_used += "_USED";

        limit = va->vector_value_str(metrics[i], limit_f);

        if (limit == "")
        {
            if ( is_default )
            {
                limit_f = UNLIMITED;
            }
            else
            {
                limit_f = DEFAULT;
            }
        }
            // Negative. Default & unlimited allowed
        if (( !is_default && limit_f < 0 && limit_f != UNLIMITED && limit_f != DEFAULT )
            ||
            // Negative. Unlimited allowed
            ( is_default && limit_f < 0 && limit_f != UNLIMITED )
           )
        {
            return 0;
        }

        limits.insert(make_pair(metrics[i], one_util::float_to_str(limit_f)));
        limits.insert(make_pair(metrics_used, "0"));
    }

    string id = va->vector_value("ID");

    if ( !id.empty() )
    {
        limits.insert(make_pair("ID", id));
    }

    return new VectorAttribute(template_name,limits);
}
<|endoftext|>


<commit_before>/* Copyright (C) Teemu Suutari */

#include "IMPDecompressor.hpp"
#include "HuffmanDecoder.hpp"
#include "InputStream.hpp"
#include "OutputStream.hpp"

static bool readIMPHeader(uint32_t hdr,uint32_t &addition) noexcept
{
	switch (hdr)
	{
		case FourCC('IMP!'):
		case FourCC('ATN!'):
		addition=7;
		return true;

		case FourCC('BDPI'):
		addition=0x6e8;
		return true;

		case FourCC('CHFI'):
		addition=0xfe4;
		return true;

		// I haven't got these files to be sure what is the addition
		case FourCC('Dupa'):
		case FourCC('EDAM'):
		case FourCC('FLT!'):
		case FourCC('M.H.'):
		case FourCC('PARA'):
		case FourCC('RDC9'):
		addition=0; 		// disable checksum for now
		return true;

		default:
		return false;
	}
}

bool IMPDecompressor::detectHeader(uint32_t hdr) noexcept
{
	uint32_t dummy;
	return readIMPHeader(hdr,dummy);
}

bool IMPDecompressor::detectHeaderXPK(uint32_t hdr) noexcept
{
	return hdr==FourCC('IMPL');
}

std::unique_ptr<Decompressor> IMPDecompressor::create(const Buffer &packedData,bool exactSizeKnown,bool verify)
{
	return std::make_unique<IMPDecompressor>(packedData,verify);
}

std::unique_ptr<XPKDecompressor> IMPDecompressor::create(uint32_t hdr,uint32_t recursionLevel,const Buffer &packedData,std::unique_ptr<XPKDecompressor::State> &state,bool verify)
{
	return std::make_unique<IMPDecompressor>(hdr,recursionLevel,packedData,state,verify);
}

IMPDecompressor::IMPDecompressor(const Buffer &packedData,bool verify) :
	_packedData(packedData)
{
	uint32_t hdr=packedData.readBE32(0);
	uint32_t checksumAddition;
	if (!readIMPHeader(hdr,checksumAddition) || packedData.size()<0x32) throw InvalidFormatError();

	_rawSize=packedData.readBE32(4);
	_endOffset=packedData.readBE32(8);
	if ((_endOffset&1) || _endOffset<0xc || _endOffset+0x32<packedData.size() ||
		!_rawSize || !_endOffset ||
		_rawSize>getMaxRawSize() || _endOffset>getMaxPackedSize()) throw InvalidFormatError();
	uint32_t checksum=packedData.readBE32(_endOffset+0x2e);
	if (verify && checksumAddition)
	{
		// size is divisible by 2
		uint32_t sum=checksumAddition;
		for (uint32_t i=0;i<_endOffset+0x2e;i+=2)
		{
			// TODO: slow, optimize
			uint16_t tmp=_packedData.readBE16(i);
			sum+=uint32_t(tmp);
		}
		if (checksum!=sum) throw InvalidFormatError();
	}
}

IMPDecompressor::IMPDecompressor(uint32_t hdr,uint32_t recursionLevel,const Buffer &packedData,std::unique_ptr<XPKDecompressor::State> &state,bool verify) :
	XPKDecompressor(recursionLevel),
	_packedData(packedData)
{
	if (!detectHeaderXPK(hdr) || packedData.size()<0x2e) throw InvalidFormatError();

	_rawSize=packedData.readBE32(4);
	_endOffset=packedData.readBE32(8);
	if ((_endOffset&1) || _endOffset<0xc || _endOffset+0x2e<packedData.size()) throw InvalidFormatError();
	_isXPK=true;
}

IMPDecompressor::~IMPDecompressor()
{
	// nothing needed
}

const std::string &IMPDecompressor::getName() const noexcept
{
	static std::string name="IMP: File Imploder";
	return name;
}

const std::string &IMPDecompressor::getSubName() const noexcept
{
	static std::string name="XPK-IMPL: File Imploder";
	return name;
}

size_t IMPDecompressor::getPackedSize() const noexcept
{
	return _endOffset+0x32;
}

size_t IMPDecompressor::getRawSize() const noexcept
{
	return _rawSize;
}

void IMPDecompressor::decompressImpl(Buffer &rawData,bool verify)
{
	if (rawData.size()<_rawSize) throw DecompressionError();

	class IMPInputStream
	{
	public:
		IMPInputStream(const Buffer &buffer,size_t startOffset,size_t endOffset) :
			_bufPtr(buffer.data()),
			_currentOffset(endOffset),
			_endOffset(startOffset),
			_refOffset(endOffset)
		{
			if (_currentOffset<_endOffset || _currentOffset>buffer.size() || _endOffset>buffer.size()) throw Decompressor::DecompressionError();
			uint8_t markerByte=buffer.read8(_currentOffset+16);
			if (!(markerByte&0x80))
			{
				if (_currentOffset==_endOffset) throw Decompressor::DecompressionError();
				_currentOffset--;
			}
		}

		~IMPInputStream()
		{
			// nothing needed
		}

		uint8_t readByte()
		{
			// streamreader with funny ordering
			auto sourceOffset=[&](size_t i)->size_t
			{
				if (i>=12)
				{
					return i;
				} else {
					if (i<4)
					{
						return i+_refOffset+8;
					} else if (i<8) {
						return i+_refOffset;
					} else {
						return i+_refOffset-8;
					}
				}
			};
			if (_currentOffset<=_endOffset) throw Decompressor::DecompressionError();
			return _bufPtr[sourceOffset(--_currentOffset)];
		}

		bool eof() const { return _currentOffset==_endOffset; }

	private:
		const uint8_t		*_bufPtr;
		size_t			_currentOffset;
		size_t			_endOffset;
		size_t			_refOffset;
	};

	IMPInputStream inputStream(_packedData,0,_endOffset);
	MSBBitReader<IMPInputStream> bitReader(inputStream);
	auto readBits=[&](uint32_t count)->uint32_t
	{
		return bitReader.readBits8(count);
	};
	auto readBit=[&]()->uint32_t
	{
		return bitReader.readBits8(1);
	};
	auto readByte=[&]()->uint8_t
	{
		return inputStream.readByte();
	};
	// the anchor-bit does not seem always to be at the correct place
	{
		uint8_t halfByte=_packedData.read8(_endOffset+17);
		for (uint32_t i=0;i<7;i++)
			if (halfByte&(1<<i))
			{
				bitReader.reset(halfByte>>(i+1),7-i);
				break;
			}
	}

	BackwardOutputStream outputStream(rawData,0,_rawSize);

	// tables
	uint16_t distanceValues[2][4];
	for (uint32_t i=0;i<8;i++)
		distanceValues[i>>2][i&3]=_packedData.readBE16(_endOffset+18+i*2);
	uint8_t distanceBits[3][4];
	for (uint32_t i=0;i<12;i++)
		distanceBits[i>>2][i&3]=_packedData.read8(_endOffset+34+i);

	// length, distance & literal counts are all intertwined
	HuffmanDecoder<uint8_t> lldDecoder
	{
		HuffmanCode<uint8_t>{1,0b00000,0},
		HuffmanCode<uint8_t>{2,0b00010,1},
		HuffmanCode<uint8_t>{3,0b00110,2},
		HuffmanCode<uint8_t>{4,0b01110,3},
		HuffmanCode<uint8_t>{5,0b11110,4},
		HuffmanCode<uint8_t>{5,0b11111,5}
	};

	HuffmanDecoder<uint8_t> lldDecoder2
	{
		HuffmanCode<uint8_t>{1,0b00,0},
		HuffmanCode<uint8_t>{2,0b10,1},
		HuffmanCode<uint8_t>{2,0b11,2}
	};

	// finally loop
	uint32_t litLength=_packedData.readBE32(_endOffset+12);

	for (;;)
	{
		for (uint32_t i=0;i<litLength;i++) outputStream.writeByte(readByte());

		if (outputStream.eof()) break;

		// now the intertwined Huffman table reads.
		uint32_t i0=lldDecoder.decode(readBit);
		uint32_t selector=(i0<4)?i0:3;
		uint32_t count=i0+2;
		if (count==6)
		{
			count+=readBits(3);
		} else if (count==7) {
			count=readByte();
			// why this is error? (Well, it just is)
			if (!count) throw DecompressionError();
		}

		static const uint8_t literalLengths[4]={6,10,10,18};
		static const uint8_t literalBits[3][4]={
			{1,1,1,1},
			{2,3,3,4},
			{4,5,7,14}};
		uint32_t i1=lldDecoder2.decode(readBit);
		litLength=i1+i1;
		if (litLength==4)
		{
			litLength=literalLengths[selector];
		}
		litLength+=readBits(literalBits[i1][selector]);

		uint32_t i2=lldDecoder2.decode(readBit);
		uint32_t distance=1+((i2)?distanceValues[i2-1][selector]:0)+readBits(distanceBits[i2][selector]);

		outputStream.copy(distance,count);
	}
}

void IMPDecompressor::decompressImpl(Buffer &rawData,const Buffer &previousData,bool verify)
{
	if (_rawSize!=rawData.size()) throw DecompressionError();
	return decompressImpl(rawData,verify);
}

Decompressor::Registry<IMPDecompressor> IMPDecompressor::_registration;
XPKDecompressor::Registry<IMPDecompressor> IMPDecompressor::_XPKregistration;
<commit_msg>Fixing a (stupid) bug where IMP-decompressor would not work if the input contained trailing data<commit_after>/* Copyright (C) Teemu Suutari */

#include "IMPDecompressor.hpp"
#include "HuffmanDecoder.hpp"
#include "InputStream.hpp"
#include "OutputStream.hpp"

static bool readIMPHeader(uint32_t hdr,uint32_t &addition) noexcept
{
	switch (hdr)
	{
		case FourCC('IMP!'):
		case FourCC('ATN!'):
		addition=7;
		return true;

		case FourCC('BDPI'):
		addition=0x6e8;
		return true;

		case FourCC('CHFI'):
		addition=0xfe4;
		return true;

		// I haven't got these files to be sure what is the addition
		case FourCC('Dupa'):
		case FourCC('EDAM'):
		case FourCC('FLT!'):
		case FourCC('M.H.'):
		case FourCC('PARA'):
		case FourCC('RDC9'):
		addition=0; 		// disable checksum for now
		return true;

		default:
		return false;
	}
}

bool IMPDecompressor::detectHeader(uint32_t hdr) noexcept
{
	uint32_t dummy;
	return readIMPHeader(hdr,dummy);
}

bool IMPDecompressor::detectHeaderXPK(uint32_t hdr) noexcept
{
	return hdr==FourCC('IMPL');
}

std::unique_ptr<Decompressor> IMPDecompressor::create(const Buffer &packedData,bool exactSizeKnown,bool verify)
{
	return std::make_unique<IMPDecompressor>(packedData,verify);
}

std::unique_ptr<XPKDecompressor> IMPDecompressor::create(uint32_t hdr,uint32_t recursionLevel,const Buffer &packedData,std::unique_ptr<XPKDecompressor::State> &state,bool verify)
{
	return std::make_unique<IMPDecompressor>(hdr,recursionLevel,packedData,state,verify);
}

IMPDecompressor::IMPDecompressor(const Buffer &packedData,bool verify) :
	_packedData(packedData)
{
	uint32_t hdr=packedData.readBE32(0);
	uint32_t checksumAddition;
	if (!readIMPHeader(hdr,checksumAddition) || packedData.size()<0x32) throw InvalidFormatError();

	_rawSize=packedData.readBE32(4);
	_endOffset=packedData.readBE32(8);
	if ((_endOffset&1) || _endOffset<0xc || _endOffset+0x32>packedData.size() ||
		!_rawSize || !_endOffset ||
		_rawSize>getMaxRawSize() || _endOffset>getMaxPackedSize()) throw InvalidFormatError();
	uint32_t checksum=packedData.readBE32(_endOffset+0x2e);
	if (verify && checksumAddition)
	{
		// size is divisible by 2
		uint32_t sum=checksumAddition;
		for (uint32_t i=0;i<_endOffset+0x2e;i+=2)
		{
			// TODO: slow, optimize
			uint16_t tmp=_packedData.readBE16(i);
			sum+=uint32_t(tmp);
		}
		if (checksum!=sum) throw InvalidFormatError();
	}
}

IMPDecompressor::IMPDecompressor(uint32_t hdr,uint32_t recursionLevel,const Buffer &packedData,std::unique_ptr<XPKDecompressor::State> &state,bool verify) :
	XPKDecompressor(recursionLevel),
	_packedData(packedData)
{
	if (!detectHeaderXPK(hdr) || packedData.size()<0x2e) throw InvalidFormatError();

	_rawSize=packedData.readBE32(4);
	_endOffset=packedData.readBE32(8);
	if ((_endOffset&1) || _endOffset<0xc || _endOffset+0x2e>packedData.size()) throw InvalidFormatError();
	_isXPK=true;
}

IMPDecompressor::~IMPDecompressor()
{
	// nothing needed
}

const std::string &IMPDecompressor::getName() const noexcept
{
	static std::string name="IMP: File Imploder";
	return name;
}

const std::string &IMPDecompressor::getSubName() const noexcept
{
	static std::string name="XPK-IMPL: File Imploder";
	return name;
}

size_t IMPDecompressor::getPackedSize() const noexcept
{
	return _endOffset+0x32;
}

size_t IMPDecompressor::getRawSize() const noexcept
{
	return _rawSize;
}

void IMPDecompressor::decompressImpl(Buffer &rawData,bool verify)
{
	if (rawData.size()<_rawSize) throw DecompressionError();

	class IMPInputStream
	{
	public:
		IMPInputStream(const Buffer &buffer,size_t startOffset,size_t endOffset) :
			_bufPtr(buffer.data()),
			_currentOffset(endOffset),
			_endOffset(startOffset),
			_refOffset(endOffset)
		{
			if (_currentOffset<_endOffset || _currentOffset>buffer.size() || _endOffset>buffer.size()) throw Decompressor::DecompressionError();
			uint8_t markerByte=buffer.read8(_currentOffset+16);
			if (!(markerByte&0x80))
			{
				if (_currentOffset==_endOffset) throw Decompressor::DecompressionError();
				_currentOffset--;
			}
		}

		~IMPInputStream()
		{
			// nothing needed
		}

		uint8_t readByte()
		{
			// streamreader with funny ordering
			auto sourceOffset=[&](size_t i)->size_t
			{
				if (i>=12)
				{
					return i;
				} else {
					if (i<4)
					{
						return i+_refOffset+8;
					} else if (i<8) {
						return i+_refOffset;
					} else {
						return i+_refOffset-8;
					}
				}
			};
			if (_currentOffset<=_endOffset) throw Decompressor::DecompressionError();
			return _bufPtr[sourceOffset(--_currentOffset)];
		}

		bool eof() const { return _currentOffset==_endOffset; }

	private:
		const uint8_t		*_bufPtr;
		size_t			_currentOffset;
		size_t			_endOffset;
		size_t			_refOffset;
	};

	IMPInputStream inputStream(_packedData,0,_endOffset);
	MSBBitReader<IMPInputStream> bitReader(inputStream);
	auto readBits=[&](uint32_t count)->uint32_t
	{
		return bitReader.readBits8(count);
	};
	auto readBit=[&]()->uint32_t
	{
		return bitReader.readBits8(1);
	};
	auto readByte=[&]()->uint8_t
	{
		return inputStream.readByte();
	};
	// the anchor-bit does not seem always to be at the correct place
	{
		uint8_t halfByte=_packedData.read8(_endOffset+17);
		for (uint32_t i=0;i<7;i++)
			if (halfByte&(1<<i))
			{
				bitReader.reset(halfByte>>(i+1),7-i);
				break;
			}
	}

	BackwardOutputStream outputStream(rawData,0,_rawSize);

	// tables
	uint16_t distanceValues[2][4];
	for (uint32_t i=0;i<8;i++)
		distanceValues[i>>2][i&3]=_packedData.readBE16(_endOffset+18+i*2);
	uint8_t distanceBits[3][4];
	for (uint32_t i=0;i<12;i++)
		distanceBits[i>>2][i&3]=_packedData.read8(_endOffset+34+i);

	// length, distance & literal counts are all intertwined
	HuffmanDecoder<uint8_t> lldDecoder
	{
		HuffmanCode<uint8_t>{1,0b00000,0},
		HuffmanCode<uint8_t>{2,0b00010,1},
		HuffmanCode<uint8_t>{3,0b00110,2},
		HuffmanCode<uint8_t>{4,0b01110,3},
		HuffmanCode<uint8_t>{5,0b11110,4},
		HuffmanCode<uint8_t>{5,0b11111,5}
	};

	HuffmanDecoder<uint8_t> lldDecoder2
	{
		HuffmanCode<uint8_t>{1,0b00,0},
		HuffmanCode<uint8_t>{2,0b10,1},
		HuffmanCode<uint8_t>{2,0b11,2}
	};

	// finally loop
	uint32_t litLength=_packedData.readBE32(_endOffset+12);

	for (;;)
	{
		for (uint32_t i=0;i<litLength;i++) outputStream.writeByte(readByte());

		if (outputStream.eof()) break;

		// now the intertwined Huffman table reads.
		uint32_t i0=lldDecoder.decode(readBit);
		uint32_t selector=(i0<4)?i0:3;
		uint32_t count=i0+2;
		if (count==6)
		{
			count+=readBits(3);
		} else if (count==7) {
			count=readByte();
			// why this is error? (Well, it just is)
			if (!count) throw DecompressionError();
		}

		static const uint8_t literalLengths[4]={6,10,10,18};
		static const uint8_t literalBits[3][4]={
			{1,1,1,1},
			{2,3,3,4},
			{4,5,7,14}};
		uint32_t i1=lldDecoder2.decode(readBit);
		litLength=i1+i1;
		if (litLength==4)
		{
			litLength=literalLengths[selector];
		}
		litLength+=readBits(literalBits[i1][selector]);

		uint32_t i2=lldDecoder2.decode(readBit);
		uint32_t distance=1+((i2)?distanceValues[i2-1][selector]:0)+readBits(distanceBits[i2][selector]);

		outputStream.copy(distance,count);
	}
}

void IMPDecompressor::decompressImpl(Buffer &rawData,const Buffer &previousData,bool verify)
{
	if (_rawSize!=rawData.size()) throw DecompressionError();
	return decompressImpl(rawData,verify);
}

Decompressor::Registry<IMPDecompressor> IMPDecompressor::_registration;
XPKDecompressor::Registry<IMPDecompressor> IMPDecompressor::_XPKregistration;
<|endoftext|>


<commit_before>// Copyright 2015 Google Inc. 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.

#include "flatui/version.h"

namespace flatui {

#define FLATUI_VERSION_MAJOR 0
#define FLATUI_VERSION_MINOR 9
#define FLATUI_VERSION_REVISION 0

// Turn X into a string literal.
#define FLATUI_STRING_EXPAND(X) #X
#define FLATUI_STRING(X) FLATUI_STRING_EXPAND(X)

/// @var kVersion
/// @brief String which identifies the current version of MathFu.
///
/// @ref kVersion is used by Google developers to identify which applications
/// uploaded to Google Play are using this library. This allows the development
/// team at Google to determine the popularity of the library.
/// How it works: Applications that are uploaded to the Google Play Store are
/// scanned for this version string. We track which applications are using it
/// to measure popularity. You are free to remove it (of course) but we would
/// appreciate if you left it in.
///
static const FlatUiVersion kVersion = {
    FLATUI_VERSION_MAJOR, FLATUI_VERSION_MINOR, FLATUI_VERSION_REVISION,
    "FlatUi Library " FLATUI_STRING(FLATUI_VERSION_MAJOR) "." FLATUI_STRING(
        FLATUI_VERSION_MINOR) "." FLATUI_STRING(FLATUI_VERSION_REVISION)};

const FlatUiVersion& Version() { return kVersion; }

}  // namespace flatui
<commit_msg>Increment version number for GitHub push.<commit_after>// Copyright 2015 Google Inc. 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.

#include "flatui/version.h"

namespace flatui {

#define FLATUI_VERSION_MAJOR 1
#define FLATUI_VERSION_MINOR 0
#define FLATUI_VERSION_REVISION 0

// Turn X into a string literal.
#define FLATUI_STRING_EXPAND(X) #X
#define FLATUI_STRING(X) FLATUI_STRING_EXPAND(X)

/// @var kVersion
/// @brief String which identifies the current version of MathFu.
///
/// @ref kVersion is used by Google developers to identify which applications
/// uploaded to Google Play are using this library. This allows the development
/// team at Google to determine the popularity of the library.
/// How it works: Applications that are uploaded to the Google Play Store are
/// scanned for this version string. We track which applications are using it
/// to measure popularity. You are free to remove it (of course) but we would
/// appreciate if you left it in.
///
static const FlatUiVersion kVersion = {
    FLATUI_VERSION_MAJOR, FLATUI_VERSION_MINOR, FLATUI_VERSION_REVISION,
    "FlatUi Library " FLATUI_STRING(FLATUI_VERSION_MAJOR) "." FLATUI_STRING(
        FLATUI_VERSION_MINOR) "." FLATUI_STRING(FLATUI_VERSION_REVISION)};

const FlatUiVersion& Version() { return kVersion; }

}  // namespace flatui
<|endoftext|>


<commit_before>#include <stdio.h>
#include <string.h>
#include <math.h>
#include <string.h>
#include <iostream>
#include <fstream>
#include <string>

#include "GL/glut.h"   // - An interface and windows management library
#include "visuals.h"   // Header file for our OpenGL functions

myModel md;
static float tx = 0.0;
static float rotx = 0.0;
static bool animate = false;
static float red = 1.0;
static float green = 0.0;
static float blue = 0.0;
float lx = 0.0f, ly = 0.0f, lz=0.0f; // vector for camera dir & pos of airplane
float x= 0.0f, y=0.0f, z= 400; // x,z position of camera

using namespace std;

void createSun(void) {
	glPushMatrix();
		glTranslatef(0, 0, -515);
		glColor3f(1.0, 0.8, 0.0);
		glutSolidSphere(50.0, 40, 40);
	glPopMatrix();
}

void Render() {
	//CLEARS FRAME BUFFER ie COLOR BUFFER& DEPTH BUFFER (1.0)
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);  // Clean up the colour of the window and the depth buffer
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();

	createSun();

	glPushMatrix();
		glTranslatef(0, 0, -300);
		glTranslatef(tx, 0.0, 0.0);
		glRotatef(rotx, 1, 0, 0);

		glColor3f(0.75, 0.35, 0.05);
		DisplayModel(md);
	glPopMatrix();

	glutSwapBuffers();	// All drawing commands applied to the hidden buffer, so now, bring forward the hidden buffer and hide the visible one
}

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

void Resize(int w, int h) {
	// define the visible area of the window ( in pixels )
	if (h == 0) {
		h = 1;
	}
	// Setup viewing volume
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();

	glViewport( 0, 0, w, h);
	gluPerspective(45, (float)w/(float)h, 1, CAM_FAR);

    glMatrixMode(GL_MODELVIEW);
}

void Idle() {
	if (animate) {
		rotx += 0.4;
	}
	glutPostRedisplay();
}

void Keyboard(unsigned char key, int x, int y) {
	switch(key) {
		case 'q' :
			exit(0);
			break;
		case 'a' :
			tx -= 0.5f;
			break;
		case 'd' :
			tx += 0.5f;
			break;
		default :
			break;
	}
	glutPostRedisplay();
}

void Mouse(int button, int state, int x, int y) {
	if (state == GLUT_DOWN && button == GLUT_LEFT_BUTTON) {
		animate = !animate;
		glutPostRedisplay();
	}
}

void Setup(char *path) {
	ReadFile(path);

	//Parameter handling
	glShadeModel(GL_SMOOTH);

	glEnable(GL_DEPTH_TEST);
	glDepthFunc(GL_LEQUAL);  //renders a fragment if its z value is less or equal of the stored value
	glClearDepth(1);

	// polygon rendering mode
	glEnable(GL_COLOR_MATERIAL);
	glColorMaterial( GL_FRONT, GL_AMBIENT_AND_DIFFUSE );

	//Set up light source
	GLfloat light_position[] = { 0.0, 30.0, 50.0, 0.0 };
	  // GLfloat light_position[] = { 1000,1000,-3000, 10.0 };
	glLightfv(GL_LIGHT0, GL_POSITION, light_position);

	GLfloat ambientLight[] = { 0.3, 0.3, 0.3, 1.0 };
	GLfloat diffuseLight[] = { 0.8, 0.8, 0.8, 1.0 };
	GLfloat specularLight[] = { 1.0, 1.0, 1.0, 1.0 };

	glLightfv(GL_LIGHT0, GL_AMBIENT, ambientLight );
	glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseLight );
	glLightfv(GL_LIGHT0, GL_SPECULAR, specularLight);

	glEnable(GL_LIGHTING);
	glEnable(GL_LIGHT0);

	// glEnable(GL_COLOR_MATERIAL);
	// glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE );

	glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);

	glEnable(GL_CULL_FACE);
	glFrontFace(GL_CCW);

	// Black background
	glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
}

void MenuSelect(int choice) {
	switch (choice) {
		case RED:
			red = 1.0;
			green = 0.0;
			blue = 0.0;
			break;
		case GREEN:
			red = 0.0;
			green = 1.0;
			blue = 0.0;
			break;
		case BLUE:
			red = 0.0;
			green = 0.0;
			blue = 1.0;
			break;
		case WHITE:
			red = 1.0;
			green = 1.0;
			blue = 1.0;
			break;
		default:
			break;
	}
}

void ReadFile(char *path) {
	md.vertices = POINTS;
	md.faces = FACES;
	char first[80];
	FILE *file = fopen(path, "r");
	if (file == NULL) {
		fprintf(stderr, "Error opening file\n");
		exit(EXIT_FAILURE);
	}
	int i = 0, j = 0, m = 0;
	while (!feof(file)) {
		if (fscanf(file, "%s  ", first) != 1) {
			fprintf(stderr, "error reading line header\n");
			exit(EXIT_FAILURE);
		}
		if ( !strcmp(first, "v") ){
			if (fscanf(file,"%f %f %f ", &md.obj_points[i].x, &md.obj_points[i].y, &md.obj_points[i].z) != 3) {
				fprintf(stderr, "error reading objpoints\n");
				exit(EXIT_FAILURE);
			}
			i++;
		} else if ( !strcmp(first, "vn") ){
			if (fscanf(file,"%f %f %f ", &md.obj_normals[m].x, &md.obj_normals[m].y, &md.obj_normals[m].z) != 3) {
				fprintf(stderr, "error reading objnormals\n");
				exit(EXIT_FAILURE);
			}
			m++;
		} else if ( !strcmp( first, "f")){
			if (fscanf(file,"%d//%d %d//%d %d//%d ", &md.obj_faces[j].vtx[0], &md.obj_norm[j].vtx[0], &md.obj_faces[j].vtx[1], &md.obj_norm[j].vtx[1], &md.obj_faces[j].vtx[2], &md.obj_norm[j].vtx[2]) != 6) {
				fprintf(stderr, "error reading faces\n");
				exit(EXIT_FAILURE);
			}
			j++;
		}
	}

	fclose(file);
}

void DisplayModel(myModel md) {
	glPushMatrix();

	glBegin(GL_TRIANGLES);
		for (int i = 0; i < md.faces; i++) {
			glVertex3f(md.obj_points[md.obj_faces[i].vtx[0]-1].x, md.obj_points[md.obj_faces[i].vtx[0]-1].y, md.obj_points[md.obj_faces[i].vtx[0]-1].z);
			glNormal3f(md.obj_normals[md.obj_norm[i].vtx[0]-1].x, md.obj_normals[md.obj_norm[i].vtx[0]-1].y, md.obj_normals[md.obj_norm[i].vtx[0]-1].z);
			glVertex3f(md.obj_points[md.obj_faces[i].vtx[1]-1].x, md.obj_points[md.obj_faces[i].vtx[1]-1].y, md.obj_points[md.obj_faces[i].vtx[1]-1].z);
			glNormal3f(md.obj_normals[md.obj_norm[i].vtx[1]-1].x, md.obj_normals[md.obj_norm[i].vtx[1]-1].y, md.obj_normals[md.obj_norm[i].vtx[1]-1].z);
			glVertex3f(md.obj_points[md.obj_faces[i].vtx[2]-1].x, md.obj_points[md.obj_faces[i].vtx[2]-1].y, md.obj_points[md.obj_faces[i].vtx[2]-1].z);
			glNormal3f(md.obj_normals[md.obj_norm[i].vtx[2]-1].x, md.obj_normals[md.obj_norm[i].vtx[2]-1].y, md.obj_normals[md.obj_norm[i].vtx[2]-1].z);
		}
	glEnd();

	glPopMatrix();
}
<commit_msg>sun shining<commit_after>#include <stdio.h>
#include <string.h>
#include <math.h>
#include <string.h>
#include <iostream>
#include <fstream>
#include <string>

#include "GL/glut.h"   // - An interface and windows management library
#include "visuals.h"   // Header file for our OpenGL functions

myModel md;
static float tx = 0.0;
static float rotx = 0.0;
static bool animate = false;
static float red = 1.0;
static float green = 0.0;
static float blue = 0.0;

bool shine = true;
static float SunSize = 55.0;

using namespace std;

void createSun(void) {
	glPushMatrix();
		glTranslatef(0, 0, -515);
		glColor3f(1.0, 0.8, 0.0);
		glutSolidSphere(50.0, 40, 40);

		glEnable(GL_BLEND);
		glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
		glColor4f(1.0, 1.0, 0.0, 0.2);
  		glutSolidSphere(SunSize, 40, 40);
		glDisable(GL_BLEND);

	glPopMatrix();
}

void Render() {
	//CLEARS FRAME BUFFER ie COLOR BUFFER& DEPTH BUFFER (1.0)
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);  // Clean up the colour of the window and the depth buffer
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();

	createSun();

	glPushMatrix();
		glTranslatef(0, 0, -300);
		glTranslatef(tx, 0.0, 0.0);
		glRotatef(rotx, 1, 0, 0);

		glColor3f(0.75, 0.35, 0.05);
		DisplayModel(md);
	glPopMatrix();

	glutSwapBuffers();	// All drawing commands applied to the hidden buffer, so now, bring forward the hidden buffer and hide the visible one
}

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

void Resize(int w, int h) {
	// define the visible area of the window ( in pixels )
	if (h == 0) {
		h = 1;
	}
	// Setup viewing volume
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();

	glViewport( 0, 0, w, h);
	gluPerspective(45, (float)w/(float)h, 1, CAM_FAR);

    glMatrixMode(GL_MODELVIEW);
}

void Idle() {
	if (animate) {
		rotx += 0.4;
	}

	if (shine) {
		SunSize += 0.1;
	} else {
		SunSize -= 0.1;
	}
	if (SunSize > 62){
		shine = false;
	} else if (SunSize < 52){
		shine = true;
	}

	glutPostRedisplay();
}

void Keyboard(unsigned char key, int x, int y) {
	switch(key) {
		case 'q':
		case 'Q':
			exit(0);
			break;
		case 'a':
			tx -= 0.5f;
			break;
		case 'd':
			tx += 0.5f;
			break;
		default:
			break;
	}
	glutPostRedisplay();
}

void Mouse(int button, int state, int x, int y) {
	if (state == GLUT_DOWN && button == GLUT_LEFT_BUTTON) {
		animate = !animate;
		glutPostRedisplay();
	}
}

void Setup(char *path) {
	ReadFile(path);

	//Parameter handling
	glShadeModel(GL_SMOOTH);

	glEnable(GL_DEPTH_TEST);
	glDepthFunc(GL_LEQUAL);  //renders a fragment if its z value is less or equal of the stored value
	glClearDepth(1);

	// polygon rendering mode
	glEnable(GL_COLOR_MATERIAL);
	glColorMaterial( GL_FRONT, GL_AMBIENT_AND_DIFFUSE );

	//Set up light source
	GLfloat light_position[] = { 0.0, 30.0, 50.0, 0.0 };
	  // GLfloat light_position[] = { 1000,1000,-3000, 10.0 };
	glLightfv(GL_LIGHT0, GL_POSITION, light_position);

	GLfloat ambientLight[] = { 0.3, 0.3, 0.3, 1.0 };
	GLfloat diffuseLight[] = { 0.8, 0.8, 0.8, 1.0 };
	GLfloat specularLight[] = { 1.0, 1.0, 1.0, 1.0 };

	glLightfv(GL_LIGHT0, GL_AMBIENT, ambientLight );
	glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseLight );
	glLightfv(GL_LIGHT0, GL_SPECULAR, specularLight);

	glEnable(GL_LIGHTING);
	glEnable(GL_LIGHT0);

	// glEnable(GL_COLOR_MATERIAL);
	// glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE );

	glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);

	glEnable(GL_CULL_FACE);
	glFrontFace(GL_CCW);

	// Black background
	glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
}

void MenuSelect(int choice) {
	switch (choice) {
		case RED:
			red = 1.0;
			green = 0.0;
			blue = 0.0;
			break;
		case GREEN:
			red = 0.0;
			green = 1.0;
			blue = 0.0;
			break;
		case BLUE:
			red = 0.0;
			green = 0.0;
			blue = 1.0;
			break;
		case WHITE:
			red = 1.0;
			green = 1.0;
			blue = 1.0;
			break;
		default:
			break;
	}
}

void ReadFile(char *path) {
	md.vertices = POINTS;
	md.faces = FACES;
	char first[80];
	FILE *file = fopen(path, "r");
	if (file == NULL) {
		fprintf(stderr, "Error opening file\n");
		exit(EXIT_FAILURE);
	}
	int i = 0, j = 0, m = 0;
	while (!feof(file)) {
		if (fscanf(file, "%s  ", first) != 1) {
			fprintf(stderr, "error reading line header\n");
			exit(EXIT_FAILURE);
		}
		if ( !strcmp(first, "v") ){
			if (fscanf(file,"%f %f %f ", &md.obj_points[i].x, &md.obj_points[i].y, &md.obj_points[i].z) != 3) {
				fprintf(stderr, "error reading objpoints\n");
				exit(EXIT_FAILURE);
			}
			i++;
		} else if ( !strcmp(first, "vn") ){
			if (fscanf(file,"%f %f %f ", &md.obj_normals[m].x, &md.obj_normals[m].y, &md.obj_normals[m].z) != 3) {
				fprintf(stderr, "error reading objnormals\n");
				exit(EXIT_FAILURE);
			}
			m++;
		} else if ( !strcmp( first, "f")){
			if (fscanf(file,"%d//%d %d//%d %d//%d ", &md.obj_faces[j].vtx[0], &md.obj_norm[j].vtx[0], &md.obj_faces[j].vtx[1], &md.obj_norm[j].vtx[1], &md.obj_faces[j].vtx[2], &md.obj_norm[j].vtx[2]) != 6) {
				fprintf(stderr, "error reading faces\n");
				exit(EXIT_FAILURE);
			}
			j++;
		}
	}

	fclose(file);
}

void DisplayModel(myModel md) {
	glPushMatrix();

	glBegin(GL_TRIANGLES);
		for (int i = 0; i < md.faces; i++) {
			glVertex3f(md.obj_points[md.obj_faces[i].vtx[0]-1].x, md.obj_points[md.obj_faces[i].vtx[0]-1].y, md.obj_points[md.obj_faces[i].vtx[0]-1].z);
			glNormal3f(md.obj_normals[md.obj_norm[i].vtx[0]-1].x, md.obj_normals[md.obj_norm[i].vtx[0]-1].y, md.obj_normals[md.obj_norm[i].vtx[0]-1].z);
			glVertex3f(md.obj_points[md.obj_faces[i].vtx[1]-1].x, md.obj_points[md.obj_faces[i].vtx[1]-1].y, md.obj_points[md.obj_faces[i].vtx[1]-1].z);
			glNormal3f(md.obj_normals[md.obj_norm[i].vtx[1]-1].x, md.obj_normals[md.obj_norm[i].vtx[1]-1].y, md.obj_normals[md.obj_norm[i].vtx[1]-1].z);
			glVertex3f(md.obj_points[md.obj_faces[i].vtx[2]-1].x, md.obj_points[md.obj_faces[i].vtx[2]-1].y, md.obj_points[md.obj_faces[i].vtx[2]-1].z);
			glNormal3f(md.obj_normals[md.obj_norm[i].vtx[2]-1].x, md.obj_normals[md.obj_norm[i].vtx[2]-1].y, md.obj_normals[md.obj_norm[i].vtx[2]-1].z);
		}
	glEnd();

	glPopMatrix();
}
<|endoftext|>


<commit_before>/***************************************************************************
 *   Copyright (C) 2006 by Ingo Kloecker <kloecker@kde.org>                *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU Library General Public License as       *
 *   published by the Free Software Foundation; either version 2 of the    *
 *   License, or (at your option) any later version.                       *
 *                                                                         *
 *   This program 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 General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU Library General Public     *
 *   License along with this program; if not, write to the                 *
 *   Free Software Foundation, Inc.,                                       *
 *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.         *
 ***************************************************************************/
#include <QDebug>

#include "akonadi.h"
#include "akonadiconnection.h"
#include "storagebackend.h"
#include "storage/datastore.h"
#include "storage/entity.h"

#include "create.h"
#include "response.h"

using namespace Akonadi;

Create::Create(): Handler()
{
}

Create::~Create()
{
}

bool Create::handleLine(const QByteArray& line )
{
    // parse out the reference name and mailbox name
    const int startOfCommand = line.indexOf( ' ' ) + 1;
    const int startOfMailbox = line.indexOf( ' ', startOfCommand ) + 1;
    QByteArray mailbox = stripQuotes( line.right( line.size() - startOfMailbox ) );

    // strip off a trailing '/'
    if ( !mailbox.isEmpty() && mailbox[0] == '/' )
      mailbox = mailbox.right( mailbox.size() - 1 );

    // Responses:
    // OK - create completed
    // NO - create failure: can't create mailbox with that name
    // BAD - command unknown or arguments invalid
    Response response;
    response.setTag( tag() );

    response.setSuccess();
    response.setString( "Completed" );
    emit responseAvailable( response );

    deleteLater();
    return true;

    if ( mailbox.isEmpty() || mailbox.contains( "//" ) ) {
        response.setError();
        response.setString( "Invalid argument" );
        emit responseAvailable( response );
    }
    else {
        DataStore *db = connection()->storageBackend();
        const int startOfLocation = mailbox.indexOf( '/' );
        const QByteArray resourceName = mailbox.left( startOfLocation );
        const QByteArray locationName = mailbox.mid( startOfLocation );
        qDebug() << "Create: " << locationName
                 << " in resource: " << resourceName;
        Resource resource = db->getResourceByName( resourceName );
        // first check whether location already exists
        if ( db->getLocationByName( resource, locationName ).isValid() ) {
            response.setFailure();
            response.setString( "A folder with that name does already exist");
            emit responseAvailable( response );
        }
        // we have to create all superior hierarchical folders, so look for the
        // starting point
        QList<QByteArray> foldersToCreate;
        foldersToCreate.append( locationName );
        for ( int endOfSupFolder = locationName.lastIndexOf( '/', locationName.size() - 1 );
              endOfSupFolder > 0;
              endOfSupFolder = locationName.lastIndexOf( '/', endOfSupFolder - 2 ) ) {
            // check whether the superior hierarchical folder exists
            qDebug() << "Does " << locationName.left( endOfSupFolder )
                     << " exist in " << resourceName << "?";
            if ( ! db->getLocationByName( resource, locationName.left( endOfSupFolder ) ).isValid() ) {
                // the superior folder does not exist, so it has to be created
                qDebug() << "No, it has to be created";
                foldersToCreate.prepend( locationName.left( endOfSupFolder ) );
            }
            else {
                // the superior folder exists, so we can stop here
                qDebug() << "Yes, it exists";
                break;
            }
        }
        // now we try to create all necessary folders
        // first check whether the existing superior folder can contain subfolders
        const int endOfSupFolder = foldersToCreate[0].lastIndexOf( '/' );
        if ( endOfSupFolder > 0 ) {
            bool canContainSubfolders = false;
            const QList<MimeType> mimeTypes = db->getMimeTypesForLocation( db->getLocationByName( resource, locationName.left( endOfSupFolder ) ).getId() );
            foreach ( MimeType m, mimeTypes ) {
                if ( m.getMimeType().toLower() == "directory/inode" ) {
                    canContainSubfolders = true;
                    break;
                }
            }
            if ( !canContainSubfolders ) {
                response.setFailure();
                response.setString( "Superior folder cannot contain subfolders" );
                emit responseAvailable( response );
                deleteLater();
                return true;
            }
        }
        // everything looks good, now we create the folders
        foreach ( QByteArray folderName, foldersToCreate ) {
            int locationId = 0;
            db->appendLocation( folderName, resource, &locationId );
            //db->appendMimeTypeForLocation( locationId, MimeType( "directory/inode" ) );
        }
    }

    response.setSuccess();
    response.setString( "Completed" );
    emit responseAvailable( response );

    deleteLater();
    return true;
}

<commit_msg>Write MIME type for location (for now only directory/inode which indicates that the folder can contain subfolders.<commit_after>/***************************************************************************
 *   Copyright (C) 2006 by Ingo Kloecker <kloecker@kde.org>                *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU Library General Public License as       *
 *   published by the Free Software Foundation; either version 2 of the    *
 *   License, or (at your option) any later version.                       *
 *                                                                         *
 *   This program 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 General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU Library General Public     *
 *   License along with this program; if not, write to the                 *
 *   Free Software Foundation, Inc.,                                       *
 *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.         *
 ***************************************************************************/
#include <QDebug>

#include "akonadi.h"
#include "akonadiconnection.h"
#include "storagebackend.h"
#include "storage/datastore.h"
#include "storage/entity.h"

#include "create.h"
#include "response.h"

using namespace Akonadi;

Create::Create(): Handler()
{
}

Create::~Create()
{
}

bool Create::handleLine(const QByteArray& line )
{
    // parse out the reference name and mailbox name
    const int startOfCommand = line.indexOf( ' ' ) + 1;
    const int startOfMailbox = line.indexOf( ' ', startOfCommand ) + 1;
    QByteArray mailbox = stripQuotes( line.right( line.size() - startOfMailbox ) );

    // strip off a trailing '/'
    if ( !mailbox.isEmpty() && mailbox[0] == '/' )
      mailbox = mailbox.right( mailbox.size() - 1 );

    // Responses:
    // OK - create completed
    // NO - create failure: can't create mailbox with that name
    // BAD - command unknown or arguments invalid
    Response response;
    response.setTag( tag() );

    response.setSuccess();
    response.setString( "Completed" );
    emit responseAvailable( response );

    deleteLater();
    return true;

    if ( mailbox.isEmpty() || mailbox.contains( "//" ) ) {
        response.setError();
        response.setString( "Invalid argument" );
        emit responseAvailable( response );
        deleteLater();
        return true;
    }

    DataStore *db = connection()->storageBackend();
    const int startOfLocation = mailbox.indexOf( '/' );
    const QByteArray resourceName = mailbox.left( startOfLocation );
    const QByteArray locationName = mailbox.mid( startOfLocation );
    //qDebug() << "Create: " << locationName
    //         << " in resource: " << resourceName;
    Resource resource = db->getResourceByName( resourceName );

    // first check whether location already exists
    if ( db->getLocationByName( resource, locationName ).isValid() ) {
        response.setFailure();
        response.setString( "A folder with that name does already exist");
        emit responseAvailable( response );
        deleteLater();
        return true;
    }

    // we have to create all superior hierarchical folders, so look for the
    // starting point
    QList<QByteArray> foldersToCreate;
    foldersToCreate.append( locationName );
    for ( int endOfSupFolder = locationName.lastIndexOf( '/', locationName.size() - 1 );
          endOfSupFolder > 0;
          endOfSupFolder = locationName.lastIndexOf( '/', endOfSupFolder - 2 ) ) {
        // check whether the superior hierarchical folder exists
        if ( ! db->getLocationByName( resource, locationName.left( endOfSupFolder ) ).isValid() ) {
            // the superior folder does not exist, so it has to be created
            foldersToCreate.prepend( locationName.left( endOfSupFolder ) );
        }
        else {
            // the superior folder exists, so we can stop here
            break;
        }
    }

    // now we try to create all necessary folders
    // first check whether the existing superior folder can contain subfolders
    const int endOfSupFolder = foldersToCreate[0].lastIndexOf( '/' );
    if ( endOfSupFolder > 0 ) {
        bool canContainSubfolders = false;
        const QList<MimeType> mimeTypes = db->getMimeTypesForLocation( db->getLocationByName( resource, locationName.left( endOfSupFolder ) ).getId() );
        foreach ( MimeType m, mimeTypes ) {
            if ( m.getMimeType().toLower() == "directory/inode" ) {
                canContainSubfolders = true;
                break;
            }
        }
        if ( !canContainSubfolders ) {
            response.setFailure();
            response.setString( "Superior folder cannot contain subfolders" );
            emit responseAvailable( response );
            deleteLater();
            return true;
        }
    }
    // everything looks good, now we create the folders
    foreach ( QByteArray folderName, foldersToCreate ) {
        int locationId = 0;
        db->appendLocation( folderName, resource, &locationId );
        db->appendMimeTypeForLocation( locationId, "directory/inode" );
        // FIXME add more MIME types
    }

    response.setSuccess();
    response.setString( "Completed" );
    emit responseAvailable( response );

    deleteLater();
    return true;
}

<|endoftext|>


<commit_before>#ifndef MCNP2CAD_VERSION_H
#define MCNP2CAD_VERSION_H

#define MCNP2CAD_VERSION_MAJOR 1
#define MCNP2CAD_VERSION_MINOR 0
#define MCNP2CAD_VERSION_REV   5

#endif /* MCNP2CAD_VERSION_H */
<commit_msg>removing old file<commit_after><|endoftext|>


<commit_before>
#include <random>
#include <iostream>

#include "caf/all.hpp"

using namespace std;
using namespace caf;

class config : public actor_system_config {
public:
  size_t from   =         0;
  size_t to     = std::numeric_limits<uint32_t>::max();
  size_t amount = 268500000;
  string separator =   "\n";

  config() {
    opt_group{custom_options_, "global"}
    .add(from, "from,f", "set minimum value (default: 0)")
    .add(to,   "to,t", "set maximum value (default: max_value<uint32>)")
    .add(amount, "amount,a", "set number of values (default: 268 500 000)")
    .add(separator, "separator,s", "separator between numbers (default: \\n)");
  }
};

int main(int argc, char** argv) {
  config cfg;
  // read CLI options
  cfg.parse(argc, argv);
  // return immediately if a help text was printed
  if (cfg.cli_helptext_printed)
    return 0;

  std::mt19937 rng;
  rng.seed(std::random_device()());
  std::uniform_int_distribution<uint32_t> dist(cfg.from,cfg.to);
  vector<uint32_t> values(cfg.amount);
  auto& sep = cfg.separator;
  for (size_t i = 0; i < cfg.amount; ++i) {
    cout << dist(rng);
    if (i < cfg.amount - 1) {
      cout << sep;
    }
  }
  cout << endl;
}

<commit_msg>Set default to 16 bit values<commit_after>
#include <random>
#include <iostream>

#include "caf/all.hpp"

using namespace std;
using namespace caf;

class config : public actor_system_config {
public:
  size_t from   =         0;
  size_t to     = std::numeric_limits<uint16_t>::max();
  size_t amount = 268500000;
  string separator =   "\n";

  config() {
    opt_group{custom_options_, "global"}
    .add(from, "from,f", "set minimum value (default: 0)")
    .add(to,   "to,t", "set maximum value (default: max_value<uint32>)")
    .add(amount, "amount,a", "set number of values (default: 268 500 000)")
    .add(separator, "separator,s", "separator between numbers (default: \\n)");
  }
};

int main(int argc, char** argv) {
  config cfg;
  // read CLI options
  cfg.parse(argc, argv);
  // return immediately if a help text was printed
  if (cfg.cli_helptext_printed)
    return 0;

  std::mt19937 rng;
  rng.seed(std::random_device()());
  std::uniform_int_distribution<uint32_t> dist(cfg.from,cfg.to);
  vector<uint32_t> values(cfg.amount);
  auto& sep = cfg.separator;
  for (size_t i = 0; i < cfg.amount; ++i) {
    cout << dist(rng);
    if (i < cfg.amount - 1) {
      cout << sep;
    }
  }
  cout << endl;
}
<|endoftext|>


<commit_before>//
// Created by Lucas on 10/15/2016.
//

#include "first.h"
#include "readgramar.h"

FirstSet *first(GramaticalRule *gramaticalrule)
{
    FirstSet *head = (FirstSet*) malloc(sizeof(FirstSet));
    int mudou = false;

    //CARACTER_VAZIO esta definido em readgramar.h

    do
    {
        GramaticalRule *currentrule = gramaticalrule;
        while (currentrule != NULL)
        {
            char key = currentrule->key;
            FirstSet *currentfirstset = seekkey(head,key);
            if (currentfirstset == NUlL)
            {
                currentfirstset = (FirstSet*) malloc(sizeof(FirstSet));
                currentfirstset->key = key;
                currentfirstset->set = (char*) malloc(500);
            }

            for (int i = 0; i < strlen(currentrule->rule); i++)
            {
                char crule = currentrule->rule[i];
                if (islower(crule))
                {
                    strncat(currentfirstset->set, crule, 1);
                    mudou = true;
                } else {

                }
            }

            currentrule = currentrule->next;
        }

    } while (mudou);

}

FirstSet *seekkey(FirstSet *firstset, char key)
{
    FirstSet *current = firstset;
    while (current != NULL)
    {
        if (current->key == key)
            return current;

        current = current->next;
    }

    return NULL;
}
<commit_msg>Começando o Else do First<commit_after>//
// Created by Lucas on 10/15/2016.
//

#include "first.h"
#include "readgramar.h"

FirstSet *first(GramaticalRule *gramaticalrule)
{
    FirstSet *head = (FirstSet*) malloc(sizeof(FirstSet));
    int mudou = false;

    //CARACTER_VAZIO esta definido em readgramar.h

    do
    {
        GramaticalRule *currentrule = gramaticalrule;
        while (currentrule != NULL)
        {
            char key = currentrule->key;
            FirstSet *currentfirstset = seekkey(head,key);
            if (currentfirstset == NUlL)
            {
                currentfirstset = (FirstSet*) malloc(sizeof(FirstSet));
                currentfirstset->key = key;
                currentfirstset->set = (char*) malloc(500);
            }

            for (int i = 0; i < strlen(currentrule->rule); i++)
            {
                char crule = currentrule->rule[i];
                if (islower(crule))
                {
                    strncat(currentfirstset->set, crule, 1);
                    mudou = true;
                } else {
                    if(crule != CARACTER_VAZIO){      //verifica se é o caracter vazio
                        char crule = currentfirstset->key;  //se não for, entao o crule é first
                    }
                    for (int j = 0; j < strlen(currentrule->rule); j++) {  //verifica para o resto das regras se alguma tem vazio inclusive na primeira key

                    }

                }
            }

            currentrule = currentrule->next;
        }

    } while (mudou);

}

FirstSet *seekkey(FirstSet *firstset, char key)
{
    FirstSet *current = firstset;
    while (current != NULL)
    {
        if (current->key == key)
            return current;

        current = current->next;
    }

    return NULL;
}
<|endoftext|>


<commit_before>#ifndef __libfixmath_fix16_hpp__
#define __libfixmath_fix16_hpp__

#include "fix16.h"

class Fix16 {
	public:
		fix16_t value;

		Fix16() { value = 0; }
		Fix16(const Fix16 &inValue)  { value = inValue.value;             }
		Fix16(const fix16_t inValue) { value = inValue;                   }
		Fix16(const float inValue)   { value = fix16_from_float(inValue); }
		Fix16(const double inValue)  { value = fix16_from_dbl(inValue);   }
		Fix16(const int16_t inValue) { value = fix16_from_int(inValue);   }

		operator fix16_t() const { return value;                 }
		operator double()  const { return fix16_to_dbl(value);   }
		operator float()   const { return fix16_to_float(value); }
		operator int16_t() const { return fix16_to_int(value);   }

		Fix16 & operator=(const Fix16 &rhs)  { value = rhs.value;             return *this; }
		Fix16 & operator=(const fix16_t rhs) { value = rhs;                   return *this; }
		Fix16 & operator=(const double rhs)  { value = fix16_from_dbl(rhs);   return *this; }
		Fix16 & operator=(const float rhs)   { value = fix16_from_float(rhs); return *this; }
		Fix16 & operator=(const int16_t rhs) { value = fix16_from_int(rhs);   return *this; }

		Fix16 & operator+=(const Fix16 &rhs)  { value += rhs.value;             return *this; }
		Fix16 & operator+=(const fix16_t rhs) { value += rhs;                   return *this; }
		Fix16 & operator+=(const double rhs)  { value += fix16_from_dbl(rhs);   return *this; }
		Fix16 & operator+=(const float rhs)   { value += fix16_from_float(rhs); return *this; }
		Fix16 & operator+=(const int16_t rhs) { value += fix16_from_int(rhs);   return *this; }

		Fix16 & operator-=(const Fix16 &rhs)  { value -= rhs.value; return *this; }
		Fix16 & operator-=(const fix16_t rhs) { value -= rhs; return *this; }
		Fix16 & operator-=(const double rhs)  { value -= fix16_from_dbl(rhs); return *this; }
		Fix16 & operator-=(const float rhs)   { value -= fix16_from_float(rhs); return *this; }
		Fix16 & operator-=(const int16_t rhs) { value -= fix16_from_int(rhs); return *this; }

		Fix16 & operator*=(const Fix16 &rhs)  { value = fix16_mul(value, rhs.value); return *this; }
		Fix16 & operator*=(const fix16_t rhs) { value = fix16_mul(value, rhs); return *this; }
		Fix16 & operator*=(const double rhs)  { value = fix16_mul(value, fix16_from_dbl(rhs)); return *this; }
		Fix16 & operator*=(const float rhs)   { value = fix16_mul(value, fix16_from_float(rhs)); return *this; }
		Fix16 & operator*=(const int16_t rhs) { value *= rhs; return *this; }

		Fix16 & operator/=(const Fix16 &rhs)  { value = fix16_div(value, rhs.value); return *this; }
		Fix16 & operator/=(const fix16_t rhs) { value = fix16_div(value, rhs); return *this; }
		Fix16 & operator/=(const double rhs)  { value = fix16_div(value, fix16_from_dbl(rhs)); return *this; }
		Fix16 & operator/=(const float rhs)   { value = fix16_div(value, fix16_from_float(rhs)); return *this; }
		Fix16 & operator/=(const int16_t rhs) { value /= rhs; return *this; }

		const Fix16 operator+(const Fix16 &other) const  { Fix16 ret = *this; ret += other; return ret; }
		const Fix16 operator+(const fix16_t other) const { Fix16 ret = *this; ret += other; return ret; }
		const Fix16 operator+(const double other) const  { Fix16 ret = *this; ret += other; return ret; }
		const Fix16 operator+(const float other) const   { Fix16 ret = *this; ret += other; return ret; }
		const Fix16 operator+(const int16_t other) const { Fix16 ret = *this; ret += other; return ret; }

#ifndef FIXMATH_NO_OVERFLOW
		const Fix16 sadd(const Fix16 &other)  const { Fix16 ret = fix16_sadd(value, other.value);             return ret; }
		const Fix16 sadd(const fix16_t other) const { Fix16 ret = fix16_sadd(value, other);                   return ret; }
		const Fix16 sadd(const double other)  const { Fix16 ret = fix16_sadd(value, fix16_from_dbl(other));   return ret; }
		const Fix16 sadd(const float other)   const { Fix16 ret = fix16_sadd(value, fix16_from_float(other)); return ret; }
		const Fix16 sadd(const int16_t other) const { Fix16 ret = fix16_sadd(value, fix16_from_int(other));   return ret; }
#endif

		const Fix16 operator-(const Fix16 &other) const  { Fix16 ret = *this; ret -= other; return ret; }
		const Fix16 operator-(const fix16_t other) const { Fix16 ret = *this; ret -= other; return ret; }
		const Fix16 operator-(const double other) const  { Fix16 ret = *this; ret -= other; return ret; }
		const Fix16 operator-(const float other) const   { Fix16 ret = *this; ret -= other; return ret; }
		const Fix16 operator-(const int16_t other) const { Fix16 ret = *this; ret -= other; return ret; }

#ifndef FIXMATH_NO_OVERFLOW
		const Fix16 ssub(const Fix16 &other)  const { Fix16 ret = fix16_sadd(value, -other.value);             return ret; }
		const Fix16 ssub(const fix16_t other) const { Fix16 ret = fix16_sadd(value, -other);                   return ret; }
		const Fix16 ssub(const double other)  const { Fix16 ret = fix16_sadd(value, -fix16_from_dbl(other));   return ret; }
		const Fix16 ssub(const float other)   const { Fix16 ret = fix16_sadd(value, -fix16_from_float(other)); return ret; }
		const Fix16 ssub(const int16_t other) const { Fix16 ret = fix16_sadd(value, -fix16_from_int(other));   return ret; }
#endif

		const Fix16 operator*(const Fix16 &other) const  { Fix16 ret = *this; ret *= other; return ret; }
		const Fix16 operator*(const fix16_t other) const { Fix16 ret = *this; ret *= other; return ret; }
		const Fix16 operator*(const double other) const  { Fix16 ret = *this; ret *= other; return ret; }
		const Fix16 operator*(const float other) const   { Fix16 ret = *this; ret *= other; return ret; }
		const Fix16 operator*(const int16_t other) const { Fix16 ret = *this; ret *= other; return ret; }

#ifndef FIXMATH_NO_OVERFLOW
		const Fix16 smul(const Fix16 &other)  const { Fix16 ret = fix16_smul(value, other.value);             return ret; }
		const Fix16 smul(const fix16_t other) const { Fix16 ret = fix16_smul(value, other);                   return ret; }
		const Fix16 smul(const double other)  const { Fix16 ret = fix16_smul(value, fix16_from_dbl(other));   return ret; }
		const Fix16 smul(const float other)   const { Fix16 ret = fix16_smul(value, fix16_from_float(other)); return ret; }
		const Fix16 smul(const int16_t other) const { Fix16 ret = fix16_smul(value, fix16_from_int(other));   return ret; }
#endif

		const Fix16 operator/(const Fix16 &other) const  { Fix16 ret = *this; ret /= other; return ret; }
		const Fix16 operator/(const fix16_t other) const { Fix16 ret = *this; ret /= other; return ret; }
		const Fix16 operator/(const double other) const  { Fix16 ret = *this; ret /= other; return ret; }
		const Fix16 operator/(const float other) const   { Fix16 ret = *this; ret /= other; return ret; }
		const Fix16 operator/(const int16_t other) const { Fix16 ret = *this; ret /= other; return ret; }

#ifndef FIXMATH_NO_OVERFLOW
		const Fix16 sdiv(const Fix16 &other)  const { Fix16 ret = fix16_sdiv(value, other.value);             return ret; }
		const Fix16 sdiv(const fix16_t other) const { Fix16 ret = fix16_sdiv(value, other);                   return ret; }
		const Fix16 sdiv(const double other)  const { Fix16 ret = fix16_sdiv(value, fix16_from_dbl(other));   return ret; }
		const Fix16 sdiv(const float other)   const { Fix16 ret = fix16_sdiv(value, fix16_from_float(other)); return ret; }
		const Fix16 sdiv(const int16_t other) const { Fix16 ret = fix16_sdiv(value, fix16_from_int(other));   return ret; }
#endif

		const int operator==(const Fix16 &other)  const { return (value == other.value);             }
		const int operator==(const fix16_t other) const { return (value == other);                   }
		const int operator==(const double other)  const { return (value == fix16_from_dbl(other));   }
		const int operator==(const float other)   const { return (value == fix16_from_float(other)); }
		const int operator==(const int16_t other) const { return (value == fix16_from_int(other));   }

		const int operator!=(const Fix16 &other)  const { return (value != other.value);             }
		const int operator!=(const fix16_t other) const { return (value != other);                   }
		const int operator!=(const double other)  const { return (value != fix16_from_dbl(other));   }
		const int operator!=(const float other)   const { return (value != fix16_from_float(other)); }
		const int operator!=(const int16_t other) const { return (value != fix16_from_int(other));   }

		const int operator<=(const Fix16 &other)  const { return (value <= other.value);             }
		const int operator<=(const fix16_t other) const { return (value <= other);                   }
		const int operator<=(const double other)  const { return (value <= fix16_from_dbl(other));   }
		const int operator<=(const float other)   const { return (value <= fix16_from_float(other)); }
		const int operator<=(const int16_t other) const { return (value <= fix16_from_int(other));   }

		const int operator>=(const Fix16 &other)  const { return (value >= other.value);             }
		const int operator>=(const fix16_t other) const { return (value >= other);                   }
		const int operator>=(const double other)  const { return (value >= fix16_from_dbl(other));   }
		const int operator>=(const float other)   const { return (value >= fix16_from_float(other)); }
		const int operator>=(const int16_t other) const { return (value >= fix16_from_int(other));   }

		const int operator< (const Fix16 &other)  const { return (value <  other.value);             }
		const int operator< (const fix16_t other) const { return (value <  other);                   }
		const int operator< (const double other)  const { return (value <  fix16_from_dbl(other));   }
		const int operator< (const float other)   const { return (value <  fix16_from_float(other)); }
		const int operator< (const int16_t other) const { return (value <  fix16_from_int(other));   }

		const int operator> (const Fix16 &other)  const { return (value >  other.value);             }
		const int operator> (const fix16_t other) const { return (value >  other);                   }
		const int operator> (const double other)  const { return (value >  fix16_from_dbl(other));   }
		const int operator> (const float other)   const { return (value >  fix16_from_float(other)); }
		const int operator> (const int16_t other) const { return (value >  fix16_from_int(other));   }

		Fix16  sin() { return Fix16(fix16_sin(value));  }
		Fix16  cos() { return Fix16(fix16_cos(value));  }
		Fix16  tan() { return Fix16(fix16_tan(value));  }
		Fix16 asin() { return Fix16(fix16_asin(value)); }
		Fix16 acos() { return Fix16(fix16_acos(value)); }
		Fix16 atan() { return Fix16(fix16_atan(value)); }
		Fix16 atan2(const Fix16 &inY) { return Fix16(fix16_atan2(value, inY.value)); }
		Fix16 sqrt() { return Fix16(fix16_sqrt(value)); }
};

#endif
<commit_msg>Fix using add/sub functions in C++ wrapper<commit_after>#ifndef __libfixmath_fix16_hpp__
#define __libfixmath_fix16_hpp__

#include "fix16.h"

class Fix16 {
	public:
		fix16_t value;

		Fix16() { value = 0; }
		Fix16(const Fix16 &inValue)  { value = inValue.value;             }
		Fix16(const fix16_t inValue) { value = inValue;                   }
		Fix16(const float inValue)   { value = fix16_from_float(inValue); }
		Fix16(const double inValue)  { value = fix16_from_dbl(inValue);   }
		Fix16(const int16_t inValue) { value = fix16_from_int(inValue);   }

		operator fix16_t() const { return value;                 }
		operator double()  const { return fix16_to_dbl(value);   }
		operator float()   const { return fix16_to_float(value); }
		operator int16_t() const { return fix16_to_int(value);   }

		Fix16 & operator=(const Fix16 &rhs)  { value = rhs.value;             return *this; }
		Fix16 & operator=(const fix16_t rhs) { value = rhs;                   return *this; }
		Fix16 & operator=(const double rhs)  { value = fix16_from_dbl(rhs);   return *this; }
		Fix16 & operator=(const float rhs)   { value = fix16_from_float(rhs); return *this; }
		Fix16 & operator=(const int16_t rhs) { value = fix16_from_int(rhs);   return *this; }

		Fix16 & operator+=(const Fix16 &rhs)  { value = fix16_add(value, rhs.value);             return *this; }
		Fix16 & operator+=(const fix16_t rhs) { value = fix16_add(value, rhs);                   return *this; }
		Fix16 & operator+=(const double rhs)  { value = fix16_add(value, fix16_from_dbl(rhs));   return *this; }
		Fix16 & operator+=(const float rhs)   { value = fix16_add(value, fix16_from_float(rhs)); return *this; }
		Fix16 & operator+=(const int16_t rhs) { value = fix16_add(value, fix16_from_int(rhs));   return *this; }

		Fix16 & operator-=(const Fix16 &rhs)  { value = fix16_sub(value, rhs.value); return *this; }
		Fix16 & operator-=(const fix16_t rhs) { value = fix16_sub(value, rhs); return *this; }
		Fix16 & operator-=(const double rhs)  { value = fix16_sub(value, fix16_from_dbl(rhs)); return *this; }
		Fix16 & operator-=(const float rhs)   { value = fix16_sub(value, fix16_from_float(rhs)); return *this; }
		Fix16 & operator-=(const int16_t rhs) { value = fix16_sub(value, fix16_from_int(rhs)); return *this; }

		Fix16 & operator*=(const Fix16 &rhs)  { value = fix16_mul(value, rhs.value); return *this; }
		Fix16 & operator*=(const fix16_t rhs) { value = fix16_mul(value, rhs); return *this; }
		Fix16 & operator*=(const double rhs)  { value = fix16_mul(value, fix16_from_dbl(rhs)); return *this; }
		Fix16 & operator*=(const float rhs)   { value = fix16_mul(value, fix16_from_float(rhs)); return *this; }
		Fix16 & operator*=(const int16_t rhs) { value = fix16_mul(value, fix16_from_int(rhs)); return *this; }

		Fix16 & operator/=(const Fix16 &rhs)  { value = fix16_div(value, rhs.value); return *this; }
		Fix16 & operator/=(const fix16_t rhs) { value = fix16_div(value, rhs); return *this; }
		Fix16 & operator/=(const double rhs)  { value = fix16_div(value, fix16_from_dbl(rhs)); return *this; }
		Fix16 & operator/=(const float rhs)   { value = fix16_div(value, fix16_from_float(rhs)); return *this; }
		Fix16 & operator/=(const int16_t rhs) { value = fix16_div(value, fix16_from_int(rhs)); return *this; }

		const Fix16 operator+(const Fix16 &other) const  { Fix16 ret = *this; ret += other; return ret; }
		const Fix16 operator+(const fix16_t other) const { Fix16 ret = *this; ret += other; return ret; }
		const Fix16 operator+(const double other) const  { Fix16 ret = *this; ret += other; return ret; }
		const Fix16 operator+(const float other) const   { Fix16 ret = *this; ret += other; return ret; }
		const Fix16 operator+(const int16_t other) const { Fix16 ret = *this; ret += other; return ret; }

#ifndef FIXMATH_NO_OVERFLOW
		const Fix16 sadd(const Fix16 &other)  const { Fix16 ret = fix16_sadd(value, other.value);             return ret; }
		const Fix16 sadd(const fix16_t other) const { Fix16 ret = fix16_sadd(value, other);                   return ret; }
		const Fix16 sadd(const double other)  const { Fix16 ret = fix16_sadd(value, fix16_from_dbl(other));   return ret; }
		const Fix16 sadd(const float other)   const { Fix16 ret = fix16_sadd(value, fix16_from_float(other)); return ret; }
		const Fix16 sadd(const int16_t other) const { Fix16 ret = fix16_sadd(value, fix16_from_int(other));   return ret; }
#endif

		const Fix16 operator-(const Fix16 &other) const  { Fix16 ret = *this; ret -= other; return ret; }
		const Fix16 operator-(const fix16_t other) const { Fix16 ret = *this; ret -= other; return ret; }
		const Fix16 operator-(const double other) const  { Fix16 ret = *this; ret -= other; return ret; }
		const Fix16 operator-(const float other) const   { Fix16 ret = *this; ret -= other; return ret; }
		const Fix16 operator-(const int16_t other) const { Fix16 ret = *this; ret -= other; return ret; }

#ifndef FIXMATH_NO_OVERFLOW
		const Fix16 ssub(const Fix16 &other)  const { Fix16 ret = fix16_sadd(value, -other.value);             return ret; }
		const Fix16 ssub(const fix16_t other) const { Fix16 ret = fix16_sadd(value, -other);                   return ret; }
		const Fix16 ssub(const double other)  const { Fix16 ret = fix16_sadd(value, -fix16_from_dbl(other));   return ret; }
		const Fix16 ssub(const float other)   const { Fix16 ret = fix16_sadd(value, -fix16_from_float(other)); return ret; }
		const Fix16 ssub(const int16_t other) const { Fix16 ret = fix16_sadd(value, -fix16_from_int(other));   return ret; }
#endif

		const Fix16 operator*(const Fix16 &other) const  { Fix16 ret = *this; ret *= other; return ret; }
		const Fix16 operator*(const fix16_t other) const { Fix16 ret = *this; ret *= other; return ret; }
		const Fix16 operator*(const double other) const  { Fix16 ret = *this; ret *= other; return ret; }
		const Fix16 operator*(const float other) const   { Fix16 ret = *this; ret *= other; return ret; }
		const Fix16 operator*(const int16_t other) const { Fix16 ret = *this; ret *= other; return ret; }

#ifndef FIXMATH_NO_OVERFLOW
		const Fix16 smul(const Fix16 &other)  const { Fix16 ret = fix16_smul(value, other.value);             return ret; }
		const Fix16 smul(const fix16_t other) const { Fix16 ret = fix16_smul(value, other);                   return ret; }
		const Fix16 smul(const double other)  const { Fix16 ret = fix16_smul(value, fix16_from_dbl(other));   return ret; }
		const Fix16 smul(const float other)   const { Fix16 ret = fix16_smul(value, fix16_from_float(other)); return ret; }
		const Fix16 smul(const int16_t other) const { Fix16 ret = fix16_smul(value, fix16_from_int(other));   return ret; }
#endif

		const Fix16 operator/(const Fix16 &other) const  { Fix16 ret = *this; ret /= other; return ret; }
		const Fix16 operator/(const fix16_t other) const { Fix16 ret = *this; ret /= other; return ret; }
		const Fix16 operator/(const double other) const  { Fix16 ret = *this; ret /= other; return ret; }
		const Fix16 operator/(const float other) const   { Fix16 ret = *this; ret /= other; return ret; }
		const Fix16 operator/(const int16_t other) const { Fix16 ret = *this; ret /= other; return ret; }

#ifndef FIXMATH_NO_OVERFLOW
		const Fix16 sdiv(const Fix16 &other)  const { Fix16 ret = fix16_sdiv(value, other.value);             return ret; }
		const Fix16 sdiv(const fix16_t other) const { Fix16 ret = fix16_sdiv(value, other);                   return ret; }
		const Fix16 sdiv(const double other)  const { Fix16 ret = fix16_sdiv(value, fix16_from_dbl(other));   return ret; }
		const Fix16 sdiv(const float other)   const { Fix16 ret = fix16_sdiv(value, fix16_from_float(other)); return ret; }
		const Fix16 sdiv(const int16_t other) const { Fix16 ret = fix16_sdiv(value, fix16_from_int(other));   return ret; }
#endif

		const int operator==(const Fix16 &other)  const { return (value == other.value);             }
		const int operator==(const fix16_t other) const { return (value == other);                   }
		const int operator==(const double other)  const { return (value == fix16_from_dbl(other));   }
		const int operator==(const float other)   const { return (value == fix16_from_float(other)); }
		const int operator==(const int16_t other) const { return (value == fix16_from_int(other));   }

		const int operator!=(const Fix16 &other)  const { return (value != other.value);             }
		const int operator!=(const fix16_t other) const { return (value != other);                   }
		const int operator!=(const double other)  const { return (value != fix16_from_dbl(other));   }
		const int operator!=(const float other)   const { return (value != fix16_from_float(other)); }
		const int operator!=(const int16_t other) const { return (value != fix16_from_int(other));   }

		const int operator<=(const Fix16 &other)  const { return (value <= other.value);             }
		const int operator<=(const fix16_t other) const { return (value <= other);                   }
		const int operator<=(const double other)  const { return (value <= fix16_from_dbl(other));   }
		const int operator<=(const float other)   const { return (value <= fix16_from_float(other)); }
		const int operator<=(const int16_t other) const { return (value <= fix16_from_int(other));   }

		const int operator>=(const Fix16 &other)  const { return (value >= other.value);             }
		const int operator>=(const fix16_t other) const { return (value >= other);                   }
		const int operator>=(const double other)  const { return (value >= fix16_from_dbl(other));   }
		const int operator>=(const float other)   const { return (value >= fix16_from_float(other)); }
		const int operator>=(const int16_t other) const { return (value >= fix16_from_int(other));   }

		const int operator< (const Fix16 &other)  const { return (value <  other.value);             }
		const int operator< (const fix16_t other) const { return (value <  other);                   }
		const int operator< (const double other)  const { return (value <  fix16_from_dbl(other));   }
		const int operator< (const float other)   const { return (value <  fix16_from_float(other)); }
		const int operator< (const int16_t other) const { return (value <  fix16_from_int(other));   }

		const int operator> (const Fix16 &other)  const { return (value >  other.value);             }
		const int operator> (const fix16_t other) const { return (value >  other);                   }
		const int operator> (const double other)  const { return (value >  fix16_from_dbl(other));   }
		const int operator> (const float other)   const { return (value >  fix16_from_float(other)); }
		const int operator> (const int16_t other) const { return (value >  fix16_from_int(other));   }

		Fix16  sin() { return Fix16(fix16_sin(value));  }
		Fix16  cos() { return Fix16(fix16_cos(value));  }
		Fix16  tan() { return Fix16(fix16_tan(value));  }
		Fix16 asin() { return Fix16(fix16_asin(value)); }
		Fix16 acos() { return Fix16(fix16_acos(value)); }
		Fix16 atan() { return Fix16(fix16_atan(value)); }
		Fix16 atan2(const Fix16 &inY) { return Fix16(fix16_atan2(value, inY.value)); }
		Fix16 sqrt() { return Fix16(fix16_sqrt(value)); }
};

#endif
<|endoftext|>