Tracebin in C++

Core files

tracebin.h

// tracebin.h

#ifndef _TRACE_BIN
#define _TRACE_BIN

#include <ctype.h>
#include <stdio.h>

extern int ftracebin(FILE* pf, const char* data, int length);
extern int tracebin(const char* data, int length);

extern
char*
hex2str(const char* hexstr);

#endif

tracebin.cpp

// tracebin.cpp

#include "tracebin.h"
#include <assert.h>
#include <iostream>

using namespace std;

int ftracebin(FILE* fp, const char* data, int length)
{
  assert(NULL != fp);
  assert(NULL != data);

  enum { MAX_PRINT_HEX_LENGTH = 16 };
  int iPrintedLength = 0;
  int i = 0;

  while (length - iPrintedLength > 0)
  {
    fprintf(fp, "0x%06X  ", iPrintedLength);
    for (i = 0; i < MAX_PRINT_HEX_LENGTH; i++)
    {
      if (i == MAX_PRINT_HEX_LENGTH / 2)
        fprintf(fp, "  ");

      if (iPrintedLength + i < length)
        fprintf(fp, "%02X ", (unsigned char)data[iPrintedLength + i]);
      else
        fprintf(fp, "   ");
    }

    fprintf(fp, "  ");
    for (i = 0; i < MAX_PRINT_HEX_LENGTH; i++)
    {
      unsigned char x = data[iPrintedLength + i];
      if (iPrintedLength + i < length)
      {
        if (x >= 33 && x <= 126)
          fprintf(fp, "%c", x);
        else
          fprintf(fp, ".");
      }
      else
        fprintf(fp, "   ");
    }
    fprintf(fp, "\n");

    iPrintedLength += MAX_PRINT_HEX_LENGTH;
  }

  return 1;
}

int tracebin(const char* data, int length)
{
  return ftracebin(stdout, data, length);
}

/** Transfor hex string to buffer as file content.
 *
 * Transfor hex string, which looks like the second part of tracebin, to buffer as file content.
 *
 * @param [in] hexstr Hex string, the hex section of output of tracebin().
 *
 * @return NULL if any issue happened.
 *         string result of hex2str
 */
char*
hex2str(const char* hexstr)
{
  if (NULL == hexstr)
    return NULL;

  int hexlen = strlen(hexstr);

  char* restr = new char[hexlen/2];
  int   restr_index = 0;

  if (NULL == restr)
    return NULL;

  char bytedata = 0;
  char hextmp[3];
  memset(hextmp, 0, 3);

  // for (const char* ptr = hexstr; *ptr != '\0'; ptr++) {
  const char* ptr = hexstr;
  do {

    if (*ptr >= '0' && *ptr <= '9' ||
        *ptr >= 'A' && *ptr <= 'F' ||
        *ptr >= 'a' && *ptr <= 'f') {
      if (hextmp[0] == '\0')
      {
        hextmp[0] = *ptr;
      }
      else if (hextmp[1] == '\0')
      {
        hextmp[1] = *ptr;
      }

    }

    if (*ptr == ' ' ||
        *ptr == '\t' ||
        *ptr == '\0') {
      if (2 == strlen(hextmp)) {
        hextmp[2] = '\0';

        sscanf(hextmp, "%x", &bytedata);

        // std::cout << "Qiang---bytedata=" << std::endl;
        // tracebin(&bytedata, 1);

        memcpy(restr + restr_index++, &bytedata, 1);

        memset(hextmp, 0, 3);
      }
      else if (2 < strlen(hextmp))
        memset(hextmp, 0, 3);
    }
  } while(*ptr++ != '\0');
  // }
  return restr;
}


hex2str.cpp

// hex2str.cpp
/*
 * =====================================================================================
 *
 *       Filename:  hex2str.cpp
 *
 *    Description:
 *
 *        Version:  1.0
 *        Created:  05/08/2012 11:53:52 PM
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  YOUR NAME (),
 *        Company:
 *
 * =====================================================================================
 */

#include <iostream>
#include <fstream>
#include <string>

#include "tracebin.h"

void usage();

int main(int argc, char **argv)
{
  int option = -1;

  std::string arg_HexString;

  if (argc == 1) {
    usage();
    return 0;

  }

  while ((option = getopt (argc, argv, "d:h")) != -1)
  {
    switch (option)
    {
      case 'd':
        arg_HexString = optarg;
        break;
      case 'h':
        usage();
        exit(1);
      default:
        /*  unrecognised option ... add your error condition */
        usage();
        exit(1);
        break;
    }
  }

  std::cout << hex2str(arg_HexString.c_str()) << std::endl;

  return 0;
}

void usage() {
  std::cout << "hex2str OPTIONS" << std::endl;
  std::cout << "       -d <Hex>" << std::endl;
  std::cout << "       -h           Show this help." << std::endl;
}

Makefile

#
# Makefile
#
NAME     = tracebin
VERSION  = 1.1.0
BINNAME  = $(NAME)
LIBNAME  = lib$(NAME).so
SONAME   = $(LIBNAME).1

ifeq ($(shell echo "$$HOSTTYPE"),x86_64)
LIBDIR   = /lib64
else
LIBDIR   = /lib
endif

LDFLAGS   = -L.
LDFLAGS  += -ldl
CXXFLAGS +=
CPPFLAGS += -g -fPIC

#OBJS      = $(patsubst %.cpp,%.o,$(wildcard *.cpp))
OBJS      = tracebin.o

TMPDIR         = /var/tmp
SVNURL         = $(shell svn info | grep '^URL' | cut -b 6-)
SVNTMPDIR      = $(TMPDIR)/$(NAME)-$(VERSION)-tar

.PHONY: all clean tar

all: $(BINNAME) $(SONAME) \
        hex2str

hex2str: hex2str.o $(OBJS)
        @echo "#------------------------------------------------------------------------------"
        @echo "#                           Build $@"
        @echo "#------------------------------------------------------------------------------"
        $(CXX) $(CPPFLAGS) $^ -o $@ $(LDFLAGS)

$(BINNAME): main.o $(OBJS)
        @echo "#------------------------------------------------------------------------------"
        @echo "#                           Build $@"
        @echo "#------------------------------------------------------------------------------"
        $(CXX) $(CPPFLAGS) $^ -o $@ $(LDFLAGS)

$(SONAME): $(OBJS)
        @echo "#------------------------------------------------------------------------------"
        @echo "#                           Build $@"
        @echo "#------------------------------------------------------------------------------"
        $(CXX) $(OBJS) -o $@ $(LDFLAGS) -shared -Wl,-soname,$(SONAME)
        ln -sf $@ $(LIBNAME)

tar:
        rm -rf $(SVNTMPDIR)
        mkdir -p $(SVNTMPDIR)
        svn export $(SVNURL) $(SVNTMPDIR)/$(NAME)-$(VERSION)
        tar cvf - -C $(SVNTMPDIR)/ $(NAME)-$(VERSION) | gzip >$(NAME)-$(VERSION)-$(shell date "+%Y%m%dT%H%M").tar.gz
        rm -rf $(SVNTMPDIR)

%.o: %.cpp
        $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $< -o $@

install:
        install -d $(ROOT)$(LIBDIR)
        install -m 755 $(SONAME) $(ROOT)$(LIBDIR)/$(SONAME)
        cp -P $(LIBNAME) $(ROOT)$(LIBDIR)/$(LIBNAME)
        install -d $(ROOT)/include
        install -m 444 tracebin.h $(ROOT)/include/tracebin.h

clean:
        $(RM) $(BINNAME) hex2str $(LIBNAME) $(SONAME) *.o *~

Generate a Linux command

main.cpp

// main.cpp

#include <iostream>
#include <fstream>
#include <string>

#include "tracebin.h"

void usage();

int main(int argc, char **argv)
{
  int option = -1;

  std::string argInFileName;

  if (argc == 1) {
    usage();
    return 0;

  }

  while ((option = getopt (argc, argv, "f:h")) != -1)
  {
    switch (option)
    {
      case 'f':
        argInFileName = optarg;
        break;
      case 'h':
        usage();
        exit(1);
      default:
        /*  unrecognised option ... add your error condition */
        usage();
        exit(1);
        break;
    }
  }

  if (!argInFileName.empty())
  {
    std::ifstream fin(argInFileName.c_str(), std::ios::binary);

    std::filebuf *pBuf = fin.rdbuf();

    int iBufSize = pBuf->pubseekoff (0, std::ios::end, std::ios::in);
    pBuf->pubseekpos (0, std::ios::in);

    char *buffer = new char [iBufSize];
    pBuf->sgetn (buffer, iBufSize);

    fin.close();

    tracebin(buffer, iBufSize);
  }

  return 0;
}

void usage() {
  std::cout << "tracebin OPTIONS" << std::endl;
  std::cout << "       -f <file>    File ready to HEX." << std::endl;
  std::cout << "       -h           Show this help." << std::endl;
}

Examples

Example 1

#include "tracebin.h"
#include <iostream>
#include <string>

#define MAX_LENGTH_STR  100

long add(long a, long b)
{
    tracebin((char *)&b, sizeof(long));
    return a + b;
}

int main(int argc, char **argv)
{
    printf("%ld\n", add(-95525, 0x17525));
    printf("%ld\n", add(1, 0xFFFFFFFF));
    return 0;
}

OUTPUT:

$LD_LIBRARY_PATH=.. ./test
0x000000  25 75 01 00 00 00 00 00                             %u......
0
0x000000  FF FF FF FF 00 00 00 00                             ........
4294967296




你可能感兴趣的:(String,File,null,buffer,FP,hex)