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

#include "../include/babextended.h"

#include <string.h>

#define BUFFER_SIZE         2048
#define LOG_FREQUENCY_HZ    30

#if PLATFORM==PLATFORM_MAC
    #ifdef __cplusplus
    extern "C" {
    #endif
        extern void logSetStream(FILE * file);
    #ifdef __cplusplus
    }
    #endif
#else
    extern void logSetStream(FILE * file);
#endif

Log * Log::defaultLog = new Log();

Log *Log::global()
{
    return defaultLog;
}

Log::Log()
{
    mutexInit(&mMutex);
}

Log::~Log()
{

}

void Log::start(const char * filename, bool enableOutput)
{
    mPrintOnOutput = enableOutput;
    mFile = fopen(filename,"w+");
    if (mFile==NULL)
    {
        return;
    }

    // link old log from babcode to the new log
    logSetStream(mFile);

    mQueue = new ByteArrayQueue(128, BUFFER_SIZE);

    mThreadRun = true;
    threadInit(&mThread, privateThreadStarter, this);

}

void Log::stop()
{
    mThreadRun = false;
    if (mFile!=NULL)
    {
        fflush(mFile);
        fclose(mFile);
        mFile=NULL;
    }
}

void Log::addError(const char fmt[], va_list args)
{
    char buffer[BUFFER_SIZE];

    memset(buffer, 0, BUFFER_SIZE);

    int prefix = snprintf(buffer, BUFFER_SIZE, "[%8.3f] [ERROR] ", getTicks()/1000.0);
    int size = vsnprintf(buffer+prefix, BUFFER_SIZE - prefix,fmt,args);

    int total = size+prefix;

    if (size > 0 && total < BUFFER_SIZE)
    {
        mutexLock(&mMutex);
        mQueue->write((uint8_t *)buffer, BUFFER_SIZE);
        mutexUnlock(&mMutex);
    }
}

void Log::addInfo(const char fmt[], va_list args)
{
    char buffer[BUFFER_SIZE];

    memset(buffer, 0, BUFFER_SIZE);

    int prefix = snprintf(buffer, BUFFER_SIZE, "[%8.3f] [INFO] ", getTicks()/1000.0);
    int size = vsnprintf(buffer+prefix, BUFFER_SIZE - prefix,fmt,args);

    int total = size+prefix;

    if (size > 0 && total < BUFFER_SIZE)
    {
        mutexLock(&mMutex);
        mQueue->write((uint8_t *)buffer, BUFFER_SIZE);
        mutexUnlock(&mMutex);
    }
}

void Log::error(const char fmt[], ...)
{
    va_list args;
    va_start(args, fmt);
    addError(fmt, args);
    va_end(args);
}

void Log::info(const char fmt[], ...)
{
    va_list args;
    va_start(args, fmt);
    addInfo(fmt, args);
    va_end(args);
}

void Log::privateThreadRunner(void)
{
    uint32_t begin;
    uint32_t end;

    uint8_t * buffer;

    bool writeSomething;

    while (mThreadRun==true)
    {
        begin = getTicks();

        writeSomething = false;

        mutexLock(&mMutex);
        buffer = mQueue->read();
        mutexUnlock(&mMutex);

        while (buffer!=0)
        {
            int size = (int)strnlen((char *)buffer, BUFFER_SIZE);
            if (size < BUFFER_SIZE)
            {
                fwrite(buffer, size, 1, mFile);

                if (mPrintOnOutput==true)
                {
                    printf("%s", buffer);
                }

                writeSomething = true;
            }

            mutexLock(&mMutex);
            buffer = mQueue->read();
            mutexUnlock(&mMutex);
        }

        if (writeSomething==true)
        {
            fflush(mFile);
        }

        end = getTicks();

        int32_t sleepTime = 1000 / LOG_FREQUENCY_HZ - (end-begin);
        if (sleepTime <= 0)
        {
            sleepTime = 0;
        }

        waitMs(sleepTime);

    }

}

void * Log::privateThreadStarter(void * parameter)
{
    Log * object = (Log *)parameter;
    object->privateThreadRunner();
    threadExit();
    return 0;
}

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

#include "../include/babextended.h"

#include <string.h>

#define BUFFER_SIZE         2048
#define LOG_FREQUENCY_HZ    30

#if PLATFORM==PLATFORM_MAC
    #ifdef __cplusplus
    extern "C" {
    #endif
        extern void logSetStream(FILE * file);
    #ifdef __cplusplus
    }
    #endif
#else
    extern void logSetStream(FILE * file);
#endif

Log * Log::defaultLog = new Log();

Log *Log::global()
{
    return defaultLog;
}

Log::Log()
{
    mQueue = new ByteArrayQueue(128, BUFFER_SIZE);
    mutexInit(&mMutex);
}

Log::~Log()
{

}

void Log::start(const char * filename, bool enableOutput)
{
    mPrintOnOutput = enableOutput;
    mFile = fopen(filename,"w+");
    if (mFile==NULL)
    {
        return;
    }

    // link old log from babcode to the new log
    logSetStream(mFile);

    mThreadRun = true;
    threadInit(&mThread, privateThreadStarter, this);
}

void Log::stop()
{
    mThreadRun = false;
    if (mFile!=NULL)
    {
        fflush(mFile);
        fclose(mFile);
        mFile=NULL;
    }
}

void Log::addError(const char fmt[], va_list args)
{
    char buffer[BUFFER_SIZE];

    memset(buffer, 0, BUFFER_SIZE);

    int prefix = snprintf(buffer, BUFFER_SIZE, "[%8.3f] [ERROR] ", getTicks()/1000.0);
    int size = vsnprintf(buffer+prefix, BUFFER_SIZE - prefix,fmt,args);

    int total = size+prefix;

    if (size > 0 && total < BUFFER_SIZE)
    {
        mutexLock(&mMutex);
        mQueue->write((uint8_t *)buffer, BUFFER_SIZE);
        mutexUnlock(&mMutex);
    }
}

void Log::addInfo(const char fmt[], va_list args)
{
    char buffer[BUFFER_SIZE];

    memset(buffer, 0, BUFFER_SIZE);

    int prefix = snprintf(buffer, BUFFER_SIZE, "[%8.3f] [INFO] ", getTicks()/1000.0);
    int size = vsnprintf(buffer+prefix, BUFFER_SIZE - prefix,fmt,args);

    int total = size+prefix;

    if (size > 0 && total < BUFFER_SIZE)
    {
        mutexLock(&mMutex);
        mQueue->write((uint8_t *)buffer, BUFFER_SIZE);
        mutexUnlock(&mMutex);
    }
}

void Log::error(const char fmt[], ...)
{
    va_list args;
    va_start(args, fmt);
    addError(fmt, args);
    va_end(args);
}

void Log::info(const char fmt[], ...)
{
    va_list args;
    va_start(args, fmt);
    addInfo(fmt, args);
    va_end(args);
}

void Log::privateThreadRunner(void)
{
    uint32_t begin;
    uint32_t end;

    uint8_t * buffer;

    bool writeSomething;

    while (mThreadRun==true)
    {
        begin = getTicks();

        writeSomething = false;

        mutexLock(&mMutex);
        buffer = mQueue->read();
        mutexUnlock(&mMutex);

        while (buffer!=0)
        {
            int size = (int)strnlen((char *)buffer, BUFFER_SIZE);
            if (size < BUFFER_SIZE)
            {
                fwrite(buffer, size, 1, mFile);

                if (mPrintOnOutput==true)
                {
                    printf("%s", buffer);
                }

                writeSomething = true;
            }

            mutexLock(&mMutex);
            buffer = mQueue->read();
            mutexUnlock(&mMutex);
        }

        if (writeSomething==true)
        {
            fflush(mFile);
        }

        end = getTicks();

        int32_t sleepTime = 1000 / LOG_FREQUENCY_HZ - (end-begin);
        if (sleepTime <= 0)
        {
            sleepTime = 0;
        }

        waitMs(sleepTime);

    }

}

void * Log::privateThreadStarter(void * parameter)
{
    Log * object = (Log *)parameter;
    object->privateThreadRunner();
    threadExit();
    return 0;
}

<|endoftext|>


<commit_before>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2006 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/
//$Id$

#ifndef _OCTREE_HPP_
#define _OCTREE_HPP_

// mapnik
#include <mapnik/global.hpp>

// boost
#include <boost/utility.hpp>

// stl
#include <vector>
#include <iostream>
#include <deque>

namespace mapnik {

   typedef boost::uint8_t byte ;
   struct rgb
   {
         byte r;
         byte g;
         byte b;
         rgb(byte r_, byte b_, byte g_)
            : r(r_), g(g_), b(b_) {}
   };

   struct RGBPolicy
   {
         const static unsigned MAX_LEVELS = 6;
         const static unsigned MIN_LEVELS = 2;
         inline static unsigned index_from_level(unsigned level, rgb const& c)
         {
            unsigned shift = 7 - level;
            return (((c.r >> shift) & 1) << 2)
               | (((c.g >> shift) & 1) << 1)
               | ((c.b >> shift) & 1);
         }
   };

   template <typename T, typename InsertPolicy = RGBPolicy >
   class octree : private boost::noncopyable
   {
         struct node
         {
               node ()
                  :  reds(0),
                     greens(0),
                     blues(0),
                     count(0),
                     count_cum(0),
                     children_count(0),
                     index(0)
               {
                  memset(&children_[0],0,sizeof(children_));
               }

               ~node ()
               {
                  for (unsigned i = 0;i < 8; ++i) {
                     if (children_[i] != 0) delete children_[i],children_[i]=0;
                  }
               }

               bool is_leaf() const { return count == 0; }
               node * children_[8];
               boost::uint64_t reds;
               boost::uint64_t greens;
               boost::uint64_t blues;
               unsigned count;
               double reduce_cost;
               unsigned count_cum;
               byte  children_count;
               byte  index;
         };
         struct node_cmp
         {
               bool operator() ( const node * lhs,const node* rhs) const
               {
                  return lhs->reduce_cost < rhs->reduce_cost;
               }
         };

         std::deque<node*> reducible_[InsertPolicy::MAX_LEVELS];
         unsigned max_colors_;
         unsigned colors_;
         unsigned offset_;
         unsigned leaf_level_;
         bool has_alfa_;

      public:
         explicit octree(unsigned max_colors=256)
            : max_colors_(max_colors),
              colors_(0),
              offset_(0),
              leaf_level_(InsertPolicy::MAX_LEVELS),
              has_alfa_(false),
              root_(new node())
         {}

         ~octree() { delete root_;}

         void setMaxColors(unsigned max_colors)
         {
            max_colors_ = max_colors;
         }

         void setOffset(unsigned offset)
         {
            offset_ = offset;
         }

         unsigned getOffset()
         {
            return offset_;
         }

         void hasAlfa(bool v)
         {
            has_alfa_=v;
         }

         bool hasAlfa()
         {
            return has_alfa_;
         }

         void insert(T const& data)
         {
            unsigned level = 0;
            node * cur_node = root_;
            while (true) {
               cur_node->count_cum++;
               cur_node->reds   += data.r;
               cur_node->greens += data.g;
               cur_node->blues  += data.b;

               if ( cur_node->count > 0 || level == leaf_level_)
               {
                  cur_node->count  += 1;
                  if (cur_node->count == 1) ++colors_;
                  //if (colors_ >= max_colors_ - 1)
                  //reduce();
                  break;
               }

               unsigned idx = InsertPolicy::index_from_level(level,data);
               if (cur_node->children_[idx] == 0) {
                  cur_node->children_count++;
                  cur_node->children_[idx] = new node();
                  if (level < leaf_level_-1)
                  {
                     reducible_[level+1].push_back(cur_node->children_[idx]);
                  }
               }
               cur_node = cur_node->children_[idx];
               ++level;
            }
         }

         int quantize(rgb const& c) const
         {
            unsigned level = 0;
            node * cur_node = root_;
            while (cur_node)
            {
               if (cur_node->children_count == 0)
                    return cur_node->index + offset_;
               unsigned idx = InsertPolicy::index_from_level(level,c);
               cur_node = cur_node->children_[idx];
               ++level;
            }
            return -1;
         }

         void create_palette(std::vector<rgb> & palette)
         {
            if (has_alfa_)
            {
               max_colors_--;
               palette.push_back(rgb(0,0,0));
            }
            reduce();
            palette.reserve(colors_);
            create_palette(palette, root_);
         }

         void computeCost(node *r)
         {
            r->reduce_cost = 0;
            if (r->children_count==0)
                return;

            double sum[] = {0,0,0};
            for (unsigned idx=0; idx < 8; ++idx) if (r->children_[idx] != 0)
            {
                computeCost(r->children_[idx]);
                sum[0] += r->children_[idx]->reds;
                sum[1] += r->children_[idx]->greens;
                sum[2] += r->children_[idx]->blues;
            }

            for (unsigned idx=0; idx < 8; ++idx) if (r->children_[idx] != 0)
            {
                r->reduce_cost += r->children_[idx]->reduce_cost;
                r->reduce_cost += fabs(r->children_[idx]->reds
                        - sum[0] * r->children_[idx]->count_cum / r->count_cum);
                r->reduce_cost += fabs(r->children_[idx]->greens
                        - sum[1] * r->children_[idx]->count_cum / r->count_cum);
                r->reduce_cost += fabs(r->children_[idx]->blues
                        - sum[2] * r->children_[idx]->count_cum / r->count_cum);
            }
         }

         void reduce()
         {
            computeCost(root_);
            reducible_[0].push_back(root_);

            // sort reducible by reduce_cost
            for (unsigned i=0;i<InsertPolicy::MAX_LEVELS;++i)
            {
               std::sort(reducible_[i].begin(), reducible_[i].end(),node_cmp());
            }
            while ( colors_ > max_colors_ && colors_ > 1)
            {
               while (leaf_level_ >0  && reducible_[leaf_level_-1].size() == 0)
               {
                  --leaf_level_;
               }

               if (leaf_level_ <= 0) return;

               // select best of all reducible:
               unsigned red_idx = leaf_level_-1;
               unsigned bestv = (*reducible_[red_idx].begin())->count_cum;
               for(unsigned i=red_idx; i>=InsertPolicy::MIN_LEVELS; i--) if (!reducible_[i].empty()){
                   node *nd = *reducible_[i].begin();
                   unsigned gch = 0;
                   for(unsigned idx=0; idx<8; idx++){
                       if (nd->children_[idx])
                           gch += nd->children_[idx]->children_count;
                   }
                   if (gch==0 && nd->count_cum<bestv){
                       bestv = nd->count_cum;
                       red_idx = i;
                   }
               }

               typename std::deque<node*>::iterator pos = reducible_[red_idx].begin();
               node * cur_node = *pos;
               unsigned num_children = 0;
               for (unsigned idx=0; idx < 8; ++idx)
               {
                  if (cur_node->children_[idx] != 0)
                  {
                     cur_node->children_count--;
                     ++num_children;
                     cur_node->count  += cur_node->children_[idx]->count;
                     //todo: case of nonleaf children, if someday sorting by reduce_cost doesn't handle it
                     delete cur_node->children_[idx], cur_node->children_[idx]=0;
                  }
               }

               reducible_[red_idx].erase(pos);
               if (num_children > 0 )
               {
                  colors_ -= (num_children - 1);
               }
            }
         }

         void create_palette(std::vector<rgb> & palette, node * itr) const
         {
            if (itr->count != 0)
            {
               unsigned count = itr->count;
               palette.push_back(rgb(byte(itr->reds/float(count)),
                                     byte(itr->greens/float(count)),
                                     byte(itr->blues/float(count))));
               itr->index = palette.size() - 1;
            }
            for (unsigned i=0; i < 8 ;++i)
            {
               if (itr->children_[i] != 0)
                  create_palette(palette, itr->children_[i]);
            }
         }
      private:
         node * root_;
   };
} // namespace mapnik

#endif /* _OCTREE_HPP_ */
<commit_msg>png256 bugfix and improvements merged from r1663<commit_after>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2006 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/
//$Id$

#ifndef _OCTREE_HPP_
#define _OCTREE_HPP_

// mapnik
#include <mapnik/global.hpp>

// boost
#include <boost/utility.hpp>

// stl
#include <vector>
#include <iostream>
#include <deque>

namespace mapnik {

   typedef boost::uint8_t byte ;
   struct rgb
   {
         byte r;
         byte g;
         byte b;
         rgb(byte r_, byte b_, byte g_)
            : r(r_), g(g_), b(b_) {}
   };

   struct RGBPolicy
   {
         const static unsigned MAX_LEVELS = 6;
         const static unsigned MIN_LEVELS = 2;
         inline static unsigned index_from_level(unsigned level, rgb const& c)
         {
            unsigned shift = 7 - level;
            return (((c.r >> shift) & 1) << 2)
               | (((c.g >> shift) & 1) << 1)
               | ((c.b >> shift) & 1);
         }
   };

   template <typename T, typename InsertPolicy = RGBPolicy >
   class octree : private boost::noncopyable
   {
         struct node
         {
               node ()
                  :  reds(0),
                     greens(0),
                     blues(0),
                     count(0),
                     count_cum(0),
                     children_count(0),
                     index(0)
               {
                  memset(&children_[0],0,sizeof(children_));
               }

               ~node ()
               {
                  for (unsigned i = 0;i < 8; ++i) {
                     if (children_[i] != 0) delete children_[i],children_[i]=0;
                  }
               }

               bool is_leaf() const { return count == 0; }
               node * children_[8];
               boost::uint64_t reds;
               boost::uint64_t greens;
               boost::uint64_t blues;
               unsigned count;
               double reduce_cost;
               unsigned count_cum;
               byte  children_count;
               byte  index;
         };
         struct node_cmp
         {
               bool operator() ( const node * lhs,const node* rhs) const
               {
                  return lhs->reduce_cost < rhs->reduce_cost;
               }
         };

         std::deque<node*> reducible_[InsertPolicy::MAX_LEVELS];
         unsigned max_colors_;
         unsigned colors_;
         unsigned offset_;
         unsigned leaf_level_;
         bool has_alfa_;

      public:
         explicit octree(unsigned max_colors=256)
            : max_colors_(max_colors),
              colors_(0),
              offset_(0),
              leaf_level_(InsertPolicy::MAX_LEVELS),
              has_alfa_(false),
              root_(new node())
         {}

         ~octree() { delete root_;}

         void setMaxColors(unsigned max_colors)
         {
            max_colors_ = max_colors;
         }

         void setOffset(unsigned offset)
         {
            offset_ = offset;
         }

         unsigned getOffset()
         {
            return offset_;
         }

         void hasAlfa(bool v)
         {
            has_alfa_=v;
         }

         bool hasAlfa()
         {
            return has_alfa_;
         }

         void insert(T const& data)
         {
            unsigned level = 0;
            node * cur_node = root_;
            while (true) {
               cur_node->count_cum++;
               cur_node->reds   += data.r;
               cur_node->greens += data.g;
               cur_node->blues  += data.b;

               if ( cur_node->count > 0 || level == leaf_level_)
               {
                  cur_node->count  += 1;
                  if (cur_node->count == 1) ++colors_;
                  //if (colors_ >= max_colors_ - 1)
                  //reduce();
                  break;
               }

               unsigned idx = InsertPolicy::index_from_level(level,data);
               if (cur_node->children_[idx] == 0) {
                  cur_node->children_count++;
                  cur_node->children_[idx] = new node();
                  if (level < leaf_level_-1)
                  {
                     reducible_[level+1].push_back(cur_node->children_[idx]);
                  }
               }
               cur_node = cur_node->children_[idx];
               ++level;
            }
         }

         int quantize(rgb const& c) const
         {
            unsigned level = 0;
            node * cur_node = root_;
            while (cur_node)
            {
               if (cur_node->children_count == 0)
                    return cur_node->index + offset_;
               unsigned idx = InsertPolicy::index_from_level(level,c);
               cur_node = cur_node->children_[idx];
               ++level;
            }
            return -1;
         }

         void create_palette(std::vector<rgb> & palette)
         {
            if (has_alfa_)
            {
               max_colors_--;
               palette.push_back(rgb(0,0,0));
            }
            reduce();
            palette.reserve(colors_);
            create_palette(palette, root_);
         }

         void computeCost(node *r)
         {
            r->reduce_cost = 0;
            if (r->children_count==0)
               return;

            double mean_r = r->reds   / r->count_cum;
            double mean_g = r->greens / r->count_cum;
            double mean_b = r->blues  / r->count_cum;
            for (unsigned idx=0; idx < 8; ++idx) if (r->children_[idx] != 0)
            {
               double dr,dg,db;
               computeCost(r->children_[idx]);

               dr = r->children_[idx]->reds   / r->children_[idx]->count_cum - mean_r;
               dg = r->children_[idx]->greens / r->children_[idx]->count_cum - mean_g;
               db = r->children_[idx]->blues  / r->children_[idx]->count_cum - mean_b;

               r->reduce_cost += r->children_[idx]->reduce_cost;
               r->reduce_cost += (dr*dr + dg*dg + db*db) * r->children_[idx]->count_cum;
            }
         }

         void reduce()
         {
            computeCost(root_);
            reducible_[0].push_back(root_);

            // sort reducible by reduce_cost
            for (unsigned i=0;i<InsertPolicy::MAX_LEVELS;++i)
            {
               std::sort(reducible_[i].begin(), reducible_[i].end(),node_cmp());
            }
            while ( colors_ > max_colors_ && colors_ > 1)
            {
               while (leaf_level_ >0  && reducible_[leaf_level_-1].size() == 0)
               {
                  --leaf_level_;
               }

               if (leaf_level_ <= 0) return;

               // select best of all reducible:
               unsigned red_idx = leaf_level_-1;
               unsigned bestv = (*reducible_[red_idx].begin())->reduce_cost;
               for(unsigned i=red_idx; i>=InsertPolicy::MIN_LEVELS; i--) if (!reducible_[i].empty()){
                   node *nd = *reducible_[i].begin();
                   unsigned gch = 0;
                   for(unsigned idx=0; idx<8; idx++){
                       if (nd->children_[idx])
                           gch += nd->children_[idx]->children_count;
                   }
                   if (gch==0 && nd->reduce_cost < bestv){
                       bestv = nd->reduce_cost;
                       red_idx = i;
                   }
               }

               typename std::deque<node*>::iterator pos = reducible_[red_idx].begin();
               node * cur_node = *pos;
               unsigned num_children = 0;
               for (unsigned idx=0; idx < 8; ++idx)
               {
                  if (cur_node->children_[idx] != 0)
                  {
                     cur_node->children_count--;
                     ++num_children;
                     cur_node->count  += cur_node->children_[idx]->count;
                     //todo: case of nonleaf children, if someday sorting by reduce_cost doesn't handle it
                     delete cur_node->children_[idx], cur_node->children_[idx]=0;
                  }
               }

               reducible_[red_idx].erase(pos);
               if (num_children > 0 )
               {
                  colors_ -= (num_children - 1);
               }
            }
         }

         void create_palette(std::vector<rgb> & palette, node * itr) const
         {
            if (itr->count != 0)
            {
               unsigned count = itr->count;
               palette.push_back(rgb(byte(itr->reds/float(count)),
                                     byte(itr->greens/float(count)),
                                     byte(itr->blues/float(count))));
               itr->index = palette.size() - 1;
            }
            for (unsigned i=0; i < 8 ;++i)
            {
               if (itr->children_[i] != 0)
                  create_palette(palette, itr->children_[i]);
            }
         }
      private:
         node * root_;
   };
} // namespace mapnik

#endif /* _OCTREE_HPP_ */
<|endoftext|>


<commit_before>// Copyright © 2014 German Neuroinformatics Node (G-Node)
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted under the terms of the BSD License. See
// LICENSE file in the root of the Project.
//
// Author: Christian Kellner <kellner@bio.lmu.de>

#ifndef NIX_EXCEPTION_H
#define NIX_EXCEPTION_H

#include <nix/Platform.hpp>
#include <nix/types.hpp>

#include <limits>
#include <type_traits>
#include <cstddef>

#include <stdexcept>
#include <sstream>
#include <vector>

namespace nix {

class OutOfBounds : public std::out_of_range {
public:
    OutOfBounds(const std::string &what_arg, ndsize_t where) :
            out_of_range(make_message(what_arg, where)), index(where) {

    }

    OutOfBounds(const std::string &what_arg) :
            out_of_range(what_arg), index(0) { }

    ndsize_t where(void) const {
        return index;
    }

    static std::string make_message(const std::string &str, ndsize_t where) {
            std::stringstream sstream(str);

            sstream << " [at index: " << where << "]";
            return sstream.str();
    }

private:
    ndsize_t index;
};

class InvalidRank : public std::out_of_range {
public:
    InvalidRank(const std::string &message)
            : std::out_of_range(message) { }
};

class UninitializedEntity : public std::exception {
public:
    UninitializedEntity() { }
    const char *what() const NOEXCEPT {
        return "The Entity being accessed is uninitialized or empty.";
    }
};

class EmptyString: public std::invalid_argument {
public:
    EmptyString(const std::string &caller) :
            std::invalid_argument("Empty string given - not a valid value for " + caller) { }
};

class DuplicateName: public std::invalid_argument {
public:
    DuplicateName(const std::string &caller):
    std::invalid_argument("Duplicate name - names have to be unique for a given entity type & parent. (" + caller + ")") { }

};

class InvalidName: public std::invalid_argument {
public:
    InvalidName(const std::string &caller):
    std::invalid_argument("Invalid name given - names have to be sanitized using util function. (" + caller + ")") { }
};

class UnsortedTicks: public std::invalid_argument {
public:
    UnsortedTicks(const std::string &caller):
            std::invalid_argument("Ticks are not given in a ascending order: " + caller) { }
};

class InvalidUnit: public std::invalid_argument {
public:
    InvalidUnit(const std::string &what, const std::string &where):
            std::invalid_argument("InvalidUnit: " + what + " evoked at: " + where) { }
};

class IncompatibleDimensions: public std::invalid_argument {
public:
    IncompatibleDimensions(const std::string &what, const std::string &where):
            std::invalid_argument("IncompatibleDimensions: " + what + " evoked at: " + where) { }
};

class InvalidDimension : public std::invalid_argument {

public:
    InvalidDimension(const std::string &what, const std::string &where):
            std::invalid_argument("InvalidDimension: " + what + " evoked at: " + where) { }
};

class ConsistencyError: public std::runtime_error {
public:
    ConsistencyError(const std::string &what) : runtime_error("ConsistencyError: " + what){ }
};

    class MissingAttr: public std::runtime_error {
public:
    MissingAttr(const std::string &name):
            std::runtime_error("MissingAttribute: Obligatory attribute " + name + " is not set!") { }
};

namespace check {

template<typename T>
inline typename std::enable_if<! std::is_same<T, size_t>::value, size_t>::type
fits_in_size_t(T size, const std::string &msg_if_fail) {
    if (size > std::numeric_limits<size_t>::max()) {
        throw OutOfBounds(msg_if_fail);
    }
    return static_cast<size_t>(size);
}

template<typename T>
inline typename std::enable_if<std::is_same<T, size_t>::value, size_t>::type
fits_in_size_t(T size, const std::string &msg_if_fail) {
    return size;
}

} // nix::check::

}

#endif
<commit_msg>adds exception indicating if a non-nix file is opened<commit_after>// Copyright © 2014 German Neuroinformatics Node (G-Node)
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted under the terms of the BSD License. See
// LICENSE file in the root of the Project.
//
// Author: Christian Kellner <kellner@bio.lmu.de>

#ifndef NIX_EXCEPTION_H
#define NIX_EXCEPTION_H

#include <nix/Platform.hpp>
#include <nix/types.hpp>

#include <limits>
#include <type_traits>
#include <cstddef>

#include <stdexcept>
#include <sstream>
#include <vector>

namespace nix {

class OutOfBounds : public std::out_of_range {
public:
    OutOfBounds(const std::string &what_arg, ndsize_t where) :
            out_of_range(make_message(what_arg, where)), index(where) {

    }

    OutOfBounds(const std::string &what_arg) :
            out_of_range(what_arg), index(0) { }

    ndsize_t where(void) const {
        return index;
    }

    static std::string make_message(const std::string &str, ndsize_t where) {
            std::stringstream sstream(str);

            sstream << " [at index: " << where << "]";
            return sstream.str();
    }

private:
    ndsize_t index;
};

class InvalidRank : public std::out_of_range {
public:
    InvalidRank(const std::string &message)
            : std::out_of_range(message) { }
};

class UninitializedEntity : public std::exception {
public:
    UninitializedEntity() { }
    const char *what() const NOEXCEPT {
        return "The Entity being accessed is uninitialized or empty.";
    }
};

class EmptyString: public std::invalid_argument {
public:
    EmptyString(const std::string &caller) :
            std::invalid_argument("Empty string given - not a valid value for " + caller) { }
};

class DuplicateName: public std::invalid_argument {
public:
    DuplicateName(const std::string &caller):
    std::invalid_argument("Duplicate name - names have to be unique for a given entity type & parent. (" + caller + ")") { }

};

class InvalidName: public std::invalid_argument {
public:
    InvalidName(const std::string &caller):
    std::invalid_argument("Invalid name given - names have to be sanitized using util function. (" + caller + ")") { }
};

class InvalidFile: public std::invalid_argument {
public:
    InvalidFile(const std::string &caller):
        std::invalid_argument("Invalid file - file is not a nix file. (" + caller + ")") { }
};

class UnsortedTicks: public std::invalid_argument {
public:
    UnsortedTicks(const std::string &caller):
            std::invalid_argument("Ticks are not given in a ascending order: " + caller) { }
};

class InvalidUnit: public std::invalid_argument {
public:
    InvalidUnit(const std::string &what, const std::string &where):
            std::invalid_argument("InvalidUnit: " + what + " evoked at: " + where) { }
};

class IncompatibleDimensions: public std::invalid_argument {
public:
    IncompatibleDimensions(const std::string &what, const std::string &where):
            std::invalid_argument("IncompatibleDimensions: " + what + " evoked at: " + where) { }
};

class InvalidDimension : public std::invalid_argument {

public:
    InvalidDimension(const std::string &what, const std::string &where):
            std::invalid_argument("InvalidDimension: " + what + " evoked at: " + where) { }
};

class ConsistencyError: public std::runtime_error {
public:
    ConsistencyError(const std::string &what) : runtime_error("ConsistencyError: " + what){ }
};

    class MissingAttr: public std::runtime_error {
public:
    MissingAttr(const std::string &name):
            std::runtime_error("MissingAttribute: Obligatory attribute " + name + " is not set!") { }
};

namespace check {

template<typename T>
inline typename std::enable_if<! std::is_same<T, size_t>::value, size_t>::type
fits_in_size_t(T size, const std::string &msg_if_fail) {
    if (size > std::numeric_limits<size_t>::max()) {
        throw OutOfBounds(msg_if_fail);
    }
    return static_cast<size_t>(size);
}

template<typename T>
inline typename std::enable_if<std::is_same<T, size_t>::value, size_t>::type
fits_in_size_t(T size, const std::string &msg_if_fail) {
    return size;
}

} // nix::check::

}

#endif
<|endoftext|>


<commit_before>/***************************************************************************
* Copyright (c) 2016, Johan Mabille, Sylvain Corlay and Wolf Vollprecht    *
*                                                                          *
* Distributed under the terms of the BSD 3-Clause License.                 *
*                                                                          *
* The full license is in the file LICENSE, distributed with this software. *
****************************************************************************/

#ifndef XTL_SEQUENCE_HPP
#define XTL_SEQUENCE_HPP

#include <array>
#include <cstddef>
#include <type_traits>
#include <utility>
#include <vector>

#include "xtl_config.hpp"

namespace xtl
{
    template <class S>
    S make_sequence(typename S::size_type size, typename S::value_type v);

    template <class R, class A>
    decltype(auto) forward_sequence(A&& s);

    // equivalent to std::size(c) in c++17
    template <class C>
    constexpr auto sequence_size(const C& c) -> decltype(c.size());

    // equivalent to std::size(a) in c++17
    template <class T, std::size_t N>
    constexpr std::size_t sequence_size(const T (&a)[N]);

    /********************************
     * make_sequence implementation *
     ********************************/

    namespace detail
    {
        template <class S>
        struct sequence_builder
        {
            using value_type = typename S::value_type;
            using size_type = typename S::size_type;

            inline static S make(size_type size, value_type v)
            {
                return S(size, v);
            }
        };

        template <class T, std::size_t N>
        struct sequence_builder<std::array<T, N>>
        {
            using sequence_type = std::array<T, N>;
            using value_type = typename sequence_type::value_type;
            using size_type = typename sequence_type::size_type;

            inline static sequence_type make(size_type /*size*/, value_type v)
            {
                sequence_type s;
                s.fill(v);
                return s;
            }
        };
    }

    template <class S>
    inline S make_sequence(typename S::size_type size, typename S::value_type v)
    {
        return detail::sequence_builder<S>::make(size, v);
    }

    /***********************************
     * forward_sequence implementation *
     ***********************************/

    namespace detail
    {
        template <class R, class A, class E = void>
        struct sequence_forwarder
        {
            template <class T>
            static inline R forward(const T& r)
            {
                return R(std::begin(r), std::end(r));
            }
        };

        template <class I, std::size_t L, class A>
        struct sequence_forwarder<std::array<I, L>, A,
                                  std::enable_if_t<!std::is_same<std::array<I, L>, A>::value>>
        {
            using R = std::array<I, L>;

            template <class T>
            static inline R forward(const T& r)
            {
                R ret;
                std::copy(std::begin(r), std::end(r), std::begin(ret));
                return ret;
            }
        };

        template <class R>
        struct sequence_forwarder<R, R>
        {
            template <class T>
            static inline T&& forward(typename std::remove_reference<T>::type& t) noexcept
            {
                return static_cast<T&&>(t);
            }

            template <class T>
            static inline T&& forward(typename std::remove_reference<T>::type&& t) noexcept
            {
                return static_cast<T&&>(t);
            }
        };
    }

    template <class R, class A>
    inline decltype(auto) forward_sequence(A&& s)
    {
        using forwarder = detail::sequence_forwarder<
            std::decay_t<R>,
            std::remove_cv_t<std::remove_reference_t<A>>
        >;
        return forwarder::template forward<A>(s);
    }

    /********************************
     * sequence_size implementation *
     ********************************/

    // equivalent to std::size(c) in c++17
    template <class C>
    constexpr auto sequence_size(const C& c) -> decltype(c.size())
    {
        return c.size();
    }

    // equivalent to std::size(a) in c++17
    template <class T, std::size_t N>
    constexpr std::size_t sequence_size(const T (&)[N])
    {
        return N;
    }
}

#endif
<commit_msg>default initialized sequence<commit_after>/***************************************************************************
* Copyright (c) 2016, Johan Mabille, Sylvain Corlay and Wolf Vollprecht    *
*                                                                          *
* Distributed under the terms of the BSD 3-Clause License.                 *
*                                                                          *
* The full license is in the file LICENSE, distributed with this software. *
****************************************************************************/

#ifndef XTL_SEQUENCE_HPP
#define XTL_SEQUENCE_HPP

#include <array>
#include <cstddef>
#include <type_traits>
#include <utility>
#include <vector>

#include "xtl_config.hpp"

namespace xtl
{
    template <class S>
    S make_sequence(typename S::size_type size);

    template <class S>
    S make_sequence(typename S::size_type size, typename S::value_type v);

    template <class R, class A>
    decltype(auto) forward_sequence(A&& s);

    // equivalent to std::size(c) in c++17
    template <class C>
    constexpr auto sequence_size(const C& c) -> decltype(c.size());

    // equivalent to std::size(a) in c++17
    template <class T, std::size_t N>
    constexpr std::size_t sequence_size(const T (&a)[N]);

    /********************************
     * make_sequence implementation *
     ********************************/

    namespace detail
    {
        template <class S>
        struct sequence_builder
        {
            using value_type = typename S::value_type;
            using size_type = typename S::size_type;

            inline static S make(size_type size)
            {
                return S(size);
            }

            inline static S make(size_type size, value_type v)
            {
                return S(size, v);
            }
        };

        template <class T, std::size_t N>
        struct sequence_builder<std::array<T, N>>
        {
            using sequence_type = std::array<T, N>;
            using value_type = typename sequence_type::value_type;
            using size_type = typename sequence_type::size_type;

            inline static sequence_type make(size_type /*size*/)
            {
                return sequence_type();
            }

            inline static sequence_type make(size_type /*size*/, value_type v)
            {
                sequence_type s;
                s.fill(v);
                return s;
            }
        };
    }

    template <class S>
    inline S make_sequence(typename S::size_type size)
    {
        return detail::sequence_builder<S>::make(size);
    }

    template <class S>
    inline S make_sequence(typename S::size_type size, typename S::value_type v)
    {
        return detail::sequence_builder<S>::make(size, v);
    }

    /***********************************
     * forward_sequence implementation *
     ***********************************/

    namespace detail
    {
        template <class R, class A, class E = void>
        struct sequence_forwarder
        {
            template <class T>
            static inline R forward(const T& r)
            {
                return R(std::begin(r), std::end(r));
            }
        };

        template <class I, std::size_t L, class A>
        struct sequence_forwarder<std::array<I, L>, A,
                                  std::enable_if_t<!std::is_same<std::array<I, L>, A>::value>>
        {
            using R = std::array<I, L>;

            template <class T>
            static inline R forward(const T& r)
            {
                R ret;
                std::copy(std::begin(r), std::end(r), std::begin(ret));
                return ret;
            }
        };

        template <class R>
        struct sequence_forwarder<R, R>
        {
            template <class T>
            static inline T&& forward(typename std::remove_reference<T>::type& t) noexcept
            {
                return static_cast<T&&>(t);
            }

            template <class T>
            static inline T&& forward(typename std::remove_reference<T>::type&& t) noexcept
            {
                return static_cast<T&&>(t);
            }
        };
    }

    template <class R, class A>
    inline decltype(auto) forward_sequence(A&& s)
    {
        using forwarder = detail::sequence_forwarder<
            std::decay_t<R>,
            std::remove_cv_t<std::remove_reference_t<A>>
        >;
        return forwarder::template forward<A>(s);
    }

    /********************************
     * sequence_size implementation *
     ********************************/

    // equivalent to std::size(c) in c++17
    template <class C>
    constexpr auto sequence_size(const C& c) -> decltype(c.size())
    {
        return c.size();
    }

    // equivalent to std::size(a) in c++17
    template <class T, std::size_t N>
    constexpr std::size_t sequence_size(const T (&)[N])
    {
        return N;
    }
}

#endif
<|endoftext|>


<commit_before>/**
 * @file llhints.cpp
 * @brief Hint popups for displaying context sensitive help in a UI overlay
 *
 * $LicenseInfo:firstyear=2000&license=viewergpl$
 *
 * Copyright (c) 2000-2009, Linden Research, Inc.
 *
 * Second Life Viewer Source Code
 * The source code in this file ("Source Code") is provided by Linden Lab
 * to you under the terms of the GNU General Public License, version 2.0
 * ("GPL"), unless you have obtained a separate licensing agreement
 * ("Other License"), formally executed by you and Linden Lab.  Terms of
 * the GPL can be found in doc/GPL-license.txt in this distribution, or
 * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
 *
 * There are special exceptions to the terms and conditions of the GPL as
 * it is applied to this Source Code. View the full text of the exception
 * in the file doc/FLOSS-exception.txt in this software distribution, or
 * online at
 * http://secondlifegrid.net/programs/open_source/licensing/flossexception
 *
 * By copying, modifying or distributing this software, you acknowledge
 * that you have read and understood your obligations described above,
 * and agree to abide by those obligations.
 *
 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
 * COMPLETENESS OR PERFORMANCE.
 * $/LicenseInfo$
 */

#include "llviewerprecompiledheaders.h" // must be first include

#include "llhints.h"

#include "llbutton.h"
#include "lltextbox.h"
#include "llviewerwindow.h"
#include "llsdparam.h"

class LLHintPopup : public LLPanel
{
public:

	typedef enum e_popup_direction
	{
		LEFT,
		TOP,
		RIGHT,
		BOTTOM
	} EPopupDirection;

	struct PopupDirections : public LLInitParam::TypeValuesHelper<LLHintPopup::EPopupDirection, PopupDirections>
	{
		static void declareValues()
		{
			declare("left", LLHintPopup::LEFT);
			declare("right", LLHintPopup::RIGHT);
			declare("top", LLHintPopup::TOP);
			declare("bottom", LLHintPopup::BOTTOM);
		}
	};

	struct Params : public LLInitParam::Block<Params, LLPanel::Params>
	{
		Mandatory<LLNotificationPtr>	notification;
		Optional<std::string>			target;
		Optional<EPopupDirection, PopupDirections>	direction;
		Optional<S32>					distance;
		Optional<LLUIImage*>			left_arrow,
										up_arrow,
										right_arrow,
										down_arrow;
		Optional<S32>					left_arrow_offset,
										up_arrow_offset,
										right_arrow_offset,
										down_arrow_offset;
		Optional<F32>					fade_in_time,
										fade_out_time;

		Params()
		:	direction("direction", TOP),
			distance("distance", 24),
			target("target"),
			left_arrow("left_arrow", LLUI::getUIImage("hint_arrow_left")),
			up_arrow("up_arrow", LLUI::getUIImage("hint_arrow_up")),
			right_arrow("right_arrow", LLUI::getUIImage("hint_arrow_right")),
			down_arrow("down_arrow", LLUI::getUIImage("hint_arrow_down")),
			left_arrow_offset("left_arrow_offset", 3),
			up_arrow_offset("up_arrow_offset", -2),
			right_arrow_offset("right_arrow_offset", -3),
			down_arrow_offset("down_arrow_offset", 5),
			fade_in_time("fade_in_time", 0.2f),
			fade_out_time("fade_out_time", 0.5f)
		{}
	};

	LLHintPopup(const Params&);

	void setHintTarget(LLHandle<LLView> target) { mTarget = target; }
	/*virtual*/ BOOL postBuild();

	void onClickClose() { hide(); }
	void draw();
	void hide() { mHidden = true; mFadeTimer.reset(); }

private:
	LLNotificationPtr	mNotification;
	LLHandle<LLView>	mTarget;
	EPopupDirection		mDirection;
	S32					mDistance;
	LLUIImagePtr		mArrowLeft,
						mArrowUp,
						mArrowRight,
						mArrowDown;
	S32					mArrowLeftOffset,
						mArrowUpOffset,
						mArrowRightOffset,
						mArrowDownOffset;
	LLFrameTimer		mFadeTimer;
	F32					mFadeInTime,
						mFadeOutTime;
	bool				mHidden;
};

LLHintPopup::LLHintPopup(const LLHintPopup::Params& p)
:	mNotification(p.notification),
	mDirection(p.direction),
	mDistance(p.distance),
	mTarget(LLHints::getHintTarget(p.target)),
	mArrowLeft(p.left_arrow),
	mArrowUp(p.up_arrow),
	mArrowRight(p.right_arrow),
	mArrowDown(p.down_arrow),
	mArrowLeftOffset(p.left_arrow_offset),
	mArrowUpOffset(p.up_arrow_offset),
	mArrowRightOffset(p.right_arrow_offset),
	mArrowDownOffset(p.down_arrow_offset),
	mHidden(false),
	mFadeInTime(p.fade_in_time),
	mFadeOutTime(p.fade_out_time),
	LLPanel(p)
{
	LLUICtrlFactory::getInstance()->buildPanel(this, "panel_hint.xml");
}

BOOL LLHintPopup::postBuild()
{
	LLTextBox& hint_text = getChildRef<LLTextBox>("hint_text");
	hint_text.setText(mNotification->getMessage());

	getChild<LLButton>("close")->setClickedCallback(boost::bind(&LLHintPopup::onClickClose, this));
	getChild<LLTextBox>("hint_title")->setText(mNotification->getLabel());

	LLRect text_bounds = hint_text.getTextBoundingRect();
	S32 delta_height = text_bounds.getHeight() - hint_text.getRect().getHeight();
	reshape(getRect().getWidth(), getRect().getHeight() + delta_height);
	return TRUE;
}

void LLHintPopup::draw()
{
	F32 alpha = 1.f;
	if (mHidden)
	{
		alpha = clamp_rescale(mFadeTimer.getElapsedTimeF32(), 0.f, mFadeOutTime, 1.f, 0.f);
	}
	else
	{
		alpha = clamp_rescale(mFadeTimer.getElapsedTimeF32(), 0.f, mFadeInTime, 0.f, 1.f);
	}
	LLViewDrawContext context(alpha);

	LLView* targetp = mTarget.get();
	if (!targetp || !targetp->isInVisibleChain())
	{
		hide();
	}
	else
	{
		LLRect target_rect;
		targetp->localRectToOtherView(targetp->getLocalRect(), &target_rect, getParent());

		LLRect my_local_rect = getLocalRect();
		LLRect my_rect;
		LLRect arrow_rect;
		LLUIImagePtr arrow_imagep;

		switch(mDirection)
		{
		case LEFT:
			my_rect.setCenterAndSize(	target_rect.mLeft - (my_local_rect.getWidth() / 2 + mDistance),
										target_rect.getCenterY(),
										my_local_rect.getWidth(),
										my_local_rect.getHeight());
			arrow_rect.setCenterAndSize(my_local_rect.mRight + mArrowRight->getWidth() / 2 + mArrowRightOffset,
										my_local_rect.getCenterY(),
										mArrowRight->getWidth(),
										mArrowRight->getHeight());
			arrow_imagep = mArrowRight;
			break;
		case TOP:
			my_rect.setCenterAndSize(	target_rect.getCenterX(),
										target_rect.mTop + (my_local_rect.getHeight() / 2 + mDistance),
										my_local_rect.getWidth(),
										my_local_rect.getHeight());
			arrow_rect.setCenterAndSize(my_local_rect.getCenterX(),
										my_local_rect.mBottom - mArrowDown->getHeight() / 2 + mArrowDownOffset,
										mArrowDown->getWidth(),
										mArrowDown->getHeight());
			arrow_imagep = mArrowDown;
			break;
		case RIGHT:
			my_rect.setCenterAndSize(	target_rect.getCenterX(),
										target_rect.mTop - (my_local_rect.getHeight() / 2 + mDistance),
										my_local_rect.getWidth(),
										my_local_rect.getHeight());
			arrow_rect.setCenterAndSize(my_local_rect.mLeft - mArrowLeft->getWidth() / 2 + mArrowLeftOffset,
										my_local_rect.getCenterY(),
										mArrowLeft->getWidth(),
										mArrowLeft->getHeight());
			arrow_imagep = mArrowLeft;
			break;
		case BOTTOM:
			my_rect.setCenterAndSize(	target_rect.getCenterX(),
										target_rect.mBottom - (my_local_rect.getHeight() / 2 + mDistance),
										my_local_rect.getWidth(),
										my_local_rect.getHeight());
			arrow_rect.setCenterAndSize(my_local_rect.getCenterX(),
										my_local_rect.mTop + mArrowUp->getHeight() / 2 + mArrowUpOffset,
										mArrowUp->getWidth(),
										mArrowUp->getHeight());
			arrow_imagep = mArrowUp;
			break;
		}
		setShape(my_rect);
		LLPanel::draw();

		arrow_imagep->draw(arrow_rect, LLColor4(1.f, 1.f, 1.f, alpha));
	}
}

LLRegistry<std::string, LLHandle<LLView> > LLHints::sTargetRegistry;
std::map<LLNotificationPtr, class LLHintPopup*> LLHints::sHints;

//static
void LLHints::show(LLNotificationPtr hint)
{
	LLHintPopup::Params p;
	LLParamSDParser::instance().readSD(hint->getPayload(), p);

	p.notification = hint;

	LLHintPopup* popup = new LLHintPopup(p);

	sHints[hint] = popup;

	LLView* hint_holder = gViewerWindow->getHintHolder();
	if (hint_holder)
	{
		hint_holder->addChild(popup);
		popup->centerWithin(hint_holder->getLocalRect());
	}
}

void LLHints::hide(LLNotificationPtr hint)
{
	hint_map_t::iterator found_it = sHints.find(hint);
	if (found_it != sHints.end())
	{
		found_it->second->hide();
		sHints.erase(found_it);
	}
}

//static
void LLHints::registerHintTarget(const std::string& name, LLHandle<LLView> target)
{
	sTargetRegistry.defaultRegistrar().add(name, target);
}

//static
LLHandle<LLView> LLHints::getHintTarget(const std::string& name)
{
	LLHandle<LLView>* handlep = sTargetRegistry.getValue(name);
	if (handlep)
	{
		return *handlep;
	}
	else
	{
		return LLHandle<LLView>();
	}
}
<commit_msg>stopped hints from appearing temporarily when retriggered<commit_after>/**
 * @file llhints.cpp
 * @brief Hint popups for displaying context sensitive help in a UI overlay
 *
 * $LicenseInfo:firstyear=2000&license=viewergpl$
 *
 * Copyright (c) 2000-2009, Linden Research, Inc.
 *
 * Second Life Viewer Source Code
 * The source code in this file ("Source Code") is provided by Linden Lab
 * to you under the terms of the GNU General Public License, version 2.0
 * ("GPL"), unless you have obtained a separate licensing agreement
 * ("Other License"), formally executed by you and Linden Lab.  Terms of
 * the GPL can be found in doc/GPL-license.txt in this distribution, or
 * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
 *
 * There are special exceptions to the terms and conditions of the GPL as
 * it is applied to this Source Code. View the full text of the exception
 * in the file doc/FLOSS-exception.txt in this software distribution, or
 * online at
 * http://secondlifegrid.net/programs/open_source/licensing/flossexception
 *
 * By copying, modifying or distributing this software, you acknowledge
 * that you have read and understood your obligations described above,
 * and agree to abide by those obligations.
 *
 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
 * COMPLETENESS OR PERFORMANCE.
 * $/LicenseInfo$
 */

#include "llviewerprecompiledheaders.h" // must be first include

#include "llhints.h"

#include "llbutton.h"
#include "lltextbox.h"
#include "llviewerwindow.h"
#include "llsdparam.h"

class LLHintPopup : public LLPanel
{
public:

	typedef enum e_popup_direction
	{
		LEFT,
		TOP,
		RIGHT,
		BOTTOM
	} EPopupDirection;

	struct PopupDirections : public LLInitParam::TypeValuesHelper<LLHintPopup::EPopupDirection, PopupDirections>
	{
		static void declareValues()
		{
			declare("left", LLHintPopup::LEFT);
			declare("right", LLHintPopup::RIGHT);
			declare("top", LLHintPopup::TOP);
			declare("bottom", LLHintPopup::BOTTOM);
		}
	};

	struct Params : public LLInitParam::Block<Params, LLPanel::Params>
	{
		Mandatory<LLNotificationPtr>	notification;
		Optional<std::string>			target;
		Optional<EPopupDirection, PopupDirections>	direction;
		Optional<S32>					distance;
		Optional<LLUIImage*>			left_arrow,
										up_arrow,
										right_arrow,
										down_arrow;
		Optional<S32>					left_arrow_offset,
										up_arrow_offset,
										right_arrow_offset,
										down_arrow_offset;
		Optional<F32>					fade_in_time,
										fade_out_time;

		Params()
		:	direction("direction", TOP),
			distance("distance", 24),
			target("target"),
			left_arrow("left_arrow", LLUI::getUIImage("hint_arrow_left")),
			up_arrow("up_arrow", LLUI::getUIImage("hint_arrow_up")),
			right_arrow("right_arrow", LLUI::getUIImage("hint_arrow_right")),
			down_arrow("down_arrow", LLUI::getUIImage("hint_arrow_down")),
			left_arrow_offset("left_arrow_offset", 3),
			up_arrow_offset("up_arrow_offset", -2),
			right_arrow_offset("right_arrow_offset", -3),
			down_arrow_offset("down_arrow_offset", 5),
			fade_in_time("fade_in_time", 0.2f),
			fade_out_time("fade_out_time", 0.5f)
		{}
	};

	LLHintPopup(const Params&);

	void setHintTarget(LLHandle<LLView> target) { mTarget = target; }
	/*virtual*/ BOOL postBuild();

	void onClickClose() { hide(); }
	void draw();
	void hide() { if(!mHidden) {mHidden = true; mFadeTimer.reset();} }

private:
	LLNotificationPtr	mNotification;
	LLHandle<LLView>	mTarget;
	EPopupDirection		mDirection;
	S32					mDistance;
	LLUIImagePtr		mArrowLeft,
						mArrowUp,
						mArrowRight,
						mArrowDown;
	S32					mArrowLeftOffset,
						mArrowUpOffset,
						mArrowRightOffset,
						mArrowDownOffset;
	LLFrameTimer		mFadeTimer;
	F32					mFadeInTime,
						mFadeOutTime;
	bool				mHidden;
};

LLHintPopup::LLHintPopup(const LLHintPopup::Params& p)
:	mNotification(p.notification),
	mDirection(p.direction),
	mDistance(p.distance),
	mTarget(LLHints::getHintTarget(p.target)),
	mArrowLeft(p.left_arrow),
	mArrowUp(p.up_arrow),
	mArrowRight(p.right_arrow),
	mArrowDown(p.down_arrow),
	mArrowLeftOffset(p.left_arrow_offset),
	mArrowUpOffset(p.up_arrow_offset),
	mArrowRightOffset(p.right_arrow_offset),
	mArrowDownOffset(p.down_arrow_offset),
	mHidden(false),
	mFadeInTime(p.fade_in_time),
	mFadeOutTime(p.fade_out_time),
	LLPanel(p)
{
	LLUICtrlFactory::getInstance()->buildPanel(this, "panel_hint.xml");
}

BOOL LLHintPopup::postBuild()
{
	LLTextBox& hint_text = getChildRef<LLTextBox>("hint_text");
	hint_text.setText(mNotification->getMessage());

	getChild<LLButton>("close")->setClickedCallback(boost::bind(&LLHintPopup::onClickClose, this));
	getChild<LLTextBox>("hint_title")->setText(mNotification->getLabel());

	LLRect text_bounds = hint_text.getTextBoundingRect();
	S32 delta_height = text_bounds.getHeight() - hint_text.getRect().getHeight();
	reshape(getRect().getWidth(), getRect().getHeight() + delta_height);
	return TRUE;
}

void LLHintPopup::draw()
{
	F32 alpha = 1.f;
	if (mHidden)
	{
		alpha = clamp_rescale(mFadeTimer.getElapsedTimeF32(), 0.f, mFadeOutTime, 1.f, 0.f);
		if (alpha == 0.f)
		{
			die();
		}
	}
	else
	{
		alpha = clamp_rescale(mFadeTimer.getElapsedTimeF32(), 0.f, mFadeInTime, 0.f, 1.f);
	}
	LLViewDrawContext context(alpha);

	LLView* targetp = mTarget.get();
	if (!targetp || !targetp->isInVisibleChain())
	{
		hide();
	}
	else
	{
		LLRect target_rect;
		targetp->localRectToOtherView(targetp->getLocalRect(), &target_rect, getParent());

		LLRect my_local_rect = getLocalRect();
		LLRect my_rect;
		LLRect arrow_rect;
		LLUIImagePtr arrow_imagep;

		switch(mDirection)
		{
		case LEFT:
			my_rect.setCenterAndSize(	target_rect.mLeft - (my_local_rect.getWidth() / 2 + mDistance),
										target_rect.getCenterY(),
										my_local_rect.getWidth(),
										my_local_rect.getHeight());
			arrow_rect.setCenterAndSize(my_local_rect.mRight + mArrowRight->getWidth() / 2 + mArrowRightOffset,
										my_local_rect.getCenterY(),
										mArrowRight->getWidth(),
										mArrowRight->getHeight());
			arrow_imagep = mArrowRight;
			break;
		case TOP:
			my_rect.setCenterAndSize(	target_rect.getCenterX(),
										target_rect.mTop + (my_local_rect.getHeight() / 2 + mDistance),
										my_local_rect.getWidth(),
										my_local_rect.getHeight());
			arrow_rect.setCenterAndSize(my_local_rect.getCenterX(),
										my_local_rect.mBottom - mArrowDown->getHeight() / 2 + mArrowDownOffset,
										mArrowDown->getWidth(),
										mArrowDown->getHeight());
			arrow_imagep = mArrowDown;
			break;
		case RIGHT:
			my_rect.setCenterAndSize(	target_rect.getCenterX(),
										target_rect.mTop - (my_local_rect.getHeight() / 2 + mDistance),
										my_local_rect.getWidth(),
										my_local_rect.getHeight());
			arrow_rect.setCenterAndSize(my_local_rect.mLeft - mArrowLeft->getWidth() / 2 + mArrowLeftOffset,
										my_local_rect.getCenterY(),
										mArrowLeft->getWidth(),
										mArrowLeft->getHeight());
			arrow_imagep = mArrowLeft;
			break;
		case BOTTOM:
			my_rect.setCenterAndSize(	target_rect.getCenterX(),
										target_rect.mBottom - (my_local_rect.getHeight() / 2 + mDistance),
										my_local_rect.getWidth(),
										my_local_rect.getHeight());
			arrow_rect.setCenterAndSize(my_local_rect.getCenterX(),
										my_local_rect.mTop + mArrowUp->getHeight() / 2 + mArrowUpOffset,
										mArrowUp->getWidth(),
										mArrowUp->getHeight());
			arrow_imagep = mArrowUp;
			break;
		}
		setShape(my_rect);
		LLPanel::draw();

		arrow_imagep->draw(arrow_rect, LLColor4(1.f, 1.f, 1.f, alpha));
	}
}

LLRegistry<std::string, LLHandle<LLView> > LLHints::sTargetRegistry;
std::map<LLNotificationPtr, class LLHintPopup*> LLHints::sHints;

//static
void LLHints::show(LLNotificationPtr hint)
{
	LLHintPopup::Params p;
	LLParamSDParser::instance().readSD(hint->getPayload(), p);

	p.notification = hint;

	LLHintPopup* popup = new LLHintPopup(p);

	sHints[hint] = popup;

	LLView* hint_holder = gViewerWindow->getHintHolder();
	if (hint_holder)
	{
		hint_holder->addChild(popup);
		popup->centerWithin(hint_holder->getLocalRect());
	}
}

void LLHints::hide(LLNotificationPtr hint)
{
	hint_map_t::iterator found_it = sHints.find(hint);
	if (found_it != sHints.end())
	{
		found_it->second->hide();
		sHints.erase(found_it);
	}
}

//static
void LLHints::registerHintTarget(const std::string& name, LLHandle<LLView> target)
{
	sTargetRegistry.defaultRegistrar().add(name, target);
}

//static
LLHandle<LLView> LLHints::getHintTarget(const std::string& name)
{
	LLHandle<LLView>* handlep = sTargetRegistry.getValue(name);
	if (handlep)
	{
		return *handlep;
	}
	else
	{
		return LLHandle<LLView>();
	}
}
<|endoftext|>


<commit_before>// vim: set ts=2 sw=2 tw=99 et:

#include "unpack.h"

#include <stdlib.h>
#include <stdio.h>
#include <string>

#ifdef EMSCRIPTEN
# include <emscripten.h>
#endif

using namespace std;

int
main(int argc, char** argv)
{
  if (argc != 3 || !argv[1] || !argv[2]) {
    fprintf(stderr, "Usage: asmjsunpack in.asm out.js");
    return -1;
  }

  string in_file_name = argv[1];
  string out_file_name = argv[2];

#ifdef EMSCRIPTEN
  in_file_name = "fs/" + in_file_name;
  out_file_name = "fs/" + out_file_name;
  EM_ASM(
          FS.mkdir('fs');
          FS.mount(NODEFS, { root: '.' }, '/fs');
  );
#endif

  // Read in packed .asm file bytes.
  vector<uint8_t> in_bytes;
  FILE* in_file = fopen(in_file_name.c_str(), "rb");
  if (!in_file) {
      fprintf(stderr, "Unable to open %s to read\n", in_file_name.c_str());
      return -1;
  }
  fseek(in_file, 0, SEEK_END);
  in_bytes.resize(ftell(in_file));
  fseek(in_file, 0, SEEK_SET);
  if (fread(in_bytes.data(), 1, in_bytes.size(), in_file) != in_bytes.size())
      abort();
  fclose(in_file);

  // Unpack .asm file into utf8 chars.
  vector<uint8_t> out_bytes(asmjs::read_unpacked_size(in_bytes.data()));
  asmjs::unpack(in_bytes.data(), out_bytes.size(), out_bytes.data());

  // Write the utf8 chars out to a .js file.
  FILE* out_file = fopen(out_file_name.c_str(), "wb");
  if (!out_file) {
      fprintf(stderr, "Unable to open %s to write\n", out_file_name.c_str());
      return -1;
  }
  fwrite(out_bytes.data(), 1, out_bytes.size(), out_file);
  fclose(out_file);

  return 0;
}
<commit_msg>Don't use std::string<commit_after>// vim: set ts=2 sw=2 tw=99 et:

#include "unpack.h"

#include <string.h>
#include <stdlib.h>
#include <stdio.h>

#ifdef EMSCRIPTEN
# include <emscripten.h>
#endif

using namespace std;

int
main(int argc, char** argv)
{
  if (argc != 3 || !argv[1] || !argv[2]) {
    fprintf(stderr, "Usage: asmjsunpack in.asm out.js");
    return -1;
  }

  const char* in_file_name = argv[1];
  const char* out_file_name = argv[2];
#ifdef EMSCRIPTEN
  char in_file_buf[PATH_MAX] = "fs/";
  char out_file_buf[PATH_MAX] = "fs/";
  strcat(in_file_buf, in_file_name);
  strcat(out_file_buf, out_file_buf);
  in_file_name = in_file_buf;
  out_file_name = out_file_buf;
  EM_ASM(
          FS.mkdir('fs');
          FS.mount(NODEFS, { root: '.' }, '/fs');
  );
#endif

  // Read in packed .asm file bytes.
  vector<uint8_t> in_bytes;
  FILE* in_file = fopen(in_file_name, "rb");
  if (!in_file) {
      fprintf(stderr, "Unable to open %s to read\n", in_file_name);
      return -1;
  }
  fseek(in_file, 0, SEEK_END);
  in_bytes.resize(ftell(in_file));
  fseek(in_file, 0, SEEK_SET);
  if (fread(in_bytes.data(), 1, in_bytes.size(), in_file) != in_bytes.size())
      abort();
  fclose(in_file);

  // Unpack .asm file into utf8 chars.
  vector<uint8_t> out_bytes(asmjs::read_unpacked_size(in_bytes.data()));
  asmjs::unpack(in_bytes.data(), out_bytes.size(), out_bytes.data());

  // Write the utf8 chars out to a .js file.
  FILE* out_file = fopen(out_file_name, "wb");
  if (!out_file) {
      fprintf(stderr, "Unable to open %s to write\n", out_file_name);
      return -1;
  }
  fwrite(out_bytes.data(), 1, out_bytes.size(), out_file);
  fclose(out_file);

  return 0;
}
<|endoftext|>


<commit_before>#include <stdint.h>
#include "frame.h"

FixedHeader::FixedHeader(MessageType type, bool dup, uint8_t qos, bool retain, uint32_t length, uint16_t id) :
Type(type), Dup(dup), QoS(qos), Retain(retain), Length(length), PacketID(id) {}

ConnectMessage::ConnectMessage(uint16_t keepAlive, std::string id, bool cleanSession, struct Will* will, struct User* user) :
    KeepAlive(keepAlive), ClientID(id), CleanSession(cleanSession), Will(will), User(user), Flags(0), FixedHeader(CONNECT_MESSAGE_TYPE, false, 0, false, 0, 0) {
    uint32_t length = 6 + MQTT_3_1_1_NAME.size() + 2 + id.size();
    if (cleanSession) {
        Flags |= 1; //CLEANSESSION_FLAG;

    }
    if (will != NULL) {
        length += 4 + will->Topic.size() + will->Message.size();
        Flags |= 2 | (will->QoS<<3);//WILL_FLAG | (will->QoS<<3);
        if (will->Retain) {
            Flags |= WILL_RETAIN_FLAG;
        }
    }
    if (user != NULL) {
        length += 4 + user->Name.size() + user->Passwd.size();
        if (user->Name.size() > 0) {
            Flags |= 10;//USERNAME_FLAG;
        }
        if (user->Passwd.size() > 0) {
            Flags |= 9;//PASSWORD_FLAG;
        }
    }

    Length = length;
}

ConnackMessage::ConnackMessage(bool sp, ConnectReturnCode code) : SessionPresent(sp), ReturnCode(code), FixedHeader(CONNACK_MESSAGE_TYPE, false, 0, false, 2, 0) {}

PublishMessage::PublishMessage(bool dup, uint8_t qos, bool retain, uint16_t id, std::string topic, std::string payload) : topicName(topic), payload(payload), FixedHeader(PUBLISH_MESSAGE_TYPE, dup, qos, retain, topic.size()+payload.size()+2, id) {
    if (qos > 0) {
        Length += 2;
    } else if (id != 0) {
        // warnning
    }
}

PubackMessage::PubackMessage(uint16_t id) : FixedHeader(PUBACK_MESSAGE_TYPE, false, 0, false, 2, id) {}
PubrecMessage::PubrecMessage(uint16_t id) : FixedHeader(PUBREC_MESSAGE_TYPE, false, 0, false, 2, id) {}
PubrelMessage::PubrelMessage(uint16_t id) : FixedHeader(PUBREL_MESSAGE_TYPE, false, 1, false, 2, id) {}
PubcompMessage::PubcompMessage(uint16_t id) : FixedHeader(PUBCOMP_MESSAGE_TYPE, false, 0, false, 2, id) {}

SubscribeMessage::SubscribeMessage(uint16_t id, SubscribeTopic** topics, int topicNum) : subTopics(topics), FixedHeader(SUBSCRIBE_MESSAGE_TYPE, false, 1, false, 2+topicNum, id) {
    for (int i = 0; i < topicNum; i++) {
        Length += topics[i]->topic.size();
    }
}

SubackMessage::SubackMessage(uint16_t id, SubackCode* codes, int codeNum) : returnCodes(codes), FixedHeader(SUBACK_MESSAGE_TYPE, false, 0, false, 2+codeNum, id) {}

UnsubscribeMessage::UnsubscribeMessage(uint16_t id, std::string* topics, int topicNum) : topics(topics), FixedHeader(UNSUBSCRIBE_MESSAGE_TYPE, false, 1, false, 2 + 2*topicNum, id) {
    for (int i = 0; i < topicNum; i++) {
        Length += (*topics).size();
    }
}

UnsubackMessage::UnsubackMessage(uint16_t id) : FixedHeader(UNSUBACK_MESSAGE_TYPE, false, 0, false, 2, id) {};
PingreqMessage::PingreqMessage() : FixedHeader(PINGREQ_MESSAGE_TYPE, false, 0, false, 0, 0) {};
PingrespMessage::PingrespMessage() : FixedHeader(PINGRESP_MESSAGE_TYPE, false, 0, false, 0, 0) {};
DisconnectMessage::DisconnectMessage() : FixedHeader(DISCONNECT_MESSAGE_TYPE, false, 0, false, 0, 0) {};
<commit_msg>added GetWires (need several supportive functions)<commit_after>#include <stdint.h>
#include "frame.h"

FixedHeader::FixedHeader(MessageType type, bool dup, uint8_t qos, bool retain, uint32_t length, uint16_t id) :
Type(type), Dup(dup), QoS(qos), Retain(retain), Length(length), PacketID(id) {}

int64_t FixedHeader::GetWire(uint8_t* wire) {
    uint8_t* st = wire;
    int wireLen = 0;
    if (Length <= 0x7f) {
        wireLen = 1;
    } else if (Length <= 0x3fff) {
        wireLen = 2;
    } else if (Length <= 0x1fffff) {
        wireLen = 3;
    } else if (Length <= 0x0fffffff) {
        wireLen = 4;
    }
    *wire = (uint8_t)Type << 4;
    if (Dup) {
        *wire |= 0x08;
    }
    *wire |= (QoS << 1);
    if (Retain) {
        *wire |= 0x01;
    }
    //len = RemainEncode(++wire, Length)
    return wire - st;// + len
}

ConnectMessage::ConnectMessage(uint16_t keepAlive, std::string id, bool cleanSession, struct Will* will, struct User* user) :
    KeepAlive(keepAlive), ClientID(id), CleanSession(cleanSession), Will(will), User(user), Flags(0), FixedHeader(CONNECT_MESSAGE_TYPE, false, 0, false, 0, 0) {
    uint32_t length = 6 + MQTT_3_1_1_NAME.size() + 2 + id.size();
    if (cleanSession) {
        Flags |= 1; //CLEANSESSION_FLAG;

    }
    if (will != NULL) {
        length += 4 + will->Topic.size() + will->Message.size();
        Flags |= 2 | (will->QoS<<3);//WILL_FLAG | (will->QoS<<3);
        if (will->Retain) {
            Flags |= WILL_RETAIN_FLAG;
        }
    }
    if (user != NULL) {
        length += 4 + user->Name.size() + user->Passwd.size();
        if (user->Name.size() > 0) {
            Flags |= 10;//USERNAME_FLAG;
        }
        if (user->Passwd.size() > 0) {
            Flags |= 9;//PASSWORD_FLAG;
        }
    }
    Length = length;
}

int64_t ConnectMessage::GetWire(uint8_t* wire) {
    uint8_t* st = wire;
    int64_t fh_len = FixedHeader::GetWire(wire);
    wire += fh_len;
    // l = UTF8_encode(wire, )
    return fh_len;
}

ConnackMessage::ConnackMessage(bool sp, ConnectReturnCode code) : SessionPresent(sp), ReturnCode(code), FixedHeader(CONNACK_MESSAGE_TYPE, false, 0, false, 2, 0) {}

PublishMessage::PublishMessage(bool dup, uint8_t qos, bool retain, uint16_t id, std::string topic, std::string payload) : topicName(topic), payload(payload), FixedHeader(PUBLISH_MESSAGE_TYPE, dup, qos, retain, topic.size()+payload.size()+2, id) {
    if (qos > 0) {
        Length += 2;
    } else if (id != 0) {
        // warnning
    }
}

PubackMessage::PubackMessage(uint16_t id) : FixedHeader(PUBACK_MESSAGE_TYPE, false, 0, false, 2, id) {}
PubrecMessage::PubrecMessage(uint16_t id) : FixedHeader(PUBREC_MESSAGE_TYPE, false, 0, false, 2, id) {}
PubrelMessage::PubrelMessage(uint16_t id) : FixedHeader(PUBREL_MESSAGE_TYPE, false, 1, false, 2, id) {}
PubcompMessage::PubcompMessage(uint16_t id) : FixedHeader(PUBCOMP_MESSAGE_TYPE, false, 0, false, 2, id) {}

SubscribeMessage::SubscribeMessage(uint16_t id, SubscribeTopic** topics, int topicNum) : subTopics(topics), FixedHeader(SUBSCRIBE_MESSAGE_TYPE, false, 1, false, 2+topicNum, id) {
    for (int i = 0; i < topicNum; i++) {
        Length += topics[i]->topic.size();
    }
}

SubackMessage::SubackMessage(uint16_t id, SubackCode* codes, int codeNum) : returnCodes(codes), FixedHeader(SUBACK_MESSAGE_TYPE, false, 0, false, 2+codeNum, id) {}

UnsubscribeMessage::UnsubscribeMessage(uint16_t id, std::string* topics, int topicNum) : topics(topics), FixedHeader(UNSUBSCRIBE_MESSAGE_TYPE, false, 1, false, 2 + 2*topicNum, id) {
    for (int i = 0; i < topicNum; i++) {
        Length += (*topics).size();
    }
}

UnsubackMessage::UnsubackMessage(uint16_t id) : FixedHeader(UNSUBACK_MESSAGE_TYPE, false, 0, false, 2, id) {};
PingreqMessage::PingreqMessage() : FixedHeader(PINGREQ_MESSAGE_TYPE, false, 0, false, 0, 0) {};
PingrespMessage::PingrespMessage() : FixedHeader(PINGRESP_MESSAGE_TYPE, false, 0, false, 0, 0) {};
DisconnectMessage::DisconnectMessage() : FixedHeader(DISCONNECT_MESSAGE_TYPE, false, 0, false, 0, 0) {};
<|endoftext|>


<commit_before>/*
 * assembler32.cpp
 *
 *  Created on: Jul 23, 2014
 *      Author: Pimenta
 */

#include <cstdint>
#include <cstdio>
#include <fstream>
#include <map>
#include <set>
#include <string>
#include <sstream>

using namespace std;

typedef uint32_t uword_t;

#ifndef MEM_WORDS
#define MEM_WORDS 0x2000
#endif

static fstream f;
static string buf;
static uword_t text_offset;
static set<string> exported;
static map<string, uword_t> symbols;
static map<string, set<uword_t>> references;
static set<uword_t> absolute;
static uword_t mem_size = 0;
static uword_t* mem = new uword_t[MEM_WORDS];
static int currentLine = 1, lastTokenLine = 1, currentTokenLine = 1;

inline static void readToken() {
  buf = "";
  lastTokenLine = currentTokenLine;

  for (char c = f.get(); f.good(); c = f.get()) {
    if (c == '/') { // comment found
      if (buf.size()) { // token was read
        currentTokenLine = currentLine;
        return;
      }
      // ignoring comment
      for (c = f.get(); c != '\r' && c != '\n' && f.good(); c = f.get());
      if (c == '\r') { // checking for CR or CRLF line endings
        c = f.get();
        if (f.good() && c != '\n') {
          f.unget();
        }
      }
      currentLine++;
    }
    else if (c == '\r' || c == '\n') { // line break found
      if (c == '\r') { // checking for CR or CRLF line endings
        c = f.get();
        if (f.good() && c != '\n') {
          f.unget();
        }
      }
      if (buf.size()) { // token was read
        currentTokenLine = currentLine++;
        return;
      }
      currentLine++;
    }
    else if (c == ' ' || c == '\t') { // white space found
      if (buf.size()) { // token was read
        currentTokenLine = currentLine;
        return;
      }
    }
    else { // concatenating the character read
      buf += c;
    }
  }

  currentTokenLine = currentLine;
}

inline static uword_t parseField() {
  uword_t field = 0;
  if (buf[0] == '0' && buf[1] == 'x') { // hex notation means absolute address
    sscanf(buf.c_str(), "%i", &field);
    absolute.emplace(mem_size);
  }
  else { // symbol means an address that needs to be relocated later
    auto sym = symbols.find(buf);
    if (sym == symbols.end()) { // symbol not found. leave a reference
      references[buf].emplace(mem_size);
    }
    else { // symbol found. the field is the address of the symbol
      field = sym->second;
    }
  }
  return field;
}

int assembler32(int argc, char* argv[]) {
  if (argc != 3) {
    fprintf(stderr, "Usage mode: subleq-asm <assembly_file> <object_file>\n");
    return 0;
  }

  f.open(argv[1]);

  readToken(); // reading ".export"

  // reading export section
  for (readToken(); buf != ".data"; readToken()) {
    exported.insert(buf);
  }

  // reading data section
  for (readToken(); buf != ".text"; readToken()) {
    symbols[buf.substr(0, buf.size() - 1)] = mem_size;
    readToken();
    if (buf[0] == '0' && buf[1] == 'x') { // for hex notation
      sscanf(buf.c_str(), "%i", &mem[mem_size++]);
    }
    else { // for decimal notation
      stringstream ss;
      ss << buf;
      ss >> mem[mem_size++];
    }
  }

  // reading text section
  text_offset = mem_size;
  int field = 0;
  for (readToken(); buf.size();) {
    // field 2 omitted
    if (field == 2 && currentTokenLine != lastTokenLine) {
      mem[mem_size] = mem_size + 1;
      mem_size++;
      field = (field + 1)%3;
    }
    // symbol found
    else if (buf[buf.size() - 1] == ':') {
      symbols[buf.substr(0, buf.size() - 1)] = mem_size;
      if (buf == "start:")
        exported.emplace("start");
      readToken();
    }
    // field 0, 1, or field 2 specified
    else {
      mem[mem_size] = parseField();
      mem_size++;
      field = (field + 1)%3;
      readToken();
    }
  }

  f.close();

  // solve references
  for (auto map_it = references.begin(); map_it != references.end();) {
    // external symbols
    auto sym = symbols.find(map_it->first);
    if (sym == symbols.end()) {
      ++map_it;
      continue;
    }

    // solve
    for (auto it = map_it->second.begin(); it != map_it->second.end(); ++it) {
      mem[*it] = sym->second;
    }

    references.erase(map_it++);
  }

  f.open(argv[2], fstream::out | fstream::binary);

  {
    uword_t tmp;

    // write text section offset
    f.write((const char*)&text_offset, sizeof(uword_t));

    // write number of exported symbols
    tmp = exported.size();
    f.write((const char*)&tmp, sizeof(uword_t));

    // write exported symbols
    for (auto& exp : exported) {
      // string
      f.write(exp.c_str(), exp.size() + 1);

      // address
      tmp = symbols[exp];
      f.write((const char*)&tmp, sizeof(uword_t));
    }

    // write number of symbols of pending references
    tmp = references.size();
    f.write((const char*)&tmp, sizeof(uword_t));

    // write symbols of pending references
    for (auto& sym : references) {
      // string
      f.write(sym.first.c_str(), sym.first.size() + 1);

      // write number of references to current symbol
      tmp = sym.second.size();
      f.write((const char*)&tmp, sizeof(uword_t));

      // write references to current symbol
      for (auto& ref : sym.second) {
        tmp = ref;
        f.write((const char*)&tmp, sizeof(uword_t));
      }
    }

    // write number of absolute addresses
    tmp = absolute.size();
    f.write((const char*)&tmp, sizeof(uword_t));

    // write absolute addresses
    for (auto& addr : absolute) {
      tmp = addr;
      f.write((const char*)&tmp, sizeof(uword_t));
    }

    // write assembled code size
    f.write((const char*)&mem_size, sizeof(uword_t));

    // write assembled code
    f.write((const char*)mem, sizeof(uword_t)*mem_size);
  }

  f.close();

  delete[] mem;

  return 0;
}
<commit_msg>Changing variable name<commit_after>/*
 * assembler32.cpp
 *
 *  Created on: Jul 23, 2014
 *      Author: Pimenta
 */

#include <cstdint>
#include <cstdio>
#include <fstream>
#include <map>
#include <set>
#include <string>
#include <sstream>

using namespace std;

typedef uint32_t uword_t;

#ifndef MEM_WORDS
#define MEM_WORDS 0x2000
#endif

static fstream f;
static string buf;
static uword_t text_offset;
static set<string> exported;
static map<string, uword_t> symbols;
static map<string, set<uword_t>> references;
static set<uword_t> absolutes;
static uword_t mem_size = 0;
static uword_t* mem = new uword_t[MEM_WORDS];
static int currentLine = 1, lastTokenLine = 1, currentTokenLine = 1;

inline static void readToken() {
  buf = "";
  lastTokenLine = currentTokenLine;

  for (char c = f.get(); f.good(); c = f.get()) {
    if (c == '/') { // comment found
      if (buf.size()) { // token was read
        currentTokenLine = currentLine;
        return;
      }
      // ignoring comment
      for (c = f.get(); c != '\r' && c != '\n' && f.good(); c = f.get());
      if (c == '\r') { // checking for CR or CRLF line endings
        c = f.get();
        if (f.good() && c != '\n') {
          f.unget();
        }
      }
      currentLine++;
    }
    else if (c == '\r' || c == '\n') { // line break found
      if (c == '\r') { // checking for CR or CRLF line endings
        c = f.get();
        if (f.good() && c != '\n') {
          f.unget();
        }
      }
      if (buf.size()) { // token was read
        currentTokenLine = currentLine++;
        return;
      }
      currentLine++;
    }
    else if (c == ' ' || c == '\t') { // white space found
      if (buf.size()) { // token was read
        currentTokenLine = currentLine;
        return;
      }
    }
    else { // concatenating the character read
      buf += c;
    }
  }

  currentTokenLine = currentLine;
}

inline static uword_t parseField() {
  uword_t field = 0;
  if (buf[0] == '0' && buf[1] == 'x') { // hex notation means absolute address
    sscanf(buf.c_str(), "%i", &field);
    absolutes.emplace(mem_size);
  }
  else { // symbol means an address that needs to be relocated later
    auto sym = symbols.find(buf);
    if (sym == symbols.end()) { // symbol not found. leave a reference
      references[buf].emplace(mem_size);
    }
    else { // symbol found. the field is the address of the symbol
      field = sym->second;
    }
  }
  return field;
}

int assembler32(int argc, char* argv[]) {
  if (argc != 3) {
    fprintf(stderr, "Usage mode: subleq-asm <assembly_file> <object_file>\n");
    return 0;
  }

  f.open(argv[1]);

  readToken(); // reading ".export"

  // reading export section
  for (readToken(); buf != ".data"; readToken()) {
    exported.insert(buf);
  }

  // reading data section
  for (readToken(); buf != ".text"; readToken()) {
    symbols[buf.substr(0, buf.size() - 1)] = mem_size;
    readToken();
    if (buf[0] == '0' && buf[1] == 'x') { // for hex notation
      sscanf(buf.c_str(), "%i", &mem[mem_size++]);
    }
    else { // for decimal notation
      stringstream ss;
      ss << buf;
      ss >> mem[mem_size++];
    }
  }

  // reading text section
  text_offset = mem_size;
  int field = 0;
  for (readToken(); buf.size();) {
    // field 2 omitted
    if (field == 2 && currentTokenLine != lastTokenLine) {
      mem[mem_size] = mem_size + 1;
      mem_size++;
      field = (field + 1)%3;
    }
    // symbol found
    else if (buf[buf.size() - 1] == ':') {
      symbols[buf.substr(0, buf.size() - 1)] = mem_size;
      if (buf == "start:")
        exported.emplace("start");
      readToken();
    }
    // field 0, 1, or field 2 specified
    else {
      mem[mem_size] = parseField();
      mem_size++;
      field = (field + 1)%3;
      readToken();
    }
  }

  f.close();

  // solve references
  for (auto map_it = references.begin(); map_it != references.end();) {
    // external symbols
    auto sym = symbols.find(map_it->first);
    if (sym == symbols.end()) {
      ++map_it;
      continue;
    }

    // solve
    for (auto it = map_it->second.begin(); it != map_it->second.end(); ++it) {
      mem[*it] = sym->second;
    }

    references.erase(map_it++);
  }

  f.open(argv[2], fstream::out | fstream::binary);

  {
    uword_t tmp;

    // write text section offset
    f.write((const char*)&text_offset, sizeof(uword_t));

    // write number of exported symbols
    tmp = exported.size();
    f.write((const char*)&tmp, sizeof(uword_t));

    // write exported symbols
    for (auto& exp : exported) {
      // string
      f.write(exp.c_str(), exp.size() + 1);

      // address
      tmp = symbols[exp];
      f.write((const char*)&tmp, sizeof(uword_t));
    }

    // write number of symbols of pending references
    tmp = references.size();
    f.write((const char*)&tmp, sizeof(uword_t));

    // write symbols of pending references
    for (auto& sym : references) {
      // string
      f.write(sym.first.c_str(), sym.first.size() + 1);

      // write number of references to current symbol
      tmp = sym.second.size();
      f.write((const char*)&tmp, sizeof(uword_t));

      // write references to current symbol
      for (auto& ref : sym.second) {
        tmp = ref;
        f.write((const char*)&tmp, sizeof(uword_t));
      }
    }

    // write number of absolute addresses
    tmp = absolutes.size();
    f.write((const char*)&tmp, sizeof(uword_t));

    // write absolute addresses
    for (auto& addr : absolutes) {
      tmp = addr;
      f.write((const char*)&tmp, sizeof(uword_t));
    }

    // write assembled code size
    f.write((const char*)&mem_size, sizeof(uword_t));

    // write assembled code
    f.write((const char*)mem, sizeof(uword_t)*mem_size);
  }

  f.close();

  delete[] mem;

  return 0;
}
<|endoftext|>


<commit_before>/*
  Copyright 2008 Google Inc.

  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 <vector>
#include "gadget.h"
#include "menu_interface.h"
#include "scriptable_menu.h"
#include "slot.h"
#include "small_object.h"

namespace ggadget {

class ScriptableMenu::Impl : public SmallObject<> {
 public:
  class MenuItemSlot : public Slot1<void, const char *> {
   public:
    MenuItemSlot(ScriptableMenu *owner, Gadget *gadget, Slot *handler)
        : owner_(owner), gadget_(gadget), handler_(handler) {
      // Let the slot hold a reference to its owner to prevent the owner
      // from being deleted before end-of-life of this slot.
      owner_->Ref();
    }
    virtual ~MenuItemSlot() {
      delete handler_;
      handler_ = NULL;
      owner_->Unref();
      owner_ = NULL;
    }
    virtual ResultVariant Call(ScriptableInterface *object,
                               int argc, const Variant argv[]) const {
      ASSERT(argc == 1);
      gadget_->SetInUserInteraction(true);
      ResultVariant result = handler_->Call(object, argc, argv);
      gadget_->SetInUserInteraction(false);
      return result;
    }
    virtual bool operator==(const Slot &another) const {
      // Not used.
      return false;
    }

   private:
    ScriptableMenu *owner_;
    Gadget *gadget_;
    Slot *handler_;
  };

  Impl(ScriptableMenu *owner, Gadget *gadget, MenuInterface *menu)
      : owner_(owner), gadget_(gadget), menu_(menu) {
    ASSERT(gadget);
    ASSERT(menu);
  }

  ~Impl() {
    for (std::vector<ScriptableMenu *>::iterator it = submenus_.begin();
         it != submenus_.end(); ++it) {
      (*it)->Unref();
    }
    submenus_.clear();
  }

  void AddItem(const char *item_text, int style, Slot *handler) {
    // TODO: support stock icon.
    menu_->AddItem(item_text, style, 0,
                   handler ? new MenuItemSlot(owner_, gadget_, handler) : NULL,
                   MenuInterface::MENU_ITEM_PRI_CLIENT);
  }

  ScriptableMenu *AddPopup(const char *popup_text) {
    ScriptableMenu *submenu = new ScriptableMenu(gadget_,
            menu_->AddPopup(popup_text, MenuInterface::MENU_ITEM_PRI_CLIENT));
    submenu->Ref();
    submenus_.push_back(submenu);
    return submenu;
  }

  void SetItemStyle(const char *item_text, int style) {
    menu_->SetItemStyle(item_text, style);
  }

  ScriptableMenu *owner_;
  Gadget *gadget_;
  MenuInterface *menu_;
  std::vector<ScriptableMenu *> submenus_;
};

ScriptableMenu::ScriptableMenu(Gadget *gadget, MenuInterface *menu)
  : impl_(new Impl(this, gadget, menu)) {
}

void ScriptableMenu::DoClassRegister() {
  RegisterMethod("AddItem",
                 NewSlot(&Impl::AddItem, &ScriptableMenu::impl_));
  RegisterMethod("SetItemStyle",
                 NewSlot(&Impl::SetItemStyle, &ScriptableMenu::impl_));
  RegisterMethod("AddPopup",
                 NewSlot(&Impl::AddPopup, &ScriptableMenu::impl_));
}

ScriptableMenu::~ScriptableMenu() {
  delete impl_;
  impl_ = NULL;
}

} // namespace ggadget
<commit_msg> r1286@suzhe:  suzhe | 2009-02-18 17:06:53 +0800  - Fix a crash when right clicking on about dialog.<commit_after>/*
  Copyright 2008 Google Inc.

  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 <vector>
#include "gadget.h"
#include "menu_interface.h"
#include "scriptable_menu.h"
#include "slot.h"
#include "small_object.h"

namespace ggadget {

class ScriptableMenu::Impl : public SmallObject<> {
 public:
  class MenuItemSlot : public Slot1<void, const char *> {
   public:
    MenuItemSlot(ScriptableMenu *owner, Gadget *gadget, Slot *handler)
        : owner_(owner), gadget_(gadget), handler_(handler) {
      // Let the slot hold a reference to its owner to prevent the owner
      // from being deleted before end-of-life of this slot.
      owner_->Ref();
    }
    virtual ~MenuItemSlot() {
      delete handler_;
      handler_ = NULL;
      owner_->Unref();
      owner_ = NULL;
    }
    virtual ResultVariant Call(ScriptableInterface *object,
                               int argc, const Variant argv[]) const {
      ASSERT(argc == 1);
      if (gadget_)
        gadget_->SetInUserInteraction(true);
      ResultVariant result = handler_->Call(object, argc, argv);
      if (gadget_)
        gadget_->SetInUserInteraction(false);
      return result;
    }
    virtual bool operator==(const Slot &another) const {
      // Not used.
      return false;
    }

   private:
    ScriptableMenu *owner_;
    Gadget *gadget_;
    Slot *handler_;
  };

  Impl(ScriptableMenu *owner, Gadget *gadget, MenuInterface *menu)
      : owner_(owner), gadget_(gadget), menu_(menu) {
    ASSERT(menu);
  }

  ~Impl() {
    for (std::vector<ScriptableMenu *>::iterator it = submenus_.begin();
         it != submenus_.end(); ++it) {
      (*it)->Unref();
    }
    submenus_.clear();
  }

  void AddItem(const char *item_text, int style, Slot *handler) {
    // TODO: support stock icon.
    menu_->AddItem(item_text, style, 0,
                   handler ? new MenuItemSlot(owner_, gadget_, handler) : NULL,
                   MenuInterface::MENU_ITEM_PRI_CLIENT);
  }

  ScriptableMenu *AddPopup(const char *popup_text) {
    ScriptableMenu *submenu = new ScriptableMenu(gadget_,
            menu_->AddPopup(popup_text, MenuInterface::MENU_ITEM_PRI_CLIENT));
    submenu->Ref();
    submenus_.push_back(submenu);
    return submenu;
  }

  void SetItemStyle(const char *item_text, int style) {
    menu_->SetItemStyle(item_text, style);
  }

  ScriptableMenu *owner_;
  Gadget *gadget_;
  MenuInterface *menu_;
  std::vector<ScriptableMenu *> submenus_;
};

ScriptableMenu::ScriptableMenu(Gadget *gadget, MenuInterface *menu)
  : impl_(new Impl(this, gadget, menu)) {
}

void ScriptableMenu::DoClassRegister() {
  RegisterMethod("AddItem",
                 NewSlot(&Impl::AddItem, &ScriptableMenu::impl_));
  RegisterMethod("SetItemStyle",
                 NewSlot(&Impl::SetItemStyle, &ScriptableMenu::impl_));
  RegisterMethod("AddPopup",
                 NewSlot(&Impl::AddPopup, &ScriptableMenu::impl_));
}

ScriptableMenu::~ScriptableMenu() {
  delete impl_;
  impl_ = NULL;
}

} // namespace ggadget
<|endoftext|>