Graphite Version 3
An experimental 3D geometry processing program
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::const_pointer base_addr, index_t nb_elements
137 ) {
138 const T* attrib = reinterpret_cast<const 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::const_pointer base_addr, index_t nb_elements
188 ) {
189 const char* attrib = reinterpret_cast<const 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::const_pointer base_addr, index_t nb_elements
234 ) {
235 const char* attrib = reinterpret_cast<const 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 (*AsciiAttributeReadSerializer)(
281 FILE* file, Memory::pointer base_address, index_t nb_elements
282 );
283
284 typedef bool (*AsciiAttributeWriteSerializer)(
285 FILE* file, Memory::const_pointer base_address, index_t nb_elements
286 );
287
296 const std::string& type_name,
297 AsciiAttributeReadSerializer read,
298 AsciiAttributeWriteSerializer write
299 );
300
305 GeoFile(const std::string& filename);
306
311
319 bool is_ascii() const {
320 return ascii_;
321 }
322
333 bool gargantua_mode() const {
334 return gargantua_mode_;
335 }
336
341 const std::string& current_chunk_class() const {
342 return current_chunk_class_;
343 }
344
349 size_t current_chunk_size() const {
350 return current_chunk_size_;
351 }
352
357
361 AttributeInfo() : element_size(0), dimension(0) {
362 }
363
372 const std::string& name_in,
373 const std::string& element_type_in,
374 size_t element_size_in,
375 index_t dimension_in
376 ) :
377 name(name_in),
378 element_type(element_type_in),
379 element_size(element_size_in),
380 dimension(dimension_in) {
381 }
382
383
387 std::string name;
388
393 std::string element_type;
394
399
404 };
405
410
414 AttributeSetInfo() : nb_items(0), skip(false) {
415 }
416
424 const std::string& name_in,
425 index_t nb_items_in
426 ) :
427 name(name_in),
428 nb_items(nb_items_in),
429 skip(false) {
430 }
431
440 const std::string& name_in
441 ) const {
442 for(index_t i=0; i<attributes.size(); ++i) {
443 if(attributes[i].name == name_in) {
444 return &(attributes[i]);
445 }
446 }
447 return nullptr;
448 }
449
457 AttributeInfo* find_attribute(const std::string& name_in) {
458 for(index_t i=0; i<attributes.size(); ++i) {
459 if(attributes[i].name == name_in) {
460 return &(attributes[i]);
461 }
462 }
463 return nullptr;
464 }
465
469 std::string name;
470
475
480
485 bool skip;
486 };
487
494 AttributeSetInfo* find_attribute_set(const std::string& name) {
495 auto it = attribute_sets_.find(name);
496 if(it == attribute_sets_.end()) {
497 return nullptr;
498 }
499 return &(it->second);
500 }
501
509 const std::string& name
510 ) const {
511 auto it = attribute_sets_.find(name);
512 if(it == attribute_sets_.end()) {
513 return nullptr;
514 }
515 return &(it->second);
516 }
517
530
541 void write_index_t(index_t x, const char* comment = nullptr);
542
550
559 void write_index_t_32(index_t x, const char* comment = nullptr);
560
567 std::string read_string();
568
577 void write_string(const std::string& s, const char* comment = nullptr);
578
585 size_t read_size_t();
586
593 void write_size_t(size_t x);
594
602 std::string read_chunk_class();
603
612 void write_chunk_class(const std::string& chunk_class);
613
619 void write_string_array(const std::vector<std::string>& strings);
620
626 void read_string_array(std::vector<std::string>& strings);
627
628
637 size_t string_size(const std::string& s) const {
638 return sizeof(Numeric::uint32) + s.length();
639 }
640
648 const std::vector<std::string>& strings
649 ) const ;
650
655
665 const std::string& chunk_class, size_t size
666 );
667
673
680
687
688 protected:
689 std::string filename_;
690 gzFile file_;
691 bool ascii_;
692 FILE* ascii_file_;
693 std::string current_chunk_class_;
694 size_t current_chunk_size_;
695 size_t current_chunk_file_pos_;
696 std::map<std::string, AttributeSetInfo> attribute_sets_;
697
698 static std::map<std::string, AsciiAttributeReadSerializer>
699 ascii_attribute_read_;
700
701 static std::map<std::string, AsciiAttributeWriteSerializer>
702 ascii_attribute_write_;
703
709
712
715 };
716
717 /**************************************************************/
718
722 class GEOGRAM_API InputGeoFile : public GeoFile {
723 public:
728 InputGeoFile(const std::string& filename);
729
734 const std::string& next_chunk();
735
741 void read_attribute(void* addr);
742
743
751
752
761 geo_assert(current_attribute_set_ != nullptr);
762 return *current_attribute_set_;
763 }
764
772 geo_assert(current_attribute_ != nullptr);
773 return *current_attribute_;
774 }
775
776 /*
777 * \brief Gets the current user comment.
778 * \return a const reference to the current user comment
779 * \pre current chunk class is "CMNT" (COMMENT)
780 */
781 const std::string& current_comment() const {
782 geo_assert(current_chunk_class_ == "CMNT");
783 return current_comment_;
784 }
785
786
795 void read_command_line(std::vector<std::string>& args);
796
797 protected:
804
813 index_t* addr, size_t nb_elements, size_t element_size
814 );
815
816 AttributeSetInfo* current_attribute_set_;
817 AttributeInfo* current_attribute_;
818 std::string current_comment_;
819
820 private:
824 InputGeoFile(const InputGeoFile& rhs);
825
829 InputGeoFile& operator=(const InputGeoFile& rhs);
830 };
831
832 /**************************************************************/
833
837 class GEOGRAM_API OutputGeoFile : public GeoFile {
838 public:
845 OutputGeoFile(const std::string& filename, index_t compression_level=3);
846
854 const std::string& name, index_t nb_items
855 );
856
871 const std::string& attribute_set_name,
872 const std::string& attribute_name,
873 const std::string& element_type,
874 size_t element_size,
875 index_t dimension,
876 const void* data
877 );
878
879
884 void write_comment(const std::string& comment);
885
893 void write_command_line(const std::vector<std::string>& args);
894
895
902
903 private:
907 OutputGeoFile(const InputGeoFile& rhs);
908
912 OutputGeoFile& operator=(const InputGeoFile& rhs);
913 };
914
915 /**************************************************************/
916}
917
918#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:319
const std::string & current_chunk_class() const
Gets the current chunk class.
Definition geofile.h:341
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:333
AttributeSetInfo * find_attribute_set(const std::string &name)
Finds an attribute set by name.
Definition geofile.h:494
const AttributeSetInfo * find_attribute_set(const std::string &name) const
Finds an attribute set by name.
Definition geofile.h:508
bool gargantua_mode_
True if current file is in GARGANTUA mode.
Definition geofile.h:708
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:714
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:637
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:349
void write_string(const std::string &s, const char *comment=nullptr)
Writes a string into the file.
static void register_ascii_attribute_serializer(const std::string &type_name, AsciiAttributeReadSerializer read, AsciiAttributeWriteSerializer write)
Declares a new attribute type that can be read from and written to ascii files.
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:711
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.
Used to read a structured binary file.
Definition geofile.h:722
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:771
InputGeoFile(const std::string &filename)
InputGeoFile constructor.
const AttributeSetInfo & current_attribute_set() const
Gets the current attribute set.
Definition geofile.h:760
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:837
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:710
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
const byte * const_pointer
Const pointer to unsigned byte(s)
Definition memory.h:107
uint32_t uint32
Definition numeric.h:141
Global Vorpaline namespace.
geo_index_t index_t
The type for storing and manipulating indices.
Definition numeric.h:329
bool write_ascii_attribute(FILE *file, Memory::const_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:356
std::string name
Name of the attribute.
Definition geofile.h:387
AttributeInfo()
AttributeInfo constructor.
Definition geofile.h:361
index_t dimension
The number of elements per item.
Definition geofile.h:403
size_t element_size
The size in bytes of each element.
Definition geofile.h:398
std::string element_type
A string with the name fo the C++ type of the elements.
Definition geofile.h:393
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:371
Internal representation of an attribute set.
Definition geofile.h:409
AttributeSetInfo(const std::string &name_in, index_t nb_items_in)
AttributeSetInfo constructor.
Definition geofile.h:423
bool skip
if set, all attributes in the set are skipped when reading the file.
Definition geofile.h:485
AttributeInfo * find_attribute(const std::string &name_in)
Finds an AttributeInfo by name.
Definition geofile.h:457
index_t nb_items
number of items in each attribute of the set.
Definition geofile.h:474
vector< AttributeInfo > attributes
the attributes of the set.
Definition geofile.h:479
AttributeSetInfo()
AttributeSetInfo constructor.
Definition geofile.h:414
std::string name
name of the attribute set.
Definition geofile.h:469
const AttributeInfo * find_attribute(const std::string &name_in) const
Finds an AttributeInfo by name.
Definition geofile.h:439