Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 # include "Errata.h"
00024 # include <iostream>
00025 # include <sstream>
00026 # include <iomanip>
00027 # include <algorithm>
00028 # include <memory.h>
00029
00030 namespace ts {
00031
00032
00033
00034 namespace {
00035 std::deque<Errata::Sink::Handle> Sink_List;
00036 }
00037
00038 std::string const Errata::DEFAULT_GLUE("\n");
00039 Errata::Message const Errata::NIL_MESSAGE;
00040 Errata::Code Errata::Message::Default_Code = 0;
00041 Errata::Message::SuccessTest const Errata::Message::DEFAULT_SUCCESS_TEST =
00042 &Errata::Message::isCodeZero;
00043 Errata::Message::SuccessTest Errata::Message::Success_Test =
00044 Errata::Message::DEFAULT_SUCCESS_TEST;
00045
00046 bool
00047 Errata::Message::isCodeZero(Message const& msg) {
00048 return msg.m_code == 0;
00049 }
00050
00051 void
00052 Errata::Data::push(Message const& msg) {
00053 m_items.push_back(msg);
00054 }
00055
00056 Errata::Message const&
00057 Errata::Data::top() const {
00058 return m_items.size() ? m_items.back() : NIL_MESSAGE ;
00059 }
00060
00061 inline Errata::Errata(ImpPtr const& ptr)
00062 : m_data(ptr) {
00063 }
00064
00065 Errata::Data::~Data() {
00066 if (m_log_on_delete) {
00067 Errata tmp(this);
00068 std::deque<Errata::Sink::Handle>::iterator spot, limit;
00069 for ( spot = Sink_List.begin(), limit = Sink_List.end();
00070 spot != limit;
00071 ++spot
00072 ) {
00073 (**spot)(tmp);
00074 }
00075 tmp.m_data.release();
00076 }
00077 }
00078
00079 Errata::Errata() {
00080 }
00081
00082 Errata::Errata(self const& that)
00083 : m_data(that.m_data) {
00084 }
00085
00086 Errata::Errata(std::string const& text) {
00087 this->push(text);
00088 }
00089
00090 Errata::Errata(Id id, std::string const& text) {
00091 this->push(id, text);
00092 }
00093
00094 Errata::~Errata() {
00095 }
00096
00097
00098
00099
00100
00101 Errata::Data*
00102 Errata::pre_write() {
00103 if (m_data) {
00104 if (m_data.useCount() > 1) {
00105 m_data = new Data(*m_data);
00106 }
00107 } else {
00108 m_data = new Data;
00109 }
00110 return m_data.get();
00111 }
00112
00113
00114 Errata::Data*
00115 Errata::instance() {
00116 if (!m_data) m_data = new Data;
00117 return m_data.get();
00118 }
00119
00120 Errata&
00121 Errata::push(Message const& msg) {
00122 this->pre_write()->push(msg);
00123 return *this;
00124 }
00125
00126 Errata&
00127 Errata::operator=(self const& that) {
00128 m_data = that.m_data;
00129 return *this;
00130 }
00131
00132 Errata&
00133 Errata::operator = (Message const& msg) {
00134
00135 if (!m_data || m_data.useCount() > 1) {
00136 this->clear();
00137 this->push(msg);
00138 } else {
00139 m_data->m_items.clear();
00140 m_data->push(msg);
00141 }
00142 return *this;
00143 }
00144
00145 Errata&
00146 Errata::pull(self& that) {
00147 if (that.m_data) {
00148 this->pre_write();
00149 m_data->m_items.insert(
00150 m_data->m_items.end(),
00151 that.m_data->m_items.begin(),
00152 that.m_data->m_items.end()
00153 );
00154 that.m_data->m_items.clear();
00155 }
00156 return *this;
00157 }
00158
00159 void
00160 Errata::pop() {
00161 if (m_data && m_data->size()) {
00162 this->pre_write()->m_items.pop_front();
00163 }
00164 return;
00165 }
00166
00167 void
00168 Errata::clear() {
00169 m_data.reset(0);
00170 }
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182 static Errata::Container NIL_CONTAINER;
00183
00184 Errata::iterator
00185 Errata::begin() {
00186 return m_data ? m_data->m_items.rbegin() : NIL_CONTAINER.rbegin();
00187 }
00188
00189 Errata::const_iterator
00190 Errata::begin() const {
00191 return m_data ? static_cast<Data const&>(*m_data).m_items.rbegin()
00192 : static_cast<Container const&>(NIL_CONTAINER).rbegin();
00193 }
00194
00195 Errata::iterator
00196 Errata::end() {
00197 return m_data ? m_data->m_items.rend() : NIL_CONTAINER.rend();
00198 }
00199
00200 Errata::const_iterator
00201 Errata::end() const {
00202 return m_data ? static_cast<Data const&>(*m_data).m_items.rend()
00203 : static_cast<Container const&>(NIL_CONTAINER).rend();
00204 }
00205
00206 void
00207 Errata::registerSink(Sink::Handle const& s) {
00208 Sink_List.push_back(s);
00209 }
00210
00211 std::ostream&
00212 Errata::write(
00213 std::ostream& out,
00214 int offset,
00215 int indent,
00216 int shift,
00217 char const* lead
00218 ) const {
00219 for ( const_iterator spot = this->begin(), limit = this->end();
00220 spot != limit;
00221 ++spot
00222 ) {
00223 if ((offset + indent) > 0)
00224 out << std::setw(indent + offset) << std::setfill(' ')
00225 << ((indent > 0 && lead) ? lead : " ");
00226
00227 out << spot->m_id << " [" << spot->m_code << "]: " << spot->m_text
00228 << std::endl
00229 ;
00230 if (spot->getErrata().size())
00231 spot->getErrata().write(out, offset, indent+shift, shift, lead);
00232
00233 }
00234 return out;
00235 }
00236
00237 size_t
00238 Errata::write(
00239 char *buff,
00240 size_t n,
00241 int offset,
00242 int indent,
00243 int shift,
00244 char const* lead
00245 ) const {
00246 std::ostringstream out;
00247 std::string text;
00248 this->write(out, offset, indent, shift, lead);
00249 text = out.str();
00250 memcpy(buff, text.data(), std::min(n, text.size()));
00251 return text.size();
00252 }
00253
00254 std::ostream& operator<< (std::ostream& os, Errata const& err) {
00255 return err.write(os, 0, 0, 2, "> ");
00256 }
00257
00258 # if USING_BOOST
00259
00260 std::ostream&
00261 errata::format(std::ostream& s, std::string const& fmt, std::string const& glue) const {
00262 return this->format(s, boost::format(fmt), glue);
00263 }
00264
00265 std::ostream&
00266 errata::format(std::ostream& s, boost::format const& fmt, std::string const& glue) const {
00267 if (_data) {
00268 bool inside = false;
00269 boost::format f(fmt);
00270 f.exceptions(boost::io::all_error_bits ^ boost::io::too_many_args_bit);
00271 const_iterator spot(this->begin()), limit(this->end());
00272 while (spot != limit) {
00273 if (inside) s << glue;
00274 s << ( f % spot->_id % spot->_text );
00275 inside = true;
00276 ++spot;
00277 }
00278 }
00279 return s;
00280 }
00281
00282 std::string
00283 errata::format(std::string const& fmt, std::string const& glue) const {
00284 return this->format(boost::format(fmt), glue);
00285 }
00286
00287 std::string
00288 errata::format(boost::format const& fmt, std::string const& glue) const {
00289 std::ostringstream s;
00290 this->format(s, fmt, glue);
00291 return s.str();
00292 }
00293
00294 # endif
00295
00296 }
00297