AP_ROMFS.cpp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. /*
  2. This program is free software: you can redistribute it and/or modify
  3. it under the terms of the GNU General Public License as published by
  4. the Free Software Foundation, either version 3 of the License, or
  5. (at your option) any later version.
  6. This program is distributed in the hope that it will be useful,
  7. but WITHOUT ANY WARRANTY; without even the implied warranty of
  8. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  9. GNU General Public License for more details.
  10. You should have received a copy of the GNU General Public License
  11. along with this program. If not, see <http://www.gnu.org/licenses/>.
  12. */
  13. /*
  14. implement a file store for embedded firmware images
  15. */
  16. #include "AP_ROMFS.h"
  17. #include "tinf.h"
  18. #ifdef HAL_HAVE_AP_ROMFS_EMBEDDED_H
  19. #include <ap_romfs_embedded.h>
  20. #else
  21. const AP_ROMFS::embedded_file AP_ROMFS::files[] = {};
  22. #endif
  23. /*
  24. find an embedded file
  25. */
  26. const uint8_t *AP_ROMFS::find_file(const char *name, uint32_t &size)
  27. {
  28. for (uint16_t i=0; i<ARRAY_SIZE(files); i++) {
  29. if (strcmp(name, files[i].filename) == 0) {
  30. size = files[i].size;
  31. return files[i].contents;
  32. }
  33. }
  34. return nullptr;
  35. }
  36. /*
  37. find a compressed file and uncompress it. Space for decompressed
  38. data comes from malloc. Caller must be careful to free the resulting
  39. data after use. The next byte after the file data is guaranteed to
  40. be null
  41. */
  42. uint8_t *AP_ROMFS::find_decompress(const char *name, uint32_t &size)
  43. {
  44. uint32_t compressed_size;
  45. const uint8_t *compressed_data = find_file(name, compressed_size);
  46. if (!compressed_data) {
  47. return nullptr;
  48. }
  49. // last 4 bytes of gzip file are length of decompressed data
  50. const uint8_t *p = &compressed_data[compressed_size-4];
  51. uint32_t decompressed_size = p[0] | p[1] << 8 | p[2] << 16 | p[3] << 24;
  52. uint8_t *decompressed_data = (uint8_t *)malloc(decompressed_size + 1);
  53. if (!decompressed_data) {
  54. return nullptr;
  55. }
  56. // explicitly null terimnate the data
  57. decompressed_data[decompressed_size] = 0;
  58. TINF_DATA *d = (TINF_DATA *)malloc(sizeof(TINF_DATA));
  59. if (!d) {
  60. free(decompressed_data);
  61. return nullptr;
  62. }
  63. uzlib_uncompress_init(d, NULL, 0);
  64. d->source = compressed_data;
  65. d->source_limit = compressed_data + compressed_size - 4;
  66. // assume gzip format
  67. int res = uzlib_gzip_parse_header(d);
  68. if (res != TINF_OK) {
  69. free(decompressed_data);
  70. free(d);
  71. return nullptr;
  72. }
  73. d->dest = decompressed_data;
  74. d->destSize = decompressed_size;
  75. // we don't check CRC, as it just wastes flash space for constant
  76. // ROMFS data
  77. res = uzlib_uncompress(d);
  78. free(d);
  79. if (res != TINF_OK) {
  80. free(decompressed_data);
  81. return nullptr;
  82. }
  83. size = decompressed_size;
  84. return decompressed_data;
  85. }