# Visual C++.NET

6K

Solutions

5K

Contributors

Microsoft Visual C++ (often abbreviated as MSVC or VC++) is an integrated development environment (IDE) product from Microsoft for the C, C++, and C++/CLI programming languages. It features tools for developing and debugging C++ code, especially code written for the Microsoft Windows API, the DirectX API, and the Microsoft .NET Framework. Many applications require redistributable Visual C++ packages to function correctly and are often installed independently of applications, allowing multiple applications to make use of the package while only having to install it once

In Easy String Encryption Using CryptoAPI in C++ I described how to encrypt text and recommended that the encrypted text be stored as a series of hexadecimal digits -- because cyphertext may contain embedded NULLs or other characters that can cause processing problems.

Since then I've worked on an application in which large blocks of binary data must be encoded into hexadecimal rapidly, and when needed, decoded back to binary just as rapidly.  In the earlier article, I provided a sort of "throw-away" hex encoder/decoder, but I felt that I needed something that was more efficient for production work.

In this article, I'll explore some hex encode/decode options, including the one supported by the CryptoAPI, and at the end of the article, I'll present the ultra-fast functions that ended up in my production code.

Observe the ordering of characters in an ASCII Table The only real issue with hex encoding is that there is a gap between the 9 and the A.  Most of the complications come when dealing with that.

Your binary source byte is 8 bits.  Take the data 4 bits at a time (values 0-15).  If that value is 0-9, then just add '0' (0x30).  If the value is 10-15, then add 0x37 instead.  That gives you a hex digit ('0', '1',...,'9','A',..., 'F').  Output the resulting high hex digit followed by the low hex digit.
``````
``````
3
LVL 50

Author Comment

I know of no prohibition or limitation on use of any source code provided in an EE article or Q/A response.  Frankly, the whole point of this site is to provide usable solutions, so it would be strange if there were prohibitions on usage.   As a practical matter, the above code can be used in any way you want.  I'd expect that if you use the code in an article or publication, that you would properly attribute the author and the site.

-- Dan
0
LVL 23

Expert Comment

Don't you think a Duff's device applied would make it somewhat faster? This part

for (int j=0; j<nSrcLen; j++ ) {
*pwDest= pwHex[*pSrc];
pwDest++; pSrc++;
}

can be unrolled and rumors are that duff's device achieves for example 30% faster with gcc. I believe its definitely worth a try.

``````#define SafeMacro(statment) \
do { statment; } while (0)

#define DuffLoop(aCount, statment) \
SafeMacro( \
auto count_ = (aCount); \
auto times_ = (count_ + 7) >> 3; \
switch (count_ & 7){ \
case 0: do { statment; \
case 7: statment; \
case 6: statment; \
case 5: statment; \
case 4: statment; \
case 3: statment; \
case 2: statment; \
case 1: statment; \
} while (--times_ > 0); \
} \
)

#define DuffLoopChecked(aCount, statment) \
SafeMacro( if(aCount) { DuffLoop((aCount), statment); } )

//
DuffLoopChecked(
nSrcLen,
*pwDest++= pwHex[*pSrc++];
);
``````
0
The following diagram presents a diamond class hierarchy:
As depicted, diamond inheritance denotes when two classes (e.g., CDerived1 and CDerived2), separately extending a common base class (e.g., CBase), are sub classed simultaneously by a fourth class (e.g., CTest).

The following is how one would expect the diagram to be implemented:
``````#include <stdio.h>

class CBase
{
public:
virtual void test()
{
printf("CBase::test()\r\n");
}
};

class CDerived1 : public CBase
{
};

class CDerived2 : public CBase
{
};

class CTest : public CDerived1, public CDerived2
{
};

int main()
{
CTest test;
test.test();
return 0;
}
``````
However, the Microsoft VC+ 2005 .NET compiler gives the following message:
``````1>------ Build started: Project: vft_test, Configuration: Debug Win32 ------
1>Compiling...
1>main_romb.cpp
1>c:\source\vft_test\vft_test\main_romb.cpp(27) : error C2385: ambiguous access of 'test'
1>        could be the 'test' in base 'CBase'
1>        or could be the 'test' in base 'CBase'
1>Build log was saved at "file://c:\Source\vft_test\vft_test\Debug\BuildLog.htm"
1>vft_test - 2 error(s), 0 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
``````

Since CDerived1 and CDerived2 can have very different implementations of CBase::test(), the compiler is unsure which CTest derives.  This is the so called "Diamond problem" or even "Dreaded Diamond".

How to deal with this "dread"?

The following code will give you a clue:
``````#include <stdio.h>

class CBase
{

public:
CBase()
{
printf("CBase::CBase()");
}

virtual void test()
{
printf("CBase::test()\r\n");
}
};

class CDerived1 : public CBase
{

public:
CDerived1()
{
printf("CDerived1::CDerived1()");
}
};

class CDerived2 : public CBase
{

public:
CDerived2()
{
printf("CDerived1::CDerived1()");
}
};

class CTest : public CDerived1, public CDerived2
{

public:
CTest()
{
printf("CTest::CTest()");
}
};

int main()
{
CTest test;
return 0;
}
``````

This program is compiled successfully and works:

Of course, you know how CTest object is created.  It derives, firstly, from CDerived1 object, that inherits from CBase, and, secondly, CTest derives from CDerived2 that also inherits from CBase.  So the compiler (probably any compiler) creates CBase object, then CDerived1, and now it needs to create CBase again, ..., etc., we got 2 CBase objects!

The diagram did not show that the CBase class appears twice in the class hierarchy.

C++ provides a technique for such case.  The declaration of the CBase class as virtual solves the situation:
``````
``````
4
LVL 61

Expert Comment

Good job, pgnatyuk!
You have my vote above.
0

Expert Comment

Thanks a lot man, it helped me
0

# Visual C++.NET

6K

Solutions

5K

Contributors

Microsoft Visual C++ (often abbreviated as MSVC or VC++) is an integrated development environment (IDE) product from Microsoft for the C, C++, and C++/CLI programming languages. It features tools for developing and debugging C++ code, especially code written for the Microsoft Windows API, the DirectX API, and the Microsoft .NET Framework. Many applications require redistributable Visual C++ packages to function correctly and are often installed independently of applications, allowing multiple applications to make use of the package while only having to install it once

Top Experts In
Visual C++.NET
Monthly