1841b46d77610d10393b67122e522b19e3f96dad
[senf.git] / senf / Packets / PacketInterpreter.cc
1 // $Id$
2 //
3 // Copyright (C) 2007
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 //
6 // The contents of this file are subject to the Fraunhofer FOKUS Public License
7 // Version 1.0 (the "License"); you may not use this file except in compliance
8 // with the License. You may obtain a copy of the License at 
9 // http://senf.berlios.de/license.html
10 //
11 // The Fraunhofer FOKUS Public License Version 1.0 is based on, 
12 // but modifies the Mozilla Public License Version 1.1.
13 // See the full license text for the amendments.
14 //
15 // Software distributed under the License is distributed on an "AS IS" basis, 
16 // WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 
17 // for the specific language governing rights and limitations under the License.
18 //
19 // The Original Code is Fraunhofer FOKUS code.
20 //
21 // The Initial Developer of the Original Code is Fraunhofer-Gesellschaft e.V. 
22 // (registered association), Hansastraße 27 c, 80686 Munich, Germany.
23 // All Rights Reserved.
24 //
25 // Contributor(s):
26 //   Stefan Bund <g0dil@berlios.de>
27
28 /** \file
29     \brief PacketInterpreter non-inline non-template implementation */
30
31 //#include "PacketInterpreter.ih"
32
33 // Custom includes
34 #include "Packets.hh"
35
36 //#include "PacketInterpreter.mpp"
37 #define prefix_
38 //-/////////////////////////////////////////////////////////////////////////////////////////////////
39
40 //-/////////////////////////////////////////////////////////////////////////////////////////////////
41 // senf::PacketInterpreterBase
42
43 // structors and default members
44
45 prefix_ senf::PacketInterpreterBase::ptr senf::PacketInterpreterBase::clone()
46 {
47     detail::PacketImpl::Guard p (new detail::PacketImpl(begin(),end()));
48     ptr pi (appendClone(p.p,begin(),p.p->begin()));
49     for (ptr i (next()); i; i = i->next())
50         i->appendClone(p.p,begin(),p.p->begin());
51     pi->impl().assignAnnotations( impl());
52     return pi;
53 }
54
55 // Interpreter chain access
56
57 prefix_ senf::PacketInterpreterBase::ptr senf::PacketInterpreterBase::append(ptr packet)
58 {
59     if (next())
60         impl().truncateInterpreters(next().get());
61
62     optional_range r (nextPacketRange());
63     if (!r)
64         throw InvalidPacketChainException();
65
66     ptr rv (packet->appendClone(&impl(), *r));
67     rv->data().resize(packet->data().size());
68     std::copy(packet->data().begin(), packet->data().end(), rv->data().begin());
69
70     for (ptr p (packet->next()) ; p ; p = p->next())
71         p->appendClone(&impl(), packet->data().begin(), rv->data().begin());
72
73     return rv;
74 }
75
76 prefix_ void senf::PacketInterpreterBase::reparse()
77 {
78     if (next())
79         impl().truncateInterpreters(next().get());
80 }
81
82 // Access to the abstract interface
83
84 prefix_ void senf::PacketInterpreterBase::dump(std::ostream & os)
85 {
86     try {
87         if (detail::AnnotationRegistry::instance().begin()
88             != detail::AnnotationRegistry::instance().end()) {
89             os << "Annotations:\n";
90             impl().dumpAnnotations(os);
91         }
92         v_dump(os);
93         for (ptr i (next()); i; i = i->next())
94             i->v_dump(os);
95     }
96     catch (senf::Exception & e) {
97         os << "[Exception: " << e.message() << "]\n";
98     }
99 }
100
101 prefix_ void senf::PacketInterpreterBase::finalizeThis()
102 {
103     v_finalize();
104 }
105
106 prefix_ void senf::PacketInterpreterBase::finalizeTo(ptr other)
107 {
108     for (ptr i (other); i.get() != this && i.get(); i = i->prev())
109         i->finalizeThis();
110     finalizeThis();
111 }
112
113 // reference/memory management
114
115 prefix_ void senf::PacketInterpreterBase::add_ref()
116 {
117     if (impl_ && !refcount())
118         impl_->add_ref();
119     intrusive_refcount_t<PacketInterpreterBase>::add_ref();
120 }
121
122 prefix_ void senf::PacketInterpreterBase::release()
123 {
124     if (impl_ && refcount()==1)
125         // This call will set impl_ to 0 if we just removed the last reference ...
126         impl_->release();
127     if (intrusive_refcount_t<PacketInterpreterBase>::release() && !impl_)
128         delete this;
129 }
130
131 //-/////////////////////////////////////////////////////////////////////////////////////////////////
132 // senf::PacketInterpreterBase::Factory
133
134 prefix_  senf::PacketInterpreterBase::Factory::~Factory()
135 {}
136
137 //-/////////////////////////////////////////////////////////////////////////////////////////////////
138 #undef prefix_
139 //#include "PacketInterpreter.mpp"
140
141 \f
142 // Local Variables:
143 // mode: c++
144 // fill-column: 100
145 // c-file-style: "senf"
146 // indent-tabs-mode: nil
147 // ispell-local-dictionary: "american"
148 // compile-command: "scons -u test"
149 // comment-column: 40
150 // End: