Goto: [ Program Documentation ]
// // Programmer: Craig Stuart Sapp <craig@ccrma.stanford.edu> // Creation Date: Wed Jan 13 08:31:19 PST 1999 // Last Modified: Wed Jan 13 08:31:19 PST 1999 // Filename: ...improv/doc/examples/improv/vlv/vlv.cpp // Syntax: C++; improv // $Smake: g++ -O3 -o ../bin/%b -I../include %f -L../lib % // -limprov && strip %b // // Description: Takes Variable Length Values and returns them as // the correct value or vice-versa // #include "Options.h" #include <stdlib.h> #ifndef OLDCPP #include <iostream> #include <iomanip> using namespace std; #else #include <iostream.h> #include <iomanip.h> #endif #define DECODE 0 #define ENCODE 1 // Global variables for command-line options. Options options; // for command-line processing int direction = DECODE; // decoding=0, encoding=1 int inputStyle = 16; // number base of the input (2, 10, or 16) int outputStyle = 16; // number base of the output (2, 10, or 16) int inCount = 0; // number of command line input numbers int* input = NULL; // storage of input numbers; // function declarations: void checkOptions(Options& opts); void displayVLV(int number, ostream& out); void example(void); void printbinary(int number, ostream& out); void usage(const char* command); /////////////////////////////////////////////////////////////////////////// int main(int argc, char** argv) { options.setOptions(argc, argv); checkOptions(options); if (direction == DECODE) { // decoding unsigned long output = 0; for (int i=0; i<inCount; i++) { output = output << 7; output |= input[i] & 0x7f; } switch (outputStyle) { case 2: printbinary(output, cout); cout << endl; break; case 16: cout << hex << output << endl; break; default: cout << dec << output << endl; } } else { // encoding displayVLV(input[0], cout); cout << endl; } if (input != NULL) delete [] input; return 0; } /////////////////////////////////////////////////////////////////////////// ////////////////////////////// // // checkOptions -- // void checkOptions(Options& opts) { opts.define("2|bin=b"); // boolean for binary input opts.define("d|dec=b"); // boolean for decimal input opts.define("b=b"); // boolean for binary output opts.define("c=b"); // boolean for decimal output opts.define("x|hex=b"); // boolean for hex output opts.define("author=b"); opts.define("version=b"); opts.define("example=b"); opts.define("h|help=b"); opts.process(); if (opts.getBoolean("author")) { cout << "Written by Craig Stuart Sapp, " "craig@ccrma.stanford.edu, January 1999" << endl; exit(0); } else if (opts.getBoolean("version")) { cout << "vlv, version 1.0 (14 Jan 1999)\n" "compiled: " << __DATE__ << endl; exit(0); } else if (opts.getBoolean("help")) { usage(opts.getCommand()); exit(0); } else if (opts.getBoolean("example")) { example(); exit(0); } // determine input style (the default is 16) if (opts.getBoolean("2")) { inputStyle = 2; } else if (opts.getBoolean("d")) { inputStyle = 10; } else { inputStyle = 16; } // determine output style (the default is the input style) if (opts.getBoolean("b")) { outputStyle = 2; } else if (opts.getBoolean("x")) { outputStyle = 16; } else if (opts.getBoolean("c")) { outputStyle = 10; } else { outputStyle = inputStyle; } if (opts.getArgCount() == 0) { usage(opts.getCommand()); exit(1); } else if (opts.getArgCount() == 1) { // encoding into VLV values direction = ENCODE; } else { // decoding from VLV values direction = DECODE; } // process the input numbers: inCount = opts.getArgCount(); if (inCount > 4) { cout << "Error: VLV values cannot have more than four bytes" << endl; exit(1); } if (input != NULL) delete [] input; input = new int[inCount]; for (int i=1; i<=opts.getArgCount(); i++) { input[i-1] = strtol(opts.getArg(i), NULL, inputStyle); if (direction == DECODE && i != inCount) { if (input[i-1] < 0x80 || input[i-1] > 255) { cout << "Invalid VLV byte: " << opts.getArg(i) << endl; exit(1); } } else if (direction == DECODE && i == inCount) { if (input[i-1] < 0 || input[i-1] >0x7f) { cout << "Invalid VLV byte: " << opts.getArg(i) << endl; exit(1); } } } } ////////////////////////////// // // displayVLV -- prints the number in VLV form // void displayVLV(int number, ostream& out) { unsigned long value = (unsigned long)number; if (value >= (1 << 28)) { cout << "Error: number too large to handle" << endl; exit(1); } unsigned long byte[4]; byte[0] = (value >> 21) & 0x7f; byte[1] = (value >> 14) & 0x7f; byte[2] = (value >> 7) & 0x7f; byte[3] = (value >> 0) & 0x7f; int i; int flag = 0; for (i=0; i<3; i++) { if (byte[i] != 0) { flag = 1; } if (flag) { byte[i] |= 0x80; } } for (i=0; i<4; i++) { if (byte[i] >= 0x80 || i == 3) { switch (outputStyle) { case 2: printbinary(byte[i], out); break; case 16: out << hex << byte[i]; break; default: out << dec << byte[i]; } if (i != 3) { cout << ' '; } } } } ////////////////////////////// // // example -- shows various command-line option calls to program. // void example(void) { cout << "\n" "# convert a hex number to VLV bytes:\n" "vlv 3fff\n" "\n" "# convert a hex number to VLV bytes in decimal notation:\n" "vlv -c 3fff\n" "\n" "# convert a decimal number to VLV bytes in decimal notation:\n" "vlv -d -c 54632\n" "\n" "# convert hex VLV bytes into hex number:\n" "vlv 81 80 F4 00\n" "\n" "# convert hex VLV bytes into dec number:\n" "vlv -c 81 80 F4 00\n" "\n" << endl; } ////////////////////////////// // // printbinary -- prints the number in binary form with no // leading zeros. // void printbinary(int number, ostream& out) { unsigned long value = (unsigned long) number; int flag = 0; for (int i=0; i<32; i++) { if (value & (1 << (31-i))) { flag = 1; } if (flag) { if (value & (1 << (31-i))) { out << '1'; } else { out << '0'; } } } if (flag == 0) { out << '0'; } } ////////////////////////////// // // usage -- how to run this program from the command-line. // void usage(const char* command) { cout << "\n" "Convert/Create Variable Length Values.\n" "\n" "Usage: " << command << " [-d|-2] [-x|-c|-b] number(s)\n" "\n" "Options:\n" " -d = input numbers are given in decimal notation (hex is default)\n" " -2 = input numbers are given in binary notation (hex is default)\n" " -b = output numbers are given in binary notation\n" " -c = output numbers are given in decimal notation\n" " -x = output numbers are given in hexadecimal notation\n" " --options = list all options, default values, and aliases\n" "\n" << endl; } // md5sum: 9ab1bf95badc70d153294b2125c4ee7f vlv.cpp [20050403]