xref: /third_party/lzma/CPP/Common/DynLimBuf.cpp (revision 370b324c)
1// Common/DynLimBuf.cpp
2
3#include "StdAfx.h"
4
5#include "DynLimBuf.h"
6#include "MyString.h"
7
8CDynLimBuf::CDynLimBuf(size_t limit) throw()
9{
10  _chars = NULL;
11  _pos = 0;
12  _size = 0;
13  _sizeLimit = limit;
14  _error = true;
15  unsigned size = 1 << 4;
16  if (size > limit)
17    size = (unsigned)limit;
18  _chars = (Byte *)MyAlloc(size);
19  if (_chars)
20  {
21    _size = size;
22    _error = false;
23  }
24}
25
26CDynLimBuf & CDynLimBuf::operator+=(char c) throw()
27{
28  if (_error)
29    return *this;
30  if (_size == _pos)
31  {
32    size_t n = _sizeLimit - _size;
33    if (n == 0)
34    {
35      _error = true;
36      return *this;
37    }
38    if (n > _size)
39      n = _size;
40
41    n += _pos;
42
43    Byte *newBuf = (Byte *)MyAlloc(n);
44    if (!newBuf)
45    {
46      _error = true;
47      return *this;
48    }
49    memcpy(newBuf, _chars, _pos);
50    MyFree(_chars);
51    _chars = newBuf;
52    _size = n;
53  }
54  _chars[_pos++] = (Byte)c;
55  return *this;
56}
57
58CDynLimBuf &CDynLimBuf::operator+=(const char *s) throw()
59{
60  if (_error)
61    return *this;
62  unsigned len = MyStringLen(s);
63  size_t rem = _sizeLimit - _pos;
64  if (rem < len)
65  {
66    len = (unsigned)rem;
67    _error = true;
68  }
69  if (_size - _pos < len)
70  {
71    size_t n = _pos + len;
72    if (n - _size < _size)
73    {
74      n = _sizeLimit;
75      if (n - _size > _size)
76        n = _size * 2;
77    }
78
79    Byte *newBuf = (Byte *)MyAlloc(n);
80    if (!newBuf)
81    {
82      _error = true;
83      return *this;
84    }
85    memcpy(newBuf, _chars, _pos);
86    MyFree(_chars);
87    _chars = newBuf;
88    _size = n;
89  }
90  memcpy(_chars + _pos, s, len);
91  _pos += len;
92  return *this;
93}
94