str.c revision 33ca6b017b6ebbd048651b5e3d16915001dbc291
bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/*
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen Copyright (c) 2002 Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
e05a4c4136fec723f019bee8383103080203f127Timo Sirainen Permission is hereby granted, free of charge, to any person obtaining
50c617761ee9653bd44646a95178773a3686d62eTimo Sirainen a copy of this software and associated documentation files (the
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen "Software"), to deal in the Software without restriction, including
e2d268e9531227ead6a98466ecf3c046c857ef70Timo Sirainen without limitation the rights to use, copy, modify, merge, publish,
2b9dbb270ad82e58d5f3581436e6f143176d5819Timo Sirainen distribute, sublicense, and/or sell copies of the Software, and to
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen permit persons to whom the Software is furnished to do so, subject to
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen the following conditions:
c04f9a724a7b3cc649485a61b0a540868d25d71bTimo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen The above copyright notice and this permission notice shall be
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen included in all copies or substantial portions of the Software.
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen
128ea07dab8d67124ea74bcc085a478784b6358aTimo Sirainen THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
c04f9a724a7b3cc649485a61b0a540868d25d71bTimo Sirainen OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
e2d268e9531227ead6a98466ecf3c046c857ef70Timo Sirainen MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
e2d268e9531227ead6a98466ecf3c046c857ef70Timo Sirainen IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
c04f9a724a7b3cc649485a61b0a540868d25d71bTimo Sirainen CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
d1fbd2c264368d8b4c7139b96e3b21f45930b857Timo Sirainen TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen*/
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
eb0816090cf5a549280ad783b9aa6fec199d36baTimo Sirainen/* @UNSAFE: whole file */
eb0816090cf5a549280ad783b9aa6fec199d36baTimo Sirainen
9f19a50d5966643c4d1c5ca06868ac2ad31bc4d5Timo Sirainen#include "lib.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "buffer.h"
c04f9a724a7b3cc649485a61b0a540868d25d71bTimo Sirainen#include "str.h"
c51390c3ae6e373e7b4a052a94e8e4065b98321cAki Tuomi
e2d268e9531227ead6a98466ecf3c046c857ef70Timo Sirainen#include <stdio.h>
661998e2ccd772ad92a9d4a75cb712692a8c94b3Timo Sirainen
eb0816090cf5a549280ad783b9aa6fec199d36baTimo SirainenString *str_new(Pool pool, size_t initial_size)
eb0816090cf5a549280ad783b9aa6fec199d36baTimo Sirainen{
2b9dbb270ad82e58d5f3581436e6f143176d5819Timo Sirainen return buffer_create_dynamic(pool, initial_size, (size_t)-1);
900bb5e316d030cdebff7ee128ce65881dfb27f7Timo Sirainen}
50c617761ee9653bd44646a95178773a3686d62eTimo Sirainen
661998e2ccd772ad92a9d4a75cb712692a8c94b3Timo SirainenString *t_str_new(size_t initial_size)
d4002fe1f64d25a792f76fb102ef7dc519cd4e24Martti Rannanjärvi{
661998e2ccd772ad92a9d4a75cb712692a8c94b3Timo Sirainen return str_new(data_stack_pool, initial_size);
50c617761ee9653bd44646a95178773a3686d62eTimo Sirainen}
50c617761ee9653bd44646a95178773a3686d62eTimo Sirainen
50c617761ee9653bd44646a95178773a3686d62eTimo Sirainenstatic int str_add_nul(String *str)
50c617761ee9653bd44646a95178773a3686d62eTimo Sirainen{
661998e2ccd772ad92a9d4a75cb712692a8c94b3Timo Sirainen size_t len;
d4002fe1f64d25a792f76fb102ef7dc519cd4e24Martti Rannanjärvi
661998e2ccd772ad92a9d4a75cb712692a8c94b3Timo Sirainen len = str_len(str);
50c617761ee9653bd44646a95178773a3686d62eTimo Sirainen if (buffer_write(str, len, "", 1) != 1) {
50c617761ee9653bd44646a95178773a3686d62eTimo Sirainen /* no space - doesn't happen with our dynamically growing
50c617761ee9653bd44646a95178773a3686d62eTimo Sirainen strings though, but make sure it's \0 terminated. */
50c617761ee9653bd44646a95178773a3686d62eTimo Sirainen if (len == 0)
eb0816090cf5a549280ad783b9aa6fec199d36baTimo Sirainen return FALSE;
897368f75a68f97e172ba76540759a10c557f1c3Timo Sirainen
50c617761ee9653bd44646a95178773a3686d62eTimo Sirainen len--;
50c617761ee9653bd44646a95178773a3686d62eTimo Sirainen if (buffer_write(str, len, "", 1) != 1)
50c617761ee9653bd44646a95178773a3686d62eTimo Sirainen i_panic("BUG in str_c()");
50c617761ee9653bd44646a95178773a3686d62eTimo Sirainen }
eb0816090cf5a549280ad783b9aa6fec199d36baTimo Sirainen
eb0816090cf5a549280ad783b9aa6fec199d36baTimo Sirainen /* remove the \0 - we don't want to keep it */
eb0816090cf5a549280ad783b9aa6fec199d36baTimo Sirainen buffer_set_used_size(str, len);
eb0816090cf5a549280ad783b9aa6fec199d36baTimo Sirainen return TRUE;
01937f71b3ae0d5b30b813372f44a3e7e86c89dcTimo Sirainen}
e2d268e9531227ead6a98466ecf3c046c857ef70Timo Sirainen
e2d268e9531227ead6a98466ecf3c046c857ef70Timo Sirainenconst char *str_c(String *str)
e2d268e9531227ead6a98466ecf3c046c857ef70Timo Sirainen{
e2d268e9531227ead6a98466ecf3c046c857ef70Timo Sirainen if (!str_add_nul(str))
e2d268e9531227ead6a98466ecf3c046c857ef70Timo Sirainen return "";
c04f9a724a7b3cc649485a61b0a540868d25d71bTimo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return buffer_get_data(str, NULL);
c04f9a724a7b3cc649485a61b0a540868d25d71bTimo Sirainen}
eb0816090cf5a549280ad783b9aa6fec199d36baTimo Sirainen
c04f9a724a7b3cc649485a61b0a540868d25d71bTimo Sirainenchar *str_c_modifyable(String *str)
1f1ee8db68d9ae1604350801cd8dc33ebe29fe8aTimo Sirainen{
eb0816090cf5a549280ad783b9aa6fec199d36baTimo Sirainen if (!str_add_nul(str))
8828d7a1e76b7d301bcd7385aa27c52512e855ceTimo Sirainen return NULL;
8828d7a1e76b7d301bcd7385aa27c52512e855ceTimo Sirainen
eb0816090cf5a549280ad783b9aa6fec199d36baTimo Sirainen return buffer_get_modifyable_data(str, NULL);
eb0816090cf5a549280ad783b9aa6fec199d36baTimo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
897368f75a68f97e172ba76540759a10c557f1c3Timo Sirainensize_t str_len(const String *str)
897368f75a68f97e172ba76540759a10c557f1c3Timo Sirainen{
1460ef7a18c53216ddb4a94bb62fba96076aae8eTimo Sirainen return buffer_get_used_size(str);
897368f75a68f97e172ba76540759a10c557f1c3Timo Sirainen}
eb0816090cf5a549280ad783b9aa6fec199d36baTimo Sirainen
e2d268e9531227ead6a98466ecf3c046c857ef70Timo Sirainenvoid str_append(String *str, const char *cstr)
e2d268e9531227ead6a98466ecf3c046c857ef70Timo Sirainen{
e2d268e9531227ead6a98466ecf3c046c857ef70Timo Sirainen buffer_append(str, cstr, strlen(cstr));
e2d268e9531227ead6a98466ecf3c046c857ef70Timo Sirainen}
e2d268e9531227ead6a98466ecf3c046c857ef70Timo Sirainen
e2d268e9531227ead6a98466ecf3c046c857ef70Timo Sirainenvoid str_append_n(String *str, const char *cstr, size_t max_len)
e2d268e9531227ead6a98466ecf3c046c857ef70Timo Sirainen{
e2d268e9531227ead6a98466ecf3c046c857ef70Timo Sirainen size_t len;
103b44c67f38862d1e72c9bfdf11f067b4670675Timo Sirainen
103b44c67f38862d1e72c9bfdf11f067b4670675Timo Sirainen len = 0;
c04f9a724a7b3cc649485a61b0a540868d25d71bTimo Sirainen while (len < max_len && cstr[len] != '\0')
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen len++;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen buffer_append(str, cstr, len);
c04f9a724a7b3cc649485a61b0a540868d25d71bTimo Sirainen}
c04f9a724a7b3cc649485a61b0a540868d25d71bTimo Sirainen
d6badc27cd6e8d3398877b6766cb0aaeef3a7800Timo Sirainenvoid str_append_c(String *str, char chr)
c04f9a724a7b3cc649485a61b0a540868d25d71bTimo Sirainen{
c51390c3ae6e373e7b4a052a94e8e4065b98321cAki Tuomi buffer_append_c(str, chr);
eb0816090cf5a549280ad783b9aa6fec199d36baTimo Sirainen}
acfeae4e2b5c2acdab88a1377ff6cd4a9b5f0a3aTimo Sirainen
acfeae4e2b5c2acdab88a1377ff6cd4a9b5f0a3aTimo Sirainenvoid str_append_str(String *dest, const String *src)
acfeae4e2b5c2acdab88a1377ff6cd4a9b5f0a3aTimo Sirainen{
acfeae4e2b5c2acdab88a1377ff6cd4a9b5f0a3aTimo Sirainen const char *cstr;
acfeae4e2b5c2acdab88a1377ff6cd4a9b5f0a3aTimo Sirainen size_t len;
897368f75a68f97e172ba76540759a10c557f1c3Timo Sirainen
897368f75a68f97e172ba76540759a10c557f1c3Timo Sirainen cstr = buffer_get_data(src, &len);
1460ef7a18c53216ddb4a94bb62fba96076aae8eTimo Sirainen buffer_append(dest, cstr, len);
897368f75a68f97e172ba76540759a10c557f1c3Timo Sirainen}
01937f71b3ae0d5b30b813372f44a3e7e86c89dcTimo Sirainen
c04f9a724a7b3cc649485a61b0a540868d25d71bTimo Sirainenvoid str_printfa(String *str, const char *fmt, ...)
c04f9a724a7b3cc649485a61b0a540868d25d71bTimo Sirainen{
c04f9a724a7b3cc649485a61b0a540868d25d71bTimo Sirainen va_list args;
d6badc27cd6e8d3398877b6766cb0aaeef3a7800Timo Sirainen
d6badc27cd6e8d3398877b6766cb0aaeef3a7800Timo Sirainen va_start(args, fmt);
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen str_vprintfa(str, fmt, args);
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen va_end(args);
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen}
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainenvoid str_vprintfa(String *str, const char *fmt, va_list args)
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen{
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen char *buf;
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen size_t len;
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen len = buffer_get_used_size(str);
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen buf = buffer_append_space(str, printf_string_upper_bound(fmt, args));
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen len += vsprintf(buf, fmt, args);
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen buffer_set_used_size(str, len);
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen}
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainenvoid str_delete(String *str, size_t pos, size_t len)
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen{
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen buffer_delete(str, pos, len);
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen}
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainenvoid str_truncate(String *str, size_t len)
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen{
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen buffer_set_used_size(str, len);
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen}
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen