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

#ifndef __LISTEN_123456__
#define __LISTEN_123456__

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

template <class XX>
class List
{
  public :
    typedef XX *        iterator;
    typedef const XX *  const_iterator;

    // LIFECYCLE
                        List();
    virtual             ~List() { }

    // OPERATORS
    const XX &          operator[](
                            unsigned            n) const
                                                { return elem(n); }
    XX &                operator[](
                            unsigned            n)
                                                { return elem(n); }
    // OPERATIONS
    void                reserve(
                            unsigned            i_nSize )
                                                { alloc(i_nSize,true); }
    virtual void        insert(
                            unsigned            pos,
                            const XX &          elem );
    void                push_back(
                            const XX &          elem)
                                                { insert(size(),elem); }

    virtual void        remove(
                            unsigned            pos );
    void                pop_back()              { remove(size()-1); }
    void                erase_all()             { while (size()) remove(size()-1); }

    // INQUIRY
    const XX &          front() const           { return elem(0); }
    const XX &          back() const            { return elem(len-1); }

    unsigned            size() const            { return len; }
    unsigned            space() const           { return allocated; }
    bool                is_valid_index(
                            unsigned            n) const
                                                { return n < len; }
    // ACCESS
    XX &                front()                 { return elem(0); }
    XX &                back()                  { return elem(len-1); }

  protected:
    void                checkSize(
                            unsigned            newLength);
    void                alloc(
                            unsigned            newSpace,
                            bool                re = false );

    const XX &          elem(
                            unsigned            n ) const
                                                { return inhalt[n]; }
    XX &                elem(
                            unsigned            n )
                                                { return inhalt[n]; }
  // DATA
    XX *                inhalt;
    unsigned            len;
    unsigned            allocated;

  private:
    // forbidden functions
                        List(const List<XX> & L);
    List<XX> &          operator=(
                            const List<XX> &    L);

};

template <class XY>
class DynamicList : public List<XY*>
{
  public:
    virtual             ~DynamicList();

    virtual void        insert(
                            unsigned            pos,
                            XY * const &        elem );
    virtual void        remove(
                            unsigned            pos );
};

template <class XX>
List<XX>::List()
    :   inhalt(0),
        len(0),
        allocated(0)

{
    alloc(1);
}

template <class XX>
void
List<XX>::insert(unsigned pos, const XX & elem)
{
    if ( pos > len )
      return;

    checkSize(len+2);
    for ( unsigned p = len; p > pos; --p)
    {
        inhalt[p] = inhalt[p-1];
    }
    inhalt[pos] = elem;
    len++;
}

template <class XX>
void
List<XX>::remove(unsigned pos)
{
    if ( pos >= len )
      return;
    len--;
    for ( unsigned p = pos; p < len; ++p)
    {
        inhalt[p] = inhalt[p+1];
    }
}

// Protected:
template <class XX>
void
List<XX>::checkSize(unsigned newLength)
{
   // neuen Platzbedarf pruefen:
   unsigned newSpace = space();
   if (newLength > newSpace)
   {
      if (!newSpace)
         newSpace = 1;
      const unsigned nBorder = 65536 / 2;
      while(newLength > newSpace)
      {
        if (newSpace < nBorder)
            newSpace <<= 1;
        else
        {
            std::cerr << "List becomes too big" << std::endl;
            exit(1);
        }
      }
   }

   // Veraenderung ?:
   if (newSpace != space())
      alloc(newSpace,true);
}

template <class XX>
void
List<XX>::alloc( unsigned           newSpace,
                 bool               re )
{
    XX * pNew = new XX[newSpace];

    if (inhalt != 0)
    {
        if (re)
        {
            for (unsigned i = 0; i < len; ++i)
            {
                pNew[i] = inhalt[i];
            }  // end for
        }
        delete [] inhalt;
    }

    inhalt = pNew;
    allocated = newSpace;
}

template <class XY>
DynamicList<XY>::~DynamicList()
{
    this->erase_all();
}

template <class XY>
void
DynamicList<XY>::insert(unsigned pos, XY * const & elem)
{
    if ( pos > this->len )
      return;

    checkSize(this->len+2);
    memmove(this->inhalt[pos+1], this->inhalt[pos], (this->len-pos) * sizeof(XY*) );
    this->inhalt[pos] = elem;
    this->len++;
}

template <class XY>
void
DynamicList<XY>::remove( unsigned           pos )
{
    if (!this->is_valid_index(pos) )
        return;
    this->len--;
    delete this->inhalt[pos];
    memmove(this->inhalt[pos], this->inhalt[pos+1], (this->len-pos) * sizeof(XY*) );
}

#endif

<commit_msg>INTEGRATION: CWS warnings01 (1.8.4); FILE MERGED 2005/11/07 12:10:03 sb 1.8.4.1: #i53898# Made code warning-free (additional -W switches for GCC).<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: list.hxx,v $
 *
 *  $Revision: 1.9 $
 *
 *  last change: $Author: hr $ $Date: 2006-06-19 20:04:23 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef __LISTEN_123456__
#define __LISTEN_123456__

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

template <class XX>
class List
{
  public :
    typedef XX *        iterator;
    typedef const XX *  const_iterator;

    // LIFECYCLE
                        List();
    virtual             ~List() { }

    // OPERATORS
    const XX &          operator[](
                            unsigned            n) const
                                                { return elem(n); }
    XX &                operator[](
                            unsigned            n)
                                                { return elem(n); }
    // OPERATIONS
    void                reserve(
                            unsigned            i_nSize )
                                                { alloc(i_nSize,true); }
    virtual void        insert(
                            unsigned            pos,
                            const XX &          elem );
    void                push_back(
                            const XX &          elem_)
                                                { insert(size(),elem_); }

    virtual void        remove(
                            unsigned            pos );
    void                pop_back()              { remove(size()-1); }
    void                erase_all()             { while (size()) remove(size()-1); }

    // INQUIRY
    const XX &          front() const           { return elem(0); }
    const XX &          back() const            { return elem(len-1); }

    unsigned            size() const            { return len; }
    unsigned            space() const           { return allocated; }
    bool                is_valid_index(
                            unsigned            n) const
                                                { return n < len; }
    // ACCESS
    XX &                front()                 { return elem(0); }
    XX &                back()                  { return elem(len-1); }

  protected:
    void                checkSize(
                            unsigned            newLength);
    void                alloc(
                            unsigned            newSpace,
                            bool                re = false );

    const XX &          elem(
                            unsigned            n ) const
                                                { return inhalt[n]; }
    XX &                elem(
                            unsigned            n )
                                                { return inhalt[n]; }
  // DATA
    XX *                inhalt;
    unsigned            len;
    unsigned            allocated;

  private:
    // forbidden functions
                        List(const List<XX> & L);
    List<XX> &          operator=(
                            const List<XX> &    L);

};

template <class XY>
class DynamicList : public List<XY*>
{
  public:
    virtual             ~DynamicList();

    virtual void        insert(
                            unsigned            pos,
                            XY * const &        elem );
    virtual void        remove(
                            unsigned            pos );
};

template <class XX>
List<XX>::List()
    :   inhalt(0),
        len(0),
        allocated(0)

{
    alloc(1);
}

template <class XX>
void
List<XX>::insert(unsigned pos, const XX & elem_)
{
    if ( pos > len )
      return;

    checkSize(len+2);
    for ( unsigned p = len; p > pos; --p)
    {
        inhalt[p] = inhalt[p-1];
    }
    inhalt[pos] = elem_;
    len++;
}

template <class XX>
void
List<XX>::remove(unsigned pos)
{
    if ( pos >= len )
      return;
    len--;
    for ( unsigned p = pos; p < len; ++p)
    {
        inhalt[p] = inhalt[p+1];
    }
}

// Protected:
template <class XX>
void
List<XX>::checkSize(unsigned newLength)
{
   // neuen Platzbedarf pruefen:
   unsigned newSpace = space();
   if (newLength > newSpace)
   {
      if (!newSpace)
         newSpace = 1;
      const unsigned nBorder = 65536 / 2;
      while(newLength > newSpace)
      {
        if (newSpace < nBorder)
            newSpace <<= 1;
        else
        {
            std::cerr << "List becomes too big" << std::endl;
            exit(1);
        }
      }
   }

   // Veraenderung ?:
   if (newSpace != space())
      alloc(newSpace,true);
}

template <class XX>
void
List<XX>::alloc( unsigned           newSpace,
                 bool               re )
{
    XX * pNew = new XX[newSpace];

    if (inhalt != 0)
    {
        if (re)
        {
            for (unsigned i = 0; i < len; ++i)
            {
                pNew[i] = inhalt[i];
            }  // end for
        }
        delete [] inhalt;
    }

    inhalt = pNew;
    allocated = newSpace;
}

template <class XY>
DynamicList<XY>::~DynamicList()
{
    this->erase_all();
}

template <class XY>
void
DynamicList<XY>::insert(unsigned pos, XY * const & elem_)
{
    if ( pos > this->len )
      return;

    checkSize(this->len+2);
    memmove(this->inhalt[pos+1], this->inhalt[pos], (this->len-pos) * sizeof(XY*) );
    this->inhalt[pos] = elem_;
    this->len++;
}

template <class XY>
void
DynamicList<XY>::remove( unsigned           pos )
{
    if (!this->is_valid_index(pos) )
        return;
    this->len--;
    delete this->inhalt[pos];
    memmove(this->inhalt[pos], this->inhalt[pos+1], (this->len-pos) * sizeof(XY*) );
}

#endif

<|endoftext|>


<commit_before>
#include "jsonfile.h"
#include "b64/encode.h"
#include <cstdlib>

namespace base
{
    JsonWriterFile::JsonWriterFile(FILE* fp, char* buffer, std::size_t length):
        m_fileStream(fp, buffer, length),
        m_writer(m_fileStream),
        m_fp(fp)
    {
    }

    JsonWriterFile::~JsonWriterFile()
    {
        Flush();
    }

    FILE* JsonWriterFile::GetFp() const
    {
        return m_fp;
    }

    void JsonWriterFile::Flush()
    {
        m_fileStream.Flush();

    void JsonWriterFile::Reset()
    {
        m_writer.Reset(m_fileStream);
    }

    bool JsonWriterFile::IsComplete() const
    {
        return m_writer.IsComplete();
    }

    void JsonWriterFile::StartObject(const char* name /*= nullptr*/)
    {
        auto& writer = m_writer;
        if (name)
        {
            writer.String(name);
        }
        writer.StartObject();
    }

    void JsonWriterFile::EndObject()
    {
        m_writer.EndObject();
    }

    void JsonWriterFile::StartArray(const char* name /*= nullptr*/)
    {
        auto& writer = m_writer;
        if (name)
        {
            writer.String(name);
        }
        writer.StartArray();
    }

    void JsonWriterFile::EndArray()
    {
        m_writer.EndArray();
    }

    void JsonWriterFile::WriteNull(const char* name)
    {
        auto& writer = m_writer;
        writer.String(name);
        writer.Null();
    }

    void JsonWriterFile::WriteBool(const char* name, bool value)
    {
        auto& writer = m_writer;
        writer.String(name);
        writer.Bool(value);
    }

    void JsonWriterFile::WriteInt32(const char* name, std::int32_t value)
    {
        auto& writer = m_writer;
        writer.String(name);
        writer.Int(value);
    }

    void JsonWriterFile::WriteInt32(const char* name, std::int32_t value, bool writeCondition)
    {
        auto& writer = m_writer;
        writer.String(name);
        if (writeCondition)
        {
            writer.Int(value);
        }
        else
        {
            writer.Null();
        }
    }

    void JsonWriterFile::WriteInt64(const char* name, std::int64_t value)
    {
        auto& writer = m_writer;
        writer.String(name);
        writer.Int64(value);
    }

    void JsonWriterFile::WriteUInt32(const char* name, std::uint32_t value)
    {
        auto& writer = m_writer;
        writer.String(name);
        writer.Uint(value);
    }

    void JsonWriterFile::WriteUInt32(const char* name, std::uint32_t value, bool writeCondition)
    {
        auto& writer = m_writer;
        writer.String(name);
        if (writeCondition)
        {
            writer.Uint(value);
        }
        else
        {
            writer.Null();
        }
    }

    void JsonWriterFile::WriteUint64(const char* name, std::uint64_t value)
    {
        auto& writer = m_writer;
        writer.String(name);
        writer.Uint64(value);
    }

    void JsonWriterFile::WriteString(const char* name, const char* value)
    {
        auto& writer = m_writer;
        writer.String(name);
        writer.String(value);
    }

    void JsonWriterFile::WriteString(const char* name, const char* value, std::int32_t length)
    {
        auto& writer = m_writer;
        writer.String(name);
        writer.String(value, length);
    }

    void JsonWriterFile::WriteFloat(const char* name, const double value)
    {
        auto& writer = m_writer;
        writer.String(name);
        writer.Double(value);
    }

    void JsonWriterFile::WriteBits(const char* name, const unsigned char* data, std::size_t numBits)
    {
        auto& writer = m_writer;
        writer.String(name);

        base64::base64_encodestate state;
        base64::base64_init_encodestate(&state);
        state.flags = base64::BASE64_ENC_NO_NEWLINE_TERM;

        const std::size_t numBytes = ((numBits + 7) >> 3);
        const int encodedLenMax = base64::base64_calc_buffer_length(numBytes, &state);

        char* const encoded = (char*)calloc(encodedLenMax, 1);
        char* encodedCurOut = encoded;

        const std::size_t numTrailingBits = (numBits & 7);
        if (numTrailingBits > 0)
        {
            const std::size_t numBytesWithoutBits = (numBits >> 3);
            encodedCurOut += base64::base64_encode_block((const char*)data, numBytesWithoutBits, encodedCurOut, &state);
            const char lastByteClean = data[numBytesWithoutBits] & ~(0xFF >> numTrailingBits);
            encodedCurOut += base64::base64_encode_block(&lastByteClean, 1, encodedCurOut, &state);
        }
        else
        {
            encodedCurOut += base64::base64_encode_block((const char*)data, numBytes, encodedCurOut, &state);
        }
        encodedCurOut += base64::base64_encode_blockend(encodedCurOut, &state);

        writer.String(encoded, encodedCurOut - encoded);
        free(encoded);
        return;
    }

    void JsonWriterFile::WriteBytes(const char* name, const unsigned char* data, std::size_t numBytes)
    {
        JsonWriterFile::WriteBits(name, data, numBytes * 8);
    }
}
<commit_msg>Added fflush to JsonWriterFile Flush function<commit_after>
#include "jsonfile.h"
#include "b64/encode.h"
#include <cstdlib>

namespace base
{
    JsonWriterFile::JsonWriterFile(FILE* fp, char* buffer, std::size_t length):
        m_fileStream(fp, buffer, length),
        m_writer(m_fileStream),
        m_fp(fp)
    {
    }

    JsonWriterFile::~JsonWriterFile()
    {
        Flush();
    }

    FILE* JsonWriterFile::GetFp() const
    {
        return m_fp;
    }

    void JsonWriterFile::Flush()
    {
        m_fileStream.Flush();
        fflush(m_fp);
    }

    void JsonWriterFile::Reset()
    {
        m_writer.Reset(m_fileStream);
    }

    bool JsonWriterFile::IsComplete() const
    {
        return m_writer.IsComplete();
    }

    void JsonWriterFile::StartObject(const char* name /*= nullptr*/)
    {
        auto& writer = m_writer;
        if (name)
        {
            writer.String(name);
        }
        writer.StartObject();
    }

    void JsonWriterFile::EndObject()
    {
        m_writer.EndObject();
    }

    void JsonWriterFile::StartArray(const char* name /*= nullptr*/)
    {
        auto& writer = m_writer;
        if (name)
        {
            writer.String(name);
        }
        writer.StartArray();
    }

    void JsonWriterFile::EndArray()
    {
        m_writer.EndArray();
    }

    void JsonWriterFile::WriteNull(const char* name)
    {
        auto& writer = m_writer;
        writer.String(name);
        writer.Null();
    }

    void JsonWriterFile::WriteBool(const char* name, bool value)
    {
        auto& writer = m_writer;
        writer.String(name);
        writer.Bool(value);
    }

    void JsonWriterFile::WriteInt32(const char* name, std::int32_t value)
    {
        auto& writer = m_writer;
        writer.String(name);
        writer.Int(value);
    }

    void JsonWriterFile::WriteInt32(const char* name, std::int32_t value, bool writeCondition)
    {
        auto& writer = m_writer;
        writer.String(name);
        if (writeCondition)
        {
            writer.Int(value);
        }
        else
        {
            writer.Null();
        }
    }

    void JsonWriterFile::WriteInt64(const char* name, std::int64_t value)
    {
        auto& writer = m_writer;
        writer.String(name);
        writer.Int64(value);
    }

    void JsonWriterFile::WriteUInt32(const char* name, std::uint32_t value)
    {
        auto& writer = m_writer;
        writer.String(name);
        writer.Uint(value);
    }

    void JsonWriterFile::WriteUInt32(const char* name, std::uint32_t value, bool writeCondition)
    {
        auto& writer = m_writer;
        writer.String(name);
        if (writeCondition)
        {
            writer.Uint(value);
        }
        else
        {
            writer.Null();
        }
    }

    void JsonWriterFile::WriteUint64(const char* name, std::uint64_t value)
    {
        auto& writer = m_writer;
        writer.String(name);
        writer.Uint64(value);
    }

    void JsonWriterFile::WriteString(const char* name, const char* value)
    {
        auto& writer = m_writer;
        writer.String(name);
        writer.String(value);
    }

    void JsonWriterFile::WriteString(const char* name, const char* value, std::int32_t length)
    {
        auto& writer = m_writer;
        writer.String(name);
        writer.String(value, length);
    }

    void JsonWriterFile::WriteFloat(const char* name, const double value)
    {
        auto& writer = m_writer;
        writer.String(name);
        writer.Double(value);
    }

    void JsonWriterFile::WriteBits(const char* name, const unsigned char* data, std::size_t numBits)
    {
        auto& writer = m_writer;
        writer.String(name);

        base64::base64_encodestate state;
        base64::base64_init_encodestate(&state);
        state.flags = base64::BASE64_ENC_NO_NEWLINE_TERM;

        const std::size_t numBytes = ((numBits + 7) >> 3);
        const int encodedLenMax = base64::base64_calc_buffer_length(numBytes, &state);

        char* const encoded = (char*)calloc(encodedLenMax, 1);
        char* encodedCurOut = encoded;

        const std::size_t numTrailingBits = (numBits & 7);
        if (numTrailingBits > 0)
        {
            const std::size_t numBytesWithoutBits = (numBits >> 3);
            encodedCurOut += base64::base64_encode_block((const char*)data, numBytesWithoutBits, encodedCurOut, &state);
            const char lastByteClean = data[numBytesWithoutBits] & ~(0xFF >> numTrailingBits);
            encodedCurOut += base64::base64_encode_block(&lastByteClean, 1, encodedCurOut, &state);
        }
        else
        {
            encodedCurOut += base64::base64_encode_block((const char*)data, numBytes, encodedCurOut, &state);
        }
        encodedCurOut += base64::base64_encode_blockend(encodedCurOut, &state);

        writer.String(encoded, encodedCurOut - encoded);
        free(encoded);
        return;
    }

    void JsonWriterFile::WriteBytes(const char* name, const unsigned char* data, std::size_t numBytes)
    {
        JsonWriterFile::WriteBits(name, data, numBytes * 8);
    }
}
<|endoftext|>


<commit_before>#include <dlfcn.h>
#include <errno.h>
#include <fcntl.h>
#include <inttypes.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

void init() __attribute__((constructor));
void fini() __attribute__((destructor));

static void panic(...) __attribute__((noreturn));

#ifdef DEBUG
#define debug printf
#define assert xassert
#define xassert(e) if (e); else panic(#e)
#define IFDEBUG(X) X
#else
#define debug(...) (void)0
#define assert(...) (void)0
#define IFDEBUG(X) /* nothing */
#endif

#define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)

/**
 * These are adapted to be stored internally in whatever data we have.
 */
struct pairing_ptr_heap
{
	typedef pairing_ptr_heap T;
	typedef pairing_ptr_heap* Tp;

	/**
	 * down,right: first child and right sibling of this page in pairing heap
	 * of pages with free space.
	 */
	pairing_ptr_heap* down;
	pairing_ptr_heap* right;

	Tp delete_min()
	{
		assert(!right);
		Tp l = down;
		down = NULL;
		return mergePairs(l);
	}

	static Tp mergePairs(Tp l)
	{
		if (!l || !l->right) return l;

		Tp r = l->right;
		Tp hs = r->right;
		l->right = r->right = NULL;
		assert(hs != l && hs != r && r != l);
		// FIXME recursion...
		// We can use l->right after merge returns, since merge() always
		// returns something with a right-value of NULL. l will never be
		// touched until we're about to merge it with the result of mergePairs
		l = merge(l,r);
		hs = mergePairs(hs);
		return merge(l,hs);
	}

	static Tp merge(Tp l, Tp r)
	{
		if (!l)
		{
			assert(!r->right);
			return r;
		}
		if (!r)
		{
			assert(!l->right);
			return l;
		}

		assert(!l->right && !r->right);

		if (r < l)
		{
			Tp tmp = r;
			r = l;
			l = tmp;
		}
		// l <= r!

		r->right = l->down;
		l->down = r;
		//l->right = NULL; // we know it's already null
		return l;
	}
};
static pairing_ptr_heap* delete_min(pairing_ptr_heap* p)
{
	assert(p);
	return p->delete_min();
}
static pairing_ptr_heap* insert(pairing_ptr_heap* l, pairing_ptr_heap* r)
{
	return pairing_ptr_heap::merge(l, r);
}

struct pageinfo
{
	/**
	 * Pointer to where the page starts.
	 * TODO: Pack some stuff in here. *Twelve* vacant bits!
	 */
	void* page;

	/**
	 * The heap of address-sorted pages in this category that have free pages
	 */
	pairing_ptr_heap heap;

	uint16_t size;
	//uint16_t isize;
	uint16_t chunks;
	uint16_t chunks_free;
	uint8_t index; // index into array of pages

	/**
	 * 1-32 bytes of bitmap data. A set bit means *free* chunk.
	 */
	uint8_t bitmap[];

	// TODO merge bitmap into page?
};
#define pageinfo_from_heap(heap_) \
	((pageinfo*)((char*)(heap_) - offsetof(pageinfo, heap)))

static bool page_filled(pageinfo* page)
{
	return !page->chunks_free;
}
static void* page_get_chunk(pageinfo* page)
{
	page->chunks_free--;
	uint8_t* bitmap = page->bitmap;
	for (size_t i = 0; i < page->chunks / 8; i++)
	{
		const uint8_t found = bitmap[i];
		if (found)
		{
			uint8_t mask = 0x80;
			size_t n = i << 3;
			while (mask)
			{
				if (mask & found)
				{
					bitmap[i] = found & ~mask;
					return (uint8_t*)page->page + (n * page->size);
				}
				mask >>= 1;
				n++;
			}
		}
	}
	panic("No free chunks found?");
}
static void page_free_chunk(pageinfo* page, void* ptr)
{
	size_t ix = (uint8_t*)ptr - (uint8_t*)page->page;
	ix /= page->size; // FIXME store inverse or something instead
	page->bitmap[ix >> 3] |= 1 << (7 - (ix & 7));
	page->chunks_free++;
}

#define N_SIZES (128/16+5)
#define PAGE_SHIFT 12
#define PAGE_SIZE (1 << PAGE_SHIFT)

static pairing_ptr_heap* g_free_pages;
static pageinfo* g_chunk_pages[N_SIZES];
static uintptr_t g_first_page;
static uintptr_t g_n_pages;
// Assumes mostly contiguous pages...
static pageinfo** g_pages;

void init()
{
	g_first_page = (uintptr_t)sbrk(0);
}

void fini()
{
	// TODO Unmap everything?
}

static void panic(...)
{
	abort();
}

static size_t size_ix(size_t size)
{
	if (size <= 128)
		return (size + 15) / 16 - 1;

	size_t ix = 8; // 256 bytes
	size >>= 8;
	while (size) { size >>= 1; ix++; }
	return ix;
}

static size_t ix_size(size_t ix)
{
	return ix < 8 ? 16 * (ix + 1) : (1 << ix);
}

static void* get_page()
{
	if (void* ret = g_free_pages)
	{
		g_free_pages = delete_min(g_free_pages);
		return ret;
	}
	else
	{
		uintptr_t cur = (uintptr_t)sbrk(0);
		sbrk((PAGE_SIZE - cur) & (PAGE_SIZE - 1));
		return sbrk(PAGE_SIZE);
	}
}

static void set_pageinfo(void* page, pageinfo* info)
{
	uintptr_t offset;
	if (g_pages)
	{
		offset = ((uintptr_t)page - g_first_page) >> PAGE_SHIFT;
	}
	else
	{
		g_first_page = (uintptr_t)page;
		offset = 0;
	}

	if (offset >= g_n_pages)
	{
		size_t required = (offset + PAGE_SIZE) & ~(PAGE_SIZE-1);
		pageinfo** new_pages = (pageinfo**)mmap(NULL, required, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
		assert(new_pages != MAP_FAILED);

		memcpy(new_pages, g_pages, g_n_pages * sizeof(pageinfo*));
		munmap(g_pages, g_n_pages * sizeof(pageinfo*));

		g_pages = new_pages;
		g_n_pages = required / sizeof(pageinfo*);
	}

	g_pages[offset] = info;
}

static pageinfo* new_chunkpage(size_t size)
{
	size_t ix = size_ix(size);
	size = ix_size(ix);

	size_t nchunks = 4096/size;
	pageinfo* ret = NULL;
	size_t pisize = sizeof(pageinfo) + nchunks/8;
	if (!g_chunk_pages[size_ix(pisize)])
	{
		ret = (pageinfo*)get_page();
		set_pageinfo(ret, NULL);
	}
	else
	{
		ret = (pageinfo*)malloc(pisize);
	}

	memset(&ret->heap, 0, sizeof(ret->heap));
	ret->page = get_page();
	ret->size = size;
//	ret->shift = ix_shift(ix);
	ret->chunks = nchunks;
	ret->chunks_free = nchunks;
	ret->index = ix;

	memset(ret->bitmap, 0xff, nchunks/8);

	set_pageinfo(ret->page, ret);

	return ret;
}

static pageinfo* ptr_pageinfo(void* ptr)
{
	uintptr_t offset = ((uintptr_t)ptr - g_first_page) >> PAGE_SHIFT;
	if (offset > g_n_pages) return NULL;
	pageinfo* ret = g_pages[offset];
	assert(!ret || !(((uintptr_t)ret->page ^ (uintptr_t)ptr) >> PAGE_SHIFT));
	return ret;
}

static size_t get_alloc_size(void* ptr)
{
	pageinfo* info = ptr_pageinfo(ptr);
	if (!info) panic("get_alloc_size for unknown pointer %p", ptr);
	return info->size;
}

void *malloc(size_t size)
{
	if (!size) return NULL;

	pageinfo** pagep = g_chunk_pages + size_ix(size);
	pageinfo* page = *pagep;
	if (unlikely(!page))
	{
		debug("Adding new chunk page for size %lu (cat %ld)\n", size, size_ix(size));
		page = new_chunkpage(size);
		*pagep = page;
	}
	debug("Allocating chunk from %p (info %p, %d left)\n", page->page, page, page->chunks_free);
	void* ret = page_get_chunk(page);
	if (unlikely(page_filled(page)))
	{
		debug("Page %p (info %p) filled\n", page->page, page);
		pairing_ptr_heap* newpage = delete_min(&page->heap);
		*pagep = newpage ? pageinfo_from_heap(newpage) : NULL;
	}
	return ret;
}

void* calloc(size_t n, size_t sz)
{
	size_t size = n * sz;
	void* ptr = malloc(size);
	if (likely(ptr)) memset(ptr, 0, size);
	return ptr;
}

void* realloc(void* ptr, size_t new_size)
{
	size_t old_size = get_alloc_size(ptr);
	void* ret = malloc(new_size);
	if (likely(ret))
	{
		memcpy(ret, ptr, unlikely(new_size < old_size) ? new_size : old_size);
	}
	return ret;
}

void free(void *ptr)
{
	if (unlikely(!ptr)) return;

	pageinfo* page = ptr_pageinfo(ptr);
	if (unlikely(!page)) panic("free on unknown pointer %p", ptr);

	bool was_filled = page_filled(page);
	page_free_chunk(page, ptr);
	if (was_filled)
	{
		pageinfo** pagep = g_chunk_pages + page->index;
		pageinfo* free_page = *pagep;
		if (!free_page)
			*pagep = page;
		else
			*pagep = pageinfo_from_heap(insert(&free_page->heap, &page->heap));
	}
	else if (unlikely(page->chunks_free == page->chunks))
	{
		debug("Free: page %p (info %p) is now free\n", page->page, page);
	}
}

#ifdef TEST

static int32_t xrand()
{
	static int32_t m_w = 1246987127, m_z = 789456123;
	m_z = 36969 * (m_z & 65535) + (m_z >> 16);
	m_w = 18000 * (m_w & 65535) + (m_w >> 16);
	return (m_z << 16) + m_w;  /* 32-bit result */
}

const size_t DELAY = 10;
const size_t NTESTS = 100000;
const size_t MAXALLOC = 512;

int main()
{
	void* ptrs[DELAY] = {0};
	for (size_t i = 0; i < NTESTS; i++)
	{
		size_t size = i % MAXALLOC;
		void** p = ptrs + (i % DELAY);
		debug("free(%p)\n", *p);
		free(*p);
		debug("malloc(%lu)\n", (unsigned long)size);
		*p = malloc(size);
		debug("malloc(%lu): %p\n", (unsigned long)size, *p);
		for (size_t j = 0; j < DELAY; j++)
		{
			assert(ptrs + j == p || !p[0] || ptrs[j] != p[0]);
		}
	}
}
#endif
<commit_msg>Debugging the page_free_chunk function<commit_after>#include <dlfcn.h>
#include <errno.h>
#include <fcntl.h>
#include <inttypes.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

void init() __attribute__((constructor));
void fini() __attribute__((destructor));

static void panic(...) __attribute__((noreturn));

#ifdef DEBUG
#define debug printf
#define assert xassert
#define xassert(e) if (e); else panic(#e)
#define IFDEBUG(X) X
#else
#define debug(...) (void)0
#define assert(...) (void)0
#define IFDEBUG(X) /* nothing */
#endif

#define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)

/**
 * These are adapted to be stored internally in whatever data we have.
 */
struct pairing_ptr_heap
{
	typedef pairing_ptr_heap T;
	typedef pairing_ptr_heap* Tp;

	/**
	 * down,right: first child and right sibling of this page in pairing heap
	 * of pages with free space.
	 */
	pairing_ptr_heap* down;
	pairing_ptr_heap* right;

	Tp delete_min()
	{
		assert(!right);
		Tp l = down;
		down = NULL;
		return mergePairs(l);
	}

	static Tp mergePairs(Tp l)
	{
		if (!l || !l->right) return l;

		Tp r = l->right;
		Tp hs = r->right;
		l->right = r->right = NULL;
		assert(hs != l && hs != r && r != l);
		// FIXME recursion...
		// We can use l->right after merge returns, since merge() always
		// returns something with a right-value of NULL. l will never be
		// touched until we're about to merge it with the result of mergePairs
		l = merge(l,r);
		hs = mergePairs(hs);
		return merge(l,hs);
	}

	static Tp merge(Tp l, Tp r)
	{
		if (!l)
		{
			assert(!r->right);
			return r;
		}
		if (!r)
		{
			assert(!l->right);
			return l;
		}

		assert(!l->right && !r->right);

		if (r < l)
		{
			Tp tmp = r;
			r = l;
			l = tmp;
		}
		// l <= r!

		r->right = l->down;
		l->down = r;
		//l->right = NULL; // we know it's already null
		return l;
	}
};
static pairing_ptr_heap* delete_min(pairing_ptr_heap* p)
{
	assert(p);
	return p->delete_min();
}
static pairing_ptr_heap* insert(pairing_ptr_heap* l, pairing_ptr_heap* r)
{
	return pairing_ptr_heap::merge(l, r);
}

struct pageinfo
{
	/**
	 * Pointer to where the page starts.
	 * TODO: Pack some stuff in here. *Twelve* vacant bits!
	 */
	void* page;

	/**
	 * The heap of address-sorted pages in this category that have free pages
	 */
	pairing_ptr_heap heap;

	uint16_t size;
	//uint16_t isize;
	uint16_t chunks;
	uint16_t chunks_free;
	uint8_t index; // index into array of pages

	/**
	 * 1-32 bytes of bitmap data. A set bit means *free* chunk.
	 */
	uint8_t bitmap[];

	// TODO merge bitmap into page?
};
#define pageinfo_from_heap(heap_) \
	((pageinfo*)((char*)(heap_) - offsetof(pageinfo, heap)))

static bool page_filled(pageinfo* page)
{
	return !page->chunks_free;
}
static void* page_get_chunk(pageinfo* page)
{
	page->chunks_free--;
	uint8_t* bitmap = page->bitmap;
	for (size_t i = 0; i < page->chunks / 8; i++)
	{
		const uint8_t found = bitmap[i];
		if (found)
		{
			uint8_t mask = 0x80;
			size_t n = i << 3;
			while (mask)
			{
				if (mask & found)
				{
					bitmap[i] = found & ~mask;
					return (uint8_t*)page->page + (n * page->size);
				}
				mask >>= 1;
				n++;
			}
		}
	}
	panic("No free chunks found?");
}
static void page_free_chunk(pageinfo* page, void* ptr)
{
	size_t offset_in_page = (uint8_t*)ptr - (uint8_t*)page->page;
	size_t ix = offset_in_page;
	ix /= page->size; // FIXME store inverse or something instead
	uint8_t mask = 1 << (7 - (ix & 7));
	size_t byte = ix >> 3;
	debug("Freeing %p in %p (size %d): oring byte %d with %#x\n", ptr, page->page, page->size, byte, mask);
	page->bitmap[byte] |= mask;
	page->chunks_free++;
}

#define N_SIZES (128/16+5)
#define PAGE_SHIFT 12
#define PAGE_SIZE (1 << PAGE_SHIFT)

static pairing_ptr_heap* g_free_pages;
static pageinfo* g_chunk_pages[N_SIZES];
static uintptr_t g_first_page;
static uintptr_t g_n_pages;
// Assumes mostly contiguous pages...
static pageinfo** g_pages;

void init()
{
	g_first_page = (uintptr_t)sbrk(0);
}

void fini()
{
	// TODO Unmap everything?
}

static void panic(...)
{
	abort();
}

static size_t size_ix(size_t size)
{
	if (size <= 128)
		return (size + 15) / 16 - 1;

	size_t ix = 8; // 256 bytes
	size >>= 8;
	while (size) { size >>= 1; ix++; }
	return ix;
}

static size_t ix_size(size_t ix)
{
	return ix < 8 ? 16 * (ix + 1) : (1 << ix);
}

static void* get_page()
{
	if (void* ret = g_free_pages)
	{
		g_free_pages = delete_min(g_free_pages);
		return ret;
	}
	else
	{
		uintptr_t cur = (uintptr_t)sbrk(0);
		sbrk((PAGE_SIZE - cur) & (PAGE_SIZE - 1));
		return sbrk(PAGE_SIZE);
	}
}

static void set_pageinfo(void* page, pageinfo* info)
{
	uintptr_t offset;
	if (g_pages)
	{
		offset = ((uintptr_t)page - g_first_page) >> PAGE_SHIFT;
	}
	else
	{
		g_first_page = (uintptr_t)page;
		offset = 0;
	}

	if (offset >= g_n_pages)
	{
		size_t required = (offset + PAGE_SIZE) & ~(PAGE_SIZE-1);
		pageinfo** new_pages = (pageinfo**)mmap(NULL, required, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
		assert(new_pages != MAP_FAILED);

		memcpy(new_pages, g_pages, g_n_pages * sizeof(pageinfo*));
		munmap(g_pages, g_n_pages * sizeof(pageinfo*));

		g_pages = new_pages;
		g_n_pages = required / sizeof(pageinfo*);
	}

	g_pages[offset] = info;
}

static pageinfo* new_chunkpage(size_t size)
{
	size_t ix = size_ix(size);
	size = ix_size(ix);

	size_t nchunks = 4096/size;
	pageinfo* ret = NULL;
	size_t pisize = sizeof(pageinfo) + nchunks/8;
	if (!g_chunk_pages[size_ix(pisize)])
	{
		ret = (pageinfo*)get_page();
		set_pageinfo(ret, NULL);
	}
	else
	{
		ret = (pageinfo*)malloc(pisize);
	}

	memset(&ret->heap, 0, sizeof(ret->heap));
	ret->page = get_page();
	ret->size = size;
//	ret->shift = ix_shift(ix);
	ret->chunks = nchunks;
	ret->chunks_free = nchunks;
	ret->index = ix;

	memset(ret->bitmap, 0xff, nchunks/8);

	set_pageinfo(ret->page, ret);

	return ret;
}

static pageinfo* ptr_pageinfo(void* ptr)
{
	uintptr_t offset = ((uintptr_t)ptr - g_first_page) >> PAGE_SHIFT;
	if (offset > g_n_pages) return NULL;
	pageinfo* ret = g_pages[offset];
	assert(!ret || !(((uintptr_t)ret->page ^ (uintptr_t)ptr) >> PAGE_SHIFT));
	return ret;
}

static size_t get_alloc_size(void* ptr)
{
	pageinfo* info = ptr_pageinfo(ptr);
	if (!info) panic("get_alloc_size for unknown pointer %p", ptr);
	return info->size;
}

void *malloc(size_t size)
{
	if (!size) return NULL;

	pageinfo** pagep = g_chunk_pages + size_ix(size);
	pageinfo* page = *pagep;
	if (unlikely(!page))
	{
		debug("Adding new chunk page for size %lu (cat %ld)\n", size, size_ix(size));
		page = new_chunkpage(size);
		*pagep = page;
	}
	debug("Allocating chunk from %p (info %p, %d left)\n", page->page, page, page->chunks_free);
	void* ret = page_get_chunk(page);
	if (unlikely(page_filled(page)))
	{
		debug("Page %p (info %p) filled\n", page->page, page);
		pairing_ptr_heap* newpage = delete_min(&page->heap);
		*pagep = newpage ? pageinfo_from_heap(newpage) : NULL;
	}
	return ret;
}

void* calloc(size_t n, size_t sz)
{
	size_t size = n * sz;
	void* ptr = malloc(size);
	if (likely(ptr)) memset(ptr, 0, size);
	return ptr;
}

void* realloc(void* ptr, size_t new_size)
{
	size_t old_size = get_alloc_size(ptr);
	void* ret = malloc(new_size);
	if (likely(ret))
	{
		memcpy(ret, ptr, unlikely(new_size < old_size) ? new_size : old_size);
	}
	return ret;
}

void free(void *ptr)
{
	if (unlikely(!ptr)) return;

	pageinfo* page = ptr_pageinfo(ptr);
	if (unlikely(!page)) panic("free on unknown pointer %p", ptr);

	bool was_filled = page_filled(page);
	page_free_chunk(page, ptr);
	if (was_filled)
	{
		pageinfo** pagep = g_chunk_pages + page->index;
		pageinfo* free_page = *pagep;
		if (!free_page)
			*pagep = page;
		else
			*pagep = pageinfo_from_heap(insert(&free_page->heap, &page->heap));
	}
	else if (unlikely(page->chunks_free == page->chunks))
	{
		debug("Free: page %p (info %p) is now free\n", page->page, page);
	}
}

#ifdef TEST

static int32_t xrand()
{
	static int32_t m_w = 1246987127, m_z = 789456123;
	m_z = 36969 * (m_z & 65535) + (m_z >> 16);
	m_w = 18000 * (m_w & 65535) + (m_w >> 16);
	return (m_z << 16) + m_w;  /* 32-bit result */
}

const size_t DELAY = 10;
const size_t NTESTS = 100000;
const size_t MAXALLOC = 512;

int main()
{
	void* ptrs[DELAY] = {0};
	for (size_t i = 0; i < NTESTS; i++)
	{
		size_t size = i % MAXALLOC;
		void** p = ptrs + (i % DELAY);
		debug("free(%p)\n", *p);
		free(*p);
		debug("malloc(%lu)\n", (unsigned long)size);
		*p = malloc(size);
		debug("malloc(%lu): %p\n", (unsigned long)size, *p);
		for (size_t j = 0; j < DELAY; j++)
		{
			assert(ptrs + j == p || !p[0] || ptrs[j] != p[0]);
		}
	}
}
#endif
<|endoftext|>


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

#ifndef _COM_SUN_STAR_UNO_REFERENCE_H_
#include <com/sun/star/uno/Reference.h>
#endif

#ifndef _XMLOFF_XMLICTXT_HXX
#include "xmlictxt.hxx"
#endif

class XMLHints_Impl;
namespace com { namespace sun { namespace star {
namespace text {  class XTextRange; }
namespace xml { namespace sax { class XAttributeList; } }
} } }

#ifdef CONV_STAR_FONTS
#define CONV_FROM_STAR_BATS 1
#define CONV_FROM_STAR_MATH 2
#define CONV_STAR_FONT_FLAGS_VALID 4
#endif

class XMLParaContext : public SvXMLImportContext
{
    ::com::sun::star::uno::Reference <
        ::com::sun::star::text::XTextRange > xStart;    // xub_StrLen nStart;
    ::rtl::OUString             sStyleName;
    ::rtl::OUString             sId;
    sal_Int8                nOutlineLevel;
    XMLHints_Impl           *pHints;
    sal_Bool                bIgnoreLeadingSpace;
    sal_Bool                bHeading;
    sal_Bool                bIsListHeader;
#ifdef CONV_STAR_FONTS
    sal_uInt8               nStarFontsConvFlags;
#endif

public:

    TYPEINFO();

    XMLParaContext( SvXMLImport& rImport,
            sal_uInt16 nPrfx,
            const ::rtl::OUString& rLName,
            const ::com::sun::star::uno::Reference<
                ::com::sun::star::xml::sax::XAttributeList > & xAttrList,
            sal_Bool bHeading );

    virtual ~XMLParaContext();

    virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
            const ::rtl::OUString& rLocalName,
            const ::com::sun::star::uno::Reference<
                ::com::sun::star::xml::sax::XAttributeList > & xAttrList );

    virtual void Characters( const ::rtl::OUString& rChars );

};

#endif
<commit_msg>INTEGRATION: CWS swnumtree (1.6.2); FILE MERGED 2005/09/27 15:30:25 hbrinkm 1.6.2.1: #i45784# ~XMLParaContext: import restart of numbering in headers<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: txtparai.hxx,v $
 *
 *  $Revision: 1.7 $
 *
 *  last change: $Author: rt $ $Date: 2005-11-08 17:06:34 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#ifndef _XMLOFF_TEXTPARAI_HXX_
#define _XMLOFF_TEXTPARAI_HXX_

#ifndef _COM_SUN_STAR_UNO_REFERENCE_H_
#include <com/sun/star/uno/Reference.h>
#endif

#ifndef _XMLOFF_XMLICTXT_HXX
#include "xmlictxt.hxx"
#endif

class XMLHints_Impl;
namespace com { namespace sun { namespace star {
namespace text {  class XTextRange; }
namespace xml { namespace sax { class XAttributeList; } }
} } }

#ifdef CONV_STAR_FONTS
#define CONV_FROM_STAR_BATS 1
#define CONV_FROM_STAR_MATH 2
#define CONV_STAR_FONT_FLAGS_VALID 4
#endif

class XMLParaContext : public SvXMLImportContext
{
    ::com::sun::star::uno::Reference <
        ::com::sun::star::text::XTextRange > xStart;    // xub_StrLen nStart;
    ::rtl::OUString             sStyleName;
    ::rtl::OUString             sId;
    sal_Int8                nOutlineLevel;
    XMLHints_Impl           *pHints;
    sal_Bool                bIgnoreLeadingSpace;
    sal_Bool                bHeading;
    sal_Bool                bIsListHeader;
    sal_Bool                bIsRestart;
    sal_Int16               nStartValue;
#ifdef CONV_STAR_FONTS
    sal_uInt8               nStarFontsConvFlags;
#endif

public:

    TYPEINFO();

    XMLParaContext( SvXMLImport& rImport,
            sal_uInt16 nPrfx,
            const ::rtl::OUString& rLName,
            const ::com::sun::star::uno::Reference<
                ::com::sun::star::xml::sax::XAttributeList > & xAttrList,
            sal_Bool bHeading );

    virtual ~XMLParaContext();

    virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
            const ::rtl::OUString& rLocalName,
            const ::com::sun::star::uno::Reference<
                ::com::sun::star::xml::sax::XAttributeList > & xAttrList );

    virtual void Characters( const ::rtl::OUString& rChars );

};

#endif
<|endoftext|>


<commit_before>/*
 * copyright: (c) RDO-Team, 2011
 * filename : main.cpp
 * author   :  , Evgeny Proydakov
 * date     : 07.07.2009
 * bref     :
 * indent   : 4T
 */

// ====================================================================== PCH
// ====================================================================== INCLUDES
#include <vector>
#include <list>
#include <iostream>
#define BOOST_TEST_MODULE RdoInterfaceTest
#include <boost/test/included/unit_test.hpp>
// ====================================================================== SYNOPSIS
#include "rdo_common/rdointerface.h"
// ===============================================================================

#define DISABLE_CONSOLE_OUTPUT

const tstring strIMy1            = _T("void fun1():  ");
const tstring strIMy2            = _T("void fun2():  ");
const tstring strIMy3            = _T("void fun3():  ");
const tstring strMyClass1Create  = _T("MyClass1():"   );
const tstring strMyClass1Destroy = _T("~MyClass1():"  );
const tstring strMyClass2Create  = _T("MyClass2():"   );
const tstring strMyClass2Destroy = _T("~MyClass2():"  );
const tstring strMyClass3Create  = _T("MyClass3():"   );
const tstring strMyClass3Destroy = _T("~MyClass3():"  );

typedef std::list<tstring> LogList;
LogList s_logList;

class IMy1
{
public:
	virtual tstring fun1() = 0;
};

class IMy2
{
public:
	virtual tstring fun2() = 0;
};

class IMy3
{
public:
	virtual tstring fun3() = 0;
};

class IMy4
{
public:
	virtual tstring fun4() = 0;
};

INTERFACE_REGISTRATOR(IMy1, 1);
INTERFACE_REGISTRATOR(IMy2, 2);
INTERFACE_REGISTRATOR(IMy3, 3);
INTERFACE_REGISTRATOR(IMy4, 4);

class MyClass1: public rdo::IGetUnknown, public IMy1, public IMy2, public IInit
{
QUERY_INTERFACE_BEGIN
	QUERY_INTERFACE(IMy1)
	QUERY_INTERFACE(IMy2)
	QUERY_INTERFACE(IInit)
QUERY_INTERFACE_END

protected:
	MyClass1(char i)
		: m_i(i)
	{
#ifndef DISABLE_CONSOLE_OUTPUT
		std::cout << strMyClass1Create << i << std::endl;
#endif
		s_logList.push_back(strMyClass1Create + i);
	}
	~MyClass1()
	{
#ifndef DISABLE_CONSOLE_OUTPUT
		std::cout << strMyClass1Destroy << m_i << std::endl;
#endif
		s_logList.push_back(strMyClass1Destroy);
	}
	rbool init()
	{
		return true;
	}

protected:
	char m_i;

private:
	tstring fun1()
	{
#ifndef DISABLE_CONSOLE_OUTPUT
		std::cout << strIMy1 << m_i << std::endl;
#endif
		return strIMy1 + m_i;
	}
	tstring fun2()
	{
#ifndef DISABLE_CONSOLE_OUTPUT
		std::cout << strIMy2 << m_i << std::endl;
#endif
		return strIMy2 + m_i;
	}
};

class MyClass2: public MyClass1, public IMy3
{
DEFINE_IFACTORY(MyClass2);
QUERY_INTERFACE_BEGIN
	QUERY_INTERFACE_PARENT(MyClass1)
	QUERY_INTERFACE(IMy3)
QUERY_INTERFACE_END

private:
	MyClass2(char i)
		: MyClass1(i)
	{
#ifndef DISABLE_CONSOLE_OUTPUT
		std::cout << strMyClass2Create << i << std::endl;
#endif
		s_logList.push_back(strMyClass2Create + i);
	}
	~MyClass2()
	{
#ifndef DISABLE_CONSOLE_OUTPUT
		std::cout << strMyClass2Destroy << m_i << std::endl;
#endif
		s_logList.push_back(strMyClass2Destroy);
	}
	tstring fun3()
	{
		ASSERT(this);
		LPIMy1 int1 = this;
		ASSERT(int1)

#ifndef DISABLE_CONSOLE_OUTPUT
		std::cout << strIMy3 << m_i << std::endl;
#endif
		return strIMy3 + m_i;
	}
};

class MyClass3: public IMy3, public rdo::IGetUnknown
{
DEFINE_IFACTORY(MyClass3);
QUERY_INTERFACE_BEGIN
	QUERY_INTERFACE(IMy3)
QUERY_INTERFACE_END

protected:
	MyClass3(char i)
		: m_i(i)
	{
#ifndef DISABLE_CONSOLE_OUTPUT
		std::cout << strMyClass3Create << i << std::endl;
#endif
		s_logList.push_back(strMyClass3Create + i);
	}
	~MyClass3()
	{
#ifndef DISABLE_CONSOLE_OUTPUT
		std::cout << strMyClass3Destroy << m_i << std::endl;
#endif
		s_logList.push_back(strMyClass3Destroy);
	}

protected:
	char m_i;

private:
	tstring fun3()
	{
#ifndef DISABLE_CONSOLE_OUTPUT
		std::cout << strIMy3 << m_i << std::endl;
#endif
		return strIMy3 + m_i;
	}
};

typedef rdo::Interface<IMy3>     MyInterface;
typedef std::vector<MyInterface> MyInterfaceList;

BOOST_AUTO_TEST_SUITE(RdoInterfaceTest)

BOOST_AUTO_TEST_CASE(RdoInterfaceTest_CheckingOnTheSameOperator)
{
	char initValue = _T('2');
	rdo::UnknownPointer smptr = F(MyClass2)::create(initValue);
	BOOST_REQUIRE(smptr);

	LogList::iterator it = s_logList.begin();
	BOOST_CHECK_EQUAL(*it,     strMyClass1Create + initValue);
	BOOST_CHECK_EQUAL(*(++it), strMyClass2Create + initValue);
	s_logList.clear();

	BOOST_CHECK_EQUAL(smptr.query_cast<IMy1>()->fun1(), strIMy1 + initValue);
	BOOST_CHECK_EQUAL(smptr.query_cast<IMy3>()->fun3(), strIMy3 + initValue);

	MyInterface imy3 = smptr;

	initValue = _T('7');

	rdo::UnknownPointer smptr2;
	smptr2 = F(MyClass2)::create(initValue);
	it = s_logList.begin();
	BOOST_CHECK_EQUAL(*it, strMyClass1Create + initValue);
	BOOST_CHECK_EQUAL(*(++it), strMyClass2Create + initValue);
	s_logList.clear();

	rdo::UnknownPointer smptr2_2 = smptr2;
	//BOOST_CHECK(smptr2_2 == smptr);
	//BOOST_CHECK_EQUAL(smptr2_2, smptr);
	BOOST_CHECK(smptr2_2 == smptr2);

	rdo::Interface<IMy1> int1_1 = smptr;
	rdo::Interface<IMy1> int2_1 = smptr2;
	rdo::Interface<IMy1> int1_2 = smptr;
	//BOOST_CHECK(int1_1 == int2_1);
	//BOOST_CHECK_EQUAL(int1_1, int2_1);
	BOOST_CHECK(int1_1 == int1_2);
}

BOOST_AUTO_TEST_CASE(RdoInterfaceTest_ValidationFailureInThePreviousTest1)
{
	LogList::iterator it = s_logList.begin();
	BOOST_CHECK_EQUAL(*it, strMyClass2Destroy);
	++it;
	BOOST_CHECK_EQUAL(*it, strMyClass1Destroy);
	++it;
	BOOST_CHECK_EQUAL(*it, strMyClass2Destroy);
	++it;
	BOOST_CHECK_EQUAL(*it, strMyClass1Destroy);
	s_logList.clear();
}

BOOST_AUTO_TEST_CASE(RdoInterfaceTest_Working)
{
	char initFValue = _T('2');
	rdo::UnknownPointer smptr = F(MyClass2)::create(initFValue);
	LogList::iterator iter = s_logList.begin();
	BOOST_CHECK_EQUAL(*iter, strMyClass1Create + initFValue);
	BOOST_CHECK_EQUAL(*(++iter), strMyClass2Create + initFValue);
	s_logList.clear();

	char initSValue = _T('5');
	rdo::UnknownPointer smptr2 = F(MyClass2)::create(initSValue);
	iter = s_logList.begin();
	BOOST_CHECK_EQUAL(*iter, strMyClass1Create + initSValue);
	BOOST_CHECK_EQUAL(*(++iter), strMyClass2Create + initSValue);
	s_logList.clear();

	MyInterfaceList myInterfaceList;

	char initTValue = _T('9');
	myInterfaceList.push_back(F(MyClass3)::create(initTValue));
	myInterfaceList.push_back(smptr );
	myInterfaceList.push_back(smptr2);

	char symbolT = _T('0');

	STL_FOR_ALL_CONST(myInterfaceList, it)
	{
		rdo::Interface<IMy1> ptr1;
		ptr1 = *it;
		if (ptr1)
		{
			symbolT = (*it == smptr ? initFValue : (*it == smptr2 ? initSValue : initTValue));
			BOOST_CHECK_EQUAL(ptr1->fun1(), strIMy1 + symbolT);
		}

		rdo::Interface<IMy2> ptr2 = *it;
		if (ptr2)
		{
			symbolT = (*it == smptr ? initFValue : (*it == smptr2 ? initSValue : initTValue));
			BOOST_CHECK_EQUAL(ptr2->fun2(), strIMy2 + symbolT);
		}

		rdo::Interface<IMy3> ptr3 = *it;
		if (ptr3)
		{
			symbolT = (*it == smptr ? initFValue : (*it == smptr2 ? initSValue : initTValue));
			BOOST_CHECK_EQUAL(ptr3->fun3(), strIMy3 + symbolT);
		}
	}
	s_logList.clear();
}

BOOST_AUTO_TEST_CASE(RdoInterfaceTest_ValidationFailureInThePreviousTest2)
{
	LogList::iterator it = s_logList.begin();
	BOOST_CHECK_EQUAL(*it, strMyClass3Destroy);
	++it;
	BOOST_CHECK_EQUAL(*it, strMyClass2Destroy);
	++it;
	BOOST_CHECK_EQUAL(*it, strMyClass1Destroy);
	++it;
	BOOST_CHECK_EQUAL(*it, strMyClass2Destroy);
	++it;
	BOOST_CHECK_EQUAL(*it, strMyClass1Destroy);
	s_logList.clear();
}

BOOST_AUTO_TEST_SUITE_END()
<commit_msg> - значения как в старом тесте<commit_after>/*
 * copyright: (c) RDO-Team, 2011
 * filename : main.cpp
 * author   :  , Evgeny Proydakov
 * date     : 07.07.2009
 * bref     :
 * indent   : 4T
 */

// ====================================================================== PCH
// ====================================================================== INCLUDES
#include <vector>
#include <list>
#include <iostream>
#define BOOST_TEST_MODULE RdoInterfaceTest
#include <boost/test/included/unit_test.hpp>
// ====================================================================== SYNOPSIS
#include "rdo_common/rdointerface.h"
// ===============================================================================

#define DISABLE_CONSOLE_OUTPUT

const tstring strIMy1            = _T("void fun1():  ");
const tstring strIMy2            = _T("void fun2():  ");
const tstring strIMy3            = _T("void fun3():  ");
const tstring strMyClass1Create  = _T("MyClass1():"   );
const tstring strMyClass1Destroy = _T("~MyClass1():"  );
const tstring strMyClass2Create  = _T("MyClass2():"   );
const tstring strMyClass2Destroy = _T("~MyClass2():"  );
const tstring strMyClass3Create  = _T("MyClass3():"   );
const tstring strMyClass3Destroy = _T("~MyClass3():"  );

typedef std::list<tstring> LogList;
LogList s_logList;

class IMy1
{
public:
	virtual tstring fun1() = 0;
};

class IMy2
{
public:
	virtual tstring fun2() = 0;
};

class IMy3
{
public:
	virtual tstring fun3() = 0;
};

class IMy4
{
public:
	virtual tstring fun4() = 0;
};

INTERFACE_REGISTRATOR(IMy1, 1);
INTERFACE_REGISTRATOR(IMy2, 2);
INTERFACE_REGISTRATOR(IMy3, 3);
INTERFACE_REGISTRATOR(IMy4, 4);

class MyClass1: public rdo::IGetUnknown, public IMy1, public IMy2, public IInit
{
QUERY_INTERFACE_BEGIN
	QUERY_INTERFACE(IMy1)
	QUERY_INTERFACE(IMy2)
	QUERY_INTERFACE(IInit)
QUERY_INTERFACE_END

protected:
	MyClass1(char i)
		: m_i(i)
	{
#ifndef DISABLE_CONSOLE_OUTPUT
		std::cout << strMyClass1Create << i << std::endl;
#endif
		s_logList.push_back(strMyClass1Create + i);
	}
	~MyClass1()
	{
#ifndef DISABLE_CONSOLE_OUTPUT
		std::cout << strMyClass1Destroy << m_i << std::endl;
#endif
		s_logList.push_back(strMyClass1Destroy);
	}
	rbool init()
	{
		return true;
	}

protected:
	char m_i;

private:
	tstring fun1()
	{
#ifndef DISABLE_CONSOLE_OUTPUT
		std::cout << strIMy1 << m_i << std::endl;
#endif
		return strIMy1 + m_i;
	}
	tstring fun2()
	{
#ifndef DISABLE_CONSOLE_OUTPUT
		std::cout << strIMy2 << m_i << std::endl;
#endif
		return strIMy2 + m_i;
	}
};

class MyClass2: public MyClass1, public IMy3
{
DEFINE_IFACTORY(MyClass2);
QUERY_INTERFACE_BEGIN
	QUERY_INTERFACE_PARENT(MyClass1)
	QUERY_INTERFACE(IMy3)
QUERY_INTERFACE_END

private:
	MyClass2(char i)
		: MyClass1(i)
	{
#ifndef DISABLE_CONSOLE_OUTPUT
		std::cout << strMyClass2Create << i << std::endl;
#endif
		s_logList.push_back(strMyClass2Create + i);
	}
	~MyClass2()
	{
#ifndef DISABLE_CONSOLE_OUTPUT
		std::cout << strMyClass2Destroy << m_i << std::endl;
#endif
		s_logList.push_back(strMyClass2Destroy);
	}
	tstring fun3()
	{
		ASSERT(this);
		LPIMy1 int1 = this;
		ASSERT(int1)

#ifndef DISABLE_CONSOLE_OUTPUT
		std::cout << strIMy3 << m_i << std::endl;
#endif
		return strIMy3 + m_i;
	}
};

class MyClass3: public IMy3, public rdo::IGetUnknown
{
DEFINE_IFACTORY(MyClass3);
QUERY_INTERFACE_BEGIN
	QUERY_INTERFACE(IMy3)
QUERY_INTERFACE_END

protected:
	MyClass3(char i)
		: m_i(i)
	{
#ifndef DISABLE_CONSOLE_OUTPUT
		std::cout << strMyClass3Create << i << std::endl;
#endif
		s_logList.push_back(strMyClass3Create + i);
	}
	~MyClass3()
	{
#ifndef DISABLE_CONSOLE_OUTPUT
		std::cout << strMyClass3Destroy << m_i << std::endl;
#endif
		s_logList.push_back(strMyClass3Destroy);
	}

protected:
	char m_i;

private:
	tstring fun3()
	{
#ifndef DISABLE_CONSOLE_OUTPUT
		std::cout << strIMy3 << m_i << std::endl;
#endif
		return strIMy3 + m_i;
	}
};

typedef rdo::Interface<IMy3>     MyInterface;
typedef std::vector<MyInterface> MyInterfaceList;

BOOST_AUTO_TEST_SUITE(RdoInterfaceTest)

BOOST_AUTO_TEST_CASE(RdoInterfaceTest_CheckingOnTheSameOperator)
{
	char initValue = _T('1');
	rdo::UnknownPointer smptr = F(MyClass2)::create(initValue);
	BOOST_REQUIRE(smptr);

	LogList::iterator it = s_logList.begin();
	BOOST_CHECK_EQUAL(*it,     strMyClass1Create + initValue);
	BOOST_CHECK_EQUAL(*(++it), strMyClass2Create + initValue);
	s_logList.clear();

	BOOST_CHECK_EQUAL(smptr.query_cast<IMy1>()->fun1(), strIMy1 + initValue);
	BOOST_CHECK_EQUAL(smptr.query_cast<IMy3>()->fun3(), strIMy3 + initValue);

	initValue = _T('2');
	MyInterface         imy3 = smptr;
	rdo::UnknownPointer smptr2;
	smptr2 = F(MyClass2)::create(initValue);
	it = s_logList.begin();
	BOOST_CHECK_EQUAL(*it,     strMyClass1Create + initValue);
	BOOST_CHECK_EQUAL(*(++it), strMyClass2Create + initValue);
	s_logList.clear();

	rdo::UnknownPointer smptr2_2 = smptr2;
	//BOOST_CHECK(smptr2_2 == smptr);
	//BOOST_CHECK_EQUAL(smptr2_2, smptr);
	BOOST_CHECK(smptr2_2 == smptr2);

	rdo::Interface<IMy1> int1_1 = smptr;
	rdo::Interface<IMy1> int2_1 = smptr2;
	rdo::Interface<IMy1> int1_2 = smptr;
	//BOOST_CHECK(int1_1 == int2_1);
	//BOOST_CHECK_EQUAL(int1_1, int2_1);
	BOOST_CHECK(int1_1 == int1_2);
}

BOOST_AUTO_TEST_CASE(RdoInterfaceTest_ValidationFailureInThePreviousTest1)
{
	LogList::iterator it = s_logList.begin();
	BOOST_CHECK_EQUAL(*it, strMyClass2Destroy);
	++it;
	BOOST_CHECK_EQUAL(*it, strMyClass1Destroy);
	++it;
	BOOST_CHECK_EQUAL(*it, strMyClass2Destroy);
	++it;
	BOOST_CHECK_EQUAL(*it, strMyClass1Destroy);
	s_logList.clear();
}

BOOST_AUTO_TEST_CASE(RdoInterfaceTest_Working)
{
	char initFValue = _T('2');
	rdo::UnknownPointer smptr = F(MyClass2)::create(initFValue);
	LogList::iterator iter = s_logList.begin();
	BOOST_CHECK_EQUAL(*iter, strMyClass1Create + initFValue);
	BOOST_CHECK_EQUAL(*(++iter), strMyClass2Create + initFValue);
	s_logList.clear();

	char initSValue = _T('5');
	rdo::UnknownPointer smptr2 = F(MyClass2)::create(initSValue);
	iter = s_logList.begin();
	BOOST_CHECK_EQUAL(*iter, strMyClass1Create + initSValue);
	BOOST_CHECK_EQUAL(*(++iter), strMyClass2Create + initSValue);
	s_logList.clear();

	MyInterfaceList myInterfaceList;

	char initTValue = _T('9');
	myInterfaceList.push_back(F(MyClass3)::create(initTValue));
	myInterfaceList.push_back(smptr );
	myInterfaceList.push_back(smptr2);

	char symbolT = _T('0');

	STL_FOR_ALL_CONST(myInterfaceList, it)
	{
		rdo::Interface<IMy1> ptr1;
		ptr1 = *it;
		if (ptr1)
		{
			symbolT = (*it == smptr ? initFValue : (*it == smptr2 ? initSValue : initTValue));
			BOOST_CHECK_EQUAL(ptr1->fun1(), strIMy1 + symbolT);
		}

		rdo::Interface<IMy2> ptr2 = *it;
		if (ptr2)
		{
			symbolT = (*it == smptr ? initFValue : (*it == smptr2 ? initSValue : initTValue));
			BOOST_CHECK_EQUAL(ptr2->fun2(), strIMy2 + symbolT);
		}

		rdo::Interface<IMy3> ptr3 = *it;
		if (ptr3)
		{
			symbolT = (*it == smptr ? initFValue : (*it == smptr2 ? initSValue : initTValue));
			BOOST_CHECK_EQUAL(ptr3->fun3(), strIMy3 + symbolT);
		}
	}
	s_logList.clear();
}

BOOST_AUTO_TEST_CASE(RdoInterfaceTest_ValidationFailureInThePreviousTest2)
{
	LogList::iterator it = s_logList.begin();
	BOOST_CHECK_EQUAL(*it, strMyClass3Destroy);
	++it;
	BOOST_CHECK_EQUAL(*it, strMyClass2Destroy);
	++it;
	BOOST_CHECK_EQUAL(*it, strMyClass1Destroy);
	++it;
	BOOST_CHECK_EQUAL(*it, strMyClass2Destroy);
	++it;
	BOOST_CHECK_EQUAL(*it, strMyClass1Destroy);
	s_logList.clear();
}

BOOST_AUTO_TEST_SUITE_END()
<|endoftext|>


<commit_before>#ifndef DISSENT_CONNECTIONS_CONNECTION_TABLE_H_GUARD
#define DISSENT_CONNECTIONS_CONNECTION_TABLE_H_GUARD

#include <QDebug>
#include <QHash>

#include "Id.hpp"

namespace Dissent {
namespace Transports {
  class Edge;
}

namespace Connections {
  class Connection;

  /**
   * Contains mappings for remote peers
   */
  class ConnectionTable {
    public:
      typedef Dissent::Transports::Edge Edge;

      /**
       * Constructor
       * @param local_id so we have a "connection" to ourself
       */
      explicit ConnectionTable(const Id &local_id = Id::Zero());

      /**
       * Deconstructor
       */
      ~ConnectionTable();

      /**
       * Add an edge
       * @param edge the edge to add
       */
      void AddEdge(QSharedPointer<Edge> edge);

      /**
       * Add an edge
       * @param edge the edge to add
       */
      void AddEdge(Edge *edge);

      /**
       * Remove an edge, returns true if it is stored
       * @param edge the edge to remvoe
       */
      bool RemoveEdge(const Edge *edge);

      /**
       * Remove an edge, returns true if it is stored
       * @param edge the edge to remvoe
       */
      bool RemoveEdge(QSharedPointer<Edge> edge);

      inline bool Contains(const Connection *con) { return _cons.contains(con); }

      /**
       * Remove a connection from being looked up by Id or Edge, returns
       * true if exists.  Should be called after calling disconnect but
       * before an edge is closed.
       * @param con the connection to remove
       */
      bool Disconnect(Connection *con);

      /**
       * Returns the connection matching to the Id or 0 if none exists
       * @param id the Id to lookup
       */
      Connection *GetConnection(const Id &id) const;

      /**
       * Returns the connection matching to the Id or 0 if none exists
       * @param id the Id to lookup
       */
      Connection *GetConnection(QSharedPointer<Edge> edge) const;

      /**
       * Returns a the connection matching to the edge or 0 if none exists
       * @param edge the edge to lookup
       */
      Connection *GetConnection(const Edge *edge) const;

      inline const QList<Connection *> GetConnections() const { return _cons.values(); }

      inline QSharedPointer<Edge> GetEdge(const Edge * edge) const { return _edges[edge]; }
      inline const QList<QSharedPointer<Edge> > GetEdges() const { return _edges.values(); }

      /**
       * Adds a Connection
       * @param con the connection to add
       */
      void AddConnection(Connection *con);

      /**
       * Removes the connection from being stored, returns true if exists.
       * Should only be called after the edge has been closed.
       * @param con the stored connection
       */
      bool RemoveConnection(Connection *con);

      /**
       * Print connection table to debug output
       */
      void PrintConnectionTable();

    private:
      /**
       * Stores Id to Connection mappings
       */
      QHash<const Id, Connection *> _id_to_con;

      /**
       * Stores Edge to Connection mappings
       */
      QHash<const Edge *, Connection *> _edge_to_con;

      /**
       * Stores Connections
       */
      QHash<const Connection *, Connection *> _cons;

      /**
       * Stores Edges
       */
      QHash<const Edge *, QSharedPointer<Edge> > _edges;
  };
}
}

#endif
<commit_msg>[Connections] Missed an include<commit_after>#ifndef DISSENT_CONNECTIONS_CONNECTION_TABLE_H_GUARD
#define DISSENT_CONNECTIONS_CONNECTION_TABLE_H_GUARD

#include <QDebug>
#include <QHash>
#include <QSharedPointer>

#include "Id.hpp"

namespace Dissent {
namespace Transports {
  class Edge;
}

namespace Connections {
  class Connection;

  /**
   * Contains mappings for remote peers
   */
  class ConnectionTable {
    public:
      typedef Dissent::Transports::Edge Edge;

      /**
       * Constructor
       * @param local_id so we have a "connection" to ourself
       */
      explicit ConnectionTable(const Id &local_id = Id::Zero());

      /**
       * Deconstructor
       */
      ~ConnectionTable();

      /**
       * Add an edge
       * @param edge the edge to add
       */
      void AddEdge(QSharedPointer<Edge> edge);

      /**
       * Add an edge
       * @param edge the edge to add
       */
      void AddEdge(Edge *edge);

      /**
       * Remove an edge, returns true if it is stored
       * @param edge the edge to remvoe
       */
      bool RemoveEdge(const Edge *edge);

      /**
       * Remove an edge, returns true if it is stored
       * @param edge the edge to remvoe
       */
      bool RemoveEdge(QSharedPointer<Edge> edge);

      inline bool Contains(const Connection *con) { return _cons.contains(con); }

      /**
       * Remove a connection from being looked up by Id or Edge, returns
       * true if exists.  Should be called after calling disconnect but
       * before an edge is closed.
       * @param con the connection to remove
       */
      bool Disconnect(Connection *con);

      /**
       * Returns the connection matching to the Id or 0 if none exists
       * @param id the Id to lookup
       */
      Connection *GetConnection(const Id &id) const;

      /**
       * Returns the connection matching to the Id or 0 if none exists
       * @param id the Id to lookup
       */
      Connection *GetConnection(QSharedPointer<Edge> edge) const;

      /**
       * Returns a the connection matching to the edge or 0 if none exists
       * @param edge the edge to lookup
       */
      Connection *GetConnection(const Edge *edge) const;

      inline const QList<Connection *> GetConnections() const { return _cons.values(); }

      inline QSharedPointer<Edge> GetEdge(const Edge * edge) const { return _edges[edge]; }
      inline const QList<QSharedPointer<Edge> > GetEdges() const { return _edges.values(); }

      /**
       * Adds a Connection
       * @param con the connection to add
       */
      void AddConnection(Connection *con);

      /**
       * Removes the connection from being stored, returns true if exists.
       * Should only be called after the edge has been closed.
       * @param con the stored connection
       */
      bool RemoveConnection(Connection *con);

      /**
       * Print connection table to debug output
       */
      void PrintConnectionTable();

    private:
      /**
       * Stores Id to Connection mappings
       */
      QHash<const Id, Connection *> _id_to_con;

      /**
       * Stores Edge to Connection mappings
       */
      QHash<const Edge *, Connection *> _edge_to_con;

      /**
       * Stores Connections
       */
      QHash<const Connection *, Connection *> _cons;

      /**
       * Stores Edges
       */
      QHash<const Edge *, QSharedPointer<Edge> > _edges;
  };
}
}

#endif
<|endoftext|>


<commit_before>#include "zcm/transport.h"
#include "zcm/transport_registrar.h"
#include "zcm/transport_register.hpp"
#include "zcm/util/debug.h"

#include "generic_serial_transport.h"

#include "util/TimeUtil.hpp"

#include <unistd.h>
#include <string.h>
#include <iostream>
#include <limits>
#include <cstdio>
#include <cassert>
#include <unordered_map>
#include <algorithm>

#include <net/if.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <linux/sockios.h>

#include <linux/can.h>
#include <linux/can/raw.h>

// Define this the class name you want
#define ZCM_TRANS_CLASSNAME TransportCan
#define MTU (1<<14)

using namespace std;

struct ZCM_TRANS_CLASSNAME : public zcm_trans_t
{
    unordered_map<string, string> options;
    uint msgId;
    string address;

    int soc = -1;
    bool socSettingsGood = false;
    struct sockaddr_can addr;
	struct ifreq ifr;

    zcm_trans_t* gst = nullptr;

    string* findOption(const string& s)
    {
        auto it = options.find(s);
        if (it == options.end()) return nullptr;
        return &it->second;
    }

    ZCM_TRANS_CLASSNAME(zcm_url_t* url)
    {
        trans_type = ZCM_BLOCKING;
        vtbl = &methods;

        // build 'options'
        auto* opts = zcm_url_opts(url);
        for (size_t i = 0; i < opts->numopts; ++i)
            options[opts->name[i]] = opts->value[i];

        msgId = 0;
        auto* msgIdStr = findOption("msgid");
        if (!msgIdStr) {
            ZCM_DEBUG("Msg Id unspecified");
            return;
        } else {
            char *endptr;
            msgId = strtoul(msgIdStr->c_str(), &endptr, 10);
            if (*endptr != '\0') {
                ZCM_DEBUG("Msg Id unspecified");
                return;
            }
        }

        address = zcm_url_address(url);

        if ((soc = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0) {
            ZCM_DEBUG("Unable to make socket");
		    return;
	    }

        strcpy(ifr.ifr_name, address.c_str());
        ioctl(soc, SIOCGIFINDEX, &ifr);

        memset(&addr, 0, sizeof(addr));
        addr.can_family = AF_CAN;
        addr.can_ifindex = ifr.ifr_ifindex;

        if (bind(soc, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
            ZCM_DEBUG("Failed to bind");
            return;
        }

        struct can_filter rfilter[1];

        rfilter[0].can_id   = msgId | CAN_EFF_FLAG;
        rfilter[0].can_mask = (CAN_EFF_FLAG | CAN_RTR_FLAG | CAN_EFF_MASK);

        if (setsockopt(soc, SOL_CAN_RAW, CAN_RAW_FILTER, &rfilter, sizeof(rfilter)) < 0) {
            ZCM_DEBUG("Failed to set filter");
            return;
        }

        gst = zcm_trans_generic_serial_create(&ZCM_TRANS_CLASSNAME::get,
                                              &ZCM_TRANS_CLASSNAME::put,
                                              this,
                                              &ZCM_TRANS_CLASSNAME::timestamp_now,
                                              this,
                                              MTU, MTU * 10);
        socSettingsGood = true;
    }

    ~ZCM_TRANS_CLASSNAME()
    {
        if (gst) zcm_trans_generic_serial_destroy(gst);
        if (soc != -1 && close(soc) < 0) {
            ZCM_DEBUG("Failed to close");
	    }
        soc = -1;
    }

    bool good()
    {
        return soc != -1 && socSettingsGood;
    }

    static size_t get(uint8_t* data, size_t nData, void* usr)
    {
        ZCM_TRANS_CLASSNAME* me = cast((zcm_trans_t*) usr);

        struct can_frame frame;
        int nbytes = read(me->soc, &frame, sizeof(struct can_frame));
        if (nbytes != sizeof(struct can_frame)) return 0;

        // XXX This isn't okay. We're just throwing out data if it
        //     doesn't fit in data on this one call to get
        size_t ret = min(nData, (size_t) frame.can_dlc);
        memcpy(data, frame.data, ret);
        return ret;
    }

    static size_t sendFrame(const uint8_t* data, size_t nData, void* usr)
    {
        ZCM_TRANS_CLASSNAME* me = cast((zcm_trans_t*) usr);

        struct can_frame frame;
        frame.can_id = me->msgId | CAN_EFF_FLAG;

        size_t ret = min(nData, (size_t) 8);
        frame.can_dlc = ret;
        memcpy(frame.data, data, ret);

        if (write(me->soc, &frame, sizeof(struct can_frame)) != sizeof(struct can_frame)) {
            ZCM_DEBUG("Failed to write data");
            return -1;
        }

        return ret;
    }

    static size_t put(const uint8_t* data, size_t nData, void* usr)
    {
        size_t ret = 0;
        while (ret < nData) {
            size_t left = nData - ret;
            size_t written = sendFrame(&data[ret], left, usr);
            if (written <= 0) return ret;
            ret += written;
        }
        return ret;
    }

    static uint64_t timestamp_now(void* usr)
    {
        ZCM_TRANS_CLASSNAME* me = cast((zcm_trans_t*) usr);

        struct timeval time;
        if (ioctl(me->soc, SIOCGSTAMP, &time) == -1) return 0;
        return time.tv_sec * 1e6 + time.tv_usec;
    }

    /********************** METHODS **********************/
    size_t get_mtu()
    {
        return zcm_trans_get_mtu(this->gst);
    }

    int sendmsg(zcm_msg_t msg)
    {
        int ret = zcm_trans_sendmsg(this->gst, msg);
        if (ret != ZCM_EOK) return ret;
        return serial_update_tx(this->gst);
    }

    int recvmsgEnable(const char* channel, bool enable)
    {
        return zcm_trans_recvmsg_enable(this->gst, channel, enable);
    }

    int recvmsg(zcm_msg_t* msg, int timeoutMs)
    {
        int timeoutS = timeoutMs / 1000;
        struct timeval tm = {
            timeoutS,                                 /* seconds */
            (timeoutMs - (timeoutS * 1000)) * 1000    /* micros */
        };
        if (setsockopt(soc, SOL_SOCKET, SO_RCVTIMEO, (char *)&tm, sizeof(tm)) < 0) {
            ZCM_DEBUG("Failed to settimeout");
            return ZCM_EUNKNOWN;
        }

        uint64_t startUtime = TimeUtil::utime();
        uint64_t timeoutUs = timeoutMs > 0 ? timeoutMs * 1e3 : numeric_limits<uint64_t>::max();
        uint64_t timeoutLeft = timeoutUs;

        do {
            int ret = zcm_trans_recvmsg(this->gst, msg, timeoutLeft);
            if (ret == ZCM_EOK) return ret;
            serial_update_rx(this->gst);

            uint64_t diff = TimeUtil::utime() - startUtime;
            timeoutLeft = timeoutUs > diff ? timeoutUs - diff : 0;
        } while (timeoutLeft > 0);
        return ZCM_EAGAIN;
    }

    /********************** STATICS **********************/
    static zcm_trans_methods_t methods;
    static ZCM_TRANS_CLASSNAME *cast(zcm_trans_t *zt)
    {
        assert(zt->vtbl == &methods);
        return (ZCM_TRANS_CLASSNAME*)zt;
    }

    static size_t _get_mtu(zcm_trans_t *zt)
    { return cast(zt)->get_mtu(); }

    static int _sendmsg(zcm_trans_t *zt, zcm_msg_t msg)
    { return cast(zt)->sendmsg(msg); }

    static int _recvmsg_enable(zcm_trans_t *zt, const char *channel, bool enable)
    { return cast(zt)->recvmsgEnable(channel, enable); }

    static int _recvmsg(zcm_trans_t *zt, zcm_msg_t *msg, int timeout)
    { return cast(zt)->recvmsg(msg, timeout); }

    static void _destroy(zcm_trans_t *zt)
    { delete cast(zt); }

    /** If you choose to use the registrar, use a static registration member **/
    static const TransportRegister reg;
};

zcm_trans_methods_t ZCM_TRANS_CLASSNAME::methods = {
    &ZCM_TRANS_CLASSNAME::_get_mtu,
    &ZCM_TRANS_CLASSNAME::_sendmsg,
    &ZCM_TRANS_CLASSNAME::_recvmsg_enable,
    &ZCM_TRANS_CLASSNAME::_recvmsg,
    NULL,
    &ZCM_TRANS_CLASSNAME::_destroy,
};

static zcm_trans_t *create(zcm_url_t* url)
{
    auto* trans = new ZCM_TRANS_CLASSNAME(url);
    if (trans->good())
        return trans;

    delete trans;
    return nullptr;
}

#ifdef USING_TRANS_SERIAL
const TransportRegister ZCM_TRANS_CLASSNAME::reg(
    "can", "Transfer data via a socket CAN connection on a single id "
           "(e.g. 'can://can0?msgid=65536')", create);
#endif
<commit_msg>Minor<commit_after>#include "zcm/transport.h"
#include "zcm/transport_registrar.h"
#include "zcm/transport_register.hpp"
#include "zcm/util/debug.h"

#include "generic_serial_transport.h"

#include "util/TimeUtil.hpp"

#include <unistd.h>
#include <string.h>
#include <iostream>
#include <limits>
#include <cstdio>
#include <cassert>
#include <unordered_map>
#include <algorithm>

#include <net/if.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <linux/sockios.h>

#include <linux/can.h>
#include <linux/can/raw.h>

// Define this the class name you want
#define ZCM_TRANS_CLASSNAME TransportCan
#define MTU (1<<14)

using namespace std;

struct ZCM_TRANS_CLASSNAME : public zcm_trans_t
{
    unordered_map<string, string> options;
    uint msgId;
    string address;

    int soc = -1;
    bool socSettingsGood = false;
    struct sockaddr_can addr;
	struct ifreq ifr;

    zcm_trans_t* gst = nullptr;

    string* findOption(const string& s)
    {
        auto it = options.find(s);
        if (it == options.end()) return nullptr;
        return &it->second;
    }

    ZCM_TRANS_CLASSNAME(zcm_url_t* url)
    {
        trans_type = ZCM_BLOCKING;
        vtbl = &methods;

        // build 'options'
        auto* opts = zcm_url_opts(url);
        for (size_t i = 0; i < opts->numopts; ++i)
            options[opts->name[i]] = opts->value[i];

        msgId = 0;
        auto* msgIdStr = findOption("msgid");
        if (!msgIdStr) {
            ZCM_DEBUG("Msg Id unspecified");
            return;
        } else {
            char *endptr;
            msgId = strtoul(msgIdStr->c_str(), &endptr, 10);
            if (*endptr != '\0') {
                ZCM_DEBUG("Msg Id unspecified");
                return;
            }
        }

        address = zcm_url_address(url);

        if ((soc = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0) {
            ZCM_DEBUG("Unable to make socket");
		    return;
	    }

        strcpy(ifr.ifr_name, address.c_str());
        ioctl(soc, SIOCGIFINDEX, &ifr);

        memset(&addr, 0, sizeof(addr));
        addr.can_family = AF_CAN;
        addr.can_ifindex = ifr.ifr_ifindex;

        if (bind(soc, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
            ZCM_DEBUG("Failed to bind");
            return;
        }

        struct can_filter rfilter[1];

        rfilter[0].can_id   = msgId | CAN_EFF_FLAG;
        rfilter[0].can_mask = (CAN_EFF_FLAG | CAN_RTR_FLAG | CAN_EFF_MASK);

        if (setsockopt(soc, SOL_CAN_RAW, CAN_RAW_FILTER, &rfilter, sizeof(rfilter)) < 0) {
            ZCM_DEBUG("Failed to set filter");
            return;
        }

        gst = zcm_trans_generic_serial_create(&ZCM_TRANS_CLASSNAME::get,
                                              &ZCM_TRANS_CLASSNAME::put,
                                              this,
                                              &ZCM_TRANS_CLASSNAME::timestamp_now,
                                              this,
                                              MTU, MTU * 10);
        socSettingsGood = true;
    }

    ~ZCM_TRANS_CLASSNAME()
    {
        if (gst) zcm_trans_generic_serial_destroy(gst);
        if (soc != -1 && close(soc) < 0) {
            ZCM_DEBUG("Failed to close");
	    }
        soc = -1;
    }

    bool good()
    {
        return soc != -1 && socSettingsGood;
    }

    static size_t get(uint8_t* data, size_t nData, void* usr)
    {
        ZCM_TRANS_CLASSNAME* me = cast((zcm_trans_t*) usr);

        struct can_frame frame;
        int nbytes = read(me->soc, &frame, sizeof(struct can_frame));
        if (nbytes != sizeof(struct can_frame)) return 0;

        // XXX This isn't okay. We're just throwing out data if it
        //     doesn't fit in data on this one call to get
        size_t ret = min(nData, (size_t) frame.can_dlc);
        memcpy(data, frame.data, ret);
        return ret;
    }

    static size_t sendFrame(const uint8_t* data, size_t nData, void* usr)
    {
        ZCM_TRANS_CLASSNAME* me = cast((zcm_trans_t*) usr);

        struct can_frame frame;
        frame.can_id = me->msgId | CAN_EFF_FLAG;

        size_t ret = min(nData, (size_t) 8);
        frame.can_dlc = ret;
        memcpy(frame.data, data, ret);

        if (write(me->soc, &frame, sizeof(struct can_frame)) != sizeof(struct can_frame)) {
            ZCM_DEBUG("Failed to write data");
            return -1;
        }

        return ret;
    }

    static size_t put(const uint8_t* data, size_t nData, void* usr)
    {
        size_t ret = 0;
        while (ret < nData) {
            size_t left = nData - ret;
            size_t written = sendFrame(&data[ret], left, usr);
            if (written <= 0) return ret;
            ret += written;
        }
        return ret;
    }

    static uint64_t timestamp_now(void* usr)
    {
        ZCM_TRANS_CLASSNAME* me = cast((zcm_trans_t*) usr);

        struct timeval time;
        if (ioctl(me->soc, SIOCGSTAMP, &time) == -1) return 0;
        return time.tv_sec * 1e6 + time.tv_usec;
    }

    /********************** METHODS **********************/
    size_t get_mtu()
    {
        return zcm_trans_get_mtu(this->gst);
    }

    int sendmsg(zcm_msg_t msg)
    {
        int ret = zcm_trans_sendmsg(this->gst, msg);
        if (ret != ZCM_EOK) return ret;
        return serial_update_tx(this->gst);
    }

    int recvmsgEnable(const char* channel, bool enable)
    {
        return zcm_trans_recvmsg_enable(this->gst, channel, enable);
    }

    int recvmsg(zcm_msg_t* msg, int timeoutMs)
    {
        int timeoutS = timeoutMs / 1000;
        timeoutMs -= timeoutS * 1000;
        struct timeval tm = {
            timeoutS,           /* seconds */
            timeoutMs * 1000    /* micros */
        };
        if (setsockopt(soc, SOL_SOCKET, SO_RCVTIMEO, (char *)&tm, sizeof(tm)) < 0) {
            ZCM_DEBUG("Failed to settimeout");
            return ZCM_EUNKNOWN;
        }

        uint64_t startUtime = TimeUtil::utime();
        uint64_t timeoutUs = timeoutMs > 0 ? timeoutMs * 1e3 : numeric_limits<uint64_t>::max();
        uint64_t timeoutLeft = timeoutUs;

        do {
            int ret = zcm_trans_recvmsg(this->gst, msg, timeoutLeft);
            if (ret == ZCM_EOK) return ret;
            serial_update_rx(this->gst);

            uint64_t diff = TimeUtil::utime() - startUtime;
            timeoutLeft = timeoutUs > diff ? timeoutUs - diff : 0;
        } while (timeoutLeft > 0);
        return ZCM_EAGAIN;
    }

    /********************** STATICS **********************/
    static zcm_trans_methods_t methods;
    static ZCM_TRANS_CLASSNAME *cast(zcm_trans_t *zt)
    {
        assert(zt->vtbl == &methods);
        return (ZCM_TRANS_CLASSNAME*)zt;
    }

    static size_t _get_mtu(zcm_trans_t *zt)
    { return cast(zt)->get_mtu(); }

    static int _sendmsg(zcm_trans_t *zt, zcm_msg_t msg)
    { return cast(zt)->sendmsg(msg); }

    static int _recvmsg_enable(zcm_trans_t *zt, const char *channel, bool enable)
    { return cast(zt)->recvmsgEnable(channel, enable); }

    static int _recvmsg(zcm_trans_t *zt, zcm_msg_t *msg, int timeout)
    { return cast(zt)->recvmsg(msg, timeout); }

    static void _destroy(zcm_trans_t *zt)
    { delete cast(zt); }

    /** If you choose to use the registrar, use a static registration member **/
    static const TransportRegister reg;
};

zcm_trans_methods_t ZCM_TRANS_CLASSNAME::methods = {
    &ZCM_TRANS_CLASSNAME::_get_mtu,
    &ZCM_TRANS_CLASSNAME::_sendmsg,
    &ZCM_TRANS_CLASSNAME::_recvmsg_enable,
    &ZCM_TRANS_CLASSNAME::_recvmsg,
    NULL,
    &ZCM_TRANS_CLASSNAME::_destroy,
};

static zcm_trans_t *create(zcm_url_t* url)
{
    auto* trans = new ZCM_TRANS_CLASSNAME(url);
    if (trans->good())
        return trans;

    delete trans;
    return nullptr;
}

#ifdef USING_TRANS_SERIAL
const TransportRegister ZCM_TRANS_CLASSNAME::reg(
    "can", "Transfer data via a socket CAN connection on a single id "
           "(e.g. 'can://can0?msgid=65536')", create);
#endif
<|endoftext|>