Changeset 495


Ignore:
Timestamp:
Apr 17, 2011, 11:56:51 PM (7 years ago)
Author:
Sam Hocevar
Message:

lisp: refactor the cache system.

Location:
abuse/trunk/src
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • abuse/trunk/src/cache.cpp

    r494 r495  
    900900  ci->offset=cache_file->tell();
    901901
    902   s=block_size(block);
     902  s = block_size((LObject *)block);
    903903  cache_file->write_uint32(s);
    904   write_level(cache_file,block);
     904  write_level(cache_file, (LObject *)block);
    905905  return id;
    906906}
  • abuse/trunk/src/lcache.cpp

    r494 r495  
    99 */
    1010
     11/*
     12 * This file contains serialisation methods for the cache system. It
     13 * is NOT used to load and save games.
     14 * XXX: this code has not been tested after the LObject refactor.
     15 */
     16
    1117#include "config.h"
    1218
     
    1521#include "bus_type.h"
    1622
    17 long block_size(Cell *level)  // return size needed to recreate this block
     23size_t block_size(LObject *level)  // return size needed to recreate this block
    1824{
    19   int ret;
    20   if (!level) ret=0;    // NULL pointers don't need to be stored
    21   else
    22   {
    23     int type=item_type(level);
    24     if (type==L_CONS_CELL)
     25    if (!level) // NULL pointers don't need to be stored
     26        return 0;
     27
     28    switch (item_type(level))
    2529    {
    26     long t=0;
    27     void *b=level;
    28     for (; b && item_type(b)==L_CONS_CELL; b=CDR(b))
    29     {
    30       t+=sizeof(LList);
     30    case L_CONS_CELL:
     31        {
     32            size_t ret = sizeof(uint8_t) + sizeof(uint32_t);
     33            void *b = level;
     34            for (; b && item_type(b) == L_CONS_CELL; b = CDR(b))
     35                ;
     36            if (b)
     37                ret += block_size((LObject *)b);
     38            for (b = level; b && item_type(b) == L_CONS_CELL; b = CDR(b))
     39                ret += block_size(CAR(b));
     40            return ret;
     41        }
     42    case L_CHARACTER:
     43        return sizeof(uint8_t) + sizeof(uint16_t);
     44    case L_STRING:
     45        return sizeof(uint8_t) + sizeof(uint32_t)
     46                               + strlen(lstring_value(level)) + 1;
     47    case L_NUMBER:
     48        return sizeof(uint8_t) + sizeof(uint32_t);
     49    case L_SYMBOL:
     50        return sizeof(uint8_t) + sizeof(uintptr_t);
    3151    }
    32     if (b) t+=block_size(b);
    33     for (b=level; b && item_type(b)==L_CONS_CELL; b=CDR(b))
    34       t+=block_size(CAR(b));
    35     ret=t;
    36     } else if (type== L_NUMBER)
    37     { ret=sizeof(LNumber); }
    38     else if (type==L_CHARACTER)
    39     { ret=sizeof(LChar); }
    40     else if (type==L_STRING)
    41     {
    42       ret=sizeof(LString)+strlen(lstring_value(level))+1;
    43       if (ret<8)
    44         ret=8;
    45     }
    46     else if (type==L_POINTER)
    47     { ret=sizeof(LPointer); }
    48     else ret=0;
    49   }
    50 #ifdef WORD_ALIGN
    51   return (ret+3)&(~3);
    52 #else
    53   return ret;
    54 #endif
     52
     53    /* Do not serialise other types */
     54    return 0;
    5555}
    5656
     57void write_level(bFILE *fp, LObject *level)
     58{
     59    int type = item_type(level);
     60    fp->write_uint8(type);
    5761
     62    switch (type)
     63    {
     64    case L_CONS_CELL:
     65        if (!level)
     66            fp->write_uint32(0);
     67        else
     68        {
     69            size_t count = 0;
     70            void *b = level;
     71            for (; b && item_type(b) == L_CONS_CELL; b = CDR(b))
     72                count++;
     73            /* If last element is not the empty list, it's a dotted list
     74             * and we need to save the last object. Write a negative size
     75             * to reflect that. */
     76            fp->write_uint32(b ? -(int32_t)count : count);
     77            if (b)
     78                write_level(fp, (LObject *)b);
    5879
    59 void write_level(bFILE *fp, Cell *level)
    60 {
    61   int type=item_type(level);
    62   fp->write_uint8(type);
    63 
    64 
    65   switch (type)
    66   {
    67     case L_NUMBER :
    68     { fp->write_uint32(lnumber_value(level)); } break;
    69     case L_CHARACTER :
    70     { fp->write_uint16(lcharacter_value(level)); } break;
    71     case L_STRING :
    72     { long l=strlen(lstring_value(level))+1;
    73       fp->write_uint32(l);
    74       fp->write(lstring_value(level),l);
    75     } break;
    76     case L_SYMBOL :
    77     { fp->write_uint32((long)level); } break;
    78     case L_CONS_CELL :
    79     {
    80       if (!level) fp->write_uint32(0);
    81       else
    82       {
    83     long t=0;
    84     void *b=level;
    85     for (; b && item_type(b)==L_CONS_CELL; b=CDR(b)) t++;
    86     if (b)
    87     {
    88       fp->write_uint32(-t);      // negative number means dotted list
    89       write_level(fp,b);       // save end of dotted list
     80            for (b = level; b && item_type(b) == L_CONS_CELL; b = CDR(b))
     81                write_level(fp, CAR(b));
     82        }
     83        break;
     84    case L_CHARACTER:
     85        fp->write_uint16(lcharacter_value(level));
     86        break;
     87    case L_STRING:
     88        {
     89            size_t count = strlen(lstring_value(level)) + 1;
     90            fp->write_uint32(count);
     91            fp->write(lstring_value(level), count);
     92        }
     93        break;
     94    case L_NUMBER:
     95        fp->write_uint32(lnumber_value(level));
     96        break;
     97    case L_SYMBOL:
     98        {
     99            uintptr_t p = (uintptr_t)level;
     100            for (size_t i = 0; i < sizeof(uintptr_t); i++)
     101            {
     102                fp->write_uint8((uint8_t)p);
     103                p >>= 8;
     104            }
     105        }
    90106    }
    91     else fp->write_uint32(t);
    92 
    93     for (b=level; b && item_type(b)==L_CONS_CELL; b=CDR(b))
    94       write_level(fp,CAR(b));
    95       }
    96     } break;
    97   }
    98107}
    99108
    100 Cell *load_block(bFILE *fp)
     109LObject *load_block(bFILE *fp)
    101110{
    102   int type=fp->read_uint8();
    103   switch (type)
    104   {
    105     case L_NUMBER :
    106     { return LNumber::Create(fp->read_uint32()); } break;
    107     case L_CHARACTER :
    108     { return LChar::Create(fp->read_uint16()); } break;
    109     case L_STRING :
    110     { long l=fp->read_uint32();
    111       LString *s = LString::Create(l);
    112       fp->read(lstring_value(s),l);
    113       return s;
    114     } break;
    115     case L_SYMBOL :
    116     { return (void *)fp->read_uint32(); } break;
    117     case L_CONS_CELL :
     111    int type = fp->read_uint8();
     112
     113    switch (type)
    118114    {
    119       long t=fp->read_uint32();
    120       if (!t) return NULL;
    121       else
    122       {
    123     long x=abs(t);
    124     LList *last=NULL,*first=NULL;
    125     while (x)
    126     {
    127       LList *c = LList::Create();
    128       if (first)
    129         last->cdr=c;
    130       else first=c;
    131       last=c;
    132       x--;
     115    case L_CONS_CELL:
     116        {
     117            int32_t t = (int32_t)fp->read_uint32();
     118
     119            if (!t)
     120                return NULL;
     121
     122            LList *last = NULL, *first = NULL;
     123            for (size_t count = abs(t); count--; )
     124            {
     125                LList *c = LList::Create();
     126                if (first)
     127                    last->cdr = c;
     128                else
     129                    first = c;
     130                last = c;
     131            }
     132            last->cdr = (t < 0) ? (LObject *)load_block(fp) : NULL;
     133
     134            last = first;
     135            for (size_t count = abs(t); count--; last = (LList *)last->cdr)
     136                last->car = load_block(fp);
     137            return first;
     138        }
     139    case L_CHARACTER:
     140        return LChar::Create(fp->read_uint16());
     141    case L_STRING:
     142        {
     143            size_t count = fp->read_uint32();
     144            LString *s = LString::Create(count);
     145            fp->read(s->GetString(), count);
     146            return s;
     147        }
     148    case L_NUMBER:
     149        return LNumber::Create(fp->read_uint32());
     150    case L_SYMBOL:
     151        {
     152            uintptr_t ret = 0, mul = 1;
     153            for (size_t i = 0; i < sizeof(uintptr_t); i++)
     154            {
     155                ret |= mul * fp->read_uint8();
     156                mul *= 8;
     157            }
     158            return (LObject *)ret;
     159        }
    133160    }
    134     last->cdr = (t < 0) ? (LObject *)load_block(fp) : NULL;
    135161
    136     for (last=first,x=0; x<abs(t); x++,last=(LList *)last->cdr)
    137       last->car = (LObject *)load_block(fp);
    138     return first;
    139       }
    140     }
    141   }
    142   return NULL;
     162    return NULL;
    143163}
     164
  • abuse/trunk/src/lcache.h

    r494 r495  
    1919#endif
    2020
    21 long block_size(Cell *level);              // return number of bytes to save this block of code
    22 void write_level(bFILE *fp, Cell *level);
    23 Cell *load_block(bFILE *fp);
     21// return number of bytes to save this block of code
     22size_t block_size(LObject *level);
     23void write_level(bFILE *fp, LObject *level);
     24LObject *load_block(bFILE *fp);
    2425
    2526#endif
     27
Note: See TracChangeset for help on using the changeset viewer.