1 // Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
2 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License.
9 // This library is distributed in the hope that it will be useful
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 // File : SALOMEDS_Tool.cxx
21 // Created : Mon Oct 21 16:24:34 2002
22 // Author : Sergey RUIN
29 #include <OSD_Path.hxx>
30 #include <OSD_File.hxx>
31 #include <OSD_Protection.hxx>
32 #include <OSD_Directory.hxx>
33 #include <TCollection_AsciiString.hxx>
47 bool CreateAttributeFromASCII(HDFinternalObject *father, FILE* fp);
48 bool CreateDatasetFromASCII(HDFcontainerObject *father, FILE *fp);
49 bool CreateGroupFromASCII(HDFcontainerObject *father, FILE *fp);
51 void SaveAttributeInASCIIfile(HDFattribute *hdf_attribute, FILE* fp, int ident);
52 void SaveGroupInASCIIfile(HDFgroup *hdf_group, FILE* fp, int ident);
53 void SaveDatasetInASCIIfile(HDFdataset *hdf_dataset, FILE* fp, int ident);
56 char* makeName(char* name);
57 char* restoreName(char* name);
58 void write_float64(FILE* fp, hdf_float64* value);
59 void read_float64(FILE* fp, hdf_float64* value);
61 #define MAX_STRING_SIZE 65535
62 #define MAX_ID_SIZE 20
63 #define NB_FLOAT_IN_ROW 3
64 #define NB_INTEGER_IN_ROW 9
66 #define ASCIIHDF_ID "ASCIIHDF"
67 #define ATTRIBUTE_ID "ATTRIBUTE"
68 #define DATASET_ID "DATASET"
69 #define GROUP_ID "GROUP"
71 #define ASCIIHDF_ID_END "ASCIIHDF_END"
72 #define ATTRIBUTE_ID_END "ATTRIBUTE_END"
73 #define DATASET_ID_END "DATASET_END"
74 #define GROUP_ID_END "GROUP_END"
77 //============================================================================
79 // purpose : Returns True if the file is a converted to ASCII HDF file
80 //============================================================================
81 bool HDFascii::isASCII(const char* thePath) {
83 if(!(fd = open(thePath, O_RDONLY))) return false;
84 char* aBuffer = new char[9];
89 if(strcmp(aBuffer, ASCIIHDF_ID) == 0) return true;
94 //############################## HDF => ASCII ################################
96 //============================================================================
97 // function : ConvertFromHDFToASCII
98 // purpose : Converts a file pointed by thePath to ASCII format
99 // If isReplace is true the newly created file will replace the existent one.
100 // If isReplace is false theExtension will be added to a created file name
101 // Returns the file name of ASCII file
102 //============================================================================
103 char* HDFascii::ConvertFromHDFToASCII(const char* thePath,
105 const char* theExtension)
107 TCollection_AsciiString aPath((char*)thePath);
109 if(theExtension == NULL) aPath += ".asc";
110 else aPath += (char*)theExtension;
113 TCollection_AsciiString aFileName(aPath);
114 if(isReplace) aFileName=aPath+".ascii_tmp";
116 HDFfile *hdf_file = new HDFfile((char*)thePath);
117 hdf_file->OpenOnDisk(HDF_RDONLY);
119 char name[HDF_NAME_MAX_LEN+1];
120 int nbsons = hdf_file->nInternalObjects(), nbAttr = hdf_file->nAttributes();
122 FILE* fp = fopen(aFileName.ToCString(), "w");
123 fprintf(fp, "%s\n", ASCIIHDF_ID);
124 fprintf(fp, "%i\n", nbsons+nbAttr);
126 for(unsigned j=0; j<nbAttr; j++) {
127 char* attr_name = hdf_file->GetAttributeName(j);
128 HDFattribute *hdf_attribute = new HDFattribute(attr_name, hdf_file);
130 SaveAttributeInASCIIfile(hdf_attribute, fp, 0);
134 for (Standard_Integer i=0; i<nbsons; i++) {
135 hdf_file->InternalObjectIndentify(i,name);
136 if (strncmp(name, "INTERNAL_COMPLEX",16) == 0) continue;
138 hdf_object_type type = hdf_file->InternalObjectType(name);
140 if(type == HDF_DATASET) {
141 HDFdataset* hdf_dataset = new HDFdataset(name, hdf_file);
142 SaveDatasetInASCIIfile(hdf_dataset, fp, 0);
144 } else if(type == HDF_GROUP) {
145 HDFgroup *hdf_group = new HDFgroup(name, hdf_file);
146 SaveGroupInASCIIfile(hdf_group, fp, 0);
151 fprintf(fp, "%s", ASCIIHDF_ID_END);
155 hdf_file->CloseOnDisk();
159 OSD_Path anOSDPath(aFileName);
160 OSD_File anOSDFile(anOSDPath);
161 if(anOSDFile.Exists())
162 anOSDFile.Move(aPath);
167 int length = strlen(aPath.ToCString());
168 char *new_str = new char[ 1+length ];
169 strcpy(new_str , aPath.ToCString()) ;
175 //============================================================================
176 // function : SaveGroupInASCIIfile
178 //============================================================================
179 void SaveGroupInASCIIfile(HDFgroup *hdf_group, FILE* fp, int ident)
181 hdf_group->OpenOnDisk();
183 TCollection_AsciiString anIdent(ident, '\t');
184 int nbsons = hdf_group->nInternalObjects(), nbAttr = hdf_group->nAttributes();
186 /*fprintf(fp, "%s%s\n", anIdent.ToCString(), GROUP_ID);*/
187 fprintf(fp, "%s\n", GROUP_ID);
189 char* name = makeName(hdf_group->GetName());
191 /*fprintf(fp, "%s%s %i\n", anIdent.ToCString(), name, nbsons+nbAttr);*/
192 fprintf(fp, "%s %i\n", name, nbsons+nbAttr);
195 for(unsigned j=0; j<nbAttr; j++) {
196 name = hdf_group->GetAttributeName(j);
197 HDFattribute *hdf_attribute = new HDFattribute(name, hdf_group);
199 SaveAttributeInASCIIfile(hdf_attribute, fp, ident+1);
203 char objName[HDF_NAME_MAX_LEN+1];
205 for (int i=0; i<nbsons; i++) {
206 hdf_group->InternalObjectIndentify(i, objName);
208 if (strncmp(objName, "INTERNAL_COMPLEX",16) == 0) continue;
210 hdf_object_type type = hdf_group->InternalObjectType(objName);
212 if (type == HDF_DATASET) {
213 HDFdataset* hdf_dataset = new HDFdataset(objName, hdf_group);
214 SaveDatasetInASCIIfile(hdf_dataset, fp, ident+1);
216 } else if (type == HDF_GROUP) {
217 HDFgroup *hdf_subgroup = new HDFgroup(objName, hdf_group);
218 SaveGroupInASCIIfile(hdf_subgroup, fp, ident+1);
223 /*fprintf(fp, "%s%s\n", anIdent.ToCString(), GROUP_ID_END);*/
224 fprintf(fp, "%s\n", GROUP_ID_END);
226 hdf_group->CloseOnDisk();
229 //============================================================================
230 // function : SaveDatasetInASCIIfile
232 //============================================================================
233 void SaveDatasetInASCIIfile(HDFdataset *hdf_dataset, FILE* fp, int ident)
235 hdf_dataset->OpenOnDisk();
237 long size = hdf_dataset->GetSize();
238 long ndim = hdf_dataset->nDim(); //Get number of dimesions
239 hdf_size *dim = new hdf_size[ndim];
240 hdf_type type = hdf_dataset->GetType();
241 hdf_byte_order order = hdf_dataset->GetOrder();
242 int nbAttr = hdf_dataset->nAttributes();
244 TCollection_AsciiString anIdent(ident, '\t');
245 TCollection_AsciiString anIdentChild(ident+1, '\t');
247 char* name = makeName(hdf_dataset->GetName());
249 /*fprintf(fp, "%s%s\n", anIdent.ToCString(), DATASET_ID);*/
250 fprintf(fp, "%s\n", DATASET_ID);
251 /*fprintf(fp, "%s%s %i %i\n", anIdent.ToCString(), name, type, nbAttr);*/
252 fprintf(fp, "%s %i %i\n", name, type, nbAttr);
255 hdf_dataset->GetDim(dim);
256 /*fprintf(fp, "%s %i\n", anIdentChild.ToCString(), ndim);*/
257 fprintf(fp, " %i\n", ndim);
259 for(int i = 0;i < ndim;i++) {
260 /*fprintf(fp, "%s%i", anIdentChild.ToCString(), dim[i]);*/
261 fprintf(fp, " %i", dim[i]);
264 /*fprintf(fp, "%s\n", anIdentChild.ToCString());*/
268 /*fprintf(fp, "%s%li:", anIdentChild.ToCString(), size);*/
269 // fprintf(fp, "%li:", size);
270 fprintf(fp, "%li %i:", size, order);
272 if (type == HDF_STRING) {
273 char* val = new char[size];
274 hdf_dataset->ReadFromDisk(val);
275 fwrite(val, 1, size, fp);
277 } else if (type == HDF_FLOAT64) {
278 hdf_float64* val = new hdf_float64[size];
279 hdf_dataset->ReadFromDisk(val);
281 for (int i = 0, j = 0; i < size; i++) {
282 write_float64(fp, &val[i]);
283 if(++j == NB_FLOAT_IN_ROW) {
287 else fprintf(fp," ");
290 } else if(type == HDF_INT64) {
291 hdf_int64* val = new hdf_int64[size];
292 hdf_dataset->ReadFromDisk(val);
294 for (int i = 0, j = 0; i < size; i++) {
295 fprintf(fp, " %li", val[i]);
296 if(++j == NB_INTEGER_IN_ROW) {
302 } else if(type == HDF_INT32) {
303 hdf_int32* val = new hdf_int32[size];
304 hdf_dataset->ReadFromDisk(val);
306 for (int i = 0, j = 0; i < size; i++) {
307 fprintf(fp, " %i", val[i]);
308 if(++j == NB_INTEGER_IN_ROW) {
318 for ( unsigned j=0; j<nbAttr; j++ )
320 name = hdf_dataset->GetAttributeName(j);
321 HDFattribute *hdf_attribute = new HDFattribute(name, hdf_dataset);
323 SaveAttributeInASCIIfile(hdf_attribute, fp, ident+1);
327 /*fprintf(fp, "%s%s\n", anIdent.ToCString(), DATASET_ID_END); */
328 fprintf(fp, "%s\n", DATASET_ID_END);
330 hdf_dataset->CloseOnDisk();
334 //============================================================================
335 // function : SaveAttributeInASCIIfile
337 //============================================================================
338 void SaveAttributeInASCIIfile(HDFattribute *hdf_attribute, FILE* fp, int ident)
340 hdf_attribute->OpenOnDisk();
342 hdf_type type = hdf_attribute->GetType();
344 TCollection_AsciiString anIdent(ident, '\t');
345 TCollection_AsciiString anIdentChild(ident+1, '\t');
347 char* name = makeName(hdf_attribute->GetName());
348 int size = hdf_attribute->GetSize();
350 /*fprintf(fp, "%s%s\n", anIdent.ToCString(), ATTRIBUTE_ID);*/
351 fprintf(fp, "%s\n", ATTRIBUTE_ID);
352 /*fprintf(fp, "%s%s %i %i\n", anIdent.ToCString(), name, type, size);*/
353 fprintf(fp, "%s %i %i\n", name, type, size);
357 if (type == HDF_STRING) {
358 char* val = new char[size+1];
359 hdf_attribute->ReadFromDisk(val);
360 /*fprintf(fp, "%s:", anIdentChild.ToCString());*/
362 fwrite(val, 1, size, fp);
365 } else if (type == HDF_FLOAT64) {
367 hdf_attribute->ReadFromDisk(&val);
368 /*fprintf(fp, "%s", anIdentChild.ToCString());*/
369 write_float64(fp, &val);
371 } else if(type == HDF_INT64) {
373 hdf_attribute->ReadFromDisk(&val);
374 /*fprintf(fp, "%s%li \n", anIdentChild.ToCString(), val);*/
375 fprintf(fp, "%li \n", val);
376 } else if(type == HDF_INT32) {
378 hdf_attribute->ReadFromDisk(&val);
379 /*fprintf(fp, "%s%i \n", anIdentChild.ToCString(), val);*/
380 fprintf(fp, "%i \n", val);
383 /*fprintf(fp, "%s%s\n", anIdent.ToCString(), ATTRIBUTE_ID_END);*/
384 fprintf(fp, "%s\n", ATTRIBUTE_ID_END);
386 hdf_attribute->CloseOnDisk();
389 //############################## ASCII => HDF ################################
391 //============================================================================
392 // function : ConvertFromASCIIToHDF
393 // purpose : Converts a file pointed by thePath to HDF format
394 // Returns a name of directory where a created HDF file is placed
395 // The created file is named "hdf_from_ascii.hdf"
396 //============================================================================
397 char* HDFascii::ConvertFromASCIIToHDF(const char* thePath)
399 // Get a temporary directory to store a file
400 TCollection_AsciiString aTmpDir = GetTmpDir(), aFileName("hdf_from_ascii.hdf");
401 // Build a full file name of temporary file
402 TCollection_AsciiString aFullName = aTmpDir + aFileName;
404 HDFfile *hdf_file = new HDFfile(aFullName.ToCString());
405 hdf_file->CreateOnDisk();
407 FILE *fp = fopen(thePath, "r");
412 fscanf(fp, "%s", type);
413 fscanf(fp, "%i",&nbsons);
415 if(strcmp(type, ASCIIHDF_ID) != 0) return NULL;
417 for(i = 0; i < nbsons; i++) {
418 char id_of_begin[MAX_ID_SIZE];
419 fscanf(fp, "%s\n", id_of_begin);
421 if(strcmp(id_of_begin, GROUP_ID) == 0) {
422 if(!CreateGroupFromASCII(hdf_file, fp)) {
423 cout << "ConvertFromASCIIToHDF : Can not create group number " << i << endl;
427 else if(strcmp(id_of_begin, DATASET_ID) == 0) {
428 if(!CreateDatasetFromASCII(hdf_file, fp)) {
429 cout << "ConvertFromASCIIToHDF :Can not create dataset number " << i << endl;
433 else if(strcmp(id_of_begin, ATTRIBUTE_ID) == 0) {
434 if(!CreateAttributeFromASCII(hdf_file, fp)) {
435 cout << "ConvertFromASCIIToHDF :Can not create attribute number " << i << endl;
440 cout << "ConvertFromASCIIToHDF : Unrecognized type " << id_of_begin << endl;
443 char id_of_end[MAX_ID_SIZE];
444 fscanf(fp, "%s", id_of_end);
445 if(strcmp(id_of_end, ASCIIHDF_ID_END) != 0) {
446 cout << "ConvertFromASCIIToHDF : Can not find the end ASCII token " << endl;
450 hdf_file->CloseOnDisk();
453 int length = strlen(aTmpDir.ToCString());
454 char *new_str = new char[ 1+length ];
455 strcpy(new_str , aTmpDir.ToCString()) ;
461 //============================================================================
462 // function : CreateGroupFromASCII
463 // purpose : Creates a HDF group from a set attributes situated under theLabel
464 //============================================================================
465 bool CreateGroupFromASCII(HDFcontainerObject *father, FILE *fp)
467 char name[HDF_NAME_MAX_LEN+1];
469 fscanf(fp, "%s %i\n", name, &nbsons);
471 char* new_name = restoreName(name);
473 HDFgroup* hdf_group = new HDFgroup(new_name, father);
477 hdf_group->CreateOnDisk();
479 for(i = 0; i < nbsons; i++) {
480 char id_of_begin[MAX_ID_SIZE];
481 fscanf(fp, "%s\n", id_of_begin);
483 if(strcmp(id_of_begin, GROUP_ID) == 0) {
484 if(!CreateGroupFromASCII(hdf_group, fp)) {
485 cout << "Can not create subgroup " << i << " for group " << name << endl;
489 else if(strcmp(id_of_begin, DATASET_ID) == 0) {
490 if(!CreateDatasetFromASCII(hdf_group, fp)) {
491 cout << "Can not create dataset " << i << " for group " << name << endl;
495 else if(strcmp(id_of_begin, ATTRIBUTE_ID) == 0) {
496 if(!CreateAttributeFromASCII(hdf_group, fp)) {
497 cout << "Can not create attribute " << i << " for group " << name << endl;
502 cout << "CreateGroupFromASCII : Unrecognized type " << id_of_begin << endl;
505 hdf_group->CloseOnDisk();
506 hdf_group = 0; //will be deleted by father destructor
508 char id_of_end[MAX_ID_SIZE];
509 fscanf(fp, "%s\n", id_of_end);
510 if(strcmp(id_of_end, GROUP_ID_END) != 0) {
511 cout << "CreateGroupFromASCII : Invalid end token : " << id_of_end << endl;
519 //============================================================================
520 // function : CreateDatasetFromASCII
521 // purpose : Creates a HDF dataset from a set attributes situated under theLabel
522 //============================================================================
523 bool CreateDatasetFromASCII(HDFcontainerObject *father, FILE *fp)
525 char name[HDF_NAME_MAX_LEN+1];
527 hdf_byte_order order;
531 fscanf(fp, "%s %i %i\n", name, &type, &nbAttr);
532 char* new_name = restoreName(name);
534 fscanf(fp, "%i\n", &nbDim);
536 hdf_size* sizeArray = new hdf_size[nbDim];
538 for(i = 0; i<nbDim; i++) {
539 fscanf(fp, "%i\n", &dim);
543 // order (2-d member) was not written in earlier versions
545 int nbRead = fscanf(fp, "%li %i%c", &size, &order, &tmp);
546 if ( nbRead < 2 ) { // fscanf stops before ":"
547 fscanf(fp, "%c", &tmp);
548 order = H5T_ORDER_NONE;
550 if ( type != HDF_FLOAT64 ) // use order only for FLOAT64
551 order = H5T_ORDER_NONE;
553 HDFdataset* hdf_dataset = new HDFdataset(new_name, father,type, sizeArray, nbDim, order);
557 hdf_dataset->CreateOnDisk();
559 if (type == HDF_STRING) {
560 char *val = new char[size+1];
561 fread(val, 1, size, fp);
562 hdf_dataset->WriteOnDisk(val);
564 } else if (type == HDF_FLOAT64) {
565 hdf_float64* val = new hdf_float64[size];
566 for(i=0; i<size; i++) {
567 read_float64(fp, &(val[i]));
569 hdf_dataset->WriteOnDisk(val);
571 } else if(type == HDF_INT64) {
572 hdf_int64* val = new hdf_int64[size];
573 for(i=0; i<size; i++) {
574 fscanf(fp, " %li", &(val[i]));
576 hdf_dataset->WriteOnDisk(val);
578 } else if(type == HDF_INT32) {
579 hdf_int32* val = new hdf_int32[size];
580 for(i=0; i<size; i++) {
581 fscanf(fp, " %i", &(val[i]));
583 hdf_dataset->WriteOnDisk(val);
587 char token[MAX_ID_SIZE];
589 for(i = 0; i < nbAttr; i++) {
590 fscanf(fp, "%s\n", token);
592 if(strcmp(token, ATTRIBUTE_ID) == 0) {
593 if(!CreateAttributeFromASCII(hdf_dataset, fp)) {
594 cout << "Can not create attribute " << i << " for dataset " << name << endl;
599 cout << "CreateGroupFromASCII : Unrecognized type " << token << endl;
604 fscanf(fp, "%s\n", token);
605 if(strcmp(token, DATASET_ID_END) != 0) {
606 cout << "CreateDatasetFromASCII : Invalid end token : " << token << endl;
610 hdf_dataset->CloseOnDisk();
611 hdf_dataset = 0; //will be deleted by father destructor
617 //============================================================================
618 // function : CreateAttributeFromASCII
619 // purpose : Creates a HDF attribute from a set attributes situated under theLabel
620 //============================================================================
621 bool CreateAttributeFromASCII(HDFinternalObject *father, FILE* fp)
623 char name[HDF_NAME_MAX_LEN+1];
627 fscanf(fp, "%s %i %i\n", name, &type, &size);
628 char* new_name = restoreName(name);
629 HDFattribute* hdf_attribute = new HDFattribute(new_name, father, type, size);
631 hdf_attribute->CreateOnDisk();
635 if (type == HDF_STRING) {
637 fscanf(fp, "%c", &tmp);
638 char *val = new char[size+1];
640 fread(val, 1, size, fp);
641 hdf_attribute->WriteOnDisk(val);
643 } else if (type == HDF_FLOAT64) {
645 read_float64(fp, &val);
646 hdf_attribute->WriteOnDisk(&val);
647 } else if(type == HDF_INT64) {
649 fscanf(fp, "%li", &val);
650 hdf_attribute->WriteOnDisk(&val);
651 } else if(type == HDF_INT32) {
653 fscanf(fp, "%i", &val);
654 hdf_attribute->WriteOnDisk(&val);
657 hdf_attribute->CloseOnDisk();
658 hdf_attribute = 0; //will be deleted by father destructor
661 char id_of_end[MAX_ID_SIZE];
662 fscanf(fp, "%s\n", id_of_end);
663 if(strcmp(id_of_end, ATTRIBUTE_ID_END) != 0) {
664 cout << "CreateAttributeFromASCII : Invalid end token : " << id_of_end << endl;
672 //============================================================================
673 // function : GetTempDir
674 // purpose : Return a temp directory to store created files like "/tmp/sub_dir/"
675 //============================================================================
678 //Find a temporary directory to store a file
680 TCollection_AsciiString aTmpDir;
684 aTmp = getenv("TMP");
686 aTmpDir = TCollection_AsciiString(aTmp);
688 aTmpDir = TCollection_AsciiString("C:\\");
690 aTmpDir = TCollection_AsciiString("/tmp/");
693 srand((unsigned int)time(NULL));
695 int aRND = 999 + (int)(100000.0*rand()/(RAND_MAX+1.0)); //Get a random number to present a name of a sub directory
696 TCollection_AsciiString aSubDir(aRND);
697 if(aSubDir.Length() <= 1) aSubDir = TCollection_AsciiString("123409876");
699 aTmpDir += aSubDir; //Get RND sub directory
702 if(aTmpDir.Value(aTmpDir.Length()) != '\\') aTmpDir+='\\';
704 if(aTmpDir.Value(aTmpDir.Length()) != '/') aTmpDir+='/';
707 OSD_Path aPath(aTmpDir);
708 OSD_Directory aDir(aPath);
710 for(aRND = 0; aDir.Exists(); aRND++) {
711 aTmpDir.Insert((aTmpDir.Length() - 1), TCollection_AsciiString(aRND)); //Build a unique directory name
712 aPath = OSD_Path(aTmpDir);
713 aDir = OSD_Directory(aPath);
716 OSD_Protection aProtection(OSD_RW, OSD_RWX, OSD_RX, OSD_RX);
717 aDir.Build(aProtection);
719 int length = strlen(aTmpDir.ToCString());
720 char *new_str = new char[ 1+length ];
721 strcpy(new_str , aTmpDir.ToCString());
726 char* makeName(char* name)
728 TCollection_AsciiString aName(name), aNewName;
729 Standard_Integer i, length = aName.Length();
730 char replace = (char)19;
732 for(i=1; i<=length; i++) {
733 if(aName.Value(i) == ' ') aNewName+=replace;
734 else aNewName += aName.Value(i);
737 length = strlen(aNewName.ToCString());
738 char *new_str = new char[ 1+length ];
739 strcpy(new_str , aNewName.ToCString()) ;
743 char* restoreName(char* name)
745 TCollection_AsciiString aName(name), aNewName;
746 Standard_Integer i, length = aName.Length();
747 char replace = (char)19;
749 for(i=1; i<=length; i++) {
750 if(aName.Value(i) == replace) aNewName+=' ';
751 else aNewName += aName.Value(i);
754 length = strlen(aNewName.ToCString());
755 char *new_str = new char[ 1+length ];
756 strcpy(new_str , aNewName.ToCString()) ;
760 void write_float64(FILE* fp, hdf_float64* value)
762 unsigned char* array = (unsigned char*)value;
763 for(int i = 0; i < sizeof(hdf_float64); i++) {
764 unsigned tmp = (unsigned short)array[i];
765 fprintf(fp, " %2x", tmp);
769 void read_float64(FILE* fp, hdf_float64* value)
771 unsigned char* array = (unsigned char*)value;
772 for(int i = 0; i < sizeof(hdf_float64); i++) {
774 fscanf(fp, " %x", &tmp);
775 array[i] = (unsigned char)tmp;