Changeset 495 for abuse/trunk/src/lcache.cpp
- Timestamp:
- Apr 17, 2011, 11:56:51 PM (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
abuse/trunk/src/lcache.cpp
r494 r495 9 9 */ 10 10 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 11 17 #include "config.h" 12 18 … … 15 21 #include "bus_type.h" 16 22 17 long block_size(Cell*level) // return size needed to recreate this block23 size_t block_size(LObject *level) // return size needed to recreate this block 18 24 { 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)) 25 29 { 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); 31 51 } 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; 55 55 } 56 56 57 void write_level(bFILE *fp, LObject *level) 58 { 59 int type = item_type(level); 60 fp->write_uint8(type); 57 61 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); 58 79 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 } 90 106 } 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 }98 107 } 99 108 100 Cell*load_block(bFILE *fp)109 LObject *load_block(bFILE *fp) 101 110 { 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) 118 114 { 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 } 133 160 } 134 last->cdr = (t < 0) ? (LObject *)load_block(fp) : NULL;135 161 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; 143 163 } 164
Note: See TracChangeset
for help on using the changeset viewer.