From 9ddc14bb9b154518e2b8384d3f4571cf657c7920 Mon Sep 17 00:00:00 2001 From: srs5694 Date: Sun, 22 Aug 2010 22:44:42 -0400 Subject: Revisions for 0.6.10 release --- attributes.cc | 163 +++++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 133 insertions(+), 30 deletions(-) (limited to 'attributes.cc') diff --git a/attributes.cc b/attributes.cc index 527dc87..c9c1d23 100644 --- a/attributes.cc +++ b/attributes.cc @@ -8,36 +8,38 @@ #define __STDC_LIMIT_MACROS #define __STDC_CONSTANT_MACROS -#include #include #include #include #include + #include "attributes.h" +#include "support.h" using namespace std; -// Constructor. Its main task is to initialize the attribute name -// data. -Attributes::Attributes(void) { - int i; - ostringstream temp; +string Attributes::atNames[NUM_ATR]; +Attributes::staticInit Attributes::staticInitializer; +Attributes::staticInit::staticInit (void) { + ostringstream temp; + // Most bits are undefined, so start by giving them an // appropriate name - for (i = 1; i < NUM_ATR; i++) { + for (int i = 0; i < NUM_ATR; i++) { + temp.str(""); temp << "Undefined bit #" << i; - atNames[i] = temp.str(); + Attributes::atNames[i] = temp.str(); } // for // Now reset those names that are defined.... - atNames[0] = "system partition"; // required for computer to operate - atNames[1] = "hide from EFI"; - atNames[2] = "legacy BIOS bootable"; - atNames[60] = "read-only"; - atNames[62] = "hidden"; - atNames[63] = "do not automount"; -} // Attributes constructor + Attributes::atNames[0] = "system partition"; // required for computer to operate + Attributes::atNames[1] = "hide from EFI"; + Attributes::atNames[2] = "legacy BIOS bootable"; + Attributes::atNames[60] = "read-only"; + Attributes::atNames[62] = "hidden"; + Attributes::atNames[63] = "do not automount"; +} // Attributes::staticInit::staticInit // Destructor. Attributes::~Attributes(void) { @@ -45,7 +47,8 @@ Attributes::~Attributes(void) { // Display current attributes to user void Attributes::DisplayAttributes(void) { - int i; + uint32_t i; + int numSet = 0; cout << "Attribute value is "; cout.setf(ios::uppercase); @@ -53,37 +56,137 @@ void Attributes::DisplayAttributes(void) { cout.width(16); cout << hex << attributes << dec << ". Set fields are:\n"; for (i = 0; i < NUM_ATR; i++) { - if (((attributes >> i) % 2) == 1) { // bit is set - if (atNames[NUM_ATR - i - 1].substr(0, 9) != "Undefined") - cout << atNames[NUM_ATR - i - 1] << "\n"; + if ((UINT64_C(1) << i) & attributes) { + cout << i << " (" << Attributes::GetAttributeName(i) << ")" << "\n"; + numSet++; } // if } // for cout.fill(' '); + if (numSet == 0) + cout << " No fields set\n"; + cout << "\n"; } // Attributes::DisplayAttributes() // Prompt user for attribute changes void Attributes::ChangeAttributes(void) { - int response, i; + int response; uint64_t bitValue; cout << "Known attributes are:\n"; - for (i = 0; i < NUM_ATR; i++) { - if (atNames[i].substr(0, 9) != "Undefined") - cout << i << " - " << atNames[i] << "\n"; - } // for + ListAttributes(); + cout << "\n"; do { - response = GetNumber(0, 64, -1, (string) "Toggle which attribute field (0-63, 64 to exit): "); + DisplayAttributes(); + response = GetNumber(0, NUM_ATR, -1, "Toggle which attribute field (0-63, 64 to exit): "); if (response != 64) { - bitValue = PowerOf2(uint32_t (NUM_ATR - response - 1)); // Find the integer value of the bit - if ((bitValue & attributes) == bitValue) { // bit is set - attributes -= bitValue; // so unset it - cout << "Have disabled the '" << atNames[response] << "' attribute.\n"; + bitValue = UINT64_C(1) << response; // Find the integer value of the bit + if (bitValue & attributes) { // bit is set + attributes &= ~bitValue; // so unset it + cout << "Have disabled the '" << atNames[response] << "' attribute.\n"; } else { // bit is not set - attributes += bitValue; // so set it + attributes |= bitValue; // so set it cout << "Have enabled the '" << atNames[response] << "' attribute.\n"; } // if/else } // if } while (response != 64); } // Attributes::ChangeAttributes() +// Display all defined attributes on the screen (omits undefined bits). +void Attributes::ListAttributes(void) { + uint32_t bitNum; + string tempAttr; + + for (bitNum = 0; bitNum < NUM_ATR; bitNum++) { + tempAttr = GetAttributeName(bitNum); + if (tempAttr.substr(0, 15) != "Undefined bit #" ) + cout << bitNum << ": " << Attributes::GetAttributeName(bitNum) << "\n"; + } // for +} // Attributes::ListAttributes + +void Attributes::ShowAttributes(const uint32_t partNum) { + uint32_t bitNum; + bool bitset; + + for (bitNum = 0; bitNum < 64; bitNum++) { + bitset = (UINT64_C(1) << bitNum) & attributes; + if (bitset) { + cout << partNum+1 << ":" << bitNum << ":" << bitset + << " (" << Attributes::GetAttributeName(bitNum) << ")" << endl; + } // if + } // for +} // Attributes::ShowAttributes + +// multifaceted attributes access +// returns true upon success, false upon failure +bool Attributes::OperateOnAttributes(const uint32_t partNum, const string& attributeOperator, const string& attributeBits) { + + // attribute access opcode + typedef enum { + ao_or, ao_nand, ao_xor, ao_assignall, // operate on all attributes (bitmask) + ao_unknown, // must be after bitmask operators and before bitnum operators + ao_set, ao_clear, ao_toggle, ao_get // operate on a single attribute (bitnum) + } attribute_opcode_t; // typedef enum + + // translate attribute operator into an attribute opcode + attribute_opcode_t attributeOpcode = ao_unknown; { // opcode is not known yet + if (attributeOperator == "or") attributeOpcode = ao_or; + else if (attributeOperator == "nand") attributeOpcode = ao_nand; + else if (attributeOperator == "xor") attributeOpcode = ao_xor; + else if (attributeOperator == "=") attributeOpcode = ao_assignall; + else if (attributeOperator == "set") attributeOpcode = ao_set; + else if (attributeOperator == "clear") attributeOpcode = ao_clear; + else if (attributeOperator == "toggle") attributeOpcode = ao_toggle; + else if (attributeOperator == "get") attributeOpcode = ao_get; + else { + cerr << "Unknown attributes operator: " << attributeOperator << endl; + return false; + } // else + } // attributeOpcode + + // get bit mask if operating on entire attribute set + uint64_t attributeBitMask; { if (attributeOpcode < ao_unknown) { + if (1 != sscanf (attributeBits.c_str(), "%qx", (long long unsigned int*) &attributeBitMask)) { + cerr << "Could not convert hex attribute mask" << endl; + return false; + } // if + }} // attributeBitMask, if + + // get bit number and calculate bit mask if operating on a single attribute + int bitNum; { if (attributeOpcode > ao_unknown) { + if (1 != sscanf (attributeBits.c_str(), "%d", &bitNum)) { + cerr << "Could not convert bit number" << endl; + return false; + } // if + const uint64_t one = 1; + attributeBitMask = one << bitNum; + }} // bitNum, if + + switch (attributeOpcode) { + // assign all attributes at once + case ao_assignall: attributes = attributeBitMask; break; + + // set individual attribute(s) + case ao_set: + case ao_or: attributes |= attributeBitMask; break; + + // clear individual attribute(s) + case ao_clear: + case ao_nand: attributes &= ~attributeBitMask; break; + + // toggle individual attribute(s) + case ao_toggle: + case ao_xor: attributes ^= attributeBitMask; break; + + // display a single attribute + case ao_get: { + cout << partNum+1 << ":" << bitNum << ":" << + bool (attributeBitMask & attributes) << endl; + break; + } // case ao_get + + default: break; // will never get here + } // switch + + return true; +} // Attributes::OperateOnAttributes() -- cgit v1.2.1