make batchanalysis and textDump work
[lttv.git] / ltt / branches / poly / ltt / event.c
1 /* This file is part of the Linux Trace Toolkit viewer
2 * Copyright (C) 2003-2004 Xiangxiu Yang
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License Version 2 as
6 * published by the Free Software Foundation;
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
16 * MA 02111-1307, USA.
17 */
18
19 #ifdef HAVE_CONFIG_H
20 #include <config.h>
21 #endif
22
23 #include <stdio.h>
24 #include <string.h>
25 #include <stdlib.h>
26 #include <glib.h>
27
28 #include <asm/types.h>
29 #include <linux/byteorder/swab.h>
30
31 #include "parser.h"
32 #include <ltt/ltt.h>
33 #include "ltt-private.h"
34 #include <ltt/event.h>
35 #include <ltt/trace.h>
36 #include <ltt/ltt-types.h>
37
38 LttEvent *ltt_event_new()
39 {
40 return g_new(LttEvent, 1);
41 }
42
43 void ltt_event_destroy(LttEvent *event)
44 {
45 g_free(event);
46 }
47
48
49 #if 0
50 /* Use get_field_type_size instead */
51 /*****************************************************************************
52 *Function name
53 * ltt_event_refresh_fields : refresh fields of an event
54 *Input params
55 * offsetRoot : offset from the root
56 * offsetParent : offset from the parent
57 * fld : field
58 * evD : event data
59 * reverse_byte_order : 1 or 0
60 *Return value
61 * int : size of the field
62 ****************************************************************************/
63
64 int ltt_event_refresh_fields(int offsetRoot,int offsetParent,
65 LttField * fld, void *evD, gboolean reverse_byte_order)
66 {
67 int size, size1, element_number, i, offset1, offset2;
68 LttType * type = fld->field_type;
69
70 switch(type->type_class) {
71 case LTT_ARRAY:
72 element_number = (int) type->element_number;
73 if(fld->field_fixed == 0){// has string or sequence
74 size = 0;
75 for(i=0;i<element_number;i++){
76 size += ltt_event_refresh_fields(offsetRoot+size,size,
77 fld->child[0], evD+size, reverse_byte_order);
78 }
79 }else size = fld->field_size;
80 break;
81
82 case LTT_SEQUENCE:
83 size1 = fld->sequ_number_size;
84 element_number = getIntNumber(reverse_byte_order,size1,evD);
85 type->element_number = element_number;
86 if(fld->element_size > 0){
87 size = element_number * fld->element_size;
88 }else{//sequence has string or sequence
89 size = 0;
90 for(i=0;i<element_number;i++){
91 size += ltt_event_refresh_fields(offsetRoot+size+size1,size+size1,
92 fld->child[0], evD+size+size1, reverse_byte_order);
93 }
94 size += size1;
95 }
96 break;
97
98 case LTT_STRING:
99 size = strlen((gchar*)evD) + 1; //include end : '\0'
100 break;
101
102 case LTT_STRUCT:
103 element_number = (int) type->element_number;
104 if(fld->field_fixed == 0){
105 offset1 = offsetRoot;
106 offset2 = 0;
107 for(i=0;i<element_number;i++){
108 size=ltt_event_refresh_fields(offset1,offset2,
109 fld->child[i],evD+offset2, reverse_byte_order);
110 offset1 += size;
111 offset2 += size;
112 }
113 size = offset2;
114 }else size = fld->field_size;
115 break;
116
117 case LTT_UNION:
118 size = fld->field_size;
119 break;
120
121 default:
122 size = fld->field_size;
123 }
124
125 #if 0
126 if(type->type_class != LTT_STRUCT && type->type_class != LTT_ARRAY &&
127 type->type_class != LTT_SEQUENCE && type->type_class != LTT_STRING){
128 size = fld->field_size;
129 }else if(type->type_class == LTT_ARRAY){
130 element_number = (int) type->element_number;
131 if(fld->field_fixed == 0){// has string or sequence
132 size = 0;
133 for(i=0;i<element_number;i++){
134 size += ltt_event_refresh_fields(offsetRoot+size,size,
135 fld->child[0], evD+size);
136 }
137 }else size = fld->field_size;
138 }else if(type->type_class == LTT_SEQUENCE){
139 size1 = fld->sequ_number_size;
140 element_number = getIntNumber(size1,evD);
141 type->element_number = element_number;
142 if(fld->element_size > 0){
143 size = element_number * fld->element_size;
144 }else{//sequence has string or sequence
145 size = 0;
146 for(i=0;i<element_number;i++){
147 size += ltt_event_refresh_fields(offsetRoot+size+size1,size+size1,
148 fld->child[0], evD+size+size1);
149 }
150 size += size1;
151 }
152 }else if(type->type_class == LTT_STRING){
153 size = strlen((char*)evD) + 1; //include end : '\0'
154 }else if(type->type_class == LTT_STRUCT){
155 element_number = (int) type->element_number;
156 if(fld->field_fixed == 0){
157 offset1 = offsetRoot;
158 offset2 = 0;
159 for(i=0;i<element_number;i++){
160 size=ltt_event_refresh_fields(offset1,offset2,
161 fld->child[i],evD+offset2);
162 offset1 += size;
163 offset2 += size;
164 }
165 size = offset2;
166 }else size = fld->field_size;
167 }
168 #endif //0
169 fld->offset_root = offsetRoot;
170 fld->offset_parent = offsetParent;
171 fld->fixed_root = (offsetRoot==-1) ? 0 : 1;
172 fld->fixed_parent = (offsetParent==-1) ? 0 : 1;
173 fld->field_size = size;
174
175 return size;
176 }
177 #endif //0
178
179
180 /*****************************************************************************
181 *Function name
182 * ltt_event_eventtype_id: get event type id
183 * (base id + position of the event)
184 *Input params
185 * e : an instance of an event type
186 *Return value
187 * unsigned : event type id
188 ****************************************************************************/
189
190 unsigned ltt_event_eventtype_id(const LttEvent *e)
191 {
192 return (unsigned) e->event_id;
193 }
194
195 /*****************************************************************************
196 *Function name
197 * ltt_event_facility : get the facility of the event
198 *Input params
199 * e : an instance of an event type
200 *Return value
201 * LttFacility * : the facility of the event
202 ****************************************************************************/
203
204 LttFacility *ltt_event_facility(const LttEvent *e)
205 {
206 LttTrace * trace = e->tracefile->trace;
207 unsigned id = e->facility_id;
208 LttFacility *facility = ltt_trace_facility_by_id(trace,id);
209
210 g_assert(facility->exists);
211
212 return facility;
213 }
214
215 /*****************************************************************************
216 *Function name
217 * ltt_event_facility_id : get the facility id of the event
218 *Input params
219 * e : an instance of an event type
220 *Return value
221 * unsigned : the facility of the event
222 ****************************************************************************/
223
224 unsigned ltt_event_facility_id(const LttEvent *e)
225 {
226 return e->facility_id;
227 }
228
229 /*****************************************************************************
230 *Function name
231 * ltt_event_eventtype : get the event type of the event
232 *Input params
233 * e : an instance of an event type
234 *Return value
235 * LttEventType * : the event type of the event
236 ****************************************************************************/
237
238 LttEventType *ltt_event_eventtype(const LttEvent *e)
239 {
240 LttFacility* facility = ltt_event_facility(e);
241 if(!facility) return NULL;
242 return &g_array_index(facility->events, LttEventType, e->event_id);
243 }
244
245 /*****************************************************************************
246 *Function name
247 * ltt_event_field : get the root field of the event
248 *Input params
249 * e : an instance of an event type
250 *Return value
251 * LttField * : the root field of the event
252 ****************************************************************************/
253
254 LttField *ltt_event_field(LttEvent *e)
255 {
256 LttField * field;
257 LttEventType * event_type = ltt_event_eventtype(e);
258 if(unlikely(!event_type)) return NULL;
259 field = event_type->root_field;
260 if(unlikely(!field)) return NULL;
261
262 get_field_type_size(e->tracefile, event_type, 0, 0,
263 field, e->data);
264
265 return field;
266 }
267
268 /*****************************************************************************
269 *Function name
270 * ltt_event_time : get the time of the event
271 *Input params
272 * e : an instance of an event type
273 *Return value
274 * LttTime : the time of the event
275 ****************************************************************************/
276
277 LttTime ltt_event_time(const LttEvent *e)
278 {
279 return e->event_time;
280 }
281
282 /*****************************************************************************
283 *Function name
284 * ltt_event_time : get the cycle count of the event
285 *Input params
286 * e : an instance of an event type
287 *Return value
288 * LttCycleCount : the cycle count of the event
289 ****************************************************************************/
290
291 LttCycleCount ltt_event_cycle_count(const LttEvent *e)
292 {
293 return e->tsc;
294 }
295
296
297
298 /*****************************************************************************
299 *Function name
300 * ltt_event_position_get : get the event position data
301 *Input params
302 * e : an instance of an event type
303 * ep : a pointer to event's position structure
304 * tf : tracefile pointer
305 * block : current block
306 * offset : current offset
307 * tsc : current tsc
308 ****************************************************************************/
309 void ltt_event_position_get(LttEventPosition *ep, LttTracefile **tf,
310 guint *block, guint *offset, guint64 *tsc)
311 {
312 *tf = ep->tracefile;
313 *block = ep->block;
314 *offset = ep->offset;
315 *tsc = ep->tsc;
316 }
317
318
319 /*****************************************************************************
320 *Function name
321 * ltt_event_position : get the event's position
322 *Input params
323 * e : an instance of an event type
324 * ep : a pointer to event's position structure
325 ****************************************************************************/
326
327 void ltt_event_position(LttEvent *e, LttEventPosition *ep)
328 {
329 ep->tracefile = e->tracefile;
330 ep->block = e->block;
331 ep->offset = e->offset;
332 ep->tsc = e->tsc;
333 }
334
335 LttEventPosition * ltt_event_position_new()
336 {
337 return g_new(LttEventPosition, 1);
338 }
339
340
341 /*****************************************************************************
342 * Function name
343 * ltt_event_position_compare : compare two positions
344 * A NULL value is infinite.
345 * Input params
346 * ep1 : a pointer to event's position structure
347 * ep2 : a pointer to event's position structure
348 * Return
349 * -1 is ep1 < ep2
350 * 1 if ep1 > ep2
351 * 0 if ep1 == ep2
352 ****************************************************************************/
353
354
355 gint ltt_event_position_compare(const LttEventPosition *ep1,
356 const LttEventPosition *ep2)
357 {
358 if(ep1 == NULL && ep2 == NULL)
359 return 0;
360 if(ep1 != NULL && ep2 == NULL)
361 return -1;
362 if(ep1 == NULL && ep2 != NULL)
363 return 1;
364
365 if(ep1->tracefile != ep2->tracefile)
366 g_error("ltt_event_position_compare on different tracefiles makes no sense");
367
368 if(ep1->block < ep2->block)
369 return -1;
370 if(ep1->block > ep2->block)
371 return 1;
372 if(ep1->offset < ep2->offset)
373 return -1;
374 if(ep1->offset > ep2->offset)
375 return 1;
376 return 0;
377 }
378
379 /*****************************************************************************
380 * Function name
381 * ltt_event_position_copy : copy position
382 * Input params
383 * src : a pointer to event's position structure source
384 * dest : a pointer to event's position structure dest
385 * Return
386 * void
387 ****************************************************************************/
388 void ltt_event_position_copy(LttEventPosition *dest,
389 const LttEventPosition *src)
390 {
391 if(src == NULL)
392 dest = NULL;
393 else
394 *dest = *src;
395 }
396
397
398
399 LttTracefile *ltt_event_position_tracefile(LttEventPosition *ep)
400 {
401 return ep->tracefile;
402 }
403
404 /*****************************************************************************
405 *Function name
406 * ltt_event_cpu_i: get the cpu id where the event happens
407 *Input params
408 * e : an instance of an event type
409 *Return value
410 * unsigned : the cpu id
411 ****************************************************************************/
412
413 unsigned ltt_event_cpu_id(LttEvent *e)
414 {
415 return e->tracefile->cpu_num;
416 }
417
418 /*****************************************************************************
419 *Function name
420 * ltt_event_data : get the raw data for the event
421 *Input params
422 * e : an instance of an event type
423 *Return value
424 * void * : pointer to the raw data for the event
425 ****************************************************************************/
426
427 void *ltt_event_data(LttEvent *e)
428 {
429 return e->data;
430 }
431
432 /*****************************************************************************
433 *Function name
434 * ltt_event_field_element_number
435 * : The number of elements in a sequence field is specific
436 * to each event. This function returns the number of
437 * elements for an array or sequence field in an event.
438 *Input params
439 * e : an instance of an event type
440 * f : a field of the instance
441 *Return value
442 * unsigned : the number of elements for an array/sequence field
443 ****************************************************************************/
444 guint64 ltt_event_field_element_number(LttEvent *e, LttField *f)
445 {
446 if(f->field_type->type_class != LTT_ARRAY &&
447 f->field_type->type_class != LTT_SEQUENCE)
448 return 0;
449
450 if(f->field_type->type_class == LTT_ARRAY)
451 return f->field_type->element_number;
452 return ltt_get_uint(LTT_GET_BO(e->tracefile), f->sequ_number_size,
453 e + f->offset_root);
454 }
455
456 /*****************************************************************************
457 *Function name
458 * ltt_event_field_element_select
459 * : Set the currently selected element for a sequence or
460 * array field
461 * O(1) if fields are of fixed size, else O(n) if fields are
462 * of variable size.
463 *Input params
464 * e : an instance of an event type
465 * f : a field of the instance
466 * i : the ith element (0, ...)
467 ****************************************************************************/
468 void ltt_event_field_element_select(LttEvent *e, LttField *f, unsigned i)
469 {
470 unsigned element_number;
471 LttField *field;
472 unsigned int k;
473 size_t size;
474 LttEventType *event_type;
475
476 if(f->field_type->type_class != LTT_ARRAY &&
477 f->field_type->type_class != LTT_SEQUENCE)
478 return ;
479
480 element_number = ltt_event_field_element_number(e,f);
481 event_type = ltt_event_eventtype(e);
482 /* Sanity check for i : 0..n-1 only, and must be lower or equal element_number
483 */
484 if(i >= element_number) return;
485
486 field = f->child[0];
487
488 if(f->field_type->type_class == LTT_SEQUENCE)
489 size = f->sequ_number_size;
490 else
491 size = 0;
492
493 if(field->fixed_size == FIELD_FIXED) {
494 size += field->field_size * i;
495
496 get_field_type_size(e->tracefile, event_type,
497 f->offset_root+size, size, field, e->data);
498
499 } else {
500 for(k=0;k<=i;k++){
501 size += get_field_type_size(e->tracefile, event_type,
502 f->offset_root+size, size, field, e->data);
503 }
504 }
505 f->current_element = i;
506 }
507
508 /*****************************************************************************
509 * These functions extract data from an event after architecture specific
510 * conversions
511 ****************************************************************************/
512 guint32 ltt_event_get_unsigned(LttEvent *e, LttField *f)
513 {
514 gboolean reverse_byte_order = LTT_GET_BO(e->tracefile);
515
516 LttTypeEnum t = f->field_type->type_class;
517
518 g_assert(t == LTT_UINT || t == LTT_ENUM);
519
520 if(f->field_size == 1){
521 guint8 x = *(guint8 *)(e->data + f->offset_root);
522 return (guint32) x;
523 }else if(f->field_size == 2){
524 return (guint32)ltt_get_uint16(reverse_byte_order, e->data + f->offset_root);
525 }else if(f->field_size == 4){
526 return (guint32)ltt_get_uint32(reverse_byte_order, e->data + f->offset_root);
527 }
528 #if 0
529 else if(f->field_size == 8){
530 guint64 x = *(guint64 *)(e->data + f->offset_root);
531 if(e->tracefile->trace->my_arch_endian == LTT_LITTLE_ENDIAN)
532 return (unsigned int) (revFlag ? GUINT64_FROM_BE(x): x);
533 else
534 return (unsigned int) (revFlag ? GUINT64_FROM_LE(x): x);
535 }
536 #endif //0
537 g_critical("ltt_event_get_unsigned : field size %i unknown", f->field_size);
538 return 0;
539 }
540
541 gint32 ltt_event_get_int(LttEvent *e, LttField *f)
542 {
543 gboolean reverse_byte_order = LTT_GET_BO(e->tracefile);
544
545 g_assert(f->field_type->type_class == LTT_INT);
546
547 if(f->field_size == 1){
548 gint8 x = *(gint8 *)(e->data + f->offset_root);
549 return (gint32) x;
550 }else if(f->field_size == 2){
551 return (gint32)ltt_get_int16(reverse_byte_order, e->data + f->offset_root);
552 }else if(f->field_size == 4){
553 return (gint32)ltt_get_int32(reverse_byte_order, e->data + f->offset_root);
554 }
555 #if 0
556 else if(f->field_size == 8){
557 gint64 x = *(gint64 *)(e->data + f->offset_root);
558 if(e->tracefile->trace->my_arch_endian == LTT_LITTLE_ENDIAN)
559 return (int) (revFlag ? GINT64_FROM_BE(x): x);
560 else
561 return (int) (revFlag ? GINT64_FROM_LE(x): x);
562 }
563 #endif //0
564 g_critical("ltt_event_get_int : field size %i unknown", f->field_size);
565 return 0;
566 }
567
568 guint64 ltt_event_get_long_unsigned(LttEvent *e, LttField *f)
569 {
570 gboolean reverse_byte_order = LTT_GET_BO(e->tracefile);
571
572 LttTypeEnum t = f->field_type->type_class;
573
574 g_assert(t == LTT_UINT || t == LTT_ENUM
575 || t == LTT_ULONG || LTT_SIZE_T || LTT_OFF_T || LTT_POINTER);
576
577 if(f->field_size == 1){
578 guint8 x = *(guint8 *)(e->data + f->offset_root);
579 return (guint64) x;
580 }else if(f->field_size == 2){
581 return (guint64)ltt_get_uint16(reverse_byte_order, e->data + f->offset_root);
582 }else if(f->field_size == 4){
583 return (guint64)ltt_get_uint32(reverse_byte_order, e->data + f->offset_root);
584 }else if(f->field_size == 8){
585 return ltt_get_uint64(reverse_byte_order, e->data + f->offset_root);
586 }
587 g_critical("ltt_event_get_long_unsigned : field size %i unknown", f->field_size);
588 return 0;
589 }
590
591 gint64 ltt_event_get_long_int(LttEvent *e, LttField *f)
592 {
593 //int revFlag = e->tracefile->trace->my_arch_endian ==
594 // e->tracefile->trace->system_description->endian ? 0:1;
595 gboolean reverse_byte_order = LTT_GET_BO(e->tracefile);
596
597 g_assert( f->field_type->type_class == LTT_INT
598 || f->field_type->type_class == LTT_LONG
599 || f->field_type->type_class == LTT_SSIZE_T);
600
601 if(f->field_size == 1){
602 gint8 x = *(gint8 *)(e->data + f->offset_root);
603 return (gint64) x;
604 }else if(f->field_size == 2){
605 return (gint64)ltt_get_int16(reverse_byte_order, e->data + f->offset_root);
606 }else if(f->field_size == 4){
607 return (gint64)ltt_get_int32(reverse_byte_order, e->data + f->offset_root);
608 }else if(f->field_size == 8){
609 return ltt_get_int64(reverse_byte_order, e->data + f->offset_root);
610 }
611 g_critical("ltt_event_get_long_int : field size %i unknown", f->field_size);
612 return 0;
613 }
614
615 float ltt_event_get_float(LttEvent *e, LttField *f)
616 {
617 gboolean reverse_byte_order = LTT_GET_BO(e->tracefile);
618
619 g_assert(f->field_type->type_class == LTT_FLOAT && f->field_size == 4);
620
621 if(reverse_byte_order == 0) return *(float *)(e->data + f->offset_root);
622 else{
623 guint32 aInt;
624 memcpy((void*)&aInt, e->data + f->offset_root, 4);
625 aInt = ___swab32(aInt);
626 return ((float)aInt);
627 }
628 }
629
630 double ltt_event_get_double(LttEvent *e, LttField *f)
631 {
632 gboolean reverse_byte_order = LTT_GET_BO(e->tracefile);
633
634 g_assert(f->field_type->type_class == LTT_FLOAT && f->field_size == 8);
635
636 if(reverse_byte_order == 0) return *(double *)(e->data + f->offset_root);
637 else{
638 guint64 aInt;
639 memcpy((void*)&aInt, e->data + f->offset_root, 8);
640 aInt = ___swab64(aInt);
641 return ((double)aInt);
642 }
643 }
644
645 /*****************************************************************************
646 * The string obtained is only valid until the next read from
647 * the same tracefile.
648 ****************************************************************************/
649 char *ltt_event_get_string(LttEvent *e, LttField *f)
650 {
651 g_assert(f->field_type->type_class == LTT_STRING);
652
653 return (gchar*)g_strdup((gchar*)(e->data + f->offset_root));
654 }
655
656
657 /*****************************************************************************
658 *Function name
659 * get_field_type_size : set the fixed and dynamic sizes of the field type
660 * from the data read.
661 *Input params
662 * tf : tracefile
663 * event_type : event type
664 * offset_root : offset from the root
665 * offset_parent : offset from the parent
666 * field : field
667 * data : a pointer to the event data.
668 *Returns the field type size.
669 ****************************************************************************/
670 size_t get_field_type_size(LttTracefile *tf, LttEventType *event_type,
671 off_t offset_root, off_t offset_parent,
672 LttField *field, void *data)
673 {
674 size_t size = 0;
675 guint i;
676 LttType *type;
677
678 g_assert(field->fixed_root != FIELD_UNKNOWN);
679 g_assert(field->fixed_parent != FIELD_UNKNOWN);
680 g_assert(field->fixed_size != FIELD_UNKNOWN);
681
682 field->offset_root = offset_root;
683 field->offset_parent = offset_parent;
684
685 type = field->field_type;
686
687 switch(type->type_class) {
688 case LTT_INT:
689 case LTT_UINT:
690 case LTT_FLOAT:
691 case LTT_ENUM:
692 case LTT_POINTER:
693 case LTT_LONG:
694 case LTT_ULONG:
695 case LTT_SIZE_T:
696 case LTT_SSIZE_T:
697 case LTT_OFF_T:
698 g_assert(field->fixed_size == FIELD_FIXED);
699 size = field->field_size;
700 break;
701 case LTT_SEQUENCE:
702 {
703 gint seqnum = ltt_get_uint(LTT_GET_BO(tf),
704 field->sequ_number_size,
705 data + offset_root);
706
707 if(field->child[0]->fixed_size == FIELD_FIXED) {
708 size = field->sequ_number_size +
709 (seqnum * get_field_type_size(tf, event_type,
710 offset_root, offset_parent,
711 field->child[0], data));
712 } else {
713 size += field->sequ_number_size;
714 for(i=0;i<seqnum;i++) {
715 size_t child_size;
716 child_size = get_field_type_size(tf, event_type,
717 offset_root, offset_parent,
718 field->child[0], data);
719 offset_root += child_size;
720 offset_parent += child_size;
721 size += child_size;
722 }
723 }
724 field->field_size = size;
725 }
726 break;
727 case LTT_STRING:
728 size = strlen((char*)(data+offset_root)) + 1;// length + \0
729 field->field_size = size;
730 break;
731 case LTT_ARRAY:
732 if(field->fixed_size == FIELD_FIXED)
733 size = field->field_size;
734 else {
735 for(i=0;i<field->field_type->element_number;i++) {
736 size_t child_size;
737 child_size = get_field_type_size(tf, event_type,
738 offset_root, offset_parent,
739 field->child[0], data);
740 offset_root += child_size;
741 offset_parent += child_size;
742 size += child_size;
743 }
744 field->field_size = size;
745 }
746 break;
747 case LTT_STRUCT:
748 if(field->fixed_size == FIELD_FIXED)
749 size = field->field_size;
750 else {
751 size_t current_root_offset = offset_root;
752 size_t current_offset = 0;
753 size_t child_size = 0;
754 for(i=0;i<type->element_number;i++) {
755 child_size = get_field_type_size(tf,
756 event_type, current_root_offset, current_offset,
757 field->child[i], data);
758 current_offset += child_size;
759 current_root_offset += child_size;
760
761 }
762 size = current_offset;
763 field->field_size = size;
764 }
765 break;
766 case LTT_UNION:
767 if(field->fixed_size == FIELD_FIXED)
768 size = field->field_size;
769 else {
770 size_t current_root_offset = field->offset_root;
771 size_t current_offset = 0;
772 for(i=0;i<type->element_number;i++) {
773 size = get_field_type_size(tf, event_type,
774 current_root_offset, current_offset,
775 field->child[i], data);
776 size = max(size, field->child[i]->field_size);
777 }
778 field->field_size = size;
779 }
780 break;
781 }
782
783 return size;
784 }
785
786
This page took 0.047931 seconds and 4 git commands to generate.