scbpages.c

Go to the documentation of this file.
00001 /*
00002  * File Name: scbpages.c
00003  */
00004 
00005 /*
00006  * This file is part of liberscribble.
00007  *
00008  * liberscribble is free software: you can redistribute it and/or modify
00009  * it under the terms of the GNU General Public License as published by
00010  * the Free Software Foundation, either version 2 of the License, or
00011  * (at your option) any later version.
00012  *
00013  * liberscribble is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00016  * GNU General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU General Public License
00019  * along with this program. If not, see <http://www.gnu.org/licenses/>.
00020  */
00021 
00022 /**
00023  * Copyright (C) 2008 iRex Technologies B.V.
00024  * All rights reserved.
00025  */
00026 
00027 
00028 #define _GNU_SOURCE
00029 
00030 //----------------------------------------------------------------------------
00031 // Include Files
00032 //----------------------------------------------------------------------------
00033 
00034 // system include files, between < >
00035 #include <string.h>
00036 #include <glib.h>
00037 
00038 // ereader include files, between < >
00039 
00040 // local include files, between " "
00041 #include "scblog.h"
00042 #include "scbtype.h"
00043 #include "scbpages.h"
00044 #include "scbpage.h"
00045 
00046 #define UNUSED(x) (void)(x)
00047 
00048 
00049 //----------------------------------------------------------------------------
00050 // Type Declarations
00051 //----------------------------------------------------------------------------
00052 
00053 
00054 //----------------------------------------------------------------------------
00055 // Global Constants
00056 //----------------------------------------------------------------------------
00057 
00058 #define MAX_TIMESTAMP         0x7FFFFFFF
00059 #define CACHE_PAGES_NUMBER    20
00060 
00061 
00062 //----------------------------------------------------------------------------
00063 // Static Variables
00064 //----------------------------------------------------------------------------
00065 
00066 
00067 //============================================================================
00068 // Local Function Definitions
00069 //============================================================================
00070 
00071 static void _page_release       (gpointer data, gpointer userdata);
00072 static void _page_dump          (gpointer data, gpointer userdata);
00073 
00074 
00075 //============================================================================
00076 // Functions Implementation
00077 //============================================================================
00078 
00079 // Remove the oldest page if enough pages are cached
00080 // Return TRUE means it is not necessary to remove oldest page data until
00081 // a new page is loaded; otherwise return FALSE.
00082 gboolean remove_oldest_page_data(ScbPagesPtr pages)
00083 {
00084     // Get the page with oldest timestamp, and calculate the sum
00085     ScbPagePtr oldest_page = NULL;
00086     int oldest_timestamp = MAX_TIMESTAMP;
00087     int loaded_pages_number = 0;
00088     GList* ptr = g_list_first(pages->pages);
00089 
00090     while(ptr)
00091     {
00092         ScbPagePtr cur_page = (ScbPagePtr)ptr->data;
00093         if (cur_page != NULL && (erscribble_strokes_get_count(&cur_page->strokes) > 0))
00094         {
00095             loaded_pages_number++;
00096             if (cur_page->timestamp < oldest_timestamp)
00097             {
00098                 oldest_timestamp = cur_page->timestamp;
00099                 oldest_page = cur_page;
00100             }
00101         }
00102         ptr = g_list_next(ptr);
00103     }
00104 
00105     if (loaded_pages_number <= CACHE_PAGES_NUMBER)
00106     {
00107         return TRUE;
00108     }
00109 
00110     // clear strokes of the oldest page
00111     
00112     // TODO. Handle the situation that the number of loaded pages
00113     // are much more than the cached pages number
00114     erscribble_page_clear_strokes(oldest_page);
00115     oldest_page->is_blob_loaded = FALSE;
00116     loaded_pages_number--;
00117 
00118     if (loaded_pages_number > CACHE_PAGES_NUMBER)
00119     {
00120         return FALSE;
00121     }
00122 
00123     return TRUE;
00124 }
00125 
00126 
00127 gboolean erscribble_pages_new(ScbPagesPtr ptr)
00128 {
00129     ERSCRIBBLE_RET_FALSE_IF(NULL == ptr, "Invalid pointer!");
00130 
00131     ptr->pages = NULL;
00132     return TRUE;
00133 }
00134 
00135 
00136 void erscribble_pages_free(ScbPagesPtr ptr)
00137 {
00138     if (ptr)
00139     {
00140         // release all stroke
00141         g_list_foreach(ptr->pages, _page_release, NULL);
00142 
00143         // now the pointers are wild pointers
00144         g_list_free(ptr->pages);
00145         ptr->pages = NULL;
00146     }
00147 }
00148 
00149 
00150 // it will check whether or not the page exist. do nothing if exist
00151 // by id and pointer
00152 gboolean erscribble_pages_add_page(ScbPagesPtr pages, ScbPagePtr page)
00153 {
00154     ERSCRIBBLE_RET_FALSE_IF(NULL == pages || NULL == page, "Invalid pages or page pointer!");
00155     
00156     ScbPagePtr cur_page  = NULL;
00157     GList* ptr = g_list_first(pages->pages);
00158     while(ptr)
00159     {
00160         cur_page = (ScbPagePtr)ptr->data;
00161         // if (cur_page && 0 == strncmp(cur_page->id.id, page->id.id, ERSCRIBBLE_MAX_PAGEID_LEN))
00162         if (cur_page && (cur_page->id.position == page->id.position))
00163         {
00164             // The querying page already exist, quit, it's ok,
00165             // The new page should be removed.
00166             // WARNPRINTF("Duplicated page id %s!", page->id.id);
00167             return FALSE;
00168         }
00169         ptr = g_list_next(ptr);
00170     }
00171 
00172     pages->pages = g_list_append(pages->pages, page);
00173     return TRUE;
00174 }
00175 
00176 
00177 ScbPagePtr erscribble_pages_detach_page(ScbPagesPtr pages, ScbPageIdPtr id)
00178 {
00179     ScbPagePtr cur_page  = NULL;
00180     GList* ptr = g_list_first(pages->pages);
00181     while(ptr)
00182     {
00183         cur_page = (ScbPagePtr)ptr->data;
00184         // if (cur_page && 0 == strncmp(cur_page->id.id, id->id, ERSCRIBBLE_MAX_PAGEID_LEN))
00185         if (cur_page && (cur_page->id.position == id->position))
00186         {
00187             // ok, hit. notice.......
00188             pages->pages = g_list_remove(pages->pages, cur_page);
00189             return cur_page;
00190         }
00191         ptr = g_list_next(ptr);
00192     }
00193     return NULL;
00194 }
00195 
00196 
00197 void erscribble_pages_remove_page(ScbPagesPtr pages, ScbPageIdPtr id)
00198 {
00199     ERSCRIBBLE_RET_IF(NULL == pages || NULL == id, "Invalid pointer!");
00200     
00201     ScbPagePtr cur_page  = NULL;
00202     GList* ptr = g_list_first(pages->pages);
00203     while(ptr)
00204     {
00205         cur_page = (ScbPagePtr)ptr->data;
00206         // if (cur_page && 0 == strncmp(cur_page->id.id, id->id, ERSCRIBBLE_MAX_PAGEID_LEN))
00207         if (cur_page && (cur_page->id.position == id->position))
00208         {
00209             // ok, hit. notice.......
00210             erscribble_page_free(cur_page);
00211             pages->pages = g_list_remove(pages->pages, ptr->data);
00212             return;
00213         }
00214         ptr = g_list_next(ptr);
00215     }
00216 }
00217 
00218 
00219 int erscribble_pages_get_count(ScbPagesPtr pages)
00220 {
00221     ERSCRIBBLE_RET_INT_IF(NULL == pages, ERSCRIBBLE_INVALID_COUNT, "Invalid pages pointer!");
00222     return g_list_length(pages->pages);
00223 }
00224 
00225 
00226 ScbPagePtr erscribble_pages_get_page(ScbPagesPtr pages, ScbPageIdPtr id)
00227 {
00228     ScbPagePtr cur_page  = NULL;
00229     GList* ptr = g_list_first(pages->pages);
00230     while(ptr)
00231     {
00232         cur_page = (ScbPagePtr)ptr->data;
00233         // if (cur_page && 0 == strncmp(cur_page->id.id, id->id, ERSCRIBBLE_MAX_PAGEID_LEN))
00234         if (cur_page && (cur_page->id.position == id->position))
00235         {
00236             // ok, hit. notice.......
00237            return cur_page;
00238         }
00239         ptr = g_list_next(ptr);
00240     }
00241     return NULL;
00242 }
00243 
00244 
00245 gboolean erscribble_pages_change_page_id(ScbPagesPtr pages, ScbPageIdPtr oldId, 
00246                                          ScbPageIdPtr newId)
00247 {
00248     // change page id, make sure the id does not conflict. we do not check here
00249     
00250     ScbPagePtr cur_page  = NULL;
00251     GList* ptr = g_list_first(pages->pages);
00252     while(ptr)
00253     {
00254         cur_page = (ScbPagePtr)ptr->data;
00255         // if (cur_page && 0 == strncmp(cur_page->id.id, oldId->id, ERSCRIBBLE_MAX_PAGEID_LEN))
00256         if (cur_page && (cur_page->id.position == oldId->position))
00257         {
00258             strncpy(cur_page->id.id, newId->id, ERSCRIBBLE_MAX_PAGEID_LEN);
00259             cur_page->id.position = newId->position;
00260             cur_page->id.annotation_id = newId->annotation_id;
00261 
00262             return TRUE;
00263         }
00264         ptr = g_list_next(ptr);
00265     }
00266     return FALSE;
00267 }
00268 
00269 
00270 void erscribble_pages_dump(ScbPagesPtr pages)
00271 
00272 {
00273     ERSCRIBBLE_RET_IF(NULL == pages, "NULL pointer!");
00274     g_list_foreach(pages->pages, _page_dump, 0);
00275 }
00276 
00277 
00278 //============================================================================
00279 // Local Functions Implementation
00280 //============================================================================
00281 
00282 static void _page_release(gpointer data, gpointer userdata)
00283 {
00284     UNUSED(userdata);
00285     if (data)
00286     {
00287         erscribble_page_free((ScbPagePtr)data);
00288     }
00289 }
00290 
00291 static void _page_dump(gpointer data, gpointer userdata)
00292 {
00293     UNUSED(userdata);
00294     if (data)
00295     {
00296         erscribble_page_dump((ScbPagePtr)data);
00297     }
00298 }
00299 
Generated by  doxygen 1.6.2-20100208