You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

buffer.h 2.9KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. #ifndef BUFFER_H
  2. #define BUFFER_H
  3. #include "compiler.h" /* for doxygen */
  4. #include "stdint.h"
  5. /** @file
  6. *
  7. * Buffers for loading files.
  8. *
  9. * This file provides routines for filling a buffer with data received
  10. * piecemeal, where the size of the data is not necessarily known in
  11. * advance.
  12. *
  13. * Some protocols do not provide a mechanism for us to know the size
  14. * of the file before we happen to receive a particular block
  15. * (e.g. the final block in an MTFTP transfer). In addition, some
  16. * protocols (all the multicast protocols plus any TCP-based protocol)
  17. * can, in theory, provide the data in any order.
  18. *
  19. * Rather than requiring each protocol to implement its own equivalent
  20. * of "dd" to arrange the data into well-sized pieces before handing
  21. * off to the image loader, we provide these generic buffer functions
  22. * which assemble a file into a single contiguous block. The whole
  23. * block is then passed to the image loader.
  24. *
  25. * Example usage:
  26. *
  27. * @code
  28. *
  29. * struct buffer my_buffer;
  30. * void *data;
  31. * off_t offset;
  32. * size_t len;
  33. *
  34. * // We have an area of memory [buf_start,buf_end) into which we want
  35. * // to load a file, where buf_start and buf_end are physical addresses.
  36. * buffer->start = buf_start;
  37. * buffer->end = buf_end;
  38. * init_buffer ( &buffer );
  39. * ...
  40. * while ( get_file_block ( ... ) ) {
  41. * // Downloaded block is stored in [data,data+len), and represents
  42. * // the portion of the file at offsets [offset,offset+len)
  43. * if ( ! fill_buffer ( &buffer, data, offset, len ) ) {
  44. * // An error occurred
  45. * return 0;
  46. * }
  47. * ...
  48. * }
  49. * ...
  50. * // The whole file is now present at [buf_start,buf_start+filesize),
  51. * // where buf_start is a physical address. The struct buffer can simply
  52. * // be discarded; there is no done_buffer() call.
  53. *
  54. * @endcode
  55. *
  56. * For a description of the internal operation, see buffer.c.
  57. *
  58. */
  59. /**
  60. * A buffer
  61. *
  62. * #start and #end denote the real boundaries of the buffer, and are
  63. * physical addresses. #fill denotes the offset to the first free
  64. * block in the buffer. (If the buffer is full, #fill will equal
  65. * #end-#start.)
  66. *
  67. */
  68. struct buffer {
  69. physaddr_t start; /**< Start of buffer in memory */
  70. physaddr_t end; /**< End of buffer in memory */
  71. off_t fill; /**< Offset to first gap in buffer */
  72. };
  73. /**
  74. * A free block descriptor.
  75. *
  76. * See buffer.c for a full description of the fields.
  77. *
  78. */
  79. struct buffer_free_block {
  80. char tail; /**< Tail byte marker */
  81. char reserved[3]; /**< Padding */
  82. physaddr_t start; /**< Address of this free block */
  83. physaddr_t next; /**< Address of next free block */
  84. physaddr_t end; /**< End of this block */
  85. } __attribute__ (( packed ));
  86. /* Functions in buffer.c */
  87. extern void init_buffer ( struct buffer *buffer );
  88. extern int fill_buffer ( struct buffer *buffer, const void *data,
  89. off_t offset, size_t len );
  90. #endif /* BUFFER_H */