Exemplo n.º 1
0
namespace Common
{

const RunType RunType::full = RunType("full");
const RunType RunType::fullfiles = RunType("fullfiles");
const RunType RunType::delta = RunType("delta");


RunType::RunType(std::string textRepresentation):
	textRepresentation(textRepresentation)
{

}

std::string RunType::toString() const
{
	return textRepresentation;
}

const RunType& RunType::fromString(const std::string& str)
{
	if(str == full.toString())
	{
		return full;
	}
	else if(str == fullfiles.toString())
	{
		return fullfiles;
	}
	else if(str == delta.toString())
	{
		return delta;
	}
	else
	{
		throw std::runtime_error("Invalid RunType string: " + str);
	}
}

bool RunType::operator==(const RunType& other) const
{
	return textRepresentation == other.textRepresentation;
}

bool RunType::operator!=(const RunType& other) const
{
	return !(*this == other);
}

}
Exemplo n.º 2
0
int32_t DMGPartition::readRun(void* buf, int32_t runIndex, uint64_t offsetInSector, int32_t count)
{
	BLKXRun* run = &m_table->runs[runIndex];
	RunType runType = RunType(be(run->type));
	
	count = std::min<uint64_t>(count, uint64_t(be(run->sectorCount))*512 - offsetInSector);
	
#ifdef DEBUG
	std::cout << "readRun(): runIndex = " << runIndex << ", offsetInSector = " << offsetInSector << ", count = " << count << std::endl;
#endif
	
	switch (runType)
	{
		case RunType::Unknown: // My guess is that this value indicates a hole in the file (sparse file)
		case RunType::ZeroFill:
			//std::cout << "ZeroFill\n";
			memset(buf, 0, count);
			return count;
		case RunType::Raw:
			//std::cout << "Raw\n";
			return m_disk->read(buf, count, be(run->compOffset) + be(m_table->dataStart) + offsetInSector);
		case RunType::LZFSE:
#ifndef COMPILE_WITH_LZFSE
			throw function_not_implemented_error("LZFSE is not yet supported");
#endif
		case RunType::Zlib:
		case RunType::Bzip2:
		case RunType::ADC:
		{
			std::unique_ptr<DMGDecompressor> decompressor;
			std::shared_ptr<Reader> subReader;
			
			subReader.reset(new SubReader(m_disk, be(run->compOffset) + be(m_table->dataStart), be(run->compLength)));
			decompressor.reset(DMGDecompressor::create(runType, subReader));
			
			if (!decompressor)
				throw std::logic_error("DMGDecompressor::create() returned nullptr!");

			unsigned long long int compLength = be(run->sectorCount)*512;
			if ( offsetInSector > compLength )
				return 0;
			if ( offsetInSector + count > compLength )
				count = compLength - offsetInSector;

			int32_t dec = decompressor->decompress((uint8_t*)buf, count, offsetInSector);
			if (dec < count)
				throw io_error("Error decompressing stream");
			return count;
		}
		default:
			return 0;
	}
}
Exemplo n.º 3
0
DMGPartition::DMGPartition(std::shared_ptr<Reader> disk, BLKXTable* table)
: m_disk(disk), m_table(table)
{
	for (uint32_t i = 0; i < be(m_table->blocksRunCount); i++)
	{
		RunType type = RunType(be(m_table->runs[i].type));
		if (type == RunType::Comment || type == RunType::Terminator)
			continue;
		
		m_sectors[be(m_table->runs[i].sectorStart)] = i;
		
#ifdef DEBUG
		std::cout << "Sector " << i << " has type 0x" << std::hex << uint32_t(type) << std::dec << ", starts at byte "
			<< be(m_table->runs[i].sectorStart)*512l << ", compressed length: "
			<< be(m_table->runs[i].compLength) << ", compressed offset: " << be(m_table->runs[i].compOffset) + be(m_table->dataStart) << std::endl;
#endif
	}
}
Exemplo n.º 4
0
void DMGPartition::adviseOptimalBlock(uint64_t offset, uint64_t& blockStart, uint64_t& blockEnd)
{
	std::map<uint64_t, uint32_t>::iterator itRun = m_sectors.upper_bound(offset / SECTOR_SIZE);

	if (itRun == m_sectors.begin())
		throw io_error("Invalid run sector data");

	if (itRun == m_sectors.end())
		blockEnd = length();
	else
		blockEnd = itRun->first * SECTOR_SIZE;

	itRun--;

	blockStart = itRun->first * SECTOR_SIZE;
	
	// Issue #22: empty areas may be larger than 2**31 (causing bugs in callers).
	// Moreover, there is no such thing as "optimal block" in zero-filled areas.
	RunType runType = RunType(be(m_table->runs[itRun->second].type));
	if (runType == RunType::ZeroFill || runType == RunType::Unknown || runType == RunType::Raw)
		Reader::adviseOptimalBlock(offset, blockStart, blockEnd);
}