#include "program_store.h" #include "string.h" #include namespace Code { ProgramStore::ProgramStore() : m_numberOfPrograms(0), m_lastProgramEdited(-1) { for (int i = 0; i= 0 && i < numberOfPrograms()); cleanAndMoveFreeSpaceAfterProgram(i); int beginningOfProgram = indexOfProgram(i); // Compute the size of the program, including the free space of m_history int sizeOfEditableProgram = 0; for (int j=beginningOfProgram; j= 0 && i < numberOfPrograms()); int beginningOfProgram = indexOfProgram(i); return Program(&m_history[beginningOfProgram], strlen(&m_history[beginningOfProgram] + 1)); } int ProgramStore::numberOfPrograms() const { return m_numberOfPrograms; } Program ProgramStore::editableNewProgram() { cleanAndMoveFreeSpaceAfterProgram(numberOfPrograms()-1); m_numberOfPrograms++; return Program(&m_history[indexOfFirstFreeSpaceMarker()], sizeOfFreeSpace() - 1); } void ProgramStore::deleteProgram(int i){ assert (i >= 0 && i < numberOfPrograms()); cleanAndMoveFreeSpaceAfterProgram(i); int indexOfCharToDelete = indexOfProgram(i); while (m_history[indexOfCharToDelete] != FreeSpaceMarker) { m_history[indexOfCharToDelete] = FreeSpaceMarker; indexOfCharToDelete++; } m_numberOfPrograms--; } void ProgramStore::deleteAll(){ for (int i = 0; i= 0 && i < numberOfPrograms()); int currentProgramNumber = 0; int beginningOfProgram = 0; while (m_history[beginningOfProgram] == FreeSpaceMarker) { beginningOfProgram++; } if (i == 0) { return beginningOfProgram; } for (int j=beginningOfProgram; j 0) { return sizeOfFreeSpace; } } } return sizeOfFreeSpace; } void ProgramStore::cleanFreeSpace() { if (m_lastProgramEdited < 0 || m_lastProgramEdited >= numberOfPrograms()) { return; } int indexOfCharToChangeIntoFreeSpaceMarker = lastIndexOfProgram(m_lastProgramEdited) + 1; while (m_history[indexOfCharToChangeIntoFreeSpaceMarker] != FreeSpaceMarker) { m_history[indexOfCharToChangeIntoFreeSpaceMarker] = FreeSpaceMarker; indexOfCharToChangeIntoFreeSpaceMarker ++; } } void ProgramStore::moveFreeSpaceAfterProgram(int i) { m_lastProgramEdited = i; // If the free space is already just after the program, return int indexOfFreeSpace = indexOfFirstFreeSpaceMarker(); int lastIndexOfPrgm = lastIndexOfProgram(i); if (indexOfFreeSpace == lastIndexOfPrgm + 1){ return; } // Else move the free space depending on its relative position with the program int freeSpaceSize = sizeOfFreeSpace(); if (indexOfFreeSpace > lastIndexOfPrgm) { int indexOfNextProgram = lastIndexOfPrgm+1; int len = indexOfFreeSpace - indexOfNextProgram; // Use memmove to avoid overwriting memmove(&m_history[indexOfNextProgram + freeSpaceSize], &m_history[indexOfNextProgram], len); for (int j = indexOfNextProgram; j= 0 && i sizeOfFreeSpace() - 1) { // We keep at keast one free char. return false; } cleanAndMoveFreeSpaceAfterProgram(numberOfPrograms()-1); memcpy(&m_history[indexOfFirstFreeSpaceMarker()], program, len+1); m_numberOfPrograms++; m_lastProgramEdited = m_numberOfPrograms-1; return true; } }