/* Ce fichier contient les fonctions de creation, et de lecture */ /* du fichier de suivi des etoiles */ /* R. Ansari Mars 92 */ #include #include #include #include "machdefs.h" #include "swapbytes.h" #include "fsvcache.h" #include "filecache.h" /* SOPHYA V >= 2.130 , SWAPDEFAUT n'est plus defini */ #if ( IS_BIG_ENDIAN == 0 ) #define SWAPDEFAUT 1 #else #define SWAPDEFAUT 0 #endif #ifdef RFIO #include #endif /* ++ Module Gestion des Suivis (C) Lib fsv include fsvcache.h Ce groupe de fonctions permettent de manipuler les fichiers de suivi. Les données sont stockées sous format binaire dans le fichier et les fonctions de lecture/ écriture assure le changement de l'ordre des octets en fonction de l'architecture de la machine (Little Endian, Big Endian), à l'odre d'écriture des octets dans le fichier, et du format des données déclaré à la création du suivi. L'ordre d'écriture des octets dans le fichier correspond à celui de la machine où a lieu la création du fichier. Une description plus detaillée se trouve dans la note Peida No 1. -- */ /* declaration des fonctions privees de ce fichier */ #ifdef IBMVM #define FindSizeofRec FndSzRec #endif int_4 FindSizeofRec(char *fmt); void SwapSuiviEntete(ENTETESUIVI *hp); void SwapSuiviRecord(char* rec, char* fmt, int fmtl, int nr); static int sv_prtlev = 0; /* Nouvelle-Fonction */ void SuiviSetPrtLevel(int lev) { sv_prtlev = lev; zfSetPrtLevel(lev); } /* ++ Titre Création des fichiers de suivi -- */ /* ++ int SuiviCreate(char *filename, int typ, int rec0size, char *rec1fmt, - char *rec2fmt, char *rec3fmt, char *rec4fmt, int nitem) Cette fonction crée la structure d'entete avec la définition des formats des enregistrements (record). | filename : Nom de fichier | typ : Identificateur de type de fichier de suivi | rec0size : Taille de la zone commentaire (Rec-0) en octets | recifmt : (i=1..4) Format des records Rec-i (i=1..4) | nitem : facteur de groupement des mesures Les formats sont spécifiés sous forme d'une chaine de caractère décrivant la succession de valeurs constituant un record (Ex: "IIFFS"). | I ou L : entier (4 octets) | S : entier (2 octets) | F : Reel (4 octets) | D : Double precision (8 octets) Le code de retour est nul (0) en cas de succès. -- */ /* Nouvelle-Fonction */ int SuiviCreate(char *filename, int typ, int rec0size, char *rec1fmt, char *rec2fmt, char *rec3fmt, char *rec4fmt, int nitem) /* Cette fonction permet la creation d'un fichier de suivi */ /* Retourne 0 si OK - Non-nul si probleme. */ /* Arguments : */ /* - filename : Nom de fichier. */ /* - typ : valeur stockee ds l'entete (Type) */ /* - rec0size : Taille de la zone comment (Rec0) en byte */ /* - rec1/2/3/4fmt : Format des records type 1,2,3,4 */ /* Les formats sont specifies sous forme d'une chaines */ /* de charactere avec le codage suivant: */ /* I S L : Entiers short int et long int (L=I) */ /* F D : float et double */ /* - nitem : Nb de mesures / record (def = 10) */ { int i; ENTETESUIVI head; FILE *fip; char fiac[80]; if (rec0size < 0) rec0size=0; if (nitem <= 0) nitem = 10; head.RecSize[0] = rec0size; head.NItem = nitem; head.NbMesTot = head.NbStars = (int_4)0; head.Swap = 0; head.Type = typ; head.FgCorrupt = 0; /* Pour le Byte-Swap */ if (SWAPDEFAUT) head.Swap = 0xFFFF; else head.Swap = 0; /* Analyse des formats */ if ( (head.RecSize[1] = FindSizeofRec(rec1fmt)) <= 0 ) { printf(" SuiviCreate-Erreur ds format Rec_1 \n"); return(1); } if ( (head.RecSize[2] = FindSizeofRec(rec2fmt)) <= 0 ) { printf(" SuiviCreate-Erreur ds format Rec_2 \n"); return(2); } if ( (head.RecSize[3] = FindSizeofRec(rec3fmt)) <= 0 ) { printf(" SuiviCreate-Erreur ds format Rec_3 \n"); return(3); } if ( (head.RecSize[4] = FindSizeofRec(rec4fmt)) <= 0 ) { printf(" SuiviCreate-Erreur ds format Rec_4 \n"); return(4); } head.RecSize[3] *= head.NItem; head.RecSize[4] *= head.NItem; head.FmtSize[0] = 0; head.FmtSize[1] = strlen(rec1fmt); head.FmtSize[2] = strlen(rec2fmt); head.FmtSize[3] = strlen(rec3fmt); head.FmtSize[4] = strlen(rec4fmt); head.HSize = sizeof(ENTETESUIVI); for(i=0; i<5; i++) head.HSize += head.FmtSize[i]; head.FileSize = head.HSize; #ifndef IBMVM strcpy(fiac,"wb"); #else strcpy(fiac,"wb, recfm=FS, lrecl=1024"); #endif if ((fip=fopen(filename,fiac)) == NULL) { printf(" SuiviCreate-Erreur ouverture fichier \n"); return(10); } fwrite(&head,sizeof(ENTETESUIVI),1,fip); fwrite(rec1fmt,1,head.FmtSize[1],fip); fwrite(rec2fmt,1,head.FmtSize[2],fip); fwrite(rec3fmt,1,head.FmtSize[3],fip); fwrite(rec4fmt,1,head.FmtSize[4],fip); fclose(fip); return(0); } #ifdef IBMVM int NPg[5]={0,50,100,150,200}; int PgSz[5]={0,4096,8092,16184,32768}; #else int NPg[5]={0,10,50,100,200}; int PgSz[5]={0,2048,2048,4096,8092}; #endif /* ++ Titre Ouverture, fermeture des suivis Le pointeur (l'identificateur) de fichier renvoyé par "SuiviOpen()" est le premier argument de toutes les autres fonctions "(suivifip)". -- */ /* ++ SUIVIFIP *SuiviOpen(char * filename, int rw) Ouverture du fichier en mode lecture "rw=SUOF_RO" ou lecture/ecriture "rw=SUOF_RW". L'activation de la memoire cache se fait aussi a travers l'argument "rw" | SUOF_RW_MEM, SUOF_RO_MEM | ou MEM2 , MEM3, MEM4 int SuiviClose(SUIVIFIP *suivfip) fermeture du fichier de suivi. Le fichier peut être corrompu s'il est ouvert en écriture et si "SuiviClose()" n'est pas appelé. void SuiviSetPrtLevel(int lev) Modification du niveau d'impression des messages d'informations/debug -- */ /* Nouvelle-Fonction */ SUIVIFIP *SuiviOpen(char * filename, int rw) /* Fonction d'ouverture de fichier de suivi pour lecture/ecriture */ /* Retourne un pointeur sur la structure SUIVIFIP - NULL si Pb. */ /* rw : Flag d'ouverture fichier en Read/Write SUOF_RW */ /* ou en ReadOnly SUOF_RO */ { SUIVIFIP *sfip; char *po; char fiac[20]; int mopt; FILE *fip; int_4 res2; char* fmtspace; int i,lfmt,rsz; if ((po=(char *)malloc(sizeof(SUIVIFIP)+strlen(filename)+1)) == NULL) { printf(" SuiviOpen_Erreur : Pb malloc() \n"); return(NULL); } sfip = (SUIVIFIP *)(po); sfip->Nom = po+sizeof(SUIVIFIP); mopt = rw/10; if ( (mopt<0) || (mopt>4) ) mopt=0; rw = rw%10; if ( rw == SUOF_RW ) { strcpy(fiac,"rb+"); sfip->FgRW = SUOF_RW ; } else { strcpy(fiac,"rb"); sfip->FgRW = rw = SUOF_RO ; } #ifdef IBMVM strcat(fiac,"b"); #endif /* Lecture entete - En cas de d'ouverture en RW, on reecrit l'entete */ /* en utilisant le mot FgCorrupt qui passe a negatif - */ /* Head.FgCorrupt = Flag FileCorrupted */ /* OK -> FgCorrupt == NbMesTot , Negatif -> -(Derniere mesure OK) */ /* ou -99999999 Reza 10/12/96 */ if ( (fip = fopen(filename,fiac)) == NULL ) { printf("SuiviOpen_Erreur : Pb fopen(%s) \n",filename); free(po); return(NULL); } fseek(fip, (long)0, SEEK_SET); fread(&(sfip->Head),sizeof(ENTETESUIVI),1,fip); /* On verifie avant tout si le fichier doit etre byte-swape */ if ( (sfip->Head.Swap != 0) && (SWAPDEFAUT != 0) ) sfip->FgSwap = 0; else if ( (sfip->Head.Swap == 0) && (SWAPDEFAUT == 0) ) sfip->FgSwap = 0; else { sfip->FgSwap = 1; if (sv_prtlev > 3) printf("SuiviOpen_Warning: ByteSwap[%x,%x] de Suivi(%s) \n", (int)SWAPDEFAUT, (int)sfip->Head.Swap, filename); SwapSuiviEntete(&(sfip->Head)); } /* Allocation d'espace pour les formats */ lfmt = 0; for(i=1;i<5;i++) lfmt += (sfip->Head.FmtSize[i]+1); fmtspace = (char *)malloc(lfmt); if (fmtspace == NULL) { printf(" SuiviOpen_Erreur : Pb. malloc fmtspace \n"); free(po); return(NULL); } sfip->RecFmt[0] = fmtspace; /* Lecture des elements de formats */ for(i=1;i<5;i++) { sfip->RecFmt[i] = fmtspace; if ( (rsz=sfip->Head.FmtSize[i]) <= 0) continue; fread(sfip->RecFmt[i], 1, rsz, fip); *(sfip->RecFmt[i]+rsz) = '\0'; fmtspace += rsz; } res2 = sfip->Head.FgCorrupt; /* NbMesTot < 0 ne devrait pas arriver ! */ if (sfip->Head.NbMesTot < 0) { printf("SuiviOpen_Erreur: NMes<0 File=%s (FgCorrupt=%d NMes=%d) !?\n", filename, res2, sfip->Head.NbMesTot); free(fmtspace); free(po); fclose(fip); return(NULL); } if (res2 != sfip->Head.NbMesTot) printf("SuiviOpen_Warning : file %s corrompu (FgCorrupt=%d NMes=%d) !?\n", filename, res2, sfip->Head.NbMesTot); if ( (rw == SUOF_RW) && (res2 >= 0) ) { sfip->Head.FgCorrupt = -res2; if (sfip->Head.FgCorrupt == 0) sfip->Head.FgCorrupt = -99999999; if (sfip->Head.Swap) SwapSuiviEntete(&(sfip->Head)); /* Avant ecriture */ fseek(fip, (long)0, SEEK_SET); fwrite(&(sfip->Head),sizeof(ENTETESUIVI),1,fip); if (sfip->Head.Swap) SwapSuiviEntete(&(sfip->Head)); /* Reswap apres ecriture */ sfip->Head.FgCorrupt = res2; } fclose(fip); /* Ouverture fichier */ if ( (sfip->fcp = zfopen(filename,fiac,NPg[mopt],PgSz[mopt])) == NULL ) { printf("SuiviOpen_Erreur : Pb zfopen(%s) \n",filename); free(fmtspace); free(po); return(NULL); } sfip->fip = sfip->fcp->fip; strcpy(sfip->Nom,filename); sfip->OffsetMes = sfip->Head.HSize + sfip->Head.RecSize[0] + sfip->Head.RecSize[1] + sfip->Head.NbStars*sfip->Head.RecSize[2]; /* Impression de debug */ if (sv_prtlev > 3) { printf(" SuiviOpen_Debug : File= %s , TotSize,Hsize= %ld , %ld Offset= %ld Swap=%x\n", sfip->Nom,(long)sfip->Head.FileSize, (long)sfip->Head.HSize, (long)sfip->OffsetMes, (int)sfip->Head.Swap); printf(" SuiviOpen_Debug : RecSize[0..4] %d %d %d %d %d\n",sfip->Head.RecSize[0], sfip->Head.RecSize[1],sfip->Head.RecSize[2],sfip->Head.RecSize[3],sfip->Head.RecSize[4]); printf(" SuiviOpen_Debug : FmtSize[0..4] %d %d %d %d %d\n",sfip->Head.FmtSize[0], sfip->Head.FmtSize[1],sfip->Head.FmtSize[2],sfip->Head.FmtSize[3],sfip->Head.FmtSize[4]); printf(" SuiviOpen_Debug : NItem,NbStars,NbMesTot %d %d %d Type=%d (FgCorrupt= %d)\n", sfip->Head.NItem,sfip->Head.NbStars,sfip->Head.NbMesTot, (int)sfip->Head.Type, sfip->Head.FgCorrupt); } return(sfip); } /* ++ Titre Accès aux informations de l'entête Les fonctions suivantes permettent d'accéder a certaines informations sauvegardées dans l'entête (Nb. d'étoiles, de mesures, ...) -- */ /* ++ int_4 SuiviGetNbStars(SUIVIFIP *suivfip) Retourne le nombre d'étoiles dans le fichier. int_4 SuiviGetNbMesures(SUIVIFIP *suivfip) Retourne le nombre de mesures dans le fichier. int_4 SuiviGetType(SUIVIFIP *suivfip) Retourne le type déclaré à la création du fichier. int_4 SuiviGetSize(SUIVIFIP *suivfip) Retourne la taille actuelle du fichier de suivi. int_4 SuiviPredictSize(SUIVIFIP *suivfip, int nbst, int nbmes) Retourne la taille calculée pour le fichier avec "nbst" étoiles et "nbmes" mesures. -- */ /* Nouvelle-Fonction */ int_4 SuiviGetNbytStars(SUIVIFIP *suivfip) /* Retourne le nombre d'item pour chaque mesure ds le fichier */ { return ( suivfip->Head.RecSize[4] / suivfip->Head.NItem ) ; } /* Nouvelle-Fonction */ int_4 SuiviGetNbStars(SUIVIFIP *suivfip) /* Retourne le nombre d'etoiles ds le fichier */ { return ( suivfip->Head.NbStars ) ; } /* Nouvelle-Fonction */ int_4 SuiviGetNbMesures(SUIVIFIP *suivfip) /* Retourne le nb de mesures ds le fichier */ { return ( suivfip->Head.NbMesTot ) ; } /* Nouvelle-Fonction */ int_4 SuiviGetType(SUIVIFIP *suivfip) /* Retourne le type de fichier declare ds l'entete le fichier */ { return ( suivfip->Head.Type ) ; } /* Nouvelle-Fonction */ int_4 SuiviGetSize(SUIVIFIP *suivfip) /* Retourne la taille actuelle du fichier de suivi */ { return ( suivfip->Head.FileSize ) ; } /* Nouvelle-Fonction */ int_4 SuiviPredictSize(SUIVIFIP *sfip, int nbst, int nbmes) /* Retourne la taille calculee pour le nb d'etoiles (nbst) et mesures (nbmes) */ { int_4 totsz, nbm; totsz = sfip->Head.HSize + sfip->Head.RecSize[0] + /* Entete+zone commentaire */ sfip->Head.RecSize[1] + /* Zone globinfo */ nbst*sfip->Head.RecSize[2]; /* Les starInfos */ /* On calcule le nombre de blocks mesures */ nbm = nbmes / sfip->Head.NItem; /* Les mesures sont groupees par block de NItem */ if ((nbmes%sfip->Head.NItem) != 0) nbm++; totsz += nbm*(sfip->Head.RecSize[3] + nbst*sfip->Head.RecSize[4]); return ( totsz ) ; } /* Nouvelle-Fonction */ int SuiviClose(SUIVIFIP *suivfip) /* Fonction de fermeture de fichier de suivi - Cet appel est obligatoire en */ /* cas de modification (ecriture) du fichier de suivi, avant la fin du prog. */ /* Retour 0 OK - NonNul-> Erreur */ { if (suivfip == NULL) return(1); /* Ecriture entete fichier */ if (suivfip->FgRW == SUOF_RW) { if (suivfip->Head.FgCorrupt >= 0) /* M.A.J Flag FileCorrupted */ suivfip->Head.FgCorrupt = suivfip->Head.NbMesTot; if (suivfip->FgSwap) /* On byte-swap avant ecriture */ SwapSuiviEntete(&(suivfip->Head)); if (zfseek(suivfip->fcp, (long)(0), SEEK_SET) != 0) { printf(" SuiviClose_Erreur : Pb zfseek() \n"); return(10); } zfwrite(&(suivfip->Head),sizeof(ENTETESUIVI),1,suivfip->fcp); } zfclose(suivfip->fcp); free(suivfip->RecFmt[0]); free(suivfip); return(0); } /* ++ Titre Lecture, écriture Pour toutes les fonctions de lecture/ecriture, "buff" désigne le pointeur d'une zone mémoire contenant l'information à écrire ou destinée à recevoir l'information lue dans le fichier de suivi. L'argument "numet" indique le numéro d'étoile (1..NbStars), et "numes" le numéro de mesure (1..NbMes). Le code de retour est non nul en cas d'erreur. -- */ /* ++ int SuiviWriteComment(SUIVIFIP *suivfip, char *buff) Ecriture de la zone commentaire. int SuiviReadComment(SUIVIFIP *suivfip, char *buff) Lecture de la zone commentaire. -- */ /* Nouvelle-Fonction */ int SuiviWriteComment(SUIVIFIP *suivfip, char *buff) /* Cette fonction ecrit les comment ds le fichier de suivi */ /* retour 0 OK */ { int_4 sz; int rc; if (suivfip == NULL) return(1); if (suivfip->FgRW != SUOF_RW) {printf(" SuiviWriteComment_Erreur : Fichier ReadOnly \n"); return(2);} /* Ecriture */ rc = 0; if (zfseek(suivfip->fcp, (long)suivfip->Head.HSize, SEEK_SET) != 0) { printf(" SuiviWriteComment_Erreur : Pb zfseek() \n"); suivfip->Head.FgCorrupt = -99999999; rc = 10; } else if (zfwrite(buff,1,(size_t)suivfip->Head.RecSize[0],suivfip->fcp) != suivfip->Head.RecSize[0]) { printf(" SuiviWriteComment_Erreur : Pb zfwrite() \n"); suivfip->Head.FgCorrupt = -99999999; rc = 11; } /* M.A.J. Entete */ sz = suivfip->Head.HSize+suivfip->Head.RecSize[0]; if (suivfip->Head.FileSize < sz) suivfip->Head.FileSize = sz; return(rc); } /* Nouvelle-Fonction */ int SuiviReadComment(SUIVIFIP *suivfip, char *buff) /* Cette fonction lit les comment ds le fichier de suivi */ /* retour 0 OK */ { if (suivfip == NULL) return(1); if (zfseek(suivfip->fcp, (long)suivfip->Head.HSize, SEEK_SET) != 0) { printf(" SuiviReadComment_Erreur : Pb zfseek() \n"); return(10); } zfread(buff,1,(size_t)suivfip->Head.RecSize[0],suivfip->fcp); return(0); } /* ++ int SuiviWriteGlobInfo(SUIVIFIP *suivfip, char *buff) Ecriture de l'enregistrement GlobInfo. int SuiviReadGlobInfo(SUIVIFIP *suivfip, char *buff) Lecture de l'enregistrement GlobInfo. -- */ /* Nouvelle-Fonction */ int SuiviWriteGlobInfo(SUIVIFIP *suivfip, char *buff) /* Cette fonction ecrit l'enregistrement des infos globales */ /* retour 0 OK */ { int_4 sz; int rc; if (suivfip == NULL) return(1); if (suivfip->FgRW != SUOF_RW) {printf(" SuiviWriteComment_Erreur : Fichier ReadOnly \n"); return(2);} if (suivfip->FgSwap) /* On byte-swap avant ecriture */ SwapSuiviRecord(buff, suivfip->RecFmt[1], suivfip->Head.FmtSize[1], 1); /* Ecriture */ rc = 0; sz = suivfip->Head.HSize+suivfip->Head.RecSize[0]; if (zfseek(suivfip->fcp, (long)sz, SEEK_SET) != 0) { printf(" SuiviWriteGlobInfo_Erreur : Pb zfseek() \n"); suivfip->Head.FgCorrupt = -99999999; rc = 10; } else if (zfwrite(buff,1,(size_t)suivfip->Head.RecSize[1],suivfip->fcp) != suivfip->Head.RecSize[1]) { printf(" SuiviWriteGlobInfo_Erreur : Pb zfwrite() \n"); suivfip->Head.FgCorrupt = -99999999; rc = 11; } if (suivfip->FgSwap) /* On remet dans le bon sens */ SwapSuiviRecord(buff, suivfip->RecFmt[1], suivfip->Head.FmtSize[1], 1); /* M.A.J. Entete */ sz = suivfip->Head.HSize + suivfip->Head.RecSize[0] + suivfip->Head.RecSize[1]; if (suivfip->Head.FileSize < sz) suivfip->Head.FileSize = sz; return(rc); } /* Nouvelle-Fonction */ int SuiviReadGlobInfo(SUIVIFIP *suivfip, char *buff) /* Cette fonction lit l'enregistrement des infos globales */ /* retour 0 OK */ { int_4 pos; if (suivfip == NULL) return(1); pos = suivfip->Head.HSize+suivfip->Head.RecSize[0]; if (zfseek(suivfip->fcp, (long)pos, SEEK_SET) != 0) { printf(" SuiviReadGlobInfo_Erreur : Pb zfseek() \n"); return(10); } zfread(buff,1,(size_t)suivfip->Head.RecSize[1],suivfip->fcp); if (suivfip->FgSwap) /* On byte-swap apres lecture */ SwapSuiviRecord(buff, suivfip->RecFmt[1], suivfip->Head.FmtSize[1], 1); return(0); } /* ++ int SuiviWriteStarInfo(SUIVIFIP *suivfip, int_4 num, char *buff) Ecriture de l'enregistrement StarInfo pour l'étoile "num" int SuiviReadStarInfo(SUIVIFIP *suivfip, int_4 num, char *buff) Lecture de l'enregistrement StarInfo pour l'étoile "num" -- */ /* Nouvelle-Fonction */ int SuiviWriteStarInfo(SUIVIFIP *suivfip, int_4 num, char *buff) /* Cette fonction ecrit les infos etoiles pour l'etoile */ /* numero num - Retour 0 OK */ { int_4 sz,pos; int rc; if (suivfip == NULL) return(1); if (suivfip->FgRW != SUOF_RW) {printf(" SuiviWriteStarInfo_Erreur : Fichier ReadOnly \n"); return(2);} if (num <= (int_4)0) { printf(" SuiviWriteStarInfo_Erreur : Num (=%ld) <= 0 \n",(long)num); return(3); } if ( (suivfip->Head.NbMesTot > 0) && (suivfip->Head.NbStars < num) ) { printf(" SuiviWriteStarInfo_Erreur : Fichier contient des mesures ! \n"); return(4); } if (suivfip->FgSwap) /* On byte-swap avant ecriture */ SwapSuiviRecord(buff, suivfip->RecFmt[2], suivfip->Head.FmtSize[2], 1); /* Ecriture */ pos = suivfip->Head.HSize + suivfip->Head.RecSize[0] + suivfip->Head.RecSize[1] + (num-1)*suivfip->Head.RecSize[2]; rc = 0; if (zfseek(suivfip->fcp, (long)pos, SEEK_SET) != 0) { printf(" SuiviWriteStarInfo_Erreur : Pb zfseek() \n"); suivfip->Head.FgCorrupt = -99999999; rc = 10; } else if ( zfwrite(buff,1,(size_t)suivfip->Head.RecSize[2],suivfip->fcp) != suivfip->Head.RecSize[2]) { printf(" SuiviWriteStarInfo_Erreur : Pb zfwrite() \n"); suivfip->Head.FgCorrupt = -99999999; rc = 11; } if (suivfip->FgSwap) /* On remet dans le bon sens */ SwapSuiviRecord(buff, suivfip->RecFmt[2], suivfip->Head.FmtSize[2], 1); /* M.A.J. Entete */ sz = pos+suivfip->Head.RecSize[2]; if (suivfip->Head.FileSize < sz) suivfip->Head.FileSize = sz; if (suivfip->Head.NbStars < num) { suivfip->Head.NbStars = num; suivfip->OffsetMes = suivfip->Head.HSize + suivfip->Head.RecSize[0] + suivfip->Head.RecSize[1] + suivfip->Head.NbStars*suivfip->Head.RecSize[2]; } return(rc); } /* Nouvelle-Fonction */ int SuiviReadStarInfo(SUIVIFIP *suivfip, int_4 num, char *buff) /* Cette fonction lit les infos etoiles pour l'etoile */ /* numero num - Retour 0 OK */ { int_4 pos; if (suivfip == NULL) return(1); if ( (num <= (int_4)0) || (num > suivfip->Head.NbStars) ) { printf(" SuiviReadStarInfo_Erreur : Num (=%ld) out of range \n",(long)num); return(2); } /* lecture */ pos = suivfip->Head.HSize + suivfip->Head.RecSize[0] + suivfip->Head.RecSize[1] + (num-1)*suivfip->Head.RecSize[2]; if (zfseek(suivfip->fcp, (long)pos, SEEK_SET) != 0) { printf(" SuiviReadStarInfo_Erreur : Pb zfseek() \n"); return(10); } zfread(buff,1,(size_t)suivfip->Head.RecSize[2],suivfip->fcp); if (suivfip->FgSwap) /* On byte-swap apres lecture */ SwapSuiviRecord(buff, suivfip->RecFmt[2], suivfip->Head.FmtSize[2], 1); return(0); } /* ++ int SuiviAddMesure(SUIVIFIP *suivfip, char *buff) Ajoute une nouvelle mesure dans le fichier. "buff" contient l'information TimeInfo pour cette mesure. -- */ /* Nouvelle-Fonction */ int SuiviAddMesure(SUIVIFIP *suivfip, char *buff) /* Cette fonction rajoute une nouvelle mesure ds le fichier de suivi */ /* *buff contient l'information temps de cette mesure */ /* Les mesures correspondant a ce temps doivent etre rajoute par */ /* SuiviWriteMesure() */ { int_4 pos,l1; ENTETESUIVI *head; int_4 itsiz; char bidbuf[4] = {'\0','\0','\0','\0'}; int rc; if (suivfip == NULL) return(1); if (suivfip->FgRW != SUOF_RW) {printf(" SuiviAddMesure_Erreur : Fichier ReadOnly \n"); return(2);} head = &(suivfip->Head); /* On verifie voir s'il faut creer de nouveaux records ? */ if ( (head->NbMesTot % head->NItem) == (int_4)(0) ) { pos = suivfip->OffsetMes + ( (head->NbMesTot / head->NItem) + 1) * ( head->RecSize[3] + (head->NbStars)*head->RecSize[4] ) - 4 ; if (zfseek(suivfip->fcp, (long)pos, SEEK_SET) != 0) { printf(" SuiviAddMesure_Erreur : Pb zfseek() \n"); suivfip->Head.FgCorrupt = -99999999; return(10); } if (zfwrite(bidbuf,1, 4, suivfip->fcp) != 4) { printf(" SuiviAddMesure_Erreur : Pb zfwrite() \n"); suivfip->Head.FgCorrupt = -99999999; return(11); } head->FileSize = pos+4; } head->NbMesTot++; l1 = (head->NbMesTot-1) / head->NItem; pos = suivfip->OffsetMes + l1 * (head->RecSize[3] + head->NbStars*head->RecSize[4]); itsiz = head->RecSize[3] / head->NItem ; pos += (head->NbMesTot-1 - l1*head->NItem) * itsiz; if (suivfip->FgSwap) /* On byte-swap avant ecriture */ SwapSuiviRecord(buff, suivfip->RecFmt[3], suivfip->Head.FmtSize[3], 1); rc = 0; if (zfseek(suivfip->fcp, (long)pos, SEEK_SET) != 0) { printf(" SuiviAddMesure_Erreur : Pb zfseek() \n"); suivfip->Head.FgCorrupt = -99999999; rc = 10; } else if (zfwrite(buff,1,(size_t)itsiz,suivfip->fcp) != itsiz) { printf(" SuiviAddMesure_Erreur : Pb zfseek() \n"); suivfip->Head.FgCorrupt = -99999999; rc = 11; } if (suivfip->FgSwap) /* On remet dans le bon sens apres ecriture */ SwapSuiviRecord(buff, suivfip->RecFmt[3], suivfip->Head.FmtSize[3], 1); return(rc); } /* ++ int SuiviWriteTimeInfo(SUIVIFIP *suivfip, int_4 numes, char *buff) Ecriture de TimeInfo pour la mesure numéro "numes" (1..NbMes). -- */ /* Nouvelle-Fonction */ int SuiviWriteTimeInfo(SUIVIFIP *suivfip, int_4 numes, char *buff) /* Cette fonction ecrit l'info temps pour la mesure numero num */ /* *buff contient l'information temps - Retour 0 OK */ { int_4 pos,l1; ENTETESUIVI *head; int_4 itsiz; int rc; if (suivfip == NULL) return(1); if (suivfip->FgRW != SUOF_RW) {printf(" SuiviWriteTimeInfo_Erreur : Fichier ReadOnly \n"); return(2);} head = &(suivfip->Head); if ( (numes <= (int_4)0) || (numes > suivfip->Head.NbMesTot) ) { printf(" SuiviWriteTimeInfo_Erreur : NumMesure (=%ld) out of range \n",(long)numes); return(3); } l1 = (numes-1) / head->NItem; pos = suivfip->OffsetMes + l1 * ( head->RecSize[3] + head->NbStars*head->RecSize[4] ); itsiz = head->RecSize[3] / head->NItem ; pos += ( numes-1 - l1*head->NItem ) * itsiz; if (suivfip->FgSwap) /* On byte-swap avant ecriture */ SwapSuiviRecord(buff, suivfip->RecFmt[3], suivfip->Head.FmtSize[3], 1); rc = 0; if (zfseek(suivfip->fcp, (long)pos, SEEK_SET) != 0) { printf(" SuiviWriteTimeInfo_Erreur : Pb zfseek() \n"); suivfip->Head.FgCorrupt = -99999999; rc = 10; } if (zfwrite(buff,1,(size_t)itsiz,suivfip->fcp) != itsiz) { printf(" SuiviWriteTimeInfo_Erreur : Pb zfwrite() \n"); suivfip->Head.FgCorrupt = -99999999; rc = 11; } if (suivfip->FgSwap) /* On remet dans le bon sens apres ecriture */ SwapSuiviRecord(buff, suivfip->RecFmt[3], suivfip->Head.FmtSize[3], 1); return(rc); } /* ++ int SuiviWriteMesure(SUIVIFIP *suivfip, int_4 numet, int_4 nummes, char *buff) Ecriture de l'infomation Mesure pour l'étoile numéro "numet" et la mesure numéro "numes" -- */ /* Nouvelle-Fonction */ int SuiviWriteMesure(SUIVIFIP *suivfip, int_4 numet, int_4 nummes, char *buff) /* Cette fonction ecrit une mesure ds le fichier de suivi */ /* numet est le numero d'etoile, nummes le numero de mesure */ /* *buff contient l'information mesure - Retour 0 OK */ { int_4 pos,l1; ENTETESUIVI *head; int_4 itsiz; int rc; if (suivfip == NULL) return(1); if (suivfip->FgRW != SUOF_RW) {printf(" SuiviWriteMesure_Erreur : Fichier ReadOnly \n"); return(2);} head = &(suivfip->Head); if ( (numet <= (int_4)0) || (numet > suivfip->Head.NbStars) ) { printf(" SuiviWriteMesure_Erreur : NumEtoile (=%ld) out of range \n",(long)numet); return(2); } if ( (nummes <= (int_4)0) || (nummes > suivfip->Head.NbMesTot) ) { printf(" SuiviWriteMesure_Erreur : NumMesure (=%ld) out of range \n",(long)nummes); return(3); } l1 = (nummes-1) / head->NItem; pos = suivfip->OffsetMes + l1 * (head->RecSize[3] + head->NbStars*head->RecSize[4]) + head->RecSize[3] + (numet-1)*head->RecSize[4]; itsiz = head->RecSize[4] / head->NItem ; pos += (nummes-1 - l1*head->NItem) * itsiz; if (suivfip->FgSwap) /* On byte-swap avant ecriture */ SwapSuiviRecord(buff, suivfip->RecFmt[4], suivfip->Head.FmtSize[4], 1); rc = 0; if (zfseek(suivfip->fcp, (long)pos, SEEK_SET) != 0) { printf(" SuiviWriteMesure_Erreur : Pb zfseek() \n"); suivfip->Head.FgCorrupt = -99999999; rc = 10; } else if (zfwrite(buff,1,(size_t)itsiz,suivfip->fcp) != itsiz) { printf(" SuiviWriteMesure_Erreur : Pb zfwrite() \n"); suivfip->Head.FgCorrupt = -99999999; rc = 11; } if (suivfip->FgSwap) /* On remet dans le bon sens apres ecriture */ SwapSuiviRecord(buff, suivfip->RecFmt[4], suivfip->Head.FmtSize[4], 1); return(rc); } /* ++ int SuiviReadTimeInfo(SUIVIFIP *suivfip, int_4 debut, int_4 fin, char *buff) Lecture des informations TimeInfo pour "debut <= mes <= fin". Attention : Des erreurs d'alignement d'accès mémoire peuvent avoir lieu en cas de lecture multiple "(fin > debut)" si la taille de la structure TimeInfo ne coincide pas avec celle de l'enregistrement correspondant. -- */ /* Nouvelle-Fonction */ int SuiviReadTimeInfo(SUIVIFIP *suivfip, int_4 debut, int_4 fin, char *buff) /* Cette fonction lit l'information temps pour les mesures */ /* debut <= NumMes <= fin Retour 0 OK */ { int_4 pos,l1; ENTETESUIVI *head; int_4 itsiz; int_4 fr,to,nit; char* buff0; if (suivfip == NULL) return(1); head = &(suivfip->Head); if ( (debut <= (int_4)0) || (debut > head->NbMesTot) ) { printf(" SuiviReadTimeInfo_Erreur : NumDebut (=%ld) out of range \n",(long)debut); return(3); } if ( (fin <= (int_4)0) || (fin > head->NbMesTot) ) { printf(" SuiviReadTimeInfo_Erreur : NumFin (=%ld) out of range \n",(long)fin); return(4); } if ( debut > fin) { printf(" SuiviReadTimeInfo_Erreur : NumFin (=%ld) < NumDebut(=%ld) \n", (long)fin, (long)debut); return(5); } itsiz = head->RecSize[3] / head->NItem ; fr=to=debut; buff0 = buff; do { l1 = (fr-1) / head->NItem; to = (l1+1) * head->NItem; if (to > fin) nit = fin-fr+1; else nit = to-fr+1; pos = suivfip->OffsetMes + l1 * (head->RecSize[3] + head->NbStars*head->RecSize[4]); pos += (fr-1 - l1*head->NItem) * itsiz; if (zfseek(suivfip->fcp, (long)pos, SEEK_SET) != 0) { printf(" SuiviReadTimeInfo_Erreur : Pb zfseek() \n"); return(10); } zfread(buff,(size_t)itsiz,nit,suivfip->fcp); fr += nit; buff += nit * itsiz; } while (fr <= fin); if (suivfip->FgSwap) /* On byte-swap apres lecture */ SwapSuiviRecord(buff0, suivfip->RecFmt[3], suivfip->Head.FmtSize[3], fin-debut+1); return(0); } /* ++ int SuiviReadMesures(SUIVIFIP *suivfip, int_4 numet, int_4 debut, int_4 fin, char *buff) Lecture des informations Mesure pour l'étoile "numet", "debut <= mes <= fin". Attention : Des erreurs d'alignement d'accès mémoire peuvent avoir lieu en cas de lecture multiple "(fin > debut)" si la taille de la structure Mesure ne coincide pas avec celle de l'enregistrement correspondant. -- */ /* Nouvelle-Fonction */ int SuiviReadMesures(SUIVIFIP *suivfip, int_4 numet, int_4 debut, int_4 fin, char *buff) /* Cette fonction lit les mesures pour l'etoile numet */ /* debut <= NumMes <= fin Retour 0 OK */ { int_4 pos,l1; ENTETESUIVI *head; int_4 itsiz; int_4 fr,to,nit; char* buff0; if (suivfip == NULL) return(1); head = &(suivfip->Head); if ( (numet <= (int_4)0) || (numet > head->NbStars) ) { printf(" SuiviReadMesures_Erreur : NumEtoile (=%ld) out of range \n", (long)numet); return(2); } if ( (debut <= (int_4)0) || (debut > head->NbMesTot) ) { printf(" SuiviReadMesures_Erreur : NumDebut (=%ld) out of range \n", (long)debut); return(3); } if ( (fin <= (int_4)0) || (fin > head->NbMesTot) ) { printf(" SuiviReadMesures_Erreur : NumFin (=%ld) out of range \n", (long)fin); return(4); } if ( debut > fin) { printf(" SuiviReadMesures_Erreur : NumFin (=%ld) < NumDebut(=%ld) \n", (long)fin, (long)debut); return(5); } itsiz = head->RecSize[4] / head->NItem ; fr=to=debut; buff0 = buff; do { l1 = (fr-1) / head->NItem; to = (l1+1) * head->NItem; if (to > fin) nit = fin-fr+1; else nit = to-fr+1; pos = suivfip->OffsetMes + l1 * (head->RecSize[3] + head->NbStars*head->RecSize[4]) + head->RecSize[3] + (numet-1)*head->RecSize[4];; pos += (fr-1 - l1*head->NItem) * itsiz; if (zfseek(suivfip->fcp, (long)pos, SEEK_SET) != 0) { printf(" SuiviReadMesures_Erreur : Pb zfseek() \n"); return(10); } zfread(buff,(size_t)itsiz,nit,suivfip->fcp); fr += nit; buff += nit * itsiz; } while (fr <= fin); if (suivfip->FgSwap) /* On byte-swap apres lecture */ SwapSuiviRecord(buff0, suivfip->RecFmt[4], suivfip->Head.FmtSize[4], fin-debut+1); return(0); } /* Nouvelle-Fonction */ int_4 FindSizeofRec(char *fmt) { int i; char c; int sz; i= sz = 0; while ( (*fmt) != '\0' ) { c = toupper(*fmt); switch (c) { case 'I' : sz += sizeof(int_4); i++; break; case 'L' : sz += sizeof(int_4); i++; break; case 'S' : sz += sizeof(int_2); i++; break; case 'F' : sz += sizeof(r_4); i++; break; case 'D' : sz += sizeof(r_8); i++; break; default : printf(" FindSizeofRec_Erreur : Code format inconnu : %c \n",c); return(-1); break; } fmt++; } /* printf(" FindSizeofRec_debug : N= %d , size= %d \n",i,sz); */ return(sz); } /* Nouvelle-Fonction */ void SwapSuiviEntete(ENTETESUIVI *hp) { int i; Swap_Bytes4( &(hp->FileSize) ); Swap_Bytes4( &(hp->HSize) ); for(i=0; i<5; i++) Swap_Bytes2( &(hp->RecSize[i]) ); Swap_Bytes2( &(hp->NItem) ); Swap_Bytes4( &(hp->NbStars) ); Swap_Bytes4( &(hp->NbMesTot) ); for(i=0; i<5; i++) Swap_Bytes2( &(hp->FmtSize[i]) ); Swap_Bytes2( &(hp->Swap) ); Swap_Bytes2( &(hp->Type) ); Swap_Bytes4( &(hp->FgCorrupt) ); } /* Nouvelle-Fonction */ void SwapSuiviRecord(char* rec, char* fmt, int fmtl, int nr) { int i,j; char *pc; pc = rec; for( j = 0 ; j < nr ; j++ ) { for ( i = 0 ; i < fmtl ; i++ ) { switch( toupper(fmt[i]) ) { case 'I' : case 'L' : Swap_Bytes4(pc); pc += sizeof(int_4); break; case 'S' : Swap_Bytes2(pc); pc += sizeof(int_2); break; case 'F' : Swap_Bytes4(pc); pc += sizeof(r_4); break; case 'D' : Swap_Bytes8(pc); pc += sizeof(r_8); break; default : printf(" SwapSuiviRecord_Erreur : Code format inconnu : %c \n",fmt[i]); break; } } } return; }