Exemplo n.º 1
0
// Handles .n
static ZERO_OR_ERROR FS_read_a_part( struct one_wire_query *owq_part )
{
	struct parsedname *pn = PN(owq_part);
	size_t extension = pn->extension;
	struct filetype * ft = pn->selected_filetype ;
	struct one_wire_query * owq_all ;
	
	// bitfield
	if ( ft->format == ft_bitfield ) {
		return FS_read_a_bit( owq_part ) ;
	}

	// non-bitfield 
	owq_all = OWQ_create_aggregate( owq_part ) ;
	if ( owq_all == NO_ONE_WIRE_QUERY ) {
		return -ENOENT ;
	}
	
	// First fill the whole array with current values
	if ( FS_read_owq( owq_all ) < 0 ) {
		OWQ_destroy( owq_all ) ;
		return -EINVAL ;
	}

	// Copy ascii/binary field
	switch (ft->format) {
	case ft_binary:
	case ft_ascii:
	case ft_vascii:
	case ft_alias:
		{
			size_t extension_index;
			char *buffer_pointer = OWQ_buffer(owq_all);

			// All prior elements
			for (extension_index = 0; extension_index < extension; ++extension_index) {
				// move past their buffer position
				buffer_pointer += OWQ_array_length(owq_all, extension_index);
			}

			// now move current element's buffer to location
			OWQ_length(owq_part) = OWQ_array_length(owq_all, extension) ;
			memmove( OWQ_buffer(owq_part), buffer_pointer, OWQ_length(owq_part));
			break;
		}
	default:
		// Copy value field
		memcpy( &OWQ_val(owq_part), &OWQ_array(owq_all)[pn->extension], sizeof(union value_object) );
		break;
	}

	OWQ_destroy(owq_all);
	return 0 ;
}
Exemplo n.º 2
0
/* Higher level add of a one-wire-query object */
GOOD_OR_BAD OWQ_Cache_Add(const struct one_wire_query *owq)
{
	const struct parsedname *pn = PN(owq);
	if (pn->extension == EXTENSION_ALL) {
		switch (pn->selected_filetype->format) {
		case ft_ascii:
		case ft_vascii:
		case ft_alias:
		case ft_binary:
			return gbBAD;			// cache of string arrays not supported
		case ft_integer:
		case ft_unsigned:
		case ft_yesno:
		case ft_date:
		case ft_float:
		case ft_pressure:
		case ft_temperature:
		case ft_tempgap:
			LEVEL_DEBUG("Adding data for %s", SAFESTRING(pn->path) );
			return Cache_Add(OWQ_array(owq), (pn->selected_filetype->ag->elements) * sizeof(union value_object), pn);
		default:
			return gbBAD;
		}
	} else {
		switch (pn->selected_filetype->format) {
		case ft_ascii:
		case ft_vascii:
		case ft_alias:
		case ft_binary:
			if (OWQ_offset(owq) > 0) {
				return gbBAD;
			}
			LEVEL_DEBUG("Adding data for %s", SAFESTRING(pn->path) );
			return Cache_Add(OWQ_buffer(owq), OWQ_length(owq), pn);
		case ft_integer:
		case ft_unsigned:
		case ft_yesno:
		case ft_date:
		case ft_float:
		case ft_pressure:
		case ft_temperature:
		case ft_tempgap:
			LEVEL_DEBUG("Adding data for %s", SAFESTRING(pn->path) );
			return Cache_Add(&OWQ_val(owq), sizeof(union value_object), pn);
		default:
			return gbBAD;
		}
	}
}
Exemplo n.º 3
0
// Handles: ALL
static ZERO_OR_ERROR FS_write_in_parts( struct one_wire_query *owq_all )
{
	struct one_wire_query * owq_part = OWQ_create_separate( 0, owq_all ) ;
	struct parsedname *pn = PN(owq_all);
	size_t elements = pn->selected_filetype->ag->elements;
	size_t extension ;
	char *buffer_pointer;
	ZERO_OR_ERROR z_or_e = 0 ;
	
	// Create a "single" OWQ copy to iterate with
	if ( owq_part == NO_ONE_WIRE_QUERY ) {
		return -ENOENT ;
	}

	// create a buffer for certain types
	// point to 0th element's buffer first
	buffer_pointer = OWQ_buffer(owq_all);
	OWQ_size(owq_part) = FileLength(PN(owq_part));
	OWQ_offset(owq_part) = 0;

	// loop through all eloements
	for (extension = 0; extension < elements; ++extension) {
		ZERO_OR_ERROR single_write;

		switch (pn->selected_filetype->format) {
		case ft_ascii:
		case ft_vascii:
		case ft_alias:
		case ft_binary:
			OWQ_length(owq_part) = OWQ_array_length(owq_all,extension) ;
			OWQ_buffer(owq_part) = buffer_pointer;
			buffer_pointer += OWQ_length(owq_part);
			break;
		default:
			memcpy(&OWQ_val(owq_part), &OWQ_array(owq_all)[extension], sizeof(union value_object));
			break;
		}

		OWQ_pn(owq_part).extension = extension;
		single_write = FS_write_owq(owq_part);

		if (single_write != 0) {
			z_or_e = single_write ;
		}
	}

	return z_or_e;
}
Exemplo n.º 4
0
/* Test for a simultaneous property
 * return true if simultaneous is the prefered method
 * bad if no simultaneous, or it's not the best
*/
static GOOD_OR_BAD Cache_Get_Simultaneous(enum simul_type type, struct one_wire_query *owq)
{
	struct tree_node tn;
	time_t duration ;
	time_t time_left ;
	time_t dwell_time_simul ;
	struct parsedname * pn = PN(owq) ;
	size_t dsize = sizeof(union value_object) ;
	
	duration = TimeOut(pn->selected_filetype->change);
	if (duration <= 0) {
		// probably "uncached" requested
		return gbBAD;
	}
	
	LoadTK( pn->sn, pn->selected_filetype, pn->extension, &tn ) ;
	
	if ( Get_Stat(&cache_ext, Cache_Get_Common( &OWQ_val(owq), &dsize, &time_left, &tn)) == 0 ) {
		// valid cached primary data -- see if a simultaneous conversion should be used instead
		time_t dwell_time_data = duration - time_left ;
		
		if ( BAD( Cache_Get_Simul_Time( type, &dwell_time_simul, pn)) ) {
			// Simul not found or timed out
			LEVEL_DEBUG("Simultaneous conversion not found.") ;
			OWQ_SIMUL_CLR(owq) ;
			return gbGOOD ;
		}
		if ( dwell_time_simul < dwell_time_data ) {
			LEVEL_DEBUG("Simultaneous conversion is newer than previous reading.") ;
			OWQ_SIMUL_SET(owq) ;
			return gbBAD ; // Simul is newer
		}
		// Cached data is newer, so use it
		OWQ_SIMUL_CLR(owq) ;
		return gbGOOD ;
	}
	// fall through -- no cached primary data
	if ( BAD( Cache_Get_Simul_Time( type, &dwell_time_simul, pn)) ) {
		// no simultaneous either
		OWQ_SIMUL_CLR(owq) ;
		return gbBAD ;
	}
	OWQ_SIMUL_SET(owq) ;
	return gbBAD ; // Simul is newer
}
Exemplo n.º 5
0
/* called when pn->extension==EXTENSION_ALL and pn->selected_filetype->ag->combined==ag_separate */
static ZERO_OR_ERROR FS_read_tester_array(struct one_wire_query *owq)
{
	size_t elements = OWQ_pn(owq).selected_filetype->ag->elements;
	size_t extension;
	size_t entry_length = FileLength(PN(owq));

	for (extension = 0; extension < elements; ++extension) {
		struct one_wire_query * owq_single = OWQ_create_separate( extension, owq ) ;
		if ( owq_single == NO_ONE_WIRE_QUERY ) {
			return -ENOMEM ;
		}
		switch (OWQ_pn(owq).selected_filetype->format) {
		case ft_integer:
		case ft_yesno:
		case ft_bitfield:
		case ft_unsigned:
		case ft_pressure:
		case ft_temperature:
		case ft_tempgap:
		case ft_float:
		case ft_date:
			break;
		case ft_vascii:
		case ft_alias:
		case ft_ascii:
		case ft_binary:
			OWQ_assign_read_buffer(&OWQ_buffer(owq)[extension * entry_length],entry_length,0,owq_single) ;
			break;
		case ft_directory:
		case ft_subdir:
		case ft_unknown:
			OWQ_destroy(owq_single) ;
			return -ENOENT;
		}
		if (FS_read_tester_single(owq_single)) {
			OWQ_destroy(owq_single) ;
			return -EINVAL;
		}
		memcpy(&OWQ_array(owq)[extension], &OWQ_val(owq_single), sizeof(union value_object));
		OWQ_destroy(owq_single) ;
	}
	return 0;
}
Exemplo n.º 6
0
static SIZE_OR_ERROR OWQ_parse_output_array_with_commas(struct one_wire_query *owq)
{
	struct one_wire_query owq_single;
	size_t extension;
	int len;
	size_t used_size = 0;
	size_t remaining_size = OWQ_size(owq);
	size_t elements = OWQ_pn(owq).selected_filetype->ag->elements;

	// loop though all array elements
	for (extension = 0; extension < elements; ++extension) {
		//printf("OWQ_parse_output_array_with_commas element=%d, size_used=%d, remaining=%d\n",(int)extension,(int)used_size,(int)remaining_size) ;
		// Prepare a copy of owq that only points to a single element
		memcpy(&owq_single, owq, sizeof(owq_single));
		OWQ_pn(&owq_single).extension = extension;
		memcpy(&OWQ_val(&owq_single), &OWQ_array(owq)[extension], sizeof(union value_object));
		// add the comma first (if not the first element and enough room)
		if (used_size > 0) {
			if (remaining_size == 0) {
				return -EFAULT;
			}
			OWQ_buffer(owq)[used_size] = ',';
			++used_size;
			--remaining_size;
		}
		// Now process the single element
		OWQ_buffer(&owq_single) = &OWQ_buffer(owq)[used_size];
		OWQ_size(&owq_single) = remaining_size;
		len = OWQ_parse_output(&owq_single);
		// any error aborts
		if (len < 0) {
			return len;
		}
		remaining_size -= len;
		used_size += len;
	}
	return used_size;
}
Exemplo n.º 7
0
// Handles .n
static ZERO_OR_ERROR FS_write_a_part( struct one_wire_query *owq_part )
{
	struct parsedname *pn = PN(owq_part);
	size_t extension = pn->extension;
	struct filetype * ft = pn->selected_filetype ;
	ZERO_OR_ERROR z_or_e ;
	struct one_wire_query * owq_all ;
	
	// bitfield
	if ( ft->format == ft_bitfield ) {
		return FS_write_a_bit( owq_part ) ;
	}

	// non-bitfield 
	owq_all = OWQ_create_aggregate( owq_part ) ;
	if ( owq_all == NO_ONE_WIRE_QUERY ) {
		return -ENOENT ;
	}
	
	// First fill the whole array with current values
	if ( FS_read_local( owq_all ) < 0 ) {
		OWQ_destroy( owq_all ) ;
		return -ENOENT ;
	}

	// Copy ascii/binary field
	switch (ft->format) {
	case ft_binary:
	case ft_ascii:
	case ft_vascii:
	case ft_alias:
		{
			size_t extension_index;
			size_t elements = ft->ag->elements;
			char *buffer_pointer = OWQ_buffer(owq_all);
			char *entry_pointer;
			char *target_pointer;

			// All prior elements
			for (extension_index = 0; extension_index < extension; ++extension) {
				// move past their buffer position
				buffer_pointer += OWQ_array_length(owq_all, extension_index);
			}

			entry_pointer = buffer_pointer; // this element's buffer start

			target_pointer = buffer_pointer + OWQ_length(owq_part); // new start next element
			buffer_pointer = buffer_pointer + OWQ_array_length(owq_all, extension); // current start next element

			// move rest of elements to new locations
			for (extension_index = extension + 1; extension_index < elements; ++extension) {
				size_t this_length = OWQ_array_length(owq_all, extension_index);
				memmove(target_pointer, buffer_pointer, this_length);
				target_pointer += this_length;
				buffer_pointer += this_length;
			}

			// now move current element's buffer to location
			memmove(entry_pointer, OWQ_buffer(owq_part), OWQ_length(owq_part));
			OWQ_array_length(owq_all,extension) = OWQ_length(owq_part) ;
		}
		break;
	default:
		// Copy value field
		memcpy(&OWQ_array(owq_all)[pn->extension], &OWQ_val(owq_part), sizeof(union value_object));
		break;
	}

	// Write whole thing out
	z_or_e = FS_write_owq(owq_all);

	OWQ_destroy(owq_all);

	return z_or_e ;
}
Exemplo n.º 8
0
// Handles: ALL
static ZERO_OR_ERROR FS_read_in_parts( struct one_wire_query *owq_all )
{
	struct parsedname *pn = PN(owq_all);
	struct filetype * ft = pn->selected_filetype ;
	struct one_wire_query * owq_part ;
	size_t elements = pn->selected_filetype->ag->elements;
	size_t extension;
	char * buffer_pointer = OWQ_buffer(owq_all) ;
	size_t buffer_left = OWQ_size(owq_all) ;
	
	// single for BYTE or iteration 
	owq_part = OWQ_create_separate( 0, owq_all ) ;
	if ( owq_part == NO_ONE_WIRE_QUERY ) {
		return -ENOENT ;
	}
	
	// bitfield
	if ( ft->format == ft_bitfield ) {
		OWQ_pn(owq_part).extension = EXTENSION_BYTE ;
		if ( FS_read_owq(owq_part) < 0 ) {
			OWQ_destroy( owq_part ) ;
			return -EINVAL ;
		}
		for (extension = 0; extension < elements; ++extension) {
			OWQ_array_Y(owq_all,extension) = UT_getbit_U( OWQ_U(owq_part), extension ) ;
		}
		OWQ_destroy( owq_part ) ;
		return 0 ;
	}

	if ( BAD( OWQ_allocate_read_buffer( owq_part )) ) {
		LEVEL_DEBUG("Can't allocate buffer space");
		OWQ_destroy( owq_part ) ;
		return -EMSGSIZE ;
	}

	/* Loop through get data */
	for (extension = 0; extension < elements; ++extension) {
		size_t part_length ;
		OWQ_pn(owq_part).extension = extension;
		if ( FS_read_owq(owq_part) < 0 ) {
			OWQ_destroy( owq_part ) ;
			return -EINVAL ;
		}
		
		// Check that there is enough space for the combined message
		switch ( ft->format ) {
			case ft_ascii:
			case ft_vascii:
			case ft_alias:
			case ft_binary:
				part_length = OWQ_length(owq_part) ;
				if ( buffer_left < part_length ) {
					OWQ_destroy( owq_part ) ;
					return -EMSGSIZE ;
				}
				memcpy( buffer_pointer, OWQ_buffer(owq_part), part_length ) ;
				OWQ_array_length(owq_all,extension) = part_length ;
				buffer_pointer += part_length ;
				buffer_left -= part_length ;
				break ;
			default:
				// copy object (single to mixed array)
				memcpy(&OWQ_array(owq_all)[extension], &OWQ_val(owq_part), sizeof(union value_object));
				break;
		}
	}

	OWQ_destroy( owq_part ) ;
	return 0;
}
Exemplo n.º 9
0
GOOD_OR_BAD OWQ_Cache_Get(struct one_wire_query *owq)
{
	struct parsedname *pn = PN(owq);

	// do check here to avoid needless processing
	if (IsUncachedDir(pn) || IsAlarmDir(pn)) {
		return gbBAD;
	}

	switch (pn->selected_filetype->change) {
	case fc_simultaneous_temperature:
		return Cache_Get_Simultaneous(simul_temp, owq) ;
	case fc_simultaneous_voltage:
		return Cache_Get_Simultaneous(simul_volt, owq) ;
	default:
		break ;
	}

	if (pn->extension == EXTENSION_ALL) {
		switch (pn->selected_filetype->format) {
		case ft_ascii:
		case ft_vascii:
		case ft_alias:
		case ft_binary:
			return gbBAD;			// string arrays not supported
		case ft_integer:
		case ft_unsigned:
		case ft_yesno:
		case ft_date:
		case ft_float:
		case ft_pressure:
		case ft_temperature:
		case ft_tempgap:
			return Cache_Get_Strict(OWQ_array(owq), (pn->selected_filetype->ag->elements) * sizeof(union value_object), pn);
		default:
			return gbBAD;
		}
	} else {
		switch (pn->selected_filetype->format) {
		case ft_ascii:
		case ft_vascii:
		case ft_alias:
		case ft_binary:
			if (OWQ_offset(owq) > 0) {
				return gbBAD;
			}
			OWQ_length(owq) = OWQ_size(owq);
			return Cache_Get(OWQ_buffer(owq), &OWQ_length(owq), pn);
		case ft_integer:
		case ft_unsigned:
		case ft_yesno:
		case ft_date:
		case ft_float:
		case ft_pressure:
		case ft_temperature:
		case ft_tempgap:
			return Cache_Get_Strict(&OWQ_val(owq), sizeof(union value_object), pn);
		default:
			return gbBAD;
		}
	}
}