Exemple #1
0
bool
TBarWindow::_IsFocusMessage(BMessage* message)
{
	BMessage::Private messagePrivate(message);
	if (!messagePrivate.UsePreferredTarget())
		return false;

	bool feedFocus;
	if (message->HasInt32("_token")
		&& (message->FindBool("_feed_focus", &feedFocus) != B_OK || !feedFocus))
		return false;

	return true;
}
Exemple #2
0
status_t
MessageAdapter::_FlattenR5Message(uint32 format, const BMessage *from,
	char *buffer, ssize_t *size)
{
	BMessage::Private messagePrivate((BMessage *)from);
	BMessage::message_header *header = messagePrivate.GetMessageHeader();
	uint8 *data = messagePrivate.GetMessageData();

	r5_message_header *r5header = (r5_message_header *)buffer;
	uint8 *pointer = (uint8 *)buffer + sizeof(r5_message_header);

	r5header->magic = MESSAGE_FORMAT_R5;
	r5header->what = from->what;
	r5header->checksum = 0;

	uint8 flags = R5_MESSAGE_FLAG_VALID;
	if (header->target != B_NULL_TOKEN) {
		*(int32 *)pointer = header->target;
		pointer += sizeof(int32);
		flags |= R5_MESSAGE_FLAG_INCLUDE_TARGET;
	}

	if (header->reply_port >= 0 && header->reply_target != B_NULL_TOKEN
		&& header->reply_team >= 0) {
		// reply info
		*(port_id *)pointer = header->reply_port;
		pointer += sizeof(port_id);
		*(int32 *)pointer = header->reply_target;
		pointer += sizeof(int32);
		*(team_id *)pointer = header->reply_team;
		pointer += sizeof(team_id);

		// big flags
		*pointer = (header->reply_target == B_PREFERRED_TOKEN ? 1 : 0);
		pointer++;

		*pointer = (header->flags & MESSAGE_FLAG_REPLY_REQUIRED ? 1 : 0);
		pointer++;

		*pointer = (header->flags & MESSAGE_FLAG_REPLY_DONE ? 1 : 0);
		pointer++;

		*pointer = (header->flags & MESSAGE_FLAG_IS_REPLY ? 1 : 0);
		pointer++;

		flags |= R5_MESSAGE_FLAG_INCLUDE_REPLY;
	}

	if (header->flags & MESSAGE_FLAG_HAS_SPECIFIERS)
		flags |= R5_MESSAGE_FLAG_SCRIPT_MESSAGE;

	r5header->flags = flags;

	// store the header size - used for the checksum later
	ssize_t headerSize = (addr_t)pointer - (addr_t)buffer;

	// collect and add the data
	BMessage::field_header *field = messagePrivate.GetMessageFields();
	for (uint32 i = 0; i < header->field_count; i++, field++) {
		flags = R5_FIELD_FLAG_VALID;

		if (field->count == 1)
			flags |= R5_FIELD_FLAG_SINGLE_ITEM;
		// ToDo: we don't really know the data size now (padding missing)
		if (field->data_size <= 255 && field->count <= 255)
			;//flags |= R5_FIELD_FLAG_MINI_DATA;
		if (field->flags & FIELD_FLAG_FIXED_SIZE)
			flags |= R5_FIELD_FLAG_FIXED_SIZE;

		*pointer = flags;
		pointer++;

		*(type_code *)pointer = field->type;
		pointer += sizeof(type_code);

		if (!(flags & R5_FIELD_FLAG_SINGLE_ITEM)) {
			if (flags & R5_FIELD_FLAG_MINI_DATA) {
				*pointer = (uint8)field->count;
				pointer++;
			} else {
				*(int32 *)pointer = field->count;
				pointer += sizeof(int32);
			}
		}

		// we may have to adjust this to account for padding later
		uint8 *fieldSize = pointer;
		if (flags & R5_FIELD_FLAG_MINI_DATA) {
			*pointer = (uint8)field->data_size;
			pointer++;
		} else {
			*(ssize_t *)pointer = field->data_size;
			pointer += sizeof(ssize_t);
		}

		// name
		int32 nameLength = min_c(field->name_length - 1, 255);
		*pointer = (uint8)nameLength;
		pointer++;

		strncpy((char *)pointer, (char *)data + field->offset, nameLength);
		pointer += nameLength;

		// data
		uint8 *source = data + field->offset + field->name_length;
		if (flags & R5_FIELD_FLAG_FIXED_SIZE) {
			memcpy(pointer, source, field->data_size);
			pointer += field->data_size;
		} else {
			uint8 *previous = pointer;
			for (uint32 i = 0; i < field->count; i++) {
				ssize_t itemSize = *(ssize_t *)source + sizeof(ssize_t);
				memcpy(pointer, source, itemSize);
				ssize_t paddedSize = pad_to_8(itemSize);
				memset(pointer + itemSize, 0, paddedSize - itemSize);
				pointer += paddedSize;
				source += itemSize;
			}

			// adjust the field size to the padded value
			if (flags & R5_FIELD_FLAG_MINI_DATA)
				*fieldSize = (uint8)(pointer - previous);
			else
				*(ssize_t *)fieldSize = (pointer - previous);
		}
	}

	// terminate the fields with a pseudo field with flags 0 (not valid)
	*pointer = 0;
	pointer++;

	// calculate the flattened size from the pointers
	r5header->flattened_size = (addr_t)pointer - (addr_t)buffer;
	r5header->checksum = CalculateChecksum((uint8 *)(buffer + 8),
		headerSize - 8);

	if (size)
		*size = r5header->flattened_size;

	return B_OK;
}
Exemple #3
0
status_t
MessageAdapter::_UnflattenR5Message(uint32 format, BMessage *into,
	BDataIO *stream)
{
	into->MakeEmpty();

	BMessage::Private messagePrivate(into);
	BMessage::message_header *header = messagePrivate.GetMessageHeader();

	TReadHelper reader(stream);
	if (format == MESSAGE_FORMAT_R5_SWAPPED)
		reader.SetSwap(true);

	// the stream is already advanced by the size of the "format"
	r5_message_header r5header;
	reader(((uint8 *)&r5header) + sizeof(uint32),
		sizeof(r5header) - sizeof(uint32));

	header->what = into->what = r5header.what;
	if (r5header.flags & R5_MESSAGE_FLAG_INCLUDE_TARGET)
		reader(&header->target, sizeof(header->target));

	if (r5header.flags & R5_MESSAGE_FLAG_INCLUDE_REPLY) {
		// reply info
		reader(&header->reply_port, sizeof(header->reply_port));
		reader(&header->reply_target, sizeof(header->reply_target));
		reader(&header->reply_team, sizeof(header->reply_team));

		// big flags
		uint8 bigFlag;
		reader(bigFlag);
		if (bigFlag)
			header->reply_target = B_PREFERRED_TOKEN;

		reader(bigFlag);
		if (bigFlag)
			header->flags |= MESSAGE_FLAG_REPLY_REQUIRED;

		reader(bigFlag);
		if (bigFlag)
			header->flags |= MESSAGE_FLAG_REPLY_DONE;

		reader(bigFlag);
		if (bigFlag)
			header->flags |= MESSAGE_FLAG_IS_REPLY;
	}

	if (r5header.flags & R5_MESSAGE_FLAG_SCRIPT_MESSAGE)
		header->flags |= MESSAGE_FLAG_HAS_SPECIFIERS;

	uint8 flags;
	reader(flags);
	while (flags & R5_FIELD_FLAG_VALID) {
		bool fixedSize = flags & R5_FIELD_FLAG_FIXED_SIZE;
		bool miniData = flags & R5_FIELD_FLAG_MINI_DATA;
		bool singleItem = flags & R5_FIELD_FLAG_SINGLE_ITEM;

		type_code type;
		reader(type);

		int32 itemCount;
		if (!singleItem) {
			if (miniData) {
				uint8 miniCount;
				reader(miniCount);
				itemCount = miniCount;
			} else
				reader(itemCount);
		} else
			itemCount = 1;

		ssize_t dataSize;
		if (miniData) {
			uint8 miniSize;
			reader(miniSize);
			dataSize = miniSize;
		} else
			reader(dataSize);

		if (dataSize <= 0)
			return B_ERROR;

		// name
		uint8 nameLength;
		reader(nameLength);

		char nameBuffer[256];
		reader(nameBuffer, nameLength);
		nameBuffer[nameLength] = '\0';

		uint8 *buffer = (uint8 *)malloc(dataSize);
		uint8 *pointer = buffer;
		reader(buffer, dataSize);

		status_t result = B_OK;
		ssize_t itemSize = 0;
		if (fixedSize)
			itemSize = dataSize / itemCount;

		if (format == MESSAGE_FORMAT_R5) {
			for (int32 i = 0; i < itemCount; i++) {
				if (!fixedSize) {
					itemSize = *(ssize_t *)pointer;
					pointer += sizeof(ssize_t);
				}

				result = into->AddData(nameBuffer, type, pointer, itemSize,
					fixedSize, itemCount);

				if (result < B_OK) {
					free(buffer);
					return result;
				}

				if (fixedSize)
					pointer += itemSize;
				else
					pointer += pad_to_8(itemSize + sizeof(ssize_t)) - sizeof(ssize_t);
			}
		} else {
			for (int32 i = 0; i < itemCount; i++) {
				if (!fixedSize) {
					itemSize = __swap_int32(*(ssize_t *)pointer);
					pointer += sizeof(ssize_t);
				}

				swap_data(type, pointer, itemSize, B_SWAP_ALWAYS);
				result = into->AddData(nameBuffer, type, pointer, itemSize,
					fixedSize, itemCount);

				if (result < B_OK) {
					free(buffer);
					return result;
				}

				if (fixedSize)
					pointer += itemSize;
				else
					pointer += pad_to_8(itemSize + sizeof(ssize_t)) - sizeof(ssize_t);
			}
		}

		free(buffer);

		// flags of next field or termination byte
		reader(flags);
	}

	return B_OK;
}
Exemple #4
0
ssize_t
MessageAdapter::_R5FlattenedSize(const BMessage *from)
{
	BMessage::Private messagePrivate((BMessage *)from);
	BMessage::message_header* header = messagePrivate.GetMessageHeader();

	// header size (variable, depending on the flags)

	ssize_t flattenedSize = sizeof(r5_message_header);

	if (header->target != B_NULL_TOKEN)
		flattenedSize += sizeof(int32);

	if (header->reply_port >= 0 && header->reply_target != B_NULL_TOKEN
		&& header->reply_team >= 0) {
		// reply info + big flags
		flattenedSize += sizeof(port_id) + sizeof(int32) + sizeof(team_id) + 4;
	}

	// field size

	uint8 *data = messagePrivate.GetMessageData();
	BMessage::field_header *field = messagePrivate.GetMessageFields();
	for (uint32 i = 0; i < header->field_count; i++, field++) {
		// flags and type
		flattenedSize += 1 + sizeof(type_code);

#if 0
		bool miniData = field->dataSize <= 255 && field->count <= 255;
#else
		// ToDo: we don't know the R5 dataSize yet (padding)
		bool miniData = false;
#endif

		// item count
		if (field->count > 1)
			flattenedSize += (miniData ? sizeof(uint8) : sizeof(uint32));

		// data size
		flattenedSize += (miniData ? sizeof(uint8) : sizeof(size_t));

		// name length and name
		flattenedSize += 1 + min_c(field->name_length - 1, 255);

		// data
		if (field->flags & FIELD_FLAG_FIXED_SIZE)
			flattenedSize += field->data_size;
		else {
			uint8 *source = data + field->offset + field->name_length;

			for (uint32 i = 0; i < field->count; i++) {
				ssize_t itemSize = *(ssize_t *)source + sizeof(ssize_t);
				flattenedSize += pad_to_8(itemSize);
				source += itemSize;
			}
		}
	}

	// pseudo field with flags 0
	return flattenedSize + 1;
}