// // MetroProMapHdr.cc - reads a file saved by Zygo's MetroPro software // in the binary (.dat) format, and prints the // information it finds stored in the header. // // Requirements: // 1. A text file called MetroProMapHdr.txt must be present in the working // directory where this program is run. That file must contain the // output produced by the MetroPro executable dat_test.exe, as in // % dat_test -maps > MetroProMapHdr.txt // This program finds and reads that MetroProMapHdr.txt file and uses // it as a key for decoding the information contained in the .dat file // passed by the user as a command line argument. // // Usage: $ MetroProMapHdr // where is the path to a binary-format MetroPro map file. #include #include #include #include #include #include int main(int argc, char* argv[]) { // Open MetroProMapHdr.txt which contains a map of the // information contained in the MetroPro binary file header. std::ifstream iftxt; iftxt.open("MetroProMapHdr.txt"); if (!iftxt.is_open()) { std::cerr << "Error - unable to open MetroProMapHdr.txt for input," << " cannot continue." << std::endl; exit(1); } if (argc != 2) { std::cerr << "Usage: MetroProMapHdr " << std::endl << " where is a binary data file that was" << " previously produced by MetroPro." << std::endl; exit(2); } // Open the MetroPro binary file given on the command line, // read the first 4096 bytes, and verify the magic number. std::ifstream ifbin; ifbin.open(argv[1]); if (!ifbin.is_open()) { std::cerr << "Error - unable to open input file " << argv[1] << " so cannot continue." << std::endl; exit(3); } unsigned int ihead[1024]; char *chead = (char*)ihead; ifbin.read(chead,4096); if (ifbin.fail()) { std::cerr << "Error - unable to read header from input file " << argv[1] << " so cannot continue." << std::endl; exit(4); } ifbin.close(); if (ihead[0] != ntohl(0x881b036f)) { std::cerr << "Error - input file " << argv[1] << " is not a valid MetroPro image file " << " so cannot continue." << std::endl; exit(5); } // Read the header format from the header // and find the section in the map that describes it. int header_format = ntohs(ihead[1]); std::stringstream hformss; hformss << "Header format " << header_format << " "; char mapline[4096]; iftxt.getline(mapline,4095); std::string hforms(hformss.str()); while (strstr(mapline,hforms.c_str()) != mapline) { iftxt.getline(mapline,4095); if (!iftxt.good()) { std::cerr << "Error - unable to find the section in the map" << " describing header format " << header_format << ", cannot continue." << std::endl; exit(6); } } iftxt.getline(mapline,4095); iftxt.getline(mapline,4095); iftxt.getline(mapline,4095); // Loop through the header map, looking up and printing // the values found in the header. while (iftxt.getline(mapline,4095).good() && strlen(mapline)) { std::string key; std::string bytes; int length; std::string field; std::string defvalue; std::stringstream maplines(mapline); if (maplines.str().length() < 2) { break; } else if (maplines.str().substr(0,1) == " ") { continue; } maplines >> key >> bytes >> length >> field >> defvalue; int byte0 = atoi(bytes.substr(0,4).c_str())-1; int byte1 = atoi(bytes.substr(5,4).c_str())-1; if (length && byte1-byte0 != length-1) { std::cerr << "Error - length field in map table does not agree" << " with byte range:" << std::endl << " length=" << length << ", bytes=" << byte0 << "-" << byte1 << std::endl; exit(7); } std::cout << std::setw(30) << std::left << field; std::string key1; if (key.length() > 0) { key1 = key.substr(0,1); } if (key1 == "I") { int ival=0; char *cval = (char*)&ival; if (key == "IB") { for (int i=0; i