<commit_before>/* dtkDistributedMapper.cpp ---
 *
 * Author: Thibaud Kloczko
 * Created: 2013 Thu Feb  7 10:55:57 (+0100)
 */

/* Commentary:
 *
 */

/* Change log:
 *
 */

#include "dtkDistributedMapper.h"

#include <QtCore>

// /////////////////////////////////////////////////////////////////
// dtkDistributedMapperPrivate interface
// /////////////////////////////////////////////////////////////////

class dtkDistributedMapperPrivate
{
public:
     dtkDistributedMapperPrivate(void) {;}
    ~dtkDistributedMapperPrivate(void) {;}

public:
    void setMapping(const qlonglong& id_number, const qlonglong& pu_number);
    void initMap(const qlonglong& map_size, const qlonglong& pu_size);
    void setMap(const qlonglong& local_map_size, const qlonglong& pu_id);

public:
    qlonglong localToGlobal(const qlonglong&  local_id, const qlonglong& pu_id) const;

    qlonglong globalToLocal(const qlonglong& global_id) const;

    qlonglong count(const qlonglong& pu_id) const;

    qlonglong owner(const qlonglong& global_id) const;

    QVector<qlonglong> readers(const qlonglong& global_id) const;

public:
    qlonglong id_count;
    qlonglong pu_count;
    qlonglong step;

    QVector<qlonglong> map;
};

// /////////////////////////////////////////////////////////////////
// dtkDistributedMapperPrivate implementation
// /////////////////////////////////////////////////////////////////

void dtkDistributedMapperPrivate::setMapping(const qlonglong& id_number, const qlonglong& pu_number)
{
    this->id_count = id_number;
    this->pu_count = pu_number;
    this->map.reserve(this->pu_count + 1);
    this->map.clear();

    if (this->pu_count == 1) {
        this->map << 0;
        this->step = this->id_count;

    } else if (this->id_count < this->pu_count  ) {

        qDebug() << "Number of ids less than process count: NOT YET IMPLEMENTED";
        return;

    } else if (this->id_count < this->pu_count * 2) {

        for (qlonglong i = 0; i < this->id_count - this->pu_count; ++i)
            this->map << i * 2;

        qlonglong start = (this->id_count - this->pu_count) *2;

        for (qlonglong i = this->id_count - this->pu_count; i < this->pu_count; ++i)
            this->map << start++;

        this->step = 0;
    } else {
        this->step = qRound(this->id_count / (1. * this->pu_count));

        qlonglong last = qMin(this->id_count / this->step, this->pu_count -1);
        for (qlonglong i = 0; i < last; ++i)
            this->map << i * this->step;

        qlonglong start = (last - 1) * this->step;

        for (qlonglong i = last; i < this->pu_count; ++i) {
            start += this->step -1;
            this->map << qMin(start, this->id_count -1);
        }

        this->step = 0;
    }

    this->map << this->id_count;
}

void dtkDistributedMapperPrivate::initMap(const qlonglong& map_size, const qlonglong& pu_size)
{
    this->id_count = map_size;
    this->pu_count = pu_size;

    this->map.resize(this->pu_count + 1);
    this->map[this->pu_count] = map_size;
    this->step = 0;
}

void dtkDistributedMapperPrivate::setMap(const qlonglong& offset, const qlonglong& pu_id)
{
    this->map[pu_id] = offset;
}

qlonglong dtkDistributedMapperPrivate::localToGlobal(const qlonglong& local_id, const qlonglong& pu_id) const
{
    return ( local_id + this->map.at(pu_id) );
}

qlonglong dtkDistributedMapperPrivate::globalToLocal(const qlonglong& global_id) const
{
    qlonglong pu_id = this->owner(global_id);

    return ( global_id - this->map.at(pu_id) );
}

qlonglong dtkDistributedMapperPrivate::count(const qlonglong& pu_id) const
{
    return ( this->map.at(pu_id + 1) - this->map.at(pu_id) );
    // if ( pu_id != (this->pu_count - 1) )
    //     return ( this->map.at(pu_id + 1) - this->map.at(pu_id) );

    // else
    //     return ( this->id_count - this->map.at(pu_id) );
}

qlonglong dtkDistributedMapperPrivate::owner(const qlonglong& global_id) const
{
    if (this->step > 0) {
        return qMin((qlonglong)(global_id / this->step), this->pu_count-1);
    } else {
        qlonglong current_id = this->map[this->map.count() - 2];
        qlonglong pid = this->pu_count-1;
        while (global_id < current_id) {
            current_id = this->map.at(--pid);
        }
        return pid;
    }
}

// /////////////////////////////////////////////////////////////////
// dtkDistributedMapper implementation
// /////////////////////////////////////////////////////////////////

dtkDistributedMapper::dtkDistributedMapper(void) : QObject(), d(new dtkDistributedMapperPrivate)
{

}

dtkDistributedMapper::~dtkDistributedMapper(void)
{
    delete d;
}

void dtkDistributedMapper::setMapping(const qlonglong& id_count, const qlonglong& pu_count)
{
    d->setMapping(id_count, pu_count);
}

void dtkDistributedMapper::initMap(const qlonglong& map_size, const qlonglong& pu_size)
{
    d->initMap(map_size, pu_size);
}

void dtkDistributedMapper::setMap(const qlonglong& offset, const qlonglong& pu_id)
{
    d->setMap(offset, pu_id);
}

qlonglong dtkDistributedMapper::localToGlobal(const qlonglong& local_id, const qlonglong& pu_id) const
{
    return d->localToGlobal(local_id, pu_id);
}

qlonglong dtkDistributedMapper::globalToLocal(const qlonglong& global_id) const
{
    return d->globalToLocal(global_id);
}

qlonglong dtkDistributedMapper::count(const qlonglong& pu_id) const
{
    return d->count(pu_id);
}

qlonglong dtkDistributedMapper::startIndex(const qlonglong& pu_id) const
{
    return d->map[pu_id];
}

qlonglong dtkDistributedMapper::lastIndex(const qlonglong& pu_id) const
{
    return d->map[pu_id + 1] - 1;
}

qlonglong dtkDistributedMapper::owner(const qlonglong& global_id) const
{
    return d->owner(global_id);
}

<commit_msg>enchance default mapper<commit_after>/* dtkDistributedMapper.cpp ---
 *
 * Author: Thibaud Kloczko
 * Created: 2013 Thu Feb  7 10:55:57 (+0100)
 */

/* Commentary:
 *
 */

/* Change log:
 *
 */

#include "dtkDistributedMapper.h"

#include <QtCore>

// /////////////////////////////////////////////////////////////////
// dtkDistributedMapperPrivate interface
// /////////////////////////////////////////////////////////////////

class dtkDistributedMapperPrivate
{
public:
     dtkDistributedMapperPrivate(void) {;}
    ~dtkDistributedMapperPrivate(void) {;}

public:
    void setMapping(const qlonglong& id_number, const qlonglong& pu_number);
    void initMap(const qlonglong& map_size, const qlonglong& pu_size);
    void setMap(const qlonglong& local_map_size, const qlonglong& pu_id);

public:
    qlonglong localToGlobal(const qlonglong&  local_id, const qlonglong& pu_id) const;

    qlonglong globalToLocal(const qlonglong& global_id) const;

    qlonglong count(const qlonglong& pu_id) const;

    qlonglong owner(const qlonglong& global_id) const;

    QVector<qlonglong> readers(const qlonglong& global_id) const;

public:
    qlonglong id_count;
    qlonglong pu_count;
    qlonglong step;

    QVector<qlonglong> map;
};

// /////////////////////////////////////////////////////////////////
// dtkDistributedMapperPrivate implementation
// /////////////////////////////////////////////////////////////////

void dtkDistributedMapperPrivate::setMapping(const qlonglong& id_number, const qlonglong& pu_number)
{
    this->id_count = id_number;
    this->pu_count = pu_number;
    this->map.reserve(this->pu_count + 1);
    this->map.clear();

    if (this->pu_count == 1) {
        this->map << 0;
        this->step = this->id_count;

    } else if (this->id_count < this->pu_count  ) {

        qDebug() << "Number of ids less than process count: NOT YET IMPLEMENTED";
        return;

    } else {
        this->step = this->id_count / this->pu_count;

        qlonglong rest = this->id_count % this->pu_count;
        for (qlonglong i = 0; i < rest+1; ++i) {
            this->map << i * (this->step+1);
        }
        qlonglong last = rest * (this->step +1);
        for (qlonglong i = 1; i < this->pu_count-rest; ++i) {
            this->map << last + i * this->step;
        }

        this->step = 0;
    }

    this->map << this->id_count;
}

void dtkDistributedMapperPrivate::initMap(const qlonglong& map_size, const qlonglong& pu_size)
{
    this->id_count = map_size;
    this->pu_count = pu_size;

    this->map.resize(this->pu_count + 1);
    this->map[this->pu_count] = map_size;
    this->step = 0;
}

void dtkDistributedMapperPrivate::setMap(const qlonglong& offset, const qlonglong& pu_id)
{
    this->map[pu_id] = offset;
}

qlonglong dtkDistributedMapperPrivate::localToGlobal(const qlonglong& local_id, const qlonglong& pu_id) const
{
    return ( local_id + this->map.at(pu_id) );
}

qlonglong dtkDistributedMapperPrivate::globalToLocal(const qlonglong& global_id) const
{
    qlonglong pu_id = this->owner(global_id);

    return ( global_id - this->map.at(pu_id) );
}

qlonglong dtkDistributedMapperPrivate::count(const qlonglong& pu_id) const
{
    return ( this->map.at(pu_id + 1) - this->map.at(pu_id) );
}

qlonglong dtkDistributedMapperPrivate::owner(const qlonglong& global_id) const
{
    if (this->step > 0) {
        return qMin((qlonglong)(global_id / this->step), this->pu_count-1);
    } else {
        qlonglong current_id = this->map[this->map.count() - 2];
        qlonglong pid = this->pu_count-1;
        while (global_id < current_id) {
            current_id = this->map.at(--pid);
        }
        return pid;
    }
}

// /////////////////////////////////////////////////////////////////
// dtkDistributedMapper implementation
// /////////////////////////////////////////////////////////////////

dtkDistributedMapper::dtkDistributedMapper(void) : QObject(), d(new dtkDistributedMapperPrivate)
{

}

dtkDistributedMapper::~dtkDistributedMapper(void)
{
    delete d;
}

void dtkDistributedMapper::setMapping(const qlonglong& id_count, const qlonglong& pu_count)
{
    d->setMapping(id_count, pu_count);
}

void dtkDistributedMapper::initMap(const qlonglong& map_size, const qlonglong& pu_size)
{
    d->initMap(map_size, pu_size);
}

void dtkDistributedMapper::setMap(const qlonglong& offset, const qlonglong& pu_id)
{
    d->setMap(offset, pu_id);
}

qlonglong dtkDistributedMapper::localToGlobal(const qlonglong& local_id, const qlonglong& pu_id) const
{
    return d->localToGlobal(local_id, pu_id);
}

qlonglong dtkDistributedMapper::globalToLocal(const qlonglong& global_id) const
{
    return d->globalToLocal(global_id);
}

qlonglong dtkDistributedMapper::count(const qlonglong& pu_id) const
{
    return d->count(pu_id);
}

qlonglong dtkDistributedMapper::startIndex(const qlonglong& pu_id) const
{
    return d->map[pu_id];
}

qlonglong dtkDistributedMapper::lastIndex(const qlonglong& pu_id) const
{
    return d->map[pu_id + 1] - 1;
}

qlonglong dtkDistributedMapper::owner(const qlonglong& global_id) const
{
    return d->owner(global_id);
}

<|endoftext|>


<commit_before>/*************************************************
* Pooling Allocator Source File                  *
* (C) 1999-2007 The Botan Project                *
*************************************************/

#include <botan/mem_pool.h>
#include <botan/libstate.h>
#include <botan/config.h>
#include <botan/bit_ops.h>
#include <botan/util.h>
#include <algorithm>

namespace Botan {

namespace {

/*************************************************
* Decide how much memory to allocate at once     *
*************************************************/
u32bit choose_pref_size(u32bit provided)
   {
   if(provided)
      return provided;

   u32bit result = global_config().option_as_u32bit("base/memory_chunk");
   if(result)
      return result;

   return 16*1024;
   }

}

/*************************************************
* Memory_Block Constructor                       *
*************************************************/
Pooling_Allocator::Memory_Block::Memory_Block(void* buf)
   {
   buffer = static_cast<byte*>(buf);
   bitmap = 0;
   buffer_end = buffer + (BLOCK_SIZE * BITMAP_SIZE);
   }

/*************************************************
* Compare a Memory_Block with a void pointer     *
*************************************************/
inline bool Pooling_Allocator::Memory_Block::operator<(const void* other) const
   {
   if(buffer <= other && other < buffer_end)
      return false;
   return (buffer < other);
   }

/*************************************************
* See if ptr is contained by this block          *
*************************************************/
bool Pooling_Allocator::Memory_Block::contains(void* ptr,
                                               u32bit length) const throw()
   {
   return ((buffer <= ptr) &&
           (buffer_end >= (byte*)ptr + length * BLOCK_SIZE));
   }

/*************************************************
* Allocate some memory, if possible              *
*************************************************/
byte* Pooling_Allocator::Memory_Block::alloc(u32bit n) throw()
   {
   if(n == 0 || n > BITMAP_SIZE)
      return 0;

   if(n == BITMAP_SIZE)
      {
      if(bitmap)
         return 0;
      else
         {
         bitmap = ~bitmap;
         return buffer;
         }
      }

   bitmap_type mask = ((bitmap_type)1 << n) - 1;
   u32bit offset = 0;

   while(bitmap & mask)
      {
      mask <<= 1;
      ++offset;

      if((bitmap & mask) == 0)
         break;
      if(mask >> 63)
         break;
      }

   if(bitmap & mask)
      return 0;

   bitmap |= mask;
   return buffer + offset * BLOCK_SIZE;
   }

/*************************************************
* Mark this memory as free, if we own it         *
*************************************************/
void Pooling_Allocator::Memory_Block::free(void* ptr, u32bit blocks) throw()
   {
   clear_mem((byte*)ptr, blocks * BLOCK_SIZE);

   const u32bit offset = ((byte*)ptr - buffer) / BLOCK_SIZE;

   if(offset == 0 && blocks == BITMAP_SIZE)
      bitmap = ~bitmap;
   else
      {
      for(u32bit j = 0; j != blocks; ++j)
         bitmap &= ~((bitmap_type)1 << (j+offset));
      }
   }

/*************************************************
* Pooling_Allocator Constructor                  *
*************************************************/
Pooling_Allocator::Pooling_Allocator(u32bit p_size, bool) :
   PREF_SIZE(choose_pref_size(p_size))
   {
   mutex = global_state().get_mutex();
   last_used = blocks.begin();
   }

/*************************************************
* Pooling_Allocator Destructor                   *
*************************************************/
Pooling_Allocator::~Pooling_Allocator()
   {
   delete mutex;
   if(blocks.size())
      throw Invalid_State("Pooling_Allocator: Never released memory");
   }

/*************************************************
* Free all remaining memory                      *
*************************************************/
void Pooling_Allocator::destroy()
   {
   Mutex_Holder lock(mutex);

   blocks.clear();

   for(u32bit j = 0; j != allocated.size(); ++j)
      dealloc_block(allocated[j].first, allocated[j].second);
   allocated.clear();
   }

/*************************************************
* Allocation                                     *
*************************************************/
void* Pooling_Allocator::allocate(u32bit n)
   {
   const u32bit BITMAP_SIZE = Memory_Block::bitmap_size();
   const u32bit BLOCK_SIZE = Memory_Block::block_size();

   Mutex_Holder lock(mutex);

   if(n <= BITMAP_SIZE * BLOCK_SIZE)
      {
      const u32bit block_no = round_up(n, BLOCK_SIZE) / BLOCK_SIZE;

      byte* mem = allocate_blocks(block_no);
      if(mem)
         return mem;

      get_more_core(PREF_SIZE);

      mem = allocate_blocks(block_no);
      if(mem)
         return mem;

      throw Memory_Exhaustion();
      }

   void* new_buf = alloc_block(n);
   if(new_buf)
      return new_buf;

   throw Memory_Exhaustion();
   }

/*************************************************
* Deallocation                                   *
*************************************************/
void Pooling_Allocator::deallocate(void* ptr, u32bit n)
   {
   const u32bit BITMAP_SIZE = Memory_Block::bitmap_size();
   const u32bit BLOCK_SIZE = Memory_Block::block_size();

   if(ptr == 0 && n == 0)
      return;

   Mutex_Holder lock(mutex);

   if(n > BITMAP_SIZE * BLOCK_SIZE)
      dealloc_block(ptr, n);
   else
      {
      const u32bit block_no = round_up(n, BLOCK_SIZE) / BLOCK_SIZE;

      std::vector<Memory_Block>::iterator i =
         std::lower_bound(blocks.begin(), blocks.end(), Memory_Block(ptr));

      if(i == blocks.end() || !i->contains(ptr, block_no))
         throw Invalid_State("Pointer released to the wrong allocator");

      i->free(ptr, block_no);
      }
   }

/*************************************************
* Try to get some memory from an existing block  *
*************************************************/
byte* Pooling_Allocator::allocate_blocks(u32bit n)
   {
   if(blocks.empty())
      return 0;

   std::vector<Memory_Block>::iterator i = last_used;

   do
      {
      byte* mem = i->alloc(n);
      if(mem)
         {
         last_used = i;
         return mem;
         }

      ++i;
      if(i == blocks.end())
         i = blocks.begin();
      }
   while(i != last_used);

   return 0;
   }

/*************************************************
* Allocate more memory for the pool              *
*************************************************/
void Pooling_Allocator::get_more_core(u32bit in_bytes)
   {
   const u32bit BITMAP_SIZE = Memory_Block::bitmap_size();
   const u32bit BLOCK_SIZE = Memory_Block::block_size();

   const u32bit TOTAL_BLOCK_SIZE = BLOCK_SIZE * BITMAP_SIZE;

   const u32bit in_blocks = round_up(in_bytes, BLOCK_SIZE) / TOTAL_BLOCK_SIZE;
   const u32bit to_allocate = in_blocks * TOTAL_BLOCK_SIZE;

   void* ptr = alloc_block(to_allocate);
   if(ptr == 0)
      throw Memory_Exhaustion();

   allocated.push_back(std::make_pair(ptr, to_allocate));

   for(u32bit j = 0; j != in_blocks; ++j)
      {
      byte* byte_ptr = static_cast<byte*>(ptr);
      blocks.push_back(Memory_Block(byte_ptr + j * TOTAL_BLOCK_SIZE));
      }

   std::sort(blocks.begin(), blocks.end());
   last_used = std::lower_bound(blocks.begin(), blocks.end(),
                                Memory_Block(ptr));
   }

}
<commit_msg>Revert the last change; it actually broke the memory allocators in a fairly massive way.<commit_after>/*************************************************
* Pooling Allocator Source File                  *
* (C) 1999-2007 The Botan Project                *
*************************************************/

#include <botan/mem_pool.h>
#include <botan/libstate.h>
#include <botan/config.h>
#include <botan/bit_ops.h>
#include <botan/util.h>
#include <algorithm>

namespace Botan {

namespace {

/*************************************************
* Decide how much memory to allocate at once     *
*************************************************/
u32bit choose_pref_size(u32bit provided)
   {
   if(provided)
      return provided;

   u32bit result = global_config().option_as_u32bit("base/memory_chunk");
   if(result)
      return result;

   return 16*1024;
   }

}

/*************************************************
* Memory_Block Constructor                       *
*************************************************/
Pooling_Allocator::Memory_Block::Memory_Block(void* buf)
   {
   buffer = static_cast<byte*>(buf);
   bitmap = 0;
   buffer_end = buffer + (BLOCK_SIZE * BITMAP_SIZE);
   }

/*************************************************
* Compare a Memory_Block with a void pointer     *
*************************************************/
inline bool Pooling_Allocator::Memory_Block::operator<(const void* other) const
   {
   if(buffer <= other && other < buffer_end)
      return false;
   return (buffer < other);
   }

/*************************************************
* See if ptr is contained by this block          *
*************************************************/
bool Pooling_Allocator::Memory_Block::contains(void* ptr,
                                               u32bit length) const throw()
   {
   return ((buffer <= ptr) &&
           (buffer_end >= (byte*)ptr + length * BLOCK_SIZE));
   }

/*************************************************
* Allocate some memory, if possible              *
*************************************************/
byte* Pooling_Allocator::Memory_Block::alloc(u32bit n) throw()
   {
   if(n == 0 || n > BITMAP_SIZE)
      return 0;

   if(n == BITMAP_SIZE)
      {
      if(bitmap)
         return 0;
      else
         {
         bitmap = ~bitmap;
         return buffer;
         }
      }

   bitmap_type mask = ((bitmap_type)1 << n) - 1;
   u32bit offset = 0;

   while(bitmap & mask)
      {
      mask <<= 1;
      ++offset;

      if((bitmap & mask) == 0)
         break;
      if(mask >> 63)
         break;
      }

   if(bitmap & mask)
      return 0;

   bitmap |= mask;
   return buffer + offset * BLOCK_SIZE;
   }

/*************************************************
* Mark this memory as free, if we own it         *
*************************************************/
void Pooling_Allocator::Memory_Block::free(void* ptr, u32bit blocks) throw()
   {
   clear_mem((byte*)ptr, blocks * BLOCK_SIZE);

   const u32bit offset = ((byte*)ptr - buffer) / BLOCK_SIZE;

   if(offset == 0 && blocks == BITMAP_SIZE)
      bitmap = ~bitmap;
   else
      {
      for(u32bit j = 0; j != blocks; ++j)
         bitmap &= ~((bitmap_type)1 << (j+offset));
      }
   }

/*************************************************
* Pooling_Allocator Constructor                  *
*************************************************/
Pooling_Allocator::Pooling_Allocator(u32bit p_size, bool) :
   PREF_SIZE(choose_pref_size(p_size))
   {
   mutex = global_state().get_mutex();
   last_used = blocks.begin();
   }

/*************************************************
* Pooling_Allocator Destructor                   *
*************************************************/
Pooling_Allocator::~Pooling_Allocator()
   {
   delete mutex;
   if(blocks.size())
      throw Invalid_State("Pooling_Allocator: Never released memory");
   }

/*************************************************
* Free all remaining memory                      *
*************************************************/
void Pooling_Allocator::destroy()
   {
   Mutex_Holder lock(mutex);

   blocks.clear();

   for(u32bit j = 0; j != allocated.size(); ++j)
      dealloc_block(allocated[j].first, allocated[j].second);
   allocated.clear();
   }

/*************************************************
* Allocation                                     *
*************************************************/
void* Pooling_Allocator::allocate(u32bit n)
   {
   const u32bit BITMAP_SIZE = Memory_Block::bitmap_size();
   const u32bit BLOCK_SIZE = Memory_Block::block_size();

   Mutex_Holder lock(mutex);

   if(n <= BITMAP_SIZE * BLOCK_SIZE)
      {
      const u32bit block_no = round_up(n, BLOCK_SIZE) / BLOCK_SIZE;

      byte* mem = allocate_blocks(block_no);
      if(mem)
         return mem;

      get_more_core(PREF_SIZE);

      mem = allocate_blocks(block_no);
      if(mem)
         return mem;

      throw Memory_Exhaustion();
      }

   void* new_buf = alloc_block(n);
   if(new_buf)
      return new_buf;

   throw Memory_Exhaustion();
   }

/*************************************************
* Deallocation                                   *
*************************************************/
void Pooling_Allocator::deallocate(void* ptr, u32bit n)
   {
   const u32bit BITMAP_SIZE = Memory_Block::bitmap_size();
   const u32bit BLOCK_SIZE = Memory_Block::block_size();

   if(ptr == 0 && n == 0)
      return;

   Mutex_Holder lock(mutex);

   if(n > BITMAP_SIZE * BLOCK_SIZE)
      dealloc_block(ptr, n);
   else
      {
      const u32bit block_no = round_up(n, BLOCK_SIZE) / BLOCK_SIZE;

      std::vector<Memory_Block>::iterator i =
         std::lower_bound(blocks.begin(), blocks.end(), ptr);

      if(i == blocks.end() || !i->contains(ptr, block_no))
         throw Invalid_State("Pointer released to the wrong allocator");

      i->free(ptr, block_no);
      }
   }

/*************************************************
* Try to get some memory from an existing block  *
*************************************************/
byte* Pooling_Allocator::allocate_blocks(u32bit n)
   {
   if(blocks.empty())
      return 0;

   std::vector<Memory_Block>::iterator i = last_used;

   do
      {
      byte* mem = i->alloc(n);
      if(mem)
         {
         last_used = i;
         return mem;
         }

      ++i;
      if(i == blocks.end())
         i = blocks.begin();
      }
   while(i != last_used);

   return 0;
   }

/*************************************************
* Allocate more memory for the pool              *
*************************************************/
void Pooling_Allocator::get_more_core(u32bit in_bytes)
   {
   const u32bit BITMAP_SIZE = Memory_Block::bitmap_size();
   const u32bit BLOCK_SIZE = Memory_Block::block_size();

   const u32bit TOTAL_BLOCK_SIZE = BLOCK_SIZE * BITMAP_SIZE;

   const u32bit in_blocks = round_up(in_bytes, BLOCK_SIZE) / TOTAL_BLOCK_SIZE;
   const u32bit to_allocate = in_blocks * TOTAL_BLOCK_SIZE;

   void* ptr = alloc_block(to_allocate);
   if(ptr == 0)
      throw Memory_Exhaustion();

   allocated.push_back(std::make_pair(ptr, to_allocate));

   for(u32bit j = 0; j != in_blocks; ++j)
      {
      byte* byte_ptr = static_cast<byte*>(ptr);
      blocks.push_back(Memory_Block(byte_ptr + j * TOTAL_BLOCK_SIZE));
      }

   std::sort(blocks.begin(), blocks.end());
   last_used = std::lower_bound(blocks.begin(), blocks.end(),
                                Memory_Block(ptr));
   }

}
<|endoftext|>


<commit_before>#include "metaenum_p.h"
#include "metacontainer_p.h"

namespace rtti {

MetaEnum::MetaEnum(std::string_view const &name, const MetaContainer &owner, MetaType_ID typeId)
    : MetaItem{*new MetaEnumPrivate{name, owner, typeId}}
{}

MetaEnum *MetaEnum::create(std::string_view const &name, MetaContainer &owner, MetaType_ID typeId)
{
    auto result = const_cast<MetaEnum*>(owner.getEnum(name));
    if (!result)
    {
        result = new MetaEnum{name, owner, typeId};
        INVOKE_PROTECTED(owner, addItem, result);
    }
    return result;
}

void MetaEnum::addElement(std::string_view const &name, variant &&value)
{
    auto d = d_func();
    d->m_elements.set(name, std::move(value));
}

MetaCategory MetaEnum::category() const
{
    return mcatEnum;
}

std::size_t MetaEnum::elementCount() const
{
    auto d = d_func();
    return d->m_elements.size();
}

const variant& MetaEnum::element(std::size_t index) const
{
    auto d = d_func();
    return d->m_elements.get(index);
}

const std::string &MetaEnum::elementName(std::size_t index) const
{
    auto d = d_func();
    return d->m_elements.name(index);
}

const variant& MetaEnum::element(std::string_view const &name) const
{
    auto d = d_func();
    return d->m_elements.get(name);
}

void MetaEnum::for_each_element(enum_element_t const &func) const
{
    if (!func)
        return;

    auto d = d_func();
    d->m_elements.for_each([&func](std::string const &name, variant const &value) -> bool
    {
        return func(name, value);
    });
}

} // namespace rtti
<commit_msg>C++17<commit_after>#include "metaenum_p.h"
#include "metacontainer_p.h"

namespace rtti {

MetaEnum::MetaEnum(std::string_view const &name, MetaContainer const &owner, MetaType_ID typeId)
    : MetaItem{*new MetaEnumPrivate{name, owner, typeId}}
{}

MetaEnum *MetaEnum::create(std::string_view const &name, MetaContainer &owner, MetaType_ID typeId)
{
    auto result = const_cast<MetaEnum*>(owner.getEnum(name));
    if (!result)
    {
        result = new MetaEnum{name, owner, typeId};
        INVOKE_PROTECTED(owner, addItem, result);
    }
    return result;
}

void MetaEnum::addElement(std::string_view const &name, variant &&value)
{
    auto d = d_func();
    d->m_elements.set(name, std::move(value));
}

MetaCategory MetaEnum::category() const
{
    return mcatEnum;
}

std::size_t MetaEnum::elementCount() const
{
    auto d = d_func();
    return d->m_elements.size();
}

variant const& MetaEnum::element(std::size_t index) const
{
    auto d = d_func();
    return d->m_elements.get(index);
}

std::string const &MetaEnum::elementName(std::size_t index) const
{
    auto d = d_func();
    return d->m_elements.name(index);
}

variant const& MetaEnum::element(std::string_view const &name) const
{
    auto d = d_func();
    return d->m_elements.get(name);
}

void MetaEnum::for_each_element(enum_element_t const &func) const
{
    if (!func)
        return;

    auto d = d_func();
    d->m_elements.for_each([&func](std::string const &name, variant const &value) -> bool
    {
        return func(name, value);
    });
}

} // namespace rtti
<|endoftext|>


<commit_before>/*
 * MRustC - Rust Compiler
 * - By John Hodge (Mutabah/thePowersGang)
 *
 * mir/dump.cpp
 * - Dump MIR for functions (semi-flattened)
 */
#include "main_bindings.hpp"
#include <hir/visitor.hpp>
#include "mir.hpp"

namespace {

    class TreeVisitor:
        public ::HIR::Visitor
    {
        ::std::ostream& m_os;
        unsigned int    m_indent_level;

    public:
        TreeVisitor(::std::ostream& os):
            m_os(os),
            m_indent_level(0)
        {
        }

        void visit_type_impl(::HIR::TypeImpl& impl) override
        {
            m_os << indent() << "impl" << impl.m_params.fmt_args() << " " << impl.m_type << "\n";
            if( ! impl.m_params.m_bounds.empty() )
            {
                m_os << indent() << " " << impl.m_params.fmt_bounds() << "\n";
            }
            m_os << indent() << "{\n";
            inc_indent();
            ::HIR::Visitor::visit_type_impl(impl);
            dec_indent();
            m_os << indent() << "}\n";
        }
        virtual void visit_trait_impl(const ::HIR::SimplePath& trait_path, ::HIR::TraitImpl& impl) override
        {
            m_os << indent() << "impl" << impl.m_params.fmt_args() << " " << trait_path << impl.m_trait_args << " for " << impl.m_type << "\n";
            if( ! impl.m_params.m_bounds.empty() )
            {
                m_os << indent() << " " << impl.m_params.fmt_bounds() << "\n";
            }
            m_os << indent() << "{\n";
            inc_indent();
            ::HIR::Visitor::visit_trait_impl(trait_path, impl);
            dec_indent();
            m_os << indent() << "}\n";
        }
        void visit_marker_impl(const ::HIR::SimplePath& trait_path, ::HIR::MarkerImpl& impl) override
        {
            m_os << indent() << "impl" << impl.m_params.fmt_args() << " " << (impl.is_positive ? "" : "!") << trait_path << impl.m_trait_args << " for " << impl.m_type << "\n";
            if( ! impl.m_params.m_bounds.empty() )
            {
                m_os << indent() << " " << impl.m_params.fmt_bounds() << "\n";
            }
            m_os << indent() << "{ }\n";
        }

        // - Type Items
        void visit_type_alias(::HIR::ItemPath p, ::HIR::TypeAlias& item) override
        {
            m_os << indent() << "type " << p.get_name() << item.m_params.fmt_args() << " = " << item.m_type << item.m_params.fmt_bounds() << "\n";
        }
        void visit_trait(::HIR::ItemPath p, ::HIR::Trait& item) override
        {
            m_os << indent() << "trait " << p.get_name() << item.m_params.fmt_args() << "\n";
            if( ! item.m_params.m_bounds.empty() )
            {
                m_os << indent() << " " << item.m_params.fmt_bounds() << "\n";
            }
            m_os << indent() << "{\n";
            inc_indent();
            ::HIR::Visitor::visit_trait(p, item);
            dec_indent();
            m_os << indent() << "}\n";
        }

        void visit_function(::HIR::ItemPath p, ::HIR::Function& item) override
        {
            m_os << indent();
            if( item.m_const )
                m_os << "const ";
            if( item.m_unsafe )
                m_os << "unsafe ";
            if( item.m_abi != "rust" )
                m_os << "extern \"" << item.m_abi << "\" ";
            m_os << "fn " << p.get_name() << item.m_params.fmt_args() << "(";
            for(const auto& arg : item.m_args)
            {
                m_os << arg.first << ": " << arg.second << ", ";
            }
            m_os << ") -> " << item.m_return << "\n";
            if( ! item.m_params.m_bounds.empty() )
            {
                m_os << indent() << " " << item.m_params.fmt_bounds() << "\n";
            }

            if( item.m_code )
            {
                m_os << indent() << "{\n";
                inc_indent();
                this->dump_mir(*item.m_code.m_mir);
                dec_indent();
                m_os << indent() << "}\n";
            }
            else
            {
                m_os << indent() << "  ;\n";
            }
        }

        void dump_mir(const ::MIR::Function& fcn)
        {
            for(unsigned int i = 0; i < fcn.named_variables.size(); i ++)
            {
                m_os << indent() << "let _#" << i << ": " << fcn.named_variables[i] << ";\n";
            }
            for(unsigned int i = 0; i < fcn.temporaries.size(); i ++)
            {
                m_os << indent() << "let tmp$" << i << ": " << fcn.temporaries[i] << ";\n";
            }

            #define FMT_M(x)   FMT_CB(os, this->fmt_val(os,x);)
            for(unsigned int i = 0; i < fcn.blocks.size(); i ++)
            {
                const auto& block = fcn.blocks[i];
                m_os << indent() << "bb" << i << ": {\n";
                inc_indent();
                for(const auto& stmt : block.statements)
                {
                    m_os << indent();

                    TU_MATCHA( (stmt), (e),
                    (Assign,
                        m_os << FMT_M(e.dst) << " = " << FMT_M(e.src) << ";\n";
                        ),
                    (Drop,
                        m_os << "drop(" << FMT_M(e.slot) << ");\n";
                        )
                    )
                }

                m_os << indent();
                TU_MATCHA( (block.terminator), (e),
                (Incomplete,
                    m_os << "INVALID;\n";
                    ),
                (Return,
                    m_os << "return;\n";
                    ),
                (Diverge,
                    m_os << "diverge;\n";
                    ),
                (Goto,
                    m_os << "goto bb" << e << ";\n";
                    ),
                (Panic,
                    m_os << "panic bb" << e.dst << ";\n";
                    ),
                (If,
                    m_os << "if " << FMT_M(e.cond) << " { goto bb" << e.bb0 << "; } else { goto bb" << e.bb1 << "; }\n";
                    ),
                (Switch,
                    m_os << "switch " << FMT_M(e.val) << " {";
                    for(unsigned int j = 0; j < e.targets.size(); j ++)
                        m_os << j << " => bb" << e.targets[j] << ", ";
                    m_os << "}\n";
                    ),
                (Call,
                    m_os << FMT_M(e.ret_val) << " = (" << FMT_M(e.fcn_val) << ")( ";
                    for(const auto& arg : e.args)
                        m_os << FMT_M(arg) << ", ";
                    m_os << ") goto bb" << e.ret_block << " else bb" << e.panic_block << "\n";
                    )
                )
                dec_indent();
                m_os << indent() << "}\n";

                m_os.flush();
            }
            #undef FMT
        }
        void fmt_val(::std::ostream& os, const ::MIR::LValue& lval) {
            TU_MATCHA( (lval), (e),
            (Variable,
                os << "_#" << e;
                ),
            (Temporary,
                os << "tmp$" << e.idx;
                ),
            (Argument,
                os << "arg$" << e.idx;
                ),
            (Static,
                os << e;
                ),
            (Return,
                os << "RETURN";
                ),
            (Field,
                os << "(";
                fmt_val(os, *e.val);
                os << ")." << e.field_index;
                ),
            (Deref,
                os << "*";
                fmt_val(os, *e.val);
                ),
            (Index,
                os << "(";
                fmt_val(os, *e.val);
                os << ")[";
                fmt_val(os, *e.idx);
                os << "]";
                ),
            (Downcast,
                fmt_val(os, *e.val);
                os << " as variant" << e.variant_index;
                )
            )
        }
        void fmt_val(::std::ostream& os, const ::MIR::RValue& rval) {
            TU_MATCHA( (rval), (e),
            (Use,
                fmt_val(os, e);
                ),
            (Constant,
                TU_MATCHA( (e), (ce),
                (Int,
                    os << ce;
                    ),
                (Uint,
                    os << "0x" << ::std::hex << ce << ::std::dec;
                    ),
                (Float,
                    os << ce;
                    ),
                (Bool,
                    os << (ce ? "true" : "false");
                    ),
                (Bytes,
                    os << "b\"" << ce << "\"";
                    ),
                (StaticString,
                    os << "\"" << ce << "\"";
                    ),
                (ItemAddr,
                    os << "addr " << ce;
                    )
                )
                ),
            (SizedArray,
                os << "[";
                fmt_val(os, e.val);
                os << ";" << e.count << "]";
                ),
            (Borrow,
                os << "&";
                //os << e.region;
                switch(e.type) {
                case ::HIR::BorrowType::Shared: break;
                case ::HIR::BorrowType::Unique: os << "mut "; break;
                case ::HIR::BorrowType::Owned: os << "move "; break;
                }
                os << "(";
                fmt_val(os, e.val);
                os << ")";
                ),
            (Cast,
                os << "(";
                fmt_val(os, e.val);
                os << ") as " << e.type;
                ),
            (BinOp,
                switch(e.op)
                {
                case ::MIR::eBinOp::ADD: os << "ADD"; break;
                case ::MIR::eBinOp::SUB: os << "SUB"; break;
                case ::MIR::eBinOp::MUL: os << "MUL"; break;
                case ::MIR::eBinOp::DIV: os << "DIV"; break;
                case ::MIR::eBinOp::MOD: os << "MOD"; break;
                case ::MIR::eBinOp::ADD_OV: os << "ADD_OV"; break;
                case ::MIR::eBinOp::SUB_OV: os << "SUB_OV"; break;
                case ::MIR::eBinOp::MUL_OV: os << "MUL_OV"; break;
                case ::MIR::eBinOp::DIV_OV: os << "DIV_OV"; break;
                //case ::MIR::eBinOp::MOD_OV: os << "MOD_OV"; break;

                case ::MIR::eBinOp::BIT_OR : os << "BIT_OR"; break;
                case ::MIR::eBinOp::BIT_AND: os << "BIT_AND"; break;
                case ::MIR::eBinOp::BIT_XOR: os << "BIT_XOR"; break;

                case ::MIR::eBinOp::BIT_SHR: os << "BIT_SHR"; break;
                case ::MIR::eBinOp::BIT_SHL: os << "BIT_SHL"; break;

                case ::MIR::eBinOp::EQ: os << "EQ"; break;
                case ::MIR::eBinOp::NE: os << "NE"; break;
                case ::MIR::eBinOp::GT: os << "GT"; break;
                case ::MIR::eBinOp::GE: os << "GE"; break;
                case ::MIR::eBinOp::LT: os << "LT"; break;
                case ::MIR::eBinOp::LE: os << "LE"; break;
                }
                os << "(";
                fmt_val(os, e.val_l);
                os << ", ";
                fmt_val(os, e.val_r);
                os << ")";
                ),
            (UniOp,
                switch(e.op)
                {
                case ::MIR::eUniOp::INV: os << "INV"; break;
                case ::MIR::eUniOp::NEG: os << "NEG"; break;
                }
                os << "(";
                fmt_val(os, e.val);
                os << ")";
                ),
            (DstMeta,
                os << "META(";
                fmt_val(os, e.val);
                os << ")";
                ),
            (MakeDst,
                os << "DST(";
                fmt_val(os, e.ptr_val);
                os << ", ";
                fmt_val(os, e.meta_val);
                os << ")";
                ),
            (Tuple,
                os << "(";
                for(const auto& v : e.vals) {
                    fmt_val(os, v);
                    os << ", ";
                }
                os << ")";
                ),
            (Array,
                os << "[";
                for(const auto& v : e.vals) {
                    fmt_val(os, v);
                    os << ", ";
                }
                os << "]";
                ),
            (Struct,
                os << e.path << " { ";
                for(const auto& v : e.vals) {
                    fmt_val(os, v);
                    os << ", ";
                }
                os << "}";
                )
            )
        }
    private:
        RepeatLitStr indent() const {
            return RepeatLitStr { "   ", static_cast<int>(m_indent_level) };
        }
        void inc_indent() {
            m_indent_level ++;
        }
        void dec_indent() {
            m_indent_level --;
        }
    };
}

void MIR_Dump(::std::ostream& sink, const ::HIR::Crate& crate)
{
    TreeVisitor tv { sink };

    tv.visit_crate( const_cast< ::HIR::Crate&>(crate) );
}

<commit_msg>MIR Dump - Clean up output<commit_after>/*
 * MRustC - Rust Compiler
 * - By John Hodge (Mutabah/thePowersGang)
 *
 * mir/dump.cpp
 * - Dump MIR for functions (semi-flattened)
 */
#include "main_bindings.hpp"
#include <hir/visitor.hpp>
#include "mir.hpp"

namespace {

    class TreeVisitor:
        public ::HIR::Visitor
    {
        ::std::ostream& m_os;
        unsigned int    m_indent_level;
        bool m_short_item_name = false;

    public:
        TreeVisitor(::std::ostream& os):
            m_os(os),
            m_indent_level(0)
        {
        }

        void visit_type_impl(::HIR::TypeImpl& impl) override
        {
            m_short_item_name = true;

            m_os << indent() << "impl" << impl.m_params.fmt_args() << " " << impl.m_type << "\n";
            if( ! impl.m_params.m_bounds.empty() )
            {
                m_os << indent() << " " << impl.m_params.fmt_bounds() << "\n";
            }
            m_os << indent() << "{\n";
            inc_indent();
            ::HIR::Visitor::visit_type_impl(impl);
            dec_indent();
            m_os << indent() << "}\n";

            m_short_item_name = false;
        }
        virtual void visit_trait_impl(const ::HIR::SimplePath& trait_path, ::HIR::TraitImpl& impl) override
        {
            m_short_item_name = true;

            m_os << indent() << "impl" << impl.m_params.fmt_args() << " " << trait_path << impl.m_trait_args << " for " << impl.m_type << "\n";
            if( ! impl.m_params.m_bounds.empty() )
            {
                m_os << indent() << " " << impl.m_params.fmt_bounds() << "\n";
            }
            m_os << indent() << "{\n";
            inc_indent();
            ::HIR::Visitor::visit_trait_impl(trait_path, impl);
            dec_indent();
            m_os << indent() << "}\n";

            m_short_item_name = false;
        }
        void visit_marker_impl(const ::HIR::SimplePath& trait_path, ::HIR::MarkerImpl& impl) override
        {
            m_short_item_name = true;

            m_os << indent() << "impl" << impl.m_params.fmt_args() << " " << (impl.is_positive ? "" : "!") << trait_path << impl.m_trait_args << " for " << impl.m_type << "\n";
            if( ! impl.m_params.m_bounds.empty() )
            {
                m_os << indent() << " " << impl.m_params.fmt_bounds() << "\n";
            }
            m_os << indent() << "{ }\n";

            m_short_item_name = false;
        }

        // - Type Items
        void visit_trait(::HIR::ItemPath p, ::HIR::Trait& item) override
        {
            m_short_item_name = true;

            m_os << indent() << "trait " << p << item.m_params.fmt_args() << "\n";
            if( ! item.m_params.m_bounds.empty() )
            {
                m_os << indent() << " " << item.m_params.fmt_bounds() << "\n";
            }
            m_os << indent() << "{\n";
            inc_indent();
            ::HIR::Visitor::visit_trait(p, item);
            dec_indent();
            m_os << indent() << "}\n";

            m_short_item_name = false;
        }

        void visit_function(::HIR::ItemPath p, ::HIR::Function& item) override
        {
            m_os << indent();
            if( item.m_const )
                m_os << "const ";
            if( item.m_unsafe )
                m_os << "unsafe ";
            if( item.m_abi != "rust" )
                m_os << "extern \"" << item.m_abi << "\" ";
            m_os << "fn ";
            if( m_short_item_name )
                m_os << p.get_name();
            else
                m_os << p;
            m_os << item.m_params.fmt_args() << "(";
            for(const auto& arg : item.m_args)
            {
                m_os << arg.first << ": " << arg.second << ", ";
            }
            m_os << ") -> " << item.m_return << "\n";
            if( ! item.m_params.m_bounds.empty() )
            {
                m_os << indent() << " " << item.m_params.fmt_bounds() << "\n";
            }

            if( item.m_code )
            {
                m_os << indent() << "{\n";
                inc_indent();
                this->dump_mir(*item.m_code.m_mir);
                dec_indent();
                m_os << indent() << "}\n";
            }
            else
            {
                m_os << indent() << "  ;\n";
            }
        }

        void dump_mir(const ::MIR::Function& fcn)
        {
            for(unsigned int i = 0; i < fcn.named_variables.size(); i ++)
            {
                m_os << indent() << "let _#" << i << ": " << fcn.named_variables[i] << ";\n";
            }
            for(unsigned int i = 0; i < fcn.temporaries.size(); i ++)
            {
                m_os << indent() << "let tmp$" << i << ": " << fcn.temporaries[i] << ";\n";
            }

            #define FMT_M(x)   FMT_CB(os, this->fmt_val(os,x);)
            for(unsigned int i = 0; i < fcn.blocks.size(); i ++)
            {
                const auto& block = fcn.blocks[i];
                m_os << indent() << "bb" << i << ": {\n";
                inc_indent();
                for(const auto& stmt : block.statements)
                {
                    m_os << indent();

                    TU_MATCHA( (stmt), (e),
                    (Assign,
                        m_os << FMT_M(e.dst) << " = " << FMT_M(e.src) << ";\n";
                        ),
                    (Drop,
                        m_os << "drop(" << FMT_M(e.slot) << ");\n";
                        )
                    )
                }

                m_os << indent();
                TU_MATCHA( (block.terminator), (e),
                (Incomplete,
                    m_os << "INVALID;\n";
                    ),
                (Return,
                    m_os << "return;\n";
                    ),
                (Diverge,
                    m_os << "diverge;\n";
                    ),
                (Goto,
                    m_os << "goto bb" << e << ";\n";
                    ),
                (Panic,
                    m_os << "panic bb" << e.dst << ";\n";
                    ),
                (If,
                    m_os << "if " << FMT_M(e.cond) << " { goto bb" << e.bb0 << "; } else { goto bb" << e.bb1 << "; }\n";
                    ),
                (Switch,
                    m_os << "switch " << FMT_M(e.val) << " {";
                    for(unsigned int j = 0; j < e.targets.size(); j ++)
                        m_os << j << " => bb" << e.targets[j] << ", ";
                    m_os << "}\n";
                    ),
                (Call,
                    m_os << FMT_M(e.ret_val) << " = (" << FMT_M(e.fcn_val) << ")( ";
                    for(const auto& arg : e.args)
                        m_os << FMT_M(arg) << ", ";
                    m_os << ") goto bb" << e.ret_block << " else bb" << e.panic_block << "\n";
                    )
                )
                dec_indent();
                m_os << indent() << "}\n";

                m_os.flush();
            }
            #undef FMT
        }
        void fmt_val(::std::ostream& os, const ::MIR::LValue& lval) {
            TU_MATCHA( (lval), (e),
            (Variable,
                os << "_#" << e;
                ),
            (Temporary,
                os << "tmp$" << e.idx;
                ),
            (Argument,
                os << "arg$" << e.idx;
                ),
            (Static,
                os << e;
                ),
            (Return,
                os << "RETURN";
                ),
            (Field,
                os << "(";
                fmt_val(os, *e.val);
                os << ")." << e.field_index;
                ),
            (Deref,
                os << "*";
                fmt_val(os, *e.val);
                ),
            (Index,
                os << "(";
                fmt_val(os, *e.val);
                os << ")[";
                fmt_val(os, *e.idx);
                os << "]";
                ),
            (Downcast,
                fmt_val(os, *e.val);
                os << " as variant" << e.variant_index;
                )
            )
        }
        void fmt_val(::std::ostream& os, const ::MIR::RValue& rval) {
            TU_MATCHA( (rval), (e),
            (Use,
                fmt_val(os, e);
                ),
            (Constant,
                TU_MATCHA( (e), (ce),
                (Int,
                    os << ce;
                    ),
                (Uint,
                    os << "0x" << ::std::hex << ce << ::std::dec;
                    ),
                (Float,
                    os << ce;
                    ),
                (Bool,
                    os << (ce ? "true" : "false");
                    ),
                (Bytes,
                    os << "b\"" << ce << "\"";
                    ),
                (StaticString,
                    os << "\"" << ce << "\"";
                    ),
                (ItemAddr,
                    os << "addr " << ce;
                    )
                )
                ),
            (SizedArray,
                os << "[";
                fmt_val(os, e.val);
                os << ";" << e.count << "]";
                ),
            (Borrow,
                os << "&";
                //os << e.region;
                switch(e.type) {
                case ::HIR::BorrowType::Shared: break;
                case ::HIR::BorrowType::Unique: os << "mut "; break;
                case ::HIR::BorrowType::Owned: os << "move "; break;
                }
                os << "(";
                fmt_val(os, e.val);
                os << ")";
                ),
            (Cast,
                os << "(";
                fmt_val(os, e.val);
                os << ") as " << e.type;
                ),
            (BinOp,
                switch(e.op)
                {
                case ::MIR::eBinOp::ADD: os << "ADD"; break;
                case ::MIR::eBinOp::SUB: os << "SUB"; break;
                case ::MIR::eBinOp::MUL: os << "MUL"; break;
                case ::MIR::eBinOp::DIV: os << "DIV"; break;
                case ::MIR::eBinOp::MOD: os << "MOD"; break;
                case ::MIR::eBinOp::ADD_OV: os << "ADD_OV"; break;
                case ::MIR::eBinOp::SUB_OV: os << "SUB_OV"; break;
                case ::MIR::eBinOp::MUL_OV: os << "MUL_OV"; break;
                case ::MIR::eBinOp::DIV_OV: os << "DIV_OV"; break;
                //case ::MIR::eBinOp::MOD_OV: os << "MOD_OV"; break;

                case ::MIR::eBinOp::BIT_OR : os << "BIT_OR"; break;
                case ::MIR::eBinOp::BIT_AND: os << "BIT_AND"; break;
                case ::MIR::eBinOp::BIT_XOR: os << "BIT_XOR"; break;

                case ::MIR::eBinOp::BIT_SHR: os << "BIT_SHR"; break;
                case ::MIR::eBinOp::BIT_SHL: os << "BIT_SHL"; break;

                case ::MIR::eBinOp::EQ: os << "EQ"; break;
                case ::MIR::eBinOp::NE: os << "NE"; break;
                case ::MIR::eBinOp::GT: os << "GT"; break;
                case ::MIR::eBinOp::GE: os << "GE"; break;
                case ::MIR::eBinOp::LT: os << "LT"; break;
                case ::MIR::eBinOp::LE: os << "LE"; break;
                }
                os << "(";
                fmt_val(os, e.val_l);
                os << ", ";
                fmt_val(os, e.val_r);
                os << ")";
                ),
            (UniOp,
                switch(e.op)
                {
                case ::MIR::eUniOp::INV: os << "INV"; break;
                case ::MIR::eUniOp::NEG: os << "NEG"; break;
                }
                os << "(";
                fmt_val(os, e.val);
                os << ")";
                ),
            (DstMeta,
                os << "META(";
                fmt_val(os, e.val);
                os << ")";
                ),
            (MakeDst,
                os << "DST(";
                fmt_val(os, e.ptr_val);
                os << ", ";
                fmt_val(os, e.meta_val);
                os << ")";
                ),
            (Tuple,
                os << "(";
                for(const auto& v : e.vals) {
                    fmt_val(os, v);
                    os << ", ";
                }
                os << ")";
                ),
            (Array,
                os << "[";
                for(const auto& v : e.vals) {
                    fmt_val(os, v);
                    os << ", ";
                }
                os << "]";
                ),
            (Struct,
                os << e.path << " { ";
                for(const auto& v : e.vals) {
                    fmt_val(os, v);
                    os << ", ";
                }
                os << "}";
                )
            )
        }
    private:
        RepeatLitStr indent() const {
            return RepeatLitStr { "   ", static_cast<int>(m_indent_level) };
        }
        void inc_indent() {
            m_indent_level ++;
        }
        void dec_indent() {
            m_indent_level --;
        }
    };
}

void MIR_Dump(::std::ostream& sink, const ::HIR::Crate& crate)
{
    TreeVisitor tv { sink };

    tv.visit_crate( const_cast< ::HIR::Crate&>(crate) );
}

<|endoftext|>


<commit_before>/*
 * OtaLogger.hpp
 * Wraps ArduinoOTA into a class and shows the OTA
 * status on serial or an OLED display.
 *
 * Version: 1.0
 * Author: Lübbe Onken (http://github.com/luebbe)
 */

#ifndef SRC_OTA_H
#define SRC_OTA_H

#include <Homie.h>       // used for logger output
#include <OLEDDisplay.h> // used for display output
#include <ArduinoOTA.h>

// -----------------------------------------------------------------------------
// OTA info via Homie logger
// -----------------------------------------------------------------------------

class OtaLogger {
private:
protected:
  String getErrorMessage(ota_error_t error);

public:
  OtaLogger();

  virtual void setup(uint16_t port = 8266, const char *password = "");
  virtual void loop();

  virtual void onStart();
  virtual void onEnd();
  virtual void onProgress(unsigned int progress, unsigned int total);
  virtual void onError(ota_error_t error);
};

// -----------------------------------------------------------------------------
// OTA info via OLED Display
// -----------------------------------------------------------------------------

class OtaDisplay : public OtaLogger {
private:
  OLEDDisplay *_display;
protected:
public:
  OtaDisplay(OLEDDisplay *display);

  void setup(uint16_t port = 8266, const char *password = "") override;

  void onEnd();
  void onProgress(unsigned int progress, unsigned int total) override;
};

#endif /* end of include guard: SRC_OTA_H */
<commit_msg>Move the on* Event handlers into the protected section<commit_after>/*
 * OtaLogger.hpp
 * Wraps ArduinoOTA into a class and shows the OTA
 * status on serial or an OLED display.
 *
 * Version: 1.0
 * Author: Lübbe Onken (http://github.com/luebbe)
 */

#ifndef SRC_OTA_H
#define SRC_OTA_H

#include <Homie.h>       // used for logger output
#include <OLEDDisplay.h> // used for display output
#include <ArduinoOTA.h>

// -----------------------------------------------------------------------------
// OTA info via Homie logger
// -----------------------------------------------------------------------------

class OtaLogger {
private:
protected:
  String getErrorMessage(ota_error_t error);

  virtual void onStart();
  virtual void onEnd();
  virtual void onProgress(unsigned int progress, unsigned int total);
  virtual void onError(ota_error_t error);
public:
  OtaLogger();

  virtual void setup(uint16_t port = 8266, const char *password = "");
  virtual void loop();
};

// -----------------------------------------------------------------------------
// OTA info via OLED Display
// -----------------------------------------------------------------------------

class OtaDisplay : public OtaLogger {
private:
  OLEDDisplay *_display;
protected:
  void onEnd();
  void onProgress(unsigned int progress, unsigned int total) override;
public:
  OtaDisplay(OLEDDisplay *display);

  void setup(uint16_t port = 8266, const char *password = "") override;
};

#endif /* end of include guard: SRC_OTA_H */
<|endoftext|>


<commit_before>#include "pjobrunnernetworkscanner.h"
#include <QtNetwork>
#include "pjobrunnersessionwrapper.h"
#include <iostream>

QList<PJobRunnerSessionWrapper*> PJobRunnerNetworkScanner::s_found_sessions;
bool PJobRunnerNetworkScanner::s_blocking_scan = false;

PJobRunnerNetworkScanner::PJobRunnerNetworkScanner()
    : m_port(23023)
{
    qRegisterMetaType<QHostAddress>("QHostAddress");
}

void PJobRunnerNetworkScanner::run(){
    scan();
}

QList<PJobRunnerSessionWrapper*> PJobRunnerNetworkScanner::do_blocking_scan(){
    s_found_sessions.clear();
    s_blocking_scan = true;
    PJobRunnerNetworkScanner scanner;
    scanner.scan();
    s_blocking_scan = false;
    return s_found_sessions;
}

void PJobRunnerNetworkScanner::scan(){
    foreach(const QNetworkInterface& interface, QNetworkInterface::allInterfaces()){
        foreach(const QNetworkAddressEntry& address_entry, interface.addressEntries()){
            quint32 netmask = address_entry.netmask().toIPv4Address();
            quint32 local_ip = address_entry.ip().toIPv4Address();
            quint32 address_to_try = (local_ip & netmask) + 1;
            //quint32 inv_netmask = ~netmask;

            if(interface.humanReadableName() == "lo"){
                std::cout << "Skipping interface \"lo\"." << std::endl;
                continue;
            }

            if(!interface.isValid()){
                std::cout << "Skipping interface \"" << interface.humanReadableName().toStdString() << "\"." << std::endl;
                continue;
            }

            if(address_entry.ip().protocol() != QAbstractSocket::IPv4Protocol){
                std::cout << "Skipping non-IPv4 interface." << std::endl;
                continue;
            }

            std::cout << "Probing interface " << interface.humanReadableName().toStdString() << std::endl;
            std::cout << "Local address is " << interface.hardwareAddress().toStdString() << std::endl;
            std::cout << "Netmask: " << address_entry.netmask().toString().toStdString() << std::endl;
            std::cout << "Searching local network..." << std::endl;
            while((address_to_try & netmask) == (local_ip & netmask)){
                std::cout << "\r" << QHostAddress(address_to_try).toString().toStdString();
                std::cout.flush();
                emit probing_host(QHostAddress(address_to_try));
                PJobRunnerSessionWrapper* session = new PJobRunnerSessionWrapper(QHostAddress(address_to_try), 200);
                if(session->is_valid()) found(session);
                else delete session;
                address_to_try++;
            }
        }
    }
    emit finished_scanning();
}

void PJobRunnerNetworkScanner::found(PJobRunnerSessionWrapper* session){
    emit found_pjob_runner(session);
    if(s_blocking_scan){
        s_found_sessions.append(session);
        std::cout << "Found PJobRunner on " << session->peer().toString().toStdString() << "!" << std::endl;
    }
}
<commit_msg>PJobClient network scanner: omit localhost interface.<commit_after>#include "pjobrunnernetworkscanner.h"
#include <QtNetwork>
#include "pjobrunnersessionwrapper.h"
#include <iostream>

QList<PJobRunnerSessionWrapper*> PJobRunnerNetworkScanner::s_found_sessions;
bool PJobRunnerNetworkScanner::s_blocking_scan = false;

PJobRunnerNetworkScanner::PJobRunnerNetworkScanner()
    : m_port(23023)
{
    qRegisterMetaType<QHostAddress>("QHostAddress");
}

void PJobRunnerNetworkScanner::run(){
    scan();
}

QList<PJobRunnerSessionWrapper*> PJobRunnerNetworkScanner::do_blocking_scan(){
    s_found_sessions.clear();
    s_blocking_scan = true;
    PJobRunnerNetworkScanner scanner;
    scanner.scan();
    s_blocking_scan = false;
    return s_found_sessions;
}

void PJobRunnerNetworkScanner::scan(){
    foreach(const QNetworkInterface& interface, QNetworkInterface::allInterfaces()){
        foreach(const QNetworkAddressEntry& address_entry, interface.addressEntries()){
            quint32 netmask = address_entry.netmask().toIPv4Address();
            quint32 local_ip = address_entry.ip().toIPv4Address();
            quint32 address_to_try = (local_ip & netmask) + 1;
            //quint32 inv_netmask = ~netmask;

            if(interface.humanReadableName() == "lo"){
                std::cout << "Skipping interface \"lo\"." << std::endl;
                continue;
            }

            if(!interface.isValid()){
                std::cout << "Skipping interface \"" << interface.humanReadableName().toStdString() << "\"." << std::endl;
                continue;
            }

            if(address_entry.ip().protocol() != QAbstractSocket::IPv4Protocol){
                std::cout << "Skipping non-IPv4 interface." << std::endl;
                continue;
            }

            if(address_entry.ip() == QHostAddress::LocalHost){
                std::cout << "Skipping loopback interface." << std::endl;
                continue;
            }

            std::cout << "Probing interface " << interface.humanReadableName().toStdString() << std::endl;
            std::cout << "Local address is " << interface.hardwareAddress().toStdString() << std::endl;
            std::cout << "Netmask: " << address_entry.netmask().toString().toStdString() << std::endl;
            std::cout << "Searching local network..." << std::endl;
            while((address_to_try & netmask) == (local_ip & netmask)){
                std::cout << "\r" << QHostAddress(address_to_try).toString().toStdString();
                std::cout.flush();
                emit probing_host(QHostAddress(address_to_try));
                PJobRunnerSessionWrapper* session = new PJobRunnerSessionWrapper(QHostAddress(address_to_try), 200);
                if(session->is_valid()) found(session);
                else delete session;
                address_to_try++;
            }
        }
    }
    emit finished_scanning();
}

void PJobRunnerNetworkScanner::found(PJobRunnerSessionWrapper* session){
    emit found_pjob_runner(session);
    if(s_blocking_scan){
        s_found_sessions.append(session);
        std::cout << "Found PJobRunner on " << session->peer().toString().toStdString() << "!" << std::endl;
    }
}
<|endoftext|>


<commit_before>#include "pjobrunnersessionwrapper.h"
#include <QtCore/QRegExp>
#include <iostream>

PJobRunnerSessionWrapper::PJobRunnerSessionWrapper(QHostAddress hostname, long timeout)
    : m_peer(hostname)
{
    m_valid = false;
    m_socket.connectToHost(hostname, 23023);
    if(!m_socket.waitForConnected(timeout)) return;
    send("hello\n");
    if(!m_socket.waitForBytesWritten(10000)) return;
    if(!m_socket.waitForReadyRead(10000)) return;
    QString hello_string;
    do{
        hello_string.append(m_socket.readAll());
    }while(m_socket.waitForReadyRead(1000) && hello_string.size() < 1024);
    received(hello_string);

    if(hello_string.isEmpty()) return;

    QRegExp reg_exp("This is ([^\\s]*) \\(.*\\) version ([^\\s]*) running on ([^\\s]*) \\(([^\\s]*)\\)");

    if(reg_exp.indexIn(hello_string) == -1) return;
    m_version = reg_exp.cap(2);
    m_platform = reg_exp.cap(4);
    m_hostname = reg_exp.cap(3);
    m_valid = true;
}

PJobRunnerSessionWrapper::~PJobRunnerSessionWrapper(){
    if(m_socket.state() == QAbstractSocket::ConnectedState){
        send("exit()");
        m_socket.waitForBytesWritten(100);
        m_socket.close();
        m_socket.waitForDisconnected(1000);
    }
}

bool PJobRunnerSessionWrapper::is_valid(){
    return m_valid;
}

QString PJobRunnerSessionWrapper::platform(){
    return m_platform;
}

QString PJobRunnerSessionWrapper::version(){
    return m_version;
}

QString PJobRunnerSessionWrapper::hostname(){
    return m_hostname;
}

bool PJobRunnerSessionWrapper::upload_pjobfile(const QByteArray& content){
    send("prepare_push_connection()\n");
    if(!m_socket.waitForReadyRead(10000))return false;
    QString line = m_socket.readLine();
    received(line);
    quint32 port = line.toInt();

    std::cout << "Opening data connection to port " << port << "... ";
    QTcpSocket push_connection;
    push_connection.connectToHost(m_socket.peerAddress(), port);
    if(!push_connection.waitForConnected(10000))return false;
    std::cout << " done!" << std::endl;

    qint64 bytes_send = 0;
    qint64 all_bytes = content.size();
    const char* data = content.data();
    qint64 transfer_unit_size = 1024;

    while(bytes_send != all_bytes){
        qint64 bytes_written = push_connection.write(data, std::min(transfer_unit_size,all_bytes-bytes_send));
        data += bytes_written;
        bytes_send += bytes_written;
        push_connection.flush();
        push_connection.waitForBytesWritten();
        std::cout << "\r" << bytes_send * 100 / all_bytes << "% done...              ";
    }
    std::cout << std::endl;
    push_connection.close();
    push_connection.waitForDisconnected(10000);
    std::cout << content.size() << " bytes uploaded!" << std::endl;
    return true;
}

bool PJobRunnerSessionWrapper::download_results(QByteArray& data){
    send("prepare_pull_connection_for_results()\n");
    if(!m_socket.waitForReadyRead(10000)) exit(0);
    QString line = m_socket.readLine();
    received(line);
    QString all = m_socket.readAll();
    received(all);
    quint32 port = line.toInt();
    std::cout << " from port " << port << "...";
    QTcpSocket pull_connection;
    pull_connection.connectToHost(m_socket.peerAddress(), port);
    if(!pull_connection.waitForConnected(10000)) exit(0);
    if(!pull_connection.waitForReadyRead(10000)) exit(0);

    while(true){
        if(pull_connection.state() == QTcpSocket::UnconnectedState){
            while(pull_connection.bytesAvailable())
                data.append(pull_connection.readAll());
            break;
        }
        if(pull_connection.waitForReadyRead(10)){
            data.append(pull_connection.readAll());
        }
    }
    return true;
}

bool PJobRunnerSessionWrapper::set_parameter(const QString& name, const double& value){
    return false;
}

bool PJobRunnerSessionWrapper::run_job(){
    send("open_pjob_from_received_data()\n");
    if(!m_socket.waitForReadyRead(10000))exit(0);
    send("run_job()\n");
    bool ok=false;
    bool want_exit=false;
    while(!want_exit){
        if(!m_socket.waitForReadyRead(10)) continue;
        QString line = m_socket.readAll();
        received(line);
        if(line.contains("Process exited normally.")){ ok = true; want_exit = true; }
        if(line.contains("Process crashed!")) want_exit = true;
        std::cout << line.toStdString() << std::endl;
    }

    while(m_socket.waitForReadyRead(1000)){
        received(m_socket.readAll());
    }
    std::cout << std::endl;

    return ok;
}

bool PJobRunnerSessionWrapper::wait_for_job_finished(){
    return false;
}

QHostAddress PJobRunnerSessionWrapper::peer(){
    return m_peer;
}

bool PJobRunnerSessionWrapper::enqueue(){
    send("enqueue();\n");
    if(!m_socket.waitForReadyRead(10000)) return false;
    QString line = m_socket.readAll();
    received(line);
    if(line.contains("Successfully added to queue.")) return true;
    else return false;
}

bool PJobRunnerSessionWrapper::wait_till_its_your_turn(){
    QString buffer;
    while(m_socket.isReadable()){
        if(m_socket.waitForReadyRead(5000)){
            QByteArray read = m_socket.readAll();
            buffer.append(read);
            received(read);
            if(buffer.contains("It's your turn now! Go!")) return true;
        }
    }
    return false;
}

int PJobRunnerSessionWrapper::max_process_count(){
    send("max_process_count();\n");
    if(!m_socket.waitForReadyRead(10000)) throw QString("connection timeout");
    bool ok;
    QString line = m_socket.readAll();
    received(line);
    int value = line.toInt(&ok);
    if(ok) return value;
    else throw QString("connection problem");
}

int PJobRunnerSessionWrapper::process_count(){
    send("process_count();\n");
    if(!m_socket.waitForReadyRead(10000)) throw QString("connection timeout");
    bool ok;
    QString line = m_socket.readAll();
    received(line);
    int value = line.toInt(&ok);
    if(ok) return value;
    else throw QString("connection problem");
}

void PJobRunnerSessionWrapper::set_debug(bool b){
    m_debug_mode = b;
}

void PJobRunnerSessionWrapper::send(const QString& data){
    m_socket.write(data.toUtf8());
    if(m_debug_mode) emit debug_out(QString("to %2 >>> %1").arg(data).arg(m_peer.toString()));
}

void PJobRunnerSessionWrapper::received(const QString& data){
    if(m_debug_mode) emit debug_out(QString("from %2 <<< %1").arg(data).arg(m_peer.toString()));
}
<commit_msg>PJobClient: run_job() and wait_for_job_finished() fixed.<commit_after>#include "pjobrunnersessionwrapper.h"
#include <QtCore/QRegExp>
#include <iostream>

PJobRunnerSessionWrapper::PJobRunnerSessionWrapper(QHostAddress hostname, long timeout)
    : m_peer(hostname)
{
    m_valid = false;
    m_socket.connectToHost(hostname, 23023);
    if(!m_socket.waitForConnected(timeout)) return;
    send("hello\n");
    if(!m_socket.waitForBytesWritten(10000)) return;
    if(!m_socket.waitForReadyRead(10000)) return;
    QString hello_string;
    do{
        hello_string.append(m_socket.readAll());
    }while(m_socket.waitForReadyRead(1000) && hello_string.size() < 1024);
    received(hello_string);

    if(hello_string.isEmpty()) return;

    QRegExp reg_exp("This is ([^\\s]*) \\(.*\\) version ([^\\s]*) running on ([^\\s]*) \\(([^\\s]*)\\)");

    if(reg_exp.indexIn(hello_string) == -1) return;
    m_version = reg_exp.cap(2);
    m_platform = reg_exp.cap(4);
    m_hostname = reg_exp.cap(3);
    m_valid = true;
}

PJobRunnerSessionWrapper::~PJobRunnerSessionWrapper(){
    if(m_socket.state() == QAbstractSocket::ConnectedState){
        send("exit()");
        m_socket.waitForBytesWritten(100);
        m_socket.close();
        m_socket.waitForDisconnected(1000);
    }
}

bool PJobRunnerSessionWrapper::is_valid(){
    return m_valid;
}

QString PJobRunnerSessionWrapper::platform(){
    return m_platform;
}

QString PJobRunnerSessionWrapper::version(){
    return m_version;
}

QString PJobRunnerSessionWrapper::hostname(){
    return m_hostname;
}

bool PJobRunnerSessionWrapper::upload_pjobfile(const QByteArray& content){
    send("prepare_push_connection()\n");
    if(!m_socket.waitForReadyRead(10000))return false;
    QString line = m_socket.readLine();
    received(line);
    quint32 port = line.toInt();

    std::cout << "Opening data connection to port " << port << "... ";
    QTcpSocket push_connection;
    push_connection.connectToHost(m_socket.peerAddress(), port);
    if(!push_connection.waitForConnected(10000))return false;
    std::cout << " done!" << std::endl;

    qint64 bytes_send = 0;
    qint64 all_bytes = content.size();
    const char* data = content.data();
    qint64 transfer_unit_size = 1024;

    while(bytes_send != all_bytes){
        qint64 bytes_written = push_connection.write(data, std::min(transfer_unit_size,all_bytes-bytes_send));
        data += bytes_written;
        bytes_send += bytes_written;
        push_connection.flush();
        push_connection.waitForBytesWritten();
        std::cout << "\r" << bytes_send * 100 / all_bytes << "% done...              ";
    }
    std::cout << std::endl;
    push_connection.close();
    push_connection.waitForDisconnected(10000);
    std::cout << content.size() << " bytes uploaded!" << std::endl;
    return true;
}

bool PJobRunnerSessionWrapper::download_results(QByteArray& data){
    send("prepare_pull_connection_for_results()\n");
    if(!m_socket.waitForReadyRead(10000)) exit(0);
    QString line = m_socket.readLine();
    received(line);
    QString all = m_socket.readAll();
    received(all);
    quint32 port = line.toInt();
    std::cout << " from port " << port << "...";
    QTcpSocket pull_connection;
    pull_connection.connectToHost(m_socket.peerAddress(), port);
    if(!pull_connection.waitForConnected(10000)) exit(0);
    if(!pull_connection.waitForReadyRead(10000)) exit(0);

    while(true){
        if(pull_connection.state() == QTcpSocket::UnconnectedState){
            while(pull_connection.bytesAvailable())
                data.append(pull_connection.readAll());
            break;
        }
        if(pull_connection.waitForReadyRead(10)){
            data.append(pull_connection.readAll());
        }
    }
    return true;
}

bool PJobRunnerSessionWrapper::set_parameter(const QString& name, const double& value){
    return false;
}

bool PJobRunnerSessionWrapper::run_job(){
    send("open_pjob_from_received_data()\n");
    if(!m_socket.waitForReadyRead(10000))exit(0);
    send("run_job()\n");
    if(!m_socket.waitForReadyRead(10000)) return false;

    while(m_socket.waitForReadyRead(1000) && m_socket.state() == QTcpSocket::ConnectedState){
        QString line = m_socket.readAll();
        received(line);
        if(line.contains("Starting process:")) return true;
        if(line.contains("Starting process:")) return true;
        if(line.contains("Can't")) return false;
    }
    return false;
}

bool PJobRunnerSessionWrapper::wait_for_job_finished(){
    bool ok=false;
    bool want_exit=false;
    while(!want_exit && m_socket.state() == QTcpSocket::ConnectedState){
        if(!m_socket.waitForReadyRead(10)) continue;
        QString line = m_socket.readAll();
        received(line);
        if(line.contains("Process exited normally.")){ ok = true; want_exit = true; }
        if(line.contains("Process crashed!")) want_exit = true;
    }
    while(m_socket.waitForReadyRead(1000)){
        received(m_socket.readAll());
    }
    return ok;
}

QHostAddress PJobRunnerSessionWrapper::peer(){
    return m_peer;
}

bool PJobRunnerSessionWrapper::enqueue(){
    send("enqueue();\n");
    if(!m_socket.waitForReadyRead(10000)) return false;
    QString line = m_socket.readAll();
    received(line);
    if(line.contains("Successfully added to queue.")) return true;
    else return false;
}

bool PJobRunnerSessionWrapper::wait_till_its_your_turn(){
    QString buffer;
    while(m_socket.isReadable()){
        if(m_socket.waitForReadyRead(5000)){
            QByteArray read = m_socket.readAll();
            buffer.append(read);
            received(read);
            if(buffer.contains("It's your turn now! Go!")) return true;
        }
    }
    return false;
}

int PJobRunnerSessionWrapper::max_process_count(){
    send("max_process_count();\n");
    if(!m_socket.waitForReadyRead(10000)) throw QString("connection timeout");
    bool ok;
    QString line = m_socket.readAll();
    received(line);
    int value = line.toInt(&ok);
    if(ok) return value;
    else throw QString("connection problem");
}

int PJobRunnerSessionWrapper::process_count(){
    send("process_count();\n");
    if(!m_socket.waitForReadyRead(10000)) throw QString("connection timeout");
    bool ok;
    QString line = m_socket.readAll();
    received(line);
    int value = line.toInt(&ok);
    if(ok) return value;
    else throw QString("connection problem");
}

void PJobRunnerSessionWrapper::set_debug(bool b){
    m_debug_mode = b;
}

void PJobRunnerSessionWrapper::send(const QString& data){
    m_socket.write(data.toUtf8());
    if(m_debug_mode) emit debug_out(QString("to %2 >>> %1").arg(data).arg(m_peer.toString()));
}

void PJobRunnerSessionWrapper::received(const QString& data){
    if(m_debug_mode) emit debug_out(QString("from %2 <<< %1").arg(data).arg(m_peer.toString()));
}
<|endoftext|>


<commit_before>#include "musicdownloadquerymgartistthread.h"
#include "musicnumberutils.h"
#///QJson import
#include "qjson/parser.h"

MusicDownLoadQueryMGArtistThread::MusicDownLoadQueryMGArtistThread(QObject *parent)
    : MusicDownLoadQueryArtistThread(parent)
{
    m_queryServer = "Migu";
}

QString MusicDownLoadQueryMGArtistThread::getClassName()
{
    return staticMetaObject.className();
}

void MusicDownLoadQueryMGArtistThread::startToSearch(const QString &artist)
{
    if(!m_manager)
    {
        return;
    }

    M_LOGGER_INFO(QString("%1 startToSearch %2").arg(getClassName()).arg(artist));
    QUrl musicUrl = MusicUtils::Algorithm::mdII(MG_ARTIST_URL, false).arg(artist);
    deleteAll();
    m_interrupt = true;
    m_searchText = artist;
qDebug() << musicUrl;
    QNetworkRequest request;
    request.setUrl(musicUrl);
    request.setRawHeader("Content-Type", "application/x-www-form-urlencoded");
    request.setRawHeader("User-Agent", MusicUtils::Algorithm::mdII(MG_UA_URL_1, ALG_UA_KEY, false).toUtf8());
#ifndef QT_NO_SSL
    QSslConfiguration sslConfig = request.sslConfiguration();
    sslConfig.setPeerVerifyMode(QSslSocket::VerifyNone);
    request.setSslConfiguration(sslConfig);
#endif
    m_reply = m_manager->get(request);
    connect(m_reply, SIGNAL(finished()), SLOT(downLoadFinished()));
    connect(m_reply, SIGNAL(error(QNetworkReply::NetworkError)), SLOT(replyError(QNetworkReply::NetworkError)));
}

void MusicDownLoadQueryMGArtistThread::downLoadFinished()
{
    if(!m_reply || !m_manager)
    {
        deleteAll();
        return;
    }

    M_LOGGER_INFO(QString("%1 downLoadFinished").arg(getClassName()));
    emit clearAllItems();      ///Clear origin items
    m_musicSongInfos.clear();  ///Empty the last search to songsInfo
    m_interrupt = false;

    if(m_reply->error() == QNetworkReply::NoError)
    {
        QByteArray bytes = m_reply->readAll(); ///Get all the data obtained by request

        QJson::Parser parser;
        bool ok;
        QVariant data = parser.parse(bytes, &ok);
        if(ok)
        {
            QVariantMap value = data.toMap();
            if(value["code"].toString() == "000000" && value.contains("songs"))
            {
                bool artistFlag = false;
                QString description = value["detail"].toString();
                ////////////////////////////////////////////////////////////
                QVariantList datas = value["songs"].toList();
                foreach(const QVariant &var, datas)
                {
                    if(var.isNull())
                    {
                        continue;
                    }

                    value = var.toMap();
                    MusicObject::MusicSongInformation musicInfo;
                    musicInfo.m_singerName = value["singer"].toString();
                    musicInfo.m_songName = value["title"].toString();
                    musicInfo.m_timeLength = "-";

                    musicInfo.m_songId = value["contentid"].toString();
                    musicInfo.m_artistId = value["singerid"].toString();
                    musicInfo.m_albumId = value["albumid"].toString();

                    musicInfo.m_lrcUrl = MusicUtils::Algorithm::mdII(MG_SONG_LRC_URL, false).arg(musicInfo.m_songId);
                    musicInfo.m_smallPicUrl = value["albumImg"].toString();
                    musicInfo.m_albumName = value["album"].toString();

                    if(m_interrupt || !m_manager || m_stateCode != MusicNetworkAbstract::Init) return;
                    readFromMusicSongAttribute(&musicInfo, value, m_searchQuality, true);
                    if(m_interrupt || !m_manager || m_stateCode != MusicNetworkAbstract::Init) return;

                    if(musicInfo.m_songAttrs.isEmpty())
                    {
                        continue;
                    }
                    ////////////////////////////////////////////////////////////
                    if(!findUrlFileSize(&musicInfo.m_songAttrs)) return;
                    ////////////////////////////////////////////////////////////
                    if(!artistFlag)
                    {
                        artistFlag = true;
                        MusicPlaylistItem info;
                        info.m_description = description;
                        info.m_id = m_searchText;
                        info.m_name = musicInfo.m_singerName;
                        info.m_coverUrl = musicInfo.m_smallPicUrl;
                        emit createArtistInfoItem(info);
                    }
                    ////////////////////////////////////////////////////////////
                    MusicSearchedItem item;
                    item.m_songName = musicInfo.m_songName;
                    item.m_singerName = musicInfo.m_singerName;
                    item.m_albumName = musicInfo.m_albumName;
                    item.m_time = musicInfo.m_timeLength;
                    item.m_type = mapQueryServerString();
                    emit createSearchedItems(item);
                    m_musicSongInfos << musicInfo;
                }
            }
        }
    }

    emit downLoadDataChanged(QString());
    deleteAll();
    M_LOGGER_INFO(QString("%1 downLoadFinished deleteAll").arg(getClassName()));
}
<commit_msg>Clean code[548321]<commit_after>#include "musicdownloadquerymgartistthread.h"
#include "musicnumberutils.h"
#///QJson import
#include "qjson/parser.h"

MusicDownLoadQueryMGArtistThread::MusicDownLoadQueryMGArtistThread(QObject *parent)
    : MusicDownLoadQueryArtistThread(parent)
{
    m_queryServer = "Migu";
}

QString MusicDownLoadQueryMGArtistThread::getClassName()
{
    return staticMetaObject.className();
}

void MusicDownLoadQueryMGArtistThread::startToSearch(const QString &artist)
{
    if(!m_manager)
    {
        return;
    }

    M_LOGGER_INFO(QString("%1 startToSearch %2").arg(getClassName()).arg(artist));
    QUrl musicUrl = MusicUtils::Algorithm::mdII(MG_ARTIST_URL, false).arg(artist);
    deleteAll();
    m_interrupt = true;
    m_searchText = artist;

    QNetworkRequest request;
    request.setUrl(musicUrl);
    request.setRawHeader("Content-Type", "application/x-www-form-urlencoded");
    request.setRawHeader("User-Agent", MusicUtils::Algorithm::mdII(MG_UA_URL_1, ALG_UA_KEY, false).toUtf8());
#ifndef QT_NO_SSL
    QSslConfiguration sslConfig = request.sslConfiguration();
    sslConfig.setPeerVerifyMode(QSslSocket::VerifyNone);
    request.setSslConfiguration(sslConfig);
#endif
    m_reply = m_manager->get(request);
    connect(m_reply, SIGNAL(finished()), SLOT(downLoadFinished()));
    connect(m_reply, SIGNAL(error(QNetworkReply::NetworkError)), SLOT(replyError(QNetworkReply::NetworkError)));
}

void MusicDownLoadQueryMGArtistThread::downLoadFinished()
{
    if(!m_reply || !m_manager)
    {
        deleteAll();
        return;
    }

    M_LOGGER_INFO(QString("%1 downLoadFinished").arg(getClassName()));
    emit clearAllItems();      ///Clear origin items
    m_musicSongInfos.clear();  ///Empty the last search to songsInfo
    m_interrupt = false;

    if(m_reply->error() == QNetworkReply::NoError)
    {
        QByteArray bytes = m_reply->readAll(); ///Get all the data obtained by request

        QJson::Parser parser;
        bool ok;
        QVariant data = parser.parse(bytes, &ok);
        if(ok)
        {
            QVariantMap value = data.toMap();
            if(value["code"].toString() == "000000" && value.contains("songs"))
            {
                bool artistFlag = false;
                QString description = value["detail"].toString();
                ////////////////////////////////////////////////////////////
                QVariantList datas = value["songs"].toList();
                foreach(const QVariant &var, datas)
                {
                    if(var.isNull())
                    {
                        continue;
                    }

                    value = var.toMap();
                    MusicObject::MusicSongInformation musicInfo;
                    musicInfo.m_singerName = value["singer"].toString();
                    musicInfo.m_songName = value["title"].toString();
                    musicInfo.m_timeLength = "-";

                    musicInfo.m_songId = value["contentid"].toString();
                    musicInfo.m_artistId = value["singerid"].toString();
                    musicInfo.m_albumId = value["albumid"].toString();

                    musicInfo.m_lrcUrl = MusicUtils::Algorithm::mdII(MG_SONG_LRC_URL, false).arg(musicInfo.m_songId);
                    musicInfo.m_smallPicUrl = value["albumImg"].toString();
                    musicInfo.m_albumName = value["album"].toString();

                    if(m_interrupt || !m_manager || m_stateCode != MusicNetworkAbstract::Init) return;
                    readFromMusicSongAttribute(&musicInfo, value, m_searchQuality, true);
                    if(m_interrupt || !m_manager || m_stateCode != MusicNetworkAbstract::Init) return;

                    if(musicInfo.m_songAttrs.isEmpty())
                    {
                        continue;
                    }
                    ////////////////////////////////////////////////////////////
                    if(!findUrlFileSize(&musicInfo.m_songAttrs)) return;
                    ////////////////////////////////////////////////////////////
                    if(!artistFlag)
                    {
                        artistFlag = true;
                        MusicPlaylistItem info;
                        info.m_description = description;
                        info.m_id = m_searchText;
                        info.m_name = musicInfo.m_singerName;
                        info.m_coverUrl = musicInfo.m_smallPicUrl;
                        emit createArtistInfoItem(info);
                    }
                    ////////////////////////////////////////////////////////////
                    MusicSearchedItem item;
                    item.m_songName = musicInfo.m_songName;
                    item.m_singerName = musicInfo.m_singerName;
                    item.m_albumName = musicInfo.m_albumName;
                    item.m_time = musicInfo.m_timeLength;
                    item.m_type = mapQueryServerString();
                    emit createSearchedItems(item);
                    m_musicSongInfos << musicInfo;
                }
            }
        }
    }

    emit downLoadDataChanged(QString());
    deleteAll();
    M_LOGGER_INFO(QString("%1 downLoadFinished deleteAll").arg(getClassName()));
}
<|endoftext|>