blob: 144f5842be632b750fd6c64f69b79c282683a085 [file] [log] [blame]
// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "nacl_io/fifo_char.h"
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
namespace nacl_io {
FIFOChar::FIFOChar(size_t size)
: buffer_(NULL), size_(size), avail_(0), tail_(0) {
if (size) {
buffer_ = (char*)malloc(size);
assert(buffer_ != NULL);
}
}
FIFOChar::~FIFOChar() {
free(buffer_);
}
bool FIFOChar::IsEmpty() {
return avail_ == 0;
}
bool FIFOChar::IsFull() {
return avail_ >= size_;
}
bool FIFOChar::Resize(size_t len) {
// Can not resize smaller than the current size
if (len < avail_)
return false;
// Resize buffer
buffer_ = (char*)realloc(buffer_, len);
assert(buffer_ != NULL);
if (buffer_ == NULL)
return false;
size_ = len;
return true;
}
size_t FIFOChar::ReadAvailable() {
return avail_;
}
size_t FIFOChar::WriteAvailable() {
return size_ - avail_;
}
size_t FIFOChar::Peek(void* buf, size_t len) {
char* ptr = static_cast<char*>(buf);
size_t out = 0;
len = std::min(len, avail_);
size_t offs = tail_;
while (len > 0) {
size_t read_len = std::min(len, size_ - offs);
memcpy(ptr, &buffer_[offs], read_len);
ptr += read_len;
offs += read_len;
if (offs == size_)
offs = 0;
out += read_len;
len -= read_len;
}
return out;
}
size_t FIFOChar::Read(void* buf, size_t len) {
size_t read_len = Peek(buf, len);
if (read_len > 0) {
avail_ -= read_len;
tail_ = (tail_ + read_len) % size_;
}
return read_len;
}
size_t FIFOChar::Write(const void* buf, size_t len) {
const char* ptr = static_cast<const char*>(buf);
size_t out = 0;
size_t room = size_ - avail_;
len = std::min(len, room);
size_t offs = (tail_ + avail_) % size_;
while (len > 0) {
size_t write_len = std::min(len, size_ - offs);
memcpy(&buffer_[offs], ptr, write_len);
ptr += write_len;
offs += write_len;
if (offs == size_)
offs = 0;
out += write_len;
len -= write_len;
}
avail_ += out;
return out;
}
} // namespace nacl_io