progress to fsio type safety (#2137)

* rename

* packed type safe fsio value

* comment

* rename

Co-authored-by: Matthew Kennedy <makenne@microsoft.com>
This commit is contained in:
Matthew Kennedy 2020-12-27 14:22:11 -08:00 committed by GitHub
parent 7b483e82a1
commit ba2c675ffa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 99 additions and 0 deletions

View File

@ -442,4 +442,42 @@ LEElement *LEElementPool::parseExpression(const char * line) {
}
}
FsioValue::FsioValue(float f)
{
u.f32 = f;
// The low bit represents whether this is a bool or not, clear it for float
u.u32 &= 0xFFFFFFFE;
}
FsioValue::FsioValue(bool b)
{
u.u32 = (b ? 2 : 0); // second bit is the actual value of the bool
// Low bit indicates this is a bool
u.u32 |= 0x1;
}
bool FsioValue::isFloat() const {
uint32_t typeBit = u.u32 & 0x1;
return typeBit == 0;
}
float FsioValue::asFloat() const {
return u.f32;
}
bool FsioValue::isBool() const {
uint32_t typeBit = u.u32 & 0x1;
return typeBit == 1;
}
bool FsioValue::asBool() const {
uint32_t boolBit = u.u32 & 0x2;
return boolBit != 0;
}
#endif /* EFI_FSIO */

View File

@ -64,6 +64,31 @@ typedef enum {
} le_action_e;
// This type borrows the least significant bit of a float and uses it to indicate
// whether it's actually a boolean hiding inside that float
class FsioValue
{
public:
/*implicit*/ FsioValue(float f);
/*implicit*/ FsioValue(bool b);
bool isFloat() const;
float asFloat() const;
bool isBool() const;
bool asBool() const;
private:
// These must match for this trick to work!
static_assert(sizeof(float) == sizeof(uint32_t));
union
{
uint32_t u32;
float f32;
} u;
};
using FsioResult = expected<float>;
class LEElement {

View File

@ -342,3 +342,39 @@ TEST(fsio, fuelPump) {
// Pump should be on!
EXPECT_TRUE(efiReadPin(GPIOA_0));
}
TEST(fsio, fsioValueFloat) {
FsioValue floatVal(3.5f);
EXPECT_TRUE(floatVal.isFloat());
EXPECT_FALSE(floatVal.isBool());
EXPECT_FLOAT_EQ(floatVal.asFloat(), 3.5f);
}
TEST(fsio, fsioValueFloatZero) {
FsioValue floatVal(0.0f);
EXPECT_TRUE(floatVal.isFloat());
EXPECT_FALSE(floatVal.isBool());
EXPECT_FLOAT_EQ(floatVal.asFloat(), 0);
}
TEST(fsio, fsioValueBoolTrue) {
FsioValue boolVal(true);
EXPECT_TRUE(boolVal.isBool());
EXPECT_FALSE(boolVal.isFloat());
EXPECT_TRUE(boolVal.asBool());
}
TEST(fsio, fsioValueBoolFalse) {
FsioValue boolVal(false);
EXPECT_TRUE(boolVal.isBool());
EXPECT_FALSE(boolVal.isFloat());
EXPECT_FALSE(boolVal.asBool());
}