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