Each field_name (one element of field_names) is now dynamically allocated. This allows the field name to be copied via strcpy directly into the field_name. The field_names array is now NULL-terminated. All lines of code that depended on the previous behavior (empty string-terminated list), including one in the test driver, have been updated with this new assumption. This change also removes BC_FIELD_SIZE, which is no longer needed because there are no more statically-sized string buffers, only statically-sized arrays that store strings.
To implement this update, the following changes were made: - bc_decode_format interface changed to accept char** and drop length - bc_decode_format performs memory allocation for decoded track data - BC_*DECODED_SIZE were removed - bc_decoded_free was added to free the allocated decoded track data - driver now checks for NULL decoded track data (previously unneeded) As a side effect of updates to bc_decode to use the new bc_decode_format interface, the code for accepting input data was also made more robust by adding checks for NULL input track data.
Instead of being statically-allocated in the library, the memory for struct bc_input is now managed by the user of the library. The test drivers have been updated to reflect this; they each allocate their own static buffers which are passed into the struct bc_input. As a side-effect, bc_combine now allocates memory since it is the owner of the struct bc_input "combined". The user of bc_combine must thus free the output using the new function bc_input_free. Because of the change, bc_init no longer accepts a struct bc_input because no initialization is required anymore. This also eliminates the meaning ambiguity with the function name -- does it mean initialize a struct bc_input or initialize the library? It now means initialize the library.
The field decoding part of the library has been broken out of bc_decode and put in bc_find_fields instead. In the case of an error, this makes it easier for a user of the library to see where that error occurred: during the bit decoding stage or the field decoding (finding) stage.
Previously the driver did not print the encoding type, even though that information was returned in struct bc_decoded. Now the encoding is printed along with the rest of the information in struct bc_decoded. This changes adds the encoding_to_str function to the driver. This function should probably be in the library. I will add it to the library once I determine what the standard way is to do constant to string conversions.
Make name an element in struct bc_decoded instead of a specially-handled field in the fields list. This is much cleaner. Fixed a minor bug that may have caused garbage to be returned if the formats file were empty. Now initializing the name and fields list before starting to process the formats file. The last commit (9dfe947) introduced a minor bug fix to correct the value of rc if bc_decode_track_fields on track 3 returns 0. The fix failed to make the commit log so it is being mentioned now.
The main change here is that bc_decode now processes all tracks at once instead of processing each track individually. The library now uses a struct bc_input and struct bc_decoded to specify the input and output data. All parts of the library and driver work with this change. There are still some minor issues, including track awareness in the field list, but they will be fixed soon. The other main, but less important, change is the removal of all dynamic memory allocation. This was done after analyzing the memory footprint tradeoff of static allocation, which turned out to be around 20 kilobytes. Since that size will only be an issue for very tiny embedded devices, static allocation was chosen. This change also allows the library user to take advantage of the buffers created by the library instead of allocating its own. A minor change included in this commit is a change in the storing of field data. Instead of using one array that contains field names in the even indices and field values in the odd indices, this version uses separate arrays for the names and values. This simplifies the code a fair bit and makes it easier to read. The change was made easier by the decision to use static allocation (no need to optimize on the number of malloc calls).