ServiceMessage.hpp
Go to the documentation of this file.
1 /*----------------------------------------------------------------------------*/
2 /* */
3 /* Copyright (c) 1995, 2004 IBM Corporation. All rights reserved. */
4 /* Copyright (c) 2005-2009 Rexx Language Association. All rights reserved. */
5 /* */
6 /* This program and the accompanying materials are made available under */
7 /* the terms of the Common Public License v1.0 which accompanies this */
8 /* distribution. A copy is also available at the following address: */
9 /* http://www.ibm.com/developerworks/oss/CPLv1.0.htm */
10 /* */
11 /* Redistribution and use in source and binary forms, with or */
12 /* without modification, are permitted provided that the following */
13 /* conditions are met: */
14 /* */
15 /* Redistributions of source code must retain the above copyright */
16 /* notice, this list of conditions and the following disclaimer. */
17 /* Redistributions in binary form must reproduce the above copyright */
18 /* notice, this list of conditions and the following disclaimer in */
19 /* the documentation and/or other materials provided with the distribution. */
20 /* */
21 /* Neither the name of Rexx Language Association nor the names */
22 /* of its contributors may be used to endorse or promote products */
23 /* derived from this software without specific prior written permission. */
24 /* */
25 /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */
26 /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */
27 /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS */
28 /* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */
29 /* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */
30 /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED */
31 /* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, */
32 /* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY */
33 /* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING */
34 /* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */
35 /* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
36 /* */
37 /*----------------------------------------------------------------------------*/
38 
39 #ifndef ServiceMessage_HPP_INCLUDED
40 #define ServiceMessage_HPP_INCLUDED
41 
42 #include "rexx.h"
43 #include "ServiceException.hpp"
44 #include "SysCSStream.hpp"
45 #include "SysProcess.hpp"
46 
47 typedef enum
48 {
49  QueueWait // deferred because of queue wait issues.
50 
52 
53 /**
54  * Duplicate a C string using C++ new char[] to allocate the storage.
55  *
56  * @param oldString The string we're duplicating.
57  *
58  * @return The duplicated string.
59  */
60 inline char *dupString(const char *oldString)
61 {
62  char *newString = new char[strlen(oldString) + 1];
63  strcpy(newString, oldString);
64  return newString;
65 }
66 
67 // this port is assigned by IANA for the use of ooRexx, so
68 // in theory, we're safe to use this.
69 #define REXX_API_PORT 10010
70 
71 // a session identifier
73 
74 // definitions of server message targets
75 typedef enum
76 {
81 
83 
84 typedef enum
85 {
90 
91 typedef enum
92 {
93  // macro space operations
107 
108  // queue manager operations
124 
125  // registration manager operations
134 
135  // global API operations
141 
142 typedef enum
143 {
146 
147  // macro space results
161 
162  // queue manager results
176 
177  // registration manager results
184 
185  // API manager results
188 
190 
191 // message specific modifiers
192 typedef enum
193 {
198 
201  REXXAPI_VERSION = 100 // current Rexx api version.
203 
204 
206 {
207 public:
208  inline ServiceRegistrationData(const char *module, const char *proc, bool drop, const char *userPointer)
209  {
210  strncpy(moduleName, module, MAX_NAME_LENGTH);
211  strncpy(procedureName, proc, MAX_NAME_LENGTH);
212  dropAuthority = !drop ? DROP_ANY : OWNER_ONLY;
213  setUserData(userPointer);
214  entryPoint = 0;
215  }
216 
217  inline ServiceRegistrationData(const char *module)
218  {
219  if (module != NULL)
220  {
221  strncpy(moduleName, module, MAX_NAME_LENGTH);
222  }
223  else
224  {
225  strcpy(moduleName, "");
226  }
227  strcpy(procedureName, "");
229  setUserData(NULL);
230  entryPoint = 0;
231  }
232 
233  inline ServiceRegistrationData(REXXPFN entry, const char *userPointer)
234  {
235  strcpy(moduleName, "");
236  strcpy(procedureName, "");
237  entryPoint = (uintptr_t)entry;
239  setUserData(userPointer);
240  }
241 
242 
243  inline void setUserData(const char *userPointer)
244  {
245  // we have two bits of user data to copy
246  if (userPointer != NULL)
247  {
248  userData[0] = ((uintptr_t*)userPointer)[0];
249  userData[1] = ((uintptr_t*)userPointer)[1];
250  }
251  else
252  {
253  userData[0] = 0;
254  userData[1] = 0;
255  }
256  }
257 
258 
259  inline void retrieveUserData(char *userPointer)
260  {
261  // we have two bits of user data to copy
262  if (userPointer != NULL)
263  {
264  ((uintptr_t*)userPointer)[0] = userData[0];
265  ((uintptr_t*)userPointer)[1] = userData[1];
266  }
267  }
268 
269  enum
270  {
271  MAX_NAME_LENGTH = 256
272  };
273 
274  char moduleName[MAX_NAME_LENGTH]; // name of the library
275  char procedureName[MAX_NAME_LENGTH]; // the procedure within the library
276  size_t dropAuthority; // scope of drop authority
277  uintptr_t userData[2]; // saved user data
278  uintptr_t entryPoint; // explicit entry point address
279 };
280 
281 
283 {
284 public:
285  enum
286  {
287  NAMESIZE = 256
288  };
289 
290  ServiceMessage();
291  inline ~ServiceMessage() { ; }
292 
293  inline void setResult(ServiceReturn code)
294  {
295  result = code;
297  }
298 
299  inline void setExceptionInfo(ErrorCode error, const char *message)
300  {
302  errorCode = error;
303  strncpy(nameArg, message, NAMESIZE);
304  freeMessageData(); // make sure we don't send back any attached data
305  }
306 
308  {
310  errorCode = e->getErrorCode();
311  strncpy(nameArg, e->getMessage(), NAMESIZE);
312  freeMessageData(); // make sure we don't send back any attached data
313  }
314 
315  inline void clearExceptionInfo()
316  {
317  result = MESSAGE_OK;
319  }
320 
321  inline void raiseServerError()
322  {
323  if (errorCode != NO_ERROR_CODE)
324  {
325  // an error condition happened on the other side, raise this as an exception.
326  throw new ServiceException(errorCode, nameArg);
327  }
328  }
329 
330  // makes a local copy of the string data stored in the argument name
331  inline char *getArgumentName()
332  {
333  return dupString(nameArg);
334  }
335 
336  inline void clearMessageData()
337  {
338  messageData = NULL;
339  messageDataLength = 0;
340  retainMessageData = false;
341  }
342 
343  inline void *getMessageData() { return messageData; }
344  inline size_t getMessageDataLength() { return messageDataLength; }
345 
346  inline void transferMessageData(RXSTRING &data)
347  {
348  // if no data provided, don't copy anything.
349  if (messageDataLength == 0)
350  {
351  messageDataLength = 0;
352  }
353  // if provided a buffer, then use it if large enough
354  else if (data.strptr != NULL && messageDataLength < data.strlength)
355  {
356  memcpy(data.strptr, messageData, messageDataLength);
358  // we need to free our copy
359  freeMessageData();
360  }
361  else
362  {
364  // we've given up ownership of this data, so clear out the
365  // pointers so we don't try to free
367  }
368  }
369 
370 
371  inline void setMessageData(void *data, size_t length)
372  {
373  freeMessageData(); // make sure any existing data is cleared.
374  messageData = data;
375  messageDataLength = length;
376  // make sure we only set a pointer if this is non-zero, else
377  // we end up transmitting a stale pointer to the other side of the connection.
378  if (length == 0)
379  {
380  messageData = NULL;
381  }
382  // this is not freeable data
383  retainMessageData = true;
384  }
385 
386 
387  inline void *allocateMessageData(size_t length)
388  {
390  messageDataLength = length;
391  retainMessageData = false;
392  return messageData;
393  }
394 
395  inline void freeMessageData()
396  {
397  if (messageData != NULL && !retainMessageData)
398  {
399  // this is real message information
402  }
403  }
404 
405  void readMessage(SysServerConnection *server);
406  void writeResult(SysServerConnection *server);
407  void writeMessage(SysClientStream &server);
408  void readResult(SysClientStream &server);
409 
410  static void *allocateResultMemory(size_t length);
411  static void releaseResultMemory(void *mem);
412 
413  ServerManager messageTarget; // end receiver of the message
414  ServerOperation operation; // operation to be performed
415  SessionID session; // the sender of the message
416  uintptr_t parameter1; // first parameter passed
417  uintptr_t parameter2; // second parameter passed
418  uintptr_t parameter3; // the third parameter passed
419  uintptr_t parameter4; // the fourth parameter passed
420  uintptr_t parameter5; // the fifth parameter passed
421  ServiceReturn result; // return result
422  ErrorCode errorCode; // error code from other side
423  void *messageData; // extra data attached to the message.
424  size_t messageDataLength; // size of the extra data.
425  bool retainMessageData; // indicates the server should not release result memory.
426  char nameArg[NAMESIZE]; // buffer for name arguments
427  char userid[MAX_USERID_LENGTH]; // name of the user
428 };
429 
430 #endif
@ NO_ERROR_CODE
RegistrationType
@ ExitAPI
@ SubcomAPI
@ FunctionAPI
char * dupString(const char *oldString)
ServiceReturn
@ QUEUE_IN_USE
@ QUEUE_NO_DATA_AVAILABLE
@ CALLBACK_EXISTS
@ QUEUE_CREATED
@ MACRO_DOES_NOT_EXIST
@ NO_MORE_MACROS
@ SERVER_ERROR
@ DUPLICATE_QUEUE_NAME
@ MACRO_SPACE_CLEARED
@ QUEUE_DELETED
@ MACRO_RETURNED
@ QUEUE_EXISTS
@ CALLBACK_NOT_FOUND
@ MACRO_SEND_NEXT_BUFFER
@ QUEUE_SEND_NEXT
@ POSTORDER_MACRO
@ QUEUE_DOES_NOT_EXIST
@ MACRO_ADDED
@ QUEUE_EMPTY
@ QUEUE_ITEM_PULLED
@ MACRO_ORDER_CHANGED
@ PREORDER_MACRO
@ CALLBACK_DROPPED
@ DROP_NOT_AUTHORIZED
@ MACRO_REMOVED
@ SERVER_STOPPED
@ MESSAGE_OK
@ MACRO_IMAGE_RETURNED
@ QUEUE_PULL_NEXT
@ MACRO_RETRIEVE_NEXT_BUFFER
@ DUPLICATE_REGISTRATION
@ QUEUE_OK
@ REGISTRATION_COMPLETED
@ SERVER_NOT_STOPPABLE
@ QUEUE_ITEM_ADDED
@ MACRO_ITERATION_STARTED
uintptr_t SessionID
ServerOperation
@ CLEAR_MACRO_SPACE
@ GET_SESSION_QUEUE_COUNT
@ NEST_SESSION_QUEUE
@ CREATE_NAMED_QUEUE
@ QUERY_MACRO
@ CONNECTION_ACTIVE
@ REGISTER_LOAD_LIBRARY
@ NEXT_MACRO_DESCRIPTOR
@ REGISTER_QUERY_LIBRARY
@ MACRO_SEND_NEXT
@ CLEAR_SESSION_QUEUE
@ REGISTER_DROP_LIBRARY
@ REGISTER_ENTRYPOINT
@ GET_MACRO_DESCRIPTOR
@ DELETE_NAMED_QUEUE
@ GET_MACRO_IMAGE
@ ADD_TO_NAMED_QUEUE
@ PROCESS_CLEANUP
@ REGISTER_DROP
@ REGISTER_LIBRARY
@ REMOVE_MACRO
@ SHUTDOWN_SERVER
@ PULL_FROM_SESSION_QUEUE
@ ADD_TO_SESSION_QUEUE
@ QUERY_NAMED_QUEUE
@ OPEN_NAMED_QUEUE
@ REGISTER_QUERY
@ REORDER_MACRO
@ UPDATE_CALLBACK
@ NEXT_MACRO_IMAGE
@ ADD_MACRO
@ PULL_FROM_NAMED_QUEUE
@ CLEAR_NAMED_QUEUE
@ CLOSE_CONNECTION
@ DELETE_SESSION_QUEUE
@ GET_NAMED_QUEUE_COUNT
@ ITERATE_MACRO_DESCRIPTORS
@ ITERATE_MACROS
@ CREATE_SESSION_QUEUE
@ MACRO_RETRIEVE_NEXT
ServerManager
@ QueueManager
@ RegistrationManager
@ APIManager
@ MacroSpaceManager
ExecutionDeferral
@ QueueWait
ServiceMessageParameters
@ QUEUE_WAIT_FOR_DATA
@ DROP_ANY
@ OWNER_ONLY
@ REXXAPI_VERSION
@ QUEUE_FIFO
@ QUEUE_NO_WAIT
@ QUEUE_LIFO
const char * getMessage()
ErrorCode getErrorCode()
void setExceptionInfo(ErrorCode error, const char *message)
size_t getMessageDataLength()
ServerManager messageTarget
char * getArgumentName()
void readResult(SysClientStream &server)
void readMessage(SysServerConnection *server)
uintptr_t parameter3
ServerOperation operation
void setMessageData(void *data, size_t length)
char userid[MAX_USERID_LENGTH]
char nameArg[NAMESIZE]
static void releaseResultMemory(void *mem)
void writeResult(SysServerConnection *server)
void * allocateMessageData(size_t length)
void transferMessageData(RXSTRING &data)
uintptr_t parameter1
uintptr_t parameter4
void setResult(ServiceReturn code)
void * getMessageData()
static void * allocateResultMemory(size_t length)
void writeMessage(SysClientStream &server)
uintptr_t parameter5
void setExceptionInfo(ServiceException *e)
ServiceReturn result
uintptr_t parameter2
ServiceRegistrationData(const char *module)
void setUserData(const char *userPointer)
char procedureName[MAX_NAME_LENGTH]
ServiceRegistrationData(const char *module, const char *proc, bool drop, const char *userPointer)
void retrieveUserData(char *userPointer)
ServiceRegistrationData(REXXPFN entry, const char *userPointer)
char moduleName[MAX_NAME_LENGTH]
#define MAKERXSTRING(r, p, l)
Definition: rexx.h:182
size_t strlength
Definition: rexx.h:157
char * strptr
Definition: rexx.h:158
@ MAX_USERID_LENGTH
void * REXXPFN
UINT_PTR uintptr_t