Arduino/hardware/arduino/avr/libraries/GSM/GSM3CircularBuffer.cpp

320 lines
6.2 KiB
C++

/*
This file is part of the GSM3 communications library for Arduino
-- Multi-transport communications platform
-- Fully asynchronous
-- Includes code for the Arduino-Telefonica GSM/GPRS Shield V1
-- Voice calls
-- SMS
-- TCP/IP connections
-- HTTP basic clients
This library has been developed by Telefónica Digital - PDI -
- Physical Internet Lab, as part as its collaboration with
Arduino and the Open Hardware Community.
September-December 2012
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
The latest version of this library can always be found at
https://github.com/BlueVia/Official-Arduino
*/
#include "GSM3CircularBuffer.h"
#include <HardwareSerial.h>
GSM3CircularBuffer::GSM3CircularBuffer(GSM3CircularBufferManager* mgr)
{
head=0;
tail=0;
cbm=mgr;
}
int GSM3CircularBuffer::write(char c)
{
byte aux=(tail+1)& __BUFFERMASK__;
if(aux!=head)
{
theBuffer[tail]=c;
// Lets put an extra zero at the end, so we can
// read chains as we like.
// This is not exactly perfect, we are always 1+ behind the head
theBuffer[aux]=0;
tail=aux;
return 1;
}
return 0;
}
char GSM3CircularBuffer::read()
{
char res;
if(head!=tail)
{
res=theBuffer[head];
head=(head+1)& __BUFFERMASK__;
//if(cbm)
// cbm->spaceAvailable();
return res;
}
else
{
return 0;
}
}
char GSM3CircularBuffer::peek(int increment)
{
char res;
byte num_aux;
if (tail>head) num_aux = tail-head;
else num_aux = 128 - head + tail;
if(increment < num_aux)
{
res=theBuffer[head];
return res;
}
else
{
return 0;
}
}
void GSM3CircularBufferManager::spaceAvailable(){return;};
void GSM3CircularBuffer::flush()
{
head=tail;
}
char* GSM3CircularBuffer::nextString()
{
while(head!=tail)
{
head=(head+1) & __BUFFERMASK__;
if(theBuffer[head]==0)
{
head=(head+1) & __BUFFERMASK__;
return (char*)theBuffer+head;
}
}
return 0;
}
bool GSM3CircularBuffer::locate(const char* reference)
{
return locate(reference, head, tail, 0, 0);
}
bool GSM3CircularBuffer::chopUntil(const char* reference, bool movetotheend, bool usehead)
{
byte from, to;
if(locate(reference, head, tail, &from, &to))
{
if(usehead)
{
if(movetotheend)
head=(to+1) & __BUFFERMASK__;
else
head=from;
}
else
{
if(movetotheend)
tail=(to+1) & __BUFFERMASK__;
else
tail=from;
}
return true;
}
else
{
return false;
}
}
bool GSM3CircularBuffer::locate(const char* reference, byte thishead, byte thistail, byte* from, byte* to)
{
int refcursor=0;
bool into=false;
byte b2, binit;
bool possible=1;
if(reference[0]==0)
return true;
for(byte b1=thishead; b1!=thistail;b1=(b1+1)& __BUFFERMASK__)
{
possible = 1;
b2 = b1;
while (possible&&(b2!=thistail))
{
if(theBuffer[b2]==reference[refcursor])
{
if(!into)
binit=b2;
into=true;
refcursor++;
if(reference[refcursor]==0)
{
if(from)
*from=binit;
if(to)
*to=b2;
return true;
}
}
else if (into==true)
{
possible = 0;
into=false;
refcursor=0;
}
b2=(b2+1)& __BUFFERMASK__;
}
}
return false;
}
bool GSM3CircularBuffer::extractSubstring(const char* from, const char* to, char* buffer, int bufsize)
{
byte t1;
byte h2;
byte b;
int i;
//DEBUG
//Serial.println("Beginning extractSubstring");
//Serial.print("head,tail=");Serial.print(int(head));Serial.print(",");Serial.println(int(tail));
if(!locate(from, head, tail, 0, &t1))
return false;
//DEBUG
//Serial.println("Located chain from.");
t1++; //To point the next.
if(!locate(to, t1, tail, &h2, 0))
return false;
//DEBUG
//Serial.println("Located chain to.");
/*Serial.print("t1=");Serial.println(int(t1));
Serial.print("h2=");Serial.println(int(h2));*/
for(i=0,b=t1;i<bufsize, b!=((h2) & __BUFFERMASK__); i++, b=(b+1)& __BUFFERMASK__)
buffer[i]=theBuffer[b];
buffer[i]=0;
//DEBUG
//Serial.println("");
//Serial.println("Finishing extractSubstring");
return true;
}
int GSM3CircularBuffer::readInt()
{
int res=0;
byte c;
bool anyfound=false;
bool negative=false;
for(byte b=head + 1; b!=tail; b=(b+1)& __BUFFERMASK__)
{
c=theBuffer[b];
if((c==' ' )&&(!anyfound))
{
} else if((c=='-' )&&(!anyfound))
{
negative=true;
anyfound=true; // Don't admit blanks after -
} else if((c>='0')&&(c<='9'))
{
anyfound=true;
res=(res*10)+(int)c-48;
}
else
{
if(negative)
res=(-1)*res;
return res;
}
}
if(negative)
res=(-1)*res;
return res;
}
void GSM3CircularBuffer::debugBuffer()
{
byte h1=head;
byte t1=tail;
Serial.println();
Serial.print(h1);
Serial.print(" ");
Serial.print(t1);
Serial.print('>');
for(byte b=h1; b!=t1; b=(b+1)& __BUFFERMASK__)
printCharDebug(theBuffer[b]);
Serial.println();
}
void GSM3CircularBuffer::printCharDebug(uint8_t c)
{
if((c>31)&&(c<127))
Serial.print((char)c);
else
{
Serial.print('%');
Serial.print(c);
Serial.print('%');
}
}
bool GSM3CircularBuffer::retrieveBuffer(char* buffer, int bufsize, int& SizeWritten)
{
byte b;
int i;
/*for(i=0,b=head;i<bufsize, b!=tail; i++, b=(b+1)& __BUFFERMASK__)
{
buffer[i]=theBuffer[b];
}
buffer[i]=0;
SizeWritten = i;*/
b=head;
for(i=0;i<bufsize; i++)
{
if (b!=tail)
{
buffer[i]=theBuffer[b];
buffer[i+1]=0;
b=(b+1)& __BUFFERMASK__;
SizeWritten = i + 1;
}
}
return true;
}