Geogram Version 1.9.6-rc
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#include <geogram/third_party/zlib/zlib.h>
48
49#include <stdexcept>
50#include <fstream>
51#include <map>
52
53
59namespace GEO {
60
66 class GEOGRAM_API GeoFileException : public std::logic_error {
67 public:
73 GeoFileException(const std::string& s) : logic_error(s) {
74 }
75
81 GeoFileException(const GeoFileException& rhs) : logic_error(rhs) {
82 }
83
87 ~GeoFileException() GEO_NOEXCEPT override;
88 };
89
90 /**************************************************************/
91
102 template <class T> inline bool read_ascii_attribute(
103 FILE* file, Memory::pointer base_addr, index_t nb_elements
104 ) {
105 T* attrib = reinterpret_cast<T*>(base_addr);
106 for(index_t i=0; i<nb_elements; ++i) {
107 std::string buff;
108 int res;
109 while(char(res = fgetc(file)) != '\n') {
110 if(res == EOF) {
111 return false;
112 }
113 buff.push_back(char(res));
114 }
115 if(!String::from_string(buff.c_str(),attrib[i])) {
116 return false;
117 }
118 }
119 return true;
120 }
121
131 template <class T> inline bool write_ascii_attribute(
132 FILE* file, Memory::pointer base_addr, index_t nb_elements
133 ) {
134 T* attrib = reinterpret_cast<T*>(base_addr);
135 for(index_t i=0; i<nb_elements; ++i) {
136 if(
137 fprintf(
138 file, "%s\n", String::to_string(attrib[i]).c_str()
139 ) == 0
140 ) {
141 return false;
142 }
143 }
144 return true;
145 }
146
158 template <> inline bool read_ascii_attribute<char>(
159 FILE* file, Memory::pointer base_addr, index_t nb_elements
160 ) {
161 char* attrib = reinterpret_cast<char*>(base_addr);
162 for(index_t i=0; i<nb_elements; ++i) {
163 int val;
164 if(fscanf(file, "%d", &val) == 0) {
165 return false;
166 }
167 attrib[i] = char(val);
168 }
169 return true;
170 }
171
182 template <> inline bool write_ascii_attribute<char>(
183 FILE* file, Memory::pointer base_addr, index_t nb_elements
184 ) {
185 char* attrib = reinterpret_cast<char*>(base_addr);
186 for(index_t i=0; i<nb_elements; ++i) {
187 if(fprintf(file, "%d\n", int(attrib[i])) == 0) {
188 return false;
189 }
190 }
191 return true;
192 }
193
204 template <> inline bool read_ascii_attribute<bool>(
205 FILE* file, Memory::pointer base_addr, index_t nb_elements
206 ) {
207 char* attrib = reinterpret_cast<char*>(base_addr);
208 for(index_t i=0; i<nb_elements; ++i) {
209 int val;
210 if(fscanf(file, "%d", &val) == 0) {
211 return false;
212 }
213 attrib[i] = char(val);
214 }
215 return true;
216 }
217
228 template <> inline bool write_ascii_attribute<bool>(
229 FILE* file, Memory::pointer base_addr, index_t nb_elements
230 ) {
231 char* attrib = reinterpret_cast<char*>(base_addr);
232 for(index_t i=0; i<nb_elements; ++i) {
233 if(fprintf(file, "%d\n", int(attrib[i])) == 0) {
234 return false;
235 }
236 }
237 return true;
238 }
239
240 /**************************************************************/
241
269 class GEOGRAM_API GeoFile {
270 public:
271
276 typedef bool (*AsciiAttributeSerializer)(
277 FILE* file, Memory::pointer base_address, index_t nb_elements
278 );
279
288 const std::string& type_name,
289 AsciiAttributeSerializer read,
290 AsciiAttributeSerializer write
291 );
292
297 GeoFile(const std::string& filename);
298
303
311 bool is_ascii() const {
312 return ascii_;
313 }
314
325 bool gargantua_mode() const {
326 return gargantua_mode_;
327 }
328
333 const std::string& current_chunk_class() const {
334 return current_chunk_class_;
335 }
336
341 size_t current_chunk_size() const {
342 return current_chunk_size_;
343 }
344
349
353 AttributeInfo() : element_size(0), dimension(0) {
354 }
355
364 const std::string& name_in,
365 const std::string& element_type_in,
366 size_t element_size_in,
367 index_t dimension_in
368 ) :
369 name(name_in),
370 element_type(element_type_in),
371 element_size(element_size_in),
372 dimension(dimension_in) {
373 }
374
375
379 std::string name;
380
385 std::string element_type;
386
391
396 };
397
402
406 AttributeSetInfo() : nb_items(0), skip(false) {
407 }
408
416 const std::string& name_in,
417 index_t nb_items_in
418 ) :
419 name(name_in),
420 nb_items(nb_items_in),
421 skip(false) {
422 }
423
432 const std::string& name_in
433 ) const {
434 for(index_t i=0; i<attributes.size(); ++i) {
435 if(attributes[i].name == name_in) {
436 return &(attributes[i]);
437 }
438 }
439 return nullptr;
440 }
441
449 AttributeInfo* find_attribute(const std::string& name_in) {
450 for(index_t i=0; i<attributes.size(); ++i) {
451 if(attributes[i].name == name_in) {
452 return &(attributes[i]);
453 }
454 }
455 return nullptr;
456 }
457
461 std::string name;
462
467
472
477 bool skip;
478 };
479
486 AttributeSetInfo* find_attribute_set(const std::string& name) {
487 auto it = attribute_sets_.find(name);
488 if(it == attribute_sets_.end()) {
489 return nullptr;
490 }
491 return &(it->second);
492 }
493
501 const std::string& name
502 ) const {
503 auto it = attribute_sets_.find(name);
504 if(it == attribute_sets_.end()) {
505 return nullptr;
506 }
507 return &(it->second);
508 }
509
522
533 void write_index_t(index_t x, const char* comment = nullptr);
534
542
551 void write_index_t_32(index_t x, const char* comment = nullptr);
552
559 std::string read_string();
560
569 void write_string(const std::string& s, const char* comment = nullptr);
570
577 size_t read_size_t();
578
585 void write_size_t(size_t x);
586
594 std::string read_chunk_class();
595
604 void write_chunk_class(const std::string& chunk_class);
605
611 void write_string_array(const std::vector<std::string>& strings);
612
618 void read_string_array(std::vector<std::string>& strings);
619
620
629 size_t string_size(const std::string& s) const {
630 return sizeof(Numeric::uint32) + s.length();
631 }
632
640 const std::vector<std::string>& strings
641 ) const ;
642
647
657 const std::string& chunk_class, size_t size
658 );
659
665
672
679
680 protected:
681 std::string filename_;
682 gzFile file_;
683 bool ascii_;
684 FILE* ascii_file_;
685 std::string current_chunk_class_;
686 size_t current_chunk_size_;
687 size_t current_chunk_file_pos_;
688 std::map<std::string, AttributeSetInfo> attribute_sets_;
689
690 static std::map<std::string, AsciiAttributeSerializer>
691 ascii_attribute_read_;
692
693 static std::map<std::string, AsciiAttributeSerializer>
694 ascii_attribute_write_;
695
701
704
707 };
708
709 /**************************************************************/
710
714 class GEOGRAM_API InputGeoFile : public GeoFile {
715 public:
720 InputGeoFile(const std::string& filename);
721
726 const std::string& next_chunk();
727
733 void read_attribute(void* addr);
734
735
743
744
753 geo_assert(current_attribute_set_ != nullptr);
754 return *current_attribute_set_;
755 }
756
764 geo_assert(current_attribute_ != nullptr);
765 return *current_attribute_;
766 }
767
768 /*
769 * \brief Gets the current user comment.
770 * \return a const reference to the current user comment
771 * \pre current chunk class is "CMNT" (COMMENT)
772 */
773 const std::string& current_comment() const {
774 geo_assert(current_chunk_class_ == "CMNT");
775 return current_comment_;
776 }
777
778
787 void read_command_line(std::vector<std::string>& args);
788
789 protected:
796
805 index_t* addr, size_t nb_elements, size_t element_size
806 );
807
808 AttributeSetInfo* current_attribute_set_;
809 AttributeInfo* current_attribute_;
810 std::string current_comment_;
811
812 private:
816 InputGeoFile(const InputGeoFile& rhs);
817
821 InputGeoFile& operator=(const InputGeoFile& rhs);
822 };
823
824 /**************************************************************/
825
829 class GEOGRAM_API OutputGeoFile : public GeoFile {
830 public:
837 OutputGeoFile(const std::string& filename, index_t compression_level=3);
838
846 const std::string& name, index_t nb_items
847 );
848
863 const std::string& attribute_set_name,
864 const std::string& attribute_name,
865 const std::string& element_type,
866 size_t element_size,
867 index_t dimension,
868 const void* data
869 );
870
871
876 void write_comment(const std::string& comment);
877
885 void write_command_line(const std::vector<std::string>& args);
886
887
894
895 private:
899 OutputGeoFile(const InputGeoFile& rhs);
900
904 OutputGeoFile& operator=(const InputGeoFile& rhs);
905 };
906
907 /**************************************************************/
908}
909
910#endif
#define geo_assert(x)
Verifies that a condition is met.
Definition assert.h:149
GeoFile exception.
Definition geofile.h:66
GeoFileException(const std::string &s)
GeoFileException constructor.
Definition geofile.h:73
GeoFileException(const GeoFileException &rhs)
GeoFileException copy constructor.
Definition geofile.h:81
~GeoFileException() GEO_NOEXCEPT override
GeoFileException destructor.
Base class for reading or writing Geogram structured binary files.
Definition geofile.h:269
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:311
const std::string & current_chunk_class() const
Gets the current chunk class.
Definition geofile.h:333
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:325
AttributeSetInfo * find_attribute_set(const std::string &name)
Finds an attribute set by name.
Definition geofile.h:486
const AttributeSetInfo * find_attribute_set(const std::string &name) const
Finds an attribute set by name.
Definition geofile.h:500
bool gargantua_mode_
True if current file is in GARGANTUA mode.
Definition geofile.h:700
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:706
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:629
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:341
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:703
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:714
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:763
InputGeoFile(const std::string &filename)
InputGeoFile constructor.
const AttributeSetInfo & current_attribute_set() const
Gets the current attribute set.
Definition geofile.h:752
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:829
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:131
Types and functions for numbers manipulation.
Functions for string manipulation.
Internal representation of attributes.
Definition geofile.h:348
std::string name
Name of the attribute.
Definition geofile.h:379
AttributeInfo()
AttributeInfo constructor.
Definition geofile.h:353
index_t dimension
The number of elements per item.
Definition geofile.h:395
size_t element_size
The size in bytes of each element.
Definition geofile.h:390
std::string element_type
A string with the name fo the C++ type of the elements.
Definition geofile.h:385
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:363
Internal representation of an attribute set.
Definition geofile.h:401
AttributeSetInfo(const std::string &name_in, index_t nb_items_in)
AttributeSetInfo constructor.
Definition geofile.h:415
bool skip
if set, all attributes in the set are skipped when reading the file.
Definition geofile.h:477
AttributeInfo * find_attribute(const std::string &name_in)
Finds an AttributeInfo by name.
Definition geofile.h:449
index_t nb_items
number of items in each attribute of the set.
Definition geofile.h:466
vector< AttributeInfo > attributes
the attributes of the set.
Definition geofile.h:471
AttributeSetInfo()
AttributeSetInfo constructor.
Definition geofile.h:406
std::string name
name of the attribute set.
Definition geofile.h:461
const AttributeInfo * find_attribute(const std::string &name_in) const
Finds an AttributeInfo by name.
Definition geofile.h:431