/* $Id: Message.h,v 1.3 1996/09/16 05:25:56 swetland Exp $
**
** Streamable Message Objects
**
** Copyright 1996, Brian J. Swetland <swetland@uiuc.edu> and ACM@UIUC.
** Free for non-commercial use.  Share and Enjoy!
*/

#ifndef _MESSAGE_H
#define _MESSAGE_H

#include "Types.h"

/* message format:

   8 byte header                                          len byte message...

   |<--  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -->| |<-- -  -  -
   
   '@' 'X' <src_hi> <src_lo> <dst_hi> <dst_lo> <len_hi> <len_lo> <content...

*/

#define typeNone    0    /* illegal empty MsgNode */
#define typeByte    1    /* 1 <namelen> <name...> <byte> */
#define typeWord    2    /* 2 <namelen> <name...> <hi> <lo> */
#define typeString  3    /* 3 <namelen> <name...> <len> <byte...> */
#define typeName    4    /* 4 <namelen> <name...> */

#define typeCount   4


struct MsgNode 
{
    MsgNode *next;
    char *name;
    Byte type;
    union {
        Byte byte;
        Word word;
        String string;
    } data;    
};


class Message 
{
    char *msg_name;
    int msg_size;
    MsgNode *first;

    MsgNode *AddMsgNode(char *name, Byte type, int nocopyname=0);
    MsgNode *FindMsgNode(char *name);
    
  public:
    Message(char *name); /* create a new empty named message */
    Message(Byte *buf, int len);  /* create a message from a stream */
    ~Message();

    void Print(void);

    Byte *ToStream(int *len);  /* create and return a stream rep */
    
    void PutByte(char *name, Byte byte);
    void PutWord(char *name, Word word);
    void PutString(char *name, String string);

    void GetByte(char *name, Byte &byte);
    void GetWord(char *name, Word &word);
    void GetString(char *name, String &string);

    char *Name(void) { return msg_name; };
};


/* a class of objects that may receive messages */
class MessageHandler
{
  public:
    virtual void Receive(int src, int dst, Message *msg) = 0;
};

#endif /* _MESSAGE_H */



