00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "memfile.h"
00022
00023 #include <stdio.h>
00024 #include <stdlib.h>
00025 #include <string.h>
00026 #include <ctype.h>
00027 #include <limits.h>
00028 #include <time.h>
00029 #include "dernc.h"
00030
00031
00039 short memfile_new(struct MEMORY_FILE **mfile, unsigned long alloc_len)
00040 {
00041 (*mfile)=malloc(sizeof(struct MEMORY_FILE));
00042 if ((*mfile)==NULL) return MFILE_MALLOC_ERR;
00043 (*mfile)->len=0;
00044 (*mfile)->pos=0;
00045 (*mfile)->alloc_len=alloc_len;
00046 (*mfile)->alloc_delta=0;
00047 (*mfile)->errcode=MFILE_OK;
00048 if (alloc_len>0)
00049 {
00050 (*mfile)->content=malloc(alloc_len);
00051 if ((*mfile)->content == NULL)
00052 {
00053 free(*mfile);
00054 (*mfile)=NULL;
00055 return MFILE_MALLOC_ERR;
00056 }
00057 } else
00058 {
00059 (*mfile)->content=NULL;
00060 }
00061 return MFILE_OK;
00062 }
00063
00069 short memfile_free(struct MEMORY_FILE **mfile)
00070 {
00071 if ((*mfile)!=NULL)
00072 {
00073
00074 free((*mfile)->content);
00075 free((*mfile));
00076 }
00077 (*mfile)=NULL;
00078 return MFILE_OK;
00079 }
00080
00087 short memfile_growalloc(struct MEMORY_FILE *mfile, unsigned long alloc_len)
00088 {
00089 if (mfile->alloc_len < alloc_len)
00090 {
00091 mfile->content=realloc(mfile->content,alloc_len+mfile->alloc_delta);
00092 if (mfile->content==NULL)
00093 {
00094 mfile->alloc_len=0;
00095 mfile->len=0;
00096 mfile->errcode=MFILE_MALLOC_ERR;
00097 return mfile->errcode;
00098 }
00099 mfile->alloc_len=alloc_len+mfile->alloc_delta;
00100 }
00101 mfile->errcode=MFILE_OK;
00102 return mfile->errcode;
00103 }
00104
00112 short memfile_add(struct MEMORY_FILE *mfile,
00113 const unsigned char *buf,unsigned long buf_len)
00114 {
00115
00116 if (buf_len==0)
00117 {
00118 mfile->errcode=MFILE_OK;
00119 return mfile->errcode;
00120 }
00121 if (memfile_growalloc(mfile,mfile->len+buf_len)!=MFILE_OK)
00122 return mfile->errcode;
00123 memcpy(mfile->content+mfile->len,buf,buf_len);
00124 mfile->len+=buf_len;
00125 mfile->errcode=MFILE_OK;
00126 return mfile->errcode;
00127 }
00128
00139 short memfile_set(struct MEMORY_FILE *mfile,
00140 unsigned char *buf,unsigned long len,unsigned long alloc_len)
00141 {
00142 mfile->pos=0;
00143 free(mfile->content);
00144 if (((len>0)||(alloc_len>0))&&(buf==NULL))
00145 {
00146 mfile->content=NULL;
00147 mfile->len=0;
00148 mfile->pos=0;
00149 mfile->alloc_len=0;
00150 mfile->errcode=MFILE_INTERNAL;
00151 return mfile->errcode;
00152 }
00153 mfile->content=buf;
00154 mfile->len=len;
00155 mfile->alloc_len=alloc_len;
00156 mfile->errcode=MFILE_OK;
00157 return mfile->errcode;
00158 }
00159
00165 unsigned char *memfile_leave_content(struct MEMORY_FILE **mfile)
00166 {
00167 unsigned char *content=NULL;
00168 if ((*mfile)!=NULL)
00169 {
00170 content=(*mfile)->content;
00171 free((*mfile));
00172 }
00173 (*mfile)=NULL;
00174 return content;
00175 }
00176
00186 short memfile_read(struct MEMORY_FILE *mfile,const char *fname,unsigned long max_size)
00187 {
00188 if ((mfile==NULL) || (fname==NULL))
00189 return MFILE_INTERNAL;
00190 FILE *ifp;
00191 unsigned long plen, ulen;
00192 unsigned long alloc_plen;
00193 void *packed;
00194 ifp = fopen(fname, "rb");
00195
00196 if (ifp==NULL)
00197 {
00198 mfile->errcode=MFILE_CANNOT_OPEN;
00199 return mfile->errcode;
00200 }
00201 fseek(ifp, 0L, SEEK_END);
00202 plen = ftell(ifp);
00203
00204 if (((long)plen == -1L) || (plen > MAX_FILE_SIZE))
00205 {
00206 fclose(ifp);
00207 mfile->errcode=MFILE_SIZE_ERR;
00208 return mfile->errcode;
00209 }
00210
00211
00212 if (plen<SIZEOF_RNC_HEADER)
00213 alloc_plen=SIZEOF_RNC_HEADER+8;
00214 else
00215 alloc_plen=plen+8;
00216 rewind(ifp);
00217 packed = malloc(alloc_plen);
00218 if (packed==NULL)
00219 {
00220 fclose(ifp);
00221 mfile->errcode=MFILE_MALLOC_ERR;
00222 return mfile->errcode;
00223 }
00224 unsigned long rdlen;
00225 rdlen=fread(packed, 1, plen, ifp);
00226
00227 if (ferror(ifp))
00228 {
00229 fclose(ifp);
00230 free(packed);
00231 mfile->errcode=MFILE_READ_ERR;
00232 return mfile->errcode;
00233 }
00234 fclose(ifp);
00235
00236 if (rdlen<alloc_plen)
00237 memset(packed+rdlen,'\0',alloc_plen-rdlen);
00238 ulen = rnc_ulen(packed);
00239 if ((long)ulen == RNC_FILE_IS_NOT_RNC)
00240 {
00241 if (mfile->len > 0)
00242 {
00243 memfile_add(mfile,packed,plen);
00244 free(packed);
00245 } else
00246 memfile_set(mfile,packed,plen,alloc_plen);
00247 return mfile->errcode;
00248 }
00249 if (ulen>MAX_FILE_SIZE)
00250 {
00251 free(packed);
00252 mfile->errcode=MFILE_SIZE_ERR;
00253 return mfile->errcode;
00254 }
00255
00256 plen = rnc_plen(packed);
00257 if (((long)plen > 0) && (plen >= alloc_plen) && (plen < MAX_FILE_SIZE))
00258 {
00259 unsigned long alloc_new=plen+8;
00260
00261 packed=realloc(packed,alloc_new);
00262 if (packed==NULL)
00263 {
00264 mfile->errcode=MFILE_MALLOC_ERR;
00265 return mfile->errcode;
00266 }
00267 memset(packed+alloc_plen,'\0',alloc_new-alloc_plen);
00268 alloc_plen=alloc_new;
00269 }
00270 unsigned long alloc_ulen;
00271 void *unpacked;
00272 alloc_ulen=ulen+8;
00273
00274 unpacked = malloc(alloc_ulen);
00275 if (unpacked==NULL)
00276 {
00277 free(packed);
00278 mfile->errcode=MFILE_MALLOC_ERR;
00279 return mfile->errcode;
00280 }
00281
00282 ulen = rnc_unpack(packed, unpacked, RNC_IGNORE_NONE);
00283
00284
00285 free(packed);
00286
00287 if ( ((long)ulen < 0) && ((long)ulen > -32) )
00288 {
00289 free(unpacked);
00290 mfile->errcode=(short)ulen;
00291
00292 return mfile->errcode;
00293 }
00294
00295 if (mfile->len>0)
00296 {
00297 memfile_add(mfile,unpacked,ulen);
00298 free(unpacked);
00299 } else
00300 memfile_set(mfile,unpacked,ulen,alloc_ulen);
00301
00302 return mfile->errcode;
00303 }
00304
00315 short memfile_readnew(struct MEMORY_FILE **mfile,const char *fname,unsigned long max_size)
00316 {
00317 short errcode;
00318 errcode = memfile_new(mfile,0);
00319 if (errcode != MFILE_OK)
00320 return errcode;
00321
00322 errcode = memfile_read((*mfile),fname,max_size);
00323 if (errcode != MFILE_OK)
00324 memfile_free(mfile);
00325 return errcode;
00326 }
00327
00328 char *memfile_error(int errcode)
00329 {
00330 static char *const errors[] = {
00331 "No error",
00332 "Cannot open file",
00333 "Cannot allocate memory",
00334 "Wrong file size",
00335 "Data read error",
00336 "Internal error",
00337 "Unknown error",
00338 };
00339 if ((errcode<0)&&(errcode>=-16))
00340 {
00341 return rnc_error(errcode);
00342 }
00343 errcode = MFILE_CANNOT_OPEN+1 - errcode;
00344 if (errcode < 0)
00345 errcode = 0;
00346 if (errcode > sizeof(errors)/sizeof(*errors) - 1)
00347 errcode = sizeof(errors)/sizeof(*errors) - 1;
00348 return errors[errcode];
00349 }
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461