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.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. #ifndef _GPXE_BUFFER_H
  2. #define _GPXE_BUFFER_H
  3. #include <stdint.h>
  4. #include <errno.h>
  5. #include <gpxe/uaccess.h>
  6. /** @file
  7. *
  8. * Buffers for loading files.
  9. *
  10. * This file provides routines for filling a buffer with data received
  11. * piecemeal, where the size of the data is not necessarily known in
  12. * advance.
  13. *
  14. * Some protocols do not provide a mechanism for us to know the size
  15. * of the file before we happen to receive a particular block
  16. * (e.g. the final block in an MTFTP transfer). In addition, some
  17. * protocols (e.g. the multicast protocols) can, in theory, provide
  18. * the data in any order.
  19. *
  20. * Example usage:
  21. *
  22. * @code
  23. *
  24. * struct buffer my_buffer;
  25. * void *data;
  26. * off_t offset;
  27. * size_t len;
  28. *
  29. * // We have an area of memory [buf_start,buf_start+len) into which to
  30. * // load a file, where buf_start is a userptr_t.
  31. * memset ( &buffer, 0, sizeof ( buffer ) );
  32. * buffer->start = buf_start;
  33. * buffer->len = len;
  34. * ...
  35. * while ( get_file_block ( ... ) ) {
  36. * // Downloaded block is stored in [data,data+len), and represents
  37. * // the portion of the file at offsets [offset,offset+len)
  38. * if ( fill_buffer ( &buffer, data, offset, len ) != 0 ) {
  39. * // An error occurred
  40. * }
  41. * ...
  42. * }
  43. * ...
  44. * // The whole file is now present at [buf_start,buf_start+filesize),
  45. * // where buf_start is a userptr_t. The struct buffer can simply
  46. * // be discarded.
  47. *
  48. * @endcode
  49. *
  50. */
  51. /**
  52. * A data buffer
  53. *
  54. * A buffer looks something like this:
  55. *
  56. * @code
  57. *
  58. * XXXXXXXXXXXXXXXXX.........XXX..........XXXXXXX........XXXXXX.........
  59. *
  60. * ^
  61. * |
  62. * start
  63. *
  64. * <----- fill ---->
  65. *
  66. * <------------------------ free ---------------------------->
  67. *
  68. * <------------------------------ len -------------------------------->
  69. *
  70. * @endcode
  71. *
  72. * #start and #len denote the real boundaries of the buffer. #fill
  73. * denotes the offset to the first free block in the buffer. (If the
  74. * buffer is full, #fill, #free and #len will all be equal.)
  75. *
  76. */
  77. struct buffer {
  78. /** Start of buffer */
  79. userptr_t addr;
  80. /** Total length of buffer */
  81. size_t len;
  82. /** Offset to first free block within buffer */
  83. size_t fill;
  84. /** Offset to last free block within buffer */
  85. size_t free;
  86. /** Expand data buffer
  87. *
  88. * @v buffer Data buffer
  89. * @v new_len New length
  90. * @ret rc Return status code
  91. *
  92. * Expand the data buffer to accommodate more data. This
  93. * method is optional; if it is @c NULL then the buffer will
  94. * not be expandable.
  95. */
  96. int ( * expand ) ( struct buffer *buffer, size_t new_len );
  97. };
  98. extern int fill_buffer ( struct buffer *buffer, const void *data,
  99. size_t offset, size_t len );
  100. extern int expand_buffer ( struct buffer *buffer, size_t new_len );
  101. #endif /* _GPXE_BUFFER_H */