*Very* basic read-only Dano/Zeta message support. Only briefly tested.
Not really suited for message sending/retrieval (because target stuff is missing), but should work more or less with disk based messages. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@13428 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
1ae414f3c6
commit
dc9e836b35
@ -1,43 +1,26 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// Copyright (c) 2001-2005, OpenBeOS
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
// File Name: Message.h
|
||||
// Author(s): Erik Jaesler (erik@cgsoftware.com)
|
||||
// DarkWyrm <bpmagic@columbus.rr.com>
|
||||
// Ingo Weinhold <bonefish@users.sf.net>
|
||||
// Description: BMessage class creates objects that store data and that
|
||||
// can be processed in a message loop. BMessage objects
|
||||
// are also used as data containers by the archiving and
|
||||
// the scripting mechanisms.
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
* Copyright 2001-2005, Haiku.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Erik Jaesler (erik@cgsoftware.com)
|
||||
* DarkWyrm <bpmagic@columbus.rr.com>
|
||||
* Ingo Weinhold <bonefish@users.sf.net>
|
||||
*/
|
||||
|
||||
/** BMessage class creates objects that store data and that
|
||||
* can be processed in a message loop. BMessage objects
|
||||
* are also used as data containers by the archiving and
|
||||
* the scripting mechanisms.
|
||||
*/
|
||||
|
||||
// debugging
|
||||
//#define DBG(x) x
|
||||
#define DBG(x) ;
|
||||
#define PRINT(x) DBG({ printf("[%6ld] ", find_thread(NULL)); printf x; })
|
||||
|
||||
// Standard Includes -----------------------------------------------------------
|
||||
#include <stdio.h>
|
||||
|
||||
// System Includes -------------------------------------------------------------
|
||||
#include <Application.h>
|
||||
#include <BlockCache.h>
|
||||
#include <ByteOrder.h>
|
||||
@ -47,9 +30,6 @@
|
||||
#include <MessengerPrivate.h>
|
||||
#include <String.h>
|
||||
|
||||
//#include <CRTDBG.H>
|
||||
|
||||
// Project Includes ------------------------------------------------------------
|
||||
#include <AppMisc.h>
|
||||
#include <DataBuffer.h>
|
||||
#include <KMessage.h>
|
||||
@ -57,10 +37,14 @@
|
||||
#include <MessageUtils.h>
|
||||
#include <TokenSpace.h>
|
||||
|
||||
// Local Includes --------------------------------------------------------------
|
||||
#include "dano_message.h"
|
||||
|
||||
// Local Defines ---------------------------------------------------------------
|
||||
#define MSG_FIELD_VERSION 'FOB1'
|
||||
|
||||
static const uint32 kMessageMagic = 'FOB1';
|
||||
static const uint32 kMessageMagicSwapped = '1BOF';
|
||||
|
||||
static const uint32 kMessageMagicDano = 'FOB2';
|
||||
static const uint32 kMessageMagicDanoSwapped = '2BOF';
|
||||
|
||||
// flags for the overall message (the bitfield is 1 byte)
|
||||
#define MSG_FLAG_BIG_ENDIAN 0x01
|
||||
@ -111,6 +95,8 @@ public:
|
||||
Header() {}
|
||||
Header(const BMessage &message) { ReadFrom(message); }
|
||||
|
||||
status_t SetMagic(uint32 magic);
|
||||
|
||||
status_t ReadFrom(BDataIO &stream);
|
||||
void ReadFrom(const BMessage &message);
|
||||
status_t WriteTo(BDataIO &stream, bool calculateCheckSum = true) const;
|
||||
@ -127,7 +113,7 @@ public:
|
||||
void Dump() const;
|
||||
|
||||
private:
|
||||
int32 fMagic;
|
||||
uint32 fMagic;
|
||||
int32 fBodySize;
|
||||
uint32 fWhat;
|
||||
uint8 fFlags;
|
||||
@ -142,6 +128,24 @@ private:
|
||||
bool fSwapped;
|
||||
};
|
||||
|
||||
|
||||
status_t
|
||||
BMessage::Header::SetMagic(uint32 magic)
|
||||
{
|
||||
if (magic == kMessageMagicSwapped) {
|
||||
fSwapped = true;
|
||||
} else if (magic == kMessageMagic) {
|
||||
fSwapped = false;
|
||||
} else {
|
||||
// This is *not* a message
|
||||
return B_NOT_A_MESSAGE;
|
||||
}
|
||||
|
||||
fMagic = magic;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
// ReadFrom
|
||||
status_t
|
||||
BMessage::Header::ReadFrom(BDataIO &stream)
|
||||
@ -154,19 +158,6 @@ BMessage::Header::ReadFrom(BDataIO &stream)
|
||||
int32 flattenedSize;
|
||||
|
||||
try {
|
||||
// Get the message version
|
||||
read_helper(fMagic);
|
||||
|
||||
fSwapped = false;
|
||||
if (fMagic == '1BOF') {
|
||||
fSwapped = true;
|
||||
} else if (fMagic == 'FOB1') {
|
||||
fSwapped = false;
|
||||
} else {
|
||||
// This is *not* a message
|
||||
return B_NOT_A_MESSAGE;
|
||||
}
|
||||
|
||||
read_helper.SetSwap(fSwapped);
|
||||
|
||||
// get the checksum
|
||||
@ -237,7 +228,7 @@ BMessage::Header::ReadFrom(BDataIO &stream)
|
||||
void
|
||||
BMessage::Header::ReadFrom(const BMessage &message)
|
||||
{
|
||||
fMagic = MSG_FIELD_VERSION;
|
||||
fMagic = kMessageMagic;
|
||||
|
||||
fBodySize = message.fBody->FlattenedSize();
|
||||
fWhat = message.what;
|
||||
@ -909,172 +900,192 @@ status_t BMessage::Flatten(BDataIO* stream, ssize_t* size) const
|
||||
|
||||
return err;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
status_t BMessage::Unflatten(const char* flat_buffer)
|
||||
|
||||
|
||||
status_t
|
||||
BMessage::Unflatten(const char* buffer)
|
||||
{
|
||||
if (!flat_buffer)
|
||||
if (!buffer)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
// check whether this is a KMessage
|
||||
if (((KMessage::Header*)flat_buffer)->magic
|
||||
== KMessage::kMessageHeaderMagic) {
|
||||
return _UnflattenKMessage(flat_buffer);
|
||||
uint32 magic = *(uint32*)buffer;
|
||||
|
||||
// we support several message formats - this list is ordered
|
||||
// by importance and frequency
|
||||
|
||||
if (magic == kMessageMagic) {
|
||||
// it appears to be a normal flattened BMessage
|
||||
BMemoryIO memoryStream(buffer, ((uint32*)buffer)[2]);
|
||||
return Unflatten(&memoryStream);
|
||||
}
|
||||
|
||||
// assume it's a normal flattened BMessage
|
||||
uint32 size = ((uint32*)flat_buffer)[2];
|
||||
// check whether this is a KMessage
|
||||
if (((KMessage::Header*)buffer)->magic
|
||||
== KMessage::kMessageHeaderMagic)
|
||||
return _UnflattenKMessage(buffer);
|
||||
|
||||
BMemoryIO MemIO(flat_buffer, size);
|
||||
return Unflatten(&MemIO);
|
||||
if (magic == kMessageMagicSwapped) {
|
||||
// it appears to be a swapped flattened BMessage
|
||||
uint32 size = ((uint32*)buffer)[2];
|
||||
|
||||
BMemoryIO memoryStream(buffer, __swap_int32(size));
|
||||
return Unflatten(&memoryStream);
|
||||
}
|
||||
|
||||
if (magic == kMessageMagicDano || magic == kMessageMagicDanoSwapped) {
|
||||
// dano style message
|
||||
BMemoryIO memoryStream(buffer, BPrivate::dano_message_size(buffer));
|
||||
return Unflatten(&memoryStream);
|
||||
}
|
||||
|
||||
return B_NOT_A_MESSAGE;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
status_t BMessage::Unflatten(BDataIO* stream)
|
||||
|
||||
|
||||
status_t
|
||||
BMessage::Unflatten(BDataIO* stream)
|
||||
{
|
||||
TReadHelper reader(stream);
|
||||
Header header;
|
||||
status_t err = header.ReadFrom(*stream);
|
||||
status_t status = B_OK;
|
||||
|
||||
if (err) {
|
||||
printf("BMessage::Unflatten(): Reading the header failed: %lx\n", err);
|
||||
}
|
||||
// ToDo: while reading from a stream is certainly more convenient than
|
||||
// from a buffer, it causes a lot of unnecessary copies, and therefore
|
||||
// probably shouldn't be the preferred (or only) route.
|
||||
|
||||
try {
|
||||
uint32 magic;
|
||||
reader(magic);
|
||||
|
||||
status = header.SetMagic(magic);
|
||||
if (status < B_OK) {
|
||||
// we support reading Dano messages from disk as well
|
||||
if (magic == kMessageMagicDano)
|
||||
return BPrivate::unflatten_dano_message(magic, *stream, *this);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
status = header.ReadFrom(*stream);
|
||||
if (status < B_OK) {
|
||||
printf("BMessage::Unflatten(): Reading the header failed: %lx\n", status);
|
||||
return status;
|
||||
}
|
||||
|
||||
if (!err)
|
||||
{
|
||||
header.WriteTo(*this);
|
||||
bool swap = header.IsSwapped();
|
||||
|
||||
TReadHelper reader(stream, swap);
|
||||
int8 flags;
|
||||
type_code type;
|
||||
uint32 count;
|
||||
uint32 dataLen;
|
||||
uint8 nameLen;
|
||||
char name[MSG_NAME_MAX_SIZE];
|
||||
unsigned char* databuffer = NULL;
|
||||
|
||||
try
|
||||
{
|
||||
reader(flags);
|
||||
while (flags != MSG_LAST_ENTRY)
|
||||
{
|
||||
reader(type);
|
||||
// Is there more than one data item? (!flags & MSG_FLAG_SINGLE_ITEM)
|
||||
if (flags & MSG_FLAG_SINGLE_ITEM)
|
||||
{
|
||||
count = 1;
|
||||
if (flags & MSG_FLAG_MINI_DATA)
|
||||
{
|
||||
uint8 littleLen;
|
||||
reader(littleLen);
|
||||
dataLen = littleLen;
|
||||
}
|
||||
else
|
||||
{
|
||||
reader(dataLen);
|
||||
}
|
||||
int8 flags;
|
||||
reader(flags);
|
||||
|
||||
while (flags != MSG_LAST_ENTRY) {
|
||||
type_code type;
|
||||
reader(type);
|
||||
|
||||
// Is there more than one data item?
|
||||
if (flags & MSG_FLAG_SINGLE_ITEM) {
|
||||
count = 1;
|
||||
if (flags & MSG_FLAG_MINI_DATA) {
|
||||
uint8 littleLen;
|
||||
reader(littleLen);
|
||||
dataLen = littleLen;
|
||||
} else
|
||||
reader(dataLen);
|
||||
} else {
|
||||
// Is there a little data?
|
||||
if (flags & MSG_FLAG_MINI_DATA) {
|
||||
// Get item count (1 byte)
|
||||
uint8 littleCount;
|
||||
reader(littleCount);
|
||||
count = littleCount;
|
||||
|
||||
// Get data length (1 byte)
|
||||
uint8 littleLen;
|
||||
reader(littleLen);
|
||||
dataLen = littleLen;
|
||||
} else {
|
||||
// Is there a lot of data?
|
||||
// Get item count (4 bytes)
|
||||
reader(count);
|
||||
// Get data length (4 bytes)
|
||||
reader(dataLen);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Is there a little data? (flags & MSG_FLAG_MINI_DATA)
|
||||
if (flags & MSG_FLAG_MINI_DATA)
|
||||
{
|
||||
// Get item count (1 byte)
|
||||
uint8 littleCount;
|
||||
reader(littleCount);
|
||||
count = littleCount;
|
||||
}
|
||||
|
||||
// Get data length (1 byte)
|
||||
uint8 littleLen;
|
||||
reader(littleLen);
|
||||
dataLen = littleLen;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Is there a lot of data? (!flags & MSG_FLAG_MINI_DATA)
|
||||
// Get item count (4 bytes)
|
||||
reader(count);
|
||||
// Get data length (4 bytes)
|
||||
reader(dataLen);
|
||||
}
|
||||
}
|
||||
// Get the name length (1 byte)
|
||||
reader(nameLen);
|
||||
// Get the name (name length bytes)
|
||||
reader(name, nameLen);
|
||||
name[nameLen] = '\0';
|
||||
|
||||
// Get the name length (1 byte)
|
||||
reader(nameLen);
|
||||
// Get the name (name length bytes)
|
||||
reader(name, nameLen);
|
||||
name[nameLen] = '\0';
|
||||
// Copy the data into a new buffer to byte align it
|
||||
databuffer = (unsigned char*)realloc(databuffer, dataLen);
|
||||
if (!databuffer)
|
||||
throw B_NO_MEMORY;
|
||||
// Get the data
|
||||
reader(databuffer, dataLen);
|
||||
|
||||
// Copy the data into a new buffer to byte align it
|
||||
databuffer = (unsigned char*)realloc(databuffer, dataLen);
|
||||
if (!databuffer)
|
||||
throw B_NO_MEMORY;
|
||||
// Get the data
|
||||
reader(databuffer, dataLen);
|
||||
|
||||
// Is the data fixed size? (flags & MSG_FLAG_FIXED_SIZE)
|
||||
if (flags & MSG_FLAG_FIXED_SIZE && swap)
|
||||
{
|
||||
if (swap) {
|
||||
// Is the data fixed size?
|
||||
if ((flags & MSG_FLAG_FIXED_SIZE) != 0) {
|
||||
// Make sure to swap the data
|
||||
err = swap_data(type, (void*)databuffer, dataLen,
|
||||
status = swap_data(type, (void*)databuffer, dataLen,
|
||||
B_SWAP_ALWAYS);
|
||||
if (err)
|
||||
throw err;
|
||||
}
|
||||
// Is the data variable size? (!flags & MSG_FLAG_FIXED_SIZE)
|
||||
else if (swap && type == B_REF_TYPE)
|
||||
{
|
||||
if (status < B_OK)
|
||||
throw status;
|
||||
} else if (type == B_REF_TYPE) {
|
||||
// Is the data variable size?
|
||||
// Apparently, entry_refs are the only variable-length data
|
||||
// explicitely swapped -- the dev_t and ino_t
|
||||
// specifically
|
||||
byte_swap(*(entry_ref*)databuffer);
|
||||
}
|
||||
|
||||
// Add each data field to the message
|
||||
uint32 itemSize = 0;
|
||||
if (flags & MSG_FLAG_FIXED_SIZE)
|
||||
{
|
||||
itemSize = dataLen / count;
|
||||
}
|
||||
unsigned char* dataPtr = databuffer;
|
||||
for (uint32 i = 0; i < count; ++i)
|
||||
{
|
||||
// Line up for the next item
|
||||
if (i)
|
||||
{
|
||||
if (flags & MSG_FLAG_FIXED_SIZE)
|
||||
{
|
||||
dataPtr += itemSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Have to account for 8-byte boundary padding
|
||||
// We add 4 because padding as calculated during
|
||||
// flattening includes the four-byte size header
|
||||
dataPtr += itemSize + calc_padding(itemSize + 4, 8);
|
||||
}
|
||||
}
|
||||
|
||||
if ((flags & MSG_FLAG_FIXED_SIZE) == 0)
|
||||
{
|
||||
itemSize = *(uint32*)dataPtr;
|
||||
dataPtr += sizeof (uint32);
|
||||
}
|
||||
|
||||
err = AddData(name, type, dataPtr, itemSize,
|
||||
flags & MSG_FLAG_FIXED_SIZE);
|
||||
if (err)
|
||||
throw err;
|
||||
}
|
||||
|
||||
reader(flags);
|
||||
}
|
||||
|
||||
// Add each data field to the message
|
||||
uint32 itemSize = 0;
|
||||
if (flags & MSG_FLAG_FIXED_SIZE)
|
||||
itemSize = dataLen / count;
|
||||
|
||||
unsigned char* dataPtr = databuffer;
|
||||
|
||||
for (uint32 i = 0; i < count; ++i) {
|
||||
// Line up for the next item
|
||||
if (i) {
|
||||
if (flags & MSG_FLAG_FIXED_SIZE) {
|
||||
dataPtr += itemSize;
|
||||
} else {
|
||||
// Have to account for 8-byte boundary padding
|
||||
// We add 4 because padding as calculated during
|
||||
// flattening includes the four-byte size header
|
||||
dataPtr += itemSize + calc_padding(itemSize + 4, 8);
|
||||
}
|
||||
}
|
||||
|
||||
if ((flags & MSG_FLAG_FIXED_SIZE) == 0) {
|
||||
itemSize = *(uint32*)dataPtr;
|
||||
dataPtr += sizeof (uint32);
|
||||
}
|
||||
|
||||
status = AddData(name, type, dataPtr, itemSize,
|
||||
flags & MSG_FLAG_FIXED_SIZE);
|
||||
if (status < B_OK)
|
||||
throw status;
|
||||
}
|
||||
|
||||
reader(flags);
|
||||
}
|
||||
catch (status_t& e)
|
||||
{
|
||||
err = e;
|
||||
}
|
||||
} catch (status_t& e) {
|
||||
status = e;
|
||||
}
|
||||
|
||||
return err;
|
||||
return status;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
status_t BMessage::AddSpecifier(const char* property)
|
||||
@ -2024,7 +2035,8 @@ BMessage::_SendFlattenedMessage(void *data, int32 size, port_id port,
|
||||
// a KMessage
|
||||
KMessage::Header *header = (KMessage::Header*)data;
|
||||
header->targetToken = (preferred ? B_PREFERRED_TOKEN : token);
|
||||
} else if (*(int32*)data == '1BOF' || *(int32*)data == 'FOB1') {
|
||||
} else if (*(uint32*)data == kMessageMagic
|
||||
|| *(uint32*)data == kMessageMagicSwapped) {
|
||||
// get the header
|
||||
BMemoryIO stream(data, size);
|
||||
Header header;
|
||||
|
@ -7,6 +7,7 @@ APP_KIT_SOURCE =
|
||||
Cursor.cpp
|
||||
DataBuffer.cpp
|
||||
Clipboard.cpp
|
||||
dano_message.cpp
|
||||
Handler.cpp
|
||||
InitTerminateLibBe.cpp
|
||||
Invoker.cpp
|
||||
|
122
src/kits/app/dano_message.cpp
Normal file
122
src/kits/app/dano_message.cpp
Normal file
@ -0,0 +1,122 @@
|
||||
/*
|
||||
* Copyright 2005, Haiku.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Axel Dörfler
|
||||
*/
|
||||
|
||||
|
||||
#include "dano_message.h"
|
||||
|
||||
#include <MessageUtils.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
struct dano_header {
|
||||
uint32 code;
|
||||
int32 size;
|
||||
uint32 what;
|
||||
uint32 _unknown;
|
||||
};
|
||||
|
||||
struct dano_field_header {
|
||||
uint32 code;
|
||||
int32 size;
|
||||
};
|
||||
|
||||
struct dano_field {
|
||||
uint32 type;
|
||||
int32 data_size;
|
||||
uint8 name_size;
|
||||
char name[0];
|
||||
} _PACKED;
|
||||
|
||||
static const uint32 kMessageFormat = 'FOB2';
|
||||
static const uint32 kMessageFormatSwapped = '2BOF';
|
||||
|
||||
static const uint32 kDataField = 'SGDa';
|
||||
|
||||
|
||||
size_t
|
||||
BPrivate::dano_message_size(const char* buffer)
|
||||
{
|
||||
dano_header* header = (dano_header*)buffer;
|
||||
|
||||
if (header->code == kMessageFormatSwapped)
|
||||
return __swap_int32(header->size);
|
||||
|
||||
return header->size;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BPrivate::unflatten_dano_message(uint32 magic, BDataIO& stream, BMessage& message)
|
||||
{
|
||||
TReadHelper reader(&stream);
|
||||
message.MakeEmpty();
|
||||
|
||||
if (magic == kMessageFormatSwapped)
|
||||
reader.SetSwap(true);
|
||||
|
||||
int32 size;
|
||||
reader(size);
|
||||
reader(message.what);
|
||||
|
||||
int32 value;
|
||||
reader(value); // unknown
|
||||
|
||||
size -= sizeof(dano_header);
|
||||
int32 offset = 0;
|
||||
|
||||
while (offset < size) {
|
||||
dano_field_header fieldHeader;
|
||||
reader(fieldHeader);
|
||||
printf("field.code = %.4s (%lx), field.size = %ld\n",
|
||||
(char*)&fieldHeader.code, fieldHeader.code, fieldHeader.size);
|
||||
|
||||
if (fieldHeader.size + offset > size)
|
||||
return B_BAD_DATA;
|
||||
|
||||
uint32 fieldSize = fieldHeader.size - sizeof(dano_field_header);
|
||||
char* fieldBuffer = (char*)malloc(fieldSize);
|
||||
if (fieldBuffer == NULL)
|
||||
throw (status_t)B_NO_MEMORY;
|
||||
|
||||
reader(fieldBuffer, fieldSize);
|
||||
|
||||
if (fieldHeader.code == kDataField) {
|
||||
dano_field* field = (dano_field*)fieldBuffer;
|
||||
|
||||
int32 dataOffset = sizeof(dano_field) + field->name_size + 1;
|
||||
dataOffset = (dataOffset + 7) & ~7;
|
||||
// padding
|
||||
|
||||
if (field->data_size + dataOffset + offset > size)
|
||||
return B_BAD_DATA;
|
||||
|
||||
// ToDo: support fixed size for real
|
||||
bool fixedSize = true;
|
||||
if (field->type == B_STRING_TYPE)
|
||||
fixedSize = false;
|
||||
|
||||
status_t status = message.AddData(field->name, field->type,
|
||||
fieldBuffer + dataOffset, field->data_size, fixedSize);
|
||||
|
||||
if (status < B_OK) {
|
||||
free(fieldBuffer);
|
||||
throw status;
|
||||
}
|
||||
}
|
||||
|
||||
free(fieldBuffer);
|
||||
offset += fieldHeader.size;
|
||||
printf("offset = %ld, size = %ld\n", offset, size);
|
||||
}
|
||||
message.PrintToStream();
|
||||
return B_OK;
|
||||
}
|
||||
|
11
src/kits/app/dano_message.h
Normal file
11
src/kits/app/dano_message.h
Normal file
@ -0,0 +1,11 @@
|
||||
|
||||
#include <SupportDefs.h>
|
||||
|
||||
class BMessage;
|
||||
class BDataIO;
|
||||
|
||||
namespace BPrivate {
|
||||
status_t unflatten_dano_message(uint32 magic, BDataIO& stream, BMessage& message);
|
||||
size_t dano_message_size(const char* buffer);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user