/src/aspell/common/string.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | // This file is part of The New Aspell |
2 | | // Copyright (C) 2001 by Kevin Atkinson under the GNU LGPL license |
3 | | // version 2.0 or 2.1. You should have received a copy of the LGPL |
4 | | // license along with this library if you did not you can find |
5 | | // it at http://www.gnu.org/. |
6 | | |
7 | | #include <stdarg.h> |
8 | | #include <stdio.h> |
9 | | |
10 | | #ifndef va_copy |
11 | | # ifdef __va_copy |
12 | | # define va_copy __va_copy |
13 | | # else |
14 | | # define va_copy(dst, src) memcpy(&dst, &src, sizeof(va_list)) |
15 | | # endif |
16 | | #endif |
17 | | |
18 | | #include "string.hpp" |
19 | | #include "asc_ctype.hpp" |
20 | | |
21 | | namespace acommon { |
22 | | |
23 | | // reserve space for at least s+1 characters |
24 | | void String::reserve_i(size_t s) |
25 | 648k | { |
26 | 648k | size_t old_size = end_ - begin_; |
27 | 648k | size_t new_size = (storage_end_ - begin_) * 3 / 2; |
28 | 648k | if (new_size < 64) new_size = 64; |
29 | 648k | if (new_size < s + 1) new_size = s + 1; |
30 | 648k | if (old_size == 0) { |
31 | 614k | if (begin_) free(begin_); |
32 | 614k | begin_ = (char *)malloc(new_size); |
33 | 614k | } else { |
34 | 34.0k | begin_ = (char *)realloc(begin_, new_size); |
35 | 34.0k | } |
36 | 648k | end_ = begin_ + old_size; |
37 | 648k | storage_end_ = begin_ + new_size; |
38 | 648k | } |
39 | | |
40 | | int String::vprintf(const char * format, va_list ap0) |
41 | 0 | { |
42 | 0 | reserve(size() + 64); |
43 | 0 | int res = 0; |
44 | 0 | va_list ap; |
45 | 0 | loop: { |
46 | 0 | int avail = storage_end_ - end_; |
47 | 0 | if (res < 0 && avail > 1024*1024) |
48 | 0 | return -1; // to avoid an infinite loop in case a neg result |
49 | | // really means an error and not just "not enough |
50 | | // space" |
51 | 0 | va_copy(ap,ap0); |
52 | 0 | res = vsnprintf(end_, avail, format, ap); |
53 | 0 | va_end(ap); |
54 | 0 | if (res < 0) { |
55 | 0 | reserve_i(); goto loop; |
56 | 0 | } else if (res > avail) { |
57 | 0 | reserve_i(size() + res); goto loop; |
58 | 0 | } |
59 | 0 | } |
60 | 0 | end_ += res; |
61 | 0 | return res; |
62 | 0 | } |
63 | | |
64 | | bool StringIStream::append_line(String & str, char d) |
65 | 459 | { |
66 | 459 | if (in_str[0] == '\0') return false; |
67 | 306 | const char * end = in_str; |
68 | 5.96k | while (*end != d && *end != '\0') ++end; |
69 | 306 | str.append(in_str, end - in_str); |
70 | 306 | in_str = end; |
71 | 306 | if (*in_str == d) ++in_str; |
72 | 306 | return true; |
73 | 459 | } |
74 | | |
75 | | bool StringIStream::read(void * data, unsigned int size) |
76 | 0 | { |
77 | 0 | char * str = static_cast<char *>(data); |
78 | 0 | while (*in_str != '\0' && size != 0) { |
79 | 0 | *str = *in_str; |
80 | 0 | ++in_str; |
81 | 0 | ++str; |
82 | 0 | ++size; |
83 | 0 | } |
84 | 0 | return size == 0; |
85 | 0 | } |
86 | | } |