rds2cpp
Read and write RDS/RDA files in C++
Loading...
Searching...
No Matches
parse_rda.hpp
Go to the documentation of this file.
1#ifndef RDS2CPP_PARSE_RDA_HPP
2#define RDS2CPP_PARSE_RDA_HPP
3
4#include <memory>
5#include <stdexcept>
6#include <cstdint>
7
8#include "RdaFile.hpp"
9#include "utils_parse.hpp"
10#include "SharedParseInfo.hpp"
11#include "parse_pairlist.hpp"
12
13#include "byteme/byteme.hpp"
15
22namespace rds2cpp {
23
31 bool parallel = false;
32
38};
39
50template<class Reader_>
51RdaFile parse_rda(Reader_& reader, const ParseRdaOptions& options) {
52 std::unique_ptr<byteme::BufferedReader<unsigned char> > srcptr;
53 if (options.parallel) {
55 } else {
57 }
58 auto& src = *srcptr;
59
60 RdaFile output;
61
62 {
63 try {
64 std::string header(5, '\0');
65 quick_extract(src, 5, reinterpret_cast<unsigned char*>(header.data()));
66 if (header != "RDX2\n" && header != "RDX3\n") {
67 throw std::runtime_error("only RDX2 or RDX3 formats are currently supported");
68 }
69
70 header.resize(2);
71 quick_extract(src, 2, reinterpret_cast<unsigned char*>(header.data()));
72 if (header != "X\n") {
73 throw std::runtime_error("only RDA files in XDR format are currently supported");
74 }
75 } catch (std::exception& e) {
76 throw traceback("failed to read the header from the RDA preamble", e);
77 }
78
79 output.format_version = 0;
80 try {
81 output.format_version = quick_integer<I<decltype(output.format_version)> >(src);
82 } catch (std::exception& e) {
83 throw traceback("failed to read the format version number from the RDA preamble", e);
84 }
85
86 try {
87 output.writer_version = parse_version(src);
88 } catch (std::exception& e) {
89 throw traceback("failed to read the writer version number from the RDA preamble", e);
90 }
91
92 try {
93 output.reader_version = parse_version(src);
94 } catch (std::exception& e) {
95 throw traceback("failed to read the reader version number from the RDA preamble", e);
96 }
97 }
98
99 // Reading this undocumented section about the string encoding.
100 {
101 std::int32_t encoding_length = 0;
102 try {
103 encoding_length = quick_integer<I<decltype(encoding_length)> >(src);
104 if (encoding_length < 0) {
105 throw std::runtime_error("encoding length should be non-negative");
106 }
107 } catch (std::exception& e) {
108 throw traceback("failed to read the encoding length from the RDA preamble", e);
109 }
110
111 try {
112 auto encoding = sanisizer::create<std::string>(encoding_length, '\0');
113 quick_extract(src, encoding_length, reinterpret_cast<unsigned char*>(encoding.data()));
114 output.encoding = string_encoding_from_name(encoding);
115 } catch (std::exception& e) {
116 throw traceback("failed to read the encoding string from the RDA preamble", e);
117 }
118 }
119
120 // Now we can finally read the damn object.
121 SharedParseInfo shared;
122
123 auto details = parse_header(src);
124 auto sexp_type = details[3];
125 if (sexp_type != static_cast<unsigned char>(SEXPType::LIST)) {
126 throw std::runtime_error("expected RDA file to contain a pairlist");
127 }
128
129 auto payload = parse_pairlist_body(src, details, shared);
130 output.objects.reserve(payload->data.size());
131 for (auto& x : payload->data) {
132 if (!x.tag.has_value()) {
133 throw std::runtime_error("expected RDA file to contain a tagged pairlist");
134 }
135 output.objects.emplace_back(std::move(*(x.tag)), std::move(x.value));
136 }
137
138 output.environments = std::move(shared.environments);
139 output.symbols = std::move(shared.symbols);
140 output.external_pointers = std::move(shared.external_pointers);
141
142 return output;
143}
144
153inline RdaFile parse_rda(std::string file, const ParseRdaOptions& options) {
154 byteme::GzipFileReader reader(file.c_str(), {});
155 return parse_rda(reader, options);
156}
157
158}
159
160#endif
Information about an RDA file.
Parse an RDS file in C++.
Definition StringEncoding.hpp:12
RdaFile parse_rda(Reader_ &reader, const ParseRdaOptions &options)
Definition parse_rda.hpp:51
Container_ create(Value_ x, Args_ &&... args)
constexpr Dest_ cap(Value_ x)
Options for parse_rda().
Definition parse_rda.hpp:27
std::size_t buffer_size
Definition parse_rda.hpp:37
bool parallel
Definition parse_rda.hpp:31
Contents of the parsed RDA file.
Definition RdaFile.hpp:47
std::vector< RdaObject > objects
Definition RdaFile.hpp:71
std::vector< Symbol > symbols
Definition RdaFile.hpp:83
StringEncoding encoding
Definition RdaFile.hpp:66
std::vector< ExternalPointer > external_pointers
Definition RdaFile.hpp:89
std::vector< Environment > environments
Definition RdaFile.hpp:77
Version writer_version
Definition RdaFile.hpp:56
Version reader_version
Definition RdaFile.hpp:61
std::int32_t format_version
Definition RdaFile.hpp:51