rds2cpp
Read and write RDS/RDA files in C++
Loading...
Searching...
No Matches
parse_rds.hpp
Go to the documentation of this file.
1#ifndef RDS2CPP_PARSE_HPP
2#define RDS2CPP_PARSE_HPP
3
4#include <memory>
5#include <stdexcept>
6#include <cstdint>
7
8#include "RdsFile.hpp"
9#include "utils_parse.hpp"
10#include "SharedParseInfo.hpp"
11#include "parse_object.hpp"
12
13#include "byteme/byteme.hpp"
15
22namespace rds2cpp {
23
31 bool parallel = false;
32
38};
39
50template<class Reader_>
51RdsFile parse_rds(Reader_& reader, const ParseRdsOptions& options) {
52 std::unique_ptr<byteme::BufferedReader<unsigned char> > srcptr;
53 if (options.parallel) {
55 } else {
57 }
58 auto& src = *srcptr;
59
60 RdsFile output;
61
62 {
63 try {
64 std::string header(2, '\0');
65 quick_extract(src, 2, reinterpret_cast<unsigned char*>(header.data()));
66 if (header != "X\n") {
67 throw std::runtime_error("only RDS files in XDR format are currently supported");
68 }
69 } catch (std::exception& e) {
70 throw traceback("failed to read the header from the RDS preamble", e);
71 }
72
73 output.format_version = 0;
74 try {
75 output.format_version = quick_integer<I<decltype(output.format_version)> >(src);
76 } catch (std::exception& e) {
77 throw traceback("failed to read the format version number from the RDS preamble", e);
78 }
79
80 try {
81 output.writer_version = parse_version(src);
82 } catch (std::exception& e) {
83 throw traceback("failed to read the writer version number from the RDS preamble", e);
84 }
85
86 try {
87 output.reader_version = parse_version(src);
88 } catch (std::exception& e) {
89 throw traceback("failed to read the reader version number from the RDS preamble", e);
90 }
91 }
92
93 // Reading this undocumented section about the string encoding.
94 {
95 std::int32_t encoding_length = 0;
96 try {
97 encoding_length = quick_integer<I<decltype(encoding_length)> >(src);
98 if (encoding_length < 0) {
99 throw std::runtime_error("encoding length should be non-negative");
100 }
101 } catch (std::exception& e) {
102 throw traceback("failed to read the encoding length from the RDS preamble", e);
103 }
104
105 try {
106 auto encoding = sanisizer::create<std::string>(encoding_length, '\0');
107 quick_extract(src, encoding_length, reinterpret_cast<unsigned char*>(encoding.data()));
108 output.encoding = string_encoding_from_name(encoding);
109 } catch (std::exception& e) {
110 throw traceback("failed to read the encoding string from the RDS preamble", e);
111 }
112 }
113
114 // Now we can finally read the damn object.
115 SharedParseInfo shared;
116 output.object = parse_object(src, shared);
117 output.environments = std::move(shared.environments);
118 output.symbols = std::move(shared.symbols);
119 output.external_pointers = std::move(shared.external_pointers);
120
121 return output;
122}
123
132inline RdsFile parse_rds(std::string file, const ParseRdsOptions& options) {
133 byteme::GzipFileReader reader(file.c_str(), {});
134 return parse_rds(reader, options);
135}
136
141
142}
143
144#endif
Information about an RDS file.
Parse an RDS file in C++.
Definition StringEncoding.hpp:12
RdsFile parse_rds(Reader_ &reader, const ParseRdsOptions &options)
Definition parse_rds.hpp:51
RdsFile Parsed
Definition parse_rds.hpp:140
Container_ create(Value_ x, Args_ &&... args)
constexpr Dest_ cap(Value_ x)
Options for parse_rds().
Definition parse_rds.hpp:27
bool parallel
Definition parse_rds.hpp:31
std::size_t buffer_size
Definition parse_rds.hpp:37
Contents of the parsed RDS file.
Definition RdsFile.hpp:21
std::int32_t format_version
Definition RdsFile.hpp:25
std::unique_ptr< RObject > object
Definition RdsFile.hpp:45
std::vector< Symbol > symbols
Definition RdsFile.hpp:57
std::vector< ExternalPointer > external_pointers
Definition RdsFile.hpp:63
Version reader_version
Definition RdsFile.hpp:35
StringEncoding encoding
Definition RdsFile.hpp:40
Version writer_version
Definition RdsFile.hpp:30
std::vector< Environment > environments
Definition RdsFile.hpp:51