inputbuf.c 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. /*++
  2. Copyright (c) Alex Ionescu. All rights reserved.
  3. Module Name:
  4. inputbuf.c
  5. Abstract:
  6. This module implements helper functions for managing the input buffer that
  7. contains arithmetic-coded LZ77 match distance-length pairs and raw literals
  8. Both seeking (such that an external reader can refer to multiple bytes) and
  9. reading (capturing) an individual byte are supported. Support for aligning
  10. input data to 4 bytes (which is a requirement for XZ-encoded files) is also
  11. implemented.
  12. Author:
  13. Alex Ionescu (@aionescu) 15-Apr-2020 - Initial version
  14. Environment:
  15. Windows & Linux, user mode and kernel mode.
  16. --*/
  17. #include "minlzlib.h"
  18. //
  19. // Input Buffer State
  20. //
  21. typedef struct _BUFFER_STATE
  22. {
  23. //
  24. // Start of the buffer, current offset, current packet end, and total input size
  25. //
  26. const uint8_t* Buffer;
  27. uint32_t Offset;
  28. uint32_t SoftLimit;
  29. uint32_t Size;
  30. } BUFFER_STATE, * PBUFFER_STATE;
  31. BUFFER_STATE In;
  32. bool
  33. BfAlign (
  34. void
  35. )
  36. {
  37. uint8_t padByte;
  38. //
  39. // Keep reading until we reach 32-bit alignment. All bytes must be zero.
  40. //
  41. while (In.Offset & 3)
  42. {
  43. if (!BfRead(&padByte) || (padByte != 0))
  44. {
  45. return false;
  46. }
  47. }
  48. return true;
  49. }
  50. bool
  51. BfSetSoftLimit (
  52. uint32_t Remaining
  53. )
  54. {
  55. if ((In.Size - In.Offset) < Remaining)
  56. {
  57. return false;
  58. }
  59. In.SoftLimit = In.Offset + Remaining;
  60. return true;
  61. }
  62. void
  63. BfResetSoftLimit (
  64. void
  65. )
  66. {
  67. In.SoftLimit = In.Size;
  68. }
  69. bool
  70. BfSeek (
  71. uint32_t Length,
  72. const uint8_t** Bytes
  73. )
  74. {
  75. //
  76. // Make sure the input buffer has enough space to seek the desired size, if
  77. // it does, return the current position and then seek past the desired size
  78. //
  79. if ((In.Offset + Length) > In.SoftLimit)
  80. {
  81. *Bytes = 0;
  82. return false;
  83. }
  84. *Bytes = &In.Buffer[In.Offset];
  85. In.Offset += Length;
  86. return true;
  87. }
  88. bool
  89. BfRead (
  90. uint8_t* Byte
  91. )
  92. {
  93. const uint8_t* pByte;
  94. //
  95. // Seek past the byte and read it
  96. //
  97. if (!BfSeek(sizeof(*Byte), &pByte))
  98. {
  99. *Byte = 0;
  100. return false;
  101. }
  102. *Byte = *pByte;
  103. return true;
  104. }
  105. void
  106. BfInitialize (
  107. const uint8_t* InputBuffer,
  108. uint32_t InputSize
  109. )
  110. {
  111. //
  112. // Save all the data in the context buffer state
  113. //
  114. In.Buffer = InputBuffer;
  115. In.Size = InputSize;
  116. In.SoftLimit = InputSize;
  117. In.Offset = 0;
  118. }