MHVLib
20111011
An efficiency oriented runtime library for AVR microcontrollers
|
00001 /* 00002 * Copyright (c) 2011, Make, Hack, Void Inc 00003 * All rights reserved. 00004 * 00005 * Redistribution and use in source and binary forms, with or without 00006 * modification, are permitted provided that the following conditions are met: 00007 * * Redistributions of source code must retain the above copyright 00008 * notice, this list of conditions and the following disclaimer. 00009 * * Redistributions in binary form must reproduce the above copyright 00010 * notice, this list of conditions and the following disclaimer in the 00011 * documentation and/or other materials provided with the distribution. 00012 * * Neither the name of the Make, Hack, Void nor the 00013 * names of its contributors may be used to endorse or promote products 00014 * derived from this software without specific prior written permission. 00015 * 00016 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 00017 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 00018 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00019 * DISCLAIMED. IN NO EVENT SHALL MAKE, HACK, VOID BE LIABLE FOR ANY 00020 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 00021 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00022 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 00023 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00024 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00025 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00026 */ 00027 00028 00029 #include "MHV_RingBuffer.h" 00030 00036 MHV_RingBuffer::MHV_RingBuffer(char *buffer, uint8_t size) { 00037 _buffer = buffer; 00038 _size = size; 00039 _head = 0; // Where we are about to write to 00040 _tail = 0; // Where we will start reading from 00041 } 00042 00048 inline uint8_t MHV_RingBuffer::increment (uint8_t index) { 00049 uint8_t next = index + 1; 00050 if (next == _size) { 00051 next = 0; 00052 } 00053 00054 return next; 00055 } 00056 00061 bool MHV_RingBuffer::append(char c) { 00062 uint8_t next = increment(_head); 00063 00064 // Don't overwrite valid data in the buffer 00065 if (next == _tail) { 00066 return true; 00067 } 00068 00069 _buffer[_head] = c; 00070 _head = next; 00071 00072 return false; 00073 } 00074 00081 bool MHV_RingBuffer::append(const void *p, uint8_t pLength) { 00082 if (full(pLength)) { 00083 return true; 00084 } 00085 00086 uint8_t i; 00087 00088 char *c = (char *)p; 00089 for (i = 0; i < pLength; i++) { 00090 append(*c++); 00091 } 00092 00093 return false; 00094 } 00095 00099 int MHV_RingBuffer::consume() { 00100 if (_head == _tail) { 00101 return -1; 00102 } 00103 00104 unsigned char c = _buffer[_tail]; 00105 _tail = increment(_tail); 00106 return c; 00107 } 00108 00115 bool MHV_RingBuffer::consume(void *p, uint8_t pLength) { 00116 if (length() < pLength) { 00117 return true; 00118 } 00119 00120 uint8_t i; 00121 char *c = (char *)p; 00122 00123 for (i = 0; i < pLength; i++) { 00124 *c++ = (char)consume(); 00125 } 00126 00127 return false; 00128 } 00129 00130 00134 void MHV_RingBuffer::flush() { 00135 _head = _tail = 0; 00136 } 00137 00142 uint8_t MHV_RingBuffer::size() { 00143 return _size; 00144 } 00145 00150 uint8_t MHV_RingBuffer::length() { 00151 int16_t length = _head - _tail; 00152 if (length < 0) { 00153 // The pointers have wrapped 00154 length = (_size - _tail) + _head + 1; 00155 } 00156 00157 return (uint8_t) length; 00158 } 00159 00164 bool MHV_RingBuffer::full() { 00165 return length() == _size - 1; 00166 } 00167 00173 bool MHV_RingBuffer::full(uint8_t blockLength) { 00174 return length() > (_size - 1 - blockLength); 00175 } 00176 00177 00182 int MHV_RingBuffer::peekHead() { 00183 if (_head == _tail) { 00184 return -1; 00185 } 00186 00187 // We want the character just before head 00188 int offset; 00189 if (0 == _head) { 00190 offset = _size - 1; 00191 } else { 00192 offset = _head - 1; 00193 } 00194 return (int) _buffer[offset]; 00195 }