00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #pragma once
00021 #ifndef moses_OutputCollector_h
00022 #define moses_OutputCollector_h
00023
00024 #ifdef WITH_THREADS
00025 #include <boost/thread/mutex.hpp>
00026 #endif
00027
00028 #ifdef BOOST_HAS_PTHREADS
00029 #include <pthread.h>
00030 #endif
00031
00032 #include <iostream>
00033 #include <map>
00034 #include <ostream>
00035 #include <fstream>
00036 #include <string>
00037 #include "Util.h"
00038 #include "util/exception.hh"
00039 namespace Moses
00040 {
00044 class OutputCollector
00045 {
00046 public:
00047 OutputCollector(std::ostream* outStream= &std::cout,
00048 std::ostream* debugStream=&std::cerr)
00049 : m_nextOutput(0)
00050 , m_outStream(outStream)
00051 , m_debugStream(debugStream)
00052 , m_isHoldingOutputStream(false)
00053 , m_isHoldingDebugStream(false) {}
00054
00055 OutputCollector(std::string xout, std::string xerr = "")
00056 : m_nextOutput(0) {
00057
00058
00059 if (xout == "/dev/stderr") {
00060 m_outStream = &std::cerr;
00061 m_isHoldingOutputStream = false;
00062 } else if (xout.size() && xout != "/dev/stdout" && xout != "-") {
00063 m_outStream = new std::ofstream(xout.c_str());
00064 UTIL_THROW_IF2(!m_outStream->good(), "Failed to open output file"
00065 << xout);
00066 m_isHoldingOutputStream = true;
00067 } else {
00068 m_outStream = &std::cout;
00069 m_isHoldingOutputStream = false;
00070 }
00071
00072 if (xerr == "/dev/stdout") {
00073 m_debugStream = &std::cout;
00074 m_isHoldingDebugStream = false;
00075 } else if (xerr.size() && xerr != "/dev/stderr") {
00076 m_debugStream = new std::ofstream(xerr.c_str());
00077 UTIL_THROW_IF2(!m_debugStream->good(), "Failed to open debug stream"
00078 << xerr);
00079 m_isHoldingDebugStream = true;
00080 } else {
00081 m_debugStream = &std::cerr;
00082 m_isHoldingDebugStream = false;
00083 }
00084 }
00085
00086 ~OutputCollector() {
00087 if (m_isHoldingOutputStream)
00088 delete m_outStream;
00089 if (m_isHoldingDebugStream)
00090 delete m_debugStream;
00091 }
00092
00093 void HoldOutputStream() {
00094 m_isHoldingOutputStream = true;
00095 }
00096
00097 void HoldDebugStream() {
00098 m_isHoldingDebugStream = true;
00099 }
00100
00101 bool OutputIsCout() const {
00102 return (m_outStream == &std::cout);
00103 }
00104
00108 void Write(int sourceId,const std::string& output,const std::string& debug="") {
00109 #ifdef WITH_THREADS
00110 boost::mutex::scoped_lock lock(m_mutex);
00111 #endif
00112 if (sourceId == m_nextOutput) {
00113
00114 *m_outStream << output << std::flush;
00115 *m_debugStream << debug << std::flush;
00116 ++m_nextOutput;
00117
00118 std::map<int,std::string>::iterator iter;
00119 while ((iter = m_outputs.find(m_nextOutput)) != m_outputs.end()) {
00120 *m_outStream << iter->second << std::flush;
00121 ++m_nextOutput;
00122 std::map<int,std::string>::iterator debugIter = m_debugs.find(iter->first);
00123 m_outputs.erase(iter);
00124 if (debugIter != m_debugs.end()) {
00125 *m_debugStream << debugIter->second << std::flush;
00126 m_debugs.erase(debugIter);
00127 }
00128 }
00129 } else {
00130
00131 m_outputs[sourceId] = output;
00132 m_debugs[sourceId] = debug;
00133 }
00134 }
00135
00136
00137 private:
00138 std::map<int,std::string> m_outputs;
00139 std::map<int,std::string> m_debugs;
00140 int m_nextOutput;
00141 std::ostream* m_outStream;
00142 std::ostream* m_debugStream;
00143 bool m_isHoldingOutputStream;
00144 bool m_isHoldingDebugStream;
00145 #ifdef WITH_THREADS
00146 boost::mutex m_mutex;
00147 #endif
00148
00149 public:
00150 void SetOutputStream(std::ostream* outStream) {
00151 m_outStream = outStream;
00152 }
00153
00154 };
00155
00156 }
00157
00158 #endif