1228753Smm/*- 2228753Smm * Copyright (c) 2003-2007 Tim Kientzle 3228753Smm * All rights reserved. 4228753Smm * 5228753Smm * Redistribution and use in source and binary forms, with or without 6228753Smm * modification, are permitted provided that the following conditions 7228753Smm * are met: 8228753Smm * 1. Redistributions of source code must retain the above copyright 9228753Smm * notice, this list of conditions and the following disclaimer. 10228753Smm * 2. Redistributions in binary form must reproduce the above copyright 11228753Smm * notice, this list of conditions and the following disclaimer in the 12228753Smm * documentation and/or other materials provided with the distribution. 13228753Smm * 14228753Smm * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR 15228753Smm * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16228753Smm * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17228753Smm * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, 18228753Smm * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19228753Smm * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20228753Smm * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21228753Smm * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22228753Smm * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23228753Smm * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24228753Smm * 25229592Smm * $FreeBSD$ 26228753Smm * 27228753Smm */ 28228753Smm 29228753Smm#ifndef __LIBARCHIVE_BUILD 30228753Smm#error This header is only to be used internally to libarchive. 31228753Smm#endif 32228753Smm 33228753Smm#ifndef ARCHIVE_STRING_H_INCLUDED 34228753Smm#define ARCHIVE_STRING_H_INCLUDED 35228753Smm 36228753Smm#include <stdarg.h> 37228753Smm#ifdef HAVE_STDLIB_H 38228753Smm#include <stdlib.h> /* required for wchar_t on some systems */ 39228753Smm#endif 40228753Smm#ifdef HAVE_STRING_H 41228753Smm#include <string.h> 42228753Smm#endif 43228753Smm#ifdef HAVE_WCHAR_H 44228753Smm#include <wchar.h> 45228753Smm#endif 46228753Smm 47228753Smm#include "archive.h" 48228753Smm 49228753Smm/* 50228753Smm * Basic resizable/reusable string support a la Java's "StringBuffer." 51228753Smm * 52228753Smm * Unlike sbuf(9), the buffers here are fully reusable and track the 53228753Smm * length throughout. 54228753Smm * 55228753Smm * Note that all visible symbols here begin with "__archive" as they 56228753Smm * are internal symbols not intended for anyone outside of this library 57228753Smm * to see or use. 58228753Smm */ 59228753Smm 60228753Smmstruct archive_string { 61228753Smm char *s; /* Pointer to the storage */ 62228753Smm size_t length; /* Length of 's' */ 63228753Smm size_t buffer_length; /* Length of malloc-ed storage */ 64228753Smm}; 65228753Smm 66228753Smm/* Initialize an archive_string object on the stack or elsewhere. */ 67228753Smm#define archive_string_init(a) \ 68228753Smm do { (a)->s = NULL; (a)->length = 0; (a)->buffer_length = 0; } while(0) 69228753Smm 70228753Smm/* Append a C char to an archive_string, resizing as necessary. */ 71228753Smmstruct archive_string * 72228753Smm__archive_strappend_char(struct archive_string *, char); 73228753Smm#define archive_strappend_char __archive_strappend_char 74228753Smm 75228753Smm/* Convert a wide-char string to UTF-8 and append the result. */ 76228753Smmstruct archive_string * 77228753Smm__archive_strappend_w_utf8(struct archive_string *, const wchar_t *); 78228753Smm#define archive_strappend_w_utf8 __archive_strappend_w_utf8 79228753Smm 80228753Smm/* Convert a wide-char string to current locale and append the result. */ 81228753Smm/* Returns NULL if conversion fails. */ 82228753Smmstruct archive_string * 83228753Smm__archive_strappend_w_mbs(struct archive_string *, const wchar_t *); 84228753Smm#define archive_strappend_w_mbs __archive_strappend_w_mbs 85228753Smm 86228753Smm/* Basic append operation. */ 87228753Smmstruct archive_string * 88228753Smm__archive_string_append(struct archive_string *as, const char *p, size_t s); 89228753Smm 90228753Smm/* Copy one archive_string to another */ 91228753Smmvoid 92228753Smm__archive_string_copy(struct archive_string *dest, struct archive_string *src); 93228753Smm#define archive_string_copy(dest, src) \ 94228753Smm __archive_string_copy(dest, src) 95228753Smm 96228753Smm/* Concatenate one archive_string to another */ 97228753Smmvoid 98228753Smm__archive_string_concat(struct archive_string *dest, struct archive_string *src); 99228753Smm#define archive_string_concat(dest, src) \ 100228753Smm __archive_string_concat(dest, src) 101228753Smm 102228753Smm/* Ensure that the underlying buffer is at least as large as the request. */ 103228753Smmstruct archive_string * 104228753Smm__archive_string_ensure(struct archive_string *, size_t); 105228753Smm#define archive_string_ensure __archive_string_ensure 106228753Smm 107228753Smm/* Append C string, which may lack trailing \0. */ 108228753Smm/* The source is declared void * here because this gets used with 109228753Smm * "signed char *", "unsigned char *" and "char *" arguments. 110228753Smm * Declaring it "char *" as with some of the other functions just 111228753Smm * leads to a lot of extra casts. */ 112228753Smmstruct archive_string * 113228753Smm__archive_strncat(struct archive_string *, const void *, size_t); 114228753Smm#define archive_strncat __archive_strncat 115228753Smm 116228753Smm/* Append a C string to an archive_string, resizing as necessary. */ 117228753Smm#define archive_strcat(as,p) __archive_string_append((as),(p),strlen(p)) 118228753Smm 119228753Smm/* Copy a C string to an archive_string, resizing as necessary. */ 120228753Smm#define archive_strcpy(as,p) \ 121228753Smm ((as)->length = 0, __archive_string_append((as), (p), p == NULL ? 0 : strlen(p))) 122228753Smm 123228753Smm/* Copy a C string to an archive_string with limit, resizing as necessary. */ 124228753Smm#define archive_strncpy(as,p,l) \ 125228753Smm ((as)->length=0, archive_strncat((as), (p), (l))) 126228753Smm 127228753Smm/* Return length of string. */ 128228753Smm#define archive_strlen(a) ((a)->length) 129228753Smm 130228753Smm/* Set string length to zero. */ 131228753Smm#define archive_string_empty(a) ((a)->length = 0) 132228753Smm 133228753Smm/* Release any allocated storage resources. */ 134228753Smmvoid __archive_string_free(struct archive_string *); 135228753Smm#define archive_string_free __archive_string_free 136228753Smm 137228753Smm/* Like 'vsprintf', but resizes the underlying string as necessary. */ 138228753Smmvoid __archive_string_vsprintf(struct archive_string *, const char *, 139228753Smm va_list) __LA_PRINTF(2, 0); 140228753Smm#define archive_string_vsprintf __archive_string_vsprintf 141228753Smm 142228753Smmvoid __archive_string_sprintf(struct archive_string *, const char *, ...) 143228753Smm __LA_PRINTF(2, 3); 144228753Smm#define archive_string_sprintf __archive_string_sprintf 145228753Smm 146228753Smm/* Allocates a fresh buffer and converts as (assumed to be UTF-8) into it. 147228753Smm * Returns NULL if conversion failed in any way. */ 148228753Smmwchar_t *__archive_string_utf8_w(struct archive_string *as); 149228753Smm 150228753Smm 151228753Smm#endif 152