![]() |
![]() |
||||||
![]() |
|||||||
|
/*
* Cache.cpp
* Part of SQLMeta, a language to use sql-queries in html pages.
*
* Copyright (C) 2001 Daan Vreeken
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/
#include "sqlmeta.h"
Cache::Cache(MetaParser *MyParent)
{
Parent=MyParent;
LoopDepth=0;
Loop=NULL;
FirstBlock=NULL;
LastBlock=NULL;
LastSearchedBlock=NULL;
LastID=0;
TempBuf=NULL;
}
Cache::~Cache(void)
{
if (TempBuf!=NULL)
free(TempBuf);
}
int Cache::Feed(CacheType Type, char *Data, int Size)
{
CacheCommand Cmd;
long JumpID;
CacheBlock *Block;
int LoopAgain = 0;
CacheBlock *Pos;
char *ExecData;
int Result;
//If we're not in a loop, just spit it out...
if (LoopDepth==0)
{
if (Type==HTML)
Parent->SpitoutHTML(Data,Size);
else
return Parent->ExecCommand(Data);
return 1;
}
//We made it upto here, so we're in a loop..
//First cache the data
//Create a cache block...
Block=(CacheBlock *)new CacheBlock(this,Type,LastID++,Data,Size);
if (Block==NULL)
return Parent->Error(ErrMalloc,"Cache::Feed");
Pos=Block;
do
{
//Ask the loop-object what we have to do with it.
//if (Pos->Type==Code)
// printf("id[%d] Cmd: %s\n",Pos->ID,Pos->Data);
Cmd=Loop->Feed(Pos,&JumpID);
if (Cmd==Error)
return 0;
if (Cmd==EndLoop)
{
delete Loop;
LoopDepth--;
if (LoopDepth==0)
{
LoopAgain=0;
while (FirstBlock!=NULL)
delete FirstBlock;
Pos=NULL;
}
else
Pos=Pos->Next;
}
if (Cmd==Exec)
{
if (Pos->Type==HTML)
Parent->SpitoutHTML(Pos->Data,Pos->Size);
else
{
//Copy command
ExecData=(char *)malloc(Pos->Size+1);
if (ExecData==NULL)
return Parent->Error(ErrMalloc,"Cache::Feed");
memcpy(ExecData,Pos->Data,Pos->Size+1);
Result=Parent->ExecCommand(ExecData);
free(ExecData);
if (!Result)
return Result;
}
Pos=Pos->Next;
}
if (Cmd==SkipThisOne)
{
Pos=Pos->Next;
}
if (Cmd==Jump)
{
//printf("Loop wants us to jump to %d\n",JumpID);
LoopAgain=1;
Pos=FindBlock(JumpID);
}
} while ((LoopAgain) && (Pos!=NULL));
return 1;
}
int Cache::Flush(void)
{
if (LoopDepth!=0)
return Parent->Error(ErrLoopUnterminated);
return 1;
}
void Cache::AddLoop(MetaLoop *)
{
LoopDepth++;
}
CacheBlock *Cache::FindBlock(long ID)
{
CacheBlock *Srch = FirstBlock;
while ((Srch!=NULL) && (Srch->ID!=ID))
Srch=Srch->Next;
if (Srch->ID==ID)
return Srch;
printf("!!!!!!!!! ID NOT FOUND IN CACHE!!\n");
return NULL;
}
int Cache::SplitArgs(char *Line)
{
//Allocate temporary memory buffer
if (TempBuf!=NULL)
TempBuf=(char *)realloc(TempBuf,strlen(Line)+1);
else
TempBuf=(char *)malloc(strlen(Line)+1);
//Make a copy
strcpy(TempBuf,Line);
//Splice it into args...
return Parent->SplitArgs(TempBuf,Arg);
}
CacheBlock::CacheBlock(Cache *MyParent, CacheType MyType, long MyID, char *MyData, int MySize)
{
Parent=MyParent;
Type=MyType;
Size=MySize;
ID=MyID;
if (Type==Code)
Size=strlen(MyData);
//Make a copy of the data
Data=(char *)malloc(Size+1);
if (Data==NULL)
{
Parent->Parent->Error(ErrMalloc,"CacheBlock::CacheBlock");
exit(0);
}
if (Type==Code)
strcpy(Data,MyData);
else
{
memcpy(Data,MyData,Size);
*(Data+Size)=0;
}
//Hook it into the queue
Next=NULL;
Prev=NULL;
if (Parent->FirstBlock==NULL)
Parent->FirstBlock=this;
if (Parent->LastBlock!=NULL)
{
Parent->LastBlock->Next=this;
Prev=Parent->LastBlock;
}
Parent->LastBlock=this;
}
CacheBlock::~CacheBlock(void)
{
free(Data);
if (Prev!=NULL)
Prev->Next=Next;
if (Next!=NULL)
Next->Prev=Prev;
if (this==Parent->FirstBlock)
Parent->FirstBlock=Next;
if (this==Parent->LastBlock)
Parent->LastBlock=Prev;
}
syntax highlighted by Code2HTML, v. 0.9.1 Email me with questions/comments : Daan <Danovitsch @ Vitsch . net> |