~drizzle-trunk/drizzle/development

324.1.1 by Mats Kindahl
Adding specification of a simple protobuf-based binary log format,
1
#include "binlog_encoding.h"
2
3
#include <cstdlib>
4
#include <iostream>
5
#include <iomanip>
6
#include <stdexcept>
7
#include <getopt.h>
8
9
using std::ios;
10
using std::cout;
11
using std::cerr;
12
using std::flush;
13
14
void print_usage_and_exit(char *prog) {
15
  const char *name= strrchr(prog, '/');
16
  if (name)
17
    ++name;
18
  else
19
    name= "length";
20
  cerr << "Usage:\n"
21
       << "    " << name << " [ -vvvx ] -e <number> ...\n";
22
  cerr << "    " << name << " [ -vvvx ] -d <byte> ...\n";
23
  cerr << flush;
24
  exit(1);
25
}
26
27
void encode(int argc, char *argv[], int verbose_level, bool hex_output) {
28
  for (int i = 0 ; i < argc ; ++i) {
29
    size_t length = strtoul(argv[i], NULL, 0);
30
31
    if (length < 2)
32
      throw std::invalid_argument("Length has to be > 1");
33
34
    unsigned char buf[128];
35
    unsigned char *end= length_encode(length, buf);
36
    ios::fmtflags saved_flags= cout.flags();
37
    if (verbose_level > 0)
38
      cout << "Length " << length << ": ";
39
    if (hex_output)
40
      cout << std::hex << std::setw(2) << std::setfill('0');
41
    unsigned char *ptr= buf;
42
    while (true) {
43
      if (hex_output)
44
        cout << "0x";
45
      cout << (unsigned int) *ptr;
46
      if (++ptr == end)
47
        break;
48
      cout << " ";
49
    }
50
    cout << std::endl;
51
    cout.setf(saved_flags);
52
  }
53
}
54
55
56
void decode(int argc, char *argv[], int verbose_level, bool hex_output) {
57
  unsigned char buf[128];
58
  for (int i = 0 ; i < argc ; ++i)
59
    buf[i]= strtoul(argv[i], NULL, 0);
60
61
  size_t length;
62
  (void) length_decode(buf, &length);
63
64
  ios::fmtflags saved_flags= cout.flags();
65
  if (verbose_level > 0)
66
    cout << "Length ";
67
  if (hex_output)
68
    cout.setf(ios::hex, ios::basefield);
69
  cout << length << std::endl;
70
  cout.setf(saved_flags);
71
}
72
73
74
int main(int argc, char *argv[]) {
75
  enum { NO_ACTION, ENCODE_ACTION, DECODE_ACTION } action= NO_ACTION;
76
77
  static struct option long_options[] = {
78
    { "decode",  0 /* has_arg */, NULL, 'd' },
79
    { "encode",  0 /* has_arg */, NULL, 'e' },
80
    { "verbose", 0 /* has_arg */, NULL, 'v' },
81
    { "hex",     0 /* has_arg */, NULL, 'x' },
82
    { 0, 0, 0, 0 }
83
  };
84
85
  int verbose_level= 0;
86
  bool hex_output= false;
87
  int ch;
88
89
  while ((ch= getopt_long(argc, argv, "devx", long_options, NULL)) != -1) {
90
    switch (ch) {
91
    case 0:
92
    case '?':
93
      print_usage_and_exit(argv[0]);
94
      break;
95
96
    case 'd':
97
      action= DECODE_ACTION;
98
      break;
99
100
    case 'e':
101
      action= ENCODE_ACTION;
102
      break;
103
104
    case 'v':
105
      ++verbose_level;
106
      break;
107
108
    case 'x':
109
      hex_output= true;
110
      break;
111
    }
112
  }
113
114
  try {
115
    switch (action) {
116
    case ENCODE_ACTION:
117
      encode(argc - optind, argv + optind, verbose_level, hex_output);
118
      break;
119
    case DECODE_ACTION:
120
      decode(argc - optind, argv + optind, verbose_level, hex_output);
121
      break;
122
    default:
123
      print_usage_and_exit(argv[0]);
124
      break;
125
    }
126
  }
127
  catch (std::invalid_argument& ex) {
128
    cerr << ex.what() << "\n";
129
    print_usage_and_exit(argv[0]);
130
  }
131
132
  return EXIT_SUCCESS;
133
}
134