bytestream.cpp 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. // © 2016 and later: Unicode, Inc. and others.
  2. // License & terms of use: http://www.unicode.org/copyright.html
  3. // Copyright (C) 2009-2011, International Business Machines
  4. // Corporation and others. All Rights Reserved.
  5. //
  6. // Copyright 2007 Google Inc. All Rights Reserved.
  7. // Author: sanjay@google.com (Sanjay Ghemawat)
  8. #include "unicode/utypes.h"
  9. #include "unicode/bytestream.h"
  10. #include "cmemory.h"
  11. U_NAMESPACE_BEGIN
  12. ByteSink::~ByteSink() {}
  13. char* ByteSink::GetAppendBuffer(int32_t min_capacity,
  14. int32_t /*desired_capacity_hint*/,
  15. char* scratch, int32_t scratch_capacity,
  16. int32_t* result_capacity) {
  17. if (min_capacity < 1 || scratch_capacity < min_capacity) {
  18. *result_capacity = 0;
  19. return nullptr;
  20. }
  21. *result_capacity = scratch_capacity;
  22. return scratch;
  23. }
  24. void ByteSink::Flush() {}
  25. CheckedArrayByteSink::CheckedArrayByteSink(char* outbuf, int32_t capacity)
  26. : outbuf_(outbuf), capacity_(capacity < 0 ? 0 : capacity),
  27. size_(0), appended_(0), overflowed_(false) {
  28. }
  29. CheckedArrayByteSink::~CheckedArrayByteSink() {}
  30. CheckedArrayByteSink& CheckedArrayByteSink::Reset() {
  31. size_ = appended_ = 0;
  32. overflowed_ = false;
  33. return *this;
  34. }
  35. void CheckedArrayByteSink::Append(const char* bytes, int32_t n) {
  36. if (n <= 0) {
  37. return;
  38. }
  39. if (n > (INT32_MAX - appended_)) {
  40. // TODO: Report as integer overflow, not merely buffer overflow.
  41. appended_ = INT32_MAX;
  42. overflowed_ = true;
  43. return;
  44. }
  45. appended_ += n;
  46. int32_t available = capacity_ - size_;
  47. if (n > available) {
  48. n = available;
  49. overflowed_ = true;
  50. }
  51. if (n > 0 && bytes != (outbuf_ + size_)) {
  52. uprv_memcpy(outbuf_ + size_, bytes, n);
  53. }
  54. size_ += n;
  55. }
  56. char* CheckedArrayByteSink::GetAppendBuffer(int32_t min_capacity,
  57. int32_t /*desired_capacity_hint*/,
  58. char* scratch,
  59. int32_t scratch_capacity,
  60. int32_t* result_capacity) {
  61. if (min_capacity < 1 || scratch_capacity < min_capacity) {
  62. *result_capacity = 0;
  63. return nullptr;
  64. }
  65. int32_t available = capacity_ - size_;
  66. if (available >= min_capacity) {
  67. *result_capacity = available;
  68. return outbuf_ + size_;
  69. } else {
  70. *result_capacity = scratch_capacity;
  71. return scratch;
  72. }
  73. }
  74. U_NAMESPACE_END