bufblock.c 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. /*
  2. * This file is part of the UCB release of Plan 9. It is subject to the license
  3. * terms in the LICENSE file found in the top-level directory of this
  4. * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
  5. * part of the UCB release of Plan 9, including this file, may be copied,
  6. * modified, propagated, or distributed except according to the terms contained
  7. * in the LICENSE file.
  8. */
  9. #include "mk.h"
  10. static Bufblock *freelist;
  11. #define QUANTA 4096
  12. Bufblock *
  13. newbuf(void)
  14. {
  15. Bufblock *p;
  16. if (freelist) {
  17. p = freelist;
  18. freelist = freelist->next;
  19. } else {
  20. p = (Bufblock *) Malloc(sizeof(Bufblock));
  21. p->start = Malloc(QUANTA*sizeof(*p->start));
  22. p->end = p->start+QUANTA;
  23. }
  24. p->current = p->start;
  25. *p->start = 0;
  26. p->next = 0;
  27. return p;
  28. }
  29. void
  30. freebuf(Bufblock *p)
  31. {
  32. p->next = freelist;
  33. freelist = p;
  34. }
  35. void
  36. growbuf(Bufblock *p)
  37. {
  38. int n;
  39. Bufblock *f;
  40. char *cp;
  41. n = p->end-p->start+QUANTA;
  42. /* search the free list for a big buffer */
  43. for (f = freelist; f; f = f->next) {
  44. if (f->end-f->start >= n) {
  45. memcpy(f->start, p->start, p->end-p->start);
  46. cp = f->start;
  47. f->start = p->start;
  48. p->start = cp;
  49. cp = f->end;
  50. f->end = p->end;
  51. p->end = cp;
  52. f->current = f->start;
  53. break;
  54. }
  55. }
  56. if (!f) { /* not found - grow it */
  57. p->start = Realloc(p->start, n);
  58. p->end = p->start+n;
  59. }
  60. p->current = p->start+n-QUANTA;
  61. }
  62. void
  63. bufcpy(Bufblock *buf, char *cp, int n)
  64. {
  65. while (n--)
  66. insert(buf, *cp++);
  67. }
  68. void
  69. insert(Bufblock *buf, int c)
  70. {
  71. if (buf->current >= buf->end)
  72. growbuf(buf);
  73. *buf->current++ = c;
  74. }
  75. void
  76. rinsert(Bufblock *buf, Rune r)
  77. {
  78. int n;
  79. n = runelen(r);
  80. if (buf->current+n > buf->end)
  81. growbuf(buf);
  82. runetochar(buf->current, &r);
  83. buf->current += n;
  84. }