ふにゃるんv2

もとは、http://d.hatena.ne.jp/Wacky/

16進数ダンプを行うコード断片

同じような事を、C言語で書くと、↓こうなる。

#include    <stdio.h>
#include    <string.h>

/*! 16進数ダンプする
    \arg    _ptr    ダンプ対象のベースポインタ
    \arg    start   ダンプ開始位置
    \arg    size    ダンプ個数
*/
void dump(const void* _ptr, int start, int size)
{
    const int   ALIGN = 16;
    const int   HALF_ALIGN = 8;
    
    char    buff[256], asc[40], temp[10];
    int     i, j;
    
    const unsigned char*    ptr = reinterpret_cast<const unsigned char*>(_ptr);
    ptr += start;
    
    if(!ptr || !size) return;
    buff[0] = '\0';
    asc[0] = '\0';
    for(i = 0; i < size; i++){
        if((i % ALIGN) == 0){
            sprintf(temp, "%08lx:", ptr + i);
            strcat(buff, temp);
        }
        sprintf(temp, "%02x ", ptr[i]);
        if(((i + HALF_ALIGN) % ALIGN) == 0) strcat(buff, "- ");
        strcat(buff, temp);
        sprintf(temp, "%c", (0x20 <= ptr[i]) && (ptr[i] < 0x80) ? ptr[i] : '.');
        strcat(asc, temp);
        if((i % ALIGN) == (ALIGN - 1)){
            printf("%s : %s\n", buff, asc);
            buff[0] = '\0';
            asc[0] = '\0';
        }
    }
    
    if(strlen(buff) != 0){
        for(j = 0; j < (ALIGN - (size % ALIGN)); j++){
            if(((i + j + HALF_ALIGN) % ALIGN) == 0) strcat(buff, "- ");
            strcat(buff, "   ");
        }
        printf("%s : %s\n", buff, asc);
    }
}

int main(void)
{
    char        buff[100];  // dust buffer
    dump(buff, 0, 10);
    return 0;
}

更に迂遠な方法を取ると、↓こう。

#include    <stdio.h>
#include    <string.h>
#include    <assert.h>

/*! 読み出し抽象クラス
*/
class IReader {
public:
    virtual ~IReader()
        { /* do nothing */ }
    virtual void seek(int pos) const = 0;
    virtual unsigned char read(void) const = 0;
};

/*! メモリに対して読み出しクラス
*/
class MemoryReader : public IReader {
public:
    MemoryReader(const void* ptr) : 
        m_ptr(reinterpret_cast<const unsigned char*>(ptr)), m_pos(0) {}
    virtual void seek(int pos) const {
        assert(pos >= 0);
        m_pos = pos;
    }
    virtual unsigned char read(void) const {
        unsigned char   v = m_ptr[m_pos];
        m_pos++;
        return v;
    }
private:
    const unsigned char*    m_ptr;
    mutable int             m_pos;
};

/*! 16進数ダンプする
    \arg    is      ダンプ対象の読み出しクラス
    \arg    start   ダンプ開始位置
    \arg    size    ダンプ個数
*/
void dump(const IReader& is, int start, int size)
{
    const int   ALIGN = 16;
    const int   HALF_ALIGN = 8;
    
    char    buff[256], asc[40], temp[10];
    int     i, j;
    
    is.seek(start);
    
    if(!size) return;
    buff[0] = '\0';
    asc[0] = '\0';
    for(i = 0; i < size; i++){
        if((i % ALIGN) == 0){
            sprintf(temp, "%08lx:", start + i);
            strcat(buff, temp);
        }
        unsigned char   v = is.read();
        sprintf(temp, "%02x ", v);
        if(((i + HALF_ALIGN) % ALIGN) == 0) strcat(buff, "- ");
        strcat(buff, temp);
        sprintf(temp, "%c", (0x20 <= v) && (v < 0x80) ? v : '.');
        strcat(asc, temp);
        if((i % ALIGN) == (ALIGN - 1)){
            printf("%s : %s\n", buff, asc);
            buff[0] = '\0';
            asc[0] = '\0';
        }
    }
    
    if(strlen(buff) != 0){
        for(j = 0; j < (ALIGN - (size % ALIGN)); j++){
            if(((i + j + HALF_ALIGN) % ALIGN) == 0) strcat(buff, "- ");
            strcat(buff, "   ");
        }
        printf("%s : %s\n", buff, asc);
    }
}

int main(void)
{
    char            buff[100];
    for(int i = 0; i < 100; i++) buff[i] = i % 256;
    
    MemoryReader    ms(buff);
    dump(ms, 0, 10);
    return 0;
}

IReaderクラスの seek と read メソッドをオーバーライドすれば、ファイルにも対応できますよ〜ってな次第。