1 /*
2 * This file is part of HexEditor plugin for Code::Blocks Studio
3 * Copyright (C) 2008-2009 Bartlomiej Swiecki
4 *
5 * HexEditor plugin is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * HexEditor pluging is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with HexEditor. If not, see <http://www.gnu.org/licenses/>.
17 *
18 * $Revision: 7109 $
19 * $Id: FileContentBase.h 7109 2011-04-15 11:53:16Z mortenmacfly $
20 * $HeadURL: svn://svn.code.sf.net/p/codeblocks/code/branches/release-20.xx/src/plugins/contrib/HexEditor/FileContentBase.h $
21 */
22 
23 #ifndef FILECONTENTBASE_H
24 #define FILECONTENTBASE_H
25 
26 #include <wx/string.h>
27 
28 class HexEditViewBase;
29 
30 /** \brief Abstract class for managing content of some file */
31 class FileContentBase
32 {
33     public:
34 
35         /** \brief Offset within the file */
36         typedef unsigned long long OffsetT;
37 
38         /** \brief Structure used as a base of undo data */
39         struct ExtraUndoData
40         {
41             HexEditViewBase* m_View;        ///< \brief View which was active while performing the change
42             OffsetT          m_PosBefore;   ///< \brief Position before the change
43             int              m_PosBeforeF;  ///< \brief View-defined flags before the change (for example bit no before the change)
44             OffsetT          m_PosAfter;    ///< \brief Position after the change
45             int              m_PosAfterF;   ///< \brief View-defined flags after the change
46 
ExtraUndoDataExtraUndoData47             inline ExtraUndoData( HexEditViewBase* view, OffsetT posBefore, int posBeforeF, OffsetT posAfter, int posAfterF )
48                 : m_View      ( view       )
49                 , m_PosBefore ( posBefore  )
50                 , m_PosBeforeF( posBeforeF )
51                 , m_PosAfter  ( posAfter   )
52                 , m_PosAfterF ( posAfterF  )
53             {
54             }
55 
ExtraUndoDataExtraUndoData56             inline ExtraUndoData() {}
57         };
58 
59         /** \brief Ctor */
60         FileContentBase();
61 
62         /** \brief Dctor */
63         virtual ~FileContentBase();
64 
65         /** \brief Reading the data from the file */
66         virtual bool ReadFile( const wxString& fileName ) = 0;
67 
68         /** \brief Writing the data to the file */
69         virtual bool WriteFile( const wxString& fileName ) = 0;
70 
71         /** \brief Check if file was modified */
72         bool Modified();
73 
74         /** \brief Force current state to be modified or not */
75         void SetModified( bool modified );
76 
77         /** \brief Getting size of the content */
78         virtual OffsetT GetSize() = 0;
79 
80         /** \brief Reading some part of data
81          *  \param buff memory location where to read data into
82          *  \param position location of data in the content
83          *  \param length number of bytes to read
84          *  \return number of bytes actually read
85          */
86         virtual OffsetT Read( void* buff, OffsetT position, OffsetT length ) = 0;
87 
88         /** \brief Writing some part of data
89          *  \param buff memory location with new content
90          *  \param position location of data in the content
91          *  \param length number of bytes to read
92          *  \return number of bytes actually written
93          */
94         OffsetT Write( const ExtraUndoData& extraUndoData, const void* buff, OffsetT position, OffsetT length );
95 
96         /** \brief Deleting some range of data
97          *  \param position beginning position of block to remove
98          *  \param length length of block to remove in bytes
99          *  \return number of bytes removed
100          */
101         OffsetT Remove( const ExtraUndoData& extraUndoData, OffsetT position, OffsetT length );
102 
103         /** \brief Inserting data
104          *  \param position location in content where new data will be added
105          *  \param length size of block to add in bytes
106          *  \param data buffer with data to use for new location, if NULL, new block will be zero-filled
107          *  \return number of bytes added
108          */
109         OffsetT Add( const ExtraUndoData& extraUndoData, OffsetT position, OffsetT length, void* data = 0 );
110 
111         /** \brief Check if we can undo */
112         bool CanUndo();
113 
114         /** \brief Check if we can redo */
115         bool CanRedo();
116 
117         /** \brief Do undo
118          *  \return undo data passed while doing the modification we undo
119          */
120         const ExtraUndoData* Undo();
121 
122         /** \brief Do redo
123          *  \return undo data passed while doing the modification we redo
124          */
125         const ExtraUndoData* Redo();
126 
127         /** \brief Helper function to read one byte */
ReadByte(OffsetT position)128         inline unsigned char ReadByte( OffsetT position )
129         {
130             unsigned char val = 0;
131             return ( Read( &val, position, 1 ) == 1 ) ? val : 0;
132         }
133 
134         /** \brief Helper function to write one byte */
WriteByte(const ExtraUndoData & extraUndoData,OffsetT position,unsigned char val)135         inline bool WriteByte( const ExtraUndoData& extraUndoData, OffsetT position, unsigned char val )
136         {
137             return Write( extraUndoData, &val, position, 1 ) == 1;
138         }
139 
140         /** \brief Build implementation of this class */
141         static FileContentBase* BuildInstance( const wxString& fileName );
142 
143     protected:
144 
145         /** \brief Base class for representation of one change inside of the code */
146         class ModificationData
147         {
148             public:
149 
150                 /** \brief Ctor */
ModificationData()151                 inline ModificationData() {}
152 
153                 /** \brief Dctor forcing the class to have vtable */
~ModificationData()154                 virtual ~ModificationData() {}
155 
156                 /** \brief Apply the modification */
157                 virtual void Apply() = 0;
158 
159                 /** \brief Revert the modification */
160                 virtual void Revert() = 0;
161 
162                 /** \brief Get the length of modification */
163                 virtual OffsetT Length() = 0;
164 
165             private:
166 
167                 ModificationData*   m_Next;     ///< \brief Next element in modificatoin list
168                 ModificationData*   m_Prev;     ///< \brief Previous element in modification list
169                 ExtraUndoData       m_Data;     ///< \brief Extra data used outside
170 
171                 friend class FileContentBase;   ///< \brief To allow operations on m_Next and m_Prev
172         };
173 
174         /** \brief Create modification object for change operation */
175         virtual ModificationData* BuildChangeModification( OffsetT position, OffsetT length, const void* data = 0 ) = 0;
176 
177         /** \brief Create modification object for data add operation */
178         virtual ModificationData* BuildAddModification( OffsetT position, OffsetT length, const void* data = 0 ) = 0;
179 
180         /** \brief Create modification object for data remove operation */
181         virtual ModificationData* BuildRemoveModification( OffsetT position, OffsetT length ) = 0;
182 
183         /** \brief Notify that undo has been saved at current position */
UndoNotifySaved()184         inline void UndoNotifySaved() { m_UndoSaved = m_UndoCurrent; }
185 
186         /** \brief Clear all undo history */
UndoClear()187         inline void UndoClear() { RemoveUndoFrom( m_UndoBuffer ); m_UndoCurrent = 0; m_UndoSaved = 0; }
188 
189     private:
190 
191         ModificationData*   m_UndoBuffer;       ///< \brief Undo buffer
192         ModificationData*   m_UndoLast;         ///< \brief Last element in undo buffer
193         ModificationData*   m_UndoCurrent;      ///< \brief Current undo position
194         ModificationData*   m_UndoSaved;        ///< \brief Position of element where the file was "saved" last time (or opened)
195 
196         /** \brief Dummy class to simulate invalid bur also harmless entry in undo buffer */
197         class InvalidModificationData: public ModificationData
198         {
Apply()199             void    Apply () { }
Revert()200             void    Revert() { }
Length()201             OffsetT Length() { return 0; }
202         };
203 
204         static InvalidModificationData m_UndoInvalid;
205 
206 
207         void InsertAndApplyModification( ModificationData* mod );
208         void RemoveUndoFrom( ModificationData* mod );
209         void ApplyModification( ModificationData* mod );
210         void RevertModification( ModificationData* mod );
211 };
212 
213 #endif
214