//
//  mem.c
//  LKFScoringMac
//
//  Created by Alexander Holzer on 24.01.16.
//
//

#include <stdio.h>
#include "lkfint5.h"

#ifdef USE_LKF_MEMORYBLOCK
LKF_MEMORYBLOCK *lkf_add_memoryblock (LKF_CONTEXT *pContext, int memoryBlockLength)
{
    
    LKF_MEMORYBLOCK *pNewBlock;
    if (pContext->memoryblock_alloc == pContext->memoryblock_count) {
        LKF_MEMORYBLOCK *pOld = pContext->pMemoryBlocks;
        pContext->memoryblock_alloc += LKF_MEMORYBLOCK_EXTEND;
        pContext->pMemoryBlocks = (LKF_MEMORYBLOCK *) LKF_CALLOC(sizeof (LKF_MEMORYBLOCK), pContext->memoryblock_alloc);
        if (pOld && pContext->memoryblock_count) {
            memcpy (pContext->pMemoryBlocks, pOld, sizeof (LKF_MEMORYBLOCK) * pContext->memoryblock_count);
        }
    }
    
    pContext->pCurrentBlock = pNewBlock = pContext->pMemoryBlocks + pContext->memoryblock_count++;
    pNewBlock->len = memoryBlockLength;
    pNewBlock->buf = (char *) LKF_MALLOC (memoryBlockLength);
    pNewBlock->offset = 0;
    return pNewBlock;
}

void lkf_free_memoryblock (LKF_MEMORYBLOCK *pMemoryBlock) {
    if (pMemoryBlock->buf) {
        LKF_FREE (pMemoryBlock->buf);
        pMemoryBlock->buf = 0;
    }
}

const char *lkf_store_buf (LKF_CONTEXT *pContext, const char *buf, int length) {
    LKF_MEMORYBLOCK *pBlock;
    const char *returnBuffer;
    if (!pContext->pCurrentBlock || pContext->pCurrentBlock->offset + length + 1 >= pContext->pCurrentBlock->len)
        pBlock = lkf_add_memoryblock(pContext, LKF_MEMORYBLOCK_LENGTH);
    else
        pBlock = pContext->pCurrentBlock;
    
    memcpy (pBlock->buf + pBlock->offset, buf, length);
    returnBuffer = pBlock->buf;
    pBlock->buf[pBlock->offset += length] = 0;
    ++pBlock->offset;
    return returnBuffer;
}

void lkf_free_context_memory (LKF_CONTEXT *pContext)
{
    int i;
    for (i = 0; i < pContext->memoryblock_count; i++)
        lkf_free_memoryblock(pContext->pMemoryBlocks + i);
    LKF_FREE (pContext->pMemoryBlocks);
    pContext->pMemoryBlocks = 0;
    pContext->memoryblock_alloc = 0;
    pContext->memoryblock_count = 0;
}
#endif