VTK  9.4.20241016
vtkResourceParser.h
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
2// SPDX-License-Identifier: BSD-3-Clause
3#ifndef vtkResourceParser_h
4#define vtkResourceParser_h
5
6#include "vtkIOCoreModule.h" // For export macro
7#include "vtkObject.h"
8#include "vtkResourceStream.h" // For SeekDirection and vtkResourceStream
9#include "vtkSmartPointer.h" // For vtkSmartPointer
10
11#include <array> // for std::array
12#include <cstdint> // for std::int32_t
13#include <cstdlib> // for std::size_t
14#include <functional> // for std::function
15#include <limits> // for std::numeric_limits
16#include <memory> // for std::unique_ptr
17#include <string> // for std::string
18#include <type_traits> // for SFINAE helpers
19
20VTK_ABI_NAMESPACE_BEGIN
21
22#ifndef __VTK_WRAP__ // do not wrap
23
32enum class vtkParseResult : std::int32_t
33{
34 Error = -1, // Value not parsed because of type or formatting error
35 Ok = 0, // Value parsed successfully, no special status
36 EndOfStream = 1, // No value parsed, stream reached its end
37 EndOfLine = 2, // No value parsed, this is an end of line
38 Limit = 3, // Value parsed successfully, limit has been reached
39};
40
57class VTKIOCORE_EXPORT vtkResourceParser : public vtkObject
58{
59public:
63 using PredicateType = std::function<bool(char c)>;
64
66
78
82 using DataReceiverType = std::function<void(const char* data, std::size_t size)>;
83
84 static constexpr std::size_t NoLimit = (std::numeric_limits<std::size_t>::max)();
85
86private:
90 class vtkInternals;
91
95 class VTKIOCORE_EXPORT vtkParserContext
96 {
97 public:
98 vtkParserContext();
99 ~vtkParserContext();
100 vtkParserContext(const vtkParserContext&) = delete;
101 vtkParserContext& operator=(const vtkParserContext&) = delete;
102
104 void SetStream(vtkResourceStream* stream);
106 vtkResourceStream* GetStream() const;
107
109 bool GetStopOnNewLine() const;
111 void SetStopOnNewLine(bool on);
112
114 vtkTypeInt64 Seek(vtkTypeInt64 pos, vtkResourceStream::SeekDirection dir);
116 vtkTypeInt64 Tell();
118 std::size_t Read(char* output, std::size_t size);
120 void Reset();
121
123 template <typename T>
124 vtkParseResult Parse(T& output, const PredicateType& discardPred);
125
127 vtkParseResult ReadUntil(
128 const PredicateType& discardPred, const DataReceiverType& receiver, std::size_t limit);
130 vtkParseResult DiscardUntil(const PredicateType& discardPred);
132 vtkParseResult ReadLine(const DataReceiverType& receiver, std::size_t limit);
133
135 void PrintSelf(ostream& os, vtkIndent indent);
136
137 private:
138 std::unique_ptr<vtkInternals> Impl;
139 };
140
150 template <typename T>
151 static constexpr bool IsSupported()
152 {
153 // Only remove references to check const and volatile
154 using Type = typename std::remove_reference<T>::type;
155
156 return std::is_same<Type, char>::value || std::is_same<Type, signed char>::value ||
157 std::is_same<Type, unsigned char>::value || std::is_same<Type, short>::value ||
158 std::is_same<Type, unsigned short>::value || std::is_same<Type, int>::value ||
159 std::is_same<Type, unsigned int>::value || std::is_same<Type, long>::value ||
160 std::is_same<Type, unsigned long>::value || std::is_same<Type, long long>::value ||
161 std::is_same<Type, unsigned long long>::value || std::is_same<Type, float>::value ||
162 std::is_same<Type, double>::value || std::is_same<Type, bool>::value ||
163 std::is_same<Type, std::string>::value;
164 }
165
166public:
168 void PrintSelf(ostream& os, vtkIndent indent) override;
170
179 void SetStream(vtkResourceStream* stream) { this->Context.SetStream(stream); }
180
186 vtkResourceStream* GetStream() const { return this->Context.GetStream(); }
187
189
197 bool GetStopOnNewLine() const { return this->Context.GetStopOnNewLine(); }
198 void SetStopOnNewLine(bool on) { this->Context.SetStopOnNewLine(on); }
199 vtkBooleanMacro(StopOnNewLine, bool);
201
218 vtkTypeInt64 Seek(vtkTypeInt64 pos, vtkResourceStream::SeekDirection dir)
219 {
220 return this->Context.Seek(pos, dir);
221 }
222
235 vtkTypeInt64 Tell() { return this->Context.Tell(); }
236
247 std::size_t Read(char* output, std::size_t size) { return this->Context.Read(output, size); }
248
258 void Reset() { this->Context.Reset(); }
259
303 template <typename T, typename std::enable_if<IsSupported<T>(), bool>::type = true>
304 vtkParseResult Parse(T& output, const PredicateType& discardPred = DiscardWhitespace)
305 {
306 // Static check to prevent cryptic linker error
307 static_assert(IsSupported<T>(), "Unsupported type given to Parse function");
308 return this->Context.Parse(output, discardPred);
309 }
310
326 const PredicateType& discardPred, const DataReceiverType& receiver, std::size_t limit = NoLimit)
327 {
328 return this->Context.ReadUntil(discardPred, receiver, limit);
329 }
330
334 template <typename It>
336 {
343
348 };
349
360 template <typename OutputIt>
362 const PredicateType& discardPred, OutputIt output, std::size_t limit = NoLimit)
363 {
364 const auto result = this->ReadUntil(
365 discardPred,
366 [&output](const char* data, std::size_t size) mutable
367 {
368 for (std::size_t i{}; i < size; ++i)
369 {
370 *output++ = data[i];
371 }
372 },
373 limit);
374
375 return ReadToResult<OutputIt>{ result, output };
376 }
377
387 template <typename ForwardIt>
389 const PredicateType& discardPred, ForwardIt begin, ForwardIt end)
390 {
391 return this->ReadUntilTo(discardPred, begin, std::distance(begin, end));
392 }
393
403 {
404 return this->Context.DiscardUntil(pred);
405 }
406
433 vtkParseResult ReadLine(const DataReceiverType& receiver, std::size_t limit = NoLimit)
434 {
435 return this->Context.ReadLine(receiver, limit);
436 }
437
453 template <typename Allocator>
455 std::basic_string<char, std::char_traits<char>, Allocator>& output, std::size_t limit = NoLimit)
456 {
457 output.clear();
458
459 return this->ReadLine(
460 [&output](const char* data, std::size_t size) { output.append(data, size); }, limit);
461 }
462
475 template <typename OutputIt>
476 ReadToResult<OutputIt> ReadLineTo(OutputIt output, std::size_t limit = NoLimit)
477 {
478 const auto result = this->ReadLine(
479 [&output](const char* data, std::size_t size)
480 {
481 for (std::size_t i{}; i < size; ++i)
482 {
483 *output++ = data[i];
484 }
485 },
486 limit);
487
488 return ReadToResult<OutputIt>{ result, output };
489 }
490
503 template <typename ForwardIt>
504 ReadToResult<ForwardIt> ReadLineTo(ForwardIt begin, ForwardIt end)
505 {
506 return this->ReadLineTo(begin, std::distance(begin, end));
507 }
508
519 vtkParseResult DiscardLine(std::size_t limit = NoLimit)
520 {
521 return this->ReadLine([](const char*, std::size_t) {}, limit);
522 }
523
524protected:
528 vtkResourceParser() = default;
529 ~vtkResourceParser() override = default;
532
533private:
534 vtkParserContext Context;
535};
536
537#define DECLARE_PARSE_EXTERN_TEMPLATE(type) \
538 extern template VTKIOCORE_EXPORT vtkParseResult \
539 vtkResourceParser::vtkParserContext::Parse<type>(type&, const PredicateType& discardPred)
540
541// Declare explicit instantiation for all supported types
557
558#undef DECLARE_PARSE_EXTERN_TEMPLATE
559
560#endif
561
562VTK_ABI_NAMESPACE_END
563
564#endif
a simple class to control print indentation
Definition vtkIndent.h:108
abstract base class for most VTK objects
Definition vtkObject.h:162
void PrintSelf(ostream &os, vtkIndent indent) override
Methods invoked by print to print information about the object including superclasses.
Helper class to perform formatted input from vtkResourceStream.
ReadToResult< OutputIt > ReadLineTo(OutputIt output, std::size_t limit=NoLimit)
Read an entire line from the input stream.
std::size_t Read(char *output, std::size_t size)
Read data from the input stream.
ReadToResult< ForwardIt > ReadLineTo(ForwardIt begin, ForwardIt end)
Read an entire line from the input stream.
ReadToResult< OutputIt > ReadUntilTo(const PredicateType &discardPred, OutputIt output, std::size_t limit=NoLimit)
Read data from the input stream to any output iterator until the perdicate is met.
vtkParseResult Parse(T &output, const PredicateType &discardPred=DiscardWhitespace)
Main parsing function.
~vtkResourceParser() override=default
vtkParseResult DiscardLine(std::size_t limit=NoLimit)
Discard a line from the input stream.
std::function< void(const char *data, std::size_t size)> DataReceiverType
receiver type used by ReadUntil function
void SetStopOnNewLine(bool on)
Specifies if the parser should handle newlines as a special token to stop on.
void Reset()
Reset parser internal state.
static const PredicateType DiscardNone
Prebuild predicates for common cases.
void SetStream(vtkResourceStream *stream)
Set the stream to parse.
vtkParseResult ReadLine(const DataReceiverType &receiver, std::size_t limit=NoLimit)
Read an entire line from the input stream.
ReadToResult< ForwardIt > ReadUntilTo(const PredicateType &discardPred, ForwardIt begin, ForwardIt end)
Read data from the input stream to any output range until the perdicate is met.
vtkParseResult ReadUntil(const PredicateType &discardPred, const DataReceiverType &receiver, std::size_t limit=NoLimit)
Read data from the input stream until the perdicate is met.
vtkResourceParser(const vtkResourceParser &)=delete
vtkResourceStream * GetStream() const
Get the parsed stream.
vtkParseResult ReadLine(std::basic_string< char, std::char_traits< char >, Allocator > &output, std::size_t limit=NoLimit)
Read an entire line from the input stream.
static const PredicateType DiscardWhitespace
Prebuild predicates for common cases.
std::function< bool(char c)> PredicateType
predicate type used by ReadUntil and DiscardUntil functions
static vtkResourceParser * New()
void PrintSelf(ostream &os, vtkIndent indent) override
Methods invoked by print to print information about the object including superclasses.
vtkTypeInt64 Seek(vtkTypeInt64 pos, vtkResourceStream::SeekDirection dir)
Move stream cursor.
static const PredicateType DiscardNonAlphaNumeric
Prebuild predicates for common cases.
vtkResourceParser()=default
Constructor.
vtkResourceParser & operator=(const vtkResourceParser &)=delete
vtkParseResult DiscardUntil(const PredicateType &pred)
Discard data from the input stream until the perdicate is met.
vtkTypeInt64 Tell()
Get stream cursor position from parser context.
bool GetStopOnNewLine() const
Specifies if the parser should handle newlines as a special token to stop on.
Abstract class used for custom streams.
Structure returned by Read*To functions.
vtkParseResult Result
vtkParseResult::EndOfStream if EOS is reached before pred is met or limit is reached.
It Output
Iterator one past the last written value.
vtkParseResult
Result of a vtkResouceParser parsing operation.
#define DECLARE_PARSE_EXTERN_TEMPLATE(type)