15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Copyright (c) 2011 The Chromium Authors. All rights reserved.
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Use of this source code is governed by a BSD-style license that can be
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * found in the LICENSE file.
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdarg.h>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
99ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "ppapi/native_client/src/untrusted/nacl_ppapi_util/string_buffer.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace nacl {
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)StringBuffer::StringBuffer() {
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  nbytes_ = 1024;
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  insert_ = 0;
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  buffer_ = reinterpret_cast<char *>(malloc(nbytes_));
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (NULL == buffer_) {
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    perror("StringBuffer Ctor malloc");
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    abort();
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  buffer_[0] = '\0';
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void StringBuffer::DiscardOutput() {
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  insert_ = 0;
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  buffer_[0] = '\0';
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)StringBuffer::~StringBuffer() {
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  nbytes_ = 0;
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  insert_ = 0;
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  free(buffer_);
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  buffer_ = NULL;
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void StringBuffer::Printf(char const *fmt, ...) {
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t space;
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char *insert_pt;
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  va_list ap;
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t written = 0;
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char *new_buffer;
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (;;) {
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    space = nbytes_ - insert_;
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    insert_pt = buffer_ + insert_;
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    va_start(ap, fmt);
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    written = vsnprintf(insert_pt, space, fmt, ap);
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    va_end(ap);
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (written < space) {
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      insert_ += written;
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // insufficient space -- grow the buffer
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_buffer = reinterpret_cast<char *>(realloc(buffer_, 2 * nbytes_));
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (NULL == new_buffer) {
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // give up
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      fprintf(stderr, "StringBufferPrintf: no memory\n");
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    nbytes_ *= 2;
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    buffer_ = new_buffer;
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace nacl
66