scrap book

プログラミングとか

自前ヘキサダンプ関数

バイナリデータをバイナリエディタ風というかnetstat風というかそんな感じに16進数で表示する関数。実装はC++11。やりたかったことはできた気がするけどソースコードは汚い。

ソースコード
#include <ctype.h>
#include <string>
#include <iomanip>
#include <sstream>
#include <iostream>

static std::string GetDumpedString(
        void* targetData, int targetDataSize,
        bool showHead = true, bool showChar = true)
{
    unsigned char* data = static_cast<unsigned char*>(targetData);

    std::stringstream ssDump;
    std::stringstream ssHead;
    std::stringstream ssLine;
    std::stringstream ssChar;

    ssLine.width( 2 );
    ssLine.fill( '0' );
    ssLine.flags( std::ios::hex | std::ios::uppercase );

    for( int i = 0; i < targetDataSize; i++ )
    {
        if( showHead && ( i % 16 == 0 ) )
        {
            ssHead << std::setw(8) << std::setfill('0')
                   << std::hex
                   << i << ": " << std::flush;

            ssLine << ssHead.str();
        }

        ssLine << (int)data[i] << ' ';

        ssChar << ((isprint(data[i]) != 0) ? (char)data[i] : '.');

        if( (i+1) % 16 == 0 )
        {
            if( showChar )
            {
                ssLine << "    " << ssChar.str();
            }
            ssLine << std::endl;
            ssDump << ssLine.str();

            ssHead.str("");
            ssHead.clear(std::stringstream::goodbit);
            ssLine.str("");
            ssLine.clear(std::stringstream::goodbit);
            ssChar.str("");
            ssChar.clear(std::stringstream::goodbit);
        }
    }
    if( ssLine.str().size() > 0 )
    {
        int spaceSize = 3*16 + (showHead ? 10 : 0) + (showChar ? 4 : 0) - ssLine.str().size();
        ssLine << std::string(spaceSize, ' ') << ssChar.str() << std::endl;
        ssDump << ssLine.str();
    }


    return ssDump.str();
}

int main(void)
{
    using namespace std;

    cout << "          00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F" << endl;

    string str = "abcdefghijklmnopqrstuvwxyz"
                 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
                 "01234567890";
    cout << GetDumpedString( (char*)str.data(), str.size() ) << endl;


    return 0;
}
結果
          00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
00000000: 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70     abcdefghijklmnop
00000010: 71 72 73 74 75 76 77 78 79 7A 41 42 43 44 45 46     qrstuvwxyzABCDEF
00000020: 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56     GHIJKLMNOPQRSTUV
00000030: 57 58 59 5A 30 31 32 33 34 35 36 37 38 39 30        WXYZ01234567890