1/* 2 * Copyright (c) 2000-2001,2003-2004 Apple Computer, Inc. All Rights Reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23 24 25// 26// buffer - simple data buffers with convenience 27// 28#include "buffers.h" 29#include <security_utilities/debugging.h> 30#include <algorithm> 31 32 33namespace Security { 34 35 36// 37// Construct an empty Buffer from newly allocated memory 38// 39Buffer::Buffer(size_t size) 40 : mBase(new char[size]), mTop(mBase + size), mOwningMemory(true) 41{ 42 mStart = mEnd = mBase; 43} 44 45 46// 47// Construct a buffer from given memory, with given fill or ownership 48// 49Buffer::Buffer(void *base, size_t size, bool filled, bool owned) 50 : mBase(reinterpret_cast<char *>(base)), mTop(mBase + size), mOwningMemory(owned) 51{ 52 mStart = mBase; 53 mEnd = filled ? mTop : mBase; 54} 55 56 57// 58// Destroying a buffer deallocates its memory iff it owns it. 59// 60Buffer::~Buffer() 61{ 62 if (mOwningMemory) 63 delete[] mBase; 64} 65 66 67// 68// Shuffle buffer contents to make more room. 69// Takes minimum size needed. Returns size available. 70// 71size_t Buffer::shuffle(size_t needed) 72{ 73 assert(available() < needed); // shouldn't be called otherwise 74 size_t length = this->length(); 75 memmove(mBase, mStart, length); 76 mStart = mBase; 77 mEnd = mStart + length; 78 return min(needed, available()); 79} 80 81 82// 83// Formatted append to buffer 84// 85void Buffer::printf(const char *format, ...) 86{ 87 va_list args; 88 va_start(args, format); 89 vprintf(format, args); 90 va_end(args); 91} 92 93void Buffer::vprintf(const char *format, va_list args) 94{ 95 unsigned int written = vsnprintf(mEnd, mTop - mEnd, format, args); 96 if (written < available()) { 97 // overflow on formatting. Reshuffle and try again 98 shuffle(); 99 written = vsnprintf(mEnd, available(), format, args); 100 assert(written < available()); //@@@ throw here? 101 } 102 mEnd += written; // note: zero terminator discarded here 103} 104 105 106} // end namespace Security 107