]>
Commit | Line | Data |
---|---|---|
f3c0d7a5 A |
1 | // © 2016 and later: Unicode, Inc. and others. |
2 | // License & terms of use: http://www.unicode.org/copyright.html | |
4388f060 | 3 | // Copyright (C) 2009-2011, International Business Machines |
729e4ab9 A |
4 | // Corporation and others. All Rights Reserved. |
5 | // | |
6 | // Copyright 2007 Google Inc. All Rights Reserved. | |
7 | // Author: sanjay@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 | ||
4388f060 A |
15 | ByteSink::~ByteSink() {} |
16 | ||
729e4ab9 A |
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 | ||
4388f060 A |
36 | CheckedArrayByteSink::~CheckedArrayByteSink() {} |
37 | ||
729e4ab9 A |
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 | } | |
0f5d89e8 A |
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 | } | |
729e4ab9 A |
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 |