5 char hexDigit( char c ) {
21 std::string toHex( const char* buf, int len ) {
22 char* c = ( char* ) malloc( len * 2 );
25 return "<malloc fail>";
28 std::shared_ptr<char> mem = std::shared_ptr<char>( c, free );
30 for( int i = 0; i < len; i++ ) {
31 c[i * 2] = hexDigit( ( buf[i] >> 4 ) & 0xF );
32 c[i * 2 + 1] = hexDigit( buf[i] & 0xF );
35 return std::string( mem.get(), len * 2 );
39 this->buffer = std::vector<char>( 4096 );
40 this->decodeTarget = 0;
45 void SlipBIO::setTarget( std::shared_ptr<OpensslBIO> target ) {
46 this->target = target;
49 SlipBIO::SlipBIO( std::shared_ptr<OpensslBIO> target ) {
50 this->target = target;
51 this->buffer = std::vector<char>( 4096 );
52 this->decodeTarget = 0;
59 SlipBIO::~SlipBIO() {}
61 int SlipBIO::write( const char* buf, int num ) {
64 for( int i = 0; i < num; i++ ) {
65 if( ( buf[i] == ( char )0xc0 ) || ( buf[i] == ( char )0xDB ) ) {
70 int totalLen = num + badOnes + 1; // 2
71 char* targetPtr = ( char* ) malloc( totalLen );
77 std::shared_ptr<char> t = std::shared_ptr<char>( targetPtr, free );
80 //targetPtr[j++] = (char)0xC0;
82 for( int i = 0; i < num; i++ ) {
83 if( buf[i] == ( char )0xc0 ) {
84 targetPtr[j++] = ( char )0xDB;
85 targetPtr[j++] = ( char )0xDC;
86 } else if( buf[i] == ( char )0xDB ) {
87 targetPtr[j++] = ( char )0xDB;
88 targetPtr[j++] = ( char )0xDD;
90 targetPtr[j++] = buf[i];
94 targetPtr[j++] = ( char )0xC0;
96 if( target->write( targetPtr, j ) != j ) {
97 std::cout << "sent " << j << std::endl;
98 throw "Error, target write failed";
104 int SlipBIO::read( char* buf, int size ) {
105 // while we have no data to decode or unmasking does not yield a full package
106 while( !packageLeft && ( decodePos >= rawPos || !unmask() ) ) {
108 // we have no data, read more
109 if( buffer.size() - rawPos < 64 ) {
110 // not enough space... package is too big
115 int len = target->read( buffer.data() + rawPos, buffer.capacity() - rawPos );
128 int len = std::min( decodeTarget, ( unsigned int ) size );
129 // a package finished, return it
130 std::copy( buffer.data(), buffer.data() + len, buf );
131 // move the buffer contents back
132 std::copy( buffer.data() + len, buffer.data() + decodeTarget, buffer.data() );
135 if( decodeTarget == 0 ) {
142 long SlipBIO::ctrl( int cmod, long arg1, void* arg2 ) {
146 return target->ctrl( cmod, arg1, arg2 );
149 const char* SlipBIO::getName() {
153 bool SlipBIO::unmask() {
154 unsigned int j = decodeTarget;
156 for( unsigned int i = decodePos; i < rawPos; i++ ) {
157 if( buffer[i] == ( char ) 0xDB ) {
162 buffer[decodeTarget] = buffer[i - 1];
163 decodePos = decodeTarget;
164 rawPos = decodePos + 1;
165 return 0;// no packet
166 } else if( buffer[i] == ( char )0xdc ) {
167 buffer[j++] = ( char ) 0xc0;
168 } else if( buffer[i] == ( char )0xdd ) {
169 buffer[j++] = ( char ) 0xdb;
176 } else if( buffer[i] == ( char ) 0xc0 ) {
180 // copy rest to bufferfer i to len
188 buffer[j++] = buffer[i];