Forward compatibility: flex
[foam-extend-3.2.git] / applications / utilities / postProcessing / dataConversion / foamToTecplot360 / tecio / tecsrc / dataio4.cpp
blobf3612623ec4c6e5f3ca253324fa6b32fbc9628ac
1 /*
2 * NOTICE and LICENSE for Tecplot Input/Output Library (TecIO) - OpenFOAM
4 * Copyright (C) 1988-2009 Tecplot, Inc. All rights reserved worldwide.
6 * Tecplot hereby grants OpenCFD limited authority to distribute without
7 * alteration the source code to the Tecplot Input/Output library, known
8 * as TecIO, as part of its distribution of OpenFOAM and the
9 * OpenFOAM_to_Tecplot converter. Users of this converter are also hereby
10 * granted access to the TecIO source code, and may redistribute it for the
11 * purpose of maintaining the converter. However, no authority is granted
12 * to alter the TecIO source code in any form or manner.
14 * This limited grant of distribution does not supersede Tecplot, Inc.'s
15 * copyright in TecIO. Contact Tecplot, Inc. for further information.
17 * Tecplot, Inc.
18 * 3535 Factoria Blvd, Ste. 550
19 * Bellevue, WA 98006, USA
20 * Phone: +1 425 653 1200
21 * http://www.tecplot.com/
24 #include "stdafx.h"
25 #include "MASTER.h"
26 #define TECPLOTENGINEMODULE
29 ******************************************************************
30 ******************************************************************
31 ******* ********
32 ****** (C) 1988-2008 Tecplot, Inc. *******
33 ******* ********
34 ******************************************************************
35 ******************************************************************
38 #define DATAIO4MODULE
39 #include "GLOBAL.h"
40 #include "TASSERT.h"
41 #include "Q_UNICODE.h"
42 #include "ALLOC.h"
44 #include "AUXDATA.h"
45 #include "DATASET.h"
46 #include "FILESTREAM.h"
48 #if defined TECPLOTKERNEL
49 /* CORE SOURCE CODE REMOVED */
50 #endif
52 #include "GEOM2.h"
53 #include "GEOM.h"
54 #include "INPUT.h"
55 #include "SET.h"
56 #include "TEXT.h"
57 #include "DATAIO4.h"
58 #include "DATASET0.h"
60 #include "STRUTIL.h"
61 #include "ARRLIST.h"
62 #include "STRLIST.h"
63 #include "Q_MSG.h"
65 #if defined IRIS
66 #include <ieeefp.h>
67 #endif
69 using namespace tecplot::strutil;
71 #if !defined(TECPLOTKERNEL) && defined(MSWIN)
72 # pragma warning(disable : 4244)
73 #endif
75 /*END HEADER*/
78 * This module contains mostly low level i/o functions.
81 #if defined DECALPHA || defined COMPAQALPHA
82 #define _IEEE_FP_INEXACT
83 #define _IEEE_FP
84 #endif
86 #if defined SUN41
87 #define SEEK_SET 0
88 #define SEEK_CUR 1
89 #define SEEK_END 2
90 #endif
92 #if defined TECPLOTKERNEL
93 /* CORE SOURCE CODE REMOVED */
94 #endif
96 /**********************************************************************
97 **********************************************************************
98 ********************** INPUT **************************
99 **********************************************************************
100 **********************************************************************/
102 static char FilterFloatChar(float X)
104 char C;
105 if (((X >= 32.0) && (X <= 127.0)) ||
106 ((X >= 160.0) && (X <= 255.0)) ||
107 (X == 0.0))
108 C = (char)X;
109 else
110 C = '?';
111 return (C);
115 double GetNextValue(FileStream_s *FileStream,
116 FieldDataType_e FieldDataType,
117 double VMin,
118 double VMax,
119 Boolean_t *IsOk)
121 double X = 0.0;
123 REQUIRE(VALID_REF(IsOk) && VALID_BOOLEAN(*IsOk));
124 REQUIRE(!(*IsOk) || VALID_FIELD_DATA_TYPE(FieldDataType));
125 REQUIRE(!(*IsOk) || VALID_REF(FileStream));
127 if (*IsOk)
129 switch (FieldDataType)
131 case FieldDataType_Float :
133 float XX;
135 *IsOk = (TP_FREAD(&XX, 4, 1, FileStream->File) == 1);
137 if (!FileStream->IsByteOrderNative)
138 REVERSE_4_BYTES(&XX);
140 if (*IsOk)
141 X = XX;
142 else
143 X = 0.0;
144 } break;
145 case FieldDataType_Double :
147 double XX;
149 *IsOk = (TP_FREAD(&XX, sizeof(double), 1, FileStream->File) == 1);
150 if (!FileStream->IsByteOrderNative)
151 REVERSE_8_BYTES(&XX);
153 if (*IsOk)
154 X = XX;
155 else
156 X = 0.0;
157 } break;
158 case FieldDataType_Int32 :
160 Int32_t L;
161 *IsOk = (TP_FREAD(&L, sizeof(Int32_t), 1, FileStream->File) == 1);
162 if (!FileStream->IsByteOrderNative)
163 REVERSE_4_BYTES(&L);
164 if (*IsOk)
165 X = (double)L;
166 } break;
167 case FieldDataType_Int16 :
169 Int16_t S;
170 *IsOk = (TP_FREAD(&S, sizeof(Int16_t), 1, FileStream->File) == 1);
171 if (!FileStream->IsByteOrderNative)
172 REVERSE_2_BYTES(&S);
173 if (*IsOk)
174 X = (double)S;
175 } break;
176 case FieldDataType_Byte :
178 Byte_t B;
179 *IsOk = (TP_FREAD(&B, sizeof(Byte_t), 1, FileStream->File) == 1);
180 if (*IsOk)
181 X = (double)B;
182 } break;
183 case FieldDataType_Bit :
186 * Important note:
187 * Reading bit data a value at a time is only valid for a
188 * single bit value. If the file contains a block of more than
189 * one bit value and you attempt to read it a bit at a time it
190 * will not work as Tecplot does not buffer the read. In order
191 * to read a block of bits you must perform a block read.
193 Byte_t B;
194 *IsOk = (TP_FREAD(&B, sizeof(Byte_t), 1, FileStream->File) == 1);
195 if (*IsOk)
196 X = (double)(B & (Byte_t)01);
197 } break;
198 default: CHECK(FALSE); break;
201 if (*IsOk)
203 if ((X < VMin) || (X > VMax))
205 *IsOk = FALSE;
210 return X;
214 LgIndex_t GetNextI(FileStream_s *FileStream,
215 Boolean_t *IsOk)
217 LgIndex_t I = 0;
219 REQUIRE(VALID_REF(IsOk) && VALID_BOOLEAN(*IsOk));
220 REQUIRE(!(*IsOk) || (VALID_REF(FileStream) && VALID_REF(FileStream->File)));
222 if (*IsOk)
224 Int32_t Int32Val;
225 *IsOk = (TP_FREAD((void *) & Int32Val, 4, 1, FileStream->File) == 1);
226 if (!FileStream->IsByteOrderNative)
227 REVERSE_4_BYTES(&Int32Val);
229 I = Int32Val;
231 return I;
235 LgIndex_t GetIoFileInt(FileStream_s *FileStream,
236 short Version,
237 LgIndex_t IMin,
238 LgIndex_t IMax,
239 Boolean_t *IsOk)
241 LgIndex_t I = 0;
243 REQUIRE(VALID_REF(IsOk) && VALID_BOOLEAN(*IsOk));
244 REQUIRE(!(*IsOk) || (0 < Version && Version <= TecplotBinaryFileVersion));
245 REQUIRE(!(*IsOk) || (VALID_REF(FileStream) && VALID_REF(FileStream->File)));
246 REQUIRE(!(*IsOk) || IMin <= IMax);
248 if (!(*IsOk))
249 return (0);
251 if (Version <= 63)
253 float X;
254 if (*IsOk)
256 X = (float)GetNextValue(FileStream, FieldDataType_Float,
257 (double)IMin - 1.0e-10,
258 (double)IMax + 1.0e-10, IsOk);
259 if (*IsOk)
261 if (ABS(X) < (float)MAXINDEX)
262 I = (LgIndex_t)X;
263 else
264 *IsOk = FALSE;
266 else
267 *IsOk = FALSE;
270 else
272 I = GetNextI(FileStream, IsOk);
275 if ((I < IMin) || (I > IMax))
276 *IsOk = FALSE;
278 return (I);
282 * Basically this is "realloc" but apparently "realloc" doesn't behave reliably
283 * on all platforms.
285 static Boolean_t ReallocString(char **String,
286 LgIndex_t NewLength)
288 Boolean_t IsOk;
289 char *NewString;
291 REQUIRE(VALID_REF(String));
292 REQUIRE(*String == NULL || VALID_REF(*String));
293 REQUIRE((*String != NULL && NewLength >= (LgIndex_t)strlen(*String)) ||
294 (*String == NULL && NewLength >= 0));
296 NewString = ALLOC_ARRAY(NewLength + 1, char, "reallocated string");
297 IsOk = (NewString != NULL);
298 if (IsOk)
300 if (*String == NULL)
302 NewString[0] = '\0';
304 else
306 strcpy(NewString, *String);
307 FREE_ARRAY(*String, "old string");
309 *String = NewString;
312 ENSURE(VALID_BOOLEAN(IsOk));
313 ENSURE(IMPLICATION(IsOk, VALID_REF(*String)));
314 return IsOk;
319 * Reads a string from all versions of a binary plt file.
321 * param FileStream
322 * Open file stream positioned at the string to read.
323 * param IVersion
324 * Binary file version number.
325 * param MaxCharacters
326 * IVersion < 63
327 * This value is exactly the number of characters (actually floats, each
328 * one representing a character's ordinal value) to read from the file.
329 * IVersion >= 63 and ProcessData == TRUE
330 * If non-zero, this value represents the largest string to be returned.
331 * In other words, larger strings are read from the file but an allocated
332 * string of up to MaxCharacters is returned. A zero value indicates that
333 * the string size is unlimited and determined only by the actual length
334 * of the string in the file.
335 * param TargetStr
336 * Pointer to hold the allocated string if ProcessData == TRUE.
337 * param ProcessData
338 * Indicates if the read string should be retrieved.
340 * return
341 * TRUE if the read was successful with an allocated string *TargetStr
342 * containing the string read (no larger than requested or necessary),
343 * FALSE otherwise.
345 Boolean_t ReadInString(FileStream_s *FileStream,
346 short IVersion,
347 int MaxCharacters,
348 char **TargetStr,
349 Boolean_t ProcessData)
351 Boolean_t IsOk = TRUE;
353 REQUIRE(VALID_REF(FileStream) && VALID_REF(FileStream->File));
354 REQUIRE(0 < IVersion && IVersion <= TecplotBinaryFileVersion);
355 REQUIRE(IMPLICATION(IVersion < 63 || ProcessData, MaxCharacters >= 0));
356 REQUIRE(IMPLICATION(ProcessData, VALID_REF(TargetStr)));
357 REQUIRE(VALID_BOOLEAN(ProcessData));
359 if (IVersion < 63)
362 * One word per character. Read Exactly "MaxCharacters" number of words.
364 float X;
366 if (ProcessData)
368 *TargetStr = ALLOC_ARRAY(MaxCharacters + 1, char, "target string");
369 IsOk = (*TargetStr != NULL);
372 if (IsOk)
374 LgIndex_t I;
375 for (I = 0; IsOk && I < MaxCharacters; I++)
377 X = (float)GetNextValue(FileStream, FieldDataType_Float, 0.0, 127.0, &IsOk);
378 if (!IsOk)
379 break;
380 if (ProcessData)
381 (*TargetStr)[I] = FilterFloatChar(X);
383 if (ProcessData)
384 (*TargetStr)[I] = '\0';
386 else
388 ErrMsg(translate("Cannot allocate memory for string during read",
389 "'string' meaning the computer science data type"));
392 else
394 #define MAX_STRBUFFER_LEN 4095
395 static char StrBuffer[MAX_STRBUFFER_LEN+1];
396 LgIndex_t StrBufferLen = 0;
397 LgIndex_t TargetStrLen = 0;
398 LgIndex_t I = 0;
399 LgIndex_t CharValue = 0;
401 if (ProcessData)
402 *TargetStr = NULL;
406 CharValue = GetIoFileInt(FileStream, IVersion, 0, 255, &IsOk);
407 if (IsOk && ProcessData)
409 /* massage the character if necessary */
410 if ((CharValue < 32 && CharValue != '\0' && CharValue != '\n') ||
411 (CharValue >= 128 && CharValue < 160))
412 CharValue = ' ';
415 * if the limit is not exceded, stuff the
416 * character into the buffer
418 if (CharValue != '\0' &&
419 (I < MaxCharacters || MaxCharacters == 0))
421 StrBuffer[StrBufferLen] = (char)CharValue;
422 StrBufferLen++;
425 if (CharValue == '\0' ||
426 StrBufferLen == MAX_STRBUFFER_LEN)
428 if (StrBufferLen != 0 || *TargetStr == NULL)
430 StrBuffer[StrBufferLen] = '\0';
431 TargetStrLen += StrBufferLen;
432 IsOk = ReallocString(TargetStr, TargetStrLen);
433 if (IsOk)
434 strcat(*TargetStr, StrBuffer);
435 StrBufferLen = 0; /* reset the string buffer */
440 I++;
442 while (IsOk && (char)CharValue != '\0');
444 /* if we failed cleanup if necessary */
445 if (!IsOk &&
446 ProcessData &&
447 *TargetStr != NULL)
449 FREE_ARRAY(*TargetStr, "failed read string");
450 *TargetStr = NULL;
454 ENSURE(IMPLICATION(ProcessData,
455 (VALID_REF(*TargetStr) || *TargetStr == NULL)));
456 ENSURE(VALID_BOOLEAN(IsOk));
457 return (IsOk);
462 static void ReadDoubleBlock(FileStream_s *FileStream,
463 Boolean_t DoRead,
464 double *Buffer,
465 LgIndex_t StartIndex,
466 LgIndex_t NumValues,
467 Boolean_t *IsOk)
469 if (DoRead)
471 double *DPtr = Buffer + StartIndex;
472 *IsOk = (TP_FREAD(DPtr, sizeof(double), NumValues, FileStream->File) == (size_t)NumValues);
473 if (!FileStream->IsByteOrderNative && *IsOk)
475 LgIndex_t N;
476 for (N = 0; N < NumValues; N++)
477 REVERSE_8_BYTES(&DPtr[N]);
480 else
481 *IsOk = (TP_FSEEK(FileStream->File, NumValues * sizeof(double), SEEK_CUR) == 0);
486 static void ReadFloatBlock(FileStream_s *FileStream,
487 Boolean_t DoRead,
488 float *Buffer,
489 LgIndex_t StartIndex,
490 LgIndex_t NumValues,
491 Boolean_t *IsOk)
493 if (DoRead)
495 float *FPtr = Buffer + StartIndex;
496 *IsOk = (TP_FREAD(FPtr, sizeof(float), NumValues, FileStream->File) == (size_t)NumValues);
497 if (!FileStream->IsByteOrderNative && *IsOk)
499 LgIndex_t N;
500 for (N = 0; N < NumValues; N++)
501 REVERSE_4_BYTES(&FPtr[N]);
504 else
505 *IsOk = (TP_FSEEK(FileStream->File, NumValues * sizeof(float), SEEK_CUR) == 0);
511 static void ReadBitBlock(FileStream_s *FileStream,
512 Boolean_t DoRead,
513 Byte_t *Buffer,
514 LgIndex_t NumValues,
515 Boolean_t *IsOk)
518 * Do not allow reading of bit values if startindex is not 0.
519 * (This means geometries cannot use bit data.
521 LgIndex_t NumBytes = (NumValues + 7) / 8;
522 if (DoRead)
524 *IsOk = (TP_FREAD(Buffer,
525 sizeof(Byte_t),
526 NumBytes,
527 FileStream->File) == (size_t)NumBytes);
529 else
530 *IsOk = (TP_FSEEK(FileStream->File, NumBytes * sizeof(Byte_t), SEEK_CUR) == 0);
535 void ReadByteBlock(FileStream_s *FileStream,
536 Boolean_t DoRead,
537 Byte_t *Buffer,
538 HgIndex_t StartIndex,
539 HgIndex_t NumValues,
540 Boolean_t *IsOk)
542 if (DoRead)
544 *IsOk = (TP_FREAD(Buffer + StartIndex,
545 sizeof(Byte_t),
546 NumValues,
547 FileStream->File) == (size_t)NumValues);
549 else
550 *IsOk = (TP_FSEEK(FileStream->File, NumValues * sizeof(Byte_t), SEEK_CUR) == 0);
556 void ReadInt16Block(FileStream_s *FileStream,
557 Boolean_t DoRead,
558 Int16_t *Buffer,
559 HgIndex_t StartIndex,
560 HgIndex_t NumValues,
561 Boolean_t *IsOk)
563 if (DoRead)
565 Int16_t *IntPtr = Buffer + StartIndex;
566 *IsOk = (TP_FREAD(IntPtr,
567 sizeof(Int16_t),
568 NumValues,
569 FileStream->File) == (size_t)NumValues);
571 if (!FileStream->IsByteOrderNative && *IsOk)
573 LgIndex_t N;
574 for (N = 0; N < NumValues; N++)
575 REVERSE_2_BYTES(&IntPtr[N]);
578 else
579 *IsOk = (TP_FSEEK(FileStream->File, NumValues * sizeof(Int16_t), SEEK_CUR) == 0);
584 void ReadInt16BlockToInt32(FileStream_s *FileStream,
585 Boolean_t DoRead,
586 Int32_t *Buffer,
587 HgIndex_t StartIndex,
588 HgIndex_t NumValues,
589 Boolean_t *IsOk)
591 REQUIRE(VALID_REF(FileStream));
592 REQUIRE(VALID_BOOLEAN(DoRead));
593 REQUIRE(VALID_REF(Buffer));
594 REQUIRE(StartIndex >= 0);
595 REQUIRE(NumValues >= 0);
596 REQUIRE(VALID_REF(IsOk) && VALID_BOOLEAN(*IsOk));
598 if (DoRead)
600 HgIndex_t EndIndex = StartIndex + NumValues;
601 for (HgIndex_t ValueIndex = StartIndex; *IsOk && ValueIndex < EndIndex; ValueIndex++)
603 Int16_t Value;
604 *IsOk = (TP_FREAD(&Value, sizeof(Int16_t), 1, FileStream->File) == 1);
605 if (!FileStream->IsByteOrderNative && *IsOk)
606 REVERSE_2_BYTES(&Value);
607 Buffer[ValueIndex] = (Int32_t)Value;
610 else
611 *IsOk = (TP_FSEEK(FileStream->File, NumValues * sizeof(Int16_t), SEEK_CUR) == 0);
616 void ReadInt32Block(FileStream_s *FileStream,
617 Boolean_t DoRead,
618 Int32_t *Buffer,
619 HgIndex_t StartIndex,
620 HgIndex_t NumValues,
621 Boolean_t *IsOk)
623 if (DoRead)
625 Int32_t *IntPtr = Buffer + StartIndex;
626 *IsOk = (TP_FREAD(IntPtr,
627 sizeof(Int32_t),
628 NumValues,
629 FileStream->File) == (size_t)NumValues);
631 if (!FileStream->IsByteOrderNative && *IsOk)
633 LgIndex_t N;
634 for (N = 0; N < NumValues; N++)
635 REVERSE_4_BYTES(&IntPtr[N]);
638 else
639 *IsOk = (TP_FSEEK(FileStream->File, NumValues * sizeof(Int32_t), SEEK_CUR) == 0);
644 void ReadPureBlock(FileStream_s *FileStream,
645 Boolean_t DoRead,
646 void *Buffer,
647 FieldDataType_e FieldDataType,
648 HgIndex_t StartIndex,
649 HgIndex_t NumValues,
650 Boolean_t *IsOk)
652 REQUIRE(VALID_REF(FileStream) && VALID_REF(FileStream->File));
653 REQUIRE(VALID_BOOLEAN(DoRead));
654 REQUIRE(!DoRead || VALID_REF(Buffer));
655 REQUIRE(VALID_FIELD_DATA_TYPE(FieldDataType));
656 REQUIRE(StartIndex >= 0);
657 REQUIRE(NumValues >= 0);
658 REQUIRE(VALID_REF(IsOk) && VALID_BOOLEAN(*IsOk));
660 switch (FieldDataType)
662 case FieldDataType_Float :
664 ReadFloatBlock(FileStream,
665 DoRead,
666 (float *)Buffer,
667 StartIndex,
668 NumValues,
669 IsOk);
670 } break;
671 case FieldDataType_Double :
673 ReadDoubleBlock(FileStream,
674 DoRead,
675 (double *)Buffer,
676 StartIndex,
677 NumValues,
678 IsOk);
679 } break;
680 case FieldDataType_Bit :
682 if (StartIndex != 0)
684 ErrMsg(translate("Internal Error: Attempt to read bit data at non-zero offset",
685 "see Tecplot User's manual for a definition of 'bit' data"));
686 *IsOk = FALSE;
688 else
689 ReadBitBlock(FileStream,
690 DoRead,
691 (Byte_t *)Buffer,
692 NumValues,
693 IsOk);
694 } break;
695 case FieldDataType_Byte :
697 ReadByteBlock(FileStream,
698 DoRead,
699 (Byte_t *)Buffer,
700 StartIndex,
701 NumValues,
702 IsOk);
703 } break;
704 case FieldDataType_Int16 :
706 ReadInt16Block(FileStream,
707 DoRead,
708 (Int16_t *)Buffer,
709 StartIndex,
710 NumValues,
711 IsOk);
712 } break;
713 case FieldDataType_Int32 :
715 ReadInt32Block(FileStream,
716 DoRead,
717 (Int32_t *)Buffer,
718 StartIndex,
719 NumValues,
720 IsOk);
721 } break;
722 case FieldDataType_IJKFunction : /* Not used yet */
723 case FieldDataType_Int64 : /* Not used yet */
724 default: CHECK(FALSE); break;
726 ENSURE(VALID_BOOLEAN(*IsOk));
731 void ReadBlock(FileStream_s *FileStream,
732 FieldData_pa FieldData,
733 Boolean_t DoRead,
734 FieldDataType_e FieldDataTypeInFile,
735 HgIndex_t StartIndex,
736 HgIndex_t EndIndex,
737 Boolean_t *IsOk)
739 REQUIRE(VALID_REF(IsOk) && VALID_BOOLEAN(*IsOk));
740 REQUIRE(IMPLICATION(IsOk, VALID_REF(FileStream)));
741 REQUIRE(IMPLICATION(IsOk, VALID_FIELD_DATA_TYPE(FieldDataTypeInFile)));
742 REQUIRE(VALID_BOOLEAN(DoRead));
743 REQUIRE(IMPLICATION(DoRead, VALID_REF(FieldData)));
746 * Bit data is packed into bytes. Since Tecplot doesn't buffer reads it can
747 * not perform bit by bit value reads and therefore must only perform block
748 * reads of bit data.
750 Boolean_t ReadByBlock = IMPLICATION(DoRead, GetFieldDataType(FieldData) == FieldDataTypeInFile);
751 REQUIRE(ReadByBlock || (FieldDataTypeInFile != FieldDataType_Bit));
753 if (*IsOk)
755 LgIndex_t NumValues = EndIndex - StartIndex + 1;
756 if (ReadByBlock)
758 void *data_array;
759 if (DoRead)
760 data_array = GetFieldDataVoidPtr(FieldData);
761 else
762 data_array = NULL;
763 ReadPureBlock(FileStream,
764 DoRead,
765 data_array,
766 FieldDataTypeInFile,
767 StartIndex,
768 NumValues,
769 IsOk);
771 else
773 LgIndex_t N;
774 for (N = 0; *IsOk && (N < NumValues); N++)
776 double D = GetNextValue(FileStream, FieldDataTypeInFile, -LARGEDOUBLE, LARGEDOUBLE, IsOk);
777 if (DoRead)
778 SetFieldValue(FieldData, N + StartIndex, D);
786 void ReadClassicOrderedCCBlock(FileStream_s *DataFileStream,
787 FieldData_pa FieldData,
788 FieldDataType_e FieldDataTypeInFile,
789 LgIndex_t NumIPtsInFile,
790 LgIndex_t NumJPtsInFile,
791 LgIndex_t NumKPtsInFile,
792 Boolean_t *IsOk)
794 REQUIRE(IMPLICATION(*IsOk, VALID_REF(DataFileStream)));
795 REQUIRE(IMPLICATION(*IsOk, VALID_FIELD_DATA_TYPE(FieldDataTypeInFile)));
796 REQUIRE(VALID_REF(FieldData));
797 REQUIRE(NumIPtsInFile >= 0);
798 REQUIRE(NumJPtsInFile >= 0);
799 REQUIRE(NumKPtsInFile >= 0);
800 REQUIRE(VALID_REF(IsOk) && VALID_BOOLEAN(*IsOk));
802 if (*IsOk)
804 LgIndex_t J, K;
805 LgIndex_t NumIJPts = NumIPtsInFile * NumJPtsInFile;
806 LgIndex_t IEnd = MAX(NumIPtsInFile - 1, 1);
807 LgIndex_t JEnd = MAX(NumJPtsInFile - 1, 1);
808 LgIndex_t KEnd = MAX(NumKPtsInFile - 1, 1);
809 LgIndex_t NumValues = (IEnd * JEnd * KEnd);
810 Boolean_t IsLinear = ((NumJPtsInFile == 1 && NumKPtsInFile == 1) ||
811 (NumIPtsInFile == 1 && NumKPtsInFile == 1) ||
812 (NumIPtsInFile == 1 && NumJPtsInFile == 1));
813 if (IsLinear)
814 ReadBlock(DataFileStream, FieldData, TRUE, FieldDataTypeInFile,
815 0, NumValues - 1, IsOk);
816 else
817 for (K = 0; K < KEnd && IsOk; K++)
818 for (J = 0; J < JEnd && IsOk; J++)
820 LgIndex_t CellIndex = 0 + (J * NumIPtsInFile) + (K * NumIJPts);
821 ReadBlock(DataFileStream, FieldData, TRUE, FieldDataTypeInFile,
822 CellIndex, CellIndex + IEnd - 1, IsOk);
826 ENSURE(VALID_BOOLEAN(*IsOk));
831 static void AdjustCustomColor(short IVersion,
832 ColorIndex_t *BColor)
834 REQUIRE(0 < IVersion && IVersion <= TecplotBinaryFileVersion);
835 REQUIRE(VALID_REF(BColor));
837 if ((IVersion < 70) && (*BColor >= 15) && (*BColor <= 22))
838 *BColor -= 7;
843 * ReadInDataFileTypeTitleAndVarNames replaces ReadInDataFileTitleAndVarNames
844 * and reads in the filetype as well in files with version >= 109.
846 Boolean_t ReadInDataFileTypeTitleAndVarNames(FileStream_s *FileStream,
847 short IVersion,
848 char **DataSetTitle,
849 DataFileType_e *FileType,
850 int *NumVars,
851 StringList_pa *VarNames)
853 EntIndex_t CurVar;
854 Boolean_t IsOk = TRUE;
856 REQUIRE(VALID_REF(FileStream) && VALID_REF(FileStream->File));
857 REQUIRE(0 < IVersion && IVersion <= TecplotBinaryFileVersion);
858 REQUIRE(VALID_REF(DataSetTitle) || (DataSetTitle == NULL));
859 REQUIRE(VALID_REF(FileType) || (FileType == NULL));
860 REQUIRE(VALID_REF(NumVars));
861 REQUIRE(VALID_REF(VarNames) || (VarNames == NULL));
863 *NumVars = 0;
864 if (DataSetTitle)
865 *DataSetTitle = NULL;
866 if (IVersion >= 109)
868 if (FileType)
869 *FileType = (DataFileType_e)GetIoFileInt(FileStream,
870 IVersion,
872 DataFileType_Solution,
873 &IsOk);
874 else
875 GetIoFileInt(FileStream,
876 IVersion,
878 DataFileType_Solution,
879 &IsOk);
881 if (ReadInString(FileStream,
882 IVersion,
883 ((IVersion < 63) ? 80 : MaxChrsDatasetTitle),
884 DataSetTitle,
885 (Boolean_t)(DataSetTitle != NULL)))
887 if (DataSetTitle)
888 TrimLeadAndTrailSpaces(*DataSetTitle);
889 *NumVars = GetIoFileInt(FileStream, IVersion, 0, MAXZONEMAP, &IsOk);
891 else
892 IsOk = FALSE;
894 if (IsOk && (*NumVars > MaxNumZonesOrVars))
896 ErrMsg(translate("Too many variables"));
897 IsOk = FALSE;
900 if (IsOk && VarNames)
902 if (*NumVars > 0)
904 /* allocate a string list filled with NULL's */
905 *VarNames = StringListAlloc();
906 IsOk = (*VarNames != NULL);
907 if (IsOk)
908 IsOk = StringListSetString(*VarNames, *NumVars - 1, NULL);
910 if (!IsOk)
912 if (*VarNames != NULL)
913 StringListDealloc(VarNames);
914 ErrMsg(translate("Out of space while allocating var names"));
919 for (CurVar = 0; IsOk && (CurVar < *NumVars); CurVar++)
921 char *VName = NULL;
923 IsOk = ReadInString(FileStream,
924 IVersion,
925 ((IVersion < 63) ? 5 : MaxChrsVarName),
926 VarNames ? &VName : NULL,
927 (Boolean_t)(VarNames != NULL));
928 if (IsOk && VarNames)
930 if (VName == NULL)
932 /* NULL variable names are converted to empty names */
933 VName = ALLOC_ARRAY(1, char, "empty variable name");
934 strcpy(VName, "");
936 TrimLeadAndTrailSpaces(VName);
939 * variables are not allowed to have litteral new line characters
940 * within them but they can sneek in from ASCII data files so
941 * convert any to their appropriate two character representation
943 IsOk = ReplaceNewlineWithBackslashN(&VName);
945 IsOk = IsOk && StringListSetString(*VarNames, CurVar, VName);
946 if (VName != NULL)
947 FREE_ARRAY(VName, "variable name");
950 if (!IsOk)
952 if (VarNames && *VarNames)
953 StringListDealloc(VarNames);
954 ErrMsg(translate("Out of space while allocating variable names"));
957 ENSURE(VALID_BOOLEAN(IsOk));
958 return (IsOk);
966 static Boolean_t ReadInPresetZoneColor(FileStream_s *FileStream,
967 short IVersion,
968 ZoneSpec_s *ZoneSpec)
970 Boolean_t IsOk = TRUE;
971 LgIndex_t ZoneColor;
973 REQUIRE(VALID_REF(FileStream) && VALID_REF(FileStream->File));
974 REQUIRE(0 < IVersion && IVersion <= TecplotBinaryFileVersion);
975 REQUIRE(VALID_REF(ZoneSpec));
977 ZoneColor = GetIoFileInt(FileStream, IVersion, -1, LastBasicColor, &IsOk);
978 if (IsOk)
980 if (VALID_BASIC_COLOR(ZoneColor))
982 ZoneSpec->ZoneLoadInfo.PresetZoneColor = (EntIndex_t)ZoneColor;
983 AdjustCustomColor(IVersion, &ZoneSpec->ZoneLoadInfo.PresetZoneColor);
985 else if (ZoneColor != -1)
986 IsOk = FALSE;
989 ENSURE(VALID_BOOLEAN(IsOk));
990 return IsOk;
995 static void ConvertCommonTimeToSolutionTime(ZoneSpec_s *ZoneSpec)
997 REQUIRE(VALID_REF(ZoneSpec));
998 REQUIRE(ZoneSpec->AuxData == NULL || VALID_REF(ZoneSpec->AuxData));
1000 LgIndex_t ItemIndex;
1001 if (ZoneSpec->AuxData != NULL &&
1002 AuxDataGetItemIndex(ZoneSpec->AuxData, AuxData_Common_Time, &ItemIndex))
1004 const char *SameName;
1005 ArbParam_t Value;
1006 AuxDataType_e Type;
1007 Boolean_t Retain;
1009 AuxDataGetItemByIndex(ZoneSpec->AuxData, ItemIndex,
1010 &SameName, &Value, &Type, &Retain);
1011 CHECK(ustrcmp(AuxData_Common_Time, SameName) == 0);
1012 CHECK(Type == AuxDataType_String);
1014 char *EndPtr = NULL;
1015 double SolutionTime = strtod((const char *)Value, &EndPtr);
1016 if (EndPtr != (char *)Value)
1018 /* we only allow white space to trail a value */
1019 while (isspace(*EndPtr))
1020 EndPtr++;
1022 if (EndPtr != (char *)Value && *EndPtr == '\0')
1024 ZoneSpec->SolutionTime = SolutionTime;
1025 ZoneSpec->StrandID = STRAND_ID_PENDING;
1026 AuxDataDeleteItemByIndex(ZoneSpec->AuxData, ItemIndex);
1032 * Pass1 for a zone reads in and initializes the zone structures.
1033 * These structures are released later if the user elects to not read them
1034 * in.
1036 Boolean_t ReadInZoneHeader(FileStream_s *FileStream,
1037 short IVersion,
1038 ZoneSpec_s *ZoneSpec,
1039 Set_pa IsVarCellCentered,
1040 EntIndex_t NumVars,
1041 Boolean_t *IsRawFNAvailable,
1042 LgIndex_t *FNNumBndryConns)
1044 EntIndex_t Var;
1045 Boolean_t IsOk = TRUE;
1046 LgIndex_t I1;
1048 REQUIRE(VALID_REF(FileStream) && VALID_REF(FileStream->File));
1049 REQUIRE(0 < IVersion && IVersion <= TecplotBinaryFileVersion);
1050 REQUIRE(VALID_REF(ZoneSpec));
1051 REQUIRE(IsVarCellCentered == NULL || VALID_REF(IsVarCellCentered));
1052 REQUIRE(NumVars >= 0);
1053 REQUIRE(VALID_REF(IsRawFNAvailable));
1054 REQUIRE(VALID_REF(FNNumBndryConns));
1056 SetZoneSpecDefaults(ZoneSpec);
1058 if (IsVarCellCentered != NULL)
1060 /* assign default variable value location: nodal */
1061 ClearSet(IsVarCellCentered);
1062 IsOk = ExpandSet(IsVarCellCentered, NumVars, FALSE);
1065 if (IsOk)
1066 IsOk = ReadInString(FileStream, IVersion,
1067 ((IVersion < 63) ? 10 : MaxChrsZnTitle),
1068 &ZoneSpec->Name,
1069 TRUE);
1071 if (IsOk && ZoneSpec->Name == NULL)
1073 /* NULL zone names are converted to empty names */
1074 ZoneSpec->Name = ALLOC_ARRAY(1, char, "empty zone name");
1075 IsOk = (ZoneSpec->Name != NULL);
1076 if (IsOk)
1077 strcpy(ZoneSpec->Name, "");
1080 if (IsOk)
1081 TrimLeadAndTrailSpaces(ZoneSpec->Name);
1083 if (IVersion < 101)
1085 Boolean_t IsZoneFinite;
1086 DataFormat_e ZoneDataFormat;
1088 I1 = GetIoFileInt(FileStream, IVersion, 0, 3, &IsOk);
1090 if ((I1 < 0) || (I1 > 3))
1092 return (FALSE);
1095 ZoneDataFormat = (DataFormat_e)I1;
1097 IsZoneFinite = (ZoneDataFormat == DataFormat_FEPoint ||
1098 ZoneDataFormat == DataFormat_FEBlock);
1100 ZoneSpec->ZoneLoadInfo.IsInBlockFormat = (ZoneDataFormat == DataFormat_IJKBlock ||
1101 ZoneDataFormat == DataFormat_FEBlock);
1103 if (IVersion > 62)
1104 IsOk = ReadInPresetZoneColor(FileStream, IVersion, ZoneSpec);
1106 if (IVersion < 60)
1107 GetNextValue(FileStream, FieldDataType_Float, -LARGEDOUBLE, LARGEDOUBLE, &IsOk); /* Old ZPlane Value */
1109 if (IsOk)
1111 ZoneSpec->NumPtsI = GetIoFileInt(FileStream, IVersion, 0, MAXINDEX, &IsOk);
1112 ZoneSpec->NumPtsJ = GetIoFileInt(FileStream, IVersion, 0, MAXINDEX, &IsOk);
1113 if (IVersion >= 60)
1114 ZoneSpec->NumPtsK = GetIoFileInt(FileStream, IVersion, 0, MAXINDEX, &IsOk);
1115 else
1116 ZoneSpec->NumPtsK = 1;
1119 if (IsOk)
1121 /* If IMax,JMax, & KMax are all zero then this zone was "zombied" by
1122 a partial read to make layout files align. */
1124 if (!((ZoneSpec->NumPtsI == 0) &&
1125 (ZoneSpec->NumPtsJ == 0) &&
1126 (ZoneSpec->NumPtsK == 0)) &&
1127 ((ZoneSpec->NumPtsI <= 0) ||
1128 (ZoneSpec->NumPtsJ <= 0) ||
1129 (ZoneSpec->NumPtsK < 0) ||
1130 ((!IsZoneFinite && (ZoneSpec->NumPtsK == 0)))))
1132 ErrMsg(translate("Datafile is corrupted"));
1133 IsOk = FALSE;
1136 if (IsZoneFinite)
1138 if (IVersion >= 61)
1140 ZoneSpec->Type = (ZoneType_e)(ZoneSpec->NumPtsK + 1);
1141 switch (ZoneSpec->Type)
1143 case ZoneType_FETriangle: ZoneSpec->NumPtsK = 3; break;
1144 case ZoneType_FEQuad: ZoneSpec->NumPtsK = 4; break;
1145 case ZoneType_FETetra: ZoneSpec->NumPtsK = 4; break;
1146 case ZoneType_FEBrick: ZoneSpec->NumPtsK = 8; break;
1147 case ZoneType_FELineSeg: ZoneSpec->NumPtsK = 2; break;
1148 default:
1150 ErrMsg(translate("Datafile corrupted: Invalid element type for FE DataSet"));
1151 IsOk = FALSE;
1155 else
1157 ZoneSpec->Type = ZoneType_FEQuad;
1158 ZoneSpec->NumPtsK = 4;
1161 else
1163 ZoneSpec->Type = ZoneType_Ordered;
1165 ZoneSpec->ICellDim = ZoneSpec->NumPtsI - 1;
1166 ZoneSpec->JCellDim = ZoneSpec->NumPtsJ - 1;
1167 ZoneSpec->KCellDim = ZoneSpec->NumPtsK - 1;
1172 * Raw and user defined boundary face neighbors connections were not in
1173 * this or previous versions of the binary data files.
1175 *IsRawFNAvailable = FALSE;
1176 *FNNumBndryConns = 0;
1178 else
1180 if (IsOk && (IVersion >= 107))
1182 ZoneSpec->ParentZone = GetIoFileInt(FileStream, IVersion, -1, MAXZONEMAP - 1, &IsOk);
1183 if (!IsOk)
1184 ErrMsg(translate("Invalid datafile: parent zone assignment must be to an existing zone within the same datafile."));
1187 if (IsOk && (IVersion >= 106))
1189 /* Strand ID and solution time. Strand ID's of STRAND_ID_PENDING, -2, instruct Tecplot to generate strand ID's */
1190 ZoneSpec->StrandID = GetIoFileInt(FileStream, IVersion, -2, MAXZONEMAP - 1, &IsOk);
1191 ZoneSpec->SolutionTime = GetNextValue(FileStream, FieldDataType_Double, -LARGEDOUBLE, LARGEDOUBLE, &IsOk);
1192 if (!IsOk)
1193 ErrMsg(translate("Invalid datafile: bad StrandID or SolutionTime"));
1196 /* preset zone color */
1197 IsOk = IsOk && ReadInPresetZoneColor(FileStream, IVersion, ZoneSpec);
1199 /* ZoneType */
1200 I1 = (ZoneType_e)GetIoFileInt(FileStream, IVersion, 0, 7, &IsOk);
1201 switch (I1)
1203 case 0: ZoneSpec->Type = ZoneType_Ordered; break;
1204 case 1: ZoneSpec->Type = ZoneType_FELineSeg; break;
1205 case 2: ZoneSpec->Type = ZoneType_FETriangle; break;
1206 case 3: ZoneSpec->Type = ZoneType_FEQuad; break;
1207 case 4: ZoneSpec->Type = ZoneType_FETetra; break;
1208 case 5: ZoneSpec->Type = ZoneType_FEBrick; break;
1209 case 6: ZoneSpec->Type = ZoneType_FEPolygon; break;
1210 case 7: ZoneSpec->Type = ZoneType_FEPolyhedron; break;
1211 default:
1213 ErrMsg(translate("Invalid datafile: unknown zone type."));
1214 IsOk = FALSE;
1215 } break;
1218 /* DataPacking (Always BLOCK starting with file version 112 so removed from binary format) */
1219 if (IVersion < 112)
1220 ZoneSpec->ZoneLoadInfo.IsInBlockFormat =
1221 ((DataPacking_e)GetIoFileInt(FileStream, IVersion, 0, 1, &IsOk) == DataPacking_Block);
1222 else
1223 ZoneSpec->ZoneLoadInfo.IsInBlockFormat = TRUE;
1225 /* is the variable value location specified? */
1226 if ((Boolean_t)GetIoFileInt(FileStream, IVersion, 0, 1, &IsOk) && IsOk)
1228 /* Variable Value Location foreach Var */
1229 for (Var = 0; Var < NumVars && IsOk; Var++)
1231 if ((Boolean_t)GetIoFileInt(FileStream, IVersion, 0, 1, &IsOk) && IsOk &&
1232 IsVarCellCentered != NULL)
1234 IsOk = (ZoneSpec->ZoneLoadInfo.IsInBlockFormat);
1235 if (IsOk)
1236 IsOk = AddToSet(IsVarCellCentered, Var, FALSE);
1237 else
1238 ErrMsg(translate("Invalid datafile: cell centered "
1239 "variable must be in block format.",
1240 "See the Tecplot User's Manual for a definition of 'block format'"));
1245 /* are raw face neighbors supplied in the data section? */
1246 if (IVersion >= 108 && IsOk)
1248 *IsRawFNAvailable = GetIoFileInt(FileStream, IVersion, 0, 1, &IsOk);
1249 if (*IsRawFNAvailable &&
1250 (ZoneSpec->Type == ZoneType_Ordered ||
1251 ZoneSpec->Type == ZoneType_FELineSeg))
1253 IsOk = FALSE;
1254 ErrMsg(translate("Invalid datafile: raw face neighbors may not be "
1255 "supplied for ordered or FE line segment zones."));
1258 else
1259 *IsRawFNAvailable = FALSE;
1262 * If raw face neighbors are available in the datafile then Tecplot
1263 * should not auto-assign the neighbors after the load.
1265 ZoneSpec->FNAreCellFaceNbrsSupplied = *IsRawFNAvailable;
1267 /* miscellaneous face neighbor info */
1268 *FNNumBndryConns = GetIoFileInt(FileStream, IVersion, 0, MAXINDEX, &IsOk);
1269 if (*FNNumBndryConns != 0)
1270 ZoneSpec->FNMode = (FaceNeighborMode_e)GetIoFileInt(FileStream, IVersion, 0, 3, &IsOk);
1272 if (IVersion >= 108 && IsOk)
1274 Boolean_t FaceNeighborsComplete = FALSE;
1275 if (*FNNumBndryConns != 0 &&
1276 ZoneSpec->Type != ZoneType_Ordered)
1277 FaceNeighborsComplete = (Boolean_t)GetIoFileInt(FileStream, IVersion, 0, 1, &IsOk);
1280 * If the user defined face neighbors completely specify all the
1281 * face neighbors then we don't want to auto-assign the cell face
1282 * neighbors after loading. If they are not complete then leave the
1283 * setting (as set above) dependent on the availability of the raw
1284 * face neighbors.
1286 * NOTE:
1287 * This is a rather inefficient way to specify face neighbors.
1289 if (FaceNeighborsComplete)
1290 ZoneSpec->FNAreCellFaceNbrsSupplied = TRUE;
1293 if (ZoneSpec->Type == ZoneType_Ordered)
1295 /* IMax, JMax, KMax */
1296 ZoneSpec->NumPtsI = GetIoFileInt(FileStream, IVersion, 0, MAXINDEX, &IsOk);
1297 ZoneSpec->NumPtsJ = GetIoFileInt(FileStream, IVersion, 0, MAXINDEX, &IsOk);
1298 ZoneSpec->NumPtsK = GetIoFileInt(FileStream, IVersion, 0, MAXINDEX, &IsOk);
1300 * if not a zombie zone (zombie zone: points in all dimensions are
1301 * zero) then points in each direction must be specified
1303 if (IsOk &&
1304 !(ZoneSpec->NumPtsI == 0 &&
1305 ZoneSpec->NumPtsJ == 0 &&
1306 ZoneSpec->NumPtsK == 0) &&
1307 (ZoneSpec->NumPtsI == 0 ||
1308 ZoneSpec->NumPtsJ == 0 ||
1309 ZoneSpec->NumPtsK == 0))
1311 ErrMsg(translate("Invalid data file: incorrect specification of "
1312 "I, J, or K points for ordered data set."));
1313 IsOk = FALSE;
1316 else
1318 ZoneSpec->NumPtsI = GetIoFileInt(FileStream, IVersion, 0, MAXINDEX, &IsOk);
1319 if (ZoneSpec->Type == ZoneType_FEPolygon || ZoneSpec->Type == ZoneType_FEPolyhedron)
1321 ZoneSpec->NumPtsK = GetIoFileInt(FileStream, IVersion, 0, MAXINDEX, &IsOk); // ...NumFaces
1322 if (IVersion >= 111)
1324 ZoneSpec->NumFaceNodes = GetIoFileInt(FileStream, IVersion, 0, MAXINDEX, &IsOk);
1325 ZoneSpec->NumFaceBndryFaces = GetIoFileInt(FileStream, IVersion, 0, MAXINDEX, &IsOk);
1326 ZoneSpec->NumFaceBndryItems = GetIoFileInt(FileStream, IVersion, 0, MAXINDEX, &IsOk);
1329 else
1331 switch (ZoneSpec->Type)
1333 case ZoneType_FETriangle: ZoneSpec->NumPtsK = 3; break;
1334 case ZoneType_FEQuad: ZoneSpec->NumPtsK = 4; break;
1335 case ZoneType_FETetra: ZoneSpec->NumPtsK = 4; break;
1336 case ZoneType_FEBrick: ZoneSpec->NumPtsK = 8; break;
1337 case ZoneType_FELineSeg: ZoneSpec->NumPtsK = 2; break;
1338 default :
1340 ErrMsg(translate("Invalid data file: invalid element type for FE data set."));
1341 IsOk = FALSE;
1345 ZoneSpec->NumPtsJ = GetIoFileInt(FileStream, IVersion, 0, MAXINDEX, &IsOk);
1347 ZoneSpec->ICellDim = GetIoFileInt(FileStream, IVersion, 0, MAXINDEX, &IsOk);
1348 ZoneSpec->JCellDim = GetIoFileInt(FileStream, IVersion, 0, MAXINDEX, &IsOk);
1349 ZoneSpec->KCellDim = GetIoFileInt(FileStream, IVersion, 0, MAXINDEX, &IsOk);
1352 /* Zone Auxiliary Data indicator followed by Zone Auxiliary Data */
1353 for (I1 = GetIoFileInt(FileStream, IVersion, 0, 1, &IsOk);
1354 IsOk && I1 != 0;
1355 I1 = GetIoFileInt(FileStream, IVersion, 0, 1, &IsOk))
1357 if (ZoneSpec->AuxData == NULL)
1358 ZoneSpec->AuxData = AuxDataAlloc();
1359 IsOk = (ZoneSpec->AuxData != NULL);
1360 if (IsOk)
1361 IsOk = ReadInAuxData(FileStream, IVersion, ZoneSpec->AuxData);
1366 * Convert AuxZone's Common.Time from non-time aware data files to zone
1367 * solution time if it exists.
1369 if (IVersion < 106 && IsOk)
1370 ConvertCommonTimeToSolutionTime(ZoneSpec);
1372 ENSURE(VALID_BOOLEAN(IsOk));
1373 return (IsOk);
1380 * Pass1 for Custom labels simply acknowledges that a custom label was
1381 * parsed and skips over the labels.
1384 Boolean_t ReadInCustomLabels(FileStream_s *FileStream,
1385 short IVersion,
1386 Boolean_t OkToLoad,
1387 StringList_pa *CustomLabelBase)
1389 LgIndex_t NumLabels;
1390 short I;
1391 Boolean_t IsOk = TRUE;
1393 REQUIRE(VALID_REF(FileStream) && VALID_REF(FileStream->File));
1394 REQUIRE(IVersion > 0);
1395 REQUIRE(VALID_BOOLEAN(OkToLoad));
1396 REQUIRE(!(OkToLoad) || VALID_REF(CustomLabelBase));
1398 NumLabels = (short)GetIoFileInt(FileStream, IVersion, 1, MAXINDEX, &IsOk);
1399 if (IsOk && NumLabels != 0 && OkToLoad)
1401 *CustomLabelBase = StringListAlloc();
1402 IsOk = (*CustomLabelBase != NULL);
1403 if (!IsOk)
1404 ErrMsg(translate("Cannot allocate memory for Custom Labels."));
1407 for (I = 0; IsOk && (I < NumLabels); I++)
1409 char *TLabel = NULL;
1411 IsOk = ReadInString(FileStream, IVersion,
1412 1024,
1413 &TLabel,
1414 OkToLoad);
1415 TrimLeadAndTrailSpaces(TLabel);
1417 if (IsOk && OkToLoad)
1419 #if defined TECPLOTKERNEL
1420 /* CORE SOURCE CODE REMOVED */
1421 #endif
1422 IsOk = StringListAppendString(*CustomLabelBase, TLabel);
1423 if (TLabel != NULL)
1424 FREE_ARRAY(TLabel, "custom label");
1425 if (!IsOk)
1426 ErrMsg(translate("Cannot allocate memory for Custom Label."));
1429 if (!IsOk)
1430 ErrMsg(translate("Invalid custom axis label record in binary datafile"));
1432 ENSURE(VALID_BOOLEAN(IsOk));
1433 ENSURE(!(IsOk && NumLabels != 0 && OkToLoad) ||
1434 StringListValid(*CustomLabelBase));
1435 return IsOk;
1439 Boolean_t ReadInUserRec(FileStream_s *FileStream,
1440 short IVersion,
1441 int MaxCharactersAllowed,
1442 char **UserRec) /* NULL if to ignore */
1444 if (!ReadInString(FileStream, IVersion,
1445 MaxCharactersAllowed,
1446 UserRec,
1447 (Boolean_t)(UserRec != NULL)))
1449 ErrMsg(translate("Invalid USERREC record in binary datafile"));
1450 return (FALSE);
1452 return (TRUE);
1458 Boolean_t ReadInAuxData(FileStream_s *FileStream,
1459 short IVersion,
1460 AuxData_pa AuxData)
1462 Boolean_t IsOk;
1463 Boolean_t DoCollectData;
1464 char *AuxName = NULL;
1465 LgIndex_t AuxValueType;
1466 char *AuxValue = NULL;
1468 REQUIRE(VALID_REF(FileStream) && VALID_REF(FileStream->File));
1469 REQUIRE(0 < IVersion && IVersion <= TecplotBinaryFileVersion);
1470 REQUIRE(AuxData == NULL || VALID_REF(AuxData));
1472 DoCollectData = (AuxData != NULL);
1473 IsOk = ReadInString(FileStream,
1474 IVersion,
1475 MaxChrsVarName, /* ... seems reasonable */
1476 &AuxName,
1477 DoCollectData);
1478 if (IsOk && DoCollectData && !AuxDataIsValidName(AuxName))
1480 ErrMsg(translate("Invalid auxiliary data name."));
1481 IsOk = FALSE;
1485 * currently only one value type is supported
1486 * 0: AuxiliaryValueFormat_String
1488 if (IsOk)
1490 AuxValueType = GetIoFileInt(FileStream, IVersion, 0, 0, &IsOk);
1491 if (IsOk && (AuxValueType != (LgIndex_t)AuxDataType_String))
1493 ErrMsg(translate("Unsupported auxiliary data type"));
1494 IsOk = FALSE;
1498 if (IsOk)
1499 IsOk = ReadInString(FileStream,
1500 IVersion,
1501 MaxChrsAuxValueString,
1502 &AuxValue,
1503 DoCollectData);
1504 if (IsOk && DoCollectData)
1505 IsOk = AuxDataSetItem(AuxData,
1506 AuxName, (ArbParam_t)AuxValue,
1507 AuxDataType_String,
1508 TRUE); /* Retain */
1510 /* cleanup: auxiliary data made a copy of the name and value */
1511 if (AuxName != NULL)
1512 FREE_ARRAY(AuxName, "data set auxiliary data item name");
1513 if (AuxValue != NULL)
1514 FREE_ARRAY(AuxValue, "data set auxiliary data item value");
1516 ENSURE(VALID_BOOLEAN(IsOk));
1517 return IsOk;
1521 static void GetZoneAttachment(FileStream_s *FileStream,
1522 short IVersion,
1523 EntIndex_t *Z,
1524 Boolean_t *IsAttached,
1525 Boolean_t *IsOk)
1527 REQUIRE(VALID_REF(FileStream) && VALID_REF(FileStream->File));
1528 REQUIRE(VALID_REF(Z));
1529 REQUIRE(VALID_REF(IsAttached));
1530 REQUIRE(VALID_REF(IsOk) && VALID_BOOLEAN(*IsOk));
1532 if (IVersion >= 47)
1533 *Z = (EntIndex_t)GetIoFileInt(FileStream, IVersion, -1, MAXZONEMAP, IsOk);
1534 else
1535 *Z = 0;
1537 if (IVersion < 70)
1538 (*Z)--;
1540 if (*Z == -1)
1542 *Z = 0;
1543 *IsAttached = FALSE;
1545 else
1546 *IsAttached = TRUE;
1548 ENSURE(VALID_BOOLEAN(*IsAttached));
1549 ENSURE(VALID_BOOLEAN(*IsOk));
1550 ENSURE(*Z >= 0);
1554 static Boolean_t ReadMacroFunctionCommand(FileStream_s *FileStream,
1555 short IVersion,
1556 Boolean_t OkToLoad,
1557 char **MacroFunctionCommand)
1559 Boolean_t Result = FALSE;
1560 REQUIRE(VALID_REF(FileStream) && VALID_REF(FileStream->File));
1561 REQUIRE(IVersion > 0);
1562 REQUIRE(VALID_BOOLEAN(OkToLoad));
1563 REQUIRE(VALID_REF(MacroFunctionCommand));
1565 Result = ReadInString(FileStream, IVersion, 0, MacroFunctionCommand, OkToLoad);
1567 ENSURE(VALID_BOOLEAN(Result));
1568 return (Result);
1573 * Pass1 for Geometries simply acknowledges that a geometry was
1574 * parsed and skips over the geometry.
1576 Boolean_t ReadInGeometry(FileStream_s *FileStream,
1577 short IVersion,
1578 Boolean_t OkToLoad,
1579 Geom_s *Geom,
1580 LgIndex_t MaxDataPts)
1582 LgIndex_t I;
1583 LgIndex_t S;
1584 FieldDataType_e FFT;
1585 Boolean_t IsOk = TRUE;
1586 TranslatedString ErrMsgString = translate("Invalid geometry record");
1588 REQUIRE(VALID_REF(Geom));
1590 if (IVersion < 70)
1591 FFT = FieldDataType_Float;
1592 else
1593 FFT = FieldDataType_Double;
1595 if (IVersion < 101)
1596 I = GetIoFileInt(FileStream, IVersion, 0, 1, &IsOk);
1597 else
1598 I = GetIoFileInt(FileStream, IVersion, 0, 4, &IsOk);
1600 if (I == 0)
1601 Geom->PositionCoordSys = CoordSys_Grid;
1602 else if (I == 1)
1603 Geom->PositionCoordSys = CoordSys_Frame;
1605 * I == 2 is for CoordSys_FrameOffset and is not used currently
1607 * I == 3 is for the old window coordinate system
1609 else if (I == 4)
1610 Geom->PositionCoordSys = CoordSys_Grid3D;
1611 else
1613 ErrMsgString = translate("Invalid geometry coordinate system");
1614 IsOk = FALSE;
1617 Geom->Scope = (Scope_e)GetIoFileInt(FileStream, IVersion, 0, 1, &IsOk);
1618 if (IVersion >= 102)
1619 Geom->DrawOrder = (DrawOrder_e)GetIoFileInt(FileStream, IVersion, 0, 1, &IsOk);
1620 Geom->AnchorPos.Generic.V1 = GetNextValue(FileStream, FFT, -LARGEDOUBLE, LARGEDOUBLE, &IsOk);
1621 Geom->AnchorPos.Generic.V2 = GetNextValue(FileStream, FFT, -LARGEDOUBLE, LARGEDOUBLE, &IsOk);
1622 if (IVersion >= 45)
1623 Geom->AnchorPos.Generic.V3 = GetNextValue(FileStream, FFT, -LARGEDOUBLE, LARGEDOUBLE, &IsOk);
1624 else
1625 Geom->AnchorPos.Generic.V3 = 0.0;
1627 GetZoneAttachment(FileStream, IVersion, &Geom->Zone, &Geom->AttachToZone, &IsOk);
1629 Geom->BColor = (SmInteger_t)GetIoFileInt(FileStream, IVersion, 0, 255, &IsOk);
1631 AdjustCustomColor(IVersion, &Geom->BColor);
1633 if (IVersion > 47)
1635 Geom->FillBColor = (SmInteger_t)GetIoFileInt(FileStream, IVersion, 0, 255, &IsOk);
1636 Geom->IsFilled = (Boolean_t)GetIoFileInt(FileStream, IVersion, 0, 1, &IsOk);
1637 AdjustCustomColor(IVersion, &Geom->FillBColor);
1639 else
1641 Geom->FillBColor = Geom->BColor;
1642 Geom->IsFilled = FALSE;
1645 if (IVersion < 101)
1647 Geom->GeomType = (GeomType_e)GetIoFileInt(FileStream, IVersion, 0, 5, &IsOk);
1648 if (Geom->GeomType == GeomType_LineSegs3D)
1651 * GeomType_LineSegs3D is deprecated, converter to GeomType_LineSegs
1652 * with CoordSys_Grid3D instead
1654 Geom->GeomType = GeomType_LineSegs;
1655 Geom->PositionCoordSys = CoordSys_Grid3D; /*...should have been anyway */
1658 else
1660 Geom->GeomType = (GeomType_e)GetIoFileInt(FileStream, IVersion, 0, 4, &IsOk);
1664 * Check geom coord sys versus geom type
1666 if (Geom->PositionCoordSys == CoordSys_Grid3D &&
1667 Geom->GeomType != GeomType_LineSegs)
1669 ErrMsgString = translate("Mismatch between geometry coordinate system and geometry type");
1670 IsOk = FALSE;
1673 if (IVersion > 41)
1675 Geom->LinePattern = (LinePattern_e)GetIoFileInt(FileStream, IVersion, 0, (LgIndex_t)LinePattern_DashDotDot, &IsOk);
1677 else
1679 Geom->LinePattern = (LinePattern_e)((int)Geom->GeomType % 2);
1680 Geom->GeomType = (GeomType_e)((int)Geom->GeomType / 10);
1683 if ((IVersion < 49) && ((short)(Geom->GeomType) == 2))
1685 Geom->GeomType = GeomType_Rectangle;
1686 Geom->IsFilled = TRUE;
1689 if ((IVersion < 70) && ((short)(Geom->GeomType) > 1))
1690 Geom->GeomType = (GeomType_e)((short)Geom->GeomType + 1);
1692 ResetString(&Geom->MacroFunctionCommand, NULL, TRUE);
1694 Geom->ImageResizeFilter = ImageResizeFilter_Texture;
1696 if (IVersion >= 70)
1698 Geom->PatternLength = GetNextValue(FileStream, FFT,
1699 PatternLengthInputSpec.Min,
1700 PatternLengthInputSpec.Max,
1701 &IsOk);
1702 Geom->LineThickness = GetNextValue(FileStream, FFT,
1703 LineThicknessInputSpec.Min,
1704 LineThicknessInputSpec.Max,
1705 &IsOk);
1706 Geom->NumEllipsePts = (SmInteger_t)GetIoFileInt(FileStream, IVersion, 2, MaxPtsCircleOrEllipse, &IsOk);
1707 Geom->ArrowheadStyle = (ArrowheadStyle_e)GetIoFileInt(FileStream, IVersion, 0, (LgIndex_t)ArrowheadStyle_Hollow, &IsOk);
1708 Geom->ArrowheadAttachment = (ArrowheadAttachment_e)GetIoFileInt(FileStream, IVersion,
1710 (LgIndex_t)ArrowheadAttachment_AtBothEnds,
1711 &IsOk);
1713 Geom->ArrowheadSize = GetNextValue(FileStream, FFT,
1714 ArrowheadSizeInputSpec.Min,
1715 ArrowheadSizeInputSpec.Max,
1716 &IsOk);
1717 Geom->ArrowheadAngle = GetNextValue(FileStream, FFT,
1718 ArrowheadAngleInputSpec.Min,
1719 ArrowheadAngleInputSpec.Max,
1720 &IsOk);
1722 if (IVersion >= 75)
1724 IsOk = ReadMacroFunctionCommand(FileStream,
1725 IVersion,
1726 OkToLoad,
1727 &Geom->MacroFunctionCommand);
1728 } /* version >= 75 */
1729 } /* version >= 70 */
1730 else
1732 Geom->LineThickness = 0.001;
1733 Geom->PatternLength = 0.02;
1734 Geom->ArrowheadStyle = ArrowheadStyle_Plain;
1735 Geom->ArrowheadAttachment = ArrowheadAttachment_None;
1736 Geom->ArrowheadSize = 0.05;
1737 Geom->ArrowheadAngle = 12.0 / DEGPERRADIANS;
1740 if (IVersion < 41)
1742 GetNextValue(FileStream, FieldDataType_Float, -LARGEDOUBLE, LARGEDOUBLE, &IsOk);
1743 GetNextValue(FileStream, FieldDataType_Float, -LARGEDOUBLE, LARGEDOUBLE, &IsOk);
1744 GetNextValue(FileStream, FieldDataType_Float, -LARGEDOUBLE, LARGEDOUBLE, &IsOk);
1747 if (IVersion < 70)
1748 Geom->DataType = FieldDataType_Float;
1749 else
1750 Geom->DataType = (FieldDataType_e)GetIoFileInt(FileStream, IVersion, 1, 2, &IsOk);
1751 CHECK(VALID_GEOM_FIELD_DATA_TYPE(Geom->DataType));
1753 Geom->Clipping = Clipping_ClipToViewport; /* default value for pre 101 versions */
1754 if (IVersion >= 101)
1756 Geom->Clipping = (Clipping_e)GetIoFileInt(FileStream, IVersion, 0, 2, &IsOk);
1758 * The second clipping value was deprecated during v10 development and thus removed.
1759 * This moved Clipping_ClipToFrame to the 2nd position from the 3rd, so we convert
1760 * value 2 to ClipToFrame to support files made during v10 developement.
1762 if (Geom->Clipping == (Clipping_e)2)
1763 Geom->Clipping = Clipping_ClipToFrame;
1766 if (IVersion < 50 ||
1767 Geom->GeomType == GeomType_LineSegs)
1769 Geom->NumSegments = (SmInteger_t)GetIoFileInt(FileStream, IVersion, 1, MaxGeoSegments, &IsOk);
1770 #if defined TECPLOTKERNEL
1771 /* CORE SOURCE CODE REMOVED */
1772 #endif
1773 S = -1;
1774 I = 0;
1775 while ((S + 1 < Geom->NumSegments) &&
1776 !feof(FileStream->File) && IsOk)
1778 S++;
1779 Geom->NumSegPts[S] = GetIoFileInt(FileStream, IVersion, 1, MAXINDEX, &IsOk);
1780 if ((I + Geom->NumSegPts[S] > MaxDataPts) && OkToLoad)
1782 ErrMsgString = translate("Geometry is too big");
1783 IsOk = FALSE;
1785 else
1787 ReadBlock(FileStream, Geom->GeomData.Generic.V1Base, OkToLoad, Geom->DataType, I, I + Geom->NumSegPts[S] - 1, &IsOk);
1788 ReadBlock(FileStream, Geom->GeomData.Generic.V2Base, OkToLoad, Geom->DataType, I, I + Geom->NumSegPts[S] - 1, &IsOk);
1789 if (Geom->PositionCoordSys == CoordSys_Grid3D)
1790 ReadBlock(FileStream, Geom->GeomData.Generic.V3Base, OkToLoad, Geom->DataType, I, I + Geom->NumSegPts[S] - 1, &IsOk);
1791 I += Geom->NumSegPts[S];
1794 if (IsOk && (Geom->GeomType == GeomType_Rectangle)) /* IVersion < 50 */
1796 if (OkToLoad)
1798 CopyFieldValue(Geom->GeomData.Generic.V1Base, 0, Geom->GeomData.Generic.V1Base, 2);
1799 CopyFieldValue(Geom->GeomData.Generic.V2Base, 0, Geom->GeomData.Generic.V2Base, 2);
1803 else if (Geom->GeomType == GeomType_Rectangle ||
1804 Geom->GeomType == GeomType_Ellipse)
1806 double XX, YY;
1807 XX = GetNextValue(FileStream, Geom->DataType, -LARGEDOUBLE, LARGEDOUBLE, &IsOk);
1808 YY = GetNextValue(FileStream, Geom->DataType, -LARGEDOUBLE, LARGEDOUBLE, &IsOk);
1809 if (OkToLoad)
1811 SetFieldValue(Geom->GeomData.XYZ.XBase, 0, XX);
1812 SetFieldValue(Geom->GeomData.XYZ.YBase, 0, YY);
1814 Geom->NumSegments = 1;
1815 Geom->NumSegPts[0] = 1;
1817 else
1819 double XX;
1820 CHECK((Geom->GeomType == GeomType_Square) ||
1821 (Geom->GeomType == GeomType_Circle));
1822 XX = GetNextValue(FileStream, Geom->DataType, -LARGEDOUBLE, LARGEDOUBLE, &IsOk);
1823 if (OkToLoad)
1825 SetFieldValue(Geom->GeomData.XYZ.XBase, 0, XX);
1827 Geom->NumSegments = 1;
1828 Geom->NumSegPts[0] = 1;
1831 if (!IsOk)
1832 ErrMsg(ErrMsgString);
1834 return (IsOk);
1838 * Pass1 for text simply acknowledges that a text was
1839 * parsed and skips over the text.
1841 Boolean_t ReadInText(FileStream_s *FileStream,
1842 short IVersion,
1843 Boolean_t OkToLoad,
1844 Text_s *Text,
1845 LgIndex_t MaxTextLen)
1847 LgIndex_t I;
1848 FieldDataType_e FFT;
1849 SmInteger_t TextLength = 0;
1850 Boolean_t IsOk = TRUE;
1851 TranslatedString ErrMsgString = translate("Invalid text record");
1853 REQUIRE(VALID_REF(Text));
1855 if (IVersion < 70)
1856 FFT = FieldDataType_Float;
1857 else
1858 FFT = FieldDataType_Double;
1860 if (IVersion < 101)
1861 I = GetIoFileInt(FileStream, IVersion, 0, 1, &IsOk);
1862 else
1863 I = GetIoFileInt(FileStream, IVersion, 0, 4, &IsOk);
1865 if (I == 0)
1866 Text->PositionCoordSys = CoordSys_Grid;
1867 else if (I == 1)
1868 Text->PositionCoordSys = CoordSys_Frame;
1870 * I == 2 is for CoordSys_FrameOffset and is not used currently
1872 * I == 3 is for the old window coordinate system
1874 else if (I == 4)
1875 Text->PositionCoordSys = CoordSys_Grid3D;
1876 else
1878 ErrMsgString = translate("Invalid text coordinate system.");
1879 IsOk = FALSE;
1882 Text->Scope = (Scope_e)GetIoFileInt(FileStream, IVersion, 0, 1, &IsOk);
1883 Text->AnchorPos.Generic.V1 = GetNextValue(FileStream, FFT, -LARGEDOUBLE, LARGEDOUBLE, &IsOk);
1884 Text->AnchorPos.Generic.V2 = GetNextValue(FileStream, FFT, -LARGEDOUBLE, LARGEDOUBLE, &IsOk);
1885 if (IVersion >= 101)
1886 Text->AnchorPos.Generic.V3 = GetNextValue(FileStream, FFT, -LARGEDOUBLE, LARGEDOUBLE, &IsOk);
1887 else
1888 Text->AnchorPos.Generic.V3 = 0.0; /* default value for pre 101 versions */
1890 if (IVersion > 40)
1891 Text->TextShape.Font = (Font_e)GetIoFileInt(FileStream, IVersion, 0, (LgIndex_t)Font_CourierBold, &IsOk);
1892 else
1893 Text->TextShape.Font = Font_Helvetica;
1894 if (IVersion < 43)
1895 GetNextValue(FileStream, FFT, -LARGEDOUBLE, LARGEDOUBLE, &IsOk);
1896 if (IVersion < 70)
1898 if (Text->PositionCoordSys == CoordSys_Grid)
1899 Text->TextShape.SizeUnits = Units_Grid;
1900 else
1901 Text->TextShape.SizeUnits = Units_Frame;
1903 else
1904 Text->TextShape.SizeUnits = (Units_e)GetIoFileInt(FileStream, IVersion, 0, (LgIndex_t)Units_Point, &IsOk);
1906 Text->TextShape.Height = GetNextValue(FileStream, FFT, -LARGEDOUBLE, LARGEDOUBLE, &IsOk);
1907 if (IVersion > 47)
1909 Text->Box.BoxType = (TextBox_e)GetIoFileInt(FileStream, IVersion, 0, (LgIndex_t)TextBox_Hollow, &IsOk);
1910 if (IVersion < 70)
1912 if (Text->Box.BoxType == TextBox_Hollow)
1913 Text->Box.BoxType = TextBox_Filled;
1914 else if (Text->Box.BoxType == TextBox_Filled)
1915 Text->Box.BoxType = TextBox_Hollow;
1917 Text->Box.Margin = GetNextValue(FileStream, FFT,
1918 TextBoxMarginInputSpec.Min,
1919 TextBoxMarginInputSpec.Max,
1920 &IsOk);
1921 if (IVersion >= 70)
1922 Text->Box.LineThickness = GetNextValue(FileStream, FFT,
1923 LineThicknessInputSpec.Min,
1924 LineThicknessInputSpec.Max,
1925 &IsOk);
1926 else
1927 Text->Box.LineThickness = 0.01;
1928 Text->Box.BColor = (ColorIndex_t)GetIoFileInt(FileStream, IVersion, 0, 255, &IsOk);
1929 Text->Box.FillBColor = (ColorIndex_t)GetIoFileInt(FileStream, IVersion, 0, 255, &IsOk);
1930 AdjustCustomColor(IVersion, &Text->Box.BColor);
1931 AdjustCustomColor(IVersion, &Text->Box.FillBColor);
1933 else
1935 Text->Box.BoxType = TextBox_None;
1936 Text->Box.Margin = 0.0;
1937 Text->Box.BColor = White_C;
1938 Text->Box.FillBColor = Black_C;
1940 if (IVersion < 70)
1942 Text->Angle = GetIoFileInt(FileStream, IVersion, -720, 720, &IsOk) / DEGPERRADIANS;
1943 Text->LineSpacing = 1;
1944 Text->Anchor = TextAnchor_Left;
1946 else
1948 Text->Angle = GetNextValue(FileStream, FFT,
1949 TextAngleInputSpec.Min,
1950 TextAngleInputSpec.Max,
1951 &IsOk);
1952 Text->LineSpacing = GetNextValue(FileStream, FFT,
1953 TextLineSpacingInputSpec.Min,
1954 TextLineSpacingInputSpec.Max,
1955 &IsOk);
1956 Text->Anchor = (TextAnchor_e)GetIoFileInt(FileStream, IVersion, 0, (LgIndex_t)TextAnchor_HeadRight, &IsOk);
1959 GetZoneAttachment(FileStream, IVersion, &Text->Zone, &Text->AttachToZone, &IsOk);
1961 Text->BColor = (ColorIndex_t)GetIoFileInt(FileStream, IVersion, 0, 255, &IsOk);
1962 AdjustCustomColor(IVersion, &Text->BColor);
1963 if (IVersion < 70)
1964 TextLength = (short)GetIoFileInt(FileStream, IVersion, 0, 5000, &IsOk);
1966 ResetString(&Text->MacroFunctionCommand, NULL, TRUE);
1968 Text->Clipping = Clipping_ClipToViewport; /* default value for pre 101 versions */
1970 if (IVersion < 70)
1972 short I, S;
1973 for (I = 0; I < TextLength; I++)
1975 S = (short)GetIoFileInt(FileStream, IVersion, 0, 1000, &IsOk);
1976 if (OkToLoad && (I <= MaxTextLen))
1977 Text->Text[I] = (char)S;
1979 if (OkToLoad)
1980 Text->Text[MIN(TextLength, MaxTextLen)] = '\0';
1982 else
1984 char *S = NULL;
1986 if (IVersion >= 75)
1988 IsOk = ReadMacroFunctionCommand(FileStream,
1989 IVersion,
1990 OkToLoad,
1991 &Text->MacroFunctionCommand);
1992 } /* IVersion >= 75 */
1994 if (IVersion >= 101)
1997 * The second clipping value was deprecated during v10 development and thus removed.
1998 * This moved Clipping_ClipToFrame to the 2nd position from the 3rd, so we convert
1999 * value 2 to ClipToFrame to support files made during v10 developement.
2001 Text->Clipping = (Clipping_e)GetIoFileInt(FileStream, IVersion, 0, 2, &IsOk);
2002 if (Text->Clipping == (Clipping_e)2)
2003 Text->Clipping = Clipping_ClipToFrame;
2006 if (ReadInString(FileStream,
2007 IVersion,
2008 MaxTextLen,
2010 OkToLoad))
2012 REQUIRE(!(S || OkToLoad) || VALID_REF(Text->Text));
2013 if (S)
2015 #if defined TECPLOTKERNEL
2016 /* CORE SOURCE CODE REMOVED */
2017 #endif /* TECPLOTKERNEL */
2018 if (IsOk)
2020 strcpy(Text->Text, S);
2022 FREE_ARRAY(S, "Release temp string for new text label");
2024 else if (OkToLoad)
2025 Text->Text[0] = '\0';
2027 else
2028 IsOk = FALSE;
2031 if (!IsOk)
2032 ErrMsg(ErrMsgString);
2034 return (IsOk);
2038 static Boolean_t CompareVersion(float Version,
2039 char *VersionString,
2040 Boolean_t IsByteOrderNative)
2042 char *VersionBuf = (char *) & Version;
2044 REQUIRE(VALID_REF(VersionString));
2046 if (IsByteOrderNative)
2047 return ((VersionString[0] == VersionBuf[0]) &&
2048 (VersionString[1] == VersionBuf[1]) &&
2049 (VersionString[2] == VersionBuf[2]) &&
2050 (VersionString[3] == VersionBuf[3]));
2051 else
2052 return ((VersionString[3] == VersionBuf[0]) &&
2053 (VersionString[2] == VersionBuf[1]) &&
2054 (VersionString[1] == VersionBuf[2]) &&
2055 (VersionString[0] == VersionBuf[3]));
2058 static float ValidVersions[] = {7.0F,
2059 6.3F, 6.2F, 6.1F, 6.0F,
2060 5.0F,
2061 4.7F, 4.6F, 4.5F, 4.4F, 4.3F, 4.2F, 4.1F, 4.0F
2063 #define NUMVALIDVERSIONS ((int)(sizeof(ValidVersions)/sizeof(ValidVersions[0])))
2067 * Extra caution taken here in case value read is invalid float
2069 static Boolean_t GetDoubleVersion(char *VersionString,
2070 float *FInputVersion,
2071 Boolean_t IsByteOrderNative)
2073 int I;
2074 REQUIRE(VALID_REF(FInputVersion));
2076 for (I = 0; I < NUMVALIDVERSIONS; I++)
2077 if (CompareVersion(ValidVersions[I], VersionString, IsByteOrderNative))
2079 *FInputVersion = ValidVersions[I];
2080 return (TRUE);
2082 return (FALSE);
2086 static short GetNewInputVersion(FileStream_s *FileStream)
2091 char Buf[4];
2092 short IVersion = 0;
2093 short I;
2094 LgIndex_t OneValue;
2095 Boolean_t IsOk = TRUE;
2097 REQUIRE(VALID_REF(FileStream) && VALID_REF(FileStream->File));
2098 REQUIRE(FileStream->IsByteOrderNative);
2100 if (TP_FREAD(Buf, 4, 1, FileStream->File) != 1)
2101 return (0);
2103 if (strncmp(Buf, "#!TD", 4))
2104 return (0);
2106 if (TP_FREAD(Buf, 4, 1, FileStream->File) != 1)
2107 return (0);
2109 if (Buf[0] != 'V')
2110 return (0);
2112 I = 1;
2113 while ((I < 4) && isdigit(Buf[I]))
2114 IVersion = IVersion * 10 + Buf[I++] - '0';
2116 if (IVersion < 70)
2117 return (0);
2118 else if (IVersion > TecplotBinaryFileVersion)
2120 ErrMsg(translate("Binary file version newer than Tecplot version. "
2121 "Upgrade Tecplot or use an older Preplot to produce "
2122 "the datafile."));
2123 return (IVersion);
2127 * Determine Byte Order.
2130 OneValue = GetIoFileInt(FileStream,
2131 IVersion,
2132 -MAXINDEX,
2133 MAXINDEX,
2134 &IsOk);
2136 if (!IsOk)
2137 return (0);
2139 FileStream->IsByteOrderNative = (OneValue == 1);
2141 return (IVersion);
2145 * Return value of zero is to be considered as an invalid
2146 * tecplot binary datafile header. Actually binary files
2147 * older than version 4.0 (return value of 40) are not supported
2148 * (See notes in preplot.c).
2150 short GetInputVersion(FileStream_s *FileStream)
2152 Boolean_t IsOk = TRUE;
2153 float FInputVersion;
2154 short IVersion;
2155 char VersionString[4];
2156 FileOffset_t StartOffset = 0;
2159 * First check to see if file uses new
2160 * input version format.
2163 /* keep track of our start offset */
2164 StartOffset = TP_FTELL(FileStream->File);
2166 IVersion = GetNewInputVersion(FileStream);
2168 if (IVersion > TecplotBinaryFileVersion)
2169 return IVersion; /* unsupported version */
2170 else if (IVersion == 0)
2172 /* rewind to clear any errors and seek to the start offset */
2173 rewind(FileStream->File);
2174 IsOk = (TP_FSEEK(FileStream->File, StartOffset, SEEK_SET) == 0);
2176 if (IsOk && TP_FREAD(VersionString, 4, 1, FileStream->File) == 1)
2178 /* try both native and foreign versions numbers */
2179 if (!GetDoubleVersion(VersionString, &FInputVersion, FileStream->IsByteOrderNative))
2181 FileStream->IsByteOrderNative = !FileStream->IsByteOrderNative; /* ...reverse the byte order */
2182 IsOk = GetDoubleVersion(VersionString, &FInputVersion, FileStream->IsByteOrderNative);
2184 if (IsOk)
2185 IVersion = ROUNDS(FInputVersion * 10);
2189 if (IsOk)
2190 return (IVersion);
2191 else
2192 return ((short)0);
2195 #if defined TECPLOTKERNEL
2196 /* CORE SOURCE CODE REMOVED */
2197 #if !defined ENGINE /* TODO(RMS)-H 12/12/2005: ENGINE: refactor to use just the Interrupted flag as-is */
2198 #else
2199 #endif
2200 #endif
2204 /**********************************************************************
2205 **********************************************************************
2206 ********************** OUTPUT **************************
2207 **********************************************************************
2208 **********************************************************************/
2212 * Byte blocks cannot be unaligned or reversed in bytes
2214 Boolean_t WriteBinaryByteBlock(FileStream_s *FileStream,
2215 const Byte_t *ByteValues,
2216 const HgIndex_t NumValues)
2218 REQUIRE(VALID_REF(FileStream) && VALID_REF(FileStream->File));
2219 REQUIRE(VALID_REF(ByteValues));
2220 REQUIRE(NumValues >= 0);
2222 Boolean_t IsOk = TP_FWRITE(ByteValues,
2223 sizeof(Byte_t),
2224 (size_t)NumValues,
2225 FileStream->File) == (size_t)NumValues;
2227 ENSURE(VALID_BOOLEAN(IsOk));
2228 return IsOk;
2232 * Type Byte_t cannot be unaligned or reversed in byte order
2234 static inline Boolean_t WriteBinaryByte(FileStream_s *FileStream,
2235 Byte_t ByteValue)
2237 REQUIRE(VALID_REF(FileStream) && VALID_REF(FileStream->File));
2238 Boolean_t IsOk = WriteBinaryByteBlock(FileStream, &ByteValue, 1);
2239 ENSURE(VALID_BOOLEAN(IsOk));
2240 return IsOk;
2245 template <typename T>
2246 void CopyAndReverseUnalignedBytes(T *DstBuffer,
2247 const Byte_t *SrcBuffer)
2249 REQUIRE(VALID_REF(DstBuffer));
2250 REQUIRE(VALID_REF(SrcBuffer));
2251 size_t typeSize = sizeof(T);
2252 for (size_t ii = 0; ii < typeSize; ii++)
2253 ((Byte_t *)(DstBuffer))[ii] = ((Byte_t *)(SrcBuffer))[typeSize-1-ii];
2258 template <typename T>
2259 void CopyUnalignedBytes(T *DstBuffer,
2260 const Byte_t *SrcBuffer)
2262 REQUIRE(VALID_REF(DstBuffer));
2263 REQUIRE(VALID_REF(SrcBuffer));
2264 for (size_t ii = 0; ii < sizeof(T); ii++)
2265 ((Byte_t *)(DstBuffer))[ii] = ((Byte_t *)(SrcBuffer))[ii];
2270 template <typename T>
2271 Boolean_t WriteBinaryDataUnaligned(FileStream_s *FileStream,
2272 const Byte_t *ValueBuffer,
2273 const Boolean_t ValueInNativeOrder)
2275 REQUIRE(VALID_REF(FileStream) && VALID_FILE_HANDLE(FileStream->File));
2276 REQUIRE(VALID_REF(ValueBuffer));
2277 REQUIRE(VALID_BOOLEAN(ValueInNativeOrder));
2279 T DataValue;
2280 if (ValueInNativeOrder != FileStream->IsByteOrderNative)
2281 CopyAndReverseUnalignedBytes<T>(&DataValue, ValueBuffer);
2282 else
2283 CopyUnalignedBytes<T>(&DataValue, ValueBuffer);
2285 Boolean_t IsOk = TP_FWRITE(&DataValue, sizeof(T), 1, FileStream->File) == 1;
2287 ENSURE(VALID_BOOLEAN(IsOk));
2288 return IsOk;
2293 * This is used in many places and requires the value be in proper order.
2295 Boolean_t WriteBinaryInt16(FileStream_s *FileStream,
2296 Int16_t Value)
2298 Boolean_t IsOk;
2299 REQUIRE(VALID_REF(FileStream) && VALID_REF(FileStream->File));
2300 REQUIRE("Value can be any Int16_t");
2301 IsOk = WriteBinaryDataUnaligned<Int16_t>(FileStream, (Byte_t *) & Value, TRUE/*ValueInNativeOrder*/);
2302 ENSURE(VALID_BOOLEAN(IsOk));
2303 return IsOk;
2307 * This is used in many places and requires the value be in proper order.
2309 Boolean_t WriteBinaryInt32(FileStream_s *FileStream,
2310 Int32_t Value)
2312 Boolean_t IsOk;
2313 REQUIRE(VALID_REF(FileStream) && VALID_REF(FileStream->File));
2314 REQUIRE("Value can be any Int32_t");
2315 IsOk = WriteBinaryDataUnaligned<Int32_t>(FileStream, (Byte_t *) & Value, TRUE/*ValueInNativeOrder*/);
2316 ENSURE(VALID_BOOLEAN(IsOk));
2317 return IsOk;
2322 template <typename T>
2323 Boolean_t WriteBinaryBlockUnaligned(FileStream_s *FileStream,
2324 const Byte_t *Values,
2325 const HgIndex_t NumValues,
2326 const Boolean_t ValuesInNativeOrdering)
2328 Boolean_t IsOk = TRUE;
2329 Boolean_t WriteEachValueSeparately;
2331 REQUIRE(VALID_REF(FileStream) && VALID_REF(FileStream->File));
2332 REQUIRE(VALID_REF(Values));
2333 REQUIRE(NumValues >= 0);
2334 REQUIRE(VALID_BOOLEAN(ValuesInNativeOrdering));
2336 WriteEachValueSeparately = (ValuesInNativeOrdering != FileStream->IsByteOrderNative);
2338 if (WriteEachValueSeparately)
2340 for (HgIndex_t NIndex = 0; IsOk && NIndex < NumValues; NIndex++)
2342 IsOk = WriteBinaryDataUnaligned<T>(FileStream, Values + NIndex * sizeof(T), ValuesInNativeOrdering);
2345 else
2347 #if 1
2348 size_t NumBytesToWrite = NumValues * sizeof(T);
2349 size_t NumBytesWritten = TP_FWRITE(Values, sizeof(Byte_t), NumBytesToWrite, FileStream->File);
2350 IsOk = NumBytesToWrite == NumBytesWritten;
2351 #else
2352 IsOk = WriteBinaryByteBlock(FileStream, Values, NumValues * sizeof(T));
2353 #endif
2356 ENSURE(VALID_BOOLEAN(IsOk));
2357 return IsOk;
2362 * Use Byte_t instead of Int16_t to support unaligned values
2364 Boolean_t WriteBinaryInt16BlockUnaligned(FileStream_s *FileStream,
2365 Byte_t *Int16Values,
2366 HgIndex_t NumValues,
2367 Boolean_t ValuesInNativeOrdering)
2369 REQUIRE(VALID_REF(FileStream) && VALID_REF(FileStream->File));
2370 REQUIRE(VALID_REF(Int16Values));
2371 REQUIRE(NumValues >= 0);
2372 REQUIRE(VALID_BOOLEAN(ValuesInNativeOrdering));
2374 Boolean_t IsOk = WriteBinaryBlockUnaligned<Int16_t>(FileStream,
2375 Int16Values,
2376 NumValues,
2377 ValuesInNativeOrdering);
2378 ENSURE(VALID_BOOLEAN(IsOk));
2379 return IsOk;
2384 * Use Byte_t instead of Int32_t to support unaligned values
2386 Boolean_t WriteBinaryInt32BlockUnaligned(FileStream_s *FileStream,
2387 Byte_t *Int32Values,
2388 HgIndex_t NumValues,
2389 Boolean_t ValuesInNativeOrdering)
2391 REQUIRE(VALID_REF(FileStream) && VALID_REF(FileStream->File));
2392 REQUIRE(VALID_REF(Int32Values));
2393 REQUIRE(NumValues >= 0);
2394 REQUIRE(VALID_BOOLEAN(ValuesInNativeOrdering));
2396 Boolean_t IsOk = WriteBinaryBlockUnaligned<Int32_t>(FileStream,
2397 Int32Values,
2398 NumValues,
2399 ValuesInNativeOrdering);
2400 ENSURE(VALID_BOOLEAN(IsOk));
2401 return IsOk;
2408 Boolean_t WriteBinaryReal(FileStream_s *FileStream,
2409 double RR,
2410 FieldDataType_e FieldDataType)
2412 Boolean_t IsOk = FALSE; /* ...quite compiler */
2414 REQUIRE(VALID_REF(FileStream) && VALID_REF(FileStream->File));
2415 REQUIRE((FieldDataType == FieldDataType_Float) ||
2416 (FieldDataType == FieldDataType_Double) ||
2417 (FieldDataType == FieldDataType_Byte));
2419 switch (FieldDataType)
2421 case FieldDataType_Float :
2423 float FloatVal = CONVERT_DOUBLE_TO_FLOAT(RR);
2424 IsOk = WriteBinaryDataUnaligned<float>(FileStream, (Byte_t *) & FloatVal, TRUE/*NativeOrdering*/);
2425 } break;
2426 case FieldDataType_Double :
2428 double DoubleVal = CLAMP_DOUBLE(RR);
2429 IsOk = WriteBinaryDataUnaligned<double>(FileStream, (Byte_t *) & DoubleVal, TRUE/*NativeOrdering*/);
2430 } break;
2431 case FieldDataType_Byte :
2433 /* Note: type Byte cannot be unaligned or reversed in bytes */
2434 Byte_t B;
2435 if (RR > 255)
2436 B = 255;
2437 else if (RR < 0)
2438 B = 0;
2439 else
2440 B = (Byte_t)RR;
2441 IsOk = WriteBinaryByte(FileStream, B);
2442 } break;
2443 default: CHECK(FALSE); break;
2446 ENSURE(VALID_BOOLEAN(IsOk));
2447 return IsOk;
2451 Boolean_t WriteFieldDataType(FileStream_s *FileStream,
2452 FieldDataType_e FDT,
2453 Boolean_t WriteBinary)
2455 if (WriteBinary)
2456 return (WriteBinaryInt32(FileStream, (LgIndex_t)FDT));
2457 else
2459 short S = 0;
2460 switch (FDT)
2462 case FieldDataType_Float : S = fprintf(FileStream->File, "SINGLE "); break;
2463 case FieldDataType_Double : S = fprintf(FileStream->File, "DOUBLE "); break;
2464 case FieldDataType_Int32 : S = fprintf(FileStream->File, "LONGINT "); break;
2465 case FieldDataType_Int16 : S = fprintf(FileStream->File, "SHORTINT "); break;
2466 case FieldDataType_Byte : S = fprintf(FileStream->File, "BYTE "); break;
2467 case FieldDataType_Bit : S = fprintf(FileStream->File, "BIT "); break;
2468 default: CHECK(FALSE);
2470 return (FPRINTFOK(S));
2476 template <typename T>
2477 Boolean_t WriteBinaryChecksumByteValues(FileStream_s *FileStream,
2478 const Byte_t *ByteValues,
2479 const HgIndex_t NumValues)
2481 REQUIRE(VALID_REF(FileStream) && VALID_FILE_HANDLE(FileStream->File));
2482 REQUIRE(VALID_REF(ByteValues));
2483 REQUIRE(NumValues >= 1);
2485 Boolean_t IsOk;
2486 if (NumValues == 1)
2487 IsOk = WriteBinaryDataUnaligned<T>(FileStream, ByteValues, TRUE);
2488 else
2489 IsOk = WriteBinaryBlockUnaligned<T>(FileStream, ByteValues, NumValues, TRUE);
2491 #if defined TECPLOTKERNEL
2492 /* CORE SOURCE CODE REMOVED */
2493 #endif
2494 ENSURE(VALID_BOOLEAN(IsOk));
2495 return IsOk;
2499 * For FieldData of Type Bit, use WriteBinaryFieldDataBlockOfTypeBit instead.
2501 template <typename T>
2502 Boolean_t WriteBinaryFieldDataBlockOfType(FileStream_s *FileStream,
2503 const FieldData_pa FieldData,
2504 const LgIndex_t StartOffset,
2505 const LgIndex_t NumValues)
2507 #if defined TECPLOTKERNEL
2508 /* CORE SOURCE CODE REMOVED */
2509 #endif
2511 Boolean_t IsOk = FALSE;
2512 if (IsFieldDataDirectAccessAllowed(FieldData))
2514 Byte_t *ByteArray = GetFieldDataBytePtr(FieldData) + StartOffset * sizeof(T);
2515 IsOk = WriteBinaryChecksumByteValues<T>(FileStream, ByteArray, (HgIndex_t)NumValues);
2517 else
2519 for (LgIndex_t Offset = StartOffset; Offset < NumValues; Offset++)
2521 T ValueBuffer = (T)GetFieldValue(FieldData, Offset);
2522 Byte_t *ByteValue = (Byte_t *) & ValueBuffer;
2523 IsOk = WriteBinaryChecksumByteValues<T>(FileStream, ByteValue, 1);
2526 ENSURE(VALID_BOOLEAN(IsOk));
2527 return IsOk;
2530 static Boolean_t WriteBinaryFieldDataBlockOfTypeBit(FileStream_s *FileStream,
2531 const FieldData_pa FieldData,
2532 const LgIndex_t StartOffset, /* Not used */
2533 const LgIndex_t NumValues)
2535 #if defined TECPLOTKERNEL
2536 /* CORE SOURCE CODE REMOVED */
2537 #endif
2539 Boolean_t IsOk = FALSE;
2540 size_t NumBytes = 1 + (NumValues - 1) / 8;
2541 if (IsFieldDataDirectAccessAllowed(FieldData))
2543 Byte_t *ByteArray = GetFieldDataBytePtr(FieldData);
2544 IsOk = WriteBinaryChecksumByteValues<Byte_t>(FileStream, ByteArray, (HgIndex_t)NumBytes);
2546 else
2548 // Bits are written out a Byte at a time and since we only come in here every 8th
2549 // bit, make sure to assemble a Byte value from the next 8 bits.
2550 for (LgIndex_t Offset = 0; Offset < NumValues; Offset += 8)
2552 Byte_t ValueBuffer = 0;
2553 for (int ii = 0; ii < 8; ii++)
2555 Byte_t CurBit = (Byte_t)GetFieldValue(FieldData, Offset + ii);
2556 ValueBuffer |= (CurBit << ii);
2558 IsOk = WriteBinaryChecksumByteValues<Byte_t>(FileStream, &ValueBuffer, 1);
2561 ENSURE(VALID_BOOLEAN(IsOk));
2562 return IsOk;
2567 Boolean_t WriteBinaryFieldDataBlock(FileStream_s *FileStream,
2568 FieldData_pa FieldData,
2569 LgIndex_t StartOffset,
2570 LgIndex_t NumValues)
2572 #if defined TECPLOTKERNEL
2573 /* CORE SOURCE CODE REMOVED */
2574 #endif
2576 Boolean_t IsOk = FALSE;
2577 switch (GetFieldDataType(FieldData))
2579 case FieldDataType_Float : IsOk = WriteBinaryFieldDataBlockOfType<float>(FileStream, FieldData, StartOffset, NumValues); break;
2580 case FieldDataType_Double : IsOk = WriteBinaryFieldDataBlockOfType<double>(FileStream, FieldData, StartOffset, NumValues); break;
2581 case FieldDataType_Int32 : IsOk = WriteBinaryFieldDataBlockOfType<Int32_t>(FileStream, FieldData, StartOffset, NumValues); break;
2582 case FieldDataType_Int16 : IsOk = WriteBinaryFieldDataBlockOfType<Int16_t>(FileStream, FieldData, StartOffset, NumValues); break;
2583 case FieldDataType_Byte : IsOk = WriteBinaryFieldDataBlockOfType<Byte_t>(FileStream, FieldData, StartOffset, NumValues); break;
2584 case FieldDataType_Bit : IsOk = WriteBinaryFieldDataBlockOfTypeBit(FileStream, FieldData, StartOffset, NumValues); break;
2585 default: CHECK(FALSE); break;
2588 ENSURE(VALID_BOOLEAN(IsOk));
2589 return IsOk;
2593 static Boolean_t WriteASCIIFieldDataValue(FileStream_s *FileStream,
2594 FieldData_pa FieldData,
2595 LgIndex_t Offset,
2596 SmInteger_t AsciiPrecision)
2598 Boolean_t IsOk = FALSE; /* ...quiet compiler */
2600 #if defined TECPLOTKERNEL
2601 /* CORE SOURCE CODE REMOVED */
2602 #endif
2604 double V = 0.0;
2605 char buffer[100*MAX_SIZEOFUTF8CHAR];
2606 char *AsciiValue = buffer;
2608 #ifdef TECPLOTKERNEL
2609 /* CORE SOURCE CODE REMOVED */
2610 #endif
2612 V = GetFieldValue(FieldData, Offset);
2614 switch (GetFieldDataType(FieldData))
2616 case FieldDataType_Float :
2617 case FieldDataType_Double :
2618 /*IsOk = FPRINTFOK(fprintf(FileStream->File," %.*E",(int)AsciiPrecision,V)); */
2619 sprintf(buffer, " %.*E", (int)AsciiPrecision, V);
2620 break;
2621 case FieldDataType_Int32 :
2622 /* IsOk = FPRINTFOK(fprintf(FileStream->File," %*d",(int)AsciiPrecision,ROUNDL(V))); */
2623 sprintf(buffer, " %*d", (int)AsciiPrecision, ROUNDL(V));
2624 break;
2625 case FieldDataType_Int16 :
2626 /* IsOk = FPRINTFOK(fprintf(FileStream->File," %6d",ROUND2(V))); */
2627 sprintf(buffer, " %6d", ROUND2(V));
2628 break;
2629 case FieldDataType_Byte :
2630 /* IsOk = FPRINTFOK(fprintf(FileStream->File," %3d",ROUNDS(V))); */
2631 sprintf(buffer, " %3d", ROUNDS(V));
2632 break;
2633 case FieldDataType_Bit :
2634 /* IsOk = FPRINTFOK(fprintf(FileStream->File," %c",((V == 0) ? '0' : '1'))); */
2635 sprintf(buffer, " %c", ((V == 0) ? '0' : '1'));
2636 break;
2637 default: CHECK(FALSE); break;
2639 IsOk = FPRINTFOK(fprintf(FileStream->File, buffer));
2640 #if defined TECPLOTKERNEL
2641 /* CORE SOURCE CODE REMOVED */
2642 #endif
2643 ENSURE(VALID_BOOLEAN(IsOk));
2644 return (IsOk);
2650 Boolean_t WriteCCFieldDataBlock(FileStream_s *FileStream,
2651 FieldData_pa FieldData,
2652 Boolean_t IsOrderedData,
2653 LgIndex_t NumIPts,
2654 LgIndex_t NumJPts,
2655 LgIndex_t NumKPts,
2656 Boolean_t WriteBinary,
2657 SmInteger_t AsciiPrecision)
2659 Boolean_t IsOk = TRUE;
2660 LgIndex_t NumValues;
2661 LgIndex_t I, J, K;
2662 LgIndex_t NumIJPts = -1;
2663 LgIndex_t IEnd = -1;
2664 LgIndex_t JEnd = -1;
2665 LgIndex_t KEnd = -1;
2666 Boolean_t IsLinear = -1;
2668 REQUIRE(VALID_REF(FileStream) && VALID_REF(FileStream->File));
2669 REQUIRE(VALID_REF(FieldData));
2670 REQUIRE(VALID_BOOLEAN(IsOrderedData));
2671 REQUIRE(NumIPts >= 0);
2672 REQUIRE(NumJPts >= 0);
2673 REQUIRE(NumKPts >= 0);
2674 REQUIRE(VALID_BOOLEAN(WriteBinary));
2675 REQUIRE(IMPLICATION(!WriteBinary, AsciiPrecision >= 0));
2678 * As of version 103 Tecplot writes binary data files so that ordered cell
2679 * centered field data includes the ghost cells. This makes it much easier
2680 * for Tecplot to map the data when reading by simply writing out
2681 * FieldData->NumValues. As of version 104 the ghost cells of the slowest
2682 * moving index are not included but that does effect the output as it is
2683 * still FieldData->NumValues.
2685 if (IsOrderedData && !WriteBinary)
2688 * Ordered ASCII output is always layed out using
2689 * DataValueStructure_Classic format.
2691 NumIJPts = NumIPts * NumJPts;
2692 IEnd = MAX(NumIPts - 1, 1);
2693 JEnd = MAX(NumJPts - 1, 1);
2694 KEnd = MAX(NumKPts - 1, 1);
2695 NumValues = (IEnd * JEnd * KEnd);
2696 IsLinear = ((NumJPts == 1 && NumKPts == 1) ||
2697 (NumIPts == 1 && NumKPts == 1) ||
2698 (NumIPts == 1 && NumJPts == 1));
2700 else
2702 NumValues = GetFieldDataNumValues(FieldData);
2705 if (WriteBinary)
2707 IsOk = WriteBinaryFieldDataBlock(FileStream, FieldData, 0, NumValues);
2709 else
2711 LgIndex_t NumValuesPerLine = 80 / (AsciiPrecision + 5);
2712 if (IsOrderedData && !IsLinear)
2714 LgIndex_t ValueIndex = 0;
2715 for (K = 0; K < KEnd && IsOk; K++)
2716 for (J = 0; J < JEnd && IsOk; J++)
2717 for (I = 0; I < IEnd && IsOk; I++)
2719 LgIndex_t CellIndex = I + (J * NumIPts) + (K * NumIJPts);
2720 IsOk = WriteASCIIFieldDataValue(FileStream,
2721 FieldData,
2722 CellIndex,
2723 AsciiPrecision);
2724 if ((ValueIndex + 1) % NumValuesPerLine == 0 || ValueIndex == NumValues - 1)
2725 IsOk = (fputc('\n', FileStream->File) != EOF);
2726 ValueIndex++;
2729 else
2731 for (I = 0; I < NumValues && IsOk; I++)
2733 IsOk = WriteASCIIFieldDataValue(FileStream,
2734 FieldData,
2736 AsciiPrecision);
2737 if ((I + 1) % NumValuesPerLine == 0 || I == NumValues - 1)
2738 IsOk = (fputc('\n', FileStream->File) != EOF);
2743 ENSURE(VALID_BOOLEAN(IsOk));
2744 return IsOk;
2748 Boolean_t DumpDatafileString(FileStream_s *FileStream,
2749 const char *S,
2750 Boolean_t WriteBinary)
2752 Boolean_t IsOk = TRUE;
2753 const char *CPtr = S;
2754 if (WriteBinary)
2756 const char *CPtr = S;
2757 while (IsOk && CPtr && *CPtr)
2758 IsOk = WriteBinaryInt32(FileStream, (LgIndex_t)(unsigned char) * CPtr++);
2759 if (IsOk)
2760 IsOk = WriteBinaryInt32(FileStream, 0);
2762 else
2764 fputc('"', FileStream->File);
2765 while (CPtr && *CPtr)
2767 if (*CPtr == '\n')
2769 CPtr++;
2770 fputc('\\', FileStream->File);
2771 fputc('\\', FileStream->File);
2772 fputc('n', FileStream->File);
2774 else
2776 if ((*CPtr == '"') || (*CPtr == '\\'))
2777 fputc('\\', FileStream->File);
2778 fputc(*CPtr++, FileStream->File);
2781 fputc('"', FileStream->File);
2782 IsOk = (fputc('\n', FileStream->File) != EOF);
2784 return (IsOk);
2788 static void WriteAsciiColor(FILE *File,
2789 ColorIndex_t Color)
2791 if (Color >= FirstCustomColor && Color <= LastCustomColor)
2792 fprintf(File, "CUST%1d ", Color - FirstCustomColor + 1);
2793 else
2795 switch (Color)
2797 case Black_C : fprintf(File, "BLACK "); break;
2798 case Red_C : fprintf(File, "RED "); break;
2799 case Green_C : fprintf(File, "GREEN "); break;
2800 case Blue_C : fprintf(File, "BLUE "); break;
2801 case Cyan_C : fprintf(File, "CYAN "); break;
2802 case Yellow_C : fprintf(File, "YELLOW "); break;
2803 case Purple_C : fprintf(File, "PURPLE "); break;
2804 case White_C : fprintf(File, "WHITE "); break;
2809 static void WriteAsciiTextGeomBasics(FILE* File,
2810 CoordSys_e CoordSys,
2811 Boolean_t AttachToZone,
2812 EntIndex_t Zone,
2813 ColorIndex_t Color,
2814 Scope_e Scope,
2815 Boolean_t IncludeZ,
2816 Boolean_t WriteGridDataAsPolar,
2817 AnchorPos_u const* AnchorPos,
2818 double ScaleFact)
2820 REQUIRE(VALID_REF(File));
2821 REQUIRE(VALID_TEXT_COORDSYS(CoordSys) || VALID_GEOM_COORDSYS(CoordSys));
2822 REQUIRE(VALID_BOOLEAN(AttachToZone));
2823 REQUIRE(IMPLICATION(AttachToZone, Zone >= 0));
2824 REQUIRE(VALID_ENUM(Scope, Scope_e));
2825 REQUIRE(VALID_BOOLEAN(IncludeZ));
2826 REQUIRE(VALID_BOOLEAN(WriteGridDataAsPolar));
2827 REQUIRE(VALID_REF(AnchorPos));
2829 fprintf(File, "CS=");
2830 if (CoordSys == CoordSys_Frame)
2831 fprintf(File, "FRAME");
2832 else if (CoordSys == CoordSys_Grid)
2833 fprintf(File, "GRID");
2835 * Not currently used
2837 else if (CoordSys == CoordSys_FrameOffset)
2838 fprintf(File,"FRAMEOFFSET");
2840 else if (CoordSys == CoordSys_Grid3D)
2841 fprintf(File, "GRID3D");
2842 else
2843 CHECK(FALSE);
2845 if (CoordSys == CoordSys_Grid && !IncludeZ && WriteGridDataAsPolar)
2847 fprintf(File, "\nTHETA=%.12G,R=%.12G",
2848 ScaleFact*AnchorPos->ThetaR.Theta,
2849 ScaleFact*AnchorPos->ThetaR.R);
2850 CHECK(!IncludeZ);
2852 else
2854 fprintf(File, "\nX=%.12G,Y=%.12G",
2855 ScaleFact*AnchorPos->XYZ.X,
2856 ScaleFact*AnchorPos->XYZ.Y);
2857 if (IncludeZ)
2858 fprintf(File, ",Z=%.12G", ScaleFact*AnchorPos->XYZ.Z);
2861 if (AttachToZone)
2862 fprintf(File, "\nZN=%d", Zone + 1);
2864 fprintf(File, "\nC=");
2865 WriteAsciiColor(File, Color);
2867 fprintf(File, "\nS=");
2868 if (Scope == Scope_Global)
2869 fprintf(File, "GLOBAL");
2870 else if (Scope == Scope_Local)
2871 fprintf(File, "LOCAL");
2872 else
2873 CHECK(FALSE);
2875 fputc('\n', File);
2879 bool DumpGeometry(FileStream_s* FileStream,
2880 Geom_s const* Geom,
2881 Boolean_t WriteBinary,
2882 Boolean_t WriteGridDataAsPolar)
2884 LgIndex_t I, Index;
2885 LgIndex_t SegIndex;
2886 bool IsOk = TRUE;
2887 FieldDataType_e FDT;
2889 REQUIRE(VALID_REF(FileStream) && VALID_REF(FileStream->File));
2890 REQUIRE(VALID_REF(Geom));
2891 REQUIRE(Geom->GeomType != GeomType_Image);
2893 if (WriteBinary)
2895 WriteBinaryReal(FileStream, GeomMarker, FieldDataType_Float);
2896 if (Geom->PositionCoordSys == CoordSys_Grid)
2897 WriteBinaryInt32(FileStream, 0);
2898 else if (Geom->PositionCoordSys == CoordSys_Frame)
2899 WriteBinaryInt32(FileStream, 1);
2900 #if 0 /*
2901 * Not currently used
2903 else if (Geom->PositionCoordSys == CoordSys_FrameOffset)
2904 WriteBinaryInt32(FileStream, 2);
2905 #endif
2907 * PositionCoordSys == 3 is for old window coordinate system
2909 else if (Geom->PositionCoordSys == CoordSys_Grid3D)
2910 WriteBinaryInt32(FileStream, 4);
2911 else
2912 CHECK(FALSE);
2914 WriteBinaryInt32(FileStream, (LgIndex_t)Geom->Scope);
2915 WriteBinaryInt32(FileStream, (LgIndex_t)Geom->DrawOrder);
2916 WriteBinaryReal(FileStream, Geom->AnchorPos.Generic.V1, FieldDataType_Double);
2917 WriteBinaryReal(FileStream, Geom->AnchorPos.Generic.V2, FieldDataType_Double);
2918 WriteBinaryReal(FileStream, Geom->AnchorPos.Generic.V3, FieldDataType_Double);
2919 if (Geom->AttachToZone)
2920 WriteBinaryInt32(FileStream, (LgIndex_t)Geom->Zone);
2921 else
2922 WriteBinaryInt32(FileStream, (LgIndex_t) - 1);
2923 WriteBinaryInt32(FileStream, (LgIndex_t)Geom->BColor);
2924 WriteBinaryInt32(FileStream, (LgIndex_t)Geom->FillBColor);
2925 WriteBinaryInt32(FileStream, (LgIndex_t)Geom->IsFilled);
2926 CHECK(Geom->GeomType != GeomType_LineSegs3D); /* deprecated */
2927 WriteBinaryInt32(FileStream, (LgIndex_t)Geom->GeomType);
2928 WriteBinaryInt32(FileStream, (LgIndex_t)Geom->LinePattern);
2929 WriteBinaryReal(FileStream, Geom->PatternLength, FieldDataType_Double);
2930 WriteBinaryReal(FileStream, Geom->LineThickness, FieldDataType_Double);
2931 WriteBinaryInt32(FileStream, (LgIndex_t)Geom->NumEllipsePts);
2932 WriteBinaryInt32(FileStream, (LgIndex_t)Geom->ArrowheadStyle);
2933 WriteBinaryInt32(FileStream, (LgIndex_t)Geom->ArrowheadAttachment);
2934 WriteBinaryReal(FileStream, Geom->ArrowheadSize, FieldDataType_Double);
2936 WriteBinaryReal(FileStream, Geom->ArrowheadAngle, FieldDataType_Double);
2938 /* MACRO FUNCTION COMMAND */
2939 DumpDatafileString(FileStream, Geom->MacroFunctionCommand, TRUE);
2942 * Assume geometry has X,Y (and Z) all using same field
2943 * data type.
2945 FDT = GetGeomFieldDataType(Geom);
2946 WriteFieldDataType(FileStream, FDT, TRUE);
2947 WriteBinaryInt32(FileStream, (LgIndex_t)Geom->Clipping);
2949 if (Geom->GeomType == GeomType_LineSegs)
2951 short S;
2952 WriteBinaryInt32(FileStream, Geom->NumSegments);
2953 I = 0;
2954 for (S = 0; IsOk && (S < Geom->NumSegments); S++)
2956 WriteBinaryInt32(FileStream, Geom->NumSegPts[S]);
2957 WriteBinaryFieldDataBlock(FileStream, Geom->GeomData.Generic.V1Base, I, Geom->NumSegPts[S]);
2958 IsOk = WriteBinaryFieldDataBlock(FileStream, Geom->GeomData.Generic.V2Base, I, Geom->NumSegPts[S]) == TRUE;
2959 if (Geom->PositionCoordSys == CoordSys_Grid3D)
2960 IsOk = WriteBinaryFieldDataBlock(FileStream, Geom->GeomData.Generic.V3Base, I, Geom->NumSegPts[S]) == TRUE;
2961 I += Geom->NumSegPts[S];
2964 else if (Geom->GeomType == GeomType_Rectangle ||
2965 Geom->GeomType == GeomType_Ellipse)
2967 WriteBinaryReal(FileStream, GetFieldValue(Geom->GeomData.XYZ.XBase, 0), FDT);
2968 IsOk = WriteBinaryReal(FileStream, GetFieldValue(Geom->GeomData.XYZ.YBase, 0), FDT) == TRUE;
2970 else
2972 CHECK((Geom->GeomType == GeomType_Square) ||
2973 (Geom->GeomType == GeomType_Circle));
2974 IsOk = WriteBinaryReal(FileStream, GetFieldValue(Geom->GeomData.XYZ.XBase, 0), FDT) == TRUE;
2978 else
2980 double ScaleFact;
2981 if (Geom->PositionCoordSys == CoordSys_Frame)
2982 ScaleFact = 100.0;
2983 else
2984 ScaleFact = 1.0;
2986 fprintf(FileStream->File, "GEOMETRY\nF=POINT\n");
2987 WriteAsciiTextGeomBasics(FileStream->File,
2988 Geom->PositionCoordSys,
2989 Geom->AttachToZone,
2990 Geom->Zone,
2991 Geom->BColor,
2992 Geom->Scope,
2993 TRUE,
2994 WriteGridDataAsPolar,
2995 &Geom->AnchorPos,
2996 ScaleFact);
2998 switch (Geom->LinePattern)
3000 case LinePattern_Solid : fprintf(FileStream->File, "L=SOLID\n"); break;
3001 case LinePattern_Dashed : fprintf(FileStream->File, "L=DASHED\n"); break;
3002 case LinePattern_DashDot : fprintf(FileStream->File, "L=DASHDOT\n"); break;
3003 case LinePattern_Dotted : fprintf(FileStream->File, "L=DOTTED\n"); break;
3004 case LinePattern_LongDash : fprintf(FileStream->File, "L=LONGDASH\n"); break;
3005 case LinePattern_DashDotDot : fprintf(FileStream->File, "L=DASHDOTDOT\n"); break;
3006 default: CHECK(FALSE); break;
3008 fprintf(FileStream->File, "PL=%.12G\n",
3009 Geom->PatternLength*PatternLengthInputSpec.InterfaceAdjust.ScaleFact);
3010 fprintf(FileStream->File, "LT=%.12G\n",
3011 Geom->LineThickness*LineThicknessInputSpec.InterfaceAdjust.ScaleFact);
3013 if (Geom->IsFilled)
3015 fprintf(FileStream->File, "FC=");
3016 WriteAsciiColor(FileStream->File, Geom->FillBColor);
3019 if (Geom->Clipping == Clipping_ClipToViewport)
3020 fprintf(FileStream->File, "CLIPPING=CLIPTOVIEWPORT\n");
3021 else if (Geom->Clipping == Clipping_ClipToFrame)
3022 fprintf(FileStream->File, "CLIPPING=CLIPTOFRAME\n");
3023 else
3024 CHECK(FALSE);
3026 if (Geom->DrawOrder == DrawOrder_AfterData)
3027 fprintf(FileStream->File, "DRAWORDER=AFTERDATA\n");
3028 else if (Geom->DrawOrder == DrawOrder_BeforeData)
3029 fprintf(FileStream->File, "DRAWORDER=BEFOREDATA\n");
3030 else
3031 CHECK(FALSE);
3033 /* Macro function command */
3034 fprintf(FileStream->File, "MFC=");
3035 DumpDatafileString(FileStream, Geom->MacroFunctionCommand, FALSE);
3037 if ((Geom->GeomType == GeomType_Circle) || (Geom->GeomType == GeomType_Ellipse))
3038 fprintf(FileStream->File, "EP=%ld\n", (long)Geom->NumEllipsePts);
3040 if (Geom->GeomType == GeomType_LineSegs && Geom->PositionCoordSys != CoordSys_Grid3D)
3042 switch (Geom->ArrowheadStyle)
3044 case ArrowheadStyle_Plain : fprintf(FileStream->File, "AST=PLAIN\n"); break;
3045 case ArrowheadStyle_Filled : fprintf(FileStream->File, "AST=FILLED\n"); break;
3046 case ArrowheadStyle_Hollow : fprintf(FileStream->File, "AST=HOLLOW\n"); break;
3047 default: CHECK(FALSE); break;
3050 switch (Geom->ArrowheadAttachment)
3052 case ArrowheadAttachment_None : break;
3053 case ArrowheadAttachment_AtBeginning : fprintf(FileStream->File, "AAT=BEGINNING\n"); break;
3054 case ArrowheadAttachment_AtEnd : fprintf(FileStream->File, "AAT=END\n"); break;
3055 case ArrowheadAttachment_AtBothEnds : fprintf(FileStream->File, "AAT=BOTH\n"); break;
3056 default: CHECK(FALSE); break;
3058 if (Geom->ArrowheadAttachment != ArrowheadAttachment_None)
3060 fprintf(FileStream->File, "ASZ=%.12G\n",
3061 Geom->ArrowheadSize*ArrowheadSizeInputSpec.InterfaceAdjust.ScaleFact);
3062 fprintf(FileStream->File, "AAN=%.12G\n",
3063 Geom->ArrowheadAngle*ArrowheadAngleInputSpec.InterfaceAdjust.ScaleFact);
3067 switch (Geom->GeomType)
3069 case GeomType_LineSegs :
3071 fprintf(FileStream->File, "T=LINE\n");
3072 fprintf(FileStream->File, "DT=");
3073 WriteFieldDataType(FileStream, GetFieldDataType(Geom->GeomData.Generic.V1Base), FALSE);
3074 fputc('\n', FileStream->File);
3075 fprintf(FileStream->File, "%d\n", (int)Geom->NumSegments);
3076 SegIndex = 0;
3077 for (I = 0; IsOk && (I < Geom->NumSegments); I++)
3079 fprintf(FileStream->File, "%ld\n", (long)Geom->NumSegPts[I]);
3080 for (Index = 0; Index < Geom->NumSegPts[I]; Index++)
3082 fprintf(FileStream->File, "%.12G ", GetFieldValue(Geom->GeomData.Generic.V1Base, SegIndex + Index)*ScaleFact);
3083 fprintf(FileStream->File, "%.12G", GetFieldValue(Geom->GeomData.Generic.V2Base, SegIndex + Index)*ScaleFact);
3084 if (Geom->PositionCoordSys == CoordSys_Grid3D)
3085 IsOk = FPRINTFOK(fprintf(FileStream->File, " %.12G\n", GetFieldValue(Geom->GeomData.Generic.V3Base, SegIndex + Index)));
3086 else
3087 IsOk = (Boolean_t)(fputc('\n', FileStream->File) != EOF);
3089 SegIndex += Geom->NumSegPts[I];
3091 } break;
3092 case GeomType_Rectangle :
3094 fprintf(FileStream->File, "T=RECTANGLE %.12G %.12G\n",
3095 GetFieldValue(Geom->GeomData.XYZ.XBase, 0)*ScaleFact,
3096 GetFieldValue(Geom->GeomData.XYZ.YBase, 0)*ScaleFact);
3097 } break;
3098 case GeomType_Square :
3100 fprintf(FileStream->File, "T=SQUARE %.12G\n",
3101 GetFieldValue(Geom->GeomData.XYZ.XBase, 0)*ScaleFact);
3102 } break;
3103 case GeomType_Circle :
3105 fprintf(FileStream->File, "T=CIRCLE %.12G\n",
3106 GetFieldValue(Geom->GeomData.XYZ.XBase, 0)*ScaleFact);
3107 } break;
3108 case GeomType_Ellipse :
3110 fprintf(FileStream->File, "T=ELLIPSE %.12G %.12G\n",
3111 GetFieldValue(Geom->GeomData.XYZ.XBase, 0)*ScaleFact,
3112 GetFieldValue(Geom->GeomData.XYZ.YBase, 0)*ScaleFact);
3113 } break;
3114 default: CHECK(FALSE);
3117 return IsOk;
3122 bool DumpText(FileStream_s* FileStream,
3123 Text_s const* Text,
3124 Boolean_t WriteBinary,
3125 Boolean_t WriteGridDataAsPolar)
3127 REQUIRE(VALID_REF(FileStream) && VALID_REF(FileStream->File));
3128 REQUIRE(VALID_REF(Text));
3129 REQUIRE(VALID_BOOLEAN(WriteBinary));
3130 REQUIRE(VALID_BOOLEAN(WriteGridDataAsPolar));
3132 if (WriteBinary)
3134 WriteBinaryReal(FileStream, TextMarker, FieldDataType_Float);
3135 if (Text->PositionCoordSys == CoordSys_Grid)
3136 WriteBinaryInt32(FileStream, 0);
3137 else if (Text->PositionCoordSys == CoordSys_Frame)
3138 WriteBinaryInt32(FileStream, 1);
3139 #if 0 /*
3140 * Not currently used
3142 else if (Geom->PositionCoordSys == CoordSys_FrameOffset)
3143 WriteBinaryInt32(FileStream, 2);
3144 #endif
3146 * 3 is used for old window coordinate system
3148 else if (Text->PositionCoordSys == CoordSys_Grid3D)
3149 WriteBinaryInt32(FileStream, 4);
3150 else
3151 CHECK(FALSE);
3153 WriteBinaryInt32(FileStream, (LgIndex_t)Text->Scope);
3154 WriteBinaryReal(FileStream, Text->AnchorPos.Generic.V1, FieldDataType_Double);
3155 WriteBinaryReal(FileStream, Text->AnchorPos.Generic.V2, FieldDataType_Double);
3156 WriteBinaryReal(FileStream, Text->AnchorPos.Generic.V3, FieldDataType_Double);
3157 WriteBinaryInt32(FileStream, (LgIndex_t)Text->TextShape.Font);
3158 WriteBinaryInt32(FileStream, (LgIndex_t)Text->TextShape.SizeUnits);
3159 WriteBinaryReal(FileStream, Text->TextShape.Height, FieldDataType_Double);
3160 WriteBinaryInt32(FileStream, (LgIndex_t)Text->Box.BoxType);
3161 WriteBinaryReal(FileStream, Text->Box.Margin, FieldDataType_Double);
3162 WriteBinaryReal(FileStream, Text->Box.LineThickness, FieldDataType_Double);
3163 WriteBinaryInt32(FileStream, (LgIndex_t)Text->Box.BColor);
3164 WriteBinaryInt32(FileStream, (LgIndex_t)Text->Box.FillBColor);
3165 WriteBinaryReal(FileStream, Text->Angle, FieldDataType_Double);
3166 WriteBinaryReal(FileStream, Text->LineSpacing, FieldDataType_Double);
3167 WriteBinaryInt32(FileStream, (LgIndex_t)Text->Anchor);
3168 if (Text->AttachToZone)
3169 WriteBinaryInt32(FileStream, (LgIndex_t)Text->Zone);
3170 else
3171 WriteBinaryInt32(FileStream, (LgIndex_t) - 1);
3172 WriteBinaryInt32(FileStream, (LgIndex_t)Text->BColor);
3174 else
3176 double ScaleFact;
3177 Boolean_t IncludeZ = Text->PositionCoordSys == CoordSys_Grid3D;
3178 if (Text->PositionCoordSys == CoordSys_Frame)
3179 ScaleFact = 100.0;
3180 else
3181 ScaleFact = 1.0;
3182 fprintf(FileStream->File, "TEXT\n");
3183 WriteAsciiTextGeomBasics(FileStream->File,
3184 Text->PositionCoordSys,
3185 Text->AttachToZone,
3186 Text->Zone,
3187 Text->BColor,
3188 Text->Scope,
3189 IncludeZ,
3190 WriteGridDataAsPolar,
3191 &Text->AnchorPos,
3192 ScaleFact);
3193 fprintf(FileStream->File, "HU=");
3194 switch (Text->TextShape.SizeUnits)
3196 case Units_Grid : fprintf(FileStream->File, "GRID\n"); break;
3197 case Units_Frame : fprintf(FileStream->File, "FRAME\n"); break;
3198 case Units_Point : fprintf(FileStream->File, "POINT\n"); break;
3199 case Units_AxisPercentage : /* Not allowed */
3200 default: CHECK(FALSE); break;
3203 fprintf(FileStream->File, "LS=%.4G ", Text->LineSpacing);
3205 fprintf(FileStream->File, "AN=");
3206 switch (Text->Anchor)
3208 case TextAnchor_Left : fprintf(FileStream->File, "LEFT\n"); break;
3209 case TextAnchor_Center : fprintf(FileStream->File, "CENTER\n"); break;
3210 case TextAnchor_Right : fprintf(FileStream->File, "RIGHT\n"); break;
3211 case TextAnchor_MidLeft : fprintf(FileStream->File, "MIDLEFT\n"); break;
3212 case TextAnchor_MidCenter : fprintf(FileStream->File, "MIDCENTER\n"); break;
3213 case TextAnchor_MidRight : fprintf(FileStream->File, "MIDRIGHT\n"); break;
3214 case TextAnchor_HeadLeft : fprintf(FileStream->File, "HEADLEFT\n"); break;
3215 case TextAnchor_HeadCenter : fprintf(FileStream->File, "HEADCENTER\n"); break;
3216 case TextAnchor_HeadRight : fprintf(FileStream->File, "HEADRIGHT\n"); break;
3217 default: CHECK(FALSE); break;
3220 switch (Text->Box.BoxType)
3222 case TextBox_Hollow : fprintf(FileStream->File, "BX=Hollow "); break;
3223 case TextBox_Filled : fprintf(FileStream->File, "BX=Filled "); break;
3224 default :;
3226 fprintf(FileStream->File, "BXM=%.4G ", Text->Box.Margin*100);
3227 fprintf(FileStream->File, "LT=%.4G ", Text->Box.LineThickness*100.0);
3228 fprintf(FileStream->File, "BXO="); WriteAsciiColor(FileStream->File, Text->Box.BColor);
3229 fprintf(FileStream->File, "BXF="); WriteAsciiColor(FileStream->File, Text->Box.FillBColor);
3231 fprintf(FileStream->File, "\nF=");
3232 switch (Text->TextShape.Font)
3234 case Font_Helvetica : fprintf(FileStream->File, "HELV"); break;
3235 case Font_HelveticaBold : fprintf(FileStream->File, "HELV-BOLD"); break;
3236 case Font_Times : fprintf(FileStream->File, "TIMES"); break;
3237 case Font_TimesBold: fprintf(FileStream->File, "TIMES-BOLD"); break;
3238 case Font_TimesItalic : fprintf(FileStream->File, "TIMES-ITALIC"); break;
3239 case Font_TimesItalicBold : fprintf(FileStream->File, "TIMES-ITALIC-BOLD"); break;
3240 case Font_Courier : fprintf(FileStream->File, "COURIER"); break;
3241 case Font_CourierBold : fprintf(FileStream->File, "COURIER-BOLD"); break;
3242 case Font_Greek : fprintf(FileStream->File, "GREEK"); break;
3243 case Font_Math : fprintf(FileStream->File, "MATH"); break;
3244 case Font_UserDefined : fprintf(FileStream->File, "USER-DEF"); break;
3245 default: CHECK(FALSE); break;
3247 if (Text->TextShape.SizeUnits == Units_Frame)
3248 ScaleFact = 100.0;
3249 else
3250 ScaleFact = 1.0;
3251 fprintf(FileStream->File, "\nH=%.12G A=%.12G",
3252 Text->TextShape.Height*ScaleFact,
3253 Text->Angle*DEGPERRADIANS);
3257 if (!WriteBinary)
3258 fprintf(FileStream->File, "\nMFC=");
3260 DumpDatafileString(FileStream, Text->MacroFunctionCommand, WriteBinary);
3262 if (!WriteBinary)
3264 if (Text->Clipping == Clipping_ClipToViewport)
3265 fprintf(FileStream->File, "CLIPPING=CLIPTOVIEWPORT\n");
3266 else if (Text->Clipping == Clipping_ClipToFrame)
3267 fprintf(FileStream->File, "CLIPPING=CLIPTOFRAME\n");
3268 else
3269 CHECK(FALSE);
3271 else
3273 WriteBinaryInt32(FileStream, (LgIndex_t)Text->Clipping);
3276 if (!WriteBinary)
3277 fprintf(FileStream->File, "T=");
3279 return DumpDatafileString(FileStream, Text->Text, WriteBinary) == TRUE;
3282 Boolean_t DumpCustomAxisLabels(FileStream_s *FileStream,
3283 Boolean_t WriteBinary,
3284 StringList_pa LabelBase)
3286 Boolean_t IsOk = TRUE;
3287 LgIndex_t Index = 0;
3288 LgIndex_t Count = 0;
3290 REQUIRE(VALID_REF(FileStream) && VALID_REF(FileStream->File));
3291 REQUIRE(VALID_BOOLEAN(WriteBinary));
3292 REQUIRE(StringListValid(LabelBase));
3294 Count = StringListCount(LabelBase);
3295 if (WriteBinary)
3297 WriteBinaryReal(FileStream, CustomLabelMarker, FieldDataType_Float);
3298 WriteBinaryInt32(FileStream, Count);
3300 else
3302 fprintf(FileStream->File, " CUSTOMLABELS = \n");
3305 for (Index = 0, IsOk = TRUE; Index < Count && IsOk; Index++)
3307 const char *CurLabel = StringListGetStringRef(LabelBase, Index);
3308 IsOk = DumpDatafileString(FileStream, CurLabel, WriteBinary);
3311 ENSURE(VALID_BOOLEAN(IsOk));
3312 return IsOk;
3317 Boolean_t WriteBinaryMagic(FileStream_s *FileStream)
3320 * Write an integer value of 1 to the file. This is used
3321 * by the reader to determine byte order of the file.
3323 return (WriteBinaryInt32(FileStream, 1));
3328 bool writeBinaryVersionNumber(FileStream_s& fileStream,
3329 int versionNumber)
3331 char buffer[5];
3332 sprintf(buffer,
3333 "V%-3d",
3334 versionNumber);
3335 CHECK(strlen(buffer) == 4);
3336 return fprintf(fileStream.File,
3337 "#!TD%s",
3338 buffer) > 0;
3341 #if defined TECPLOTKERNEL
3342 /* CORE SOURCE CODE REMOVED */
3343 #if !defined SUN
3344 #else
3345 #endif
3346 #if !defined NO_ASSERTS
3347 #endif
3348 #if defined ALLOW_USERDEF_NO_NEIGHBORING_ELEMENT
3349 #else
3350 #endif
3351 #if 0 /* not used yet */
3352 #endif
3353 #if defined TECPLOTKERNEL
3354 #endif
3355 #if defined TECPLOTKERNEL
3356 #endif
3357 #endif