gambas-source-code/main/lib/db/deletemap.c
Benoît Minisini 2fbf67cb29 [CONFIGURATION]
* NEW: Update FSF address in every source file.


git-svn-id: svn://localhost/gambas/trunk@3870 867c0c6c-44f3-4631-809d-bfa615b0a4ec
2011-06-03 00:51:09 +00:00

183 lines
3.7 KiB
C

/***************************************************************************
deletemap.c
(c) 2000-2011 Benoît Minisini <gambas@users.sourceforge.net>
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, 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., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, USA.
***************************************************************************/
#define __DELETEMAP_C
#include "gambas.h"
#include "main.h"
#include "deletemap.h"
//#define DEBUG_ME
typedef
struct _DELETE_SLOT {
struct _DELETE_SLOT *prev;
struct _DELETE_SLOT *next;
int start;
int length;
}
DELETE_SLOT;
int DELETE_MAP_virtual_to_real(DELETE_MAP *dmap, int vpos)
{
DELETE_SLOT *slot = (DELETE_SLOT *)dmap;
int rpos = vpos;
while (slot)
{
if (rpos < slot->start)
break;
rpos += slot->length;
slot = slot->next;
}
#ifdef DEBUG_ME
printf("DELETE_MAP_virtual_to_real: %ld => %ld\n", vpos, rpos);
#endif
return rpos;
}
int DELETE_MAP_real_to_virtual(DELETE_MAP *dmap, int rpos)
{
DELETE_SLOT *slot = (DELETE_SLOT *)dmap;
int vpos = rpos;
while (slot)
{
if (rpos < slot->start)
break;
if (rpos < (slot->start + slot->length))
return (-1);
vpos -= slot->length;
slot = slot->next;
}
#ifdef DEBUG_ME
printf("DELETE_MAP_real_to_virtual: %ld => %ld\n", rpos, vpos);
#endif
return vpos;
}
#ifdef DEBUG_ME
static void dump(DELETE_MAP *dmap)
{
DELETE_SLOT *slot = (DELETE_SLOT *)dmap;
printf("dumping map %p\n", dmap);
while (slot)
{
printf("[ %ld %ld ]\n", slot->start, slot->length);
slot = slot->next;
}
printf("\n");
}
#endif
static void create_slot(DELETE_SLOT **pslot, int pos, DELETE_SLOT *before, DELETE_SLOT *after)
{
GB.Alloc(POINTER(pslot), sizeof(DELETE_SLOT));
(*pslot)->prev = before;
(*pslot)->next = after;
(*pslot)->start = pos;
(*pslot)->length = 1;
if (before)
before->next = *pslot;
if (after)
after->prev = *pslot;
}
static DELETE_SLOT *delete_slot(DELETE_SLOT *slot)
{
DELETE_SLOT *nslot;
nslot = slot->next;
if (slot->prev)
slot->prev->next = slot->next;
if (slot->next)
slot->next->prev = slot->prev;
GB.Free(POINTER(&slot));
return nslot;
}
void DELETE_MAP_add(DELETE_MAP **dmap, int vpos)
{
DELETE_SLOT *slot;
DELETE_SLOT *nslot;
DELETE_SLOT *bslot = NULL;
int rpos;
if (vpos < 0)
return;
rpos = DELETE_MAP_virtual_to_real(*dmap, vpos);
for (slot = (DELETE_SLOT *)*dmap; slot; slot = slot->next)
{
if (rpos < slot->start)
break;
bslot = slot;
}
create_slot(&nslot, rpos, bslot, slot);
if ((DELETE_SLOT *)*dmap == slot)
*dmap = (DELETE_MAP *)nslot;
slot = nslot;
if (slot->prev)
slot = slot->prev;
while (slot->next)
{
if ((slot->start + slot->length) == (slot->next->start))
{
nslot = slot->next;
slot->length += nslot->length;
delete_slot(nslot);
}
else
slot = slot->next;
}
#ifdef DEBUG_ME
printf("DELETE_MAP_add: %ld\n", vpos);
dump(*dmap);
#endif
}
void DELETE_MAP_free(DELETE_MAP **dmap)
{
DELETE_SLOT *slot;
slot = (DELETE_SLOT *)*dmap;
while (slot)
slot = delete_slot(slot);
*dmap = NULL;
}