Esempio n. 1
0
// PrintToStream
void
ResourceFile::PrintToStream(bool longInfo)
{
	if (longInfo) {
		off_t resourcesOffset = fFile.GetOffset();
		printf("ResourceFile:\n");
		printf("file type              : %s\n", kFileTypeNames[fFileType]);
		printf("endianess              : %s\n",
			   (fHostEndianess == (bool)B_HOST_IS_LENDIAN) ? "little" : "big");
		printf("resource section offset: 0x%08Lx (%Ld)\n", resourcesOffset,
			   resourcesOffset);
		if (fInfoTableItem) {
			int32 offset = fInfoTableItem->GetOffset();
			int32 size = fInfoTableItem->GetSize();
			printf("resource info table    : offset: 0x%08lx (%ld), "
				   "size: 0x%08lx (%ld)\n", offset, offset, size, size);
		}
		printf("number of resources    : %ld\n", fResourceCount);
		for (int32 i = 0; i < fResourceCount; i++) {
			ResourceItem* item = ItemAt(i);
			item->PrintToStream();
		}
	} else {
		printf("   Type     ID     Size  Name\n");
		printf("  ------ ----- --------  --------------------\n");
		for (int32 i = 0; i < fResourceCount; i++) {
			ResourceItem* item = ItemAt(i);
			type_code type = item->GetType();
			char typeName[4] = { type >> 24, (type >> 16) & 0xff,
								 (type >> 8) & 0xff, type & 0xff };
			printf("  '%.4s' %5ld %8lu  %s\n", typeName, item->GetID(),
				   item->GetSize(), item->GetName());
		}
	}
}
Esempio n. 2
0
// WriteResources
uint32
ResourceFile::WriteResources(void* buffer, uint32 bufferSize)
{
	// calculate sizes and offsets
	// header
	uint32 size = kResourcesHeaderSize;
	// index section
	uint32 indexSectionOffset = size;
	uint32 indexSectionSize = kResourceIndexSectionHeaderSize
		+ fResourceCount * kResourceIndexEntrySize;
	indexSectionSize = align_value(indexSectionSize,
								   kResourceIndexSectionAlignment);
	size += indexSectionSize;
	// unknown section
	uint32 unknownSectionOffset = size;
	uint32 unknownSectionSize = kUnknownResourceSectionSize;
	size += unknownSectionSize;
	// data
	uint32 dataOffset = size;
	uint32 dataSize = 0;
	for (int32 i = 0; i < fResourceCount; i++) {
		ResourceItem* item = ItemAt(i);
		dataSize += item->GetSize();
	}
	size += dataSize;
	// info table
	uint32 infoTableOffset = size;
	uint32 infoTableSize = 0;
	type_code type = 0;
	for (int32 i = 0; i < fResourceCount; i++) {
		ResourceItem* item = ItemAt(i);
		if (i == 0 || type != item->GetType()) {
			if (i != 0)
				infoTableSize += kResourceInfoSeparatorSize;
			type = item->GetType();
			infoTableSize += kMinResourceInfoBlockSize;
		} else
			infoTableSize += kMinResourceInfoSize;
		uint32 nameLen = strlen(item->GetName());
		if (nameLen != 0)
			infoTableSize += nameLen + 1;
	}
	infoTableSize += kResourceInfoSeparatorSize + kResourceInfoTableEndSize;
	size += infoTableSize;
	// check whether the buffer is large enough
	if (!buffer)
		throw Exception("Supplied buffer is NULL.");
	if (bufferSize < size)
		throw Exception("Supplied buffer is too small.");
	// write...
	void* data = buffer;
	// header
	resources_header* resourcesHeader = (resources_header*)data;
	resourcesHeader->rh_resources_magic = kResourcesHeaderMagic;
	resourcesHeader->rh_resource_count = fResourceCount;
	resourcesHeader->rh_index_section_offset = indexSectionOffset;
	resourcesHeader->rh_admin_section_size = indexSectionOffset
											 + indexSectionSize;
	for (int32 i = 0; i < 13; i++)
		resourcesHeader->rh_pad[i] = 0;
	// index section
	// header
	data = skip_bytes(buffer, indexSectionOffset);
	resource_index_section_header* indexHeader
		= (resource_index_section_header*)data;
	indexHeader->rish_index_section_offset = indexSectionOffset;
	indexHeader->rish_index_section_size = indexSectionSize;
	indexHeader->rish_unknown_section_offset = unknownSectionOffset;
	indexHeader->rish_unknown_section_size = unknownSectionSize;
	indexHeader->rish_info_table_offset = infoTableOffset;
	indexHeader->rish_info_table_size = infoTableSize;
	fill_pattern(buffer, &indexHeader->rish_unused_data1, 1);
	fill_pattern(buffer, indexHeader->rish_unused_data2, 25);
	fill_pattern(buffer, &indexHeader->rish_unused_data3, 1);
	// index table
	data = skip_bytes(data, kResourceIndexSectionHeaderSize);
	resource_index_entry* entry = (resource_index_entry*)data;
	uint32 entryOffset = dataOffset;
	for (int32 i = 0; i < fResourceCount; i++, entry++) {
		ResourceItem* item = ItemAt(i);
		uint32 entrySize = item->GetSize();
		entry->rie_offset = entryOffset;
		entry->rie_size = entrySize;
		entry->rie_pad = 0;
		entryOffset += entrySize;
	}
	// padding + unknown section
	data = skip_bytes(buffer, dataOffset);
	fill_pattern(buffer, entry, data);
	// data
	for (int32 i = 0; i < fResourceCount; i++) {
		ResourceItem* item = ItemAt(i);
		status_t error = item->LoadData(fFile);
		if (error != B_OK)
			throw Exception(error, "Error loading resource data.");
		uint32 entrySize = item->GetSize();
		memcpy(data, item->GetData(), entrySize);
		data = skip_bytes(data, entrySize);
	}
	// info table
	data = skip_bytes(buffer, infoTableOffset);
	type = 0;
	for (int32 i = 0; i < fResourceCount; i++) {
		ResourceItem* item = ItemAt(i);
		resource_info* info = NULL;
		if (i == 0 || type != item->GetType()) {
			if (i != 0) {
				resource_info_separator* separator
					= (resource_info_separator*)data;
				separator->ris_value1 = 0xffffffff;
				separator->ris_value2 = 0xffffffff;
				data = skip_bytes(data, kResourceInfoSeparatorSize);
			}
			type = item->GetType();
			resource_info_block* infoBlock = (resource_info_block*)data;
			infoBlock->rib_type = type;
			info = infoBlock->rib_info;
		} else
			info = (resource_info*)data;
		// info
		info->ri_id = item->GetID();
		info->ri_index = i + 1;
		info->ri_name_size = 0;
		data = info->ri_name;
		uint32 nameLen = strlen(item->GetName());
		if (nameLen != 0) {
			memcpy(info->ri_name, item->GetName(), nameLen + 1);
			data = skip_bytes(data, nameLen + 1);
			info->ri_name_size = nameLen + 1;
		}
	}
	// separator
	resource_info_separator* separator = (resource_info_separator*)data;
	separator->ris_value1 = 0xffffffff;
	separator->ris_value2 = 0xffffffff;
	// table end
	data = skip_bytes(data, kResourceInfoSeparatorSize);
	resource_info_table_end* tableEnd = (resource_info_table_end*)data;
	void* infoTable = skip_bytes(buffer, infoTableOffset);
	tableEnd->rite_check_sum = calculate_checksum(infoTable,
		infoTableSize - kResourceInfoTableEndSize);
	tableEnd->rite_terminator = 0;
	// final check
	data = skip_bytes(data, kResourceInfoTableEndSize);
	uint32 bytesWritten = (char*)data - (char*)buffer;
	if (bytesWritten != size) {
		throw Exception("Bad boy error: Wrote %lu bytes, though supposed to "
						"write %lu bytes.", bytesWritten, size);
	}
	return size;
}