void isoFile::ReadBlock(u8* dst, uint lsn) { if (lsn > m_blocks) { FastFormatUnicode msg; msg.Write("isoFile error: Block index is past the end of file! (%u > %u).", lsn, m_blocks); pxAssertDev(false, msg); Console.Error(msg); // [TODO] : Throw exception? // Typically an error like this is bad; indicating an invalid dump or corrupted // iso file. return; } if (m_flags == ISOFLAGS_BLOCKDUMP_V2) _ReadBlockD(dst, lsn); else _ReadBlock(dst, lsn); if (m_type == ISOTYPE_CD) { lsn_to_msf(dst + 12, lsn); dst[15] = 2; } }
status_t _GetBlock(uint64 blockIndex, CheckSumBlock*& _block) { // check whether we have already cached the block for (BlockList::Iterator it = fBlocks.GetIterator(); CheckSumBlock* block = it.Next();) { if (block->used && block->blockIndex) { // we know it -- requeue and return it.Remove(); fBlocks.Add(block); _block = block; return B_OK; } } // flush the least recently used block and recycle it CheckSumBlock* block = fBlocks.Head(); status_t error = _FlushBlock(block); if (error != B_OK) return error; error = _ReadBlock(block, blockIndex); if (error != B_OK) return error; // requeue fBlocks.Remove(block); fBlocks.Add(block); _block = block; return B_OK; }
Item Database::_ReadBlock(uint64_t blockpos, uint64_t jmpfrom) { _GetLock(blockpos, true); uint64_t blkhdrs[4]; backing.read((char*)blkhdrs, sizeof(uint64_t)*4); if (blkhdrs[1] != blkhdrs[2] && blkhdrs[0] == 0 && jmpfrom == 0) std::cerr << "Corrupt header in block @ " << blockpos << " (sizes differ, but no JMP)" << std::endl; char content[blkhdrs[2]]; uint64_t contentlen = blkhdrs[1]; backing.read(content, contentlen); if (blkhdrs[0] != 0) { Item tomerge = _ReadBlock(blkhdrs[0], blockpos); for (uint64_t i = 0; i < tomerge.itemsize; i++) { content[contentlen] = tomerge.item[i]; contentlen++; } } _ReleaseLock(blockpos, true); Item toret; toret.itemsize = contentlen; toret.item = content; return toret; }
IndexBlock Database::_ReadIndex(const uint64_t indexpos) { Item indexblockraw = _ReadBlock(indexpos, 0); IndexBlock output; output.HighestID = *((uint64_t*)indexblockraw.item); /* ulong - highest used row ID ulong - row ID uint - name length cstr - name ulong - byte location of block */ uint64_t codepos = sizeof(uint64_t); //Because I'm lazy, and whenever a compiler f***s up the standard while (indexblockraw.itemsize < codepos) { Index toinput; toinput.id = *((uint64_t*)indexblockraw.item+codepos); codepos += sizeof(toinput.id); uint32_t namelen = *((uint32_t*)indexblockraw.item+codepos); codepos += sizeof(namelen); toinput.name = (char*)malloc(namelen); strcpy(toinput.name, indexblockraw.item+codepos); codepos += namelen; toinput.blockoffset = *((uint64_t*)indexblockraw.item+codepos); codepos += sizeof(toinput.blockoffset); output.Indexes.insert(output.Indexes.end(), toinput); } return output; }
Item* Database::operator[] (const char* id) { for (uint64_t i = 0; i < indexstore.Indexes.size(); ++i) { if (strcmp(indexstore.Indexes[i].name, id)) { Item target = _ReadBlock(indexstore.Indexes[i].blockoffset, 0); Item *output = (Item *) malloc(sizeof(Item)); *output = target; return output; } throw Exceptions::ITEM_NOT_FOUND; } }
uint16_t I2C_eeprom::readBlock(const uint16_t memoryAddress, uint8_t* buffer, const uint16_t length) { uint16_t addr = memoryAddress; uint16_t len = length; uint16_t rv = 0; while (len > 0) { uint8_t cnt = min(len, I2C_TWIBUFFERSIZE); rv += _ReadBlock(addr, buffer, cnt); addr += cnt; buffer += cnt; len -= cnt; } return rv; }
uint64_t Database::AddItem(const Item item) { Index toadd; Item topmostblock = _ReadBlock(indexstore.HighestID, 0); uint64_t blockpos = indexstore.Indexes[indexstore.HighestID].blockoffset+topmostblock.itemsize; _WriteBlock(item, blockpos); toadd.blockoffset = blockpos; toadd.id = indexstore.HighestID+1; toadd.name = (char*)malloc(strlen(item.name)); strcpy(toadd.name, item.name); indexstore.Indexes.insert(indexstore.Indexes.end(), toadd); indexstore.HighestID++; return toadd.id; }
// returns 64, 32, 16, 8, 4, 2, 1, 0 // 0 is smaller than 1K int I2C_eeprom::determineSize() { int rv = 0; // unknown uint8_t orgValues[8]; uint16_t addr; // try to read a byte to see if connected rv += _ReadBlock(0x00, orgValues, 1); if (rv == 0) return -1; // remember old values, non destructive for (uint8_t i=0; i<8; i++) { addr = (512 << i) + 1; orgValues[i] = readByte(addr); } // scan page folding for (uint8_t i=0; i<8; i++) { rv = i; uint16_t addr1 = (512 << i) + 1; uint16_t addr2 = (512 << (i+1)) + 1; writeByte(addr1, 0xAA); writeByte(addr2, 0x55); if (readByte(addr1) == 0x55) // folded! { break; } } // restore original values for (uint8_t i=0; i<8; i++) { uint16_t addr = (512 << i) + 1; writeByte(addr, orgValues[i]); } return 0x01 << (rv-1); }
uint8_t I2C_eeprom::readByte(const uint16_t memoryAddress) { uint8_t rdata; _ReadBlock(memoryAddress, &rdata, 1); return rdata; }
Item* Database::operator[] (const uint64_t id) { Item target = _ReadBlock(indexstore.Indexes[id].blockoffset, 0); Item *output = (Item *) malloc(sizeof(Item)); *output = target; return output; }