00001
00002
00003
00004 #include <stdlib.h>
00005 #include <stdio.h>
00006 #include <string.h>
00007 #include "machine.h"
00008 #include "MALLOC.h"
00009 #include "sciprint.h"
00010
00011 #define typ_short "s"
00012 #define typ_ushort "us"
00013 #define typ_char "c"
00014 #define typ_uchar "uc"
00015 #define typ_double "d"
00016 #define typ_int "i"
00017 #define Min(x,y) ((x) < (y) ? (x) : (y))
00018
00019 extern int ripole(char *inputfile, char *outputfile, int debug, int verbose);
00020 extern void C2F(mgetnc) (integer *fd, void *res, integer *n, char *type, integer *ierr);
00021 extern void C2F(mtell) (integer *fd, double *offset, integer *err);
00022 extern void C2F(mseek) (integer *fd, integer *offset, char *flag, integer *err);
00023 extern FILE *GetFile(integer *fd);
00024 extern int GetSwap(integer *fd);
00025
00026
00027
00028
00029 void xls_read(int *fd, int *cur_pos,double **data, int **chainesind, int *N, int *M, int *err);
00030 void xls_open(int *err, int *fd, char ***sst, int *ns, char ***Sheetnames, int** Abspos,int *nsheets);
00031 static double NumFromRk2(long rk);
00032 static void getBoundsheets(int * fd,char ***Sheetnames, int** Abspos, int *nsheets,int *cur_pos,int *err);
00033 static void getSST(int *fd,short Len,int BIFF,int *ns,char ***sst,int *err);
00034 static void getBOF(int *fd ,int* Data, int *err);
00035 static void getString(int *fd,short *count, short *Len, int flag,char **str,int *err);
00036 static int get_oleheader(int *fd);
00037
00038
00039 static double return_a_nan()
00040 {
00041 static int first = 1;
00042 static double nan = 1.0;
00043
00044 if ( first )
00045 {
00046 nan = (nan - (double) first)/(nan - (double) first);
00047 first = 0;
00048 }
00049 return (nan);
00050 }
00051
00052
00053
00054 void xls_read(int *fd, int *cur_pos,double **data, int **chainesind, int *N, int *M, int *err)
00055 {
00056
00057 unsigned short Opcode, Len;
00058 double *valeur;
00059 double pos;
00060
00061 int one=1;
00062 int three=3;
00063
00064 int i;
00065 int hauteur=0, longueur=0, capacite;
00066 int taille;
00067 char *sheetname;
00068 int rkvalue;
00069
00070 unsigned short row, col, xf;
00071
00072 unsigned short ixfe;
00073 short colFirst,colLast,ncol;
00074
00075 short labelsst1[3];
00076 int indsst;
00077
00078 int f_row,l_row;
00079 unsigned short f_col, l_col, notused;
00080
00081 double resultat;
00082 short optionflag;
00083 int formula_notused;
00084 double NaN=return_a_nan();
00085
00086 int BOFData[7];
00087
00088 valeur=(double *)NULL;
00089 sheetname=(char *)NULL;
00090 *chainesind= (int *) NULL;
00091 *err=0;
00092
00093 *cur_pos=*cur_pos;
00094 C2F(mseek) (fd, cur_pos, "set", err);
00095 if (*err > 0) goto ErrL;
00096
00097
00098 getBOF(fd ,BOFData, err);
00099
00100 if (*err > 0) return;
00101 if (BOFData[0]<0) {
00102 *err=2;
00103 return;
00104 }
00105 if (BOFData[0] != 8) {
00106 *err=3;
00107 return;
00108 }
00109
00110 C2F(mtell) (fd, &pos, err);
00111 if (*err > 0) goto ErrL;
00112 *cur_pos=(int)pos;
00113
00114 while(1)
00115 {
00116 C2F(mseek) (fd, cur_pos, "set", err);
00117 if (*err > 0) goto ErrL;
00118
00119 C2F(mgetnc) (fd, &Opcode, &one, typ_ushort, err);
00120 if (*err > 0) goto ErrL;
00121 C2F(mgetnc) (fd, &Len, &one, typ_ushort, err);
00122 if (*err > 0) goto ErrL;
00123 switch(Opcode) {
00124 case 10:
00125 *N=hauteur;
00126 *M=longueur;
00127 *data=valeur;
00128 *cur_pos=*cur_pos+4+Len;
00129 return;
00130 case 638:
00131 C2F(mgetnc) (fd, (void*)&row, &one, typ_ushort, err);
00132 if (*err > 0) goto ErrL;
00133 C2F(mgetnc) (fd, (void*)&col, &one, typ_ushort, err);
00134 if (*err > 0) goto ErrL;
00135 C2F(mgetnc) (fd, (void*)&xf , &one, typ_ushort, err);
00136 if (*err > 0) goto ErrL;
00137 C2F(mgetnc) (fd, (void*) &rkvalue , &one, typ_int, err);
00138 if (*err > 0) goto ErrL;
00139 valeur[col*(hauteur)+row]= NumFromRk2(rkvalue);
00140 break;
00141 case 515:
00142 C2F(mgetnc) (fd, (void*)&row, &one, typ_ushort, err);
00143 if (*err > 0) goto ErrL;
00144 C2F(mgetnc) (fd, (void*)&col, &one, typ_ushort, err);
00145 if (*err > 0) goto ErrL;
00146 C2F(mgetnc) (fd, (void*)&xf , &one, typ_ushort, err);
00147 if (*err > 0) goto ErrL;
00148 C2F(mgetnc) (fd, (void*) &resultat , &one, typ_double, err);
00149 if (*err > 0) goto ErrL;
00150 valeur[col*(hauteur)+row]=resultat ;
00151 break;
00152
00153 case 189:
00154 C2F(mgetnc) (fd, (void*)&row, &one, typ_ushort, err);
00155 if (*err > 0) goto ErrL;
00156 C2F(mgetnc) (fd, (void*)&colFirst, &one, typ_short, err);
00157 if (*err > 0) goto ErrL;
00158
00159 ncol=(Len-6)/6;
00160 for (i=0;i<ncol;i++) {
00161 C2F(mgetnc) (fd, (void*) &ixfe, &one, typ_short, err);
00162 if (*err > 0) goto ErrL;
00163 C2F(mgetnc) (fd, (void*) &rkvalue, &one, typ_int, err);
00164 if (*err > 0) goto ErrL;
00165 valeur[row+(colFirst+i)*hauteur]=NumFromRk2(rkvalue);
00166 }
00167
00168
00169 C2F(mgetnc) (fd, (void*) &colLast, &one, typ_ushort, err);
00170 if (*err > 0) goto ErrL;
00171 break;
00172
00173 case 253:
00174 C2F(mgetnc) (fd, (void*) labelsst1, &three, typ_short, err);
00175 if (*err > 0) goto ErrL;
00176 C2F(mgetnc) (fd, (void*) &indsst , &one, typ_int, err);
00177 if (*err > 0) goto ErrL;
00178
00179 (*chainesind)[(labelsst1[1])*(hauteur)+labelsst1[0]]=indsst+1;
00180 break;
00181 case 512:
00182 C2F(mgetnc) (fd, (void*) &f_row, &one, typ_int, err);
00183 if (*err > 0) goto ErrL;
00184 C2F(mgetnc) (fd, (void*) &l_row, &one, typ_int, err);
00185 if (*err > 0) goto ErrL;
00186 C2F(mgetnc) (fd, (void*) &f_col, &one, typ_ushort, err);
00187 if (*err > 0) goto ErrL;
00188 C2F(mgetnc) (fd, (void*) &l_col, &one, typ_ushort, err);
00189 if (*err > 0) goto ErrL;
00190 C2F(mgetnc) (fd, (void*) ¬used, &one, typ_ushort, err);
00191 if (*err > 0) goto ErrL;
00192
00193
00194 hauteur=l_row;
00195 longueur=l_col;
00196 capacite=hauteur*longueur;
00197
00198
00199 if ((valeur=(void*) MALLOC((capacite+1)*sizeof(double)))==NULL) goto ErrL;
00200 if ((*chainesind=(int *) MALLOC((capacite+1)*sizeof(int)))==NULL) goto ErrL;
00201 for (i=0;i<=capacite;i++) {
00202 (*chainesind)[i]=0;
00203 valeur[i]=NaN;
00204 }
00205 break;
00206 case 6:
00207 C2F(mgetnc) (fd, (void*) &row, &one, typ_ushort, err);
00208 if (*err > 0) goto ErrL;
00209 C2F(mgetnc) (fd, (void*) &col, &one, typ_ushort, err);
00210 if (*err > 0) goto ErrL;
00211 C2F(mgetnc) (fd, (void*) &xf, &one, typ_ushort, err);
00212 if (*err > 0) goto ErrL;
00213
00214 C2F(mgetnc) (fd, (void*) &resultat, &one, typ_double, err);
00215 if (*err > 0) goto ErrL;
00216
00217 valeur[(col*hauteur+row)]=resultat;
00218
00219 C2F(mgetnc) (fd, (void*)&optionflag, &one, typ_short, err);
00220 if (*err > 0) goto ErrL;
00221
00222 C2F(mgetnc) (fd, (void*) &formula_notused, &one, typ_int, err);
00223 if (*err > 0) goto ErrL;
00224
00225
00226 taille=Len-2-2-2-8-2-4;
00227
00228
00229
00230
00231 break;
00232 }
00233 *cur_pos=*cur_pos+4+Len;
00234 }
00235 return;
00236 ErrL:
00237 {
00238 FREE(sheetname);
00239 FREE(valeur);
00240 FREE(*chainesind);
00241 if (*err==0)
00242 *err=1;
00243 else
00244 *err=2;
00245 return;
00246 }
00247 }
00248
00249
00250 void xls_open(int *err, int *fd, char ***sst, int *ns, char ***Sheetnames, int** Abspos,int *nsheets)
00251 {
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270 int k,one=1;
00271 int cur_pos, init_pos;
00272 double pos;
00273 unsigned short Opcode, Len;
00274
00275 int BOFData[7];
00276 *nsheets=0;
00277 *err=0;
00278
00279 cur_pos=0;
00280
00281
00282
00283
00284
00285 C2F(mtell) (fd, &pos, err);
00286 cur_pos=(int)pos;
00287 init_pos=cur_pos;
00288
00289
00290 getBOF(fd ,BOFData, err);
00291 if (*err > 0) return;
00292
00293 if (BOFData[0]<0) {
00294 *err=4;
00295 return;
00296 }
00297 if (BOFData[0] != 8) {
00298 *err=5;
00299 return;
00300 }
00301
00302 C2F(mtell) (fd, &pos, err);
00303 if (*err > 0) goto Err2;
00304 cur_pos=(int)pos;
00305
00306
00307 while(1) {
00308 C2F(mseek) (fd, &cur_pos, "set", err);
00309 if (*err > 0) goto Err2;
00310
00311 C2F(mgetnc) (fd, &Opcode, &one, typ_ushort, err);
00312 if (*err > 0) goto Err2;
00313 C2F(mgetnc) (fd, &Len, &one, typ_ushort, err);
00314 if (*err > 0) goto Err2;
00315
00316 switch(Opcode) {
00317 case 10:
00318 cur_pos=cur_pos+4+Len;
00319 return ;
00320 case 133:
00321 getBoundsheets(fd,Sheetnames, Abspos,nsheets,&cur_pos,err);
00322 for (k=0;k<*nsheets;k++) (*Abspos)[k]+=init_pos;
00323 if (*err > 0) return;
00324 break;
00325 case 252:
00326 getSST(fd,Len,BOFData[0],ns,sst,err);
00327 if (*err > 0) return;
00328 cur_pos=cur_pos+4+Len;
00329 break;
00330 default:
00331 cur_pos=cur_pos+4+Len;
00332 }
00333 }
00334
00335 Err2:
00336 *err=4;
00337 return;
00338
00339 }
00340
00341 static double NumFromRk2(long rk)
00342 {
00343 double num;
00344 if(rk & 0x02)
00345 {
00346
00347 num = (double) (rk >> 2);
00348 }
00349 else
00350 {
00351
00352 *((int *)&num+1) = rk & 0xfffffffc;
00353 *((int *)&num) = 0;
00354 }
00355 if(rk & 0x01)
00356
00357 num /= 100;
00358 return num;
00359 }
00360
00361 static void getBOF(int *fd ,int* Data, int *err)
00362 {
00363
00364
00365 int BIFF;
00366 short Version;
00367 short DataType;
00368 short Identifier=0;
00369 short Year=0;
00370 int HistoryFlags=0;
00371 int LowestXlsVersion=0;
00372
00373 unsigned short Opcode;
00374 unsigned short Len;
00375 int one=1;
00376
00377 C2F(mgetnc) (fd, (void*)&Opcode, &one, typ_ushort, err);
00378 if (*err > 0) return;
00379 C2F(mgetnc) (fd, (void*)&Len, &one, typ_ushort, err);
00380 if (*err > 0) return;
00381
00382 switch(Opcode) {
00383 case 2057:
00384 C2F(mgetnc) (fd, (void*)&Version, &one, typ_short, err);
00385 if (*err > 0) return;
00386 C2F(mgetnc) (fd, (void*)&DataType, &one, typ_short, err);
00387 if (*err > 0) return;
00388 C2F(mgetnc) (fd, (void*)&Identifier, &one, typ_short, err);
00389 if (*err > 0) return;
00390 C2F(mgetnc) (fd, (void*)&Year, &one, typ_short, err);
00391 if (*err > 0) return;
00392 if (Len==16) {
00393 C2F(mgetnc) (fd, (void*)&HistoryFlags, &one, typ_int, err);
00394 if (*err > 0) return;
00395 C2F(mgetnc) (fd, (void*)&LowestXlsVersion, &one, typ_int, err);
00396 if (*err > 0) return;
00397 BIFF=8;
00398 if (Version != 1536) return;
00399 }
00400 else
00401 BIFF=7;
00402 break;
00403 case 1033 :
00404 C2F(mgetnc) (fd, (void*)&Version, &one, typ_short, err);
00405 if (*err > 0) return;
00406 C2F(mgetnc) (fd, (void*)&DataType, &one, typ_short, err);
00407 if (*err > 0) return;
00408 BIFF=4;
00409 break;
00410 case 521 :
00411 C2F(mgetnc) (fd, (void*)&Version, &one, typ_short, err);
00412 if (*err > 0) return;
00413 C2F(mgetnc) (fd, (void*)&DataType, &one, typ_short, err);
00414 if (*err > 0) return;
00415 BIFF=3;
00416 break;
00417 case 9 :
00418 C2F(mgetnc) (fd, (void*)&Version, &one, typ_short, err);
00419 if (*err > 0) return;
00420 C2F(mgetnc) (fd, (void*)&DataType, &one, typ_short, err);
00421 if (*err > 0) return;
00422 BIFF=2;
00423 break;
00424 default:
00425 BIFF=-1;
00426 Version=0;
00427 DataType=0;
00428 }
00429 Data[0]=BIFF;
00430 Data[1]=Version;
00431 Data[2]=DataType;
00432 Data[3]=Identifier;
00433 Data[4]=Year;
00434 Data[5]=HistoryFlags;
00435 Data[6]=LowestXlsVersion;
00436
00437 }
00438
00439 static void getSST(int *fd,short Len,int BIFF,int *ns,char ***sst,int *err)
00440 {
00441 int i,one=1;
00442
00443 int ntot;
00444 int nm;
00445 short count=0;
00446
00447 char *transfert;
00448 transfert=(char *)NULL;
00449 *ns=0;
00450 *sst=NULL;
00451
00452 if(BIFF==8) {
00453
00454 C2F(mgetnc) (fd, (void*)&ntot, &one, typ_int, err);
00455 if (*err > 0) goto ErrL;
00456 C2F(mgetnc) (fd, (void*)&nm, &one, typ_int, err);
00457 if (*err > 0) goto ErrL;
00458 *ns=nm;
00459 count+=8;
00460 if (nm !=0) {
00461 if( (*sst=(char **)MALLOC(nm*sizeof(char*)))==NULL) goto ErrL;
00462 for (i=0;i<nm;i++) (*sst)[i]=NULL;
00463 for(i=0;i<nm;i++) {
00464 *err=i;
00465 getString(fd,&count,&Len,1,&((*sst)[i]),err);
00466 if (*err > 0) goto ErrL;
00467
00468 }
00469 }
00470 }
00471 return;
00472 ErrL:
00473 if (*sst != NULL) {
00474 for (i=0;i<nm;i++)
00475 if ( (*sst)[i]!= NULL ) FREE((*sst)[i]);
00476 FREE(*sst);
00477 }
00478
00479 if (*err==0)
00480 *err=3;
00481 else
00482 *err=4;
00483 }
00484
00485 static void getString(int *fd,short *PosInRecord, short *RecordLen, int flag,char **str,int *err)
00486 {
00487 short ln=0;
00488 short Opcode;
00489 int BytesToBeRead,one=1,strindex;
00490 char OptionFlag=0;
00491 int sz;
00492 short rt;
00493 int UTFEncoding,extendedString,richString;
00494 int j,l1;
00495
00496 *str=(char *)NULL;
00497 *err=0;
00498 ln=0;
00499
00500
00501 if (flag&&(*PosInRecord==*RecordLen)) {
00502
00503
00504 C2F(mgetnc) (fd, &Opcode, &one, typ_ushort, err);
00505 if ((*err > 0)||(Opcode!=60)) goto ErrL;
00506 C2F(mgetnc) (fd, RecordLen, &one, typ_ushort, err);
00507 if (*err > 0) goto ErrL;
00508 *PosInRecord=0;
00509 }
00510
00511
00512 if (flag){
00513 C2F(mgetnc) (fd, (void*)&ln, &one, typ_short, err);
00514 if (*err > 0) goto ErrL;
00515 *PosInRecord+=2;
00516 }
00517 else {
00518 C2F(mgetnc) (fd, (void*)&ln, &one, typ_char, err);
00519 if (*err > 0) goto ErrL;
00520 *PosInRecord+=1;
00521 }
00522
00523
00524 C2F(mgetnc) (fd, (void*)&OptionFlag, &one, typ_char, err);
00525 if (*err > 0) goto ErrL;
00526 *PosInRecord+=1;
00527
00528 UTFEncoding = (OptionFlag&0x01) == 1;
00529 extendedString = (OptionFlag & 0x04) != 0;
00530 richString = (OptionFlag & 0x08) != 0;
00531
00532 if (richString) {
00533 C2F(mgetnc) (fd, (void*)&rt, &one, typ_short, err);
00534 *PosInRecord+=2;
00535 if (*err > 0) goto ErrL;
00536 }
00537
00538 if (extendedString) {
00539 C2F(mgetnc) (fd, (void*)&sz, &one, typ_int, err);
00540 if (*err > 0) goto ErrL;
00541 *PosInRecord+=4;
00542 }
00543
00544
00545 BytesToBeRead = (UTFEncoding)? ln*2 : ln;
00546
00547
00548 if ((*str= (char*) MALLOC((BytesToBeRead+1)*sizeof(char)))==NULL) goto ErrL;
00549
00550
00551 if (!flag||(*PosInRecord+BytesToBeRead<=*RecordLen)) {
00552
00553 C2F(mgetnc) (fd, (void*)*str, &BytesToBeRead, typ_char, err);
00554 if (*err > 0) goto ErrL;
00555 *PosInRecord+=BytesToBeRead;
00556 }
00557 else {
00558 int bytesRead = *RecordLen-*PosInRecord;
00559 strindex=0;
00560
00561
00562 C2F(mgetnc) (fd, (void*)(*str+strindex), &bytesRead, typ_char, err);
00563 if (*err > 0) goto ErrL;
00564 strindex+=bytesRead;
00565 *PosInRecord+=bytesRead;
00566 while (BytesToBeRead-bytesRead > 0){
00567
00568 C2F(mgetnc) (fd, &Opcode, &one, typ_ushort, err);
00569 if ((*err > 0)||(Opcode!=60)) goto ErrL;
00570 C2F(mgetnc) (fd, RecordLen, &one, typ_ushort, err);
00571 if (*err > 0) goto ErrL;
00572 *PosInRecord=0;
00573
00574 C2F(mgetnc) (fd, (void*)&OptionFlag, &one, typ_char, err);
00575 if (*err > 0) goto ErrL;
00576 *PosInRecord+=1;
00577
00578 if ((!UTFEncoding && (OptionFlag == 0))||(UTFEncoding && (OptionFlag != 0))) {
00579
00580 l1=Min(BytesToBeRead-bytesRead,*RecordLen-*PosInRecord);
00581 C2F(mgetnc) (fd, (void*)(*str+strindex), &l1, typ_char, err);
00582 if (*err > 0) goto ErrL;
00583 bytesRead+=l1;
00584 strindex+=l1;
00585 *PosInRecord+=l1;
00586 }
00587 else if (UTFEncoding && (OptionFlag == 0)) {
00588
00589
00590 l1=Min(BytesToBeRead-bytesRead,*RecordLen-*PosInRecord);
00591 for (j=0;j<l1;j++){
00592 C2F(mgetnc) (fd, (void*)(*str+strindex), &one, typ_char, err);
00593 if (*err > 0) goto ErrL;
00594 (*str)[strindex+1]='\0';
00595 strindex+=2;
00596 *PosInRecord+=2;
00597 UTFEncoding =0;
00598 }
00599 }
00600 else {
00601
00602
00603 char *str1=*str;
00604 strindex=0;
00605 if ((str= (char*) MALLOC((2*BytesToBeRead+1)*sizeof(char)))==NULL) goto ErrL;
00606 for (j=0;j<bytesRead;j++) {
00607 (*str)[strindex]=str1[j];
00608 (*str)[strindex+1]='\0';
00609 strindex+=2;
00610 }
00611 FREE(str1);
00612 BytesToBeRead=BytesToBeRead*2;
00613 bytesRead=bytesRead*2;
00614
00615 l1=Min((BytesToBeRead-bytesRead)*2,*RecordLen-*PosInRecord);
00616 C2F(mgetnc) (fd, (void*)(*str+strindex), &l1, typ_char, err);
00617 if (*err > 0) goto ErrL;
00618 bytesRead+=l1;
00619 strindex+=l1;
00620 *PosInRecord+=l1;
00621 UTFEncoding =1;
00622 }
00623
00624 }
00625
00626 }
00627
00628
00629
00630 l1=4*rt;
00631 if (richString) {C2F(mseek) (fd, &l1, "cur", err);*PosInRecord+=l1;}
00632 if (extendedString) {C2F(mseek) (fd, &sz, "cur", err);*PosInRecord+=sz;}
00633
00634
00635 if (UTFEncoding) {
00636
00637 strindex=0;
00638 for (j=0;j<BytesToBeRead;j+=2) {
00639 (*str)[strindex]=(*str)[j];
00640 strindex++;
00641 }
00642 BytesToBeRead=BytesToBeRead/2;
00643 }
00644 (*str)[BytesToBeRead]='\0';
00645
00646
00647 return;
00648 ErrL:
00649 if (*err == 0) {
00650 FREE(*str);
00651 *err=3;
00652 }
00653 else
00654 *err=4;
00655 }
00656
00657 static void getBoundsheets(int * fd,char ***Sheetnames, int** Abspos, int *nsheets,int *cur_pos,int *err)
00658 {
00659
00660 int abspos;
00661 char visibility,sheettype;
00662 int pos;
00663 unsigned short Opcode;
00664 unsigned short Len;
00665 int one=1;
00666 int ns,i;
00667
00668 *Sheetnames=(char **)NULL;
00669 *Abspos=(int *)NULL;
00670 *err=0;
00671
00672
00673 pos=*cur_pos;
00674
00675 ns=0;
00676 while(1) {
00677 C2F(mseek) (fd, cur_pos, "set", err);
00678 if (*err > 0) goto ErrL;
00679 C2F(mgetnc) (fd, &Opcode, &one, typ_ushort, err);
00680 if (*err > 0) goto ErrL;
00681 C2F(mgetnc) (fd, &Len, &one, typ_ushort, err);
00682 if (*err > 0) goto ErrL;
00683 if (Opcode==133) {
00684 C2F(mgetnc) (fd, (void*)&abspos, &one, typ_int, err);
00685 if (*err > 0) goto ErrL;
00686 C2F(mgetnc) (fd, (void*)&visibility, &one, typ_char, err);
00687 if (*err > 0) goto ErrL;
00688 C2F(mgetnc) (fd, (void*)&sheettype, &one, typ_char, err);
00689 if (sheettype==0) {
00690 ns++;
00691 }
00692 *cur_pos=*cur_pos+4+Len;
00693 }
00694 else
00695 break;
00696
00697 }
00698
00699 *nsheets=ns;
00700
00701 if( (*Sheetnames=(char **)MALLOC(ns*sizeof(char*)))==NULL) goto ErrL;
00702 if( (*Abspos=(int *)MALLOC(ns*sizeof(int)))==NULL) goto ErrL;
00703
00704
00705 *cur_pos=pos;
00706 i=-1;
00707 while(1) {
00708 C2F(mseek) (fd, cur_pos, "set", err);
00709 if (*err > 0) goto ErrL;
00710 C2F(mgetnc) (fd, &Opcode, &one, typ_ushort, err);
00711 C2F(mgetnc) (fd, &Len, &one, typ_ushort, err);
00712 if (Opcode==133) {
00713 C2F(mgetnc) (fd, (void*)&abspos, &one, typ_int, err);
00714 if (*err > 0) goto ErrL;
00715 C2F(mgetnc) (fd, (void*)&visibility, &one, typ_char, err);
00716 if (*err > 0) goto ErrL;
00717 C2F(mgetnc) (fd, (void*)&sheettype, &one, typ_char, err);
00718 if (sheettype==0) {
00719 short count=0;
00720 i++;
00721 (*Abspos)[i]=abspos;
00722 getString(fd,&count,&Len, 0,&((*Sheetnames)[i]),err);
00723 if (*err > 0) goto ErrL;
00724 }
00725 *cur_pos=*cur_pos+4+Len;
00726 }
00727 else
00728 break;
00729
00730 }
00731 return;
00732 ErrL:
00733 if (*Sheetnames != NULL) {
00734 for (i=0;i<ns;i++)
00735 if ( (*Sheetnames)[i]!= NULL ) FREE((*Sheetnames)[i]);
00736 FREE(*Sheetnames);
00737 }
00738 FREE(*Abspos);
00739 if (*err==0)
00740 *err=3;
00741 else
00742 *err=4;
00743 }
00744 static int get_oleheader(int *fd)
00745 {
00746 unsigned char MAGIC[8] = { 0xd0, 0xcf, 0x11, 0xe0, 0xa1, 0xb1, 0x1a, 0xe1 };
00747 unsigned char header[512];
00748 int c,ierr;
00749
00750 C2F(mgetnc) (fd, (void *)header,(c=512,&c), typ_uchar, &ierr);
00751 if (ierr !=0) return 1;
00752 if (memcmp (header, MAGIC, sizeof (MAGIC)) != 0) return 1;
00753 return 0;
00754 }