boxscript-interperter-c/source/parser.cpp

985 lines
28 KiB
C++
Raw Permalink Normal View History

2022-12-01 03:27:30 +00:00
#include "parser.hpp"
#include <algorithm>
#include <cstring>
namespace BoxScript
{
void IApplicationState::AddThreadOwner()
{
}
void IApplicationState::RemoveThreadOwner()
{
}
void SubscopeApplicationState::AddThreadOwner()
{
this->state->AddThreadOwner();
this->threads++;
}
void SubscopeApplicationState::RemoveThreadOwner()
{
this->state->RemoveThreadOwner();
if(this->threads <= 0)
{
delete this;
}
}
ApplicationState::ApplicationState()
{
this->isRunning=true;
this->NoBoxes=0;
this->NoExpressions=0;
this->NoStreams=0;
}
int64_t ApplicationState::CreateBox(string text)
{
int64_t boxId=this->NoBoxes++;
if(this->boxes.count(boxId) <= 0)
{
this->boxes.insert({boxId,{vector<int64_t>(), false}});
}
for(int i =0;i<text.length();i++)
{
this->boxes[boxId].first.push_back(text[i]);
}
return boxId;
}
Expression* ApplicationState::Calln(int64_t e)
{
if(this->expressions.count(e) > 0)
{
return expressions[e];
}
return new ConstantNumber("0");
}
int64_t ApplicationState::ReadByteFromStream(int64_t streamId)
{
Stream* strm = GetStream(streamId);
return strm->ReadByte();
}
int64_t ApplicationState::CreateBufferedStream(int64_t existingStreamId)
{
Stream* strm = GetStream(existingStreamId);
return CreateStream(new BufferedStream(strm));
}
int64_t ApplicationState::e2n(Expression* e)
{
int64_t eId = this->NoExpressions++;
this->expressions.insert({eId,e});
return eId;
}
string ApplicationState::BoxToString(int64_t boxId)
{
string s ="";
if(boxes.count(boxId) == 0)
{
throw exception();
}
else
{
for(int i =0;i<boxes[boxId].first.size();i++)
{
char c = (char)(boxes[boxId].first[i] % 256);
s+= c;
}
}
return s;
}
int64_t ApplicationState::CreateBox(int boxLen)
{
int64_t i = NoBoxes++;
if(this->boxes.count(i) <= 0)
{
this->boxes.insert({i,{vector<int64_t>(), false}});
}
this->boxes[i].first.reserve(boxLen);
return i;
}
void ApplicationState::AddRuntimeFunction(string str,internal_func func)
{
if(!HasRuntimeFunction(str))
{
runtime_funcs.insert({str,func});
}
}
void ApplicationState::DestroyBox(int64_t boxId)
{
if(boxes.count(boxId) == 0) return;
if(!boxes[boxId].second)
{
boxes[boxId].first.clear();
boxes.erase(boxId);
}
}
int64_t ApplicationState::CreateStream(Stream* strm)
{
int64_t i = NoStreams++;
streams.insert({i,strm});
return i;
}
int64_t ApplicationState::GetBoxValue(int64_t bId,int index)
{
if(boxes.count(bId) == 0)
{
throw exception();
}else
{
if(index>boxes[bId].first.size())
{
throw exception();
}else{
return boxes[bId].first[index];
}
}
}
void ApplicationState::SetBoxValue(int64_t bId,int index,int64_t value)
{
if(value > 2147483647) throw exception();
if(boxes.count(bId) == 0)
{
throw exception();
}
else
{
if(boxes[bId].second) throw new exception();
if(index > boxes[bId].first.size())
{
throw exception();
}else{
boxes[bId].first[index] = value;
}
}
}
bool ApplicationState::HasVariable(string name)
{
return variables.count(name) > 0;
}
int64_t ApplicationState::GetVariable(string name)
{
if(variables.count(name) > 0)
{
return variables[name];
}else{
return 0;
}
}
IApplicationState* ApplicationState::NewScope()
{
return new SubscopeApplicationState(this);
}
void ApplicationState::SetVariable(string name,int64_t value)
{
if(variables.count(name) > 0)
{
variables[name]=value;
}else{
variables.insert({name,value});
}
}
void ApplicationState::ClearBox(int64_t bId)
{
if(boxes.count(bId) == 0)
{
throw exception();
}
else
{
if(boxes[bId].second) throw exception();
boxes[bId].first.clear();
}
}
void ApplicationState::AddToBox(int64_t bId,int64_t value)
{
if(boxes.count(bId) == 0)
{
throw exception();
}else
{
if(boxes[bId].second) throw exception();
boxes[bId].first.push_back(value);
}
}
void ApplicationState::RemoveFromBox(int64_t bId,int64_t value)
{
if(boxes.count(bId)==0)
{
throw exception();
}
else
{
if(boxes[bId].second) throw exception();
vector<int64_t>::iterator itr= find(boxes[bId].first.begin(),boxes[bId].first.end(),value);
if(itr < boxes[bId].first.end())
{
boxes[bId].first.erase(itr);
}
}
}
void ApplicationState::RemoveAtFromBox(int64_t bId,int index)
{
if(boxes.count(bId)==0)
{
throw exception();
}
else
{
if(boxes[bId].second) throw exception();
vector<int64_t>::iterator itr= boxes[bId].first.begin() + index;
if(itr < boxes[bId].first.end())
{
boxes[bId].first.erase(itr);
}
}
}
void ApplicationState::InsertToBox(int64_t bId,int index,int64_t value)
{
if(boxes.count(bId)==0)
{
throw exception();
}
else
{
if(boxes[bId].second) throw exception();
vector<int64_t>::iterator itr= boxes[bId].first.begin() + index;
if(itr != boxes[bId].first.end())
{
boxes[bId].first.insert(itr,value);
}
}
}
int64_t ApplicationState::BoxLength(int64_t boxId)
{
if(boxes.count(boxId)==0)
{
throw exception();
}
else
{
return boxes[boxId].first.size();
}
}
bool ApplicationState::HasRuntimeFunction(string str)
{
return runtime_funcs.count(str) > 0;
}
internal_func ApplicationState::GetRuntimeFunction(string str)
{
return runtime_funcs[str];
}
int64_t ApplicationState::ExecuteFunction(string str,vector<Expression*> expressions)
{
if(!HasFunction(str)) return 0;
//var func=methods[str]
IApplicationState* res = NewScope();
res->AddThreadOwner();
for(int i = 0;i<min(expressions.size(),methods[str].first.size());i++)
{
res->SetVariable(methods[str].first[i],expressions[i]->Evaluate(res));
}
int64_t result= methods[str].second->Evaluate(res);
res->RemoveThreadOwner();
return result;
}
int64_t ApplicationState::CreateBoxPermanent(string text)
{
int64_t boxId=this->NoBoxes++;
if(this->boxes.count(boxId) <= 0)
{
this->boxes.insert({boxId,{vector<int64_t>(), true}});
}
for(int i =0;i<text.length();i++)
{
this->boxes[boxId].first.push_back(text[i]);
}
return boxId;
}
bool ApplicationState::HasFunction(string str)
{
return methods.count(str) > 0;
}
void ApplicationState::AddFunction(string str,vector<string> args,Expression* exp)
{
if(!HasFunction(str))
{
methods.insert({str,{args,exp}});
}
}
void ApplicationState::CopyStream(int64_t src,int64_t dest)
{
if(streams.count(src) == 0 || streams.count(dest) == 0) return;
GetStream(src)->CopyTo(GetStream(dest));
}
Stream* ApplicationState::GetStream(int64_t streamId)
{
if(streams.count(streamId) == 0) throw exception();
return streams[streamId];
}
void ApplicationState::CloseStream(int64_t streamId)
{
if(streams.count(streamId)==0) throw exception();
streams[streamId]->Close();
delete streams[streamId];
streams.erase(streamId);
}
void ApplicationState::WriteToStream(int64_t streamId,int64_t boxId,int64_t offset,int64_t len)
{
if(streams.count(streamId) == 0) return;
Stream* strm=GetStream(streamId);
if(!strm->CanWrite())return;
size_t len2=boxes[boxId].first.size();
len2-=offset;
int64_t len3=min(len,(int64_t)len2);
uint8_t data[len3];
for(int64_t i = 0;i<len3;i++)
{
uint8_t byte=(uint8_t)boxes[boxId].first[i+offset];
data[i] = byte;
}
strm->Write(data,(size_t)len3);
}
int64_t ApplicationState::ReadFromStream(int64_t streamId,int64_t boxId,int64_t offset,int64_t len)
{
if(streams.count(streamId) == 0) return 0;
Stream* strm=GetStream(streamId);
if(boxes[boxId].second || !strm->CanRead()) return 0;
size_t len2=boxes[boxId].first.size();
len2-=offset;
int64_t len3=min(len,(int64_t)len2);
uint8_t data[len3];
len3=strm->Read(data,len3);
for(int64_t i = 0;i<len3;i++)
{
boxes[boxId].first[i+offset]=data[i];
}
return len3;
}
void ApplicationState::SetStreamPosition(int64_t streamId,int64_t streamPos)
{
if(streams.count(streamId) == 0) return;
Stream* strm=GetStream(streamId);
if(!strm->CanSeek()) return;
strm->SetPosition(streamPos);
}
int64_t ApplicationState::GetStreamLength(int64_t streamId)
{
if(streams.count(streamId) == 0) return 0;
Stream* strm=GetStream(streamId);
return strm->GetLength();
}
int64_t ApplicationState::GetStreamPosition(int64_t streamId)
{
if(streams.count(streamId) == 0) return 0;
Stream* strm=GetStream(streamId);
if(!strm->CanSeek()) return 0;
return strm->GetPosition();
}
bool ApplicationState::CanRead(int64_t streamId)
{
if(streams.count(streamId) == 0) return false;
return GetStream(streamId)->CanRead();
}
bool ApplicationState::CanWrite(int64_t streamId)
{
if(streams.count(streamId) == 0) return false;
return GetStream(streamId)->CanWrite();
}
bool ApplicationState::CanSeek(int64_t streamId)
{
if(streams.count(streamId) == 0) return false;
return GetStream(streamId)->CanSeek();
}
void ApplicationState::FlushStream(int64_t streamId)
{
if(streams.count(streamId) == 0) return;
GetStream(streamId)->Flush();
}
#pragma region SubscopeApplicationState
SubscopeApplicationState::SubscopeApplicationState(IApplicationState* _state)
{
this->threads=0;
this->state=_state;
}
internal_func SubscopeApplicationState::GetRuntimeFunction(string str)
{
return this->state->GetRuntimeFunction(str);
}
void SubscopeApplicationState::FlushStream(int64_t stream)
{
this->state->FlushStream(stream);
}
void SubscopeApplicationState::DestroyBox(int64_t id)
{
this->state->DestroyBox(id);
}
int64_t SubscopeApplicationState::e2n(Expression* e)
{
return this->state->e2n(e);
}
Expression* SubscopeApplicationState::Calln(int64_t e)
{
return this->state->Calln(e);
}
int64_t SubscopeApplicationState::CreateStream(Stream* strm)
{
return this->state->CreateStream(strm);
}
void SubscopeApplicationState::CopyStream(int64_t strmSrc,int64_t strmDest)
{
this->state->CopyStream(strmSrc,strmDest);
}
void SubscopeApplicationState::CloseStream(int64_t streamId)
{
this->state->CloseStream(streamId);
}
void SubscopeApplicationState::WriteToStream(int64_t streamId,int64_t boxId,int64_t offset,int64_t len)
{
this->state->WriteToStream(streamId,boxId,offset,len);
}
int64_t SubscopeApplicationState::ReadFromStream(int64_t streamId,int64_t boxId,int64_t offset,int64_t len)
{
return this->state->ReadFromStream(streamId,boxId,offset,len);
}
void SubscopeApplicationState::SetStreamPosition(int64_t streamId,int64_t streamPos)
{
this->state->SetStreamPosition(streamId,streamPos);
}
int64_t SubscopeApplicationState::GetStreamPosition(int64_t streamId)
{
return this->state->GetStreamPosition(streamId);
}
int64_t SubscopeApplicationState::GetStreamLength(int64_t streamId)
{
return this->state->GetStreamLength(streamId);
}
bool SubscopeApplicationState::CanRead(int64_t streamId)
{
return this->state->CanRead(streamId);
}
bool SubscopeApplicationState::CanWrite(int64_t streamId)
{
return this->state->CanWrite(streamId);
}
bool SubscopeApplicationState::CanSeek(int64_t streamId)
{
return this->state->CanSeek(streamId);
}
int64_t SubscopeApplicationState::ExecuteFunction(string str,vector<Expression*> expressions)
{
return this->state->ExecuteFunction(str,expressions);
}
bool SubscopeApplicationState::HasRuntimeFunction(string str)
{
return this->state->HasRuntimeFunction(str);
}
bool SubscopeApplicationState::HasFunction(string str)
{
return this->state->HasFunction(str);
}
void SubscopeApplicationState::AddFunction(string str,vector<string> args,Expression* exp)
{
this->state->AddFunction(str,args,exp);
}
void SubscopeApplicationState::AddRuntimeFunction(string str,internal_func func)
{
this->state->AddRuntimeFunction(str,func);
}
string SubscopeApplicationState::BoxToString(int64_t boxId)
{
return this->state->BoxToString(boxId);
}
void SubscopeApplicationState::ClearBox(int64_t bId)
{
this->state->ClearBox(bId);
}
int64_t SubscopeApplicationState::ReadByteFromStream(int64_t streamId)
{
return this->state->ReadByteFromStream(streamId);
}
int64_t SubscopeApplicationState::CreateBufferedStream(int64_t existingStreamId)
{
return this->state->CreateBufferedStream(existingStreamId);
}
void SubscopeApplicationState::AddToBox(int64_t bId,int64_t value)
{
this->state->AddToBox(bId,value);
}
void SubscopeApplicationState::RemoveFromBox(int64_t bId,int64_t value)
{
this->state->RemoveFromBox(bId,value);
}
void SubscopeApplicationState::RemoveAtFromBox(int64_t bId,int index)
{
this->state->RemoveAtFromBox(bId,index);
}
void SubscopeApplicationState::InsertToBox(int64_t bId,int index,int64_t value)
{
this->state->InsertToBox(bId,index,value);
}
void SubscopeApplicationState::SetBoxValue(int64_t bId,int index,int64_t value)
{
this->state->SetBoxValue(bId,index,value);
}
int64_t SubscopeApplicationState::BoxLength(int64_t boxId)
{
return this->state->BoxLength(boxId);
}
int64_t SubscopeApplicationState::CreateBox(int len)
{
return this->state->CreateBox(len);
}
int64_t SubscopeApplicationState::CreateBox(string text)
{
return this->state->CreateBox(text);
}
int64_t SubscopeApplicationState::CreateBoxPermanent(string text)
{
return this->state->CreateBoxPermanent(text);
}
int64_t SubscopeApplicationState::GetBoxValue(int64_t bId, int index)
{
return this->state->GetBoxValue(bId,index);
}
bool SubscopeApplicationState::HasVariable(string name)
{
return variables.count(name) > 0 || (name.substr(0,4) != "cur." && this->state->HasVariable(name));
}
void SubscopeApplicationState::SetVariable(string name,int64_t value)
{
if(name.substr(0,4) != "cur." && state->HasVariable(name))
{
this->state->SetVariable(name,value);
}else{
if(this->variables.count(name) > 0)
{
variables[name]=value;
}else{
variables.insert({name,value});
}
}
}
int64_t SubscopeApplicationState::GetVariable(string name)
{
if(name.substr(0,4) != "cur." && state->HasVariable(name))
{
return this->state->GetVariable(name);
}else{
if(this->variables.count(name) > 0) return this->variables[name];
}
return 0;
}
IApplicationState* SubscopeApplicationState::NewScope()
{
return new SubscopeApplicationState(this);
}
#pragma endregion
void Stream::CopyTo(Stream* strm)
{
uint8_t buffer[4096];
size_t read;
do
{
read = this->Read(buffer,4096);
strm->Write(buffer,read);
} while (read != 0);
}
ExpressionStream::ExpressionStream(IApplicationState* state,vector<Expression*> expressions)
{
this->st = state;
this->exp = exp;
}
void ExpressionStream::Write(uint8_t* data,size_t len)
{
int64_t box = st->CreateBox((int64_t)len);
IApplicationState* newSc = st->NewScope();
newSc->AddThreadOwner();
newSc->SetVariable("stream_count_value",len);
newSc->SetVariable("stream_buffer",box);
for(size_t i = 0;i<len;i++)
{
st->AddToBox(box,data[i]);
}
exp[1]->Evaluate(newSc);
newSc->DestroyBox(box);
newSc->RemoveThreadOwner();
}
size_t ExpressionStream::Read(uint8_t* data,size_t len)
{
int64_t box = st->CreateBox((int64_t)len);
IApplicationState* newSc = st->NewScope();
newSc->AddThreadOwner();
newSc->SetVariable("stream_count_value",len);
newSc->SetVariable("stream_buffer",box);
size_t read = (size_t)exp[0]->Evaluate(newSc);
for(size_t i = 0;i<min(read,len);i++)
{
uint8_t v = (uint8_t)st->GetBoxValue(box,(int)i);
data[i]=v;
}
newSc->DestroyBox(box);
newSc->RemoveThreadOwner();
return min(read,len);
}
int64_t ExpressionStream::GetPosition()
{
//3
return exp[3]->Evaluate(st);
}
int64_t ExpressionStream::GetLength()
{
//4
return exp[4]->Evaluate(st) > 0;
}
void ExpressionStream::SetPosition(int64_t pos)
{
//2
IApplicationState* newSc = st->NewScope();
newSc->AddThreadOwner();
newSc->SetVariable("stream_length_value",pos);
exp[2]->Evaluate(newSc);
newSc->RemoveThreadOwner();
}
void ExpressionStream::Flush()
{
//8
exp[8]->Evaluate(st);
}
void ExpressionStream::Close()
{
//9
exp[9]->Evaluate(st);
}
bool ExpressionStream::CanRead()
{
//5
return exp[5]->Evaluate(st) > 0;
}
bool ExpressionStream::CanWrite()
{
//6
return exp[6]->Evaluate(st) > 0;
}
bool ExpressionStream::CanSeek()
{
//7
return exp[7]->Evaluate(st) > 0;
}
FileStream::FileStream(FILE* fs,bool canRead,bool canWrite,bool canSeek,bool ownFile)
{
this->f=fs;
this->cr = canRead;
this->cw = canWrite;
this->cs = canSeek;
this->own=ownFile;
}
bool FileStream::CanSeek()
{
return this->cs;
}
bool FileStream::CanRead()
{
return this->cr;
}
bool FileStream::CanWrite()
{
return this->cw;
}
void FileStream::Write(uint8_t* data,size_t len)
{
if(!cw) return;
fwrite(data,1,len,f);
}
size_t FileStream::Read(uint8_t* data,size_t len)
{
if(!cr) return 0;
return fread(data,1,len,f);
}
void FileStream::Flush()
{
fflush(f);
}
void FileStream::Close()
{
if(own)
fclose(f);
}
int64_t FileStream::GetPosition()
{
if(!cs) return 0;
return (int64_t)ftello(f);
}
int64_t FileStream::GetLength()
{
if(!cs) return 0;
fpos_t pos;
fgetpos(f,&pos);
fseeko(f,0,SEEK_END);
int64_t len= (int64_t)ftello(f);
fsetpos(f,&pos);
return len;
}
void FileStream::SetPosition(int64_t pos)
{
if(!cs) return;
fseeko(f,(off_t)pos,SEEK_SET);
}
void Parse(ListNode* node,vector<Lexer::LexToken> tokens)
{
int i = 0;
ParseNode(node,tokens,&i,true);
}
ListNode* Parse(vector<Lexer::LexToken> tokens)
{
ListNode* node = new ListNode();
Parse(node,tokens);
return node;
}
void ParseNode(ListNode* node,vector<Lexer::LexToken> tokens,int* i)
{
ParseNode(node,tokens,i,false);
}
void ParseNode(ListNode* node,vector<Lexer::LexToken> tokens,int* i,bool root)
{
node->root = root;
while(*i < tokens.size() && tokens[*i].type != Lexer::RBRACE)
{
if(tokens[*i].type == Lexer::SEMI) (*i)++;
if(*i+2 < tokens.size() && tokens[*i+1].type == Lexer::EQUALS )
{
string varname = tokens[*i].text;
*i=*i+2;
node->nodes.push_back(new SetVariableNode(ParseExpression(tokens,i),varname));
if(!root && *i<tokens.size() && tokens[*i].type == Lexer::RBRACE) break;
(*i)++;
}
else if(*i+1 < tokens.size() && tokens[*i+1].type == Lexer::LPAREN)
{
node->nodes.push_back(ParseExpression(tokens,i));
if(!root && *i<tokens.size() && tokens[*i].type == Lexer::RBRACE) break;
(*i)++;
}
else
{
node->nodes.push_back(ParseExpression(tokens,i));
if(!root && *i<tokens.size() && tokens[*i].type == Lexer::RBRACE) break;
(*i)++;
}
}
}
Expression* ParseExpression(vector<Lexer::LexToken> tokens,int* i)
{
Expression* res = ParseTerm(tokens,i);
while(*i < tokens.size() && (tokens[*i].type == Lexer::PLUS||tokens[*i].type == Lexer::MINUS))
{
if(*i < tokens.size() && tokens[*i].type == Lexer::PLUS)
{
(*i)++;
res = (Expression*)new AddNode(res,ParseTerm(tokens,i));
}
if(*i < tokens.size() && tokens[*i].type == Lexer::MINUS)
{
(*i)++;
res = (Expression*)new MinusNode(res,ParseTerm(tokens,i));
}
}
return res;
}
Expression* ParseTerm(vector<Lexer::LexToken> tokens,int* i)
{
Expression* res = ParseFactor(tokens,i);
while(*i < tokens.size() && (tokens[*i].type == Lexer::MULTIPLY||tokens[*i].type == Lexer::DIVIDE ||tokens[*i].type == Lexer::MOD))
{
if(*i < tokens.size() && tokens[*i].type == Lexer::MULTIPLY)
{
(*i)++;
res = (Expression*)new MultiplyNode(res,ParseFactor(tokens,i));
}
if(*i < tokens.size() && tokens[*i].type == Lexer::DIVIDE)
{
(*i)++;
res = (Expression*)new DivideNode(res,ParseFactor(tokens,i));
}
if(*i < tokens.size() && tokens[*i].type == Lexer::MOD)
{
(*i)++;
res = (Expression*)new ModulusNode(res,ParseFactor(tokens,i));
}
}
return res;
}
Expression* ParseFactor(vector<Lexer::LexToken> tokens,int* i)
{
if(*i>=tokens.size()) throw exception();
Lexer::LexToken token = tokens[*i];
if(token.type == Lexer::LPAREN)
{
(*i)++;
Expression* res = ParseExpression(tokens,i);
if(*i>=tokens.size()) throw exception();
if(tokens[*i].type != Lexer::RPAREN) throw exception();
(*i)++;
return res;
}
if(token.type == Lexer::LBRACE)
{
(*i)++;
ListNode* res = new ListNode();
ParseNode(res,tokens,i,false);
if(*i>=tokens.size()) throw exception();
if(tokens[*i].type != Lexer::RBRACE) throw exception();
(*i)++;
return (Expression*)res;
}
if(token.type == Lexer::IDENTIFER)
{
(*i)++;
if(*i<tokens.size() && tokens[*i].type == Lexer::LPAREN)
{
vector<Expression*> funcArgs;
(*i)++;
while(*i<tokens.size() && tokens[*i].type != Lexer::RPAREN)
{
if(tokens[*i].type == Lexer::COMMA) (*i)++;
funcArgs.push_back(ParseExpression(tokens,i));
}
(*i)++;
return (Expression*)new FunctionCallNode(token.text,funcArgs);
}else{
return (Expression*)new VariableGetValueNode(token.text);
}
}
if(token.type == Lexer::STRING)
{
(*i)++;
return (Expression*)new StringNode(token.text);
}
if(token.type == Lexer::NUMBER)
{
(*i)++;
return (Expression*)new ConstantNumber(token.text);
}
throw exception();
}
void ApplicationState::StopRunning()
{
std::vector<Expression*> exp;
this->isRunning=(bool)this->ExecuteFunction("stopinterrupt",exp);
}
void ApplicationState::ExitIfNotRunning()
{
if(!isRunning)
{
exit(0);
}
}
void SubscopeApplicationState::StopRunning()
{
this->state->StopRunning();
}
void SubscopeApplicationState::ExitIfNotRunning()
{
this->state->ExitIfNotRunning();
}
#pragma region "BufferedStream"
BufferedStream::BufferedStream(Stream* parent)
{
this->strm = parent;
}
int64_t Stream::ReadByte()
{
uint8_t buffer[1];
return this->Read(buffer,1) > 0 ? buffer[0] : -1;
}
int64_t BufferedStream::ReadByte()
{
if(pos<min((int)this->readIn,4096))
{
return (int64_t)this->buffer[this->pos];
}else{
this->readIn=this->strm->Read(this->buffer,4096);
this->pos = 0;
if(this->readIn > 0)
{
return this->buffer[this->pos++];
}else{
return -1;
}
}
}
void BufferedStream::Write(uint8_t* data,size_t len)
{
this->strm->Write(data,len);
}
size_t BufferedStream::Read(uint8_t* data,size_t len)
{
if(this->pos<min((int)this->readIn,4096) && this->pos > 0)
{
int _len=min((int)this->readIn-this->pos,(int)len);
memcpy(data,this->buffer + this->pos,_len);
this->pos+=_len;
return _len;
}else{
return this->strm->Read(data,len);
}
}
int64_t BufferedStream::GetPosition()
{
return 0;
}
int64_t BufferedStream::GetLength()
{
return 0;
}
void BufferedStream::SetPosition(int64_t pos)
{
}
void BufferedStream::Flush()
{
this->strm->Flush();
}
void BufferedStream::Close()
{
}
bool BufferedStream::CanRead()
{
return this->strm->CanRead();
}
bool BufferedStream::CanWrite()
{
return this->strm->CanWrite();
}
bool BufferedStream::CanSeek()
{
return false;
}
#pragma endregion
};