1// Copyright (c) 2013 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "nacl_io/fifo_char.h" 6 7#include <assert.h> 8#include <stdlib.h> 9#include <string.h> 10 11#include <algorithm> 12 13namespace nacl_io { 14 15FIFOChar::FIFOChar(size_t size) 16 : buffer_(NULL), size_(size), avail_(0), tail_(0) { 17 if (size) { 18 buffer_ = (char*)malloc(size); 19 assert(buffer_ != NULL); 20 } 21} 22 23FIFOChar::~FIFOChar() { 24 free(buffer_); 25} 26 27bool FIFOChar::IsEmpty() { 28 return avail_ == 0; 29} 30 31bool FIFOChar::IsFull() { 32 return avail_ >= size_; 33} 34 35bool FIFOChar::Resize(size_t len) { 36 // Can not resize smaller than the current size 37 if (len < avail_) 38 return false; 39 40 // Resize buffer 41 buffer_ = (char*)realloc(buffer_, len); 42 assert(buffer_ != NULL); 43 if (buffer_ == NULL) 44 return false; 45 size_ = len; 46 return true; 47} 48 49size_t FIFOChar::ReadAvailable() { 50 return avail_; 51} 52 53size_t FIFOChar::WriteAvailable() { 54 return size_ - avail_; 55} 56 57size_t FIFOChar::Peek(void* buf, size_t len) { 58 char* ptr = static_cast<char*>(buf); 59 60 size_t out = 0; 61 len = std::min(len, avail_); 62 63 size_t offs = tail_; 64 while (len > 0) { 65 size_t read_len = std::min(len, size_ - offs); 66 memcpy(ptr, &buffer_[offs], read_len); 67 68 ptr += read_len; 69 offs += read_len; 70 71 if (offs == size_) 72 offs = 0; 73 74 out += read_len; 75 len -= read_len; 76 } 77 78 return out; 79} 80 81size_t FIFOChar::Read(void* buf, size_t len) { 82 size_t read_len = Peek(buf, len); 83 if (read_len > 0) { 84 avail_ -= read_len; 85 tail_ = (tail_ + read_len) % size_; 86 } 87 return read_len; 88} 89 90size_t FIFOChar::Write(const void* buf, size_t len) { 91 const char* ptr = static_cast<const char*>(buf); 92 size_t out = 0; 93 size_t room = size_ - avail_; 94 len = std::min(len, room); 95 96 size_t offs = (tail_ + avail_) % size_; 97 while (len > 0) { 98 size_t write_len = std::min(len, size_ - offs); 99 memcpy(&buffer_[offs], ptr, write_len); 100 101 ptr += write_len; 102 offs += write_len; 103 if (offs == size_) 104 offs = 0; 105 106 out += write_len; 107 len -= write_len; 108 } 109 110 avail_ += out; 111 return out; 112} 113 114} // namespace nacl_io 115