/* Dissects a configuration frame (only the most important stuff, tries * to be fast, does no GUI stuff) and returns a pointer to a config_frame * struct that contains all the information from the frame needed to * dissect a DATA frame. * * use 'config_frame_free()' to free the config_frame again */ static config_frame *config_frame_fast(tvbuff_t *tvb) { guint16 idcode, num_pmu; gint offset; config_frame *frame; /* get a new frame and initialize it */ frame = wmem_new(wmem_file_scope(), config_frame); frame->config_blocks = wmem_array_new(wmem_file_scope(), sizeof(config_block)); idcode = tvb_get_ntohs(tvb, 4); frame->id = idcode; num_pmu = tvb_get_ntohs(tvb, 18); offset = 20; /* start of repeating blocks */ while (num_pmu) { guint16 format_flags; gint num_ph, num_an, num_dg; gint i, phunit, anunit, fnom; config_block block; /* initialize the block */ block.phasors = wmem_array_new(wmem_file_scope(), sizeof(phasor_info)); block.analogs = wmem_array_new(wmem_file_scope(), sizeof(analog_info)); /* copy the station name from the tvb to block, and add NULL byte */ tvb_memcpy(tvb, block.name, offset, CHNAM_LEN); offset += CHNAM_LEN; block.name[CHNAM_LEN] = '\0'; block.id = tvb_get_ntohs(tvb, offset); offset += 2; format_flags = tvb_get_ntohs(tvb, offset); offset += 2; block.format_fr = (format_flags & 0x0008) ? floating_point : integer; block.format_an = (format_flags & 0x0004) ? floating_point : integer; block.format_ph = (format_flags & 0x0002) ? floating_point : integer; block.phasor_notation = (format_flags & 0x0001) ? polar : rect; num_ph = tvb_get_ntohs(tvb, offset); offset += 2; num_an = tvb_get_ntohs(tvb, offset); offset += 2; num_dg = tvb_get_ntohs(tvb, offset); offset += 2; block.num_dg = num_dg; /* the offset of the PHUNIT, ANUNIT, and FNOM blocks */ phunit = offset + (num_ph + num_an + num_dg * CHNAM_LEN) * CHNAM_LEN; anunit = phunit + num_ph * 4; fnom = anunit + num_an * 4 + num_dg * 4; /* read num_ph phasor names and conversation factors */ for (i = 0; i != num_ph; i++) { phasor_info pi; guint32 conv; /* copy the phasor name from the tvb, and add NULL byte */ tvb_memcpy(tvb, pi.name, offset, CHNAM_LEN); offset += CHNAM_LEN; pi.name[CHNAM_LEN] = '\0'; conv = tvb_get_ntohl(tvb, phunit + 4 * i); pi.unit = conv & 0xFF000000 ? A : V; pi.conv = conv & 0x00FFFFFF; wmem_array_append_one(block.phasors, pi); } /* read num_an analog value names and conversation factors */ for (i = 0; i != num_an; i++) { analog_info ai; guint32 conv; /* copy the phasor name from the tvb, and add NULL byte */ tvb_memcpy(tvb, ai.name, offset, CHNAM_LEN); offset += CHNAM_LEN; ai.name[CHNAM_LEN] = '\0'; conv = tvb_get_ntohl(tvb, anunit + 4 * i); ai.conv = conv; wmem_array_append_one(block.analogs, ai); } /* the names for the bits in the digital status words aren't saved, there is no space to display them in the GUI anyway */ /* save FNOM */ block.fnom = tvb_get_ntohs(tvb, fnom) & 0x0001 ? 50 : 60; offset = fnom + 2; /* skip CFGCNT */ offset += 2; wmem_array_append_one(frame->config_blocks, block); num_pmu--; } return frame; }
static void wmem_test_array(void) { wmem_allocator_t *allocator; wmem_array_t *array; unsigned int i, j, k; guint32 val, *buf; guint32 vals[8]; allocator = wmem_allocator_new(WMEM_ALLOCATOR_STRICT); array = wmem_array_new(allocator, sizeof(guint32)); g_assert(array); g_assert(wmem_array_get_count(array) == 0); for (i=0; i<CONTAINER_ITERS; i++) { val = i; wmem_array_append_one(array, val); g_assert(wmem_array_get_count(array) == i+1); val = *(guint32*)wmem_array_index(array, i); g_assert(val == i); } wmem_strict_check_canaries(allocator); for (i=0; i<CONTAINER_ITERS; i++) { val = *(guint32*)wmem_array_index(array, i); g_assert(val == i); } array = wmem_array_sized_new(allocator, sizeof(guint32), 73); for (i=0; i<CONTAINER_ITERS; i++) { for (j=0; j<8; j++) { vals[j] = i+j; } wmem_array_append(array, vals, 8); g_assert(wmem_array_get_count(array) == 8*(i+1)); } wmem_strict_check_canaries(allocator); buf = (guint32*)wmem_array_get_raw(array); for (i=0; i<CONTAINER_ITERS; i++) { for (j=0; j<8; j++) { g_assert(buf[i*8 + j] == i+j); } } wmem_array_sort(array, wmem_test_compare_guint32); for (i=0, k=0; i<8; i++) { for (j=0; j<=i; j++, k++) { val = *(guint32*)wmem_array_index(array, k); g_assert(val == i); } } for (j=k; k<8*(CONTAINER_ITERS+1)-j; k++) { val = *(guint32*)wmem_array_index(array, k); g_assert(val == ((k-j)/8)+8); } for (i=0; i<7; i++) { for (j=0; j<7-i; j++, k++) { val = *(guint32*)wmem_array_index(array, k); g_assert(val == CONTAINER_ITERS+i); } } g_assert(k == wmem_array_get_count(array)); wmem_destroy_allocator(allocator); }