/*
**********************************************************************
* Copyright (C) 1998-2008, International Business Machines
* Corporation and others. All Rights Reserved.
**********************************************************************
*/
#include "LETypes.h"
#include "LEInsertionList.h"
U_NAMESPACE_BEGIN
#define ANY_NUMBER 1
struct InsertionRecord
{
InsertionRecord *next;
le_int32 position;
le_int32 count;
LEGlyphID glyphs[ANY_NUMBER];
};
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(LEInsertionList)
LEInsertionList::LEInsertionList(le_bool rightToLeft)
: head(NULL), tail(NULL), growAmount(0), append(rightToLeft)
{
tail = (InsertionRecord *) &head;
}
LEInsertionList::~LEInsertionList()
{
reset();
}
void LEInsertionList::reset()
{
while (head != NULL) {
InsertionRecord *record = head;
head = head->next;
LE_DELETE_ARRAY(record);
}
tail = (InsertionRecord *) &head;
growAmount = 0;
}
le_int32 LEInsertionList::getGrowAmount()
{
return growAmount;
}
LEGlyphID *LEInsertionList::insert(le_int32 position, le_int32 count, LEErrorCode &success)
{
if (LE_FAILURE(success)) {
return 0;
}
InsertionRecord *insertion = (InsertionRecord *) LE_NEW_ARRAY(char, sizeof(InsertionRecord) + (count - ANY_NUMBER) * sizeof (LEGlyphID));
if (insertion == NULL) {
success = LE_MEMORY_ALLOCATION_ERROR;
return 0;
}
insertion->position = position;
insertion->count = count;
growAmount += count - 1;
if (append) {
// insert on end of list...
insertion->next = NULL;
tail->next = insertion;
tail = insertion;
} else {
// insert on front of list...
insertion->next = head;
head = insertion;
}
return insertion->glyphs;
}
le_bool LEInsertionList::applyInsertions(LEInsertionCallback *callback)
{
for (InsertionRecord *rec = head; rec != NULL; rec = rec->next) {
if (callback->applyInsertion(rec->position, rec->count, rec->glyphs)) {
return TRUE;
}
}
return FALSE;
}
U_NAMESPACE_END