Message.h

00001 /* This file is Copyright 2000-2008 Meyer Sound Laboratories Inc.  See the included LICENSE.txt file for details. */
00002 
00003 /******************************************************************************
00004 /
00005 /   File:       Message.h
00006 /
00007 /   Description:   OS-independent version of Be's BMessage class.
00008 /         Doesn't contain all of BMessage's functionality,
00009 /         but keeps enough of it to be useful as a portable
00010 /         data object (dictionary) in cross-platform apps.
00011 /         Also adds some functionality that BMessage doesn't have,
00012 /         such as iterators and optional direct (non-copying) access to internal
00013 /         data (for efficiency)
00014 /
00015 *******************************************************************************/
00016 
00017 #ifndef MuscleMessage_h
00018 #define MuscleMessage_h
00019 
00020 #include "support/Point.h"
00021 #include "support/Rect.h"
00022 #include "util/ByteBuffer.h"
00023 #include "util/String.h"
00024 #include "util/Hashtable.h"
00025 
00026 BEGIN_NAMESPACE(muscle);
00027 
00028 class Message;
00029 typedef Ref<Message> MessageRef;
00030 
00035 const Message & GetEmptyMessage();
00036 
00038 const MessageRef & GetEmptyMessageRef();
00039 
00044 MessageRef::ItemPool * GetMessagePool();
00045 
00050 MessageRef GetMessageFromPool(uint32 what = 0L);
00051 
00057 MessageRef GetMessageFromPool(ObjectPool<Message> & pool, uint32 what = 0L);
00058 
00063 MessageRef GetMessageFromPool(const Message & copyMe);
00064 
00070 MessageRef GetMessageFromPool(ObjectPool<Message> & pool, const Message & copyMe);
00071 
00072 // this declaration is for internal use only
00073 class AbstractDataArray;
00074 
00078 class MessageFieldNameIterator : private HashtableIterator<String, GenericRef>
00079 {
00080 public:
00084    MessageFieldNameIterator() : _typeCode(B_ANY_TYPE) {/* empty */}
00085 
00093    MessageFieldNameIterator(const Message & msg, uint32 type = B_ANY_TYPE, uint32 flags = 0);
00094 
00096    ~MessageFieldNameIterator() {/* empty */}
00097 
00099    void operator++(int) {(void) GetNextFieldNameString();}
00100 
00102    void operator--(int) {bool b = IsBackwards(); SetBackwards(!b); (void) GetNextFieldNameString(); SetBackwards(b);}
00103 
00105    bool HasMoreFieldNames() const {return (PeekNextFieldNameString() != NULL);}
00106 
00111    const String & GetFieldName() const {return *PeekNextFieldNameString();}
00112 
00118    status_t GetNextFieldName(String & name);
00119 
00125    const char * GetNextFieldName() {const String * r = GetNextFieldNameString(); return r ? r->Cstr() : NULL;}
00126 
00131    const String * GetNextFieldNameString();
00132 
00138    status_t PeekNextFieldName(String & name) const;
00139 
00145    const char * PeekNextFieldName() const {const String * r = PeekNextFieldNameString(); return r ? r->Cstr() : NULL;}
00146 
00151    const String * PeekNextFieldNameString() const;
00152 
00153 private:
00154    friend class Message;
00155    MessageFieldNameIterator(const HashtableIterator<String, GenericRef> & iter, uint32 tc) : HashtableIterator<String, GenericRef>(iter), _typeCode(tc) {/* empty */}
00156 
00157    uint32 _typeCode;
00158 };
00159 
00160 // Version number of the Message serialization protocol.
00161 // Will be the first four bytes of each serialized Message buffer.
00162 // Only buffers beginning with version numbers between these two 
00163 // constants (inclusive) will be Unflattened as Messages.
00164 #define OLDEST_SUPPORTED_PROTOCOL_VERSION 1347235888 // 'PM00'
00165 #define CURRENT_PROTOCOL_VERSION          1347235888 // 'PM00'
00166 
00174 class Message : public FlatCountable
00175 {
00176 public:
00178    uint32 what;
00179 
00181    Message() : what(0) {/* empty */}
00182 
00186    Message(uint32 what) : what(what) {/* empty */}
00187 
00189    Message(const Message & copyMe) : FlatCountable() {*this = copyMe;}
00190 
00192    virtual ~Message() {/* empty */}
00193 
00195    Message &operator=(const Message &msg);
00196 
00201    bool operator ==(const Message & rhs) const;
00202 
00204    bool operator !=(const Message & rhs) const {return !(*this == rhs);}
00205 
00213    status_t GetInfo(const String & name, uint32 *type, uint32 *c = NULL, bool *fixed_size = NULL) const;
00214 
00219    uint32 CountNames(uint32 type = B_ANY_TYPE) const;
00220 
00225    bool HasNames(uint32 type = B_ANY_TYPE) const {return (CountNames(type) > 0);}
00226 
00228    bool IsEmpty() const {return (_entries.IsEmpty());}
00229 
00234    void PrintToStream(bool recursive = true, int indentLevel = 0) const;
00235 
00239    String ToString(bool recursive = true, int indentLevel = 0) const;
00240 
00244    void AddToString(String & s, bool recursive = true, int indentLevel = 0) const;
00245 
00252    status_t Rename(const String & old_entry, const String & new_entry);
00253 
00255    virtual bool IsFixedSize() const {return false;}
00256 
00258    virtual uint32 TypeCode() const {return B_MESSAGE_TYPE;}
00259 
00261    virtual uint32 FlattenedSize() const;
00262  
00268    virtual void Flatten(uint8 *buffer) const;
00269 
00278    virtual status_t Unflatten(const uint8 *buf, uint32 size);
00279 
00285    status_t AddString(const String & name, const String & val);
00286 
00292    status_t AddInt8(const String & name, int8 val);
00293 
00299    status_t AddInt16(const String & name, int16 val);
00300 
00306    status_t AddInt32(const String & name, int32 val);
00307 
00313    status_t AddInt64(const String & name, int64 val);
00314 
00320    status_t AddBool(const String & name, bool val);
00321 
00327    status_t AddFloat(const String & name, float val);
00328 
00334    status_t AddDouble(const String & name, double val);
00335 
00344    status_t AddMessage(const String & name, const Message & msg) {return AddMessage(name, GetMessageFromPool(msg));}
00345 
00354    status_t AddMessage(const String & name, const MessageRef & msgRef); 
00355 
00361    status_t AddPointer(const String & name, const void * ptr);
00362 
00368    status_t AddPoint(const String & name, const Point & point);
00369 
00375    status_t AddRect(const String & name, const Rect & rect);
00376 
00383    status_t AddFlat(const String & name, const Flattenable &obj);
00384 
00390    status_t AddFlat(const String & name, const FlatCountableRef & ref);
00391 
00397    status_t AddFlat(const String & name, const ByteBufferRef & ref)
00398    {
00399       FlatCountableRef fcRef;
00400       fcRef.SetFromGenericUnchecked(ref.GetGeneric());
00401       return AddFlat(name, fcRef);
00402    }
00403 
00412    status_t AddTag(const String & name, const GenericRef & tagRef);
00413 
00430    status_t AddData(const String & name, uint32 type, const void *data, uint32 numBytes) {return AddDataAux(name, data, numBytes, type, false);}
00431 
00437    status_t PrependString(const String & name, const String & val);
00438 
00444    status_t PrependInt8(const String & name, int8 val);
00445 
00451    status_t PrependInt16(const String & name, int16 val);
00452 
00458    status_t PrependInt32(const String & name, int32 val);
00459 
00465    status_t PrependInt64(const String & name, int64 val);
00466 
00472    status_t PrependBool(const String & name, bool val);
00473 
00479    status_t PrependFloat(const String & name, float val);
00480 
00486    status_t PrependDouble(const String & name, double val);
00487 
00495    status_t PrependMessage(const String & name, const Message & msg) {return PrependMessage(name, GetMessageFromPool(msg));}
00496 
00505    status_t PrependMessage(const String & name, const MessageRef & msgRef); 
00506 
00512    status_t PrependPointer(const String & name, const void * ptr);
00513 
00519    status_t PrependPoint(const String & name, const Point & point);
00520 
00526    status_t PrependRect(const String & name, const Rect & rect);
00527 
00535    status_t PrependFlat(const String & name, const Flattenable &obj);
00536 
00542    status_t PrependFlat(const String & name, const FlatCountableRef & flatRef);
00543 
00549    status_t PrependFlat(const String & name, const ByteBufferRef & ref)
00550    {
00551       FlatCountableRef fcRef;
00552       fcRef.SetFromGenericUnchecked(ref.GetGeneric());
00553       return PrependFlat(name, fcRef);
00554    }
00555 
00564    status_t PrependTag(const String & name, const GenericRef & tagRef);
00565 
00582    status_t PrependData(const String & name, uint32 type, const void *data, uint32 numBytes) {return AddDataAux(name, data, numBytes, type, true);}
00583 
00590    status_t RemoveData(const String & name, uint32 index = 0);
00591 
00596    status_t RemoveName(const String & name);
00597 
00602    void Clear(bool releaseCachedBuffers = false) {_entries.Clear(releaseCachedBuffers);}
00603 
00610    status_t FindString(const String & name, uint32 index, const String ** setMe) const;
00611 
00613    status_t FindString(const String & name, const String ** setMe) const {return FindString(name, 0, setMe);}
00614 
00621    status_t FindString(const String & name, uint32 index, const char ** setMe) const;
00622 
00624    status_t FindString(const String & name, const char ** setMe) const {return FindString(name, 0, setMe);}
00625 
00632    status_t FindString(const String & name, uint32 index, String & setMe) const;
00633 
00635    status_t FindString(const String & name, String & setMe) const {return FindString(name, 0, setMe);}
00636 
00643    status_t FindInt8(const String & name, uint32 index, int8 *val) const {return FindDataItemAux(name, index, B_INT8_TYPE, val, sizeof(int8));}
00644 
00646    status_t FindInt8(const String & name, int8 *value) const {return FindInt8(name, 0, value);}
00647 
00654    status_t FindInt16(const String & name, uint32 index, int16 *val) const {return FindDataItemAux(name, index, B_INT16_TYPE, val, sizeof(int16));} 
00655 
00657    status_t FindInt16(const String & name, int16 *value) const {return FindInt16(name, 0, value);}
00658 
00665    status_t FindInt32(const String & name, uint32 index, int32 *val) const {return FindDataItemAux(name, index, B_INT32_TYPE, val, sizeof(int32));} 
00666 
00668    status_t FindInt32(const String & name, int32 *value) const {return FindInt32(name, 0, value);}
00669 
00676    status_t FindInt64(const String & name, uint32 index, int64 *val) const {return FindDataItemAux(name, index, B_INT64_TYPE, val, sizeof(int64));}  
00677 
00679    status_t FindInt64(const String & name, int64 *value) const {return FindInt64(name, 0, value);}
00680 
00687    status_t FindBool(const String & name, uint32 index, bool *val) const {return FindDataItemAux(name, index, B_BOOL_TYPE, val, sizeof(bool));} 
00688 
00690    status_t FindBool(const String & name, bool *value) const {return FindBool(name, 0, value);}
00691 
00698    status_t FindFloat(const String & name, uint32 index, float *val) const {return FindDataItemAux(name, index, B_FLOAT_TYPE, val, sizeof(float));}
00699 
00701    status_t FindFloat(const String & name, float *f) const {return FindFloat(name, 0, f);}
00702 
00709    status_t FindDouble(const String & name, uint32 index, double * val) const {return FindDataItemAux(name, index, B_DOUBLE_TYPE, val, sizeof(double));}
00710 
00712    status_t FindDouble(const String & name, double *d) const {return FindDouble(name, 0, d);}
00713 
00722    status_t FindMessage(const String & name, uint32 index, Message &msg) const;
00723 
00725    status_t FindMessage(const String & name, Message &msg) const {return FindMessage(name, 0, msg);}
00726 
00735    status_t FindMessage(const String & name, uint32 index, MessageRef &msgRef) const;
00736 
00738    status_t FindMessage(const String & name, MessageRef &msgRef) const {return FindMessage(name, 0, msgRef);}
00739 
00746    status_t FindPointer(const String & name, uint32 index, void ** val) const {return FindDataItemAux(name, index, B_POINTER_TYPE, val, sizeof(void *));}
00747 
00749    status_t FindPointer(const String & name, void ** ptr) const {return FindPointer(name, 0, ptr);}
00750 
00757    status_t FindPoint(const String & name, uint32 index, Point & point) const;
00758 
00760    status_t FindPoint(const String & name, Point & point) const {return FindPoint(name, 0, point);}
00761 
00768    status_t FindRect(const String & name, uint32 index, Rect & rect) const;
00769 
00771    status_t FindRect(const String & name, Rect & rect) const {return FindRect(name, 0, rect);}
00772 
00779    status_t FindFlat(const String & name, uint32 index, Flattenable &obj) const;
00780 
00782    status_t FindFlat(const String & name, Flattenable &obj) const {return FindFlat(name, 0, obj);}
00783 
00790    status_t FindFlat(const String & name, uint32 index, FlatCountableRef & ref) const;
00791 
00793    status_t FindFlat(const String & name, FlatCountableRef &ref) const {return FindFlat(name, 0, ref);}
00794 
00798    status_t FindFlat(const String & name, uint32 index, ByteBufferRef & ref) const
00799    {
00800       FlatCountableRef fcRef;
00801       return (FindFlat(name, index, fcRef) == B_NO_ERROR) ? ref.SetFromGeneric(fcRef.GetGeneric()) : B_ERROR;
00802    }
00803 
00805    status_t FindFlat(const String & name, ByteBufferRef &ref) const {return FindFlat(name, 0, ref);}
00806 
00813    status_t FindTag(const String & name, uint32 index, GenericRef & tagRef) const;
00814 
00816    status_t FindTag(const String & name, GenericRef &tagRef) const {return FindTag(name, 0, tagRef);}
00817 
00829    status_t FindData(const String & name, uint32 type, uint32 index, const void **data, uint32 *numBytes) const;
00830 
00832    status_t FindData(const String & name, uint32 type, const void **data, uint32 *numBytes) const {return FindData(name, type, 0, data, numBytes);}
00833 
00839    status_t FindDataPointer(const String & name, uint32 type, uint32 index, void **data, uint32 *numBytes) const;
00840 
00842    status_t FindDataPointer(const String & name, uint32 type, void **data, uint32 *numBytes) const {return FindDataPointer(name, type, 0, data, numBytes);}
00843 
00851    status_t ReplaceString(bool okayToAdd, const String & name, uint32 index, const String & newString);
00852 
00854    status_t ReplaceString(bool okayToAdd, const String & name, const String & newString) {return ReplaceString(okayToAdd, name, 0, newString);}
00855 
00863    status_t ReplaceInt8(bool okayToAdd, const String & name, uint32 index, int8 val);
00864 
00866    status_t ReplaceInt8(bool okayToAdd, const String & name, int8 val) {return ReplaceInt8(okayToAdd, name, 0, val);}
00867 
00875    status_t ReplaceInt16(bool okayToAdd, const String & name, uint32 index, int16 val);
00876 
00878    status_t ReplaceInt16(bool okayToAdd, const String & name, int16 val) {return ReplaceInt16(okayToAdd, name, 0, val);}
00879 
00887    status_t ReplaceInt32(bool okayToAdd, const String & name, uint32 index, int32 val);
00888 
00890    status_t ReplaceInt32(bool okayToAdd, const String & name, int32 val) {return ReplaceInt32(okayToAdd, name, 0, val);}
00891 
00899    status_t ReplaceInt64(bool okayToAdd, const String & name, uint32 index, int64 val);
00900 
00902    status_t ReplaceInt64(bool okayToAdd, const String & name, int64 val) {return ReplaceInt64(okayToAdd, name, 0, val);}
00903 
00911    status_t ReplaceBool(bool okayToAdd, const String & name, uint32 index, bool val);
00912 
00914    status_t ReplaceBool(bool okayToAdd, const String & name, bool val) {return ReplaceBool(okayToAdd, name, 0, val);}
00915 
00923    status_t ReplaceFloat(bool okayToAdd, const String & name, uint32 index, float val);
00924 
00926    status_t ReplaceFloat(bool okayToAdd, const String & name, float val) {return ReplaceFloat(okayToAdd, name, 0, val);}
00927 
00935    status_t ReplaceDouble(bool okayToAdd, const String & name, uint32 index, double val);
00936 
00938    status_t ReplaceDouble(bool okayToAdd, const String & name, double val) {return ReplaceDouble(okayToAdd, name, 0, val);}
00939 
00947    status_t ReplacePointer(bool okayToAdd, const String & name, uint32 index, const void * ptr);
00948 
00950    status_t ReplacePointer(bool okayToAdd, const String & name, const void * ptr) {return ReplacePointer(okayToAdd, name, 0, ptr);}
00951 
00959    status_t ReplacePoint(bool okayToAdd, const String & name, uint32 index, const Point & point);
00960 
00962    status_t ReplacePoint(bool okayToAdd, const String & name, const Point & point) {return ReplacePoint(okayToAdd, name, 0, point);}
00963 
00971    status_t ReplaceRect(bool okayToAdd, const String & name, uint32 index, const Rect & rect);
00972 
00974    status_t ReplaceRect(bool okayToAdd, const String & name, const Rect & rect) {return ReplaceRect(okayToAdd, name, 0, rect);}
00975 
00983    status_t ReplaceMessage(bool okayToAdd, const String & name, uint32 index, const Message &msg) {return ReplaceMessage(okayToAdd, name, index, GetMessageFromPool(msg));}
00984 
00986    status_t ReplaceMessage(bool okayToAdd, const String & name, const Message &msg) {return ReplaceMessage(okayToAdd, name, 0, msg);}
00987 
00995    status_t ReplaceMessage(bool okayToAdd, const String & name, uint32 index, const MessageRef & msgRef);
00996 
00998    status_t ReplaceMessage(bool okayToAdd, const String & name, const MessageRef & msgRef) {return ReplaceMessage(okayToAdd, name, 0, msgRef);}
00999 
01007    status_t ReplaceFlat(bool okayToAdd, const String & name, uint32 index, const Flattenable &obj);
01008 
01010    status_t ReplaceFlat(bool okayToAdd, const String & name, const Flattenable &obj) {return ReplaceFlat(okayToAdd, name, 0, obj);}
01011 
01019    status_t ReplaceFlat(bool okayToAdd, const String & name, uint32 index, const FlatCountableRef & ref);
01020 
01022    status_t ReplaceFlat(bool okayToAdd, const String & name, FlatCountableRef &ref) {return ReplaceFlat(okayToAdd, name, 0, ref);}
01023 
01025    status_t ReplaceFlat(bool okayToAdd, const String & name, uint32 index, const ByteBufferRef & ref) 
01026    {
01027       FlatCountableRef fcRef;
01028       fcRef.SetFromGenericUnchecked(ref.GetGeneric());
01029       return ReplaceFlat(okayToAdd, name, index, fcRef);
01030    }
01031 
01033    status_t ReplaceFlat(bool okayToAdd, const String & name, ByteBufferRef &ref) {return ReplaceFlat(okayToAdd, name, 0, ref);}
01034 
01042    status_t ReplaceTag(bool okayToAdd, const String & name, uint32 index, const GenericRef & tag);
01043 
01045    status_t ReplaceTag(bool okayToAdd, const String & name, const GenericRef & tag) {return ReplaceTag(okayToAdd, name, 0, tag);}
01046 
01059    status_t ReplaceData(bool okayToAdd, const String & name, uint32 type, uint32 index, const void *data, uint32 numBytes);
01060 
01062    status_t ReplaceData(bool okayToAdd, const String & name, uint32 type, const void *data, uint32 numBytes) {return ReplaceData(okayToAdd, name, type, 0, data, numBytes);}
01063 
01070    const String * GetFirstFieldNameString(uint32 optTypeCode = B_ANY_TYPE) const {return GetExtremeFieldNameStringAux(optTypeCode, false);}
01071 
01078    const String * GetLastFieldNameString(uint32 optTypeCode = B_ANY_TYPE) const {return GetExtremeFieldNameStringAux(optTypeCode, true);}
01079 
01085    bool HasName(const String & fieldName, uint32 type = B_ANY_TYPE) const {return (GetArray(fieldName, type) != NULL);}
01086 
01093    uint32 GetNumValuesInName(const String & fieldName, uint32 type = B_ANY_TYPE) const;
01094 
01101    status_t MoveName(const String & name, Message &moveTo);
01102 
01110    status_t CopyName(const String & name, Message &copyTo) const;
01111 
01117    void SwapContents(Message & swapWith);
01118 
01129    uint32 CalculateChecksum(bool countNonFlattenableFields = false) const;
01130 
01140    MessageFieldNameIterator GetFieldNameIterator(uint32 type = B_ANY_TYPE, uint32 flags = 0) const {return MessageFieldNameIterator(_entries.GetIterator(flags), type);}
01141 
01151    MessageFieldNameIterator GetFieldNameIteratorAt(const String & startFieldName, uint32 type = B_ANY_TYPE, uint32 flags = 0) const {return MessageFieldNameIterator(_entries.GetIteratorAt(startFieldName, flags), type);}
01152 
01153 protected:
01155    virtual status_t CopyFromImplementation(const Flattenable & copyFrom);
01156 
01157 private:
01158    // Helper functions
01159    status_t AddDataAux(const String &name, uint32 type, const void *data, uint32 numBytes, bool prepend);
01160 
01161    // Given a known uint32, returns the size of an item of that type.
01162    // Returns zero if items of the given type are variable length.
01163    uint32 GetElementSize(uint32 type) const;
01164 
01165    GenericRef GetArrayRef(const String & arrayName, uint32 etc) const;
01166    AbstractDataArray * GetArray(const String & arrayName, uint32 etc) const;
01167    AbstractDataArray * GetOrCreateArray(const String & arrayName, uint32 tc);
01168 
01169    status_t AddFlatBuffer(const String & name, const Flattenable & flat, uint32 etc, bool prepend);
01170    status_t AddFlatRef(const String & name, const FlatCountableRef & flat, uint32 etc, bool prepend);
01171    status_t AddDataAux(const String & name, const void * data, uint32 size, uint32 etc, bool prepend);
01172 
01173    status_t FindFlatAux(const String & name, uint32 index, Flattenable & flat) const;
01174    status_t FindDataItemAux(const String & name, uint32 index, uint32 tc, void * setValue, uint32 valueSize) const;
01175 
01176    status_t ReplaceFlatItemBuffer(bool okayToAdd, const String & name, uint32 index, const Flattenable & flat, uint32 tc);
01177    status_t ReplaceDataAux(bool okayToAdd, const String & name, uint32 index, void * dataBuf, uint32 bufSize, uint32 tc);
01178  
01179    bool FieldsAreSubsetOf(const Message & rhs, bool compareData) const;
01180 
01181    const String * GetExtremeFieldNameStringAux(uint32 optTypeCode, bool isLast) const
01182    {
01183       return (optTypeCode == B_ANY_TYPE) ? (isLast ? _entries.GetLastKey() : _entries.GetFirstKey()) 
01184                                          : MessageFieldNameIterator(*this, optTypeCode, HTIT_FLAG_NOREGISTER|(isLast?HTIT_FLAG_BACKWARDS:0)).GetNextFieldNameString();
01185    }
01186 
01187    // Iterator support methods
01188    friend class MessageFieldNameIterator;
01189    Hashtable<String, GenericRef> _entries;   
01190 };
01191 
01192 inline MessageFieldNameIterator :: MessageFieldNameIterator(const Message & msg, uint32 type, uint32 flags) : HashtableIterator<String, GenericRef>(msg._entries.GetIterator(flags)), _typeCode(type) {/* empty */}
01193 
01194 END_NAMESPACE(muscle);
01195 
01196 #endif /* _MUSCLEMESSAGE_H */
01197 

Generated on Thu Jun 5 17:47:53 2008 for MUSCLE by  doxygen 1.5.1