File: SC_StringBuffer.cpp

package info (click to toggle)
supercollider 1%3A3.13.0%2Brepack-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 80,292 kB
  • sloc: cpp: 476,363; lisp: 84,680; ansic: 77,685; sh: 25,509; python: 7,909; makefile: 3,440; perl: 1,964; javascript: 974; xml: 826; java: 677; yacc: 314; lex: 175; objc: 152; ruby: 136
file content (106 lines) | stat: -rw-r--r-- 3,230 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
// emacs:		-*- c++ -*-
// file:		SC_StringBuffer.cpp
// copyright:	2003 stefan kersten <steve@k-hornz.de>
// cvs:			$Id$

// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
// USA

#include "SC_StringBuffer.h"
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <stdexcept>

#ifdef _WIN32
#    define vsnprintf _vsnprintf
#    include <stdio.h>
#    include <stdarg.h>
#endif

#include <string>

SC_StringBuffer::SC_StringBuffer(size_t initialSize): mCapacity(0), mPtr(0), mData(0) { growBy(initialSize); }

SC_StringBuffer::SC_StringBuffer(const SC_StringBuffer& other): mCapacity(0), mPtr(0), mData(0) {
    growBy(other.getSize());
    append(other.getData(), other.getSize());
}

SC_StringBuffer::~SC_StringBuffer() { free(mData); }

void SC_StringBuffer::append(const char* src, size_t size) {
    if (size > 0) {
        size_t remaining = getRemaining();
        if (size > remaining) {
            growBy(size - remaining);
        }
        memcpy(mPtr, src, size);
        mPtr += size;
    }
}

void SC_StringBuffer::append(char c) { append(&c, sizeof(c)); }

void SC_StringBuffer::append(const char* str) { append(str, strlen(str)); }

void SC_StringBuffer::vappendf(const char* fmt, va_list ap) {
    va_list ap2;
    size_t remaining = getRemaining();

    // Calling vsnprintf may invalidate vargs, so keep a copy
    va_copy(ap2, ap);

    // NOTE: This only works since glibc 2.0.6!
    int size = vsnprintf(mPtr, remaining, fmt, ap);
    va_end(ap);

    // size returned excludes trailing \0
    if (size++ > 0) {
        if ((size_t)size > remaining) {
            growBy(size - remaining);
            vsnprintf(mPtr, size, fmt, ap2);
        }
        mPtr += size - 1; // omit trailing \0
    }

    va_end(ap2);
}

void SC_StringBuffer::appendf(const char* fmt, ...) {
    va_list ap;
    va_start(ap, fmt);
    vappendf(fmt, ap);
    va_end(ap);
}

void SC_StringBuffer::growBy(size_t request) {
    size_t oldSize = getSize();
    size_t newCapacity = mCapacity + ((request + (size_t)kGrowAlign) & (size_t)~kGrowMask);

    // 	fprintf(stderr, "%s: mCapacity %u, request %u, newCapacity %u\n",
    // 			__PRETTY_FUNCTION__, mCapacity, request, newCapacity);
    assert((newCapacity >= (mCapacity + request)) && ((newCapacity & kGrowMask) == 0));

    char* newData = (char*)realloc(mData, newCapacity);
    if (newData) {
        mData = newData;
        mCapacity = newCapacity;
        mPtr = mData + oldSize;
    } else
        throw std::runtime_error(std::string("SC_StringBuffer: memory allocation failure"));
}

// EOF