00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <stdio.h>
00025 #include <sys/types.h>
00026 #include <sys/ipc.h>
00027 #include <sys/msg.h>
00028 #include <stdlib.h>
00029 #include <string.h>
00030 #include <errno.h>
00031
00032 #include <stlib/os/MessageQueue.h>
00033 #include <stlib/ByteArray.h>
00034 #include <stlib/String.h>
00035 #include "ipckey.h"
00036
00037 #define MAXBUFFERLEN 256
00038
00039 using namespace OS;
00040
00041
00042 MessageQueue::MessageQueue(int queueKey, bool exclusive)
00043 {
00044 int flags = 0664 | IPC_CREAT;
00045
00046 if (exclusive)
00047 flags = flags | IPC_EXCL;
00048 queueid = msgget(queueKey, flags);
00049 queueCreationKey = queueKey;
00050 if (queueid >= 0) active = true;
00051 _priority = 1;
00052 }
00053
00054 MessageQueue *MessageQueue::open(void)
00055 {
00056 return MessageQueue::open(new String("stlib-MessageQueue"));
00057 }
00058
00059 MessageQueue *MessageQueue::open(bool exclusive)
00060 {
00061 return MessageQueue::open(new String("stlib-MessageQueue"), exclusive);
00062 }
00063
00064 MessageQueue *MessageQueue::open(String *key, bool exclusive)
00065 {
00066 return new MessageQueue(getkey(key->asCString()), exclusive);
00067 }
00068
00069
00070 long MessageQueue::bufferSize(void)
00071 {
00072 return MAXBUFFERLEN;
00073 }
00074
00075 void MessageQueue::priority(long level)
00076 {
00077 _priority = level;
00078 }
00079
00080 long MessageQueue::priority(void)
00081 {
00082 return _priority;
00083 }
00084
00085
00086 void MessageQueue::close(void)
00087 {
00088 if (active)
00089 msgctl(queueid, IPC_RMID, NULL);
00090 active = false;
00091 }
00092
00093
00094 int MessageQueue::readInto(ByteArray *buffer, long startIndex, long count)
00095 {
00096 int bytes;
00097 struct msgbuf {
00098 long mtype;
00099 unsigned char data[MAXBUFFERLEN];
00100 } buf;
00101
00102 if (queueid < 0) return 0;
00103 if (count > MAXBUFFERLEN) count = MAXBUFFERLEN;
00104
00105 bytes = msgrcv(queueid, &buf, count, 0, MSG_NOERROR);
00106 if (bytes > 0)
00107 buffer->replace(startIndex, startIndex+bytes, buf.data);
00108 return bytes;
00109 }
00110
00111 int MessageQueue::writeFrom(ByteArray *buffer, long startIndex, long count)
00112 {
00113 struct msgbuf {
00114 long mtype;
00115 unsigned char mtext[MAXBUFFERLEN];
00116 } buf;
00117
00118 if (queueid < 0 || count < 1)
00119 return 0;
00120
00121 if (count > MAXBUFFERLEN) count = MAXBUFFERLEN;
00122 buf.mtype = _priority;
00123
00124 memcpy(buf.mtext, &(buffer->rawBytesReadOnly())[startIndex], count);
00125 int error = msgsnd(queueid, &buf, count, 0);
00126 if (error < 0)
00127 perror(__PRETTY_FUNCTION__);
00128
00129 return (error < 0) ? 0 : count;
00130 }
00131
00132
00133 void MessageQueue::seekTo(long position)
00134 {
00135 shouldNotImplement(new String(__PRETTY_FUNCTION__));
00136 }