libclod
C library for interacting with NBTs, region files, LOD data and other things.
Loading...
Searching...
No Matches
region_open.c
1#include <clod/region.h>
2#include "region_impl.h"
3#include "error.h"
4#include <stdlib.h>
5#include <string.h>
6
7enum clod_region_result read_opts(struct clod_region_opts *dst, const struct clod_region_opts *src) {
8 if (src->version != CLOD_REGION_VERSION) {
9 return region_error(CLOD_REGION_INVALID_USAGE,
10 "Invalid opts.version %d. Current version is %d. Make sure to set opts.version correctly or update the library.",
12 }
14
15 if (src->dims) {
16 if (src->dims > CLOD_REGION_DIMENSIONS_MAX) {
17 return region_error(CLOD_REGION_INVALID_USAGE,
18 "Invalid opts.dims %d. Must be <= %d.", src->dims,
19 CLOD_REGION_DIMENSIONS_MAX);
20 }
21 dst->dims = src->dims;
22 } else {
23 dst->dims = 2;
24 }
25
26 if (src->mode) {
27 if (src->mode != CLOD_REGION_MODE_RDWR && src->mode != CLOD_REGION_MODE_RDONLY) {
28 return region_error(CLOD_REGION_INVALID_USAGE,
29 "Invalid opts.mode %d. Must be CLOD_REGION_MODE_RDWR or CLOD_REGION_MODE_RDONLY.",
30 src->mode);
31 }
32 dst->mode = src->mode;
33 } else {
34 dst->mode = CLOD_REGION_MODE_RDWR;
35 }
36
37 if (src->unix_fd) {
38 if (src->unix_fd < 0) {
39 return region_error(CLOD_REGION_INVALID_USAGE,
40 "Invalid opts.unix_fd %d. Must be >= 0.",
41 src->unix_fd);
42 }
43 dst->unix_fd = src->unix_fd;
44 }
45
46 if (src->unix_file_perms) {
48 }
49
50 if (src->prefix[0]) {
51 if (memchr(src->prefix, '.', CLOD_REGION_PREFIX_MAX) != nullptr) {
52 return region_error(CLOD_REGION_INVALID_USAGE,
53 "Invalid opts.prefix %s. Must not contain a '.' character.",
54 src->prefix);
55 }
56 strncpy(dst->prefix, src->prefix, CLOD_REGION_PREFIX_MAX);
57 dst->prefix[CLOD_REGION_PREFIX_MAX] = '\0';
58 } else {
59 strncpy(dst->prefix, "region", CLOD_REGION_PREFIX_MAX + 1);
60 }
61
62 if (src->region_ext[0]) {
63 strncpy(dst->region_ext, src->region_ext, CLOD_REGION_EXTENSION_MAX);
64 dst->region_ext[CLOD_REGION_EXTENSION_MAX] = '\0';
65 } else {
66 strncpy(dst->region_ext, "mcr", CLOD_REGION_EXTENSION_MAX + 1);
67 }
68
69 if (src->chunk_ext[0]) {
70 strncpy(dst->chunk_ext, src->chunk_ext, CLOD_REGION_EXTENSION_MAX);
71 dst->chunk_ext[CLOD_REGION_EXTENSION_MAX] = '\0';
72 } else {
73 strncpy(dst->chunk_ext, "mcc", CLOD_REGION_EXTENSION_MAX + 1);
74 }
75
76 if (src->compression) {
78 return region_error(CLOD_REGION_INVALID_USAGE,
79 "Invalid opts.compression %d. Either the required compression library has been intentionally disabled, or the compression mode is invalid.",
80 src->compression);
81 }
82 dst->compression = src->compression;
83 } else if (is_vanilla_compatible(dst)) {
85 return region_error(CLOD_REGION_INVALID_USAGE,
86 "libdeflate has been disabled, but it is required to compress/decompress minecraft-compatible region files.");
87 }
88 } else {
91 } else {
93 }
94 }
95
96 return true;
97}
98struct clod_region *clod_region_open(const char *path, const struct clod_region_opts *opts) {
99 struct clod_region *r = malloc(sizeof(struct clod_region));
100 if (!r) return nullptr;
101
102 memset(r, 0, sizeof(struct clod_region));
103 if (!read_opts(&r->opts, opts)) {
104 free(r);
105 return nullptr;
106 }
107
108 mutex_init(&r->mtx);
109 auto const res = dir_open(&r->d, path, &r->opts);
110 if (res != CLOD_REGION_OK) {
111 mutex_destroy(&r->mtx);
112 free(r);
113 return nullptr;
114 }
115
116 r->cache_len = 0;
117 r->cache = nullptr;
118
119 return r;
120}
122 if (r->inside != 0) {
123 region_error(CLOD_REGION_INVALID_USAGE, "Attempted to close region while still in use.");
124 exit(EXIT_FAILURE);
125 }
126
127 mutex_destroy(&r->mtx);
128 auto const dir_res = dir_close(r->d);
129 auto const fc_res = file_cache_destroy(r);
130 free(r);
131 return dir_res != CLOD_REGION_OK ? dir_res : fc_res;
132}
bool clod_compression_support(enum clod_compression_method method)
Definition compression.c:4
@ CLOD_UNCOMPRESSED
Definition compression.h:34
@ CLOD_LZ4F
Definition compression.h:50
@ CLOD_ZLIB
Definition compression.h:42
#define CLOD_REGION_VERSION
Definition region.h:30
clod_region_result
Definition region.h:43
struct clod_region * clod_region_open(const char *path, const struct clod_region_opts *opts)
Definition region_open.c:98
enum clod_region_result clod_region_close(struct clod_region *r)
@ CLOD_REGION_INVALID_USAGE
Definition region.h:49
@ CLOD_REGION_OK
Definition region.h:45
uint8_t dims
Definition region.h:173
uint8_t mode
Definition region.h:176
enum clod_compression_method compression
Definition region.h:181
char chunk_ext[10+1]
Definition region.h:207
uint8_t version
Definition region.h:170
char region_ext[10+1]
Definition region.h:203
uint32_t unix_file_perms
Definition region.h:195
char prefix[30+1]
Definition region.h:199