#include "bitfields.h" #include /// Takes a pointer, offset bitcount and data bitcount, returning the unsigned int read from the givens. /// offsetBits may be > 7, in which case offsetBits / 8 is added to the pointer automatically. /// This function assumes Most Significant Bits first. /// If dataBits > 64, only the last 64 bits are returned. unsigned long long Bit::getMSB(char * pointer, unsigned int offsetBits, unsigned int dataBits){ //If the offset is a whole byte or more, add the whole bytes to the pointer instead. pointer += offsetBits >> 3; //The offset is now guaranteed less than a whole byte. offsetBits &= 0x07; unsigned long long retVal = 0; //Now we parse the remaining bytes while (dataBits){ //Calculate how many bits we're reading from this byte //We assume all except for the offset unsigned int curBits = 8 - offsetBits; //If that is too much, we use the remainder instead if (curBits > dataBits){ curBits = dataBits; } //First, shift the current return value by the amount of bits we're adding retVal <<= curBits; //Next, add those bits from the current pointer position at the correct offset, increasing the pointer by one retVal |= ((int)(*(pointer++)) << offsetBits) >> (8 - curBits); //Finally, set the offset to zero and remove curBits from dataBits. offsetBits = 0; dataBits -= curBits; }//Loop until we run out of dataBits, then return the result return retVal; } /// Takes a pointer, offset bitcount and data bitcount, setting to given value. /// offsetBits may be > 7, in which case offsetBits / 8 is added to the pointer automatically. /// This function assumes Most Significant Bits first. /// WARNING: UNFINISHED. DO NOT USE. /// \todo Finish writing this - untested atm. void Bit::setMSB(char * pointer, unsigned int offsetBits, unsigned int dataBits, unsigned long long value){ //Set the pointer to the last byte we need to be setting pointer += (offsetBits + dataBits) >> 3; //The offset is now guaranteed less than a whole byte. offsetBits = (offsetBits + dataBits) & 0x07; unsigned long long retVal = 0; //Now we set the remaining bytes while (dataBits){ //Calculate how many bits we're setting in this byte //We assume all that will fit in the current byte unsigned int curBits = offsetBits; //If that is too much, we use the remainder instead if (curBits > dataBits){ curBits = dataBits; } //Set the current pointer position at the correct offset, increasing the pointer by one retVal |= ((int)(*(pointer++)) << offsetBits) >> (8 - curBits); *pointer = (((*pointer) << offsetBits) >> offsetBits) | ((value & 0xFF) << (8 - offsetBits)); --pointer; //Finally, shift the current value by the amount of bits we're adding value >>= offsetBits; //... and set the offset to eight and remove curBits from dataBits. offsetBits = 8; dataBits -= curBits; }//Loop until we run out of dataBits, then return the result } /// Parses a string reference to a boolean. /// Returns true if the string, with whitespace removed and converted to lowercase, prefix-matches any of: "1", "yes", "true", "cont". /// Returns false otherwise. bool Util::stringToBool(std::string & str){ std::string tmp; tmp.reserve(4); for (unsigned int i = 0; i < str.size() && tmp.size() < 4; ++i){ if (!::isspace(str[i])){ tmp.push_back((char)tolower(str[i])); } } return (strncmp(tmp.c_str(), "1", 1) == 0 || strncmp(tmp.c_str(), "yes", 3) == 0 || strncmp(tmp.c_str(), "true", 4) == 0 || strncmp(tmp.c_str(), "cont", 4) == 0); }