From 49649329ebc1ac5a53e05f9bf80ead570fd726c6 Mon Sep 17 00:00:00 2001 From: Edouard DUPIN Date: Sat, 26 Oct 2013 13:16:30 +0200 Subject: [PATCH] [DEV] Add buffer iterator out of bounds control --- sources/appl/Buffer/Buffer.cpp | 344 +++++++++++++++++-- sources/appl/Buffer/Buffer.h | 94 +++-- sources/appl/Buffer/TextPluginAutoIndent.cpp | 2 +- sources/appl/Gui/TextViewer.cpp | 10 +- sources/appl/glyphDecoration/GlyphPainting.h | 4 +- 5 files changed, 393 insertions(+), 61 deletions(-) diff --git a/sources/appl/Buffer/Buffer.cpp b/sources/appl/Buffer/Buffer.cpp index d5280bf..be1d656 100644 --- a/sources/appl/Buffer/Buffer.cpp +++ b/sources/appl/Buffer/Buffer.cpp @@ -12,10 +12,12 @@ #include appl::Buffer::Iterator& appl::Buffer::Iterator::operator++ (void) { + m_value = etk::UChar::Null; if ( m_data != NULL && m_current < m_data->m_data.size() ) { int8_t nbChar = etk::UChar::theoricUTF8Len(m_data->m_data[m_current]); if (m_current+nbChar >= m_data->m_data.size()) { + m_current = m_data->m_data.size(); return *this; } m_current+=nbChar; @@ -24,22 +26,37 @@ appl::Buffer::Iterator& appl::Buffer::Iterator::operator++ (void) { } appl::Buffer::Iterator& appl::Buffer::Iterator::operator-- (void) { - if ( m_data != NULL - && m_current > 0) { - int32_t iii = -1; - while( etk::UChar::theoricUTF8First(m_data->m_data[m_current+iii]) == false - && iii >= -6 - && m_current-iii>0) { - --iii; - }; - m_current += iii; + m_value = etk::UChar::Null; + if (m_data != NULL) { + if (m_current > 0) { + int32_t iii = -1; + while( etk::UChar::theoricUTF8First(m_data->m_data[m_current+iii]) == false + && iii >= -6 + && m_current-iii>0) { + --iii; + }; + m_current += iii; + } else { + m_current = -1; + } + return *this; } return *this; } -etk::UChar appl::Buffer::Iterator::operator* (void) const { - etk::UChar retVal = '\0'; - APPL_CHECK_INOUT(m_current < m_data->m_data.size()); +etk::UChar appl::Buffer::Iterator::operator* (void) { + if (m_value != etk::UChar::Null) { + return m_value; + } + if (m_data == NULL) { + APPL_ERROR("request an element that iterator not link"); + return m_value; + } + if ( m_current < 0 + || m_current >= m_data->m_data.size()) { + APPL_ERROR("request an element out of bounding !!! 0 <= " << m_current << " < " << m_data->m_data.size()); + return m_value; + } char tmpVal[5]; memset(tmpVal, 0, sizeof(tmpVal)); tmpVal[0] = m_data->m_data[m_current]; @@ -48,8 +65,8 @@ etk::UChar appl::Buffer::Iterator::operator* (void) const { tmpVal[iii] = m_data->m_data[m_current+iii]; } // transform ... - retVal.setUtf8(tmpVal); - return retVal; + m_value.setUtf8(tmpVal); + return m_value; } @@ -110,15 +127,12 @@ void appl::Buffer::setFileName(const etk::UString& _name) { void appl::Buffer::countNumberofLine(void) { m_nbLines = 0; for (Iterator it = begin(); - it != end(); + (bool)it == true; ++it) { if (*it == etk::UChar::Return) { ++m_nbLines; } } - if (*end() == etk::UChar::Return) { - ++m_nbLines; - } } @@ -143,7 +157,7 @@ bool appl::Buffer::search(const appl::Buffer::Iterator& _pos, const etk::UChar& // move in the string etk::UChar value; for (Iterator it = _pos; - it != end(); + (bool)it == true; ++it) { if (*it == _search) { _result = it; @@ -158,7 +172,7 @@ bool appl::Buffer::searchBack(const appl::Buffer::Iterator& _pos, const etk::UCh // move in the string etk::UChar value; for (Iterator it = _pos - 1; - it != begin(); + (bool)it == true; --it) { //APPL_DEBUG("compare : " << *it << " ?= " << _search); if (*it == _search) { @@ -201,7 +215,7 @@ bool appl::Buffer::getPosAround(const appl::Buffer::Iterator& _startPos, APPL_DEBUG("select spacer"); // Search back for (Iterator it = --position(_startPos); - it != begin(); + (bool)it == true; --it) { currentValue = *it; if ( currentValue != etk::UChar::Tabulation @@ -212,7 +226,7 @@ bool appl::Buffer::getPosAround(const appl::Buffer::Iterator& _startPos, } // Search forward for (Iterator it = position(_startPos); - it != end(); + (bool)it == true; ++it) { currentValue = *it; if ( currentValue != etk::UChar::Tabulation @@ -226,7 +240,7 @@ bool appl::Buffer::getPosAround(const appl::Buffer::Iterator& _startPos, APPL_DEBUG("select normal Char"); // Search back for (Iterator it = --position(_startPos); - it != begin(); + (bool)it == true; --it) { currentValue = *it; if ( currentValue != '_' @@ -237,7 +251,7 @@ bool appl::Buffer::getPosAround(const appl::Buffer::Iterator& _startPos, } // Search forward for (Iterator it = position(_startPos); - it != end(); + (bool)it == true; ++it) { currentValue = *it; if ( currentValue != '_' @@ -252,7 +266,7 @@ bool appl::Buffer::getPosAround(const appl::Buffer::Iterator& _startPos, etk::UChar comparechar = currentValue; // Search back for (Iterator it = --position(_startPos); - it != begin(); + (bool)it == true; --it) { currentValue = *it; if (comparechar != currentValue) { @@ -262,7 +276,7 @@ bool appl::Buffer::getPosAround(const appl::Buffer::Iterator& _startPos, } // Search forward for (Iterator it = position(_startPos); - it != end(); + (bool)it == true; ++it) { currentValue = *it; if (comparechar != currentValue) { @@ -341,7 +355,7 @@ appl::Buffer::Iterator appl::Buffer::countForwardNLines(const appl::Buffer::Iter int32_t lineCount = 0; //APPL_INFO("startPos=" << startPos << " nLines=" << nLines); for (Iterator it = ++position(_startPos); - it != end(); + (bool)it == true; ++it) { value = *it; if (value == etk::UChar::Return) { @@ -385,7 +399,7 @@ bool appl::Buffer::copy(etk::UString& _data) { esize_t endPos = getStopSelectionPos(); for (Iterator it = position(startPos); it != position(endPos) && - it != end(); + (bool)it == true; ++it) { _data += *it; } @@ -400,7 +414,7 @@ void appl::Buffer::copy(etk::UString& _data, const appl::Buffer::Iterator& _pos, esize_t endPos = getStopSelectionPos(); for (Iterator it = _pos; it != _posEnd && - it != end(); + (bool)it == true; ++it) { _data += *it; } @@ -435,4 +449,276 @@ void appl::Buffer::removeSelection(void) { } } +#if 0 + + +// TODO : Check this fuction it have too many conditionnal inside == > can do a better algo +void appl::Buffer::RegenerateHighLightAt(int32_t _pos, int32_t _nbDeleted, int32_t _nbAdded) { + // prevent ERROR... + if (NULL == m_Highlight) { + return; + } + // prevent No data Call + if ( _nbDeleted == 0 + && _nbAdded == 0) { + return; + } + // normal case + //APPL_INFO("(pos="<" << stopId); + } + } else if (stopId == -1) { + //APPL_DEBUG("3 * Erase " << startId+1 << "-> end"); + m_HLDataPass1.EraseLen(startId+1, m_HLDataPass1.size() - startId); + stopId = -1; + } else { + int32_t currentSize = m_HLDataPass1.size(); + //APPL_DEBUG("4 * Erase " << startId+1 << "->" << stopId << " in " << currentSize << " elements" ); + m_HLDataPass1.EraseLen(startId+1, stopId - startId); + if (stopId == currentSize-1) { + stopId = -1; + } + } + //APPL_DEBUG("new size=" << (int32_t)m_HLDataPass1.size()-1); + // update position after the range position : + int32_t elemStart; + if (startId == -1) { + elemStart = 0; + } else { + elemStart = startId+1; + } + for (esize_t iii = elemStart; iii < m_HLDataPass1.size(); ++iii) { + //APPL_DEBUG("move element=" << i); + m_HLDataPass1[iii].beginStart += _nbAdded - _nbDeleted; + m_HLDataPass1[iii].beginStop += _nbAdded - _nbDeleted; + m_HLDataPass1[iii].endStart += _nbAdded - _nbDeleted; + m_HLDataPass1[iii].endStop += _nbAdded - _nbDeleted; + } + //Regenerate Element inside range + if ( startId == -1 + && stopId == -1) { + //APPL_DEBUG("******* Regenerate ALL"); + generateHighLightAt(0, m_data.size()); + } else if(-1 == startId) { + //APPL_DEBUG("******* Regenerate START"); + generateHighLightAt(0, m_HLDataPass1[0].beginStart, 0); + } else if(-1 == stopId) { + //APPL_DEBUG("******* Regenerate STOP"); + generateHighLightAt(m_HLDataPass1[m_HLDataPass1.size() -1].endStop, m_data.Size(), m_HLDataPass1.Size()); + } else { + //APPL_DEBUG("******* Regenerate RANGE"); + generateHighLightAt(m_HLDataPass1[startId].endStop, m_HLDataPass1[startId+1].beginStart, startId+1); + } + } else { + // Parse the new element ... + generateHighLightAt(0, m_data.size()); + } +} + +void appl::Buffer::findMainHighLightPosition(int32_t _startPos, + int32_t _endPos, + int32_t& _startId, + int32_t& _stopId, + bool _backPreviousNotEnded) { + _startId = -1; + _stopId = -1; + /* rules to start stop: + HighLight data ---- + remove area **** + Start pos S + End pos E + + Some Case : + ----------- ------------ ------------- ---------- + S **** E + + ----------- ------------ ------------- ---------- + S ********** E + + ----------- ------------ ------------- ---------- + S **** E + + ----------- ------------ ------------- ---------- + S ********* E + + ----------- ------------ ------------- ---------- + S ********************* E + + ----------- ------------ ------------- ---------- + S ************************ E + + ----------- ------------ ------------- ---------- + S ***************** E + + ----------- ------------ ------------- ---------- + S *************** E + + ----------- ------------ + S *************** E=-1 + + ------------ ------------- ---------- + S=-1 *************** E + */ + for (esize_t iii = 0; iii < m_HLDataPass1.size(); ++iii) { + if (m_HLDataPass1[iii].endStop > _startPos) { + break; + } + _startId = iii; + } + // go back while the previous element is not eneded + if (_backPreviousNotEnded == true) { + for (int64_t iii = startId; iii >= 0; --iii) { + if (m_HLDataPass1[iii].notEnded == false) { + break; + } + _startId = iii-1; + } + } + int32_t elemStart; + if(_startId == -1) { + elemStart = 0; + } else { + elemStart = _startId+1; + } + for (esize_t iii = elemStart; iii < m_HLDataPass1.size(); ++iii) { + if (m_HLDataPass1[iii].beginStart > _endPos) { + _stopId = i; + break; + } + } +} + +void appl::Buffer::generateHighLightAt(int32_t _pos, int32_t _endPos, int32_t _addingPos) { + if (NULL == m_Highlight) { + return; + } + //APPL_DEBUG("area : ("<Parse(_pos, _endPos, m_HLDataPass1, _addingPos, m_data); +} + +void EdnBuf::cleanHighLight(void) { + // remove all element in the list... + m_HLDataPass1.clear(); +} + + +appl::ColorInfo *appl::Buffer::getElementColorAtPosition(int32_t _pos, int32_t &_starPos) { + int32_t start = etk_max(0, _starPos-1); + for (esize_t iii = start; iii < m_HLDataPass1.size(); ++iii) { + starPos = iii; + if ( m_HLDataPass1[iii].beginStart <= _pos + && m_HLDataPass1[iii].endStop > _pos) { + return &m_HLDataPass1[iii]; + } + if(m_HLDataPass1[iii].beginStart > _pos) { + return NULL; + } + } + return NULL; +} + + +void appl::Buffer::HightlightGenerateLines(displayHLData_ts_& _MData, int32_t _HLStart, int32_t _nbLines) { + _MData.posHLPass1 = 0; + _MData.posHLPass2 = 0; + if (NULL == m_Highlight) { + return; + } + //GTimeVal timeStart; + //g_get_current_time(&timeStart); + _HLStart = StartOfLine(HLStart); + _MData.HLData.clear(); + int32_t HLStop = CountForwardNLines(_HLStart, _nbLines); + int32_t startId, stopId; + // find element previous + findMainHighLightPosition(_HLStart, HLStop, startId, stopId, true); + + //APPL_DEBUG("List of section between : "<< startId << " & " << stopId); + int32_t endSearch = stopId+1; + if (stopId == -1) { + endSearch = m_HLDataPass1.size(); + } + int64_t kkk; + for (kkk = etk_max(startId, 0); kkk < endSearch; ++kkk) { + // empty section : + if (kkk == 0) { + if (_HLStart < m_HLDataPass1[kkk].beginStart) { + //APPL_DEBUG(" == > (empty section 1 ) k="< (empty section 2 ) k="< (under section ) k="< (empty section 3 ) k="< (empty section 4 ) k="< _pos) + { + return &_MData.HLData[i]; + } + if(_MData.HLData[i].beginStart > _pos) { + return getElementColorAtPosition(_pos, _MData.posHLPass1); + } + } + return getElementColorAtPosition(_pos, _MData.posHLPass1); +} +#endif \ No newline at end of file diff --git a/sources/appl/Buffer/Buffer.h b/sources/appl/Buffer/Buffer.h index fbdceec..b166755 100644 --- a/sources/appl/Buffer/Buffer.h +++ b/sources/appl/Buffer/Buffer.h @@ -24,26 +24,29 @@ namespace appl { class Iterator { // Private data : private: - esize_t m_current; //!< curent Id in the Buffer + int64_t m_current; //!< curent Id in the Buffer appl::Buffer* m_data; //!< Pointer on the curent Buffer + etk::UChar m_value; //!< store vlue to prevent multiple calcule of getting the data public: /** * @brief Basic itarator constructor with no link. */ Iterator(void): m_current(0), - m_data(NULL) { + m_data(NULL), + m_value(etk::UChar::Null) { // nothing to do ... - } + }; /** * @brief Recopy constructor. * @param[in] _obj The Iterator that might be copy */ Iterator(const Iterator & _obj): m_current(_obj.m_current), - m_data(_obj.m_data) { + m_data(_obj.m_data), + m_value(etk::UChar::Null) { // nothing to do ... - } + }; /** * @brief Asignation operator. * @param[in] _otherIterator The Iterator that might be copy @@ -52,15 +55,17 @@ namespace appl { Iterator& operator=(const Iterator & _obj) { m_current = _obj.m_current; m_data = _obj.m_data; + m_value = etk::UChar::Null; return *this; - } + }; /** * @brief Basic destructor */ ~Iterator(void) { m_current = 0; m_data = NULL; - } + m_value = etk::UChar::Null; + }; /** * @brief basic boolean cast * @return true if the element is present in buffer @@ -69,8 +74,14 @@ namespace appl { if (m_data == NULL) { return false; } - return (m_current < m_data->m_data.size()); - } + if (m_current >= m_data->m_data.size()) { + return false; + } + if (m_current < 0) { + return false; + } + return true; + }; /** * @brief basic boolean cast * @return true if the element is present in buffer @@ -79,8 +90,14 @@ namespace appl { if (m_data == NULL) { return 0; } + if (m_current < 0) { + return 0; + } + if (m_current >= m_data->m_data.size()) { + return m_data->m_data.size()-1; + } return m_current; - } + }; /** * @brief Incremental operator * @return Reference on the current iterator incremented @@ -99,7 +116,7 @@ namespace appl { Iterator it(*this); ++(*this); return it; - } + }; /** * @brief Decremental operator * @return Reference on a new iterator and decrement the other one @@ -108,7 +125,7 @@ namespace appl { Iterator it(*this); --(*this); return it; - } + }; /** * @brief egality iterator * @return true if the iterator is identical pos @@ -119,7 +136,7 @@ namespace appl { return true; } return false; - } + }; /** * @brief egality iterator * @return true if the iterator is identical pos @@ -130,7 +147,7 @@ namespace appl { return true; } return false; - } + }; /** * @brief <= iterator * @return true if the iterator is identical pos @@ -143,7 +160,7 @@ namespace appl { return true; } return false; - } + }; /** * @brief >= iterator * @return true if the iterator is identical pos @@ -156,7 +173,7 @@ namespace appl { return true; } return false; - } + }; /** * @brief < iterator * @return true if the iterator is identical pos @@ -169,7 +186,7 @@ namespace appl { return true; } return false; - } + }; /** * @brief > iterator * @return true if the iterator is identical pos @@ -182,19 +199,28 @@ namespace appl { return true; } return false; - } + }; /** * @brief Get the value on the current element * @return The request element value */ - etk::UChar operator* (void) const ; + etk::UChar operator* (void); /** * @brief Get the position in the buffer * @return The requested position. */ esize_t getPos(void) const { + if (m_data == NULL) { + return 0; + } + if (m_current < 0) { + return 0; + } + if (m_current >= m_data->m_data.size()) { + return m_data->m_data.size()-1; + } return m_current; - } + }; /** * @brief move the element position * @return a new iterator. @@ -205,7 +231,7 @@ namespace appl { ++tmpp; } return tmpp; - } + }; /** * @brief move the element position * @return a new iterator. @@ -216,13 +242,14 @@ namespace appl { --tmpp; } return tmpp; - } + }; private: Iterator(Buffer* _obj, int32_t _pos) : m_current(_pos), - m_data(_obj) { + m_data(_obj), + m_value(etk::UChar::Null) { // nothing to do ... - } + }; friend class Buffer; }; public: @@ -454,6 +481,25 @@ namespace appl { * @brief Count the number of line in the buffer */ void countNumberofLine(void); + protected: + etk::UString m_highlightType; //!< Name of the highlight type + public: + /** + * @brief Find the Highligh capability + */ + void tryFindHighlightType(void); + /** + * @brief Set type of highlight + * @param[in] _type type of the highlight + */ + void setHighlightType(const etk::UString& _type); + /** + * @brief Get type of highlight + * @return Type of the highlight + */ + const etk::UString& setHighlightType(void) { + return m_highlightType; + }; }; }; diff --git a/sources/appl/Buffer/TextPluginAutoIndent.cpp b/sources/appl/Buffer/TextPluginAutoIndent.cpp index d18b180..a22fd0d 100644 --- a/sources/appl/Buffer/TextPluginAutoIndent.cpp +++ b/sources/appl/Buffer/TextPluginAutoIndent.cpp @@ -47,7 +47,7 @@ bool appl::TextPluginAutoIndent::onEventEntry(appl::TextViewer& _textDrawer, for (appl::Buffer::Iterator it = startLine+1; - it != _textDrawer.m_buffer->end(); + (bool)it == true; ++it) { if (*it == etk::UChar::Space) { data.append(etk::UChar::Space); diff --git a/sources/appl/Gui/TextViewer.cpp b/sources/appl/Gui/TextViewer.cpp index 7538b89..3d1263c 100644 --- a/sources/appl/Gui/TextViewer.cpp +++ b/sources/appl/Gui/TextViewer.cpp @@ -130,7 +130,7 @@ void appl::TextViewer::onRegenerateDisplay(void) { int32_t startLineId = 0; if (m_size.y() < m_displayText.getPos().y()) { for (startingIt = m_buffer->begin(); - startingIt != m_buffer->end(); + (bool)startingIt == true; ++startingIt) { if (*startingIt == etk::UChar::Return) { ++startLineId; @@ -178,7 +178,7 @@ void appl::TextViewer::onRegenerateDisplay(void) { } float maxSizeX = 0; for (appl::Buffer::Iterator it = startingIt; - it != m_buffer->end(); + (bool)it == true; ++it) { if (it == m_buffer->cursor()) { // need to display the cursor : @@ -452,7 +452,7 @@ appl::Buffer::Iterator appl::TextViewer::getMousePosition(const vec2& _relativeP m_displayText.clear(); m_displayText.forceLineReturn(); for (appl::Buffer::Iterator it = m_buffer->begin(); - it != m_buffer->end(); + (bool)it == true; ++it) { currentValue = *it; m_buffer->expand(countColomn, currentValue, stringToDisplay); @@ -708,7 +708,7 @@ appl::Buffer::Iterator appl::TextViewer::getPosSize(const appl::Buffer::Iterator m_displayText.clear(); m_displayText.forceLineReturn(); for (appl::Buffer::Iterator it = _startLinePos; - it != m_buffer->end(); + (bool)it == true; ++it) { currentValue = *it; m_buffer->expand(countColomn, currentValue, stringToDisplay); @@ -736,7 +736,7 @@ float appl::TextViewer::getScreenSize(const appl::Buffer::Iterator& _startLinePo m_displayText.clear(); for (appl::Buffer::Iterator it = _startLinePos; - it != m_buffer->end() && it <= _stopPos; + (bool)it == true && it <= _stopPos; ++it) { currentValue = *it; //APPL_DEBUG("parse : " << currentValue); diff --git a/sources/appl/glyphDecoration/GlyphPainting.h b/sources/appl/glyphDecoration/GlyphPainting.h index 6ae25d1..71bacbf 100644 --- a/sources/appl/glyphDecoration/GlyphPainting.h +++ b/sources/appl/glyphDecoration/GlyphPainting.h @@ -6,8 +6,8 @@ * @license GPL v3 (see license file) */ -#ifndef __GLYPH_DECORATION_MANAGER_H__ -#define __GLYPH_DECORATION_MANAGER_H__ +#ifndef __APPL_GLYPH_PAINTING_H__ +#define __APPL_GLYPH_PAINTING_H__ #include #include