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 <stdlib.h> 8#include <string.h> 9 10#include <algorithm> 11 12namespace nacl_io { 13 14FIFOChar::FIFOChar(size_t size) 15 : buffer_(NULL), size_(size), avail_(0), tail_(0) { 16 if (size) 17 buffer_ = new char[size]; 18} 19 20FIFOChar::~FIFOChar() { 21 delete[] buffer_; 22} 23 24bool FIFOChar::IsEmpty() { 25 return avail_ == 0; 26} 27 28bool FIFOChar::IsFull() { 29 return avail_ >= size_; 30} 31 32bool FIFOChar::Resize(size_t len) { 33 // Can not resize smaller than the current size 34 if (len < avail_) 35 return false; 36 37 // Read current data into new buffer 38 char* data = new char[len]; 39 avail_ = Read(data, avail_); 40 41 // Replace buffer 42 delete[] buffer_; 43 buffer_ = data; 44 size_ = len; 45 return true; 46} 47 48size_t FIFOChar::ReadAvailable() { 49 return avail_; 50} 51 52size_t FIFOChar::WriteAvailable() { 53 return size_ - avail_; 54} 55 56size_t FIFOChar::Peek(void* buf, size_t len) { 57 char* ptr = static_cast<char*>(buf); 58 59 size_t out = 0; 60 len = std::min(len, avail_); 61 62 size_t offs = tail_; 63 while (len > 0) { 64 size_t read_len = std::min(len, size_ - offs); 65 memcpy(ptr, &buffer_[offs], read_len); 66 67 ptr += read_len; 68 offs += read_len; 69 70 if (offs == size_) 71 offs = 0; 72 73 out += read_len; 74 len -= read_len; 75 } 76 77 return out; 78} 79 80size_t FIFOChar::Read(void* buf, size_t len) { 81 size_t read_len = Peek(buf, len); 82 if (read_len > 0) { 83 avail_ -= read_len; 84 tail_ = (tail_ + read_len) % size_; 85 } 86 return read_len; 87} 88 89size_t FIFOChar::Write(const void* buf, size_t len) { 90 const char* ptr = static_cast<const char*>(buf); 91 size_t out = 0; 92 size_t room = size_ - avail_; 93 len = std::min(len, room); 94 95 size_t offs = (tail_ + avail_) % size_; 96 while (len > 0) { 97 size_t write_len = std::min(len, size_ - offs); 98 memcpy(&buffer_[offs], ptr, write_len); 99 100 ptr += write_len; 101 offs += write_len; 102 if (offs == size_) 103 offs = 0; 104 105 out += write_len; 106 len -= write_len; 107 } 108 109 avail_ += out; 110 return out; 111} 112 113} // namespace nacl_io 114