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 (at) google.com (Sanjay Ghemawat) 8 9 #include "unicode/utypes.h" 10 #include "unicode/bytestream.h" 11 #include "cmemory.h" 12 13 U_NAMESPACE_BEGIN 14 15 ByteSink::~ByteSink() {} 16 17 char* ByteSink::GetAppendBuffer(int32_t min_capacity, 18 int32_t /*desired_capacity_hint*/, 19 char* scratch, int32_t scratch_capacity, 20 int32_t* result_capacity) { 21 if (min_capacity < 1 || scratch_capacity < min_capacity) { 22 *result_capacity = 0; 23 return NULL; 24 } 25 *result_capacity = scratch_capacity; 26 return scratch; 27 } 28 29 void ByteSink::Flush() {} 30 31 CheckedArrayByteSink::CheckedArrayByteSink(char* outbuf, int32_t capacity) 32 : outbuf_(outbuf), capacity_(capacity < 0 ? 0 : capacity), 33 size_(0), appended_(0), overflowed_(FALSE) { 34 } 35 36 CheckedArrayByteSink::~CheckedArrayByteSink() {} 37 38 CheckedArrayByteSink& CheckedArrayByteSink::Reset() { 39 size_ = appended_ = 0; 40 overflowed_ = FALSE; 41 return *this; 42 } 43 44 void CheckedArrayByteSink::Append(const char* bytes, int32_t n) { 45 if (n <= 0) { 46 return; 47 } 48 if (n > (INT32_MAX - appended_)) { 49 // TODO: Report as integer overflow, not merely buffer overflow. 50 appended_ = INT32_MAX; 51 overflowed_ = TRUE; 52 return; 53 } 54 appended_ += n; 55 int32_t available = capacity_ - size_; 56 if (n > available) { 57 n = available; 58 overflowed_ = TRUE; 59 } 60 if (n > 0 && bytes != (outbuf_ + size_)) { 61 uprv_memcpy(outbuf_ + size_, bytes, n); 62 } 63 size_ += n; 64 } 65 66 char* CheckedArrayByteSink::GetAppendBuffer(int32_t min_capacity, 67 int32_t /*desired_capacity_hint*/, 68 char* scratch, 69 int32_t scratch_capacity, 70 int32_t* result_capacity) { 71 if (min_capacity < 1 || scratch_capacity < min_capacity) { 72 *result_capacity = 0; 73 return NULL; 74 } 75 int32_t available = capacity_ - size_; 76 if (available >= min_capacity) { 77 *result_capacity = available; 78 return outbuf_ + size_; 79 } else { 80 *result_capacity = scratch_capacity; 81 return scratch; 82 } 83 } 84 85 U_NAMESPACE_END 86