|
|
November 30 alloca function allocates memory from stack, thus is much faster than heap and is released automatically when function exit. At first look it like like declare a char array, but the difference is that you can only declare array of fixed size on stack, but you can get variable size memory (although limited by available stack size) via alloca. #include <windows.h> #include <iostream> #include <iomanip> #include <exception> void test_stackoverflow(int size) { std::cout << __FUNCTION__ << "("<<size<<")\n"; char* ptr = static_cast<char*>(alloca(size)); ptr[0]='a'; std::cout << __FUNCTION__ << "()\n"; } void test_with_std_exception() { try { for(int i=102; ;i++ ) test_stackoverflow(i*10240); } catch (std::exception& e) { std::cout << e.what()<<std::endl; } } void main(int argc, char* argv[]) { __try{ for(int i=102; ;i++ ) test_stackoverflow(i*10240); } __except (EXCEPTION_EXECUTE_HANDLER) { std::cout<<"Exception code 0x"<<std::hex<< _exception_code()<<std::endl; } if (argc>1) test_with_std_exception(); } // cl -EHa overflow.cpp // D:\test\stl>overflow.exe //test_stackoverflow(1044480) // Exception code 0xc00000fd November 17 The interesting fact is that std::queue and std::priority_queue has different interface – std::queue has front(), but std::priority_queue has top(). #include <stack> #include <list> #include <iostream> #include <string> #include <queue> template<typename ContainerType> void fill_container(ContainerType& cnt) { cnt.push('a'); cnt.push('0'); cnt.push('b'); cnt.push('c'); } void main() { typedef std::stack< char, std::list<char> > char_list_stack; char_list_stack mystack; fill_container(mystack); std::cout << "\ncontent in stack:"; while(mystack.size()) { std::cout << mystack.top() << " "; mystack.pop(); } std::queue<char, std::list<char> > myqueue; fill_container(myqueue); std::cout << "\ncontent in queue:"; while(myqueue.size()) { std::cout << myqueue.front() << " "; myqueue.pop(); } //std::priority_queue<char, std::deque<char> > mypqueue; std::priority_queue<char, std::vector<char> > mypqueue; fill_container(mypqueue); std::cout << "\ncontent in priority_queue:"; while(mypqueue.size()) { std::cout << mypqueue.top() << " "; mypqueue.pop(); } } // cl -EHsc stack.cpp -link -verbose:lib // content in stack:c b 0 a // content in queue:a 0 b c // content in priority_queue:c b a 0 operator new return NULL if ctor throw exception, this will leads to resource leak, and other possible problem like lock is not released. // ctor.cpp : test throw exception in ctor. // cl -EHsc -d1reportSingleClassLayoutCtorWithException ctor.cpp #define _CRTDBG_MAP_ALLOC #include <tchar.h> #include <stdlib.h> #include <crtdbg.h> #include <iostream> #include <iomanip> class CtorWithException { public: CtorWithException(bool throw_exception):m_buf(new char[10240]) { std::cout << __FUNCTION__ << " this=" << std::hex << (int)this <<std::endl; if (throw_exception) throw std::runtime_error("exception in ctor"); } ~CtorWithException() { delete[] m_buf; std::cout << __FUNCTION__ << " this=" << std::hex << (int)this <<std::endl; } private: char* m_buf; }; class TestCtorWithException { public: TestCtorWithException():m_buf(new char[1024*1024]),m_no_exp(false),m_has_exp(true),m_uninitialized(false) { std::cout << __FUNCTION__ << " this=" << std::hex << (int)this <<std::endl; }; ~TestCtorWithException() { delete[] m_buf; std::cout << __FUNCTION__ << " this=" << std::hex << (int)this <<std::endl; }; private: char *m_buf; CtorWithException m_no_exp; CtorWithException m_has_exp; CtorWithException m_uninitialized; }; int _tmain(int argc, _TCHAR* argv[]) { _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE); _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDOUT ); TestCtorWithException* testobj=NULL; try { //TestCtorWithException test_obj; testobj=new TestCtorWithException; } catch (std::exception& e) { std::cout << e.what() << std::endl; } std::cout << "new return " << std::hex << testobj << std::endl; _CrtDumpMemoryLeaks(); return 0; } // program output //CtorWithException::CtorWithException this=38cf34 //CtorWithException::CtorWithException this=38cf38 //CtorWithException::~CtorWithException this=38cf34 //exception in ctor //new return 00000000 //Detected memory leaks! //Dumping objects -> //{225} normal block at 0x00530068, 10240 bytes long. //Data: < > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD //{203} normal block at 0x00420040, 1048576 bytes long. //Data: < > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD // Object dump complete. A program linking with libboost_program_options-vc90-mt-gd-1_35.lib crashed at desc.add_options(), but the release version worked. At last it turned out to be due to mixed usage of debug version CRT and release version CRT – the program in trouble linked to some release version library in its debug build. The interesting fact is that VC++ 2008 does not complain during compilation, but boost.program_options raised obscure run-time error. October 27 Here is a simple example that demonstrate usage of INNER, FULL, LEFT and RIGHT JOIN. Create 2 tables create table p1(pid integer, pname varchar(20)); create table p2(pid integer, ptype varchar(10)); insert some data into the tables. insert into p1(pid, pname) values(1,'p1'); insert into p1(pid, pname) values(2, 'p2'); insert into p1(pid, pname) values(4, 'p4'); insert into p2(pid, ptype) values(1,'t1'); insert into p2(pid, ptype) values(2, 't2'); insert into p2(pid, ptype) values(3, 't3');
select * from p1; | | pid | pname | | 1 | 1 | p1 | | 2 | 2 | p2 | | 3 | 4 | p4 | select * from p2; | | pid | ptype | | 1 | 1 | t1 | | 2 | 2 | t2 | | 3 | 4 | t4 | inner join is implicit. The following two produce the same result. select * from p1,p2 where p1.pid=p2.pid; select * from p1 inner join p2 on p1.pid=p2.pid;
| | pid | pname | pid | ptype | | 1 | 1 | p1 | 1 | t1 | | 2 | 2 | p2 | 2 | t2 | select * from p1 left join p2 on p1.pid=p2.pid;
| | pid | pname | pid | ptype | | 1 | 1 | p1 | 1 | t1 | | 2 | 2 | p2 | 2 | t2 | | 3 | 4 | p4 | | | 1;"p1";1;"t1" 2;"p2";2;"t2" 4;"p4";;"" select * from p1 right join p2 on p1.pid=p2.pid;
| | pid | pname | pid | ptype | | 1 | 1 | p1 | 1 | t1 | | 2 | 2 | p2 | 2 | t2 | | 3 | | | 3 | t3 | select * from p1 full join p2 on p1.pid=p2.pid;
| | pid | pname | pid | ptype | | 1 | 1 | p1 | 1 | t1 | | 2 | 2 | p2 | 2 | t2 | | 3 | | | 3 | t3 | | 4 | 4 | p4 | | | Compare aspects of CORBA and COM | | CORBA | COM | WebService | | interface | IDL | IDL | WSDL | | | Interface Repository | typelib | WSDL | | | POA | ClassFactory | | | | Active Object Map | GIT, ROT | | | Locate the server | Implementation Repository; IIOP Interoperable Object Reference (IOR) | Registry | UDDI | | | CORBA::object to string | | | | | static invocation interface (SII) | | | | | dynamic invocation interface | IDispatch | | | | Dynamic Skeleton Interface (DSI) | | | October 19 QuickREx provides a nice dialog to help user compose regex pattern, but it does not provide “replace” feature. Regex Util provides nice feature to displace “replaced” result, but it does not allow user to copy result into clipboard, just allows user to preview results. Another not so nice fact is that Regex Util uses “$1”, but boost.regex uses “\1” format. October 13 Custom deleter can be used to manage resource other than memory via
shared_ptr. Here I elaborated some usage of custom deleter.
#include <iostream> #include
<boost/shared_ptr.hpp> #include <boost/bind.hpp> #include
<list> using namespace std; class
custom_deleter_demo { public: custom_deleter_demo(int
data):m_data(data){ } void custom_deleter0() {
std::cout << __FUNCTION__ << " data is " << m_data <<
std::endl; delete this; } void custom_deleter1(int
extra_arg) { std::cout << __FUNCTION__ << " data
is " << m_data << ", extra argument is " <<
extra_arg << std::endl; delete this; } static
void static_custom_deleter(custom_deleter_demo* ptr) {
std::cout << __FUNCTION__ << " data is " << ptr->m_data
<< std::endl; delete ptr; } private:
~custom_deleter_demo() { std::cout << __FUNCTION__
<< " data is " << m_data << std::endl; } int
m_data; };
int main() { typedef boost::shared_ptr<custom_deleter_demo>
ptr_custom_deleter; std::list<ptr_custom_deleter> my_list;
my_list.push_back(ptr_custom_deleter(new
custom_deleter_demo(__LINE__),
custom_deleter_demo::static_custom_deleter)); custom_deleter_demo*
ptr_object=new custom_deleter_demo(__LINE__);
my_list.push_back(ptr_custom_deleter(ptr_object,
boost::bind(&custom_deleter_demo::custom_deleter0, ptr_object)) );
ptr_object=new custom_deleter_demo(__LINE__);
my_list.push_back(ptr_custom_deleter(ptr_object,
boost::bind(&custom_deleter_demo::custom_deleter1, ptr_object,__LINE__))
); my_list.clear(); cout << "Demo custom deleter with
shared_ptr" << endl; return 0; } September 30 At first I build it in usual way as I did with boost 1.39, but bjam (Boost.Jam 03.1.17) prints a lot of errors like the following. cl : Command line error D8022 : cannot open 'bin.v2\libs\math\config\msvc-9.0\debug\link-static\threading-multi\has_long_double_support.obj.rsp' The file does exist on my disk. At last I resort to the tool File Monitor in order to find out the root cause. File Monitor captured the following error: 1:53:37 PM cl.exe:6324 OPEN D:\bin.v2\libs\math\build\msvc-9.0\debug\threading-multi\pch.pch.rsp PATH NOT FOUND Options: Open Access: Read It seems that bjam was passing incorrect path to cl.exe. The error is known, and the fix is simple. I created the following batch file and build it successfully. Before starting, I already have d:\boost_1_40_0\bjam.exe in place. size of d:\boost_1_40_0 is 5.56 GB after build completed. subst x: D:\boost_1_40_0 call "%VS90COMNTOOLS%\..\..\vc\bin\vcvars32.bat" SET PYTHON_ROOT=C:\Python26 SET PYTHON_VERSION=2.6 SET ICU_PATH=D:\opensource\ICU4C-4_2\icu cd /d x:\ .\bjam.exe --without-mpi --toolset=msvc-9.0 stage --build-type=complete
Command line to build single library: cd /d D:\opensource\boost\boost_1_40_0\libs\program_options\build D:\opensource\boost\bjam.exe "-sTOOLS=msvc" link=static threading=multi D:\opensource\boost\bjam.exe "-sTOOLS=msvc" link=static threading=multi variant=release D:\opensource\boost\bjam.exe "-sTOOLS=msvc" threading=multi variant=release D:\opensource\boost\bjam.exe "-sTOOLS=msvc" threading=multi variant=release Command line from "Building Boost with Visual Studio" .\bjam --toolset=msvc-9.0 --with-date_time --with-filesystem --with-iostreams -sBZIP2_INCLUDE=C:\bzip2-1.0.5 -sBZIP2_SOURCE=C:\bzip2-1.0.5 -sZLIB_INCLUDE=C:\zlib-1.2.3 -sZLIB_SOURCE=C:\zlib-1.2.3 --with-serialization --with-test --with-thread --build-type=complete stage Command line from boost-users@lists.boost.org bjam --layout=versioned --toolset=msvc-9.0 variant=debug threading=multi link=static runtime-link=static stage September 29 It is nice to save some useful information at the point of application crash. The useful methods including call stack and minidump file. Call stack can be obtained by installing exception filter via AddVectoredExceptionHandler Function, stack trace can be obtained via StackWalk64 Function, and minidump file can be created via MiniDumpWriteDump Function. WinDbg can open the minidump file. Use .sympath+ <pdb path name> to let WinDBG search this folder before _NT_SYMBOL_PATH. Use .exepath+ command to inform windbg search for executable image file. September 25 I am glad to found Achieve More Reliable Resource Management with Our Custom C++ Classes, but when using it in a unit test project, I got weird compile error. The error points to line 238 of scoped_any.h DECLARE_SMART_ANY_TYPEDEFS(scoped) and according to other error message it claims “close_rpc_binding” is not valid. After struggling it turned out to be confliction between ATL and MFC. In an ATL project the source file compiled successfully, but in its corresponding unit test project I have to use MFC because CPPUNIT MFCTestRunner is used to produce GUI. At last the problem was solved by moving MFC related headers from stdafx.h to where they are actually required, and disable precompiled header. There is also a post(Automate Resource Management with shared_ptr) demonstrating resource management via custom deleter and boost::shared_ptr. September 22 // another sample that send file name and content to Tcp server, but using asynchronous mode Tcp connection // // send a file to a tcp server via boost.asio library #include <iostream> #include <boost/asio.hpp> #include <boost/bind.hpp> #include <fstream> #include <sstream> using boost::asio::ip::tcp; class async_tcp_client { public: async_tcp_client(boost::asio::io_service& io_service, const std::string& server, const std::string& path) : resolver_(io_service), socket_(io_service) { size_t pos = server.find(':'); if (pos==std::string::npos) return; std::string port_string = server.substr(pos+1); std::string server_ip_or_host = server.substr(0, pos); source_file.open(path.c_str(), std::ios_base::binary | std::ios_base::ate); if (!source_file) { std::cout << "failed to open " << path << std::endl; return ; } size_t file_size = source_file.tellg(); source_file.seekg(0); // first send file name and file size to server std::ostream request_stream(&request_); request_stream << path << "\n" << file_size << "\n\n"; std::cout << "request size:"<<request_.size()<<std::endl; // Start an asynchronous resolve to translate the server and service names // into a list of endpoints. tcp::resolver::query query(server_ip_or_host, port_string); resolver_.async_resolve(query, boost::bind(&async_tcp_client::handle_resolve, this, boost::asio::placeholders::error, boost::asio::placeholders::iterator)); } private: void handle_resolve(const boost::system::error_code& err, tcp::resolver::iterator endpoint_iterator) { if (!err) { // Attempt a connection to the first endpoint in the list. Each endpoint // will be tried until we successfully establish a connection. tcp::endpoint endpoint = *endpoint_iterator; socket_.async_connect(endpoint, boost::bind(&async_tcp_client::handle_connect, this, boost::asio::placeholders::error, ++endpoint_iterator)); } else { std::cout << "Error: " << err.message() << "\n"; } } void handle_connect(const boost::system::error_code& err, tcp::resolver::iterator endpoint_iterator) { if (!err) { // The connection was successful. Send the request. boost::asio::async_write(socket_, request_, boost::bind(&async_tcp_client::handle_write_file, this, boost::asio::placeholders::error)); } else if (endpoint_iterator != tcp::resolver::iterator()) { // The connection failed. Try the next endpoint in the list. socket_.close(); tcp::endpoint endpoint = *endpoint_iterator; socket_.async_connect(endpoint, boost::bind(&async_tcp_client::handle_connect, this, boost::asio::placeholders::error, ++endpoint_iterator)); } else { std::cout << "Error: " << err.message() << "\n"; } } void handle_write_file(const boost::system::error_code& err) { if (!err) { if (source_file.eof()==false) { source_file.read(buf.c_array(), (std::streamsize)buf.size()); if (source_file.gcount()<=0) { std::cout << "read file error " << std::endl; return; } std::cout << "send " <<source_file.gcount()<<" bytes, total:" << source_file.tellg() << " bytes.\n"; boost::asio::async_write(socket_, boost::asio::buffer(buf.c_array(), source_file.gcount()), boost::bind(&async_tcp_client::handle_write_file, this, boost::asio::placeholders::error)); if (err) { std::cout << "send error:" << err << std::endl; return; } } else return; } else { std::cout << "Error: " << err.message() << "\n"; } } tcp::resolver resolver_; tcp::socket socket_; boost::array<char, 1024> buf; boost::asio::streambuf request_; std::ifstream source_file; }; int main(int argc, char* argv[]) { if (argc != 3) { std::cerr << "Usage: " << argv[0] << " <server-address> <file path>" << std::endl; std::cerr << "sample: " << argv[0] << " 127.0.0.1:1234 c:\\tmp\\a.txt" << std::endl; return __LINE__; } try { boost::asio::io_service io_service; async_tcp_client client(io_service, argv[1], argv[2]); io_service.run(); std::cout << "send file " << argv[2] << " completed successfully.\n"; // system("pause"); } catch (std::exception& e) { std::cerr << e.what() << std::endl; } return 0; } // I also made an asynchronous Tcp server to accept work with above client. //receive a file from socket client via boost.asio #include <iostream> #include <string> #include <boost/asio.hpp> #include <fstream> #include <boost/bind.hpp> #include <boost/function.hpp> #include <boost/shared_ptr.hpp> #include <boost/enable_shared_from_this.hpp> unsigned short tcp_port = 1234; class async_tcp_connection: public boost::enable_shared_from_this<async_tcp_connection> { public: async_tcp_connection(boost::asio::io_service& io_service) : socket_(io_service), file_size(0) { } void start() { std::cout << __FUNCTION__ << std::endl; async_read_until(socket_, request_buf, "\n\n", boost::bind(&async_tcp_connection::handle_read_request, shared_from_this(), boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)); } boost::asio::ip::tcp::socket& socket() { return socket_; } private: boost::asio::streambuf request_buf; size_t file_size; std::ofstream output_file; boost::asio::ip::tcp::socket socket_; boost::array<char, 40960> buf; void handle_read_request(const boost::system::error_code& err, std::size_t bytes_transferred) { if (err) { return handle_error(__FUNCTION__, err); } std::cout << __FUNCTION__ << "(" << bytes_transferred << ")" << ", in_avail=" << request_buf.in_avail() << ", size=" << request_buf.size() << ", max_size=" << request_buf.max_size() <<".\n"; std::istream request_stream(&request_buf); std::string file_path; request_stream >> file_path; request_stream >> file_size; request_stream.read(buf.c_array(), 2); // eat the "\n\n" std::cout << file_path << " size is " << file_size << ", tellg=" << request_stream.tellg()<< std::endl; size_t pos = file_path.find_last_of('\\'); if (pos!=std::string::npos) file_path = file_path.substr(pos+1); output_file.open(file_path.c_str(), std::ios_base::binary); if (!output_file) { std::cout << "failed to open " << file_path << std::endl; return; } // write extra bytes to file do { request_stream.read(buf.c_array(), (std::streamsize)buf.size()); std::cout << __FUNCTION__ << " write " << request_stream.gcount() << " bytes.\n"; output_file.write(buf.c_array(), request_stream.gcount()); } while (request_stream.gcount()>0); async_read(socket_, boost::asio::buffer(buf.c_array(), buf.size()), boost::bind(&async_tcp_connection::handle_read_file_content, shared_from_this(), boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)); } void handle_read_file_content(const boost::system::error_code& err, std::size_t bytes_transferred) { if (bytes_transferred>0) { output_file.write(buf.c_array(), (std::streamsize)bytes_transferred); std::cout << __FUNCTION__ << " recv " << output_file.tellp() << " bytes."<< std::endl; if (output_file.tellp()>=(std::streamsize)file_size) { return; } } if (err) { return handle_error(__FUNCTION__, err); } async_read(socket_, boost::asio::buffer(buf.c_array(), buf.size()), boost::bind(&async_tcp_connection::handle_read_file_content, shared_from_this(), boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)); } void handle_error(const std::string& function_name, const boost::system::error_code& err) { std::cout << __FUNCTION__ << " in " << function_name <<" due to " << err <<" " << err.message()<< std::endl; } }; class async_tcp_server : private boost::noncopyable { public: typedef boost::shared_ptr<async_tcp_connection> ptr_async_tcp_connection; async_tcp_server(unsigned short port) : acceptor_(io_service_, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), port), true) { ptr_async_tcp_connection new_connection_(new async_tcp_connection(io_service_)); acceptor_.async_accept(new_connection_->socket(), boost::bind(&async_tcp_server::handle_accept, this,new_connection_, boost::asio::placeholders::error)); io_service_.run(); } void handle_accept(ptr_async_tcp_connection current_connection, const boost::system::error_code& e) { std::cout << __FUNCTION__ << " " << e << ", " << e.message()<<std::endl; if (!e) { current_connection->start(); //ptr_async_tcp_connection new_connection_(new async_tcp_connection(io_service_)); //acceptor_.async_accept(new_connection_->socket(), // boost::bind(&async_tcp_server::handle_accept, this,new_connection_, // boost::asio::placeholders::error)); } } ~async_tcp_server() { io_service_.stop(); } private: boost::asio::io_service io_service_; boost::asio::ip::tcp::acceptor acceptor_; }; int main(int argc, char* argv[]) { try { if (argc==2) { tcp_port=atoi(argv[1]); } std::cout <<argv[0] << " listen on port " << tcp_port << std::endl; async_tcp_server *recv_file_tcp_server = new async_tcp_server(tcp_port); delete recv_file_tcp_server; } catch (std::exception& e) { std::cerr << e.what() << std::endl; } return 0; } //First is a synchronous TCP client that send file name and file content to Tcp Server. // // send a file to a tcp server via boost.asio library #include <iostream> #include <boost/asio.hpp> #include <fstream> #include <sstream> using boost::asio::ip::tcp; int main(int argc, char* argv[]) { if (argc != 3) { std::cerr << "Usage: " << argv[0] << " <server-address> <file path>" << std::endl; std::cerr << "sample: " << argv[0] << " 127.0.0.1:1234 c:\\tmp\\a.txt" << std::endl; return __LINE__; } try { std::string server_ip_or_host = argv[1]; size_t pos = server_ip_or_host.find(':'); if (pos==std::string::npos) return __LINE__; std::string port_string = server_ip_or_host.substr(pos+1); server_ip_or_host = server_ip_or_host.substr(0, pos); boost::asio::io_service io_service; tcp::resolver resolver(io_service); tcp::resolver::query query(server_ip_or_host, port_string); tcp::resolver::iterator endpoint_iterator = resolver.resolve(query); tcp::resolver::iterator end; tcp::socket socket(io_service); boost::system::error_code error = boost::asio::error::host_not_found; while (error && endpoint_iterator != end) { socket.close(); socket.connect(*endpoint_iterator++, error); } if (error) return __LINE__; std::cout << "connected to " << argv[1] << std::endl; boost::array<char, 1024> buf; std::ifstream source_file(argv[2], std::ios_base::binary | std::ios_base::ate); if (!source_file) { std::cout << "failed to open " << argv[2] << std::endl; return __LINE__; } size_t file_size = source_file.tellg(); source_file.seekg(0); // first send file name and file size to server boost::asio::streambuf request; std::ostream request_stream(&request); request_stream << argv[2] << "\n" << file_size << "\n\n"; boost::asio::write(socket, request); std::cout << "start sending file content.\n"; for (;;) { if (source_file.eof()==false) { source_file.read(buf.c_array(), (std::streamsize)buf.size()); if (source_file.gcount()<=0) { std::cout << "read file error " << std::endl; return __LINE__; } boost::asio::write(socket, boost::asio::buffer(buf.c_array(), source_file.gcount()), boost::asio::transfer_all(), error); if (error) { std::cout << "send error:" << error << std::endl; return __LINE__; } } else break; } std::cout << "send file " << argv[2] << " completed successfully.\n"; } catch (std::exception& e) { std::cerr << e.what() << std::endl; } return 0; } // next is a Tcp server working in synchronous mode that accept file from above Tcp client. This sample also demonstrate usage of async_read_until(). The trick with async_read_until is that it will read more than I want and those extra bytes must be properly handled. //receive a file from socket client via boost.asio #include <ctime> #include <iostream> #include <string> #include <boost/asio.hpp> #include <fstream> #include <sstream> unsigned short tcp_port = 1234; int main(int argc, char* argv[]) { boost::array<char, 1024> buf; size_t file_size = 0; try { if (argc==2) { tcp_port=atoi(argv[1]); } std::cout <<argv[0] << " listen on port " << tcp_port << std::endl; boost::asio::io_service io_service; boost::asio::ip::tcp::acceptor acceptor(io_service, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), tcp_port)); boost::system::error_code error; boost::asio::ip::tcp::socket socket(io_service); acceptor.accept(socket); std::cout << "get client connection." << std::endl; boost::asio::streambuf request_buf; boost::asio::read_until(socket, request_buf, "\n\n"); std::cout<< "request size:" << request_buf.size() << "\n"; std::istream request_stream(&request_buf); std::string file_path; request_stream >> file_path; request_stream >> file_size; request_stream.read(buf.c_array(), 2); // eat the "\n\n" std::cout << file_path << " size is " << file_size << std::endl; size_t pos = file_path.find_last_of('\\'); if (pos!=std::string::npos) file_path = file_path.substr(pos+1); std::ofstream output_file(file_path.c_str(), std::ios_base::binary); if (!output_file) { std::cout << "failed to open " << file_path << std::endl; return __LINE__; } // write extra bytes to file do { request_stream.read(buf.c_array(), (std::streamsize)buf.size()); std::cout << __FUNCTION__ << " write " << request_stream.gcount() << " bytes.\n"; output_file.write(buf.c_array(), request_stream.gcount()); } while (request_stream.gcount()>0); for (;;) { size_t len = socket.read_some(boost::asio::buffer(buf), error); if (len>0) output_file.write(buf.c_array(), (std::streamsize)len); if (output_file.tellp()== (std::fstream::pos_type)(std::streamsize)file_size) break; // file was received if (error) { std::cout << error << std::endl; break; } } std::cout << "received " << output_file.tellp() << " bytes.\n"; } catch (std::exception& e) { std::cerr << e.what() << std::endl; } return 0; } July 26 DevPartner failed to instrument two projects with “Error and Coverage” type, the only common fact is that there is a medium size CPP file in thos projects, one is around 40k, another is around 64k. It seems to be bug because those two projects can be instrumented successfully with “Error detection” or “Coverage or performance” type, and the debug configuration is also working, at last a colleague found a workaround with release configuration – disable optimization. July 04 I just need to create options_description as usual, and prepare configuration file in the following format: #include <boost/program_options.hpp> namespace po = boost::program_options; std::stringstream ss; ss << "CurrentX=1234"<<std::endl <<"CurrentY=456"<<std::endl; po::options_description desc("Allowed options"); desc.add_options() ("help,h", "produce help message") ("CurrentX", po::value<int>(), "set CurrentX") ("CurrentY", po::value<int>(), "set CurrentY") ; po::variables_map vm; po::store(po::parse_config_file(ss, desc, true), vm);
|
|
|
|