Exemple #1
0
int ft_swap_chunks_from_native(UINT32_T size, UINT32_T nchans, void *buf) {
	UINT32_T offset = 0;
	while (offset + sizeof(ft_chunkdef_t) <= size) {
		ft_chunk_t *chunk = (ft_chunk_t *) ((char *) buf + offset);
		offset += sizeof(ft_chunkdef_t) + chunk->def.size;
		
		/* chunk definition fault (=too big) ? */
		if (offset > size) return -1;
		
		switch(chunk->def.type) {
			case FT_CHUNK_RESOLUTIONS:
				if (chunk->def.size >= nchans*sizeof(FLOAT64_T)) {
					ft_swap64(nchans, chunk->data);
				}
				break;
			/* Add other cases here as needed */
		}
		
		ft_swap32(2, &(chunk->def));
	}
	return 0;
}
Exemple #2
0
void ft_swap_data(UINT32_T numel, UINT32_T datatype, void *data) {
	switch(datatype) {
		case DATATYPE_CHAR:
		case DATATYPE_UINT8:
		case DATATYPE_INT8:
			return;
		case DATATYPE_UINT16:
		case DATATYPE_INT16:
			ft_swap16(numel, data);
			return;
		case DATATYPE_UINT32:
		case DATATYPE_INT32:
		case DATATYPE_FLOAT32:
			ft_swap32(numel, data);
			return;
		case DATATYPE_UINT64:
		case DATATYPE_INT64:
		case DATATYPE_FLOAT64:
			ft_swap64(numel, data);
			return;
	}	
}
Exemple #3
0
/** Prepares "start" RDA packet with channel names determined from the corresponding chunk (or empty)
	Also converts to little-endian if this machine is big endian
	@param hdr  Points to headerdef_t structure, will be filled, may not be NULL
	@return created start item, or NULL on error (connection / out of memory)
*/
rda_buffer_item_t *rda_aux_get_hdr_prep_start(int ft_buffer, headerdef_t *hdr) {
	rda_buffer_item_t *item = NULL;
	const ft_chunk_t *chunk;
	rda_msg_start_t *R;
	char *str;
	double *dRes;
	const void *dResSource;
	size_t bytesTotal;
	int i,r,numExtraZeros,sizeOrgNames;
	message_t req, *resp = NULL;
	messagedef_t msg_def;	
	
	req.def = &msg_def;
	req.buf = NULL;
	msg_def.version = VERSION;
	msg_def.command = GET_HDR;
	msg_def.bufsize = 0;
	
	r = clientrequest(ft_buffer, &req, &resp);
	if (r<0 || resp == NULL || resp->def == NULL) {
		goto cleanup;
	}
	
	if (resp->def->command != GET_OK || resp->def->bufsize < sizeof(headerdef_t) || resp->buf == NULL) {
		goto cleanup;
	}
	
	memcpy(hdr, resp->buf, sizeof(headerdef_t));
	
	/* Ok, we have the basic header, now look for proper FT_CHUNK_RESOLUTIONS */
	chunk = find_chunk(resp->buf, sizeof(headerdef_t), resp->def->bufsize, FT_CHUNK_RESOLUTIONS);
	if (chunk != NULL && chunk->def.size == hdr->nchans*sizeof(double)) {
		dResSource = chunk->data;
		/* fine - we just need a memcpy later on */
	} else {
		dResSource = NULL;
		/* no suitable chunk found - set defaults later on */
	}
	
	/* Now see if we can find channel names */
	chunk = find_chunk(resp->buf, sizeof(headerdef_t), resp->def->bufsize, FT_CHUNK_CHANNEL_NAMES);
	if (chunk != NULL && chunk->def.size >= hdr->nchans) {
		/* The chunk seems ok - check whether we really have N (0-terminated) strings */
		int k,nz = 0;
		for (k = 0; k<chunk->def.size && nz<=hdr->nchans; k++) {
			if (chunk->data[k] == 0) nz++;
		}
		/* Okay, either k is at the end and we have nz<=N, or we have reached N=nz before the
		   end of the chunk. In both cases, it's safe to transmit the first 'k' bytes and
		   add (N-nz) trailing zeros */
		numExtraZeros = hdr->nchans - nz;
		sizeOrgNames = k;
	} else {
		sizeOrgNames = 0;
		numExtraZeros = hdr->nchans;
	}
	
	bytesTotal = sizeof(rda_msg_start_t) + hdr->nchans*(sizeof(double)) + sizeOrgNames + numExtraZeros;
		
	item = rda_aux_alloc_item(bytesTotal);
	if (item == NULL) goto cleanup;
		
	R = (rda_msg_start_t *) item->data;
	memcpy(R->hdr.guid, _rda_guid, sizeof(_rda_guid));
	R->hdr.nSize = bytesTotal;
	R->hdr.nType = RDA_START_MSG;
	R->nChannels = hdr->nchans;
	R->dSamplingInterval = 1.0e6/(double) hdr->fsample;	/* should be in microseconds */
	
	if (_i_am_big_endian_) {
		/* take care of hdr.nSize, hdr.nType, nChannels */
		ft_swap32(3, &(R->hdr.nSize)); 
		ft_swap64(1, &(R->dSamplingInterval));
	}
	
	/* R+1 points to first byte after header info */
	dRes = (double *) ((void *)(R+1)); 
	if (dResSource == NULL) {
		/* Fill with resolution = 1.0 -- we have nothing better */
		for (i=0;i<hdr->nchans;i++) dRes[i]=1.0;
	} else {
		memcpy(dRes, dResSource, hdr->nchans * sizeof(double));
	}
	/* swap byte order if necessary */
	if (_i_am_big_endian_) {
		ft_swap64(hdr->nchans, dRes);
	}
	
	/* Let 'str' point to first byte after the resolution values */
	str = (char *) ((void *)(dRes + hdr->nchans));
	if (sizeOrgNames > 0) {
		memcpy(str, chunk->data, sizeOrgNames);
	}
	for (i=0;i<numExtraZeros;i++) str[sizeOrgNames + i] = 0;
	
	/* done */
cleanup:
	if (resp) {
		if (resp->def) free(resp->def);
		if (resp->buf) free(resp->buf);
		free(resp);
	}
	return item;
}