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 メソッドをオーバーライドすれば、ファイルにも対応できますよ〜ってな次第。