This is all the code for the backing store for BMessage (BMessageBody &
BMessageField) for the "template madness" version. Also included is BDataBuffer which is a little reference counting raw data container. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@2955 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -0,0 +1,237 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Copyright (c) 2001-2002, 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: MessageBody.h
|
||||||
|
// Author(s): Erik Jaesler ([email protected])
|
||||||
|
// Description: BMessageBody handles data storage and retrieval for
|
||||||
|
// BMessage.
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#ifndef MESSAGEBODY_H
|
||||||
|
#define MESSAGEBODY_H
|
||||||
|
#include <MessageField.h>
|
||||||
|
// Standard Includes -----------------------------------------------------------
|
||||||
|
#include <map>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
// System Includes -------------------------------------------------------------
|
||||||
|
#include <Entry.h>
|
||||||
|
#include <Path.h>
|
||||||
|
#include <Point.h>
|
||||||
|
#include <Rect.h>
|
||||||
|
//#include <StreamIO.h>
|
||||||
|
#include <String.h>
|
||||||
|
#include <SupportDefs.h>
|
||||||
|
|
||||||
|
// Project Includes ------------------------------------------------------------
|
||||||
|
|
||||||
|
// Local Includes --------------------------------------------------------------
|
||||||
|
|
||||||
|
// Local Defines ---------------------------------------------------------------
|
||||||
|
|
||||||
|
// Globals ---------------------------------------------------------------------
|
||||||
|
|
||||||
|
enum { B_FLATTENABLE_TYPE = 'FLAT' };
|
||||||
|
|
||||||
|
namespace BPrivate {
|
||||||
|
|
||||||
|
class BMessageBody
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
BMessageBody();
|
||||||
|
BMessageBody(const BMessageBody& rhs);
|
||||||
|
~BMessageBody();
|
||||||
|
|
||||||
|
BMessageBody& operator=(const BMessageBody& rhs);
|
||||||
|
|
||||||
|
// Statistics and misc info
|
||||||
|
status_t GetInfo(type_code typeRequested, int32 which, char **name,
|
||||||
|
type_code *typeReturned, int32 *count = NULL) const;
|
||||||
|
|
||||||
|
status_t GetInfo(const char *name, type_code *type, int32 *c = 0) const;
|
||||||
|
status_t GetInfo(const char *name, type_code *type, bool *fixed_size) const;
|
||||||
|
|
||||||
|
int32 CountNames(type_code type) const;
|
||||||
|
bool IsEmpty() const;
|
||||||
|
bool IsSystem() const;
|
||||||
|
bool IsReply() const;
|
||||||
|
void PrintToStream() const;
|
||||||
|
|
||||||
|
status_t Rename(const char *old_entry, const char *new_entry);
|
||||||
|
|
||||||
|
// Flattening data
|
||||||
|
ssize_t FlattenedSize() const;
|
||||||
|
status_t Flatten(BDataIO *stream) const;
|
||||||
|
status_t Unflatten(const char *flat_buffer);
|
||||||
|
status_t Unflatten(BDataIO *stream);
|
||||||
|
|
||||||
|
// Removing data
|
||||||
|
status_t RemoveData(const char *name, int32 index = 0);
|
||||||
|
status_t RemoveName(const char *name);
|
||||||
|
status_t MakeEmpty();
|
||||||
|
|
||||||
|
bool HasData(const char* name, type_code t, int32 n) const;
|
||||||
|
|
||||||
|
template<class T1>
|
||||||
|
status_t AddData(const char* name, const T1& data, type_code type);
|
||||||
|
status_t FindData(const char* name, type_code type, int32 index,
|
||||||
|
const void** data, ssize_t* numBytes) const;
|
||||||
|
template<class T1>
|
||||||
|
status_t FindData(const char* name, int32 index, T1* data, type_code type);
|
||||||
|
template<class T1>
|
||||||
|
status_t ReplaceData(const char* name, int32 index, const T1& data, type_code type);
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
void *operator new(size_t size);
|
||||||
|
void operator delete(void *ptr, size_t size);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
private:
|
||||||
|
BMessageField* FindData(const char *name, type_code type,
|
||||||
|
status_t& err) const;
|
||||||
|
|
||||||
|
typedef std::map<std::string, BMessageField*> TMsgDataMap;
|
||||||
|
TMsgDataMap fData;
|
||||||
|
ssize_t fFlattenedSize;
|
||||||
|
};
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
template<class T1>
|
||||||
|
status_t BMessageBody::AddData(const char *name, const T1 &data, type_code type)
|
||||||
|
{
|
||||||
|
// The flattened message format in R5 only allows 1 byte
|
||||||
|
// for the length of field names
|
||||||
|
if (strlen(name) > 255) return B_BAD_VALUE;
|
||||||
|
|
||||||
|
status_t err = B_OK;
|
||||||
|
BMessageField* BMF = FindData(name, type, err);
|
||||||
|
|
||||||
|
// Reset err; we just want the variable
|
||||||
|
err = B_OK;
|
||||||
|
|
||||||
|
if (!BMF)
|
||||||
|
{
|
||||||
|
BMF = new(nothrow) BMessageFieldImpl<T1>(name, type);
|
||||||
|
if (BMF)
|
||||||
|
{
|
||||||
|
fData[name] = BMF;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
err = B_NO_MEMORY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!err)
|
||||||
|
{
|
||||||
|
BMessageFieldImpl<T1>* RItem =
|
||||||
|
dynamic_cast<BMessageFieldImpl<T1>*>(BMF);
|
||||||
|
if (!RItem)
|
||||||
|
{
|
||||||
|
debugger("\n\n\tyou \033[44;1;37mB\033[41;1;37me\033[m screwed\n\n");
|
||||||
|
}
|
||||||
|
RItem->AddItem(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
template<class T1>
|
||||||
|
status_t BMessageBody::FindData(const char *name, int32 index, T1 *data,
|
||||||
|
type_code type)
|
||||||
|
{
|
||||||
|
status_t err = B_OK;
|
||||||
|
if (index < 0)
|
||||||
|
{
|
||||||
|
err = B_BAD_INDEX;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
BMessageField* Item = FindData(name, type, err);
|
||||||
|
if (Item)
|
||||||
|
{
|
||||||
|
BMessageFieldImpl<T1>* RItem =
|
||||||
|
dynamic_cast<BMessageFieldImpl<T1>*>(Item);
|
||||||
|
if (!RItem)
|
||||||
|
{
|
||||||
|
debugger("\n\n\tyou \033[44;1;37mB\033[41;1;37me"
|
||||||
|
"\033[m screwed\n\n");
|
||||||
|
}
|
||||||
|
if (index < RItem->CountItems())
|
||||||
|
{
|
||||||
|
*data = RItem->Data()[index];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
err = B_BAD_INDEX;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
template<class T1>
|
||||||
|
status_t BMessageBody::ReplaceData(const char *name, int32 index,
|
||||||
|
const T1 &data, type_code type)
|
||||||
|
{
|
||||||
|
status_t err = B_OK;
|
||||||
|
if (index < 0)
|
||||||
|
{
|
||||||
|
err = B_BAD_INDEX;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
BMessageField* Item = FindData(name, type, err);
|
||||||
|
if (Item)
|
||||||
|
{
|
||||||
|
BMessageFieldImpl<T1>* RItem =
|
||||||
|
dynamic_cast<BMessageFieldImpl<T1>*>(Item);
|
||||||
|
if (!RItem)
|
||||||
|
{
|
||||||
|
debugger("\n\n\tyou \033[44;1;37mB\033[41;1;37me\033[m screwed\n\n");
|
||||||
|
}
|
||||||
|
if (index < RItem->Data().Size())
|
||||||
|
{
|
||||||
|
RItem->Data()[index] = data;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
err = B_BAD_INDEX;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
} // namespace BPrivate
|
||||||
|
|
||||||
|
#endif //MESSAGEBODY_H
|
||||||
|
|
||||||
|
/*
|
||||||
|
* $Log $
|
||||||
|
*
|
||||||
|
* $Id $
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
@@ -0,0 +1,584 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Copyright (c) 2001-2002, 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: MessageField.h
|
||||||
|
// Author(s): Erik Jaesler ([email protected])
|
||||||
|
// Description: BMessageField contains and manages the data for indiviual
|
||||||
|
// named field in BMessageBody
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#ifndef MESSAGEFIELD_H
|
||||||
|
#define MESSAGEFIELD_H
|
||||||
|
|
||||||
|
// Standard Includes -----------------------------------------------------------
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
// System Includes -------------------------------------------------------------
|
||||||
|
#include <Entry.h>
|
||||||
|
#include <Path.h>
|
||||||
|
#include <Point.h>
|
||||||
|
#include <Rect.h>
|
||||||
|
#include <String.h>
|
||||||
|
#include <SupportDefs.h>
|
||||||
|
|
||||||
|
// Project Includes ------------------------------------------------------------
|
||||||
|
#include <DataBuffer.h>
|
||||||
|
|
||||||
|
// Local Includes --------------------------------------------------------------
|
||||||
|
|
||||||
|
// Local Defines ---------------------------------------------------------------
|
||||||
|
// flags for each entry (the bitfield is 1 byte)
|
||||||
|
#define MSG_FLAG_VALID 0x01
|
||||||
|
#define MSG_FLAG_MINI_DATA 0x02
|
||||||
|
#define MSG_FLAG_FIXED_SIZE 0x04
|
||||||
|
#define MSG_FLAG_SINGLE_ITEM 0x08
|
||||||
|
#define MSG_FLAG_ALL 0x0F
|
||||||
|
|
||||||
|
#define MSG_LAST_ENTRY 0x0
|
||||||
|
|
||||||
|
// Globals ---------------------------------------------------------------------
|
||||||
|
namespace BPrivate {
|
||||||
|
|
||||||
|
class BMessageField
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static const char* sNullData;
|
||||||
|
|
||||||
|
BMessageField(const std::string& name, type_code t)
|
||||||
|
: fName(name), fType(t)
|
||||||
|
{;}
|
||||||
|
virtual const std::string& Name() const { return fName; }
|
||||||
|
virtual type_code Type() const { return fType; }
|
||||||
|
virtual bool FixedSize() const { return true; }
|
||||||
|
virtual ssize_t FlattenedSize() const { return 0; }
|
||||||
|
virtual status_t Flatten(BDataIO& stream) const = 0;
|
||||||
|
virtual ssize_t CountItems() const { return 0; }
|
||||||
|
virtual void RemoveItem(ssize_t index) = 0;
|
||||||
|
virtual void PrintToStream(const char* name) const;
|
||||||
|
virtual const void* DataAt(int32 index, ssize_t* size) const = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void PrintDataItem(int32 index) const = 0;
|
||||||
|
|
||||||
|
private:
|
||||||
|
type_code fType;
|
||||||
|
std::string fName;
|
||||||
|
};
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
template<class T>
|
||||||
|
struct BMessageFieldStoragePolicy
|
||||||
|
{
|
||||||
|
class Store
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// Compiler-generated versions should be just fine
|
||||||
|
#if 0
|
||||||
|
Store();
|
||||||
|
Store(const Store& rhs);
|
||||||
|
~Store();
|
||||||
|
Store& operator=(const Store& rhs);
|
||||||
|
#endif
|
||||||
|
inline size_t Size() const { return fData.size(); }
|
||||||
|
inline T& operator[](uint index) { return fData[index]; }
|
||||||
|
inline const T& operator[](uint index) const { return fData[index]; }
|
||||||
|
inline void Add(const T& data) { fData.push_back(data); }
|
||||||
|
inline void Remove(uint index) { fData.erase(fData.begin() + index); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<T> fData;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
template<class T>
|
||||||
|
struct BMessageFieldSizePolicy
|
||||||
|
{
|
||||||
|
typedef typename BMessageFieldStoragePolicy<T>::Store Store;
|
||||||
|
|
||||||
|
inline static size_t Size(const T&) { return sizeof (T); }
|
||||||
|
inline static size_t Size(const Store& data)
|
||||||
|
{
|
||||||
|
return sizeof (T) * data.Size();
|
||||||
|
}
|
||||||
|
inline static bool Fixed() { return true; }
|
||||||
|
};
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
template<class T>
|
||||||
|
struct BMessageFieldPrintPolicy
|
||||||
|
{
|
||||||
|
static void PrintData(const T& data) {;}
|
||||||
|
};
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
template<class T>
|
||||||
|
struct BMessageFieldFlattenPolicy
|
||||||
|
{
|
||||||
|
typedef BMessageFieldSizePolicy<T> SizePolicy;
|
||||||
|
|
||||||
|
inline static status_t Flatten(BDataIO& stream, const T& data)
|
||||||
|
{
|
||||||
|
return stream.Write((const void*)&data, SizePolicy::Size(data));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
template
|
||||||
|
<
|
||||||
|
class T1,
|
||||||
|
class StoragePolicy = BMessageFieldStoragePolicy<T1>,
|
||||||
|
class SizePolicy = BMessageFieldSizePolicy<T1>,
|
||||||
|
class PrintPolicy = BMessageFieldPrintPolicy<T1>,
|
||||||
|
class FlattenPolicy = BMessageFieldFlattenPolicy<T1>
|
||||||
|
>
|
||||||
|
class BMessageFieldImpl : public BMessageField
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef typename StoragePolicy::Store StorageType;
|
||||||
|
|
||||||
|
BMessageFieldImpl(const std::string& name, type_code type)
|
||||||
|
: BMessageField(name, type),
|
||||||
|
fMaxSize(0),
|
||||||
|
fFlags(MSG_FLAG_ALL)
|
||||||
|
{;}
|
||||||
|
|
||||||
|
virtual bool FixedSize() const
|
||||||
|
{ return fFlags & MSG_FLAG_FIXED_SIZE; }
|
||||||
|
virtual ssize_t FlattenedSize() const;
|
||||||
|
virtual status_t Flatten(BDataIO& stream) const;
|
||||||
|
virtual ssize_t CountItems() const { return fData.Size(); }
|
||||||
|
virtual void AddItem(const T1& data);
|
||||||
|
virtual void RemoveItem(ssize_t index)
|
||||||
|
{ fData.Remove(index); };
|
||||||
|
|
||||||
|
virtual const void* DataAt(int32 index, ssize_t* size) const;
|
||||||
|
StorageType& Data() { return fData; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void PrintDataItem(int32 index) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
StorageType fData;
|
||||||
|
size_t fMaxSize;
|
||||||
|
uchar fFlags;
|
||||||
|
};
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
template
|
||||||
|
<
|
||||||
|
class T1,
|
||||||
|
class StoragePolicy,
|
||||||
|
class SizePolicy,
|
||||||
|
class PrintPolicy,
|
||||||
|
class FlattenPolicy
|
||||||
|
>
|
||||||
|
ssize_t
|
||||||
|
BMessageFieldImpl<T1, StoragePolicy, SizePolicy, PrintPolicy, FlattenPolicy>::
|
||||||
|
FlattenedSize() const
|
||||||
|
{
|
||||||
|
ssize_t size = 0;
|
||||||
|
|
||||||
|
// Mandatory stuff
|
||||||
|
size += 1; // field flags byte
|
||||||
|
size += sizeof (type_code); // field type bytes
|
||||||
|
if (!(fFlags & MSG_FLAG_SINGLE_ITEM)) // item count byte
|
||||||
|
++size;
|
||||||
|
++size; // data length byte
|
||||||
|
++size; // name length byte
|
||||||
|
size += Name().length(); // name length
|
||||||
|
|
||||||
|
size += SizePolicy::Size(fData); // data length and item size bytes
|
||||||
|
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
template
|
||||||
|
<
|
||||||
|
class T1,
|
||||||
|
class StoragePolicy,
|
||||||
|
class SizePolicy,
|
||||||
|
class PrintPolicy,
|
||||||
|
class FlattenPolicy
|
||||||
|
>
|
||||||
|
status_t
|
||||||
|
BMessageFieldImpl<T1, StoragePolicy, SizePolicy, PrintPolicy, FlattenPolicy>::
|
||||||
|
Flatten(BDataIO& stream) const
|
||||||
|
{
|
||||||
|
status_t err = B_OK;
|
||||||
|
type_code type = Type();
|
||||||
|
uint8 count = fData.Size();
|
||||||
|
uint8 size = SizePolicy::Size(fData);
|
||||||
|
uint8 nameLen = Name().length();
|
||||||
|
|
||||||
|
err = stream.Write(&fFlags, 1);
|
||||||
|
|
||||||
|
// Field type_code
|
||||||
|
if (err >= 0)
|
||||||
|
err = stream.Write(&type, sizeof (type_code));
|
||||||
|
|
||||||
|
// Item count, if more than one
|
||||||
|
if (err >= 0 && !(fFlags & MSG_FLAG_SINGLE_ITEM))
|
||||||
|
err = stream.Write(&count, 1);
|
||||||
|
|
||||||
|
// Data length
|
||||||
|
if (err >= 0)
|
||||||
|
err = stream.Write(&size, 1);
|
||||||
|
|
||||||
|
// Name length
|
||||||
|
if (err >= 0)
|
||||||
|
err = stream.Write(&nameLen, 1);
|
||||||
|
|
||||||
|
// Name
|
||||||
|
if (err >= 0)
|
||||||
|
err = stream.Write(Name().c_str(), Name().length());
|
||||||
|
|
||||||
|
// Actual data items
|
||||||
|
for (uint32 i = 0; i < fData.Size() && err >= 0; ++i)
|
||||||
|
{
|
||||||
|
err = FlattenPolicy::Flatten(stream, fData[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (err >= 0)
|
||||||
|
err = B_OK;
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
template
|
||||||
|
<
|
||||||
|
class T1,
|
||||||
|
class StoragePolicy,
|
||||||
|
class SizePolicy,
|
||||||
|
class PrintPolicy,
|
||||||
|
class FlattenPolicy
|
||||||
|
>
|
||||||
|
void
|
||||||
|
BMessageFieldImpl<T1, StoragePolicy, SizePolicy, PrintPolicy, FlattenPolicy>::
|
||||||
|
AddItem(const T1& data)
|
||||||
|
{
|
||||||
|
fData.Add(data);
|
||||||
|
|
||||||
|
if (fMaxSize)
|
||||||
|
{
|
||||||
|
if ((fFlags & MSG_FLAG_FIXED_SIZE) &&
|
||||||
|
(!SizePolicy::Fixed() ||
|
||||||
|
fMaxSize != SizePolicy::Size(data)))
|
||||||
|
{
|
||||||
|
fMaxSize = max(SizePolicy::Size(data), fMaxSize);
|
||||||
|
fFlags &= ~MSG_FLAG_FIXED_SIZE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!SizePolicy::Fixed())
|
||||||
|
{
|
||||||
|
fFlags &= ~MSG_FLAG_FIXED_SIZE;
|
||||||
|
}
|
||||||
|
fMaxSize = SizePolicy::Size(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fData.Size() > 256 || fMaxSize > 256)
|
||||||
|
fFlags &= ~MSG_FLAG_MINI_DATA;
|
||||||
|
|
||||||
|
if (fData.Size() > 1)
|
||||||
|
fFlags &= ~MSG_FLAG_SINGLE_ITEM;
|
||||||
|
}
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
template
|
||||||
|
<
|
||||||
|
class T1,
|
||||||
|
class StoragePolicy,
|
||||||
|
class SizePolicy,
|
||||||
|
class PrintPolicy,
|
||||||
|
class FlattenPolicy
|
||||||
|
>
|
||||||
|
const void*
|
||||||
|
BMessageFieldImpl<T1, StoragePolicy, SizePolicy, PrintPolicy, FlattenPolicy>::
|
||||||
|
DataAt(int32 index, ssize_t* size) const
|
||||||
|
{
|
||||||
|
if (index > CountItems())
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
*size = SizePolicy::Size(fData[index]);
|
||||||
|
const T1& ref = fData[index];
|
||||||
|
const T1* data = &ref;
|
||||||
|
|
||||||
|
return (const void*)data;
|
||||||
|
}
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
template
|
||||||
|
<
|
||||||
|
class T1,
|
||||||
|
class StoragePolicy,
|
||||||
|
class SizePolicy,
|
||||||
|
class PrintPolicy,
|
||||||
|
class FlattenPolicy
|
||||||
|
>
|
||||||
|
void
|
||||||
|
BMessageFieldImpl<T1, StoragePolicy, SizePolicy, PrintPolicy, FlattenPolicy>::
|
||||||
|
PrintDataItem(int32 index) const
|
||||||
|
{
|
||||||
|
if (index && FixedSize())
|
||||||
|
{
|
||||||
|
std::printf(" ");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::printf("size=%2ld, ", SizePolicy::Size(fData[index]));
|
||||||
|
}
|
||||||
|
std::printf("data[%ld]: ", index);
|
||||||
|
PrintPolicy::PrintData(fData[index]);
|
||||||
|
}
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
// Print policy specializations ------------------------------------------------
|
||||||
|
template<> struct BMessageFieldPrintPolicy<bool>
|
||||||
|
{
|
||||||
|
static void PrintData(const bool& b) { std::printf("%d", int(b)); }
|
||||||
|
};
|
||||||
|
template<> struct BMessageFieldPrintPolicy<int8>
|
||||||
|
{
|
||||||
|
static void PrintData(const int8& i)
|
||||||
|
{ std::printf("0x%X (%d, '%c')", int(i), int(i), char(i)); }
|
||||||
|
};
|
||||||
|
template<> struct BMessageFieldPrintPolicy<int16>
|
||||||
|
{
|
||||||
|
static void PrintData(const int16& i)
|
||||||
|
{ std::printf("0x%X (%d, '%c')", i, i, char(i)); }
|
||||||
|
};
|
||||||
|
template<> struct BMessageFieldPrintPolicy<int32>
|
||||||
|
{
|
||||||
|
static void PrintData(const int32& i)
|
||||||
|
{ std::printf("0x%lX (%ld, '%c')", i, i, char(i)); }
|
||||||
|
};
|
||||||
|
template<> struct BMessageFieldPrintPolicy<int64>
|
||||||
|
{
|
||||||
|
static void PrintData(const int64& i)
|
||||||
|
{ std::printf("0x%LX (%Ld, '%c')", i, i, char(i)); }
|
||||||
|
};
|
||||||
|
template<> struct BMessageFieldPrintPolicy<float>
|
||||||
|
{
|
||||||
|
static void PrintData(const float& f) { std::printf("%.4f", f); }
|
||||||
|
};
|
||||||
|
template<> struct BMessageFieldPrintPolicy<double>
|
||||||
|
{
|
||||||
|
static void PrintData(const double& d) { std::printf("%.8lf", d); }
|
||||||
|
};
|
||||||
|
template<> struct BMessageFieldPrintPolicy<BString>
|
||||||
|
{
|
||||||
|
static void PrintData(const BString& s) { std::printf("\"%s\"", s.String()); }
|
||||||
|
};
|
||||||
|
template<> struct BMessageFieldPrintPolicy<BPoint>
|
||||||
|
{
|
||||||
|
static void PrintData(const BPoint& p) { std::printf("BPoint(x:%.1f, y:%.1f)", p.x, p.y); }
|
||||||
|
};
|
||||||
|
template<> struct BMessageFieldPrintPolicy<BRect>
|
||||||
|
{
|
||||||
|
static void PrintData(const BRect& r)
|
||||||
|
{ std::printf("BRect(l:%.1f, t:%.1f, r:%.1f, b:%.1f)", r.left, r.top, r.right, r.bottom); }
|
||||||
|
};
|
||||||
|
template<> struct BMessageFieldPrintPolicy<entry_ref>
|
||||||
|
{
|
||||||
|
static void PrintData(const entry_ref& ref)
|
||||||
|
{
|
||||||
|
std::printf("device=%ld, directory=%Ld, name=\"%s\", path=\"%s\"",
|
||||||
|
ref.device, ref.directory, ref.name, BPath(&ref).Path());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// Storage policy specializations ----------------------------------------------
|
||||||
|
template<>
|
||||||
|
struct BMessageFieldStoragePolicy<bool>
|
||||||
|
{
|
||||||
|
class Store
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
struct Boolean
|
||||||
|
{
|
||||||
|
Boolean() : data(bool()) {;}
|
||||||
|
Boolean(bool b) : data(b) {;}
|
||||||
|
bool data;
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
inline size_t Size() const
|
||||||
|
{ return fData.size(); }
|
||||||
|
inline bool& operator[](uint index)
|
||||||
|
{ return fData[index].data; }
|
||||||
|
inline const bool& operator[](uint index) const
|
||||||
|
{ return fData[index].data; }
|
||||||
|
void Add(const bool& data)
|
||||||
|
{
|
||||||
|
fData.push_back(data);
|
||||||
|
}
|
||||||
|
void Remove(uint index)
|
||||||
|
{
|
||||||
|
fData.erase(fData.begin() + index);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<Boolean> fData;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
// Size policy specializations -------------------------------------------------
|
||||||
|
template<> struct BMessageFieldSizePolicy<BString>
|
||||||
|
{
|
||||||
|
typedef BMessageFieldStoragePolicy<BString>::Store Store;
|
||||||
|
|
||||||
|
inline static size_t Size(const BString& s) { return s.Length() + 1; }
|
||||||
|
inline static size_t Size(const Store& data)
|
||||||
|
{
|
||||||
|
size_t size = 0;
|
||||||
|
size_t temp;
|
||||||
|
for (uint32 i = 0; i < data.Size(); ++i)
|
||||||
|
{
|
||||||
|
temp = Size(data[i]) + 4; // Four extra bytes for size info
|
||||||
|
// Calculate padding
|
||||||
|
temp += 8 - (temp % 8);
|
||||||
|
size += temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
inline static bool Fixed() { return false; }
|
||||||
|
};
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
template<> struct BMessageFieldSizePolicy<BDataBuffer>
|
||||||
|
{
|
||||||
|
typedef BMessageFieldStoragePolicy<BDataBuffer>::Store Store;
|
||||||
|
|
||||||
|
inline static size_t Size(const BDataBuffer& db)
|
||||||
|
{ return db.BufferSize(); }
|
||||||
|
inline static size_t Size(const Store& data)
|
||||||
|
{
|
||||||
|
size_t size = 0;
|
||||||
|
size_t temp;
|
||||||
|
for (uint32 i = 0; i < data.Size(); ++i)
|
||||||
|
{
|
||||||
|
temp = Size(data[i]) + 4; // Four extra bytes for size info
|
||||||
|
// Calculate padding
|
||||||
|
temp += 8 - (temp % 8);
|
||||||
|
size += temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
inline static bool Fixed() { return false; }
|
||||||
|
};
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
template<> struct BMessageFieldSizePolicy<BMessage*>
|
||||||
|
{
|
||||||
|
typedef BMessageFieldStoragePolicy<BMessage*>::Store Store;
|
||||||
|
|
||||||
|
inline static size_t Size(const BMessage* msg)
|
||||||
|
{ return msg->FlattenedSize(); }
|
||||||
|
inline static size_t Size(const Store& data)
|
||||||
|
{
|
||||||
|
size_t size = 0;
|
||||||
|
size_t temp;
|
||||||
|
for (uint32 i = 0; i < data.Size(); ++i)
|
||||||
|
{
|
||||||
|
temp = Size(data[i]) + 4; // Four extra bytes for size info
|
||||||
|
// Calculate padding
|
||||||
|
temp += 8 - (temp % 8);
|
||||||
|
size += temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
inline static bool Fixed() { return false; }
|
||||||
|
};
|
||||||
|
// Flatten policy specializations ----------------------------------------------
|
||||||
|
template<>
|
||||||
|
struct BMessageFieldFlattenPolicy<BString>
|
||||||
|
{
|
||||||
|
typedef BMessageFieldSizePolicy<BString> SizePolicy;
|
||||||
|
|
||||||
|
static status_t Flatten(BDataIO& stream, const BString& data)
|
||||||
|
{
|
||||||
|
size_t size = SizePolicy::Size(data);
|
||||||
|
status_t err = stream.Write(&size, 4);
|
||||||
|
|
||||||
|
if (err >= 0)
|
||||||
|
err = stream.Write((const void*)data.String(), size);
|
||||||
|
|
||||||
|
if (err >= 0)
|
||||||
|
{
|
||||||
|
// Pad data to 8-byte boundary
|
||||||
|
size += 4; // Account for the stored size of size
|
||||||
|
size %= 8;
|
||||||
|
if (size)
|
||||||
|
{
|
||||||
|
err = stream.Write(&BMessageField::sNullData[size], 8 - (size));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (err >= 0)
|
||||||
|
err = B_OK;
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
template<>
|
||||||
|
struct BMessageFieldFlattenPolicy<BMessage*>
|
||||||
|
{
|
||||||
|
typedef BMessageFieldSizePolicy<BMessage*> SizePolicy;
|
||||||
|
|
||||||
|
static status_t Flatten(BDataIO& stream, const BMessage* data)
|
||||||
|
{
|
||||||
|
size_t size = SizePolicy::Size(data);
|
||||||
|
status_t err = stream.Write(&size, 4);
|
||||||
|
|
||||||
|
if (err >= 0)
|
||||||
|
err = data->Flatten(&stream);
|
||||||
|
|
||||||
|
if (err >= 0)
|
||||||
|
{
|
||||||
|
// Pad data to 8-byte boundary
|
||||||
|
size += 4; // Account for the stored size of size
|
||||||
|
size %= 8;
|
||||||
|
if (size)
|
||||||
|
{
|
||||||
|
err = stream.Write(&BMessageField::sNullData[size], 8 - (size));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (err >= 0)
|
||||||
|
err = B_OK;
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
} // namespace BPrivate
|
||||||
|
|
||||||
|
#endif // MESSAGEFIELD_H
|
||||||
|
|
||||||
|
/*
|
||||||
|
* $Log $
|
||||||
|
*
|
||||||
|
* $Id $
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
@@ -0,0 +1,197 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// MessageUtils.h
|
||||||
|
//
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#ifndef MESSAGEUTILS_H
|
||||||
|
#define MESSAGEUTILS_H
|
||||||
|
|
||||||
|
// Standard Includes -----------------------------------------------------------
|
||||||
|
|
||||||
|
// System Includes -------------------------------------------------------------
|
||||||
|
#include <ByteOrder.h>
|
||||||
|
#include <DataIO.h>
|
||||||
|
#include <Entry.h>
|
||||||
|
#include <Message.h>
|
||||||
|
#include <Messenger.h>
|
||||||
|
#include <SupportDefs.h>
|
||||||
|
|
||||||
|
// Project Includes ------------------------------------------------------------
|
||||||
|
|
||||||
|
// Local Includes --------------------------------------------------------------
|
||||||
|
|
||||||
|
// Local Defines ---------------------------------------------------------------
|
||||||
|
|
||||||
|
// Globals ---------------------------------------------------------------------
|
||||||
|
|
||||||
|
uint32 _checksum_(const uchar *buf, int32 size);
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// _set_message_target_
|
||||||
|
/*! \brief Sets the target of a message.
|
||||||
|
|
||||||
|
\param message The message.
|
||||||
|
\param token The target handler token.
|
||||||
|
\param preferred Indicates whether to use the looper's preferred handler.
|
||||||
|
*/
|
||||||
|
inline
|
||||||
|
void
|
||||||
|
_set_message_target_(BMessage *message, int32 token, bool preferred)
|
||||||
|
{
|
||||||
|
message->fTarget = token;
|
||||||
|
message->fPreferred = preferred;
|
||||||
|
}
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// _set_message_reply_
|
||||||
|
/*! \brief Sets a message's reply target.
|
||||||
|
|
||||||
|
\param message The message.
|
||||||
|
\param messenger The reply messenger.
|
||||||
|
*/
|
||||||
|
inline
|
||||||
|
void
|
||||||
|
_set_message_reply_(BMessage *message, BMessenger messenger)
|
||||||
|
{
|
||||||
|
message->fReplyTo.port = messenger.fPort;
|
||||||
|
message->fReplyTo.target = messenger.fHandlerToken;
|
||||||
|
message->fReplyTo.team = messenger.fTeam;
|
||||||
|
message->fReplyTo.preferred = messenger.fPreferredTarget;
|
||||||
|
}
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
inline int32 _get_message_target_(BMessage *msg)
|
||||||
|
{
|
||||||
|
return msg->fTarget;
|
||||||
|
}
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
inline bool _use_preferred_target_(BMessage *msg)
|
||||||
|
{
|
||||||
|
return msg->fPreferred;
|
||||||
|
}
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
inline status_t normalize_err(status_t err)
|
||||||
|
{
|
||||||
|
return err >= 0 ? B_OK : err;
|
||||||
|
}
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
template<class T>
|
||||||
|
inline void byte_swap(T& /*data*/)
|
||||||
|
{
|
||||||
|
// Specialize for data types which actually swap
|
||||||
|
}
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
inline void write_helper(BDataIO* stream, const void* data, size_t size,
|
||||||
|
status_t& err)
|
||||||
|
{
|
||||||
|
err = normalize_err(stream->Write(data, size));
|
||||||
|
}
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Will the template madness never cease??
|
||||||
|
template<class T>
|
||||||
|
inline status_t write_helper(BDataIO* stream, T& data, status_t& err)
|
||||||
|
{
|
||||||
|
return normalize_err(stream->Write((const void*)data, sizeof (T)));
|
||||||
|
}
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
class TReadHelper
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TReadHelper(BDataIO* stream)
|
||||||
|
: fStream(stream), err(B_OK), fSwap(false)
|
||||||
|
{
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
TReadHelper(BDataIO* stream, bool swap)
|
||||||
|
: fStream(stream), err(B_OK), fSwap(swap)
|
||||||
|
{
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T> inline void operator()(T& data)
|
||||||
|
{
|
||||||
|
err = normalize_err(fStream->Read((void*)&data, sizeof (T)));
|
||||||
|
if (err)
|
||||||
|
throw err;
|
||||||
|
|
||||||
|
if (IsSwapping())
|
||||||
|
{
|
||||||
|
byte_swap(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T> inline void operator()(T data, size_t len)
|
||||||
|
{
|
||||||
|
err = normalize_err(fStream->Read((void*)data, len));
|
||||||
|
if (err)
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t Status() { return err; }
|
||||||
|
void SetSwap(bool yesNo) { fSwap = yesNo; }
|
||||||
|
bool IsSwapping() { return fSwap; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
BDataIO* fStream;
|
||||||
|
status_t err;
|
||||||
|
bool fSwap;
|
||||||
|
};
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
class TChecksumHelper
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TChecksumHelper(uchar* buffer) : fBuffer(buffer), fBufPtr(buffer) {;}
|
||||||
|
|
||||||
|
template<class T> inline void Cache(T& data)
|
||||||
|
{
|
||||||
|
*((T*)fBufPtr) = data;
|
||||||
|
fBufPtr += sizeof (T);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32 CheckSum();
|
||||||
|
|
||||||
|
private:
|
||||||
|
uchar* fBuffer;
|
||||||
|
uchar* fBufPtr;
|
||||||
|
};
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
template<class T> inline status_t read_helper(BDataIO* stream, T& data)
|
||||||
|
{
|
||||||
|
return normalize_err(stream->Read((void*)&data, sizeof (T)));
|
||||||
|
}
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
template<> inline void byte_swap(double& data)
|
||||||
|
{
|
||||||
|
data = __swap_double(data);
|
||||||
|
}
|
||||||
|
template<> inline void byte_swap(float& data)
|
||||||
|
{
|
||||||
|
data = __swap_float(data);
|
||||||
|
}
|
||||||
|
template<> inline void byte_swap(int64& data)
|
||||||
|
{
|
||||||
|
data = __swap_int64(data);
|
||||||
|
}
|
||||||
|
template<> inline void byte_swap(int32& data)
|
||||||
|
{
|
||||||
|
data = __swap_int32(data);
|
||||||
|
}
|
||||||
|
template<> inline void byte_swap(int16& data)
|
||||||
|
{
|
||||||
|
data = __swap_int16(data);
|
||||||
|
}
|
||||||
|
template<> inline void byte_swap(entry_ref& data)
|
||||||
|
{
|
||||||
|
byte_swap(data.device);
|
||||||
|
byte_swap(data.directory);
|
||||||
|
}
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#endif // MESSAGEUTILS_H
|
||||||
|
|
||||||
|
/*
|
||||||
|
* $Log $
|
||||||
|
*
|
||||||
|
* $Id $
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
@@ -0,0 +1,76 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// DataBuffer.h
|
||||||
|
//
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#ifndef DATABUFFER_H
|
||||||
|
#define DATABUFFER_H
|
||||||
|
|
||||||
|
// Standard Includes -----------------------------------------------------------
|
||||||
|
|
||||||
|
// System Includes -------------------------------------------------------------
|
||||||
|
#include <SupportDefs.h>
|
||||||
|
|
||||||
|
// Project Includes ------------------------------------------------------------
|
||||||
|
|
||||||
|
// Local Includes --------------------------------------------------------------
|
||||||
|
|
||||||
|
// Local Defines ---------------------------------------------------------------
|
||||||
|
|
||||||
|
// Globals ---------------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace BPrivate {
|
||||||
|
|
||||||
|
class BDataBuffer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
BDataBuffer(size_t len);
|
||||||
|
BDataBuffer(void* data, size_t len);
|
||||||
|
BDataBuffer(const BDataBuffer& rhs);
|
||||||
|
~BDataBuffer();
|
||||||
|
|
||||||
|
BDataBuffer& operator=(const BDataBuffer& rhs);
|
||||||
|
|
||||||
|
size_t BufferSize() const;
|
||||||
|
const void* Buffer();
|
||||||
|
|
||||||
|
private:
|
||||||
|
class BDataReference
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void Acquire(BDataReference*& ref);
|
||||||
|
void Release(BDataReference*& ref);
|
||||||
|
|
||||||
|
char* Data() { return data; }
|
||||||
|
size_t Size() const { return size; }
|
||||||
|
int32 Count() { return count; }
|
||||||
|
|
||||||
|
static void Create(void* data, size_t len, BDataReference*& ref);
|
||||||
|
static void Create(size_t len, BDataReference*& ref);
|
||||||
|
|
||||||
|
private:
|
||||||
|
BDataReference(void* data, size_t len);
|
||||||
|
BDataReference(size_t len);
|
||||||
|
~BDataReference();
|
||||||
|
|
||||||
|
char* data;
|
||||||
|
size_t size;
|
||||||
|
int32 count;
|
||||||
|
};
|
||||||
|
|
||||||
|
BDataBuffer(); // No default construction allowed!
|
||||||
|
|
||||||
|
BDataReference* fDataRef;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace BPrivate
|
||||||
|
|
||||||
|
#endif // DATABUFFER_H
|
||||||
|
|
||||||
|
/*
|
||||||
|
* $Log $
|
||||||
|
*
|
||||||
|
* $Id $
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
@@ -0,0 +1,390 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Copyright (c) 2001-2002, 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: MessageBody.cpp
|
||||||
|
// Author(s): Erik Jaesler ([email protected])
|
||||||
|
// Description: BMessageBody handles data storage and retrieval for
|
||||||
|
// BMessage.
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Standard Includes -----------------------------------------------------------
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
// System Includes -------------------------------------------------------------
|
||||||
|
#include <TypeConstants.h>
|
||||||
|
|
||||||
|
// Project Includes ------------------------------------------------------------
|
||||||
|
#include <MessageBody.h>
|
||||||
|
|
||||||
|
// Local Includes --------------------------------------------------------------
|
||||||
|
|
||||||
|
// Local Defines ---------------------------------------------------------------
|
||||||
|
|
||||||
|
// Globals ---------------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace BPrivate {
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
BMessageBody::BMessageBody()
|
||||||
|
: fFlattenedSize(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
BMessageBody::BMessageBody(const BMessageBody &rhs)
|
||||||
|
{
|
||||||
|
*this = rhs;
|
||||||
|
}
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
BMessageBody::~BMessageBody()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
BMessageBody& BMessageBody::operator=(const BMessageBody &rhs)
|
||||||
|
{
|
||||||
|
if (this != &rhs)
|
||||||
|
{
|
||||||
|
fData = rhs.fData;
|
||||||
|
fFlattenedSize = rhs.fFlattenedSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
status_t BMessageBody::GetInfo(type_code typeRequested, int32 which,
|
||||||
|
char** name, type_code* typeReturned,
|
||||||
|
int32* count) const
|
||||||
|
{
|
||||||
|
TMsgDataMap::const_iterator i = fData.begin();
|
||||||
|
int32 index = 0;
|
||||||
|
for (index = 0; i != fData.end(); ++i)
|
||||||
|
{
|
||||||
|
if (B_ANY_TYPE == typeRequested && i->second->Type() == typeRequested)
|
||||||
|
{
|
||||||
|
++index;
|
||||||
|
if (index == which)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// We couldn't find any appropriate data
|
||||||
|
if (i == fData.end())
|
||||||
|
{
|
||||||
|
// TODO: research
|
||||||
|
// Which gets returned on an empty message with
|
||||||
|
// typeRequested == B_ANY_TYPE?
|
||||||
|
if (index)
|
||||||
|
{
|
||||||
|
// TODO: research
|
||||||
|
// Is B_NAME_NOT_FOUND ever really returned from this function, as
|
||||||
|
// the BeBook claims?
|
||||||
|
return B_BAD_INDEX;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (count) *count = 0;
|
||||||
|
return B_BAD_TYPE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: BC Break
|
||||||
|
// Change 'name' parameter to const char*
|
||||||
|
*name = const_cast<char*>(i->first.c_str());
|
||||||
|
*typeReturned = i->second->Type();
|
||||||
|
if (count) *count = i->second->CountItems();
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
status_t BMessageBody::GetInfo(const char* name, type_code* type,
|
||||||
|
int32* c) const
|
||||||
|
{
|
||||||
|
status_t err;
|
||||||
|
BMessageField* BMF = FindData(name, B_ANY_TYPE, err);
|
||||||
|
if (BMF)
|
||||||
|
{
|
||||||
|
*type = BMF->Type();
|
||||||
|
if (c)
|
||||||
|
{
|
||||||
|
*c = BMF->CountItems();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (c)
|
||||||
|
{
|
||||||
|
*c = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
status_t BMessageBody::GetInfo(const char* name, type_code* type,
|
||||||
|
bool* fixed_size) const
|
||||||
|
{
|
||||||
|
status_t err;
|
||||||
|
BMessageField* BMF = FindData(name, B_ANY_TYPE, err);
|
||||||
|
if (BMF)
|
||||||
|
{
|
||||||
|
*type = BMF->Type();
|
||||||
|
*fixed_size = BMF->FixedSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
int32 BMessageBody::CountNames(type_code type) const
|
||||||
|
{
|
||||||
|
if (type == B_ANY_TYPE)
|
||||||
|
{
|
||||||
|
return fData.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
int32 count = 0;
|
||||||
|
for (TMsgDataMap::const_iterator i = fData.begin(); i != fData.end(); ++i)
|
||||||
|
{
|
||||||
|
if (type == B_ANY_TYPE || i->second->Type() == type)
|
||||||
|
{
|
||||||
|
++count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
bool BMessageBody::IsEmpty() const
|
||||||
|
{
|
||||||
|
return fData.empty();
|
||||||
|
}
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
void BMessageBody::PrintToStream() const
|
||||||
|
{
|
||||||
|
// TODO: implement
|
||||||
|
for (TMsgDataMap::const_iterator i = fData.begin(); i != fData.end(); ++i)
|
||||||
|
{
|
||||||
|
i->second->PrintToStream(i->first.c_str());
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
status_t BMessageBody::Rename(const char* old_entry, const char* new_entry)
|
||||||
|
{
|
||||||
|
TMsgDataMap::iterator i = fData.find(old_entry);
|
||||||
|
if (i == fData.end())
|
||||||
|
{
|
||||||
|
return B_NAME_NOT_FOUND;
|
||||||
|
}
|
||||||
|
fData.erase(new_entry);
|
||||||
|
fData[new_entry] = i->second;
|
||||||
|
fData.erase(old_entry);
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
ssize_t BMessageBody::FlattenedSize() const
|
||||||
|
{
|
||||||
|
ssize_t size = 1; // For MSG_LAST_ENTRY
|
||||||
|
|
||||||
|
for (TMsgDataMap::const_iterator i = fData.begin(); i != fData.end(); ++i)
|
||||||
|
{
|
||||||
|
size += i->second->FlattenedSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
status_t BMessageBody::Flatten(BDataIO* stream) const
|
||||||
|
{
|
||||||
|
status_t err = B_OK;
|
||||||
|
|
||||||
|
for (TMsgDataMap::const_iterator i = fData.begin();
|
||||||
|
i != fData.end() && !err;
|
||||||
|
++i)
|
||||||
|
{
|
||||||
|
err = i->second->Flatten(*stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!err)
|
||||||
|
{
|
||||||
|
err = stream->Write("", 1); // For MSG_LAST_ENTRY
|
||||||
|
if (err >= 0)
|
||||||
|
err = B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
status_t BMessageBody::Unflatten(const char* flat_buffer)
|
||||||
|
{
|
||||||
|
// TODO: implement
|
||||||
|
}
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
status_t BMessageBody::Unflatten(BDataIO* stream)
|
||||||
|
{
|
||||||
|
// TODO: implement
|
||||||
|
}
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
status_t BMessageBody::AddData(const char* name, type_code type,
|
||||||
|
const void* data, ssize_t numBytes,
|
||||||
|
bool is_fixed_size, int32 /* count */)
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
@note The same logic applies here are in AddFlat(): is_fixed_size and
|
||||||
|
count aren't useful to us because dynamically adding items isn't
|
||||||
|
an issue. Nevertheless, we keep is_fixed_size to set flags
|
||||||
|
appropriately when flattening the message.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// TODO: test
|
||||||
|
// In particular, we want to see what happens if is_fixed_size == true and
|
||||||
|
// the user attempts to add something bigger or smaller. We may need to
|
||||||
|
// enforce the size thing.
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
status_t BMessageBody::RemoveData(const char* name, int32 index)
|
||||||
|
{
|
||||||
|
if (index < 0)
|
||||||
|
{
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t err = B_OK;
|
||||||
|
BMessageField* BMF = FindData(name, B_ANY_TYPE, err);
|
||||||
|
if (BMF)
|
||||||
|
{
|
||||||
|
if (index < BMF->CountItems())
|
||||||
|
{
|
||||||
|
BMF->RemoveItem(index);
|
||||||
|
if (!BMF->CountItems())
|
||||||
|
{
|
||||||
|
RemoveName(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
err = B_BAD_INDEX;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
status_t BMessageBody::RemoveName(const char* name)
|
||||||
|
{
|
||||||
|
return fData.erase(name) ? B_OK : B_NAME_NOT_FOUND;
|
||||||
|
}
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
status_t BMessageBody::MakeEmpty()
|
||||||
|
{
|
||||||
|
fData.clear();
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
#if 0
|
||||||
|
void* BMessageBody::operator new(size_t size)
|
||||||
|
{
|
||||||
|
return ::new BMessageBody;
|
||||||
|
}
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
void BMessageBody::operator delete(void* ptr, size_t size)
|
||||||
|
{
|
||||||
|
::delete(ptr);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
bool BMessageBody::HasData(const char* name, type_code t, int32 n) const
|
||||||
|
{
|
||||||
|
if (n < 0)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t err;
|
||||||
|
BMessageField* BMF = FindData(name, t, err);
|
||||||
|
if (!BMF)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (n >= BMF->CountItems())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
status_t BMessageBody::FindData(const char *name, type_code type, int32 index,
|
||||||
|
const void **data, ssize_t *numBytes) const
|
||||||
|
{
|
||||||
|
status_t err;
|
||||||
|
*data = NULL;
|
||||||
|
BMessageField* Field = FindData(name, type, err);
|
||||||
|
if (!err)
|
||||||
|
{
|
||||||
|
*data = Field->DataAt(index, numBytes);
|
||||||
|
// TODO: verify
|
||||||
|
if (!*data)
|
||||||
|
{
|
||||||
|
err = B_BAD_INDEX;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
BMessageField* BMessageBody::FindData(const char* name, type_code type,
|
||||||
|
status_t& err) const
|
||||||
|
{
|
||||||
|
BMessageField* Item = NULL;
|
||||||
|
err = B_OK;
|
||||||
|
|
||||||
|
TMsgDataMap::const_iterator i = fData.find(name);
|
||||||
|
if (i == fData.end())
|
||||||
|
{
|
||||||
|
err = B_NAME_NOT_FOUND;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Item = i->second;
|
||||||
|
if (Item->Type() != type)
|
||||||
|
{
|
||||||
|
err = B_BAD_TYPE;
|
||||||
|
Item = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Item;
|
||||||
|
}
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
} // namespace BPrivate
|
||||||
|
|
||||||
|
/*
|
||||||
|
* $Log $
|
||||||
|
*
|
||||||
|
* $Id $
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// MessageField.cpp
|
||||||
|
//
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Standard Includes -----------------------------------------------------------
|
||||||
|
|
||||||
|
// System Includes -------------------------------------------------------------
|
||||||
|
#include <ByteOrder.h>
|
||||||
|
|
||||||
|
// Project Includes ------------------------------------------------------------
|
||||||
|
#include "MessageField.h"
|
||||||
|
|
||||||
|
// Local Includes --------------------------------------------------------------
|
||||||
|
|
||||||
|
// Local Defines ---------------------------------------------------------------
|
||||||
|
|
||||||
|
// Globals ---------------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace BPrivate {
|
||||||
|
|
||||||
|
const char* BMessageField::sNullData = "\0\0\0\0\0\0\0\0";
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
void BMessageField::PrintToStream(const char* name) const
|
||||||
|
{
|
||||||
|
int32 type = B_BENDIAN_TO_HOST_INT32(Type());
|
||||||
|
printf(" entry %14s, type='%.4s', c=%2ld, ",
|
||||||
|
name, (char*)&type, CountItems());
|
||||||
|
|
||||||
|
for (int32 i = 0; i < CountItems(); ++i)
|
||||||
|
{
|
||||||
|
if (i)
|
||||||
|
{
|
||||||
|
printf(" ");
|
||||||
|
}
|
||||||
|
PrintDataItem(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
} // namespace BPrivate
|
||||||
|
|
||||||
|
/*
|
||||||
|
* $Log $
|
||||||
|
*
|
||||||
|
* $Id $
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// MessageUtils.cpp
|
||||||
|
//
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Standard Includes -----------------------------------------------------------
|
||||||
|
|
||||||
|
// System Includes -------------------------------------------------------------
|
||||||
|
|
||||||
|
// Project Includes ------------------------------------------------------------
|
||||||
|
#include <MessageUtils.h>
|
||||||
|
|
||||||
|
// Local Includes --------------------------------------------------------------
|
||||||
|
|
||||||
|
// Local Defines ---------------------------------------------------------------
|
||||||
|
|
||||||
|
// Globals ---------------------------------------------------------------------
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
uint32 _checksum_(const uchar* buf, int32 size)
|
||||||
|
{
|
||||||
|
uint32 sum = 0;
|
||||||
|
uint32 temp = 0;
|
||||||
|
|
||||||
|
while (size > 3) {
|
||||||
|
#if defined(__INTEL__)
|
||||||
|
sum += B_SWAP_INT32(*(int*)buf);
|
||||||
|
#else
|
||||||
|
sum += *(int*)buf;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
buf += 4;
|
||||||
|
size -= 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (size > 0) {
|
||||||
|
temp = (temp << 8) + *buf++;
|
||||||
|
size -= 1;
|
||||||
|
sum += temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
int32 TChecksumHelper::CheckSum()
|
||||||
|
{
|
||||||
|
return _checksum_(fBuffer, fBufPtr - fBuffer);
|
||||||
|
}
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/*
|
||||||
|
* $Log $
|
||||||
|
*
|
||||||
|
* $Id $
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
@@ -3,6 +3,7 @@ APP_KIT_SOURCE =
|
|||||||
AppMisc.cpp
|
AppMisc.cpp
|
||||||
AppServerLink.cpp
|
AppServerLink.cpp
|
||||||
Cursor.cpp
|
Cursor.cpp
|
||||||
|
DataBuffer.cpp
|
||||||
Clipboard.cpp
|
Clipboard.cpp
|
||||||
Handler.cpp
|
Handler.cpp
|
||||||
InitTerminateLibBe.cpp
|
InitTerminateLibBe.cpp
|
||||||
@@ -10,10 +11,13 @@ APP_KIT_SOURCE =
|
|||||||
Looper.cpp
|
Looper.cpp
|
||||||
LooperList.cpp
|
LooperList.cpp
|
||||||
Message.cpp
|
Message.cpp
|
||||||
|
MessageBody.cpp
|
||||||
|
MessageField.cpp
|
||||||
MessageFilter.cpp
|
MessageFilter.cpp
|
||||||
MessageQueue.cpp
|
MessageQueue.cpp
|
||||||
MessageRunner.cpp
|
MessageRunner.cpp
|
||||||
Messenger.cpp
|
Messenger.cpp
|
||||||
|
MessageUtils.cpp
|
||||||
PropertyInfo.cpp
|
PropertyInfo.cpp
|
||||||
PortLink.cpp
|
PortLink.cpp
|
||||||
RegistrarDefs.cpp
|
RegistrarDefs.cpp
|
||||||
|
|||||||
@@ -0,0 +1,129 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// DataBuffer.cpp
|
||||||
|
//
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Standard Includes -----------------------------------------------------------
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
// System Includes -------------------------------------------------------------
|
||||||
|
|
||||||
|
// Project Includes ------------------------------------------------------------
|
||||||
|
#include <DataBuffer.h>
|
||||||
|
|
||||||
|
// Local Includes --------------------------------------------------------------
|
||||||
|
|
||||||
|
// Local Defines ---------------------------------------------------------------
|
||||||
|
|
||||||
|
// Globals ---------------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace BPrivate {
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
BDataBuffer::BDataBuffer(size_t len)
|
||||||
|
{
|
||||||
|
BDataReference::Create(len, fDataRef);
|
||||||
|
}
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
BDataBuffer::BDataBuffer(void* data, size_t len)
|
||||||
|
{
|
||||||
|
BDataReference::Create(data, len, fDataRef);
|
||||||
|
}
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
BDataBuffer::BDataBuffer(const BDataBuffer& rhs)
|
||||||
|
{
|
||||||
|
*this = rhs;
|
||||||
|
}
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
BDataBuffer::~BDataBuffer()
|
||||||
|
{
|
||||||
|
if (fDataRef)
|
||||||
|
{
|
||||||
|
fDataRef->Release(fDataRef);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
BDataBuffer& BDataBuffer::operator=(const BDataBuffer& rhs)
|
||||||
|
{
|
||||||
|
if (this != &rhs)
|
||||||
|
{
|
||||||
|
rhs.fDataRef->Acquire(fDataRef);
|
||||||
|
}
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
size_t BDataBuffer::BufferSize() const
|
||||||
|
{
|
||||||
|
return fDataRef->Size();
|
||||||
|
}
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
const void* BDataBuffer::Buffer()
|
||||||
|
{
|
||||||
|
return (const void*)fDataRef->Data();
|
||||||
|
}
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
void BDataBuffer::BDataReference::Create(void* data, size_t len,
|
||||||
|
BDataReference*& ref)
|
||||||
|
{
|
||||||
|
BDataReference* temp = new BDataReference(data, len);
|
||||||
|
temp->Acquire(ref);
|
||||||
|
}
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
void BDataBuffer::BDataReference::Create(size_t len, BDataReference*& ref)
|
||||||
|
{
|
||||||
|
BDataReference* temp = new BDataReference(len);
|
||||||
|
temp->Acquire(ref);
|
||||||
|
}
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
void BDataBuffer::BDataReference::Acquire(BDataReference*& ref)
|
||||||
|
{
|
||||||
|
ref = this;
|
||||||
|
++count;
|
||||||
|
}
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
void BDataBuffer::BDataReference::Release(BDataReference*& ref)
|
||||||
|
{
|
||||||
|
ref = NULL;
|
||||||
|
--count;
|
||||||
|
if (count <= 0)
|
||||||
|
{
|
||||||
|
delete this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
BDataBuffer::BDataReference::BDataReference(void* data, size_t len)
|
||||||
|
: data(NULL), size(len), count(0)
|
||||||
|
{
|
||||||
|
data = new char[len];
|
||||||
|
memcpy((void*)data, data, len);
|
||||||
|
}
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
BDataBuffer::BDataReference::BDataReference(size_t len)
|
||||||
|
: data(NULL), size(len), count(0)
|
||||||
|
{
|
||||||
|
data = new char[len];
|
||||||
|
}
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
BDataBuffer::BDataReference::~BDataReference()
|
||||||
|
{
|
||||||
|
if (data)
|
||||||
|
{
|
||||||
|
delete[] data;
|
||||||
|
data = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
} // namespace BPrivate
|
||||||
|
|
||||||
|
/*
|
||||||
|
* $Log $
|
||||||
|
*
|
||||||
|
* $Id $
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
@@ -9,4 +9,5 @@ SUPPORT_KIT_SOURCE =
|
|||||||
StopWatch.cpp
|
StopWatch.cpp
|
||||||
String.cpp
|
String.cpp
|
||||||
string_helper.cpp
|
string_helper.cpp
|
||||||
|
# StreamIO.cpp
|
||||||
;
|
;
|
||||||
|
|||||||
Reference in New Issue
Block a user