Skip to content

Commit 17be03d

Browse files
committed
Support reading and writing of RDA (a.k.a. RData) files.
Internally, RDA is pretty much just a wrapper around a RDS containing a pairlist, so it's easy enough to do. Also did some refactoring to improve sharing of code between the RDA and RDS readers/writers.
1 parent 3868e34 commit 17be03d

File tree

15 files changed

+712
-73
lines changed

15 files changed

+712
-73
lines changed

docs/Doxyfile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -796,8 +796,12 @@ INPUT = ../include/rds2cpp/StringEncoding.hpp \
796796
../include/rds2cpp/Environment.hpp \
797797
../include/rds2cpp/Symbol.hpp \
798798
../include/rds2cpp/RdsFile.hpp \
799+
../include/rds2cpp/Version.hpp \
800+
../include/rds2cpp/RdaFile.hpp \
799801
../include/rds2cpp/parse_rds.hpp \
800802
../include/rds2cpp/write_rds.hpp \
803+
../include/rds2cpp/parse_rda.hpp \
804+
../include/rds2cpp/write_rda.hpp \
801805
../include/rds2cpp/rds2cpp.hpp \
802806
../README.md
803807

include/rds2cpp/RdaFile.hpp

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
#ifndef RDS2CPP_RDAFILE_HPP
2+
#define RDS2CPP_RDAFILE_HPP
3+
4+
#include <array>
5+
#include <cstdint>
6+
7+
#include "RObject.hpp"
8+
#include "Environment.hpp"
9+
#include "ExternalPointer.hpp"
10+
#include "Symbol.hpp"
11+
#include "Version.hpp"
12+
13+
/**
14+
* @file RdaFile.hpp
15+
*
16+
* @brief Information about an RDA file.
17+
*/
18+
19+
namespace rds2cpp {
20+
21+
/**
22+
* @brief Contents of the parsed RDA file.
23+
*/
24+
struct RdaFile {
25+
/**
26+
* Version of the R serialization format.
27+
*/
28+
std::int32_t format_version = 3;
29+
30+
/**
31+
* R version used to write the file.
32+
*/
33+
Version writer_version;
34+
35+
/**
36+
* Minimum R version required to read the file.
37+
*/
38+
Version reader_version;
39+
40+
/**
41+
* String encoding used to write the file, for conversion of unflagged strings.
42+
*/
43+
StringEncoding encoding = StringEncoding::UTF8;
44+
45+
/**
46+
* The unserialized pairlist containing all saved objects.
47+
* This pairlist will be tagged with the object names.
48+
*/
49+
PairList contents;
50+
51+
/**
52+
* All environments inside the file.
53+
* This can be referenced by position using `EnvironmentIndex::index`.
54+
*/
55+
std::vector<Environment> environments;
56+
57+
/**
58+
* All symbols inside the file.
59+
* This can be referenced by position using `SymbolIndex::index`.
60+
*/
61+
std::vector<Symbol> symbols;
62+
63+
/**
64+
* All external pointers inside the file.
65+
* This can be referenced by position using `ExternalPointerIndex::index`.
66+
*/
67+
std::vector<ExternalPointer> external_pointers;
68+
};
69+
70+
}
71+
72+
#endif

include/rds2cpp/RdsFile.hpp

Lines changed: 6 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include "Environment.hpp"
99
#include "ExternalPointer.hpp"
1010
#include "Symbol.hpp"
11+
#include "Version.hpp"
1112

1213
/**
1314
* @file RdsFile.hpp
@@ -17,37 +18,17 @@
1718

1819
namespace rds2cpp {
1920

20-
/**
21-
* @brief Major-minor-patch version.
22-
*/
23-
struct Version {
24-
/**
25-
* Major version.
26-
*/
27-
std::int16_t major = 3;
28-
29-
/**
30-
* Minor version.
31-
*/
32-
std::uint8_t minor = 5;
33-
34-
/**
35-
* Patch version.
36-
*/
37-
std::uint8_t patch = 0;
38-
};
39-
4021
/**
4122
* @brief Contents of the parsed RDS file.
4223
*/
4324
struct RdsFile {
4425
/**
45-
* Version of the RDS format.
26+
* Version of the R serialization format.
4627
*/
4728
std::int32_t format_version = 3;
4829

4930
/**
50-
* R version used to write the file as major-minor-patch integers.
31+
* R version used to write the file.
5132
*/
5233
Version writer_version;
5334

@@ -68,19 +49,19 @@ struct RdsFile {
6849

6950
/**
7051
* All environments inside the file.
71-
* This can be referenced by the `index` in `EnvironmentIndex`.
52+
* This can be referenced by position using `EnvironmentIndex::index`.
7253
*/
7354
std::vector<Environment> environments;
7455

7556
/**
7657
* All symbols inside the file.
77-
* This can be referenced by the `index` in `SymbolIndex`.
58+
* This can be referenced by position using `SymbolIndex::index`.
7859
*/
7960
std::vector<Symbol> symbols;
8061

8162
/**
8263
* All external pointers inside the file.
83-
* This can be referenced by the `index` in `ExternalPointerIndex`.
64+
* This can be referenced by position using `ExternalPointerIndex::index`.
8465
*/
8566
std::vector<ExternalPointer> external_pointers;
8667
};

include/rds2cpp/Version.hpp

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
#ifndef RDS2CPP_VERSION_HPP
2+
#define RDS2CPP_VERSION_HPP
3+
4+
#include <cstdint>
5+
6+
#include "sanisizer/sanisizer.hpp"
7+
8+
#include "utils_parse.hpp"
9+
#include "utils_write.hpp"
10+
11+
/**
12+
* @file Version.hpp
13+
*
14+
* @brief R version information.
15+
*/
16+
17+
namespace rds2cpp {
18+
19+
/**
20+
* @brief Major-minor-patch version number, usually of R itself.
21+
*/
22+
struct Version {
23+
/**
24+
* Major version.
25+
*/
26+
std::int16_t major = 3;
27+
28+
/**
29+
* Minor version.
30+
*/
31+
std::uint8_t minor = 5;
32+
33+
/**
34+
* Patch version.
35+
*/
36+
std::uint8_t patch = 0;
37+
};
38+
39+
/**
40+
* @cond
41+
*/
42+
template<typename Source_>
43+
Version parse_version(Source_& src) {
44+
// Using int32_t for the versions as the R_Version macro operates with signed integers AFIACT.
45+
auto writer_version = quick_integer<std::int32_t>(src);
46+
Version output;
47+
output.major = (writer_version >> 16);
48+
output.minor = (writer_version >> 8) & 255;
49+
output.patch = writer_version & 255;
50+
return output;
51+
}
52+
53+
template<class BufferedWriter_>
54+
void write_version(const Version& version, BufferedWriter_& bufwriter) {
55+
// Mimic the behavior of the R_Version macro.
56+
inject_integer<std::int32_t, std::int32_t>(
57+
sanisizer::product_unsafe<std::int32_t>(version.major, 65536) +
58+
sanisizer::product_unsafe<std::int32_t>(version.minor, 256) +
59+
static_cast<std::int32_t>(version.patch),
60+
bufwriter
61+
);
62+
}
63+
/**
64+
* @endcond
65+
*/
66+
67+
}
68+
69+
#endif

0 commit comments

Comments
 (0)