Geogram Version 1.9.7
A programming library of geometric algorithms
Loading...
Searching...
No Matches
geofile.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2000-2022 Inria
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * * Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 * * Neither the name of the ALICE Project-Team nor the names of its
14 * contributors may be used to endorse or promote products derived from this
15 * software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
21 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 * POSSIBILITY OF SUCH DAMAGE.
28 *
29 * Contact: Bruno Levy
30 *
31 * https://www.inria.fr/fr/bruno-levy
32 *
33 * Inria,
34 * Domaine de Voluceau,
35 * 78150 Le Chesnay - Rocquencourt
36 * FRANCE
37 *
38 */
39
40#ifndef GEOGRAM_BASIC_GEOFILE
41#define GEOGRAM_BASIC_GEOFILE
42
47#ifdef GEOGRAM_USE_BUILTIN_DEPS
48#include <geogram/third_party/zlib/zlib.h>
49#else
50#include <zlib.h>
51#endif
52
53#include <stdexcept>
54#include <fstream>
55#include <map>
56
57
63namespace GEO {
64
70 class GEOGRAM_API GeoFileException : public std::logic_error {
71 public:
77 GeoFileException(const std::string& s) : logic_error(s) {
78 }
79
85 GeoFileException(const GeoFileException& rhs) : logic_error(rhs) {
86 }
87
91 ~GeoFileException() GEO_NOEXCEPT override;
92 };
93
94 /**************************************************************/
95
106 template <class T> inline bool read_ascii_attribute(
107 FILE* file, Memory::pointer base_addr, index_t nb_elements
108 ) {
109 T* attrib = reinterpret_cast<T*>(base_addr);
110 for(index_t i=0; i<nb_elements; ++i) {
111 std::string buff;
112 int res;
113 while(char(res = fgetc(file)) != '\n') {
114 if(res == EOF) {
115 return false;
116 }
117 buff.push_back(char(res));
118 }
119 if(!String::from_string(buff.c_str(),attrib[i])) {
120 return false;
121 }
122 }
123 return true;
124 }
125
135 template <class T> inline bool write_ascii_attribute(
136 FILE* file, Memory::pointer base_addr, index_t nb_elements
137 ) {
138 T* attrib = reinterpret_cast<T*>(base_addr);
139 for(index_t i=0; i<nb_elements; ++i) {
140 if(
141 fprintf(
142 file, "%s\n", String::to_string(attrib[i]).c_str()
143 ) == 0
144 ) {
145 return false;
146 }
147 }
148 return true;
149 }
150
162 template <> inline bool read_ascii_attribute<char>(
163 FILE* file, Memory::pointer base_addr, index_t nb_elements
164 ) {
165 char* attrib = reinterpret_cast<char*>(base_addr);
166 for(index_t i=0; i<nb_elements; ++i) {
167 int val;
168 if(fscanf(file, "%d", &val) == 0) {
169 return false;
170 }
171 attrib[i] = char(val);
172 }
173 return true;
174 }
175
186 template <> inline bool write_ascii_attribute<char>(
187 FILE* file, Memory::pointer base_addr, index_t nb_elements
188 ) {
189 char* attrib = reinterpret_cast<char*>(base_addr);
190 for(index_t i=0; i<nb_elements; ++i) {
191 if(fprintf(file, "%d\n", int(attrib[i])) == 0) {
192 return false;
193 }
194 }
195 return true;
196 }
197
208 template <> inline bool read_ascii_attribute<bool>(
209 FILE* file, Memory::pointer base_addr, index_t nb_elements
210 ) {
211 char* attrib = reinterpret_cast<char*>(base_addr);
212 for(index_t i=0; i<nb_elements; ++i) {
213 int val;
214 if(fscanf(file, "%d", &val) == 0) {
215 return false;
216 }
217 attrib[i] = char(val);
218 }
219 return true;
220 }
221
232 template <> inline bool write_ascii_attribute<bool>(
233 FILE* file, Memory::pointer base_addr, index_t nb_elements
234 ) {
235 char* attrib = reinterpret_cast<char*>(base_addr);
236 for(index_t i=0; i<nb_elements; ++i) {
237 if(fprintf(file, "%d\n", int(attrib[i])) == 0) {
238 return false;
239 }
240 }
241 return true;
242 }
243
244 /**************************************************************/
245
273 class GEOGRAM_API GeoFile {
274 public:
275
280 typedef bool (*AsciiAttributeSerializer)(
281 FILE* file, Memory::pointer base_address, index_t nb_elements
282 );
283
292 const std::string& type_name,
293 AsciiAttributeSerializer read,
294 AsciiAttributeSerializer write
295 );
296
301 GeoFile(const std::string& filename);
302
307
315 bool is_ascii() const {
316 return ascii_;
317 }
318
329 bool gargantua_mode() const {
330 return gargantua_mode_;
331 }
332
337 const std::string& current_chunk_class() const {
338 return current_chunk_class_;
339 }
340
345 size_t current_chunk_size() const {
346 return current_chunk_size_;
347 }
348
353
357 AttributeInfo() : element_size(0), dimension(0) {
358 }
359
368 const std::string& name_in,
369 const std::string& element_type_in,
370 size_t element_size_in,
371 index_t dimension_in
372 ) :
373 name(name_in),
374 element_type(element_type_in),
375 element_size(element_size_in),
376 dimension(dimension_in) {
377 }
378
379
383 std::string name;
384
389 std::string element_type;
390
395
400 };
401
406
410 AttributeSetInfo() : nb_items(0), skip(false) {
411 }
412
420 const std::string& name_in,
421 index_t nb_items_in
422 ) :
423 name(name_in),
424 nb_items(nb_items_in),
425 skip(false) {
426 }
427
436 const std::string& name_in
437 ) const {
438 for(index_t i=0; i<attributes.size(); ++i) {
439 if(attributes[i].name == name_in) {
440 return &(attributes[i]);
441 }
442 }
443 return nullptr;
444 }
445
453 AttributeInfo* find_attribute(const std::string& name_in) {
454 for(index_t i=0; i<attributes.size(); ++i) {
455 if(attributes[i].name == name_in) {
456 return &(attributes[i]);
457 }
458 }
459 return nullptr;
460 }
461
465 std::string name;
466
471
476
481 bool skip;
482 };
483
490 AttributeSetInfo* find_attribute_set(const std::string& name) {
491 auto it = attribute_sets_.find(name);
492 if(it == attribute_sets_.end()) {
493 return nullptr;
494 }
495 return &(it->second);
496 }
497
505 const std::string& name
506 ) const {
507 auto it = attribute_sets_.find(name);
508 if(it == attribute_sets_.end()) {
509 return nullptr;
510 }
511 return &(it->second);
512 }
513
526
537 void write_index_t(index_t x, const char* comment = nullptr);
538
546
555 void write_index_t_32(index_t x, const char* comment = nullptr);
556
563 std::string read_string();
564
573 void write_string(const std::string& s, const char* comment = nullptr);
574
581 size_t read_size_t();
582
589 void write_size_t(size_t x);
590
598 std::string read_chunk_class();
599
608 void write_chunk_class(const std::string& chunk_class);
609
615 void write_string_array(const std::vector<std::string>& strings);
616
622 void read_string_array(std::vector<std::string>& strings);
623
624
633 size_t string_size(const std::string& s) const {
634 return sizeof(Numeric::uint32) + s.length();
635 }
636
644 const std::vector<std::string>& strings
645 ) const ;
646
651
661 const std::string& chunk_class, size_t size
662 );
663
669
676
683
684 protected:
685 std::string filename_;
686 gzFile file_;
687 bool ascii_;
688 FILE* ascii_file_;
689 std::string current_chunk_class_;
690 size_t current_chunk_size_;
691 size_t current_chunk_file_pos_;
692 std::map<std::string, AttributeSetInfo> attribute_sets_;
693
694 static std::map<std::string, AsciiAttributeSerializer>
695 ascii_attribute_read_;
696
697 static std::map<std::string, AsciiAttributeSerializer>
698 ascii_attribute_write_;
699
705
708
711 };
712
713 /**************************************************************/
714
718 class GEOGRAM_API InputGeoFile : public GeoFile {
719 public:
724 InputGeoFile(const std::string& filename);
725
730 const std::string& next_chunk();
731
737 void read_attribute(void* addr);
738
739
747
748
757 geo_assert(current_attribute_set_ != nullptr);
758 return *current_attribute_set_;
759 }
760
768 geo_assert(current_attribute_ != nullptr);
769 return *current_attribute_;
770 }
771
772 /*
773 * \brief Gets the current user comment.
774 * \return a const reference to the current user comment
775 * \pre current chunk class is "CMNT" (COMMENT)
776 */
777 const std::string& current_comment() const {
778 geo_assert(current_chunk_class_ == "CMNT");
779 return current_comment_;
780 }
781
782
791 void read_command_line(std::vector<std::string>& args);
792
793 protected:
800
809 index_t* addr, size_t nb_elements, size_t element_size
810 );
811
812 AttributeSetInfo* current_attribute_set_;
813 AttributeInfo* current_attribute_;
814 std::string current_comment_;
815
816 private:
820 InputGeoFile(const InputGeoFile& rhs);
821
825 InputGeoFile& operator=(const InputGeoFile& rhs);
826 };
827
828 /**************************************************************/
829
833 class GEOGRAM_API OutputGeoFile : public GeoFile {
834 public:
841 OutputGeoFile(const std::string& filename, index_t compression_level=3);
842
850 const std::string& name, index_t nb_items
851 );
852
867 const std::string& attribute_set_name,
868 const std::string& attribute_name,
869 const std::string& element_type,
870 size_t element_size,
871 index_t dimension,
872 const void* data
873 );
874
875
880 void write_comment(const std::string& comment);
881
889 void write_command_line(const std::vector<std::string>& args);
890
891
898
899 private:
903 OutputGeoFile(const InputGeoFile& rhs);
904
908 OutputGeoFile& operator=(const InputGeoFile& rhs);
909 };
910
911 /**************************************************************/
912}
913
914#endif
#define geo_assert(x)
Verifies that a condition is met.
Definition assert.h:149
GeoFile exception.
Definition geofile.h:70
GeoFileException(const std::string &s)
GeoFileException constructor.
Definition geofile.h:77
GeoFileException(const GeoFileException &rhs)
GeoFileException copy constructor.
Definition geofile.h:85
~GeoFileException() GEO_NOEXCEPT override
GeoFileException destructor.
Base class for reading or writing Geogram structured binary files.
Definition geofile.h:273
std::string read_chunk_class()
Reads a chunk class from the file.
void check_chunk_size()
Checks that the actual chunk size corresponds to the specified chunk size.
void write_chunk_class(const std::string &chunk_class)
Writes a chunk class into the file.
bool is_ascii() const
Tests whether this GeoFile is ascii.
Definition geofile.h:315
const std::string & current_chunk_class() const
Gets the current chunk class.
Definition geofile.h:337
size_t string_array_size(const std::vector< std::string > &strings) const
Gets the size in bytes used by a given string array in the file.
size_t read_size_t()
Reads an unsigned 64 bits integer from the file.
bool gargantua_mode() const
Tests whether this GeoFile is in GARGANTUA mode.
Definition geofile.h:329
AttributeSetInfo * find_attribute_set(const std::string &name)
Finds an attribute set by name.
Definition geofile.h:490
const AttributeSetInfo * find_attribute_set(const std::string &name) const
Finds an attribute set by name.
Definition geofile.h:504
bool gargantua_mode_
True if current file is in GARGANTUA mode.
Definition geofile.h:704
GeoFile(const std::string &filename)
GeoFile constructor.
void clear_attribute_maps()
Clears all memorized information about attributes and attribute sets.
bool convert_64_to_32_
True if reading a GARGANTUA file in standard mode.
Definition geofile.h:710
std::string read_string()
Reads a string from the file.
size_t string_size(const std::string &s) const
Gets the size in bytes used by a given string in the file.
Definition geofile.h:633
void write_size_t(size_t x)
Writes an unsigned 64 bits integer into the file.
void read_string_array(std::vector< std::string > &strings)
Reads a string array from the file.
size_t current_chunk_size() const
Gets the size of the current chunk.
Definition geofile.h:345
void write_string(const std::string &s, const char *comment=nullptr)
Writes a string into the file.
void check_zlib_version()
Compares the zlib version declared in the header file with the zlib version obtained from the runtime...
bool convert_32_to_64_
True if reading a standard file in GARGANTUA mode.
Definition geofile.h:707
index_t read_index_t()
Reads an integer from the file.
void write_index_t_32(index_t x, const char *comment=nullptr)
Writes a 32-bit integer into the file.
index_t read_index_t_32()
Reads a 32-bit integer from the file.
void write_string_array(const std::vector< std::string > &strings)
Writes a string array into the file.
~GeoFile()
GeoFile destructor.
void write_index_t(index_t x, const char *comment=nullptr)
Writes an integer into the file.
void write_chunk_header(const std::string &chunk_class, size_t size)
Writes a chunk header into the file.
void read_chunk_header()
Reads a chunk header from the file.
static void register_ascii_attribute_serializer(const std::string &type_name, AsciiAttributeSerializer read, AsciiAttributeSerializer write)
Declares a new attribute type that can be read from and written to ascii files.
Used to read a structured binary file.
Definition geofile.h:718
void skip_attribute_set()
Indicates that all the attributes attached to the latest attribute set should be skipped.
void skip_chunk()
Skips the latest chunk.
const AttributeInfo & current_attribute() const
Gets the current attribute.
Definition geofile.h:767
InputGeoFile(const std::string &filename)
InputGeoFile constructor.
const AttributeSetInfo & current_attribute_set() const
Gets the current attribute set.
Definition geofile.h:756
void read_attribute(void *addr)
Reads the latest attribute.
void read_command_line(std::vector< std::string > &args)
Reads the command line from the file.
void read_and_convert_index_t_array(index_t *addr, size_t nb_elements, size_t element_size)
Reads an array of index_t, possibly with different GARGANTUA mode, and adapts it to current GARGANTUA...
const std::string & next_chunk()
Advances to the next chunk.
Used to write a structured binary file.
Definition geofile.h:833
void write_attribute_set(const std::string &name, index_t nb_items)
Writes a new attribute set to the file.
void write_separator()
Writes a separator into the file.
OutputGeoFile(const std::string &filename, index_t compression_level=3)
OutputGeoFile constructor.
void write_comment(const std::string &comment)
Writes a new comment to the file.
void write_attribute(const std::string &attribute_set_name, const std::string &attribute_name, const std::string &element_type, size_t element_size, index_t dimension, const void *data)
Writes a new attribute to the file.
void write_command_line(const std::vector< std::string > &args)
Writes the command line to the file.
Vector with aligned memory allocation.
Definition memory.h:660
Common include file, providing basic definitions. Should be included before anything else by all head...
Types and functions for memory manipulation.
byte * pointer
Pointer to unsigned byte(s)
Definition memory.h:104
uint32_t uint32
Definition numeric.h:141
Global Vorpaline namespace.
Definition basic.h:55
geo_index_t index_t
The type for storing and manipulating indices.
Definition numeric.h:329
bool write_ascii_attribute(FILE *file, Memory::pointer base_addr, index_t nb_elements)
Writes an ASCII attribute to a file.
Definition geofile.h:135
Types and functions for numbers manipulation.
Functions for string manipulation.
Internal representation of attributes.
Definition geofile.h:352
std::string name
Name of the attribute.
Definition geofile.h:383
AttributeInfo()
AttributeInfo constructor.
Definition geofile.h:357
index_t dimension
The number of elements per item.
Definition geofile.h:399
size_t element_size
The size in bytes of each element.
Definition geofile.h:394
std::string element_type
A string with the name fo the C++ type of the elements.
Definition geofile.h:389
AttributeInfo(const std::string &name_in, const std::string &element_type_in, size_t element_size_in, index_t dimension_in)
AttributeInfo constructor.
Definition geofile.h:367
Internal representation of an attribute set.
Definition geofile.h:405
AttributeSetInfo(const std::string &name_in, index_t nb_items_in)
AttributeSetInfo constructor.
Definition geofile.h:419
bool skip
if set, all attributes in the set are skipped when reading the file.
Definition geofile.h:481
AttributeInfo * find_attribute(const std::string &name_in)
Finds an AttributeInfo by name.
Definition geofile.h:453
index_t nb_items
number of items in each attribute of the set.
Definition geofile.h:470
vector< AttributeInfo > attributes
the attributes of the set.
Definition geofile.h:475
AttributeSetInfo()
AttributeSetInfo constructor.
Definition geofile.h:410
std::string name
name of the attribute set.
Definition geofile.h:465
const AttributeInfo * find_attribute(const std::string &name_in) const
Finds an AttributeInfo by name.
Definition geofile.h:435