static GOOD_OR_BAD OWQ_allocate_array( struct one_wire_query * owq ) { struct parsedname * pn = PN(owq) ; if (pn->extension == EXTENSION_ALL && pn->type != ePN_structure) { OWQ_array(owq) = owcalloc((size_t) pn->selected_filetype->ag->elements, sizeof(union value_object)); if (OWQ_array(owq) == NO_ONE_WIRE_QUERY) { return gbBAD ; } OWQ_cleanup(owq) |= owq_cleanup_array ; } else { OWQ_I(owq) = 0; } return gbGOOD ; }
void OWQ_destroy(struct one_wire_query *owq) { if ( owq == NO_ONE_WIRE_QUERY) { return ; } if ( OWQ_cleanup(owq) & owq_cleanup_buffer ) { owfree(OWQ_buffer(owq)) ; } if ( OWQ_cleanup(owq) & owq_cleanup_rbuffer ) { //owfree(OWQ_read_buffer(owq)) ; } if ( OWQ_cleanup(owq) & owq_cleanup_array ) { owfree(OWQ_array(owq)) ; } if ( OWQ_cleanup(owq) & owq_cleanup_pn ) { FS_ParsedName_destroy(PN(owq)) ; } if ( OWQ_cleanup(owq) & owq_cleanup_owq ) { owfree(owq) ; } else { OWQ_cleanup(owq) = owq_cleanup_none ; } }
// 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 ; }
/* 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; } } }
// 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; }
/* 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; }
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; }
// 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 ; }
// 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; }
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; } } }