#include #include #include namespace FxOS { //--- // Data types //--- static DataType _u8(IntegerType(1, false)); static DataType _i8(IntegerType(1, true)); static DataType _u16(IntegerType(2, false)); static DataType _i16(IntegerType(2, true)); static DataType _u32(IntegerType(4, false)); static DataType _i32(IntegerType(4, true)); DataType const *IntegerType::u8 = &_u8; DataType const *IntegerType::i8 = &_i8; DataType const *IntegerType::u16 = &_u16; DataType const *IntegerType::i16 = &_i16; DataType const *IntegerType::u32 = &_u32; DataType const *IntegerType::i32 = &_i32; BitfieldType::Field BitfieldType::named_field(std::string name) const { for(auto &f: fields) { if(f.first == name) return f; } throw std::domain_error("No such field name in bit field"); } DataType::DataKind DataType::kind() const noexcept { return (DataKind)v.index(); } size_t DataType::size() const noexcept { switch(kind()) { case Integer: return integer().size; case Bitfield: return bitfield().size; case Array: return array().size; case String: return string().size; case Struct: return structs().size; } return 0; }; IntegerType const &DataType::integer() const { return std::get(v); } BitfieldType const &DataType::bitfield() const { return std::get(v); } ArrayType const &DataType::array() const { return std::get(v); } StringType const &DataType::string() const { return std::get(v); } StructType const &DataType::structs() const { return std::get(v); } //--- // Data values //--- DataValue::DataValue(): type {nullptr} { } DataValue::DataValue(DataType const *type): type {type}, mem(type->size(), (int16_t)-1) { } void DataValue::access(size_t offset, size_t size) const { if(size != 1 && size != 2 && size != 4) throw std::logic_error("Invalid simulated access size"); if(offset + size > mem.size()) throw std::logic_error("Access overflows from data"); } uint32_t DataValue::read(size_t offset, size_t size) const { access(offset, size); uint32_t result = 0; while(size--) { int16_t byte = mem[offset++]; if(byte == -1) throw std::logic_error("Read uninitialized value"); result = (result << 8) | byte; } return result; } void DataValue::write(size_t offset, size_t size, uint32_t contents) { access(offset, size); offset += size; while(size-- > 0) { mem[--offset] = contents & 0xff; contents >>= 8; } } std::string DataValue::str() const noexcept { std::string result; switch(type->kind()) { /* Format all integers in hexadecimal */ case DataType::Integer: return format("0x%0*x", 2*type->size(), read(0,type->size())); /* TODO: Print data values of complex types */ case DataType::Bitfield: case DataType::Array: case DataType::String: case DataType::Struct: /* If the type is not supported, use hexadecimal notation */ default: for(size_t i = 0; i < mem.size(); i++) { int16_t byte = mem[i]; if(byte == -1) result += " UND"; else result += format(" %02x", byte); } result[0] = '{'; result += '}'; } return result; } } /* namespace FxOS */