persist.h Source File






Misc >
Help >
FAQ >


Links >



persist.h

00001 /* persist.h -- Persistent Object Management
00002 Copyright 2001 Free Software Foundation, Inc.
00003 Written by Stephane Carrez (stcarrez@worldnet.fr)
00004 
00005 This file is part of GEL.
00006 
00007 GEL is free software; you can redistribute it and/or modify
00008 it under the terms of the GNU General Public License as published by
00009 the Free Software Foundation; either version 2, or (at your option)
00010 any later version.
00011 
00012 GEL is distributed in the hope that it will be useful,
00013 but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00015 GNU General Public License for more details.
00016 
00017 You should have received a copy of the GNU General Public License
00018 along with GEL; see the file COPYING. If not, write to
00019 the Free Software Foundation, 59 Temple Place - Suite 330,
00020 Boston, MA 02111-1307, USA. */
00021 
00022 #ifndef _GEL_PERSIST_H
00023 #define _GEL_PERSIST_H
00024 
00025 #include <sys/param.h>
00026 #include <stddef.h>
00027 #include <string.h>
00028 
00029 #define PERSIST_INVALID_ID (persist_id_t) (0xffff)
00030 #define PERSIST_FREE_SLOT (persist_id_t) (0x7fff)
00031 
00032 typedef unsigned short persist_id_t;
00033 
00046 class persistent_store
00047 {
00048 protected:
00049 
00051 //
00052 // The persistent area starts with a persistent store id and the size
00053 // of that store. The store id is used to retrieve the store when
00054 // we start. The size is used to be able to walk the persistent areas,
00055 // manage their allocation/deallocation. */
00056 typedef struct
00057 {
00058 persist_id_t id;
00059 unsigned char size;
00060 unsigned char data[0];
00061 } persistent_area_t;
00062 
00064 //
00065 // Returns a pointer to the persistent area or NULL if not found.
00066 static persistent_area_t *find_store (persist_id_t id);
00067 
00069 //
00070 // Returns a pointer to the persistent area allocated for the new store.
00071 static persistent_area_t *allocate_store (persist_id_t id, size_t len);
00072 
00073 // Start in Eprom of the persistent memory.
00074 static persistent_area_t start_area asm ("0xb000");
00075 
00076 // End of the persistent memory.
00077 static persistent_area_t end_area asm ("0xb200");
00078 
00079 // The persistent area used by that store (saved copy).
00080 persistent_area_t *area;
00081 
00083 //
00084 // If the runtime copy of the object is modified, update its
00085 // copy in persistent memory.
00086 void
00087 save (const unsigned char *object);
00088 
00090 //
00091 // Retrieve the persistent store identified by `id', initialize
00092 // the runtime copy `object' with it. If the persistent storage
00093 // does not exist for that store, allocate one.
00094 //
00095 // Returns 1 when the persistent store was created, 0 otherwise.
00096 int
00097 create (persist_id_t id, void *object, size_t len);
00098 
00099 inline
00100 persistent_store ()
00101 {}
00102 
00103 private:
00104 // Copy constructor is forbidden.
00105 inline
00106 persistent_store (const persistent_store&)
00107 {
00108 ;
00109 }
00110 
00111 // Copy of persistent store objects is forbidden.
00112 inline persistent_store&
00113 operator = (const persistent_store&)
00114 {
00115 return *this;
00116 }
00117 
00118 protected:
00120 inline
00121 persistent_store (persist_id_t id, void *object, size_t len)
00122 {
00123 create (id, object, len);
00124 }
00125 
00126 public:
00128 //
00129 // The persistent store is freed and is no longer used to save
00130 // the object.
00131 void
00132 revoke ();
00133 };
00134 
00135 
00140 class persistent_object : private persistent_store
00141 {
00142 protected:
00143 
00144 // First persistent object in the list.
00145 static persistent_object *first;
00146 
00147 // Next persistent object in the list.
00148 persistent_object *next;
00149 
00150 // Pointer to the object in memory (runtime copy).
00151 unsigned char *object;
00152 
00153 inline
00154 persistent_object ()
00155 {}
00156 
00157 private:
00158 // Copy constructor is forbidden.
00159 inline
00160 persistent_object (const persistent_object&)
00161 {
00162 ;
00163 }
00164 
00165 // Copy of persistent object is forbidden.
00166 inline persistent_object&
00167 operator = (const persistent_object&)
00168 {
00169 return *this;
00170 }
00171 public:
00172 
00174 inline
00175 persistent_object (persist_id_t id, void *object, size_t len)
00176 : persistent_store (id, object, len)
00177 {
00178 next = first;
00179 first = this;
00180 }
00181 
00183 //
00184 // Persistent objects with external storage are not managed completely
00185 // by `persistent_object' class. We are not aware of when the object
00186 // is modified. For these objects, it is necessary to call `save_all'
00187 // to synchronize the runtime value with the persistent storage.
00188 // Only the bytes that have changed are updated.
00189 static void
00190 save_all ();
00191 };
00192 
00193 
00194 
00196 //
00197 // This class is suitable for a transparent persistent object.
00198 // When the object is modified, the persistent storage is also updated.
00199 // This is implemented by overriding the `=' operator and the `(type)'
00200 // type conversion.
00201 //
00202 template <class type>
00203 class persistent : private persistent_store
00204 {
00205 type obj;
00206 
00208 inline void
00209 sync ()
00210 {
00211 save ((const unsigned char*) &obj);
00212 }
00213 public:
00215 inline
00216 persistent (persist_id_t id)
00217 : persistent_store (id, &obj, sizeof (obj))
00218 {
00219 }
00220 
00222 //
00223 // If it's the first time the object is created, initialize it
00224 // with <b>init</b>.
00225 inline
00226 persistent (persist_id_t id, const type& init)
00227 : persistent_store ()
00228 {
00229 if (create (id, &obj, sizeof (type)))
00230 {
00231 obj = init;
00232 sync ();
00233 }
00234 }
00235 
00237 //
00238 // If it's the first time the object is created, initialize it
00239 // with <b>init</b>.
00240 inline
00241 persistent (persist_id_t id, type& init)
00242 : persistent_store ()
00243 {
00244 if (create (id, &obj, sizeof (type)))
00245 {
00246 memcpy (&obj, &init, sizeof (type));
00247 sync ();
00248 }
00249 }
00250 
00252 //
00253 // The object can still be retrieve from persistent storage.
00254 inline
00255 ~persistent ()
00256 {
00257 ;
00258 }
00259 
00261 //
00262 // Modify the object and update its persistent storage.
00263 inline persistent<type>&
00264 operator = (const type& value)
00265 {
00266 memcpy (&obj, value, sizeof (value));
00267 sync ();
00268 return *this;
00269 }
00270 
00272 //
00273 // Modify the object and update its persistent storage.
00274 inline persistent<type>&
00275 operator = (type& value)
00276 {
00277 memcpy (&obj, &value, sizeof (value));
00278 sync ();
00279 return *this;
00280 }
00281 
00283 inline
00284 operator const type& ()
00285 {
00286 return obj;
00287 }
00288 
00289 inline persistent<type>&
00290 operator ++ (int)
00291 {
00292 obj++;
00293 sync ();
00294 return *this;
00295 }
00296 
00297 inline persistent<type>&
00298 operator -- (int)
00299 {
00300 obj--;
00301 sync ();
00302 return *this;
00303 }
00304 };
00305 
00306 
00307 #endif

Copyright (C) 1999, 2000, 2001, 2002, 2003 Stéphane Carrez, France
Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA Verbatim copying and distribution of this entire article is permitted in any medium, provided this notice is preserved.


AltStyle によって変換されたページ (->オリジナル) /