seq_buf.h 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. #ifndef _LINUX_SEQ_BUF_H
  2. #define _LINUX_SEQ_BUF_H
  3. #include <linux/fs.h>
  4. /*
  5. * Trace sequences are used to allow a function to call several other functions
  6. * to create a string of data to use.
  7. */
  8. /**
  9. * seq_buf - seq buffer structure
  10. * @buffer: pointer to the buffer
  11. * @size: size of the buffer
  12. * @len: the amount of data inside the buffer
  13. * @readpos: The next position to read in the buffer.
  14. */
  15. struct seq_buf {
  16. char *buffer;
  17. size_t size;
  18. size_t len;
  19. loff_t readpos;
  20. };
  21. static inline void seq_buf_clear(struct seq_buf *s)
  22. {
  23. s->len = 0;
  24. s->readpos = 0;
  25. }
  26. static inline void
  27. seq_buf_init(struct seq_buf *s, unsigned char *buf, unsigned int size)
  28. {
  29. s->buffer = buf;
  30. s->size = size;
  31. seq_buf_clear(s);
  32. }
  33. /*
  34. * seq_buf have a buffer that might overflow. When this happens
  35. * the len and size are set to be equal.
  36. */
  37. static inline bool
  38. seq_buf_has_overflowed(struct seq_buf *s)
  39. {
  40. return s->len > s->size;
  41. }
  42. static inline void
  43. seq_buf_set_overflow(struct seq_buf *s)
  44. {
  45. s->len = s->size + 1;
  46. }
  47. /*
  48. * How much buffer is left on the seq_buf?
  49. */
  50. static inline unsigned int
  51. seq_buf_buffer_left(struct seq_buf *s)
  52. {
  53. if (seq_buf_has_overflowed(s))
  54. return 0;
  55. return s->size - s->len;
  56. }
  57. /* How much buffer was written? */
  58. static inline unsigned int seq_buf_used(struct seq_buf *s)
  59. {
  60. return min(s->len, s->size);
  61. }
  62. /**
  63. * seq_buf_get_buf - get buffer to write arbitrary data to
  64. * @s: the seq_buf handle
  65. * @bufp: the beginning of the buffer is stored here
  66. *
  67. * Return the number of bytes available in the buffer, or zero if
  68. * there's no space.
  69. */
  70. static inline size_t seq_buf_get_buf(struct seq_buf *s, char **bufp)
  71. {
  72. WARN_ON(s->len > s->size + 1);
  73. if (s->len < s->size) {
  74. *bufp = s->buffer + s->len;
  75. return s->size - s->len;
  76. }
  77. *bufp = NULL;
  78. return 0;
  79. }
  80. /**
  81. * seq_buf_commit - commit data to the buffer
  82. * @s: the seq_buf handle
  83. * @num: the number of bytes to commit
  84. *
  85. * Commit @num bytes of data written to a buffer previously acquired
  86. * by seq_buf_get. To signal an error condition, or that the data
  87. * didn't fit in the available space, pass a negative @num value.
  88. */
  89. static inline void seq_buf_commit(struct seq_buf *s, int num)
  90. {
  91. if (num < 0) {
  92. seq_buf_set_overflow(s);
  93. } else {
  94. /* num must be negative on overflow */
  95. BUG_ON(s->len + num > s->size);
  96. s->len += num;
  97. }
  98. }
  99. extern __printf(2, 3)
  100. int seq_buf_printf(struct seq_buf *s, const char *fmt, ...);
  101. extern __printf(2, 0)
  102. int seq_buf_vprintf(struct seq_buf *s, const char *fmt, va_list args);
  103. extern int seq_buf_print_seq(struct seq_file *m, struct seq_buf *s);
  104. extern int seq_buf_to_user(struct seq_buf *s, char __user *ubuf,
  105. int cnt);
  106. extern int seq_buf_puts(struct seq_buf *s, const char *str);
  107. extern int seq_buf_putc(struct seq_buf *s, unsigned char c);
  108. extern int seq_buf_putmem(struct seq_buf *s, const void *mem, unsigned int len);
  109. extern int seq_buf_putmem_hex(struct seq_buf *s, const void *mem,
  110. unsigned int len);
  111. extern int seq_buf_path(struct seq_buf *s, const struct path *path, const char *esc);
  112. #ifdef CONFIG_BINARY_PRINTF
  113. extern int
  114. seq_buf_bprintf(struct seq_buf *s, const char *fmt, const u32 *binary);
  115. #endif
  116. #endif /* _LINUX_SEQ_BUF_H */