labcomm2006_private.h 16.3 KB
Newer Older
1
/*
Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
2
  labcomm2006_private.h -- semi private declarations for handling encoding and 
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
                       decoding of labcomm samples.

  Copyright 2006-2013 Anders Blomdell <anders.blomdell@control.lth.se>

  This file is part of LabComm.

  LabComm is free software: you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation, either version 3 of the License, or
  (at your option) any later version.

  LabComm is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

23
24
#ifndef __LABCOMM2006_PRIVATE_H__
#define __LABCOMM2006_PRIVATE_H__
25
26
27
28
29
30

#ifdef LABCOMM_COMPAT
  #include LABCOMM_COMPAT
#else
  #include <endian.h>
  #include <stdio.h>
Tommy Olofsson's avatar
Tommy Olofsson committed
31
32
  #include <stdint.h>
  #include <unistd.h>
33
34
35
36
#endif

//#include <stdlib.h>
#include <string.h>
Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
37
#include "labcomm2006.h"
38
39
40
41
42
43
44

/*
 * Predeclared aggregate type indices
 */
#define LABCOMM_SAMPLE   0x02
#define LABCOMM_ARRAY    0x10
#define LABCOMM_STRUCT   0x11
45
#define LABCOMM_USER     0x40   /* ..0xffffffff */
46
47

/*
Anders Blomdell's avatar
Anders Blomdell committed
48
 * Predefined primitive type indices
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
 */
#define LABCOMM_BOOLEAN  0x20 
#define LABCOMM_BYTE     0x21
#define LABCOMM_SHORT    0x22
#define LABCOMM_INT      0x23
#define LABCOMM_LONG     0x24
#define LABCOMM_FLOAT    0x25
#define LABCOMM_DOUBLE   0x26
#define LABCOMM_STRING   0x27

/*
 * Macro to automagically call constructors in modules compiled 
 * with the labcomm compiler. If __attribute__((constructor)) is
 * not supported, these calls has to be done first in main program.
 */
#ifndef LABCOMM_CONSTRUCTOR
#define LABCOMM_CONSTRUCTOR __attribute__((constructor))
#endif

/*
 * Semi private dynamic memory declarations
 */

Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
72
73
74
struct labcomm2006_memory {
  void *(*alloc)(struct labcomm2006_memory *m, int lifetime, size_t size);
  void *(*realloc)(struct labcomm2006_memory *m, int lifetime, 
75
		   void *ptr, size_t size);
Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
76
  void (*free)(struct labcomm2006_memory *m, int lifetime, void *ptr);
77
78
79
80
81
82
  void *context;
};

/*
 * Semi private decoder declarations
 */
Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
83
typedef void (*labcomm2006_handler_function)(void *value, void *context);
84

Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
85
86
87
typedef void (*labcomm2006_decoder_function)(
  struct labcomm2006_reader *r,
  labcomm2006_handler_function handler,
88
89
  void *context);

Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
90
struct labcomm2006_reader_action_context;
91

Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
92
93
struct labcomm2006_reader_action {
  /* 'alloc' is called at the first invocation of 'labcomm2006_decoder_decode_one' 
94
     on the decoder containing the reader.
95
96
97
98
99

     Returned value:
       >  0    Number of bytes allocated for buffering
       <= 0    Error
  */
Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
100
  int (*alloc)(struct labcomm2006_reader *r, 
101
	       struct labcomm2006_reader_action_context *action_context);
102
103
104
105
106
107
108
  /* 'free' returns the resources claimed by 'alloc' and might have other
     reader specific side-effects as well.

     Returned value:
       == 0    Success
       != 0    Error
  */
Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
109
110
  int (*free)(struct labcomm2006_reader *r, 
	      struct labcomm2006_reader_action_context *action_context);
111
112
113
114
115
116
117
118
  /* 'start' is called at the following instances:
     1. When a sample is registered 
          (local_index != 0, remote_index == 0, value == NULL)
     2. When a sample definition is received 
          (local_index != 0, remote_index != 0, value == NULL)
     3. When a sample is received
          (local_index != 0, remote_index != 0, value != NULL)
   */
Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
119
120
  int (*start)(struct labcomm2006_reader *r, 
	       struct labcomm2006_reader_action_context *action_context,
121
	       int local_index, int remote_index,
Anders Blomdell's avatar
Anders Blomdell committed
122
	       const struct labcomm2006_signature *signature,
123
	       void *value);
Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
124
125
126
127
128
129
  int (*end)(struct labcomm2006_reader *r, 
	     struct labcomm2006_reader_action_context *action_context);
  int (*fill)(struct labcomm2006_reader *r, 
	      struct labcomm2006_reader_action_context *action_context);
  int (*ioctl)(struct labcomm2006_reader *r, 
	       struct labcomm2006_reader_action_context *action_context,
130
	       int local_index, int remote_index,
Anders Blomdell's avatar
Anders Blomdell committed
131
	       const struct labcomm2006_signature *signature, 
132
133
134
	       uint32_t ioctl_action, va_list args);
};

Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
135
136
137
struct labcomm2006_reader_action_context {
  struct labcomm2006_reader_action_context *next;
  const struct labcomm2006_reader_action *action;
138
139
140
  void *context;  
};

Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
141
142
143
144
145
struct labcomm2006_reader {
  struct labcomm2006_reader_action_context *action_context;
  struct labcomm2006_memory *memory;
  /* The following fields are initialized by labcomm2006_decoder_new */
  struct labcomm2006_decoder *decoder;
146
147
148
149
150
151
152
  unsigned char *data;
  int data_size;
  int count;
  int pos;
  int error;
};

Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
153
int labcomm2006_reader_alloc(struct labcomm2006_reader *r, 
Anders Blomdell's avatar
Anders Blomdell committed
154
                             struct labcomm2006_reader_action_context *action_context);
Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
155
int labcomm2006_reader_free(struct labcomm2006_reader *r, 
Anders Blomdell's avatar
Anders Blomdell committed
156
                            struct labcomm2006_reader_action_context *action_context);
Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
157
int labcomm2006_reader_start(struct labcomm2006_reader *r, 
Anders Blomdell's avatar
Anders Blomdell committed
158
159
160
161
                             struct labcomm2006_reader_action_context *action_context,
                             int local_index, int remote_index,
                             const struct labcomm2006_signature *signature,
                             void *value);
Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
162
int labcomm2006_reader_end(struct labcomm2006_reader *r, 
Anders Blomdell's avatar
Anders Blomdell committed
163
                           struct labcomm2006_reader_action_context *action_context);
Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
164
int labcomm2006_reader_fill(struct labcomm2006_reader *r, 
Anders Blomdell's avatar
Anders Blomdell committed
165
                            struct labcomm2006_reader_action_context *action_context);
Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
166
int labcomm2006_reader_ioctl(struct labcomm2006_reader *r, 
Anders Blomdell's avatar
Anders Blomdell committed
167
168
169
170
                             struct labcomm2006_reader_action_context *action_context,
                             int local_index, int remote_index,
                             const struct labcomm2006_signature *signature, 
                             uint32_t ioctl_action, va_list args);
171
172
173

/*
 * Non typesafe registration function to be called from
Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
174
 * generated labcomm2006_decoder_register_* functions.
175
 */
Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
176
177
int labcomm2006_internal_decoder_register(
  struct labcomm2006_decoder *d, 
Anders Blomdell's avatar
Anders Blomdell committed
178
  const struct labcomm2006_signature *s, 
Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
179
180
  labcomm2006_decoder_function decoder,
  labcomm2006_handler_function handler,
181
182
  void *context);

Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
183
int labcomm2006_internal_decoder_ioctl(struct labcomm2006_decoder *decoder, 
Anders Blomdell's avatar
Anders Blomdell committed
184
185
                                       const struct labcomm2006_signature *signature,
                                       uint32_t ioctl_action, va_list args);
186
187
188
189

#if __BYTE_ORDER == __LITTLE_ENDIAN

#define LABCOMM_DECODE(name, type)					\
Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
190
  static inline type labcomm2006_read_##name(struct labcomm2006_reader *r) {	\
191
192
193
    type result; int i;							\
    for (i = sizeof(type) - 1 ; i >= 0 ; i--) {				\
      if (r->pos >= r->count) {						\
Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
194
	labcomm2006_reader_fill(r, r->action_context);			\
195
196
197
198
199
200
201
202
203
204
205
206
207
	if (r->error < 0) {						\
	  return 0;							\
	}								\
      }									\
      ((unsigned char*)(&result))[i] = r->data[r->pos];			\
      r->pos++;								\
    }									\
    return result;							\
  }

#else

#define LABCOMM_DECODE(name, type)					\
Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
208
  static inline type labcomm2006_read_##name(struct labcomm2006_reader *r) {	\
209
210
211
    type result; int i;							\
    for (i = 0 ; i < sizeof(type) ; i++) {				\
      if (r->pos >= r->count) {						\
Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
212
	labcomm2006_reader_fille(r, r->action_context);			\
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
	if (r->error < 0) {						\
	  return 0;							\
	}								\
      }									\
      ((unsigned char*)(&result))[i] = r->data[r->pos];			\
      r->pos++;								\
    }									\
    return result;							\
  }

#endif

LABCOMM_DECODE(boolean, unsigned char)
LABCOMM_DECODE(byte, unsigned char)
LABCOMM_DECODE(short, short)
LABCOMM_DECODE(int, int)
LABCOMM_DECODE(long, long long)
LABCOMM_DECODE(float, float)
LABCOMM_DECODE(double, double)

Anders Blomdell's avatar
Anders Blomdell committed
233
// compatibility with 2014 version
Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
234
#define labcomm2006_read_packed32 labcomm2006_read_int
235

Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
236
static inline char *labcomm2006_read_string(struct labcomm2006_reader *r)
237
238
239
240
{
  char *result = NULL;
  int length, pos; 
  
Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
241
242
  length = labcomm2006_read_packed32(r);
  result = labcomm2006_memory_alloc(r->memory, 1, length + 1);
Anders Blomdell's avatar
Anders Blomdell committed
243
244
245
246
247
  if (!result) {
    labcomm2006_on_error_fprintf(LABCOMM_ERROR_MEMORY, 4, "%d byte at %s:%d",
                     length+1, __FUNCTION__, __LINE__);
    return NULL;
  }
248
249
  for (pos = 0 ; pos < length ; pos++) {
    if (r->pos >= r->count) {	
Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
250
      labcomm2006_reader_fill(r, r->action_context);
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
      if (r->error < 0) {
	goto out;
      }
    }
    result[pos] = r->data[r->pos];
    r->pos++;
  }
out:
  result[pos] = 0;
  return result;
}

/*
 * Semi private encoder declarations
 */
Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
266
typedef int (*labcomm2006_encoder_function)(struct labcomm2006_writer *,
Anders Blomdell's avatar
Anders Blomdell committed
267
                                            void *value);
Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
268
269
270
271
struct labcomm2006_writer_action_context;

struct labcomm2006_writer_action {
  int (*alloc)(struct labcomm2006_writer *w, 
272
	       struct labcomm2006_writer_action_context *action_context);
Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
273
274
  int (*free)(struct labcomm2006_writer *w, 
	      struct labcomm2006_writer_action_context *action_context);
275
276
277
278
279
280
281
282
283
  /* 'start' is called right before a sample is to be sent. In the 
     case of a sample or typedef, 'value' == NULL.

     Returned value:
       == 0          Success -> continue sending the sample
       == -EALREADY  Success -> silently skip sending the sample,
                                'end' will not be called
       < 0           Error
   */
Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
284
285
  int (*start)(struct labcomm2006_writer *w, 
	       struct labcomm2006_writer_action_context *action_context,
Anders Blomdell's avatar
Anders Blomdell committed
286
	       int index, const struct labcomm2006_signature *signature,
287
	       void *value);
Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
288
289
290
291
292
293
  int (*end)(struct labcomm2006_writer *w, 
	     struct labcomm2006_writer_action_context *action_context);
  int (*flush)(struct labcomm2006_writer *w, 
	       struct labcomm2006_writer_action_context *action_context); 
  int (*ioctl)(struct labcomm2006_writer *w, 
	       struct labcomm2006_writer_action_context *action_context, 
Anders Blomdell's avatar
Anders Blomdell committed
294
	       int index, const struct labcomm2006_signature *signature, 
295
296
297
	       uint32_t ioctl_action, va_list args);
};

Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
298
299
300
struct labcomm2006_writer_action_context {
  struct labcomm2006_writer_action_context *next;
  const struct labcomm2006_writer_action *action;
301
302
303
  void *context;  
};

Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
304
305
306
307
308
struct labcomm2006_writer {
  struct labcomm2006_writer_action_context *action_context;
  struct labcomm2006_memory *memory;
  /* The following fields are initialized by labcomm2006_encoder_new */
  struct labcomm2006_encoder *encoder;
309
310
311
312
313
314
315
  unsigned char *data;
  int data_size;
  int count;
  int pos;
  int error;
};

Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
316
int labcomm2006_writer_alloc(struct labcomm2006_writer *w, 
317
			 struct labcomm2006_writer_action_context *action_context);
Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
318
319
320
321
int labcomm2006_writer_free(struct labcomm2006_writer *w, 
			struct labcomm2006_writer_action_context *action_context);
int labcomm2006_writer_start(struct labcomm2006_writer *w, 
			 struct labcomm2006_writer_action_context *action_context,
Anders Blomdell's avatar
Anders Blomdell committed
322
			 int index, const struct labcomm2006_signature *signature,
323
			 void *value);
Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
324
325
326
327
328
329
int labcomm2006_writer_end(struct labcomm2006_writer *w, 
		       struct labcomm2006_writer_action_context *action_context);
int labcomm2006_writer_flush(struct labcomm2006_writer *w, 
			 struct labcomm2006_writer_action_context *action_context); 
int labcomm2006_writer_ioctl(struct labcomm2006_writer *w, 
			 struct labcomm2006_writer_action_context *action_context, 
Anders Blomdell's avatar
Anders Blomdell committed
330
			 int index, const struct labcomm2006_signature *signature, 
331
332
			 uint32_t ioctl_action, va_list args);

Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
333
334
int labcomm2006_internal_encoder_register(
  struct labcomm2006_encoder *encoder, 
Anders Blomdell's avatar
Anders Blomdell committed
335
  const struct labcomm2006_signature *signature, 
Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
336
  labcomm2006_encoder_function encode);
337

Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
338
339
int labcomm2006_internal_encode(
  struct labcomm2006_encoder *encoder, 
Anders Blomdell's avatar
Anders Blomdell committed
340
  const struct labcomm2006_signature *signature, 
Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
341
  labcomm2006_encoder_function encode,
342
343
  void *value);

Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
344
int labcomm2006_internal_encoder_ioctl(struct labcomm2006_encoder *encoder, 
Anders Blomdell's avatar
Anders Blomdell committed
345
346
                                       const struct labcomm2006_signature *signature,
                                       uint32_t ioctl_action, va_list args);
347

Anders Blomdell's avatar
Anders Blomdell committed
348
int labcomm2006_internal_sizeof(const struct labcomm2006_signature *signature,
Anders Blomdell's avatar
Anders Blomdell committed
349
350
                                void *v);

351
352
353
#if __BYTE_ORDER == __LITTLE_ENDIAN

#define LABCOMM_ENCODE(name, type)					\
Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
354
  static inline int labcomm2006_write_##name(struct labcomm2006_writer *w, type data) { \
355
356
357
358
    int i;								\
    for (i = sizeof(type) - 1 ; i >= 0 ; i--) {				\
      if (w->pos >= w->count) { /*buffer is full*/			\
        int err;							\
Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
359
	err = labcomm2006_writer_flush(w, w->action_context);		\
360
361
362
363
364
365
366
367
368
369
370
	if (err != 0) { return err; }					\
      }									\
      w->data[w->pos] = ((unsigned char*)(&data))[i];			\
      w->pos++;								\
    }									\
    return 0;								\
  }

#else

#define LABCOMM_ENCODE(name, type)					\
Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
371
  static inline int labcomm2006_write_##name(struct labcomm2006_writer *w, type data) { \
372
373
374
375
    int i;								\
    for (i = 0 ; i < sizeof(type) ; i++) {				\
      if (w->pos >= w->count) {						\
        int err;							\
Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
376
	err = labcomm2006_writer_flush(w, w->action_context);		\
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
	if (err != 0) { return err; }					\
      }									\
      w->data[w->pos] = ((unsigned char*)(&data))[i];			\
      w->pos++;								\
    }									\
    return 0;								\
  }

#endif

LABCOMM_ENCODE(boolean, unsigned char)
LABCOMM_ENCODE(byte, unsigned char)
LABCOMM_ENCODE(short, short)
LABCOMM_ENCODE(int, int)
LABCOMM_ENCODE(long, long long)
LABCOMM_ENCODE(float, float)
LABCOMM_ENCODE(double, double)

Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
395
#define labcomm2006_write_packed32 labcomm2006_write_int
396
397

#if 0
Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
398
static inline int labcomm2006_write_packed32(struct labcomm2006_writer *w, 
399
400
401
402
403
404
405
406
407
408
409
					 unsigned int data)
{
  unsigned char tmp[5];
  int i;
  
  for (i = 0 ; i == 0 || data ; i++, data = (data >> 7)) {
    tmp[i] = data & 0x7f;
  }
  for (i = i - 1 ; i >= 0 ; i--) {
    if (w->pos >= w->count) {					
      int err;
Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
410
      err = labcomm2006_writer_flush(w, w->action_context);	
411
412
413
414
415
416
417
418
      if (err != 0) { return err; }
    }
    w->data[w->pos++] = tmp[i] | (i?0x80:0x00);
  }
  return 0;
}
#endif

Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
419
static inline int labcomm2006_write_string(struct labcomm2006_writer *w, char *s)
420
421
422
423
{
  int length, i, err; 

  length = strlen((char*)s);
Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
424
  err = labcomm2006_write_packed32(w, length);
425
426
427
428
  if (err != 0) { return err; }
  for (i = 0 ; i < length ; i++) {
    if (w->pos >= w->count) {	
      int err;
Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
429
      err = labcomm2006_writer_flush(w, w->action_context);	
430
431
432
433
434
435
436
437
438
      if (err != 0) { return err; }
    }
    w->data[w->pos] = s[i];
    w->pos++;
  }
  return 0;
}

/* Size of packed32 variable is 4 as we use int*/
Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
439
static inline int labcomm2006_size_packed32(unsigned int data)
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
{
  return 4;
}

/*
 * Macros for handling arrays indexed by signature index
 */

#define LABCOMM_SIGNATURE_ARRAY_DEF(name, kind)	\
  struct {					\
    int first;					\
    int last;					\
    kind *data;					\
  } name

#define LABCOMM_SIGNATURE_ARRAY_DEF_INIT(name, kind)		\
  LABCOMM_SIGNATURE_ARRAY_DEF(name, kind) = { 0, 0, NULL }

#define LABCOMM_SIGNATURE_ARRAY_INIT(name, kind)		\
  name.first = 0; name.last = 0; name.data = NULL;		\
  name.data = (kind *)name.data; /* typechecking no-op */

#define LABCOMM_SIGNATURE_ARRAY_FREE(memory, name, kind)	\
Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
463
  if (name.data) { labcomm2006_memory_free(memory, 0, name.data); }	\
464
465
  name.data = (kind *)NULL; /* typechecking */

Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
466
void *labcomm2006_signature_array_ref(struct labcomm2006_memory * memory,
Anders Blomdell's avatar
Anders Blomdell committed
467
468
                                      int *first, int *last, void **data,
                                      int size, int index);
469
470
471
472
473
474
475
476
477
/*
 * NB: the pointer returned by LABCOMM_SIGNATURE_ARRAY_REF might be
 *     rendered invalid by a subsequent call to LABCOMM_SIGNATURE_ARRAY_REF
 *     on the same SIGNATURE_ARRAY, so make sure not to use the result if 
 *     any other code might have made a call to LABCOMM_SIGNATURE_ARRAY_REF
 *     on the same SIGNATURE_ARRAY.
 */
#define LABCOMM_SIGNATURE_ARRAY_REF(memory, name, kind, index)		\
  (name.data = (kind *)name.data, /* typechecking no-op */		\
Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
478
   (kind *)(labcomm2006_signature_array_ref(memory,				\
479
480
481
482
483
484
485
486
487
					&name.first, &name.last,	\
					(void **)&name.data,		\
					sizeof(kind), index)))

#define LABCOMM_SIGNATURE_ARRAY_FOREACH(name, kind, var)		\
  for (name.data = (kind *)name.data, /* typechecking no-op */		\
       var = name.first ; var < name.last ; var++)

/* Give signature a free local index, this may not be used concurrently */
Sven Gestegård Robertz's avatar
Sven Gestegård Robertz committed
488
void labcomm2006_set_local_index(struct labcomm2006_signature *signature);
489
490

/* Get the local index for a signature */
Anders Blomdell's avatar
Anders Blomdell committed
491
int labcomm2006_get_local_index(const struct labcomm2006_signature *s);
492
493

#endif