Salome HOME
Update of CheckDone
[modules/smesh.git] / src / DriverGMF / libmesh5.c
1
2
3 /*----------------------------------------------------------*/
4 /*                                                                                                                      */
5 /*                                              LIBMESH V 5.46                                          */
6 /*                                                                                                                      */
7 /*----------------------------------------------------------*/
8 /*                                                                                                                      */
9 /*      Description:            handle .meshb file format I/O           */
10 /*      Author:                         Loic MARECHAL                                           */
11 /*      Creation date:          feb 16 2007                                                     */
12 /*      Last modification:      apr 03 2012                                                     */
13 /*                                                                                                                      */
14 /*----------------------------------------------------------*/
15
16
17 /*----------------------------------------------------------*/
18 /* Includes                                                                                                     */
19 /*----------------------------------------------------------*/
20
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <stdarg.h>
24 #include <string.h>
25 #include <float.h>
26 #include <math.h>
27 #include <ctype.h>
28 #include "libmesh5.h"
29 #ifdef WIN32
30 #include <windows.h>
31 #endif
32
33 /*----------------------------------------------------------*/
34 /* Defines                                                                                                      */
35 /*----------------------------------------------------------*/
36
37 #define Asc 1
38 #define Bin 2
39 #define MshFil 4
40 #define SolFil 8
41 #define MaxMsh 100
42 #define InfKwd 1
43 #define RegKwd 2
44 #define SolKwd 3
45 #define WrdSiz 4
46 #define BufSiz 10000
47
48
49 /*----------------------------------------------------------*/
50 /* Structures                                                                                           */
51 /*----------------------------------------------------------*/
52
53 typedef struct
54 {
55         int typ, SolSiz, NmbWrd, NmbLin, NmbTyp, TypTab[ GmfMaxTyp ];
56         long pos;
57         char fmt[ GmfMaxTyp*9 ];
58 }KwdSct;
59
60 typedef struct
61 {
62         int dim, ver, mod, typ, cod, pos;
63         long NexKwdPos, siz;
64         KwdSct KwdTab[ GmfMaxKwd + 1 ];
65         FILE *hdl;
66         int *IntBuf;
67         float *FltBuf;
68         unsigned char *buf;
69         char FilNam[ GmfStrSiz ];
70         double DblBuf[1000/8];
71         unsigned char blk[ BufSiz + 1000 ];
72 }GmfMshSct;
73
74
75 /*----------------------------------------------------------*/
76 /* Global variables                                                                                     */
77 /*----------------------------------------------------------*/
78
79 static int GmfIniFlg=0;
80 static GmfMshSct *GmfMshTab[ MaxMsh + 1 ];
81 /* see MeshGems/Docs/meshgems_formats_description.pdf */
82 static const char *GmfKwdFmt[ GmfMaxKwd + 1 ][4] = 
83 {       {"Reserved", "", "", ""},
84         {"MeshVersionFormatted", "", "", "i"},
85         {"Reserved", "", "", ""},
86         {"Dimension", "", "", "i"},
87         {"Vertices", "Vertex", "i", "dri"},
88         {"Edges", "Edge", "i", "iii"},
89         {"Triangles", "Triangle", "i", "iiii"},
90         {"Quadrilaterals", "Quadrilateral", "i", "iiiii"},
91         {"Tetrahedra", "Tetrahedron", "i", "iiiii"},
92         {"Prisms", "Prism", "i", "iiiiiii"},
93         {"Hexahedra", "Hexahedron", "i", "iiiiiiiii"},
94         {"IterationsAll", "IterationAll","","i"},
95         {"TimesAll", "TimeAll","","r"},                                 
96         {"Corners", "Corner", "i", "i"},
97         {"Ridges", "Ridge", "i", "i"},
98         {"RequiredVertices", "RequiredVertex", "i", "i"},
99         {"RequiredEdges", "RequiredEdge", "i", "i"},
100         {"RequiredTriangles", "RequiredTriangle", "i", "i"},
101         {"RequiredQuadrilaterals", "RequiredQuadrilateral", "i", "i"},
102         {"TangentAtEdgeVertices", "TangentAtEdgeVertex", "i", "iii"},
103         {"NormalAtVertices", "NormalAtVertex", "i", "ii"},
104         {"NormalAtTriangleVertices", "NormalAtTriangleVertex", "i", "iii"},
105         {"NormalAtQuadrilateralVertices", "NormalAtQuadrilateralVertex", "i", "iiii"},
106         {"AngleOfCornerBound", "", "", "r"},
107         {"TrianglesP2", "TriangleP2", "i", "iiiiiii"},
108         {"EdgesP2", "EdgeP2", "i", "iiii"},
109         {"SolAtPyramids", "SolAtPyramid", "i", "sr"},
110         {"QuadrilateralsQ2", "QuadrilateralQ2", "i", "iiiiiiiiii"},
111         {"ISolAtPyramids", "ISolAtPyramid", "i", "iiiii"},
112         {"SubDomainFromGeom", "SubDomainFromGeom", "i", "iiii"},
113         {"TetrahedraP2", "TetrahedronP2", "i", "iiiiiiiiiii"},
114         {"Fault_NearTri", "Fault_NearTri", "i", "i"},
115         {"Fault_Inter", "Fault_Inter", "i", "i"},
116         {"HexahedraQ2", "HexahedronQ2", "i", "iiiiiiiiiiiiiiiiiiiiiiiiiiii"},
117         {"ExtraVerticesAtEdges", "ExtraVerticesAtEdge", "i", "in"},
118         {"ExtraVerticesAtTriangles", "ExtraVerticesAtTriangle", "i", "in"},
119         {"ExtraVerticesAtQuadrilaterals", "ExtraVerticesAtQuadrilateral", "i", "in"},
120         {"ExtraVerticesAtTetrahedra", "ExtraVerticesAtTetrahedron", "i", "in"},
121         {"ExtraVerticesAtPrisms", "ExtraVerticesAtPrism", "i", "in"},
122         {"ExtraVerticesAtHexahedra", "ExtraVerticesAtHexahedron", "i", "in"},
123         {"VerticesOnGeometricVertices", "VertexOnGeometricVertex", "i", "iir"},
124         {"VerticesOnGeometricEdges", "VertexOnGeometricEdge", "i", "iirr"},
125         {"VerticesOnGeometricTriangles", "VertexOnGeometricTriangle", "i", "iirrr"},
126         {"VerticesOnGeometricQuadrilaterals", "VertexOnGeometricQuadrilateral", "i", "iirrr"},
127         {"EdgesOnGeometricEdges", "EdgeOnGeometricEdge", "i", "iir"},
128         {"Fault_FreeEdge", "Fault_FreeEdge", "i", "i"},
129         {"Polyhedra", "Polyhedron", "i", "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii"},
130         {"Polygons", "Polygon", "", "iiiiiiiii"},
131         {"Fault_Overlap", "Fault_Overlap", "i", "i"},
132         {"Pyramids", "Pyramid", "i", "iiiiii"},
133         {"BoundingBox", "", "", "drdr"},
134         {"Body","i", "drdrdrdr"},
135         {"PrivateTable", "PrivateTable", "i", "i"},
136         {"Fault_BadShape", "Fault_BadShape", "i", "i"},
137         {"End", "", "", ""},
138         {"TrianglesOnGeometricTriangles", "TriangleOnGeometricTriangle", "i", "iir"},
139         {"TrianglesOnGeometricQuadrilaterals", "TriangleOnGeometricQuadrilateral", "i", "iir"},
140         {"QuadrilateralsOnGeometricTriangles", "QuadrilateralOnGeometricTriangle", "i", "iir"},
141         {"QuadrilateralsOnGeometricQuadrilaterals", "QuadrilateralOnGeometricQuadrilateral", "i", "iir"},
142         {"Tangents", "Tangent", "i", "dr"},
143         {"Normals", "Normal", "i", "dr"},
144         {"TangentAtVertices", "TangentAtVertex", "i", "ii"},
145         {"SolAtVertices", "SolAtVertex", "i", "sr"},
146         {"SolAtEdges", "SolAtEdge", "i", "sr"},
147         {"SolAtTriangles", "SolAtTriangle", "i", "sr"},
148         {"SolAtQuadrilaterals", "SolAtQuadrilateral", "i", "sr"},
149         {"SolAtTetrahedra", "SolAtTetrahedron", "i", "sr"},
150         {"SolAtPrisms", "SolAtPrism", "i", "sr"},
151         {"SolAtHexahedra", "SolAtHexahedron", "i", "sr"},
152         {"DSolAtVertices", "DSolAtVertex", "i", "sr"},
153         {"ISolAtVertices", "ISolAtVertex", "i", "i"},
154         {"ISolAtEdges", "ISolAtEdge", "i", "ii"},
155         {"ISolAtTriangles", "ISolAtTriangle", "i", "iii"},
156         {"ISolAtQuadrilaterals", "ISolAtQuadrilateral", "i", "iiii"},
157         {"ISolAtTetrahedra", "ISolAtTetrahedron", "i", "iiii"},
158         {"ISolAtPrisms", "ISolAtPrism", "i", "iiiiii"},
159         {"ISolAtHexahedra", "ISolAtHexahedron", "i", "iiiiiiii"},
160         {"Iterations", "","","i"},
161         {"Time", "","","r"},
162         {"Fault_SmallTri", "Fault_SmallTri","i","i"},
163         {"CoarseHexahedra", "CoarseHexahedron", "i", "i"},
164         {"Fault_MultipleEdge", "Fault_MultipleEdge", "i", "i"}
165  };
166
167
168 /*----------------------------------------------------------*/
169 /* Prototypes of local procedures                                                       */
170 /*----------------------------------------------------------*/
171
172 static void ScaWrd(GmfMshSct *, unsigned char *);
173 static void ScaDblWrd(GmfMshSct *, unsigned char *);
174 static void ScaBlk(GmfMshSct *, unsigned char *, int);
175 static long GetPos(GmfMshSct *);
176 static void RecWrd(GmfMshSct *, unsigned char *);
177 static void RecDblWrd(GmfMshSct *, unsigned char *);
178 static void RecBlk(GmfMshSct *, unsigned char *, int);
179 static void SetPos(GmfMshSct *, long);
180 static int ScaKwdTab(GmfMshSct *);
181 static void ExpFmt(GmfMshSct *, int);
182 static void ScaKwdHdr(GmfMshSct *, int);
183
184
185 /*----------------------------------------------------------*/
186 /* Open a mesh file in read or write mod                                        */
187 /*----------------------------------------------------------*/
188
189 int GmfOpenMesh(const char *FilNam, int mod, ...)
190 {
191         int i, KwdCod, res, *PtrVer, *PtrDim, MshIdx=0;
192         char str[ GmfStrSiz ];
193         va_list VarArg;
194         GmfMshSct *msh;
195         char *ptr;
196         int k;
197 #if defined(WIN32) && defined(UNICODE)
198                 wchar_t* encoded = 0;
199                 int size_needed = 0;
200 #endif
201         if(!GmfIniFlg)
202         {
203                 for(i=0;i<=MaxMsh;i++)
204                         GmfMshTab[i] = NULL;
205
206                 GmfIniFlg = 1;
207         }
208
209         /*---------------------*/
210         /* MESH STRUCTURE INIT */
211         /*---------------------*/
212
213         for(i=1;i<=MaxMsh;i++)
214                 if(!GmfMshTab[i])
215                 {
216                         MshIdx = i;
217                         break;
218                 }
219
220         if( !MshIdx || !(msh = calloc(1, sizeof(GmfMshSct))) )
221                 return(0);
222
223         /* Copy the FilNam into the structure */
224
225         if(strlen(FilNam) + 7 >= GmfStrSiz)
226         {
227                 free (msh);
228                 return(0);
229         }
230
231         strcpy(msh->FilNam, FilNam);
232
233         /* Store the opening mod (read or write) and guess the filetype (binary or ascii) depending on the extension */
234
235         msh->mod = mod;
236         msh->buf = (unsigned char *)msh->DblBuf;
237         msh->FltBuf = (float *)msh->DblBuf;
238         msh->IntBuf = (int *)msh->DblBuf;
239
240         k = strlen(msh->FilNam) - 6;
241         if(k < 0)
242                 k = 0;
243         ptr = msh->FilNam+k;
244         if(strstr(ptr, ".meshb"))
245                 msh->typ |= (Bin | MshFil);
246         else if(strstr(ptr, ".mesh"))
247                 msh->typ |= (Asc | MshFil);
248         else if(strstr(ptr, ".solb"))
249                 msh->typ |= (Bin | SolFil);
250         else if(strstr(ptr, ".sol"))
251                 msh->typ |= (Asc | SolFil);
252         else {
253                 free (msh);
254                 return(0);
255         }
256
257         /* Open the file in the required mod and initialise the mesh structure */
258
259         if(msh->mod == GmfRead)
260         {
261
262                 /*-----------------------*/
263                 /* OPEN FILE FOR READING */
264                 /*-----------------------*/
265
266                 va_start(VarArg, mod);
267                 PtrVer = va_arg(VarArg, int *);
268                 PtrDim = va_arg(VarArg, int *);
269                 va_end(VarArg);
270
271                 /* Create the name string and open the file */
272 #if defined(WIN32) && defined(UNICODE)
273                                 size_needed = MultiByteToWideChar(CP_UTF8, 0, msh->FilNam, strlen(msh->FilNam), NULL, 0);
274                                 encoded = malloc((size_needed + 1)*sizeof(wchar_t));
275                                 MultiByteToWideChar(CP_UTF8, 0, msh->FilNam, strlen(msh->FilNam), encoded, size_needed);
276                                 encoded[size_needed] = '\0';
277                                 if (!(msh->hdl = _wfopen(encoded, L"rb")))
278 #else
279                                 if (!(msh->hdl = fopen(msh->FilNam, "rb")))
280 #endif
281                 {
282                         free (msh);
283 #if defined(WIN32) && defined(UNICODE)
284                                                 free(encoded);
285 #endif
286                         return(0);
287                 }
288
289 #if defined(WIN32) && defined(UNICODE)
290                                 free(encoded);
291 #endif
292
293                 /* Read the endian coding tag, the mesh version and the mesh dimension (mandatory kwd) */
294
295                 if(msh->typ & Bin)
296                 {
297                         fread((unsigned char *)&msh->cod, WrdSiz, 1, msh->hdl);
298
299                         if( (msh->cod != 1) && (msh->cod != 16777216) )
300                         {
301                                 free (msh);
302                                 return(0);
303                         }
304
305                         ScaWrd(msh, (unsigned char *)&msh->ver);
306
307                         if( (msh->ver < 1) || (msh->ver > 3) )
308                         {
309                                 free (msh);
310                                 return(0);
311                         }
312
313                         if( (msh->ver == 3) && (sizeof(long) == 4) )
314                         {
315                                 free (msh);
316                                 return(0);
317                         }
318
319                         ScaWrd(msh, (unsigned char *)&KwdCod);
320
321                         if(KwdCod != GmfDimension)
322                         {
323                                 free (msh);
324                                 return(0);
325                         }
326
327                         GetPos(msh);
328                         ScaWrd(msh, (unsigned char *)&msh->dim);
329                 }
330                 else
331                 {
332                         do
333                         {
334                                 res = fscanf(msh->hdl, "%s", str);
335                         }while( (res != EOF) && strcmp(str, "MeshVersionFormatted") );
336
337                         if(res == EOF)
338                         {
339                                 free (msh);
340                                 return(0);
341                         }
342
343                         fscanf(msh->hdl, "%d", &msh->ver);
344
345                         if( (msh->ver < 1) || (msh->ver > 3) )
346                         {
347                                 free (msh);
348                                 return(0);
349                         }
350
351                         do
352                         {
353                                 res = fscanf(msh->hdl, "%s", str);
354                         }while( (res != EOF) && strcmp(str, "Dimension") );
355
356                         if(res == EOF)
357                         {
358                                 free (msh);
359                                 return(0);
360                         }
361
362                         fscanf(msh->hdl, "%d", &msh->dim);
363                 }
364
365                 if( (msh->dim != 2) && (msh->dim != 3) )
366                 {
367                         free (msh);
368                         return(0);
369                 }
370
371                 (*PtrVer) = msh->ver;
372                 (*PtrDim) = msh->dim;
373
374                 /*------------*/
375                 /* KW READING */
376                 /*------------*/
377
378                 /* Read the list of kw present in the file */
379
380                 if(!ScaKwdTab(msh))
381                 {
382                         free (msh);
383                         return(0);
384                 }
385
386                 GmfMshTab[ MshIdx ] = msh;
387
388                 return(MshIdx);
389         }
390         else if(msh->mod == GmfWrite)
391         {
392
393                 /*-----------------------*/
394                 /* OPEN FILE FOR WRITING */
395                 /*-----------------------*/
396
397                 msh->cod = 1;
398
399                 /* Check if the user provided a valid version number and dimension */
400
401                 va_start(VarArg, mod);
402                 msh->ver = va_arg(VarArg, int);
403                 msh->dim = va_arg(VarArg, int);
404                 va_end(VarArg);
405
406                 if( (msh->ver < 1) || (msh->ver > 3) )
407                 {
408                         free (msh);
409                         return(0);
410                 }
411
412                 if( (msh->ver == 3) && (sizeof(long) == 4) )
413                 {
414                         free (msh);
415                         return(0);
416                 }
417
418                 if( (msh->dim != 2) && (msh->dim != 3) )
419                 {
420                         free (msh);
421                         return(0);
422                 }
423
424                 /* Create the mesh file */
425 #if defined(WIN32) && defined(UNICODE)
426                                 size_needed = MultiByteToWideChar(CP_UTF8, 0, msh->FilNam, strlen(msh->FilNam), NULL, 0);
427                                 encoded = malloc((size_needed + 1) * sizeof(wchar_t));
428                                 MultiByteToWideChar(CP_UTF8, 0, msh->FilNam, strlen(msh->FilNam), encoded, size_needed);
429                                 encoded[size_needed] = '\0';
430                                 if (!(msh->hdl = _wfopen(encoded, L"wb")))
431 #else
432                 if(!(msh->hdl = fopen(msh->FilNam, "wb")))
433 #endif
434                 {
435                         free (msh);
436 #if defined(WIN32) && defined(UNICODE)
437                                                 free(encoded);
438 #endif
439                         return(0);
440                 }
441
442 #if defined(WIN32) && defined(UNICODE)
443                                 free(encoded);
444 #endif
445                 GmfMshTab[ MshIdx ] = msh;
446
447
448                 /*------------*/
449                 /* KW WRITING */
450                 /*------------*/
451
452                 /* Write the mesh version and dimension */
453
454                 if(msh->typ & Asc)
455                 {
456                         fprintf(msh->hdl, "%s %d\n\n", GmfKwdFmt[ GmfVersionFormatted ][0], msh->ver);
457                         fprintf(msh->hdl, "%s %d\n", GmfKwdFmt[ GmfDimension ][0], msh->dim);
458                 }
459                 else
460                 {
461                         RecWrd(msh, (unsigned char *)&msh->cod);
462                         RecWrd(msh, (unsigned char *)&msh->ver);
463                         GmfSetKwd(MshIdx, GmfDimension, 0);
464                         RecWrd(msh, (unsigned char *)&msh->dim);
465                 }
466
467                 return(MshIdx);
468         }
469         else
470         {
471                 free (msh);
472                 return(0);
473         }
474 }
475
476
477 /*----------------------------------------------------------*/
478 /* Close a meshfile in the right way                                            */
479 /*----------------------------------------------------------*/
480
481 int GmfCloseMesh(int MshIdx)
482 {
483         int res = 1;
484         GmfMshSct *msh;
485
486         if( (MshIdx < 1) || (MshIdx > MaxMsh) )
487                 return(0);
488
489         msh = GmfMshTab[ MshIdx ];
490         RecBlk(msh, msh->buf, 0);
491
492         /* In write down the "End" kw in write mode */
493
494         if(msh->mod == GmfWrite){
495                 if(msh->typ & Asc)
496                         fprintf(msh->hdl, "\n%s\n", GmfKwdFmt[ GmfEnd ][0]);
497                 else
498                         GmfSetKwd(MshIdx, GmfEnd, 0);
499         }
500         /* Close the file and free the mesh structure */
501
502         if(fclose(msh->hdl))
503                 res = 0;
504
505         free(msh);
506         GmfMshTab[ MshIdx ] = NULL;
507
508         return(res);
509 }
510
511
512 /*----------------------------------------------------------*/
513 /* Read the number of lines and set the position to this kwd*/
514 /*----------------------------------------------------------*/
515
516 int GmfStatKwd(int MshIdx, int KwdCod, ...)
517 {
518         int i, *PtrNmbTyp, *PtrSolSiz, *TypTab;
519         GmfMshSct *msh;
520         KwdSct *kwd;
521         va_list VarArg;
522
523         if( (MshIdx < 1) || (MshIdx > MaxMsh) )
524                 return(0);
525
526         msh = GmfMshTab[ MshIdx ];
527
528         if( (KwdCod < 1) || (KwdCod > GmfMaxKwd) )
529                 return(0);
530
531         kwd = &msh->KwdTab[ KwdCod ];
532
533         if(!kwd->NmbLin)
534                 return(0);
535
536         /* Read further arguments if this kw is a sol */
537
538         if(kwd->typ == SolKwd)
539         {
540                 va_start(VarArg, KwdCod);
541
542                 PtrNmbTyp = va_arg(VarArg, int *);
543                 *PtrNmbTyp = kwd->NmbTyp;
544
545                 PtrSolSiz = va_arg(VarArg, int *);
546                 *PtrSolSiz = kwd->SolSiz;
547
548                 TypTab = va_arg(VarArg, int *);
549
550                 for(i=0;i<kwd->NmbTyp;i++)
551                         TypTab[i] = kwd->TypTab[i];
552
553                 va_end(VarArg);
554         }
555
556         return(kwd->NmbLin);
557 }
558
559
560 /*----------------------------------------------------------*/
561 /* Set the current file position to a given kwd                         */
562 /*----------------------------------------------------------*/
563
564 int GmfGotoKwd(int MshIdx, int KwdCod)
565 {
566         GmfMshSct *msh;
567         KwdSct *kwd;
568
569         if( (MshIdx < 1) || (MshIdx > MaxMsh) )
570                 return(0);
571
572         msh = GmfMshTab[ MshIdx ];
573
574         if( (KwdCod < 1) || (KwdCod > GmfMaxKwd) )
575                 return(0);
576
577         kwd = &msh->KwdTab[ KwdCod ];
578
579         if(!kwd->NmbLin)
580                 return(0);
581
582         return(fseek(msh->hdl, kwd->pos, SEEK_SET));
583 }
584
585
586 /*----------------------------------------------------------*/
587 /* Write the kwd and set the number of lines                            */
588 /*----------------------------------------------------------*/
589
590 int GmfSetKwd(int MshIdx, int KwdCod, ...)
591 {
592         int i, NmbLin=0, *TypTab;
593         long CurPos;
594         va_list VarArg;
595         GmfMshSct *msh;
596         KwdSct *kwd;
597
598         if( (MshIdx < 1) || (MshIdx > MaxMsh) )
599                 return(0);
600
601         msh = GmfMshTab[ MshIdx ];
602         RecBlk(msh, msh->buf, 0);
603
604         if( (KwdCod < 1) || (KwdCod > GmfMaxKwd) )
605                 return(0);
606
607         kwd = &msh->KwdTab[ KwdCod ];
608
609         /* Read further arguments if this kw has a header */
610
611         if(strlen(GmfKwdFmt[ KwdCod ][2]))
612         {
613                 va_start(VarArg, KwdCod);
614                 NmbLin = va_arg(VarArg, int);
615
616                 if(!strcmp(GmfKwdFmt[ KwdCod ][3], "sr"))
617                 {
618                         kwd->NmbTyp = va_arg(VarArg, int);
619                         TypTab = va_arg(VarArg, int *);
620
621                         for(i=0;i<kwd->NmbTyp;i++)
622                                 kwd->TypTab[i] = TypTab[i];
623                 }
624
625                 va_end(VarArg);
626         }
627
628         /* Setup the kwd info */
629
630         ExpFmt(msh, KwdCod);
631
632         if(!kwd->typ)
633                 return(0);
634         else if(kwd->typ == InfKwd)
635                 kwd->NmbLin = 1;
636         else
637                 kwd->NmbLin = NmbLin;
638
639         /* Store the next kwd position in binary file */
640
641         if( (msh->typ & Bin) && msh->NexKwdPos )
642         {
643                 CurPos = ftell(msh->hdl);
644                 fseek(msh->hdl, msh->NexKwdPos, SEEK_SET);
645                 SetPos(msh, CurPos);
646                 fseek(msh->hdl, CurPos, SEEK_SET);
647         }
648
649         /* Write the header */
650
651         if(msh->typ & Asc)
652         {
653                 fprintf(msh->hdl, "\n%s\n", GmfKwdFmt[ KwdCod ][0]);
654
655                 if(kwd->typ != InfKwd)
656                         fprintf(msh->hdl, "%d\n", kwd->NmbLin);
657
658                 /* In case of solution field, write the extended header */
659
660                 if(kwd->typ == SolKwd)
661                 {
662                         fprintf(msh->hdl, "%d ", kwd->NmbTyp);
663
664                         for(i=0;i<kwd->NmbTyp;i++)
665                                 fprintf(msh->hdl, "%d ", kwd->TypTab[i]);
666
667                         fprintf(msh->hdl, "\n\n");
668                 }
669         }
670         else
671         {
672                 RecWrd(msh, (unsigned char *)&KwdCod);
673                 msh->NexKwdPos = ftell(msh->hdl);
674                 SetPos(msh, 0);
675
676                 if(kwd->typ != InfKwd)
677                         RecWrd(msh, (unsigned char *)&kwd->NmbLin);
678
679                 /* In case of solution field, write the extended header at once */
680
681                 if(kwd->typ == SolKwd)
682                 {
683                         RecWrd(msh, (unsigned char *)&kwd->NmbTyp);
684
685                         for(i=0;i<kwd->NmbTyp;i++)
686                                 RecWrd(msh, (unsigned char *)&kwd->TypTab[i]);
687                 }
688         }
689
690         /* Reset write buffer position */
691         msh->pos = 0;
692
693         /* Estimate the total file size and check whether it crosses the 2GB threshold */
694
695         msh->siz += kwd->NmbLin * kwd->NmbWrd * WrdSiz;
696
697         if(msh->siz > 2E9)
698                 return(0);
699         else
700                 return(kwd->NmbLin);
701 }
702
703
704 /*----------------------------------------------------------*/
705 /* Read a full line from the current kwd                                        */
706 /*----------------------------------------------------------*/
707
708 void GmfGetLin(int MshIdx, int KwdCod, ...)
709 {
710         int i, j;
711         float *FltSolTab;
712         double *DblSolTab;
713         va_list VarArg;
714         GmfMshSct *msh = GmfMshTab[ MshIdx ];
715         KwdSct *kwd = &msh->KwdTab[ KwdCod ];
716
717         /* Start decoding the arguments */
718
719         va_start(VarArg, KwdCod);
720
721         if(kwd->typ != SolKwd)
722         {
723                 int k, nb_repeat = 0;
724
725                 if(msh->ver == 1)
726                 {
727                         if(msh->typ & Asc)
728                         {
729                                 for(i=0;i<kwd->SolSiz;i++)
730                                         if(kwd->fmt[i] == 'r')
731                                                 fscanf(msh->hdl, "%f", va_arg(VarArg, float *));
732                                         else if(kwd->fmt[i] == 'n') {
733                                                 fscanf(msh->hdl, "%d", &nb_repeat);
734                                                 *(va_arg(VarArg,  int *)) = nb_repeat;
735                                                 for(k=0;k<nb_repeat;k++)
736                                                         fscanf(msh->hdl, "%d", va_arg(VarArg, int *));
737                                         }
738                                         else
739                                                 fscanf(msh->hdl, "%d", va_arg(VarArg, int *));
740                         }
741                         else
742                         {
743                                 for(i=0;i<kwd->SolSiz;i++)
744                                         if(kwd->fmt[i] == 'r')
745                                                 ScaWrd(msh, (unsigned char *)va_arg(VarArg, float *));
746                                         else if(kwd->fmt[i] == 'n') {
747                                                 ScaWrd(msh, (unsigned char *)&nb_repeat);
748                                                 *(va_arg(VarArg,  int *)) = nb_repeat;
749                                                 for(k=0;k<nb_repeat;k++)
750                                                         ScaWrd(msh, (unsigned char *)va_arg(VarArg, int *));
751                                         }
752                                         else
753                                                 ScaWrd(msh, (unsigned char *)va_arg(VarArg, int *));
754                         }
755                 }
756                 else
757                 {
758                         if(msh->typ & Asc)
759                         {
760                                 for(i=0;i<kwd->SolSiz;i++)
761                                         if(kwd->fmt[i] == 'r')
762                                                 fscanf(msh->hdl, "%lf", va_arg(VarArg, double *));
763                                         else if(kwd->fmt[i] == 'n') {
764                                                 fscanf(msh->hdl, "%d", &nb_repeat);
765                                                 *(va_arg(VarArg,  int *)) = nb_repeat;
766                                                 for(k=0;k<nb_repeat;k++)
767                                                         fscanf(msh->hdl, "%d", va_arg(VarArg, int *));
768                                         }
769                                         else
770                                                 fscanf(msh->hdl, "%d", va_arg(VarArg, int *));
771                         }
772                         else
773                                 for(i=0;i<kwd->SolSiz;i++)
774                                         if(kwd->fmt[i] == 'r')
775                                                 ScaDblWrd(msh, (unsigned char *)va_arg(VarArg, double *));
776                                         else if(kwd->fmt[i] == 'n') {
777                                                 ScaWrd(msh, (unsigned char *)&nb_repeat);
778                                                 *(va_arg(VarArg,  int *)) = nb_repeat;
779                                                 for(k=0;k<nb_repeat;k++)
780                                                         ScaWrd(msh, (unsigned char *)va_arg(VarArg, int *));
781                                         }
782                                         else
783                                                 ScaWrd(msh, (unsigned char *)va_arg(VarArg, int *));
784                 }
785         }
786         else
787         {
788                 if(msh->ver == 1)
789                 {
790                         FltSolTab = va_arg(VarArg, float *);
791
792                         if(msh->typ & Asc)
793                                 for(j=0;j<kwd->SolSiz;j++)
794                                         fscanf(msh->hdl, "%f", &FltSolTab[j]);
795                         else
796                                 ScaBlk(msh, (unsigned char *)FltSolTab, kwd->NmbWrd);
797                 }
798                 else
799                 {
800                         DblSolTab = va_arg(VarArg, double *);
801
802                         if(msh->typ & Asc)
803                                 for(j=0;j<kwd->SolSiz;j++)
804                                         fscanf(msh->hdl, "%lf", &DblSolTab[j]);
805                         else
806                                 for(j=0;j<kwd->SolSiz;j++)
807                                         ScaDblWrd(msh, (unsigned char *)&DblSolTab[j]);
808                 }
809         }
810
811         va_end(VarArg);
812 }
813
814
815 /*----------------------------------------------------------*/
816 /* Write a full line from the current kwd                                       */
817 /*----------------------------------------------------------*/
818
819 void GmfSetLin(int MshIdx, int KwdCod, ...)
820 {
821         int i, j, pos, *IntBuf;
822         float *FltSolTab;
823         double *DblSolTab, *DblBuf;
824         va_list VarArg;
825         GmfMshSct *msh = GmfMshTab[ MshIdx ];
826         KwdSct *kwd = &msh->KwdTab[ KwdCod ];
827
828         /* Start decoding the arguments */
829
830         va_start(VarArg, KwdCod);
831
832         if(kwd->typ != SolKwd)
833         {
834                 int k, nb_repeat = 0;
835
836                 if(msh->ver == 1)
837                 {
838                         if(msh->typ & Asc)
839                         {
840                                 for(i=0;i<kwd->SolSiz;i++)
841                                         if(kwd->fmt[i] == 'r')
842                                                 fprintf(msh->hdl, "%g ", (float)va_arg(VarArg, double));
843                                         else if(kwd->fmt[i] == 'n') {
844                                                 nb_repeat = va_arg(VarArg, int);
845                                                 fprintf(msh->hdl, "%d ", nb_repeat);
846                                                 for(k=0;k<nb_repeat;k++)
847                                                         fprintf(msh->hdl, "%d ", va_arg(VarArg, int));
848                                         }
849                                         else
850                                                 fprintf(msh->hdl, "%d ", va_arg(VarArg, int));
851                         }
852                         else
853                         {
854                                 int size_of_block = kwd->SolSiz;
855                                 for(i=0;i<kwd->SolSiz;i++)
856                                         if(kwd->fmt[i] == 'r')
857                                                 msh->FltBuf[i] = va_arg(VarArg, double);
858                                         else if(kwd->fmt[i] == 'n') {
859                                                 nb_repeat = va_arg(VarArg, int);
860                                                 msh->FltBuf[i] = nb_repeat;
861                                                 for(k=0;k<nb_repeat;k++) {
862                                                         msh->IntBuf[i+1+k] = va_arg(VarArg, int);
863                                                         size_of_block ++;
864                                                 }
865                                         }
866                                         else
867                                                 msh->IntBuf[i] = va_arg(VarArg, int);
868
869                                 RecBlk(msh, msh->buf, size_of_block);
870                         }
871                 }
872                 else
873                 {
874                         if(msh->typ & Asc)
875                         {
876                                 for(i=0;i<kwd->SolSiz;i++)
877                                         if(kwd->fmt[i] == 'r')
878                                                 fprintf(msh->hdl, "%.15g ", va_arg(VarArg, double)); /* was "%.15lg and warning "ISO C90 does not support the '%lg' gnu_printf format"*/
879                                         else if(kwd->fmt[i] == 'n') {
880                                                 nb_repeat = va_arg(VarArg, int);
881                                                 fprintf(msh->hdl, "%d ", nb_repeat);
882                                                 for(k=0;k<nb_repeat;k++)
883                                                         fprintf(msh->hdl, "%d ", va_arg(VarArg, int));
884                                         }
885                                         else
886                                                 fprintf(msh->hdl, "%d ", va_arg(VarArg, int));
887                         }
888                         else
889                         {
890                                 pos = 0;
891
892                                 for(i=0;i<kwd->SolSiz;i++)
893                                         if(kwd->fmt[i] == 'r')
894                                         {
895                                                 DblBuf = (double *)&msh->buf[ pos ];
896                                                 *DblBuf = va_arg(VarArg, double);
897                                                 pos += 8;
898                                         }
899                                         else if(kwd->fmt[i] == 'n')
900                                         {
901                                                 IntBuf = (int *)&msh->buf[ pos ];
902                                                 nb_repeat = va_arg(VarArg, int);
903                                                 *IntBuf = nb_repeat;
904                                                 pos += 4;
905                                                 for(k=0;k<nb_repeat;k++) {
906                                                         IntBuf = (int *)&msh->buf[ pos ];
907                                                         *IntBuf = va_arg(VarArg, int);
908                                                         pos += 4;
909                                                 }
910                                         }
911                                         else
912                                         {
913                                                 IntBuf = (int *)&msh->buf[ pos ];
914                                                 *IntBuf = va_arg(VarArg, int);
915                                                 pos += 4;
916                                         }
917                                 RecBlk(msh, msh->buf, pos/4);
918                         }
919                 }
920         }
921         else
922         {
923                 if(msh->ver == 1)
924                 {
925                         FltSolTab = va_arg(VarArg, float *);
926
927                         if(msh->typ & Asc)
928                                 for(j=0;j<kwd->SolSiz;j++)
929                                         fprintf(msh->hdl, "%g ", FltSolTab[j]);
930                         else
931                                 RecBlk(msh, (unsigned char *)FltSolTab, kwd->NmbWrd);
932                 }
933                 else
934                 {
935                         DblSolTab = va_arg(VarArg, double *);
936
937                         if(msh->typ & Asc)
938                                 for(j=0;j<kwd->SolSiz;j++)
939                                         fprintf(msh->hdl, "%.15g ", DblSolTab[j]); /* was " %.15lg " and warning "ISO C90 does not support the '%lg' gnu_printf format" */
940                         else
941                                 RecBlk(msh, (unsigned char *)DblSolTab, kwd->NmbWrd);
942                 }
943         }
944
945         va_end(VarArg);
946
947         if(msh->typ & Asc)
948                 fprintf(msh->hdl, "\n");
949 }
950
951
952 /*----------------------------------------------------------*/
953 /* Private procedure for transmesh : copy a whole line          */
954 /*----------------------------------------------------------*/
955
956 void GmfCpyLin(int InpIdx, int OutIdx, int KwdCod)
957 {
958         double d;
959         float f;
960         int i, a;
961         GmfMshSct *InpMsh = GmfMshTab[ InpIdx ], *OutMsh = GmfMshTab[ OutIdx ];
962         KwdSct *kwd = &InpMsh->KwdTab[ KwdCod ];
963
964         for(i=0;i<kwd->SolSiz;i++)
965         {
966                 if(kwd->fmt[i] == 'r')
967                 {
968                         if(InpMsh->ver == 1)
969                         {
970                                 if(InpMsh->typ & Asc)
971                                         fscanf(InpMsh->hdl, "%f", &f);
972                                 else
973                                         ScaWrd(InpMsh, (unsigned char *)&f);
974
975                                 d = f;
976                         }
977                         else
978                         {
979                                 if(InpMsh->typ & Asc)
980                                         fscanf(InpMsh->hdl, "%lf", &d);
981                                 else
982                                         ScaDblWrd(InpMsh, (unsigned char *)&d);
983
984                                 f = (float)d;
985                         }
986
987                         if(OutMsh->ver == 1)
988                                 if(OutMsh->typ & Asc)
989                                         fprintf(OutMsh->hdl, "%g ", f);
990                                 else
991                                         RecWrd(OutMsh, (unsigned char *)&f);
992                         else
993                                 if(OutMsh->typ & Asc)
994                                         fprintf(OutMsh->hdl, "%.15g ", d);
995                                 else
996                                         RecDblWrd(OutMsh, (unsigned char *)&d);
997                 }
998                 else if(kwd->fmt[i] == 'n')
999                 {
1000                         int k, nb_repeat = 0;
1001
1002                         if(InpMsh->typ & Asc)
1003                                 fscanf(InpMsh->hdl, "%d", &a);
1004                         else
1005                                 ScaWrd(InpMsh, (unsigned char *)&a);
1006
1007                         nb_repeat = a;
1008
1009                         if(OutMsh->typ & Asc)
1010                                 fprintf(OutMsh->hdl, "%d ", a);
1011                         else
1012                                 RecWrd(OutMsh, (unsigned char *)&a);
1013
1014                         for(k=0;k<nb_repeat;k++) {
1015                                 if(InpMsh->typ & Asc)
1016                                         fscanf(InpMsh->hdl, "%d", &a);
1017                                 else
1018                                         ScaWrd(InpMsh, (unsigned char *)&a);
1019
1020                                 if(OutMsh->typ & Asc)
1021                                         fprintf(OutMsh->hdl, "%d ", a);
1022                                 else
1023                                         RecWrd(OutMsh, (unsigned char *)&a);
1024                         }
1025                 }
1026                 else
1027                 {
1028                         if(InpMsh->typ & Asc)
1029                                 fscanf(InpMsh->hdl, "%d", &a);
1030                         else
1031                                 ScaWrd(InpMsh, (unsigned char *)&a);
1032
1033                         if(OutMsh->typ & Asc)
1034                                 fprintf(OutMsh->hdl, "%d ", a);
1035                         else
1036                                 RecWrd(OutMsh, (unsigned char *)&a);
1037                 }
1038         }
1039
1040         if(OutMsh->typ & Asc)
1041                 fprintf(OutMsh->hdl, "\n");
1042 }
1043
1044
1045 /*----------------------------------------------------------*/
1046 /* Find every kw present in a meshfile                                          */
1047 /*----------------------------------------------------------*/
1048
1049 static int ScaKwdTab(GmfMshSct *msh)
1050 {
1051         int KwdCod;
1052         long  NexPos, CurPos, EndPos;
1053         char str[ GmfStrSiz ];
1054
1055         if(msh->typ & Asc)
1056         {
1057                 /* Scan each string in the file until the end */
1058
1059                 while(fscanf(msh->hdl, "%s", str) != EOF)
1060                 {
1061                         /* Fast test in order to reject quickly the numeric values */
1062
1063                         if(isalpha(str[0]))
1064                         {
1065                                 /* Search which kwd code this string is associated with, 
1066                                         then get its header and save the current position in file (just before the data) */
1067                                 /* printf("libmesh ScaKwdTab %s\n", str); */
1068                                 for(KwdCod=1; KwdCod<= GmfMaxKwd; KwdCod++)
1069                                         if(!strcmp(str, GmfKwdFmt[ KwdCod ][0]))
1070                                         {
1071                                                 ScaKwdHdr(msh, KwdCod);
1072                                                 break;
1073                                         }
1074                         }
1075                         else if(str[0] == '#')
1076                                 while(fgetc(msh->hdl) != '\n');
1077                 }
1078         }
1079         else
1080         {
1081                 /* Get file size */
1082
1083                 CurPos = ftell(msh->hdl);
1084                 fseek(msh->hdl, 0, SEEK_END);
1085                 EndPos = ftell(msh->hdl);
1086                 fseek(msh->hdl, CurPos, SEEK_SET);
1087
1088                 /* Jump through kwd positions in the file */
1089
1090                 do
1091                 {
1092                         /* Get the kwd code and the next kwd position */
1093
1094                         ScaWrd(msh, (unsigned char *)&KwdCod);
1095                         NexPos = GetPos(msh);
1096
1097                         if(NexPos > EndPos)
1098                                 return(0);
1099
1100                         /* Check if this kwd belongs to this mesh version */
1101
1102                         if( (KwdCod >= 1) && (KwdCod <= GmfMaxKwd) )
1103                                 ScaKwdHdr(msh, KwdCod);
1104
1105                         /* Go to the next kwd */
1106
1107                         if(NexPos)
1108                                 fseek(msh->hdl, NexPos, SEEK_SET);
1109                 }while(NexPos && (KwdCod != GmfEnd));
1110         }
1111
1112         return(1);
1113 }
1114
1115
1116 /*----------------------------------------------------------*/
1117 /* Read and setup the keyword's header                                          */
1118 /*----------------------------------------------------------*/
1119
1120 static void ScaKwdHdr(GmfMshSct *msh, int KwdCod)
1121 {
1122         int i;
1123         KwdSct *kwd = &msh->KwdTab[ KwdCod ];
1124
1125         if(!strcmp("i", GmfKwdFmt[ KwdCod ][2]))
1126         {
1127                 if(msh->typ & Asc)
1128                         fscanf(msh->hdl, "%d", &kwd->NmbLin);
1129                 else
1130                         ScaWrd(msh, (unsigned char *)&kwd->NmbLin);
1131         }
1132         else
1133                 kwd->NmbLin = 1;
1134
1135         if(!strcmp("sr", GmfKwdFmt[ KwdCod ][3]))
1136         {
1137                 if(msh->typ & Asc)
1138                 {
1139                         fscanf(msh->hdl, "%d", &kwd->NmbTyp);
1140
1141                         for(i=0;i<kwd->NmbTyp;i++)
1142                                 fscanf(msh->hdl, "%d", &kwd->TypTab[i]);
1143                 }
1144                 else
1145                 {
1146                         ScaWrd(msh, (unsigned char *)&kwd->NmbTyp);
1147
1148                         for(i=0;i<kwd->NmbTyp;i++)
1149                                 ScaWrd(msh, (unsigned char *)&kwd->TypTab[i]);
1150                 }
1151         }
1152
1153         ExpFmt(msh, KwdCod);
1154         kwd->pos = ftell(msh->hdl);
1155 }
1156
1157
1158 /*----------------------------------------------------------*/
1159 /* Expand the compacted format and compute the line size        */
1160 /*----------------------------------------------------------*/
1161
1162 static void ExpFmt(GmfMshSct *msh, int KwdCod)
1163 {
1164         int i, j, TmpSiz=0;
1165         char chr;
1166         const char *InpFmt = GmfKwdFmt[ KwdCod ][3];
1167         KwdSct *kwd = &msh->KwdTab[ KwdCod ];
1168
1169         /* Set the kwd's type */
1170
1171         if(!strlen(GmfKwdFmt[ KwdCod ][2]))
1172                 kwd->typ = InfKwd;
1173         else if(!strcmp(InpFmt, "sr"))
1174                 kwd->typ = SolKwd;
1175         else
1176                 kwd->typ = RegKwd;
1177
1178         /* Get the solution-field's size */
1179
1180         if(kwd->typ == SolKwd)
1181                 for(i=0;i<kwd->NmbTyp;i++)
1182                         switch(kwd->TypTab[i])
1183                         {
1184                                 case GmfSca    : TmpSiz += 1; break;
1185                                 case GmfVec    : TmpSiz += msh->dim; break;
1186                                 case GmfSymMat : TmpSiz += (msh->dim * (msh->dim+1)) / 2; break;
1187                                 case GmfMat    : TmpSiz += msh->dim * msh->dim; break;
1188                         }
1189
1190         /* Scan each character from the format string */
1191
1192         i = kwd->SolSiz = kwd->NmbWrd = 0;
1193
1194         while(i < (int)strlen(InpFmt))
1195         {
1196                 chr = InpFmt[ i++ ];
1197
1198                 if(chr == 'd')
1199                 {
1200                         chr = InpFmt[i++];
1201
1202                         for(j=0;j<msh->dim;j++)
1203                                 kwd->fmt[ kwd->SolSiz++ ] = chr;
1204                 }
1205                 else if(chr == 's')
1206                 {
1207                         chr = InpFmt[i++];
1208
1209                         for(j=0;j<TmpSiz;j++)
1210                                 kwd->fmt[ kwd->SolSiz++ ] = chr;
1211                 }
1212                 else
1213                         kwd->fmt[ kwd->SolSiz++ ] = chr;
1214         }
1215
1216         for(i=0;i<kwd->SolSiz;i++)
1217                 if(kwd->fmt[i] == 'i')
1218                         kwd->NmbWrd++;
1219                 else if(msh->ver >= 2)
1220                         kwd->NmbWrd += 2;
1221                 else
1222                         kwd->NmbWrd++;
1223 }
1224
1225
1226 /*----------------------------------------------------------*/
1227 /* Read a four bytes word from a mesh file                                      */
1228 /*----------------------------------------------------------*/
1229
1230 static void ScaWrd(GmfMshSct *msh, unsigned char *wrd)
1231 {
1232         unsigned char swp;
1233
1234         fread(wrd, WrdSiz, 1, msh->hdl);
1235
1236         if(msh->cod == 1)
1237                 return;
1238
1239         swp = wrd[3];
1240         wrd[3] = wrd[0];
1241         wrd[0] = swp;
1242
1243         swp = wrd[2];
1244         wrd[2] = wrd[1];
1245         wrd[1] = swp;
1246 }
1247
1248
1249 /*----------------------------------------------------------*/
1250 /* Read an eight bytes word from a mesh file                            */
1251 /*----------------------------------------------------------*/
1252
1253 static void ScaDblWrd(GmfMshSct *msh, unsigned char *wrd)
1254 {
1255         int i;
1256         unsigned char swp;
1257
1258         fread(wrd, WrdSiz, 2, msh->hdl);
1259
1260         if(msh->cod == 1)
1261                 return;
1262
1263         for(i=0;i<4;i++)
1264         {
1265                 swp = wrd[7-i];
1266                 wrd[7-i] = wrd[i];
1267                 wrd[i] = swp;
1268         }
1269 }
1270
1271
1272 /*----------------------------------------------------------*/
1273 /* Read ablock of four bytes word from a mesh file                      */
1274 /*----------------------------------------------------------*/
1275
1276 static void ScaBlk(GmfMshSct *msh, unsigned char *blk, int siz)
1277 {
1278         int i, j;
1279         unsigned char swp, *wrd;
1280
1281         fread(blk, WrdSiz, siz, msh->hdl);
1282
1283         if(msh->cod == 1)
1284                 return;
1285
1286         for(i=0;i<siz;i++)
1287         {
1288                 wrd = &blk[ i * 4 ];
1289
1290                 for(j=0;j<2;j++)
1291                 {
1292                         swp = wrd[ 3-j ];
1293                         wrd[ 3-j ] = wrd[j];
1294                         wrd[j] = swp;
1295                 }
1296         }
1297 }
1298
1299
1300 /*----------------------------------------------------------*/
1301 /* Read a 4 or 8 bytes position in mesh file                            */
1302 /*----------------------------------------------------------*/
1303
1304 static long GetPos(GmfMshSct *msh)
1305 {
1306         int IntVal;
1307         long pos;
1308
1309         if(msh->ver >= 3)
1310                 ScaDblWrd(msh, (unsigned char*)&pos);
1311         else
1312         {
1313                 ScaWrd(msh, (unsigned char*)&IntVal);
1314                 pos = IntVal;
1315         }
1316
1317         return(pos);
1318 }
1319
1320
1321 /*----------------------------------------------------------*/
1322 /* Write a four bytes word to a mesh file                                       */
1323 /*----------------------------------------------------------*/
1324
1325 static void RecWrd(GmfMshSct *msh, unsigned char *wrd)
1326 {
1327         fwrite(wrd, WrdSiz, 1, msh->hdl);
1328 }
1329
1330
1331 /*----------------------------------------------------------*/
1332 /* Write an eight bytes word to a mesh file                                     */
1333 /*----------------------------------------------------------*/
1334
1335 static void RecDblWrd(GmfMshSct *msh, unsigned char *wrd)
1336 {
1337         fwrite(wrd, WrdSiz, 2, msh->hdl);
1338 }
1339
1340
1341 /*----------------------------------------------------------*/
1342 /* Write a block of four bytes word to a mesh file                      */
1343 /*----------------------------------------------------------*/
1344
1345 static void RecBlk(GmfMshSct *msh, unsigned char *blk, int siz)
1346 {
1347         /* Copy this line-block into the main mesh buffer */
1348
1349         if(siz)
1350         {
1351                 memcpy(&msh->blk[ msh->pos ], blk, siz * WrdSiz);
1352                 msh->pos += siz * WrdSiz;
1353         }
1354
1355         /* When the buffer is full or this procedure is called with a 0 size, flush the cache on disk */
1356
1357         if( (msh->pos > BufSiz) || (!siz && msh->pos) )
1358         {
1359                 fwrite(msh->blk, 1, msh->pos, msh->hdl);
1360                 msh->pos = 0;
1361         }
1362 }
1363
1364
1365 /*----------------------------------------------------------*/
1366 /* Write a 4 or 8 bytes position in a mesh file                         */
1367 /*----------------------------------------------------------*/
1368
1369 static void SetPos(GmfMshSct *msh, long pos)
1370 {
1371         int IntVal;
1372
1373         if(msh->ver >= 3)
1374                 RecDblWrd(msh, (unsigned char*)&pos);
1375         else
1376         {
1377                 IntVal = pos;
1378                 RecWrd(msh, (unsigned char*)&IntVal);
1379         }
1380 }