Newer
Older
// Copyright (C) 2007
// Fraunhofer Institute for Open Communication Systems (FOKUS)
// Competence Center NETwork research (NET), St. Augustin, GERMANY
// Stefan Bund <g0dil@berlios.de>
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the
// Free Software Foundation, Inc.,
// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
/** \file
\brief PacketImpl inline non-template implementation */
// Custom includes
#include "../Utils/senfassert.hh"
// #include "PacketInterpreter.hh"
#define prefix_ inline
///////////////////////////////cci.p///////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
// senf::detail::AnnotationIndexerBase
prefix_ senf::detail::AnnotationIndexerBase::~AnnotationIndexerBase()
{}
prefix_ std::vector<bool> & senf::detail::AnnotationIndexerBase::small()
{
static std::vector<bool> smalls;
return smalls;
}
prefix_ std::vector<senf::detail::AnnotationIndexerBase*> &
senf::detail::AnnotationIndexerBase::registry()
{
static std::vector<AnnotationIndexerBase*> reg;
return reg;
}
///////////////////////////////////////////////////////////////////////////
// senf::detail::AnnotationP
prefix_ senf::detail::AnnotationP::~AnnotationP()
{}
// Memory management:
// * The PacketImpl destructor will *explicitly* clean-up the interpreters_ list by removing
// each element from the list and deleting it if it's (intrusive) refcount is 0
// * The PacketInterpreters use safe hooks -> they know wether they are part of a list or not
// * PacketHandle has an intrusive_ptr to PacketInterpreterBase. The intrusive_ptr_add_ref
// will refcount both the PacketImpl as well as the PacketInterpreterBase
// * intrusive_ptr_remove will only delete the object if it's not in a container
// * removing an object from the list will decrement the PacketImpl refcount accordingly
// * inserting an object into the list will incroment the PacketImpl refcount accordingly
// * each PacketInterpreterBase instance holds a *raw* pointer to the PacketImpl
//
// The following operations change refcounts:
//
// * intrusive_ptr_add_ref(PacketInterpreterBase *);
// * intrusive_ptr_remove(PacketInterpreterBase *);
// * PacketImpl::appendInterpreter();
// * PacketImpl::prependInterpreter();
// * PacketImpl::truncateInterpreters();
//
// The last three also modify the impl_ member accordingly by calling
// PacketInterpreterBase::assign/release
///////////////////////////////////////////////////////////////////////////
// senf::detail::PacketImpl
prefix_ senf::detail::PacketImpl::PacketImpl()
: refcount_(0), annotations_(AnnotationIndexerBase::maxAnnotations)
{}
prefix_ senf::detail::PacketImpl::PacketImpl(size_type size, byte initValue)
: refcount_(0), data_(size,initValue), annotations_(AnnotationIndexerBase::maxAnnotations)
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
{}
// rerference/memory management
prefix_ void senf::detail::PacketImpl::add_ref(refcount_t n)
{
refcount_ += n;
}
prefix_ senf::detail::PacketImpl::refcount_t senf::detail::PacketImpl::refcount()
const
{
return refcount_;
}
// Interpreter chain
prefix_ senf::PacketInterpreterBase * senf::detail::PacketImpl::first()
{
return interpreters_.empty() ? 0 : & interpreters_.front();
}
prefix_ senf::PacketInterpreterBase * senf::detail::PacketImpl::last()
{
return interpreters_.empty() ? 0 : & interpreters_.back();
}
prefix_ senf::PacketInterpreterBase * senf::detail::PacketImpl::next(PacketInterpreterBase * p)
{
interpreter_list::iterator i (interpreter_list::current(*p));
return (++i == interpreters_.end()) ? 0 : &*i;
}
prefix_ senf::PacketInterpreterBase * senf::detail::PacketImpl::prev(PacketInterpreterBase * p)
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
interpreter_list::iterator i (interpreter_list::current(*p));
return (i == interpreters_.begin()) ? 0 : &*(--i);
}
prefix_ void senf::detail::PacketImpl::truncateInterpreters(PacketInterpreterBase * p)
{
Guard guard (this);
eraseInterpreters(interpreter_list::current(*p),interpreters_.end());
}
prefix_ void senf::detail::PacketImpl::truncateInterpretersBackwards(PacketInterpreterBase * p)
{
Guard guard (this);
eraseInterpreters(interpreters_.begin(),boost::next(interpreter_list::current(*p)));
}
// Data container
prefix_ senf::detail::PacketImpl::iterator senf::detail::PacketImpl::begin()
{
return data_.begin();
}
prefix_ senf::detail::PacketImpl::iterator senf::detail::PacketImpl::end()
{
return data_.end();
}
prefix_ senf::detail::PacketImpl::size_type senf::detail::PacketImpl::size()
{
return data_.size();
}
prefix_ void senf::detail::PacketImpl::insert(PacketData * self, iterator pos, byte v)
{
difference_type ix (std::distance(begin(),pos));
data_.insert(pos,v);
}
prefix_ void senf::detail::PacketImpl::insert(PacketData * self, iterator pos, size_type n,
byte v)
{
difference_type ix (std::distance(begin(),pos));
data_.insert(pos,n,v);
}
prefix_ void senf::detail::PacketImpl::erase(PacketData * self, iterator pos)
{
difference_type ix (std::distance(begin(),pos));
data_.erase(pos);
updateIterators(self,ix,-1);
}
prefix_ void senf::detail::PacketImpl::erase(PacketData * self, iterator first, iterator last)
{
difference_type ix (std::distance(begin(),first));
difference_type delta (std::distance(first,last));
data_.erase(first,last);
updateIterators(self,ix,-delta);
prefix_ void senf::detail::PacketImpl::reserve(size_type n)
{
data_.reserve(n);
}
prefix_ senf::detail::PacketImpl::size_type senf::detail::PacketImpl::capacity()
const
{
return data_.capacity();
}
prefix_ void senf::detail::PacketImpl::dumpAnnotations(std::ostream & os)
{
AnnotationIndexerBase::dump(this, os);
}
// This function has a problem being inlined. Somehow, often when calling this, the size of the
// resulting inlined code would be huge?
prefix_ void senf::detail::PacketImpl::release(refcount_t n)
{
SENF_ASSERT(refcount_ >= n);
// uah ... we need to be extremely careful here. If refcount_ is n, we want to commit suicide,
// however the destructor will remove all PacketInterpreters from the list and will thereby
// decrement refcount -> only decrenebt refcount_ when *not* caling delete
if (refcount_ == n)
delete this;
else
refcount_ -= n;
}
///////////////////////////////////////////////////////////////////////////
// senf::detail::PacketImpl::Guard
prefix_ senf::detail::PacketImpl::Guard::Guard(PacketImpl * impl)
: p (impl)
{
p->add_ref();
}
prefix_ senf::detail::PacketImpl::Guard::~Guard()
{
p->release();
}
///////////////////////////////cci.e///////////////////////////////////////
#undef prefix_
// Local Variables:
// mode: c++
// fill-column: 100
// c-file-style: "senf"
// indent-tabs-mode: nil
// ispell-local-dictionary: "american"
// compile-command: "scons -u test"
// comment-column: 40