VTK  9.3.0
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 for (std::size_t i{}; i < size; ++i)
368 {
369 *output++ = data[i];
370 }
371 },
372 limit);
373
374 return ReadToResult<OutputIt>{ result, output };
375 }
376
386 template <typename ForwardIt>
388 const PredicateType& discardPred, ForwardIt begin, ForwardIt end)
389 {
390 return this->ReadUntilTo(discardPred, begin, std::distance(begin, end));
391 }
392
402 {
403 return this->Context.DiscardUntil(pred);
404 }
405
432 vtkParseResult ReadLine(const DataReceiverType& receiver, std::size_t limit = NoLimit)
433 {
434 return this->Context.ReadLine(receiver, limit);
435 }
436
452 template <typename Allocator>
454 std::basic_string<char, std::char_traits<char>, Allocator>& output, std::size_t limit = NoLimit)
455 {
456 output.clear();
457
458 return this->ReadLine(
459 [&output](const char* data, std::size_t size) { output.append(data, size); }, limit);
460 }
461
474 template <typename OutputIt>
475 ReadToResult<OutputIt> ReadLineTo(OutputIt output, std::size_t limit = NoLimit)
476 {
477 const auto result = this->ReadLine(
478 [&output](const char* data, std::size_t size) {
479 for (std::size_t i{}; i < size; ++i)
480 {
481 *output++ = data[i];
482 }
483 },
484 limit);
485
486 return ReadToResult<OutputIt>{ result, output };
487 }
488
501 template <typename ForwardIt>
502 ReadToResult<ForwardIt> ReadLineTo(ForwardIt begin, ForwardIt end)
503 {
504 return this->ReadLineTo(begin, std::distance(begin, end));
505 }
506
517 vtkParseResult DiscardLine(std::size_t limit = NoLimit)
518 {
519 return this->ReadLine([](const char*, std::size_t) {}, limit);
520 }
521
522protected:
526 vtkResourceParser() = default;
527 ~vtkResourceParser() override = default;
530
531private:
532 vtkParserContext Context;
533};
534
535#define DECLARE_PARSE_EXTERN_TEMPLATE(type) \
536 extern template VTKIOCORE_EXPORT vtkParseResult \
537 vtkResourceParser::vtkParserContext::Parse<type>(type&, const PredicateType& discardPred)
538
539// Declare explicit instantiation for all supported types
555
556#undef DECLARE_PARSE_EXTERN_TEMPLATE
557
558#endif
559
560VTK_ABI_NAMESPACE_END
561
562#endif
a simple class to control print indentation
Definition vtkIndent.h:29
abstract base class for most VTK objects
Definition vtkObject.h:49
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)