MacroSpaceManager.cpp
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 #include "MacroSpaceManager.hpp"
40 #include "Utilities.hpp"
41 
42 /**
43  * Create a macro item entry.
44  *
45  * @param n The name of the macro.
46  * @param data The image data for the macro.
47  * @param l The size of the image data.
48  * @param p The search position.
49  */
50 MacroItem::MacroItem(const char *n, const char *data, size_t l, size_t p)
51 {
52  next = NULL;
53  name = dupString(n);
54  imageBuffer = data;
55  imageSize = l;
56  searchPosition = p;
57 }
58 
59 /**
60  * Update the image data for a macro item.
61  *
62  * @param data The new image data.
63  * @param l The length of the new data.
64  * @param p The position data.
65  */
66 void MacroItem::update(const char *data, size_t l, size_t p)
67 {
69  imageBuffer = data;
70  imageSize = l;
71  searchPosition = p;
72 }
73 
74 
75 /**
76  * Clear the macro table.
77  */
79 {
80  iterator = NULL; // this invalidates any iterator we may have
81  MacroItem *current = macros;
82  while (current != NULL)
83  {
84  MacroItem *next = current->next;
85  delete current;
86  current = next;
87  }
88  macros = NULL; // clear the anchor
89 }
90 
91 
92 /**
93  * locate a named macro item.
94  *
95  * @param name The required macro item.
96  *
97  * @return The located macro item entry.
98  */
99 MacroItem *MacroTable::locate(const char *name)
100 {
101  MacroItem *current = macros; // start the search
102  MacroItem *previous = NULL; // no previous one
103 
104  while (current != NULL) /* while more macros */
105  {
106  // find the one we want?
107  if (Utilities::strCaselessCompare(name, current->name) == 0)
108  {
109  // move this to the front so we find it quickly
110  reorder(current, previous);
111  return current;
112  }
113  previous = current; /* remember this block */
114  current = current->next; /* step to the next block */
115  }
116  return NULL;
117 }
118 
119 /**
120  * locate and remove a named macro space
121  *
122  * @param name The name of the target macro.
123  *
124  * @return The removed table item, or NULL if this is not found.
125  */
126 MacroItem *MacroTable::remove(const char *name)
127 {
128  MacroItem *current = macros; // start the search
129  MacroItem *previous = NULL; // no previous one
130 
131  while (current != NULL) /* while more macros */
132  {
133  iterator = NULL; // this invalidates any iterator we may have
134  // find the one we want?
135  if (Utilities::strCaselessCompare(name, current->name) == 0)
136  {
137  // move this to the front so we find it quickly
138  removeMacro(current, previous);
139  return current;
140  }
141  previous = current; /* remember this block */
142  current = current->next; /* step to the next block */
143  }
144  return NULL;
145 }
146 
147 
148 // Add an item to the macro space. The message arguments have the
149 // following meanings:
150 //
151 // parameter1 -- length of the macro image
152 // parameter2 -- order flag
153 // nameArg -- ASCII-Z name of the macro
155 {
156  MacroItem *item = macros.locate(message.nameArg);
157  // already exists?
158  if (item == NULL)
159  {
160  item = new MacroItem(message.nameArg, (const char *)message.getMessageData(), message.getMessageDataLength(), message.parameter2);
161  macros.add(item);
162  }
163  else
164  {
165  item->update((const char *)message.getMessageData(), message.getMessageDataLength(), message.parameter2);
166  }
167  // we're keeping the storage here, so detach it from the message.
168  message.clearMessageData();
169  message.setResult(MACRO_ADDED);
170 }
171 
172 
173 // Remove an item from the macro space. The message arguments have the
174 // following meanings:
175 //
176 // nameArg -- ASCII-Z name of the macro
178 {
179  MacroItem *item = macros.locate(message.nameArg);
180  // already exists?
181  if (item != NULL)
182  {
183  macros.remove(message.nameArg);
184  message.setResult(MACRO_REMOVED);
185  }
186  else
187  {
189  return;
190  }
191 }
192 
193 // Remove all macros from the macro space.
195 {
196  macros.clear();
198 }
199 
200 
201 // Query an item from the macro space. The message arguments have the
202 // following meanings:
203 //
204 // nameArg -- ASCII-Z name of the macro
206 {
207  MacroItem *item = macros.locate(message.nameArg);
208  // already exists?
209  if (item != NULL)
210  {
211  message.setResult((ServiceReturn)item->searchPosition);
212  }
213  else
214  {
216  }
217 }
218 
219 
220 // Change the order of a macro space item. The message arguments have the
221 // following meanings:
222 //
223 // parameter1 -- postorder or preorder flag
224 // nameArg -- ASCII-Z name of the macro
226 {
227  MacroItem *item = macros.locate(message.nameArg);
228  // already exists?
229  if (item != NULL)
230  {
231  item->searchPosition = message.parameter1;
233  }
234  else
235  {
237  }
238 }
239 
240 
241 // Start iteration through the macro list. The message arguments have the
242 // following meanings:
243 //
244 // parameter1 -- used to return count of macros
246 {
248  message.parameter1 = macros.macroCount();
250 }
251 
252 
253 // Get next macro descriptor from iterator. The message arguments are
254 // empty, but the definition is returned in the message.
255 //
256 // parameter1 -- size of the macro image
257 // parameter2 -- postorder/preorder flag
258 // nameArg -- ASCII-Z name of the macro
260 {
261  MacroItem *item = macros.getNext();
262  // no item, we're done
263  if (item == NULL)
264  {
265  // this is an end indication
266  message.setResult(NO_MORE_MACROS);
267  }
268  else
269  {
270  message.parameter1 = item->imageSize;
271  message.parameter2 = item->searchPosition;
272  strcpy(message.nameArg, item->name);
273  // this is an end indication
274  message.setResult(MACRO_RETURNED);
275  }
276 }
277 
278 // Get next macro descriptor from iterator. The message arguments are
279 // empty, but the definition is returned in the message.
280 //
281 // parameter1 -- size of the macro image
282 // parameter2 -- postorder/preorder flag
283 // nameArg -- ASCII-Z name of the macro
285 {
286  MacroItem *item = macros.getNext();
287  // no item, we're done
288  if (item == NULL)
289  {
290  // this is an end indication
291  message.setResult(NO_MORE_MACROS);
292  }
293  else
294  {
295  message.parameter1 = item->imageSize;
296  message.parameter2 = item->searchPosition;
297  strcpy(message.nameArg, item->name);
298 
299  // get the macro data
300  message.setMessageData((void *)item->imageBuffer, item->imageSize);
301  // this data is retained after the result send.
302  message.retainMessageData = true;
303  }
304 }
305 
306 
307 // Get the descriptor for a macro. The message arguments is
308 // just the name of the macro.
309 //
310 // parameter1 -- size of the macro image
311 // parameter2 -- postorder/preorder flag
312 // nameArg -- ASCII-Z name of the macro
314 {
315  MacroItem *item = macros.locate(message.nameArg);
316  // no item, we're done
317  if (item == NULL)
318  {
319  // this is an end indication
321  }
322  else
323  {
324  // copy the specifics
325  message.parameter1 = item->imageSize;
326  message.parameter2 = item->searchPosition;
327  // this is an end indication
328  message.setResult(MACRO_RETURNED);
329  }
330 }
331 
332 
333 // Get the full descriptor for a macro, including the image data.
334 // The message arguments is
335 // just the name of the macro.
336 //
337 // parameter1 -- size of the macro image
338 // parameter2 -- postorder/preorder flag
339 // nameArg -- ASCII-Z name of the macro
341 {
342  MacroItem *item = macros.locate(message.nameArg);
343  // no item, we're done
344  if (item == NULL)
345  {
346  // this is an end indication
348  }
349  else
350  {
351  // copy the specifics
352  message.parameter1 = item->imageSize;
353  message.parameter2 = item->searchPosition;
354  // get the macro data
355  message.setMessageData((void *)item->imageBuffer, item->imageSize);
356  // this data is retained after the result send.
357  message.retainMessageData = true;
358  }
359 }
360 
361 
362 /**
363  * Dispatch an inbound operation to this service manager.
364  *
365  * @param message The message to process.
366  */
368 {
369  switch (message.operation)
370  {
371  case ADD_MACRO:
372  addMacro(message);
373  break;
375  iterateMacros(message);
376  break;
378  nextDescriptor(message);
379  break;
380  case GET_MACRO_IMAGE:
381  getImage(message);
382  break;
384  getDescriptor(message);
385  break;
386  case CLEAR_MACRO_SPACE:
387  clear(message);
388  break;
389  case REMOVE_MACRO:
390  deleteMacro(message);
391  break;
392  case QUERY_MACRO:
393  queryMacro(message);
394  break;
395  case REORDER_MACRO:
396  reorderMacro(message);
397  break;
398  case ITERATE_MACROS:
399  iterateMacros(message);
400  break;
401  case NEXT_MACRO_IMAGE:
402  nextImage(message);
403  break;
404  default:
405  message.setExceptionInfo(SERVER_FAILURE, "Invalid macro space manager operation");
406  break;
407  }
408 }
409 
411 {
412  // this is a NOP for the macro space
413 }
@ SERVER_FAILURE
char * dupString(const char *oldString)
ServiceReturn
@ MACRO_DOES_NOT_EXIST
@ NO_MORE_MACROS
@ MACRO_SPACE_CLEARED
@ MACRO_RETURNED
@ MACRO_ADDED
@ MACRO_ORDER_CHANGED
@ MACRO_REMOVED
@ MACRO_ITERATION_STARTED
uintptr_t SessionID
@ CLEAR_MACRO_SPACE
@ QUERY_MACRO
@ NEXT_MACRO_DESCRIPTOR
@ GET_MACRO_DESCRIPTOR
@ GET_MACRO_IMAGE
@ REMOVE_MACRO
@ REORDER_MACRO
@ NEXT_MACRO_IMAGE
@ ADD_MACRO
@ ITERATE_MACRO_DESCRIPTORS
@ ITERATE_MACROS
MacroItem(const char *n, const char *, size_t l, size_t p)
MacroItem * next
const char * imageBuffer
void update(const char *, size_t l, size_t p)
const char * name
size_t searchPosition
MacroItem * remove(const char *name)
void removeMacro(MacroItem *current, MacroItem *previous)
MacroItem * getNext()
MacroItem * macros
MacroItem * iterator
void reorder(MacroItem *current, MacroItem *previous)
void add(MacroItem *macro)
MacroItem * locate(const char *name)
void iterateMacros(ServiceMessage &message)
void clear(ServiceMessage &message)
void getDescriptor(ServiceMessage &message)
void queryMacro(ServiceMessage &message)
void getImage(ServiceMessage &message)
void nextDescriptor(ServiceMessage &message)
void nextImage(ServiceMessage &message)
void cleanupProcessResources(SessionID session)
void reorderMacro(ServiceMessage &message)
void dispatch(ServiceMessage &message)
void addMacro(ServiceMessage &message)
void deleteMacro(ServiceMessage &message)
void setExceptionInfo(ErrorCode error, const char *message)
size_t getMessageDataLength()
ServerOperation operation
void setMessageData(void *data, size_t length)
char nameArg[NAMESIZE]
static void releaseResultMemory(void *mem)
uintptr_t parameter1
void setResult(ServiceReturn code)
void * getMessageData()
uintptr_t parameter2
static int strCaselessCompare(const char *opt1, const char *opt2)
Definition: Utilities.cpp:82