Navigation
Home
gpl
sqlmeta
v1.1b
cache.cpp








































cache.cpp
   
   /*
    * 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;
   
   	ArgBuf=NULL;
   }
   
   
   
   Cache::~Cache(void)
   {
   	if (ArgBuf!=NULL)
   		free(ArgBuf);
   }
   
   
   
   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 (ArgBuf!=NULL)
   		ArgBuf=(char *)realloc(ArgBuf,strlen(Line)+1);
   	else
   		ArgBuf=(char *)malloc(strlen(Line)+1);
   
   	//Make a copy
   	strcpy(ArgBuf,Line);
   
   	//Splice it into args...
   	return Parent->SplitArgs(ArgBuf,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 <Daan @ pa4dan . nl>