#include namespace FxOS { DataValue::DataValue(): type(nullptr), determined(false) { } uint32_t DataValue::read(int offset, int size) { if(offset < 0 || size < 0 || (type->size && offset+size >= type->size)) throw std::logic_error("Invalid read into simulated data"); if(!size || size & (size - 1)) throw std::logic_error("Simulated read not a power of 2"); if(type->kind==DataType::Integral || type->kind==DataType::BitField) { int shift = (4 - size - offset) << 3; uint32_t u = uinteger >> shift; return (size == 4) ? u : (size == 2) ? (uint16_t)u : (uint8_t)u; } else if(type->kind == DataType::Array) { int elsize = type->arraytype->size; int index = offset / elsize; if(index >= (int)entries.size()) throw std::logic_error("Read out of array bounds"); /* Will throw if reading from two entries simultaneously */ return entries[index].read(offset % elsize, size); } else if(type->kind == DataType::Array) { int index = 0; while(offset >= type->attributes[index].size) { index++; offset -= type->attributes[index].size; } return entries[index].read(offset, size); } throw std::logic_error("Read into unknown DataValue kind"); } void DataValue::write(int offset, int size, uint32_t contents) { if(offset < 0 || size < 0 || (type->size && offset+size >= type->size)) throw std::logic_error("Invalid write into simulated data"); if(!size || size & (size - 1)) throw std::logic_error("Simulated write not a power of 2"); if(type->kind==DataType::Integral || type->kind==DataType::BitField) { uint32_t mask = (size == 1) ? 0xff : (size == 2) ? 0xffff : 0xffffffff; int shift = (4 - size - offset) << 3; uinteger = (uinteger & ~(mask << shift)) | (contents << shift); } else if(type->kind == DataType::Array) { int elsize = type->arraytype->size; int index = offset / elsize; if(index >= (int)entries.size()) throw std::logic_error("Write out of array bounds"); entries[index].write(offset % elsize, size, contents); } else if(type->kind == DataType::Array) { int index = 0; while(offset >= type->attributes[index].size) { index++; offset -= type->attributes[index].size; } entries[index].write(offset, size, contents); } throw std::logic_error("Write into unknown DataValue kind"); } } /* namespace FxOS */