167 lines
		
	
	
	
		
			4.2 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			167 lines
		
	
	
	
		
			4.2 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /*
 | |
|  * Copyright (c) 2008-2011 Juli Mallett. All rights reserved.
 | |
|  *
 | |
|  * Redistribution and use in source and binary forms, with or without
 | |
|  * modification, are permitted provided that the following conditions
 | |
|  * are met:
 | |
|  * 1. Redistributions of source code must retain the above copyright
 | |
|  *    notice, this list of conditions and the following disclaimer.
 | |
|  * 2. Redistributions in binary form must reproduce the above copyright
 | |
|  *    notice, this list of conditions and the following disclaimer in the
 | |
|  *    documentation and/or other materials provided with the distribution.
 | |
|  *
 | |
|  * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 | |
|  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 | |
|  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 | |
|  * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
 | |
|  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 | |
|  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 | |
|  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 | |
|  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 | |
|  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 | |
|  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 | |
|  * SUCH DAMAGE.
 | |
|  */
 | |
| 
 | |
| #include <sys/uio.h>
 | |
| #include <limits.h>
 | |
| #include <iostream>
 | |
| #include <common/limits.h>
 | |
| #include <common/buffer.h>
 | |
| 
 | |
| ////////////////////////////////////////////////////////////////////////////////
 | |
| //                                                                            //
 | |
| // File:           buffer.cc                                                  //
 | |
| // Description:    generic buffer composed by reference counted segments      //
 | |
| // Project:        WANProxy XTech                                             //
 | |
| // Adapted by:     Andreu Vidal Bramfeld-Software                             //
 | |
| // Last modified:  2015-04-01                                                 //
 | |
| //                                                                            //
 | |
| ////////////////////////////////////////////////////////////////////////////////
 | |
| 
 | |
| #if USING_SEGMENT_CACHE	
 | |
| std::deque<BufferSegment *> BufferSegment::segment_cache;
 | |
| pthread_mutex_t BufferSegment::segment_mutex = PTHREAD_MUTEX_INITIALIZER;
 | |
| #endif
 | |
| 
 | |
| size_t
 | |
| Buffer::fill_iovec(struct iovec *iov, size_t niov) const
 | |
| {
 | |
| 	if (niov == 0)
 | |
| 		return (0);
 | |
| 
 | |
| 	if (niov > IOV_MAX)
 | |
| 		niov = IOV_MAX;
 | |
| 
 | |
| 	segment_list_t::const_iterator iter = data_.begin();
 | |
| 	size_t iovcnt = 0;
 | |
| 	unsigned i;
 | |
| 
 | |
| 	for (i = 0; i < niov; i++) {
 | |
| 		if (iter == data_.end())
 | |
| 			break;
 | |
| 		const BufferSegment *seg = *iter;
 | |
| 		iov[i].iov_base = (void *)(uintptr_t)seg->data();
 | |
| 		iov[i].iov_len = seg->length();
 | |
| 		iovcnt++;
 | |
| 		iter++;
 | |
| 	}
 | |
| 	return (iovcnt);
 | |
| }
 | |
| 
 | |
| std::string
 | |
| Buffer::hexdump(unsigned start) const
 | |
| {
 | |
| 	static const char hexchars[] = "0123456789abcdef";
 | |
| 
 | |
| 	std::string hex;
 | |
| 	std::string vis;
 | |
| 
 | |
| 	segment_list_t::const_iterator iter = data_.begin();
 | |
| 	while (iter != data_.end()) {
 | |
| 		const BufferSegment *seg = *iter++;
 | |
| 		const uint8_t *p;
 | |
| 
 | |
| 		for (p = seg->data(); p < seg->end(); p++) {
 | |
| 			hex += hexchars[(*p & 0xf0) >> 4];
 | |
| 			hex += hexchars[*p & 0xf];
 | |
| 
 | |
| 			if (isprint(*p))
 | |
| 				vis += (char)*p;
 | |
| 			else
 | |
| 				vis += '.';
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	std::string dump;
 | |
| 	unsigned cur = 0;
 | |
| 
 | |
| 	for (;;) {
 | |
| 		unsigned offset = start + cur;
 | |
| 		std::string str;
 | |
| 		unsigned n;
 | |
| 
 | |
| 		while (offset != 0) {
 | |
| 			str = hexchars[offset & 0xf] + str;
 | |
| 			offset >>= 4;
 | |
| 		}
 | |
| 
 | |
| 		while (str.length() < 8)
 | |
| 			str = '0' + str;
 | |
| 
 | |
| 		dump += str;
 | |
| 
 | |
| 		if (cur == length_) {
 | |
| 			break;
 | |
| 		}
 | |
| 
 | |
| 		/*
 | |
| 		 * Print hex.
 | |
| 		 */
 | |
| 		for (n = 0; n < 16; n++) {
 | |
| 			if (n % 8 == 0)
 | |
| 				dump += " ";
 | |
| 			dump += " ";
 | |
| 			if (cur + n < length_) {
 | |
| 				dump += hex[n * 2];
 | |
| 				dump += hex[n * 2 + 1];
 | |
| 			} else {
 | |
| 				hex = "";
 | |
| 				dump += "  ";
 | |
| 			}
 | |
| 		}
 | |
| 		if (hex != "")
 | |
| 			hex = hex.substr(32);
 | |
| 
 | |
| 		dump += "  |";
 | |
| 		for (n = 0; cur < length_ && n < 16; n++) {
 | |
| 			dump += vis[n];
 | |
| 			cur++;
 | |
| 		}
 | |
| 		if (cur < length_)
 | |
| 			vis = vis.substr(16);
 | |
| 		dump += "|";
 | |
| 
 | |
| 		if (cur == length_ && cur % 16 == 0)
 | |
| 			break;
 | |
| 
 | |
| 		dump += "\n";
 | |
| 	}
 | |
| 
 | |
| 
 | |
| 	return (dump);
 | |
| }
 | |
| 
 | |
| std::ostream&
 | |
| operator<< (std::ostream& os, const Buffer *buf)
 | |
| {
 | |
| 	std::string str;
 | |
| 	buf->extract(str);
 | |
| 	return (os << str);
 | |
| }
 | |
| 
 | |
| std::ostream&
 | |
| operator<< (std::ostream& os, const Buffer& buf)
 | |
| {
 | |
| 	return (os << &buf);
 | |
| }
 |