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; }
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; }
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; }
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; }