Jackalope / jrf (public) (License: GPLv3 or later version) (since 2019-11-21) (hash sha1)
Libriary for reading and writing resource files: vertices, indices, meshes, images, models and scene data.
Supports reading from filesystem as well as from zip files.
It uses unique binary container format for those resources.
It is used in tool for converting popular formats like wavefront .obj file, TARGA image to this container and also used in resource loader as part of graphics framework.

It requires jlib libriary (see my user repositories) and libzip.
It is possible to remove libzip dependency.
List of commits:
Subject Hash Author Date (UTC)
refactoring 66f541c32f51d6ed6f90fba1f3b58561726e8659 Jackalope 2020-05-10 00:55:34
extra vertices check c3bd2141d2eaeb96beb5c8ad29e3333c015db4c8 jp.larry 2019-12-26 14:38:29
removed dead code f4ddde689122f1b96fda5292e69f612bf2ca327d jp.larry 2019-12-26 14:38:06
removed forgotten vertex data_size writing 25244188b395b6cca35502f4156d3e78cc1e74ec jp.larry 2019-12-26 13:19:31
better read errors d6d7bc5df695d694ea0dee225905212ef1dfe41b jp.larry 2019-12-26 13:18:55
changed vertices file structure to prevent undefined behaviour 603e283ccf234f87f6e8c38a669280be36a5aafb jp.larry 2019-12-26 12:35:05
vertex attributes is separated, not inteleaved now d3e7b79c74e9fae7b8b788d1a55db2e664feb107 jp.larry 2019-12-26 01:19:17
compiled on windows with mingw 51eacaf02dd542415cea1edd615d88234fb5b344 Jackalope 2019-12-15 07:05:58
added mesh to read and write functions 173144a8516441420feb4327a66d26fa3f57376d Your Name 2019-12-07 22:09:04
warning hidden by implicit cast f49b32439aa1e8719bd340da9fc3bb7e9b906d0d Your Name 2019-12-07 21:01:08
Vertices have vertices count value cf3b63932cdcdb88b72e70df93a4dd8b478d163b jp.larry 2019-12-07 16:02:55
removed IndicesArrays, added Mesh resource and Vertices attributes is not dynamically allocated a54a61cfc285bbec4246b1affdc5fe9251c059d0 jp.larry 2019-12-06 17:04:06
new obj file error f4385161fdd1ad8038e2d0924e1d3de2a6506cc9 Your Name 2019-12-01 10:26:18
scene issues solved cef4ba84d44cbdc6690c87e553df9fbfba60059f Your Name 2019-12-01 04:19:29
changed transformation matrix to 4x4 from 3x3 5b5728dabefb471cf126bf4b524f5079a14c0735 Your Name 2019-11-30 15:16:50
added missing return 94644ed6f61207f664ac4675fa015afbe017ddea jp.larry 2019-11-29 09:03:14
scene improvements, changed shift type to unsigned, set default-value funtions, model must be path a2708b94b88eb0ede73b9aab396e7a13f13baa52 Your Name 2019-11-29 09:27:32
separate function for str reading 9127f9a18f9f4974975fa35d58f596952b6aa4e5 Your Name 2019-11-29 09:26:43
new result errors ef56e017e2e761fdf23c6a64ed33277c98569e13 Your Name 2019-11-29 09:26:12
new types for Scene e2fde0d2b66e125ba3bfd86b8f51c81ecb5ab047 Your Name 2019-11-29 00:38:27
Commit 66f541c32f51d6ed6f90fba1f3b58561726e8659 - refactoring
Author: Jackalope
Author date (UTC): 2020-05-10 00:55
Committer name: Jackalope
Committer date (UTC): 2020-05-10 00:55
Parent(s): 3a6a7fbe488d19b990f6368d8d56512c45c20766
Signing key:
Tree: cc2d12a8cd9f7230ef9ae73d74d2c91d559b1cdb
File Lines added Lines deleted
CMakeLists.txt 0 2
include/jrf/image.h 70 91
include/jrf/indices.h 40 46
include/jrf/jrf.h 35 41
include/jrf/mesh.h 99 109
include/jrf/model.h 27 37
include/jrf/read.h 90 111
include/jrf/result.h 77 80
include/jrf/scene.h 99 123
include/jrf/vertices.h 71 87
include/jrf/write.h 28 32
include/jrf/zip.h 368 370
src/result.cpp 56 66
File CMakeLists.txt changed (mode: 100644) (index e73ee54..96f88e8)
1 1 cmake_minimum_required(VERSION 3.5) cmake_minimum_required(VERSION 3.5)
2
3 2 set(JRF_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/include PARENT_SCOPE) set(JRF_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/include PARENT_SCOPE)
4
5 3 add_library(JRF STATIC src/result.cpp) add_library(JRF STATIC src/result.cpp)
6 4 target_include_directories(JRF PUBLIC include ${LIBZIP_INCLUDE_DIR}) target_include_directories(JRF PUBLIC include ${LIBZIP_INCLUDE_DIR})
7 5 target_link_libraries(JRF ${LIBZIP_INCLUDE_LIBS}) target_link_libraries(JRF ${LIBZIP_INCLUDE_LIBS})
File include/jrf/image.h changed (mode: 100644) (index a52b381..bec75b7)
1 1 #pragma once #pragma once
2
3 2 #include <jlib/io_agent.h> #include <jlib/io_agent.h>
4 3 #include <jlib/allocate.h> #include <jlib/allocate.h>
5 4 #include "result.h" #include "result.h"
6 5
7 namespace jrf
6 namespace jrf { struct Image; }
7 struct jrf::Image
8 8 { {
9 struct Image
10 {
11 constexpr static const uint16_t DEPTH_LIMIT = uint16_t(~0u);
12 struct Extent
13 {
14 uint16_t width;
15 uint16_t height;
16 uint16_t depth;
17 uint16_t pixelSize;
18
19 [[nodiscard]] inline uint64_t pixel_count() { return width * height * depth; }
20 [[nodiscard]] inline uint64_t size() { return pixel_count() * pixelSize; }
21
22 [[nodiscard]] inline bool sameUV(const Extent& other)
23 {
24 return width == other.width && height == other.height;
25 }
26 };
27 static_assert (sizeof (Extent) == 8, "Important for read & write file");
28
29 enum Format
30 {
31 B8G8R8_SRGB = 36,
32 B8G8R8A8_SRGB = 50,
33 R8G8B8A8_SRGB = 152
34 };
35 static_assert (sizeof(Format) == 4, "Important for read & write file");
36
37 [[nodiscard]] inline bool init(Extent extent_, Format format_)
38 {
39 extent = extent_;
40 size = extent.size();
41 format = format_;
42
43 return jl::allocate_bytes(&p_pixels, size);
44 }
45
46 inline void destroy()
47 {
48 jl::deallocate(&p_pixels);
49 }
50
51
52 template<typename IO = jl::io_agent>
53 [[nodiscard]] Result read(IO *p_mediator)
54 {
55 if (p_mediator->read(&extent, sizeof(extent)) != sizeof(extent))
56 return Result::MEDIATOR_ERROR;
57 if (p_mediator->read(&format, sizeof(format)) != sizeof(format))
58 return Result::MEDIATOR_ERROR;
59
60 size = extent.size();
61
62 if (size == 0)
63 {
64 p_pixels = nullptr;
65 return Result::FILE_NO_DATA;
66 }
67
68 if (not jl::allocate_bytes(&p_pixels, size))
69 return Result::ALLOCATION_FAIL;
70
71 if (p_mediator->read(p_pixels, size) != int64_t(size)) {
72 destroy();
73 return Result::MEDIATOR_ERROR;
74 }
75
76 return Result::SUCCESS;
77 }
78
79 template<typename IO = jl::io_agent>
80 [[nodiscard]] Result write(IO *p_mediator) const
81 {
82 if (p_mediator->write(&extent, sizeof(extent)) != sizeof(extent))
83 return Result::MEDIATOR_ERROR;
84 if (p_mediator->write(&format, sizeof(format)) != sizeof(format))
85 return Result::MEDIATOR_ERROR;
86 if (p_mediator->write(p_pixels, size) != int64_t(size))
87 return Result::MEDIATOR_ERROR;
88
89 return Result::SUCCESS;
90 }
91
92 void *p_pixels;
93 uint64_t size;
94 Extent extent;
95 Format format;
96 };
97 }
9 constexpr static const uint16_t DEPTH_LIMIT = uint16_t(~0u);
10 struct Extent {
11 [[nodiscard]] uint64_t pixel_count() {
12 return width * height * depth;
13 }
14 [[nodiscard]] uint64_t size() {
15 return pixel_count() * pixelSize;
16 }
17 [[nodiscard]] bool sameUV(const Extent& other) {
18 return width == other.width && height == other.height;
19 }
20 uint16_t width;
21 uint16_t height;
22 uint16_t depth;
23 uint16_t pixelSize;
24 };
25 static_assert (sizeof (Extent) == 8, "Important for compatibility");
26
27 enum Format {
28 B8G8R8_SRGB = 36,
29 B8G8R8A8_SRGB = 50,
30 R8G8B8A8_SRGB = 152
31 };
32 static_assert (sizeof(Format) == 4, "Important for compatibility");
33
34 [[nodiscard]] bool init(Extent extent, Format format) {
35 this->extent = extent;
36 this->size = extent.size();
37 this->format = format;
38 return jl::allocate_bytes(&p_pixels, size);
39 }
40 void destroy() {
41 jl::deallocate(&p_pixels);
42 }
43 template<typename IO = jl::io_agent> [[nodiscard]]
44 Result read(IO *p_mediator) {
45 if (p_mediator->read(&extent, sizeof(extent)) != sizeof(extent))
46 return Result::MEDIATOR_ERROR;
47 if (p_mediator->read(&format, sizeof(format)) != sizeof(format))
48 return Result::MEDIATOR_ERROR;
49 size = extent.size();
50 if (size == 0) {
51 p_pixels = nullptr;
52 return Result::FILE_NO_DATA;
53 }
54 if (not jl::allocate_bytes(&p_pixels, size))
55 return Result::ALLOCATION_FAIL;
56 if (p_mediator->read(p_pixels, size) != int64_t(size)) {
57 destroy();
58 return Result::MEDIATOR_ERROR;
59 }
60 return Result::SUCCESS;
61 }
62 template<typename IO = jl::io_agent> [[nodiscard]]
63 Result write(IO *p_mediator) const {
64 if (p_mediator->write(&extent, sizeof(extent)) != sizeof(extent))
65 return Result::MEDIATOR_ERROR;
66 if (p_mediator->write(&format, sizeof(format)) != sizeof(format))
67 return Result::MEDIATOR_ERROR;
68 if (p_mediator->write(p_pixels, size) != int64_t(size))
69 return Result::MEDIATOR_ERROR;
70 return Result::SUCCESS;
71 }
72 void *p_pixels;
73 uint64_t size;
74 Extent extent;
75 Format format;
76 };
File include/jrf/indices.h changed (mode: 100644) (index 3513cff..5c2486c)
1 1 #pragma once #pragma once
2
3 2 #include <jlib/io_agent.h> #include <jlib/io_agent.h>
4 3 #include <jlib/allocate.h> #include <jlib/allocate.h>
5 4 #include "result.h" #include "result.h"
6 5
7 6 namespace jrf namespace jrf
8 7 { {
9 enum IndexFormat : uint32_t { U16 = 2, U32 = 4 };
10
11 struct Indices
12 {
13 uint8_t *p_data;
14 uint64_t size;
15 IndexFormat format;
16
17 void destroy() { jl::deallocate(&p_data); }
18
19 template<typename IO = jl::io_agent>
20 [[nodiscard]] Result read(IO *p_mediator)
21 {
22 auto *p_io = jl::io_agent_p_alt_cast(p_mediator);
23 if (not p_io->read_items(&format))
24 return Result::MEDIATOR_ERROR;
25 if (not p_io->read_items(&size))
26 return Result::MEDIATOR_ERROR;
27
28 if (size == 0)
29 p_data = nullptr;
30 else
31 {
32 if (not jl::allocate_bytes(&p_data, size))
33 return Result::MEDIATOR_ERROR;
34 if (not p_io->read_bytes(p_data, size))
35 return this->destroy(), Result::MEDIATOR_ERROR;
36 }
37 return Result::SUCCESS;
38 }
39
40 template<typename IO = jl::io_agent>
41 [[nodiscard]] Result write(IO *p_mediator) const
42 {
43 auto *p_io = jl::io_agent_p_alt_cast(p_mediator);
44 if (not p_io->write_items(&format))
45 return Result::MEDIATOR_ERROR;
46 if (not p_io->write_items(&size))
47 return Result::MEDIATOR_ERROR;
48 if (not p_io->write_bytes(p_data, size))
49 return Result::MEDIATOR_ERROR;
50
51 return Result::SUCCESS;
52 }
53 };
8 enum IndexFormat : uint32_t { U16 = 2, U32 = 4 };
9 struct Indices;
54 10 } }
11 struct jrf::Indices
12 {
13 void destroy() {
14 jl::deallocate(&p_data);
15 }
16 template<typename IO = jl::io_agent> [[nodiscard]]
17 Result read(IO *p_mediator) {
18 auto *p_io = jl::io_agent_p_alt_cast(p_mediator);
19 if (not p_io->read_items(&format))
20 return Result::MEDIATOR_ERROR;
21 if (not p_io->read_items(&size))
22 return Result::MEDIATOR_ERROR;
23 if (size == 0)
24 p_data = nullptr;
25 else {
26 if (not jl::allocate_bytes(&p_data, size))
27 return Result::MEDIATOR_ERROR;
28 if (not p_io->read_bytes(p_data, size))
29 return this->destroy(), Result::MEDIATOR_ERROR;
30 }
31 return Result::SUCCESS;
32 }
33 template<typename IO = jl::io_agent> [[nodiscard]]
34 Result write(IO *p_mediator) const {
35 auto *p_io = jl::io_agent_p_alt_cast(p_mediator);
36 if (not p_io->write_items(&format))
37 return Result::MEDIATOR_ERROR;
38 if (not p_io->write_items(&size))
39 return Result::MEDIATOR_ERROR;
40 if (not p_io->write_bytes(p_data, size))
41 return Result::MEDIATOR_ERROR;
42
43 return Result::SUCCESS;
44 }
45 uint8_t *p_data;
46 uint64_t size;
47 IndexFormat format;
48 };
File include/jrf/jrf.h changed (mode: 100644) (index ca76334..31d2fb3)
4 4
5 5 namespace jrf namespace jrf
6 6 { {
7 template<ResourceType RT>
8 struct Resource { using T = void; };
7 template<ResourceType RT>
8 struct Resource { using T = void; };
9 9
10 template<>
11 struct Resource<ResourceType::IMAGE> { using T = Image; };
12 template<>
13 struct Resource<ResourceType::VERTICES> { using T = Vertices; };
14 template<>
15 struct Resource<ResourceType::INDICES> { using T = Indices; };
16 template<>
17 struct Resource<ResourceType::MESH> { using T = Mesh; };
18 template<>
19 struct Resource<ResourceType::MODEL> { using T = Model; };
20 template<>
21 struct Resource<ResourceType::SCENE> { using T = Scene; };
10 template<> struct Resource<ResourceType::IMAGE> { using T = Image; };
11 template<> struct Resource<ResourceType::VERTICES> { using T = Vertices; };
12 template<> struct Resource<ResourceType::INDICES> { using T = Indices; };
13 template<> struct Resource<ResourceType::MESH> { using T = Mesh; };
14 template<> struct Resource<ResourceType::MODEL> { using T = Model; };
15 template<> struct Resource<ResourceType::SCENE> { using T = Scene; };
22 16
23 union ResourceUnion {
24 Image image;
25 Vertices vertices;
26 Indices indices;
27 Mesh mesh;
28 Model model;
29 Scene scene;
30 };
17 union ResourceUnion {
18 Image image;
19 Vertices vertices;
20 Indices indices;
21 Mesh mesh;
22 Model model;
23 Scene scene;
24 };
31 25
32 static const constexpr union {
33 uint64_t integer;
34 uint8_t data[8] = {'j','r','f','0','0','0','0'};
35 } MAGIC {};
26 static const constexpr union {
27 uint64_t integer;
28 uint8_t data[8] = {'j','r','f','0','0','0','0'};
29 } MAGIC {};
36 30
37 struct EntryHeader {
38 uint64_t magic;
39 ResourceType type;
40 };
31 struct EntryHeader {
32 uint64_t magic;
33 ResourceType type;
34 };
41 35
42 void inline destroy(ResourceType type, ResourceUnion *p_ru) {
43 switch(type) {
44 case ResourceType::IMAGE: p_ru->image .destroy(); break;
45 case ResourceType::VERTICES: p_ru->vertices.destroy(); break;
46 case ResourceType::INDICES: p_ru->indices .destroy(); break;
47 case ResourceType::MESH: p_ru->mesh .destroy(); break;
48 case ResourceType::MODEL: p_ru->model .destroy(); break;
49 case ResourceType::SCENE: p_ru->scene .destroy(); break;
50 default: return;
51 }
52 }
36 void inline destroy(ResourceType type, ResourceUnion *p_ru) {
37 switch(type) {
38 case ResourceType::IMAGE: p_ru->image .destroy(); break;
39 case ResourceType::VERTICES: p_ru->vertices.destroy(); break;
40 case ResourceType::INDICES: p_ru->indices .destroy(); break;
41 case ResourceType::MESH: p_ru->mesh .destroy(); break;
42 case ResourceType::MODEL: p_ru->model .destroy(); break;
43 case ResourceType::SCENE: p_ru->scene .destroy(); break;
44 default: return;
45 }
46 }
53 47 } }
File include/jrf/mesh.h changed (mode: 100644) (index 51878a1..356556b)
1 1 #pragma once #pragma once
2
3 2 #include "vertices.h" #include "vertices.h"
4 3 #include "indices.h" #include "indices.h"
5 4 #include <jlib/string.h> #include <jlib/string.h>
 
7 6
8 7 namespace jrf namespace jrf
9 8 { {
10 template<typename IO = jl::io_agent>
11 [[nodiscard]] Result read_str(IO *p_io, jl::string *p_dst)
12 {
13 jl::darray<char> path_tmp;
14 path_tmp.init();
15 char sym;
16 do {
17 if (p_io->read(&sym, 1) != 1)
18 return Result::MEDIATOR_ERROR;
19 if (not path_tmp.insert(sym))
20 return Result::ALLOCATION_FAIL;
21 }
22 while(sym != '\0');
23 *p_dst = {path_tmp.begin(), path_tmp.end()};
24 return Result::SUCCESS;
25 }
26
27 template<typename T>
28 struct Data {
29 union {
30 T data;
31 jl::string path;
32 } u;
33 ResourceMode mode;
34
35 void destroy() {
36 switch(mode) {
37 case ResourceMode::DATA: u.data.destroy(); break;
38 case ResourceMode::PATH: u.path.destroy(); break;
39 case ResourceMode::NONE: break;
40 }
41 }
42
43 template<typename IO = jl::io_agent>
44 [[nodiscard]] Result read(IO *p_io)
45 {
46 if (p_io->read(&mode, sizeof(mode)) != sizeof(mode))
47 return Result::MEDIATOR_ERROR;
48 switch(mode)
49 {
50 case ResourceMode::NONE: break;
51 case ResourceMode::DATA: {
52 Result res = u.data.read(p_io);
53 if (res != Result::SUCCESS)
54 return res;
55 } break;
56 case ResourceMode::PATH: {
57 auto res = read_str(p_io, &u.path);
58 if (res != Result::SUCCESS)
59 return res;
60 }
61 }
62 return Result::SUCCESS;
63 }
64 template<typename IO = jl::io_agent>
65 [[nodiscard]] Result write(IO *p_io) const
66 {
67 if (p_io->write(&mode, sizeof(mode)) != sizeof(mode))
68 return Result::MEDIATOR_ERROR;
69 switch(mode) {
70 case ResourceMode::DATA: {
71 Result res = u.data.write(p_io);
72 if (res != Result::SUCCESS)
73 return res;
74 } break;
75 case ResourceMode::PATH: {
76 if (p_io->write(u.path.begin(), u.path.size())
77 != int64_t(u.path.size()))
78 return Result::MEDIATOR_ERROR;
79 } break;
80 default: break;
81 }
82 return Result::SUCCESS;
83 }
84 };
85
86 struct Mesh
87 {
88 Data<Vertices> vert;
89 Data<Indices> ind;
90
91 void destroy() {
92 vert.destroy();
93 ind .destroy();
94 }
95
96 template<typename IO = jl::io_agent>
97 [[nodiscard]] Result read(IO *p_mediator)
98 {
99 Result res;
100 res = vert.read(p_mediator);
101 if (res != Result::SUCCESS)
102 return res;
103 res = ind.read(p_mediator);
104 if (res != Result::SUCCESS)
105 vert.destroy();
106 return res;
107 }
108
109 template<typename IO = jl::io_agent>
110 [[nodiscard]] Result write(IO *p_mediator) const
111 {
112 Result res = vert.write(p_mediator);
113 if (res != Result::SUCCESS)
114 return res;
115 return ind.write(p_mediator);
116 }
117 };
9 template<typename IO = jl::io_agent> [[nodiscard]]
10 Result read_str(IO *p_io, jl::string *p_dst) {
11 jl::darray<char> path_tmp;
12 path_tmp.init();
13 char sym;
14 do {
15 if (p_io->read(&sym, 1) != 1)
16 return Result::MEDIATOR_ERROR;
17 if (not path_tmp.insert(sym))
18 return Result::ALLOCATION_FAIL;
19 }
20 while(sym != '\0');
21 *p_dst = {path_tmp.begin(), path_tmp.end()};
22 return Result::SUCCESS;
23 }
24 template<typename T>
25 struct Data;
26 struct Mesh;
118 27 } }
28 template<typename T>
29 struct jrf::Data
30 {
31 void destroy() {
32 switch(mode) {
33 case ResourceMode::DATA: u.data.destroy(); break;
34 case ResourceMode::PATH: u.path.destroy(); break;
35 case ResourceMode::NONE: break;
36 }
37 }
38 template<typename IO = jl::io_agent> [[nodiscard]]
39 Result read(IO *p_io) {
40 if (p_io->read(&mode, sizeof(mode)) != sizeof(mode))
41 return Result::MEDIATOR_ERROR;
42 switch(mode) {
43 case ResourceMode::NONE: break;
44 case ResourceMode::DATA: {
45 Result res = u.data.read(p_io);
46 if (res != Result::SUCCESS)
47 return res;
48 } break;
49 case ResourceMode::PATH: {
50 auto res = read_str(p_io, &u.path);
51 if (res != Result::SUCCESS)
52 return res;
53 }
54 }
55 return Result::SUCCESS;
56 }
57 template<typename IO = jl::io_agent> [[nodiscard]]
58 Result write(IO *p_io) const {
59 if (p_io->write(&mode, sizeof(mode)) != sizeof(mode))
60 return Result::MEDIATOR_ERROR;
61 switch(mode) {
62 case ResourceMode::DATA: {
63 Result res = u.data.write(p_io);
64 if (res != Result::SUCCESS)
65 return res;
66 } break;
67 case ResourceMode::PATH: {
68 if (p_io->write(u.path.begin(), u.path.size())
69 != int64_t(u.path.size()))
70 return Result::MEDIATOR_ERROR;
71 } break;
72 default: break;
73 }
74 return Result::SUCCESS;
75 }
76 union {
77 T data;
78 jl::string path;
79 } u;
80 ResourceMode mode;
81 };
82 struct jrf::Mesh
83 {
84 void destroy() {
85 vert.destroy();
86 ind .destroy();
87 }
88 template<typename IO = jl::io_agent> [[nodiscard]]
89 Result read(IO *p_mediator) {
90 Result res;
91 res = vert.read(p_mediator);
92 if (res != Result::SUCCESS)
93 return res;
94 res = ind.read(p_mediator);
95 if (res != Result::SUCCESS)
96 vert.destroy();
97 return res;
98 }
99 template<typename IO = jl::io_agent> [[nodiscard]]
100 Result write(IO *p_mediator) const {
101 Result res = vert.write(p_mediator);
102 if (res != Result::SUCCESS)
103 return res;
104 return ind.write(p_mediator);
105 }
106 Data<Vertices> vert;
107 Data<Indices> ind;
108 };
File include/jrf/model.h changed (mode: 100644) (index cf7285c..541c20f)
1 1 #pragma once #pragma once
2
3 2 #include "mesh.h" #include "mesh.h"
4 3 #include "image.h" #include "image.h"
5 4
6
7 namespace jrf
5 namespace jrf { struct Model; }
6 struct jrf::Model
8 7 { {
9 struct Model
10 {
11 Data<Mesh> mesh;
12 Data<Image> image;
13
14 void destroy() {
15 mesh.destroy();
16 image.destroy();
17 }
18
19 template<typename IO = jl::io_agent>
20 [[nodiscard]] Result read(IO *p_mediator)
21 {
22 Result res;
23 res = mesh.read(p_mediator);
24 if (res != Result::SUCCESS)
25 return res;
26
27 res = image.read(p_mediator);
28 if (res != Result::SUCCESS)
29 mesh.destroy();
30 return res;
31 }
32
33 template<typename IO = jl::io_agent>
34 [[nodiscard]] Result write(IO *p_io) const
35 {
36 Result res = mesh.write(p_io);
37 if (res != Result::SUCCESS)
38 return res;
39 return image.write(p_io);
40 }
41 };
42 }
8 void destroy() {
9 mesh.destroy();
10 image.destroy();
11 }
12 template<typename IO = jl::io_agent> [[nodiscard]]
13 Result read(IO *p_mediator) {
14 Result res;
15 res = mesh.read(p_mediator);
16 if (res != Result::SUCCESS)
17 return res;
18 res = image.read(p_mediator);
19 if (res != Result::SUCCESS)
20 mesh.destroy();
21 return res;
22 }
23 template<typename IO = jl::io_agent> [[nodiscard]]
24 Result write(IO *p_io) const {
25 Result res = mesh.write(p_io);
26 if (res != Result::SUCCESS)
27 return res;
28 return image.write(p_io);
29 }
30 Data<Mesh> mesh;
31 Data<Image> image;
32 };
File include/jrf/read.h changed (mode: 100644) (index cb2c8fd..a3e5842)
1 1 #pragma once #pragma once
2
3 2 #include "jrf.h" #include "jrf.h"
4 3 #include "zip.h" #include "zip.h"
5 4 #include <jlib/io_agent_mem_ro.h> #include <jlib/io_agent_mem_ro.h>
6 5 #include <jlib/fs.h> #include <jlib/fs.h>
7 6
8 namespace jrf::details
9 {
10 template<typename IO = jl::io_agent>
11 [[nodiscard]] inline Result read(IO *p_io, ResourceType type,
12 ResourceUnion *p_ru)
13 {
14 switch(type)
15 {
16 case ResourceType::IMAGE: return p_ru->image .read(p_io);
17 case ResourceType::VERTICES: return p_ru->vertices.read(p_io);
18 case ResourceType::INDICES: return p_ru->indices .read(p_io);
19 case ResourceType::MESH: return p_ru->mesh .read(p_io);
20 case ResourceType::MODEL: return p_ru->model .read(p_io);
21 case ResourceType::SCENE: return p_ru->scene .read(p_io);
22 default: return Result::UNKNOWN_RESOURCE_TYPE;
23 }
24 }
7 namespace jrf::details {
8 template<typename IO = jl::io_agent>
9 [[nodiscard]] inline
10 Result read(IO *p_io, ResourceType type, ResourceUnion *p_ru) {
11 switch(type) {
12 case ResourceType::IMAGE: return p_ru->image .read(p_io);
13 case ResourceType::VERTICES: return p_ru->vertices.read(p_io);
14 case ResourceType::INDICES: return p_ru->indices .read(p_io);
15 case ResourceType::MESH: return p_ru->mesh .read(p_io);
16 case ResourceType::MODEL: return p_ru->model .read(p_io);
17 case ResourceType::SCENE: return p_ru->scene .read(p_io);
18 default: return Result::UNKNOWN_RESOURCE_TYPE;
19 }
20 }
25 21 } }
26 22 namespace jrf namespace jrf
27 23 { {
28 template<typename IO = jl::io_agent>
29 [[nodiscard]] inline Result read(IO *p_mediator, ResourceUnion *p_ru)
30 {
31 EntryHeader header;
32
33 if (not p_mediator->read(&header, sizeof (EntryHeader)))
34 return MEDIATOR_ERROR;
35 if (header.magic != MAGIC.integer)
36 return Result::FILE_WRONG_HEADER;
37 return details::read(p_mediator, header.type, p_ru);
38 }
39
40 template<ResourceType RT, typename IO = jl::io_agent>
41 [[nodiscard]] inline Result read(IO *p_io,
42 typename Resource<RT>::T *p_resource)
43 {
44 EntryHeader header;
45
46 if (not p_io->read(&header, sizeof (EntryHeader)))
47 return MEDIATOR_ERROR;
48 if (header.magic != MAGIC.integer)
49 return Result::FILE_WRONG_HEADER;
50 if (header.type != RT)
51 return Result::RESOURCE_TYPE_MISMATCH;
52 return p_resource->read(p_io);
53 }
54
55 template<ResourceType RT>
56 [[nodiscard]] inline Result read(typename Resource<RT>::T *p_resource,
57 const char *p_file_path)
58 {
59 char *f_data;
60 uint64_t fsize;
61 if (not jl::fs::read_file(p_file_path, &f_data, &fsize))
62 return Result::FILE_OPEN_ERROR;
63
64 jl::io_agent_mem_ro m;
65 m.init(f_data, fsize);
66 auto res = read<RT>(&m, p_resource);
67 jl::deallocate(&f_data);
68 if (res == Result::MEDIATOR_ERROR)
69 if (m.is_end())
70 return Result::FILE_UNEXPECTED_EOF;
71 return res;
72 }
73
74 template<ResourceType RT>
75 [[nodiscard]] inline Result read(typename Resource<RT>::T *p_resource,
76 const char *p_zip_path, const char *p_fpath_in_zip)
77 {
78 ZipArchive zip;
79 auto zres = zip.open(p_zip_path);
80 if (zres != ZipResult::SUCCESS)
81 return Result::ZIP_ERROR;
82
83 char *f_data;
84 uint64_t fsize;
85 zres = ZipSubFile::read_whole_file(&zip, p_fpath_in_zip, &f_data, &fsize);
86 (void)zip.close();
87 if (zres != ZipResult::SUCCESS)
88 return Result::ZIP_ERROR;
89
90 jl::io_agent_mem_ro m;
91 m.init(f_data, fsize);
92 auto res = read<RT>(&m, p_resource);
93 jl::deallocate(&f_data);
94 if (res == Result::MEDIATOR_ERROR)
95 if (m.is_end())
96 return Result::FILE_UNEXPECTED_EOF;
97 return res;
98 }
24 template<typename IO = jl::io_agent> [[nodiscard]] inline
25 Result read(IO *p_mediator, ResourceUnion *p_ru) {
26 EntryHeader header;
27 if (not p_mediator->read(&header, sizeof (EntryHeader)))
28 return MEDIATOR_ERROR;
29 if (header.magic != MAGIC.integer)
30 return Result::FILE_WRONG_HEADER;
31 return details::read(p_mediator, header.type, p_ru);
32 }
33 template<ResourceType RT, typename IO = jl::io_agent> [[nodiscard]] inline
34 Result read(IO *p_io, typename Resource<RT>::T *p_resource) {
35 EntryHeader header;
36 if (not p_io->read(&header, sizeof (EntryHeader)))
37 return MEDIATOR_ERROR;
38 if (header.magic != MAGIC.integer)
39 return Result::FILE_WRONG_HEADER;
40 if (header.type != RT)
41 return Result::RESOURCE_TYPE_MISMATCH;
42 return p_resource->read(p_io);
43 }
44 template<ResourceType RT> [[nodiscard]] inline
45 Result read(typename Resource<RT>::T *p_resource, const char *p_file_path) {
46 char *f_data;
47 uint64_t fsize;
48 if (not jl::fs::read_file(p_file_path, &f_data, &fsize))
49 return Result::FILE_OPEN_ERROR;
50 jl::io_agent_mem_ro m;
51 m.init(f_data, fsize);
52 auto res = read<RT>(&m, p_resource);
53 jl::deallocate(&f_data);
54 if (res == Result::MEDIATOR_ERROR)
55 if (m.is_end())
56 return Result::FILE_UNEXPECTED_EOF;
57 return res;
58 }
99 59
100 //single path - file path, two paths - zip and file in zip
101 template<typename ... PATHS>
102 [[nodiscard]] inline Result read(ResourceType type, ResourceUnion *p_ru,
103 PATHS ... paths)
104 {
105 switch(type)
106 {
107 case ResourceType::IMAGE:
108 return read<ResourceType::IMAGE> (&p_ru->image, paths...);
109 case ResourceType::VERTICES:
110 return read<ResourceType::VERTICES>(&p_ru->vertices, paths...);
111 case ResourceType::INDICES:
112 return read<ResourceType::INDICES> (&p_ru->indices, paths...);
113 case ResourceType::MESH:
114 return read<ResourceType::MESH> (&p_ru->mesh, paths...);
115 case ResourceType::MODEL:
116 return read<ResourceType::MODEL> (&p_ru->model, paths...);
117 case ResourceType::SCENE:
118 return read<ResourceType::SCENE> (&p_ru->scene, paths...);
119 default: return Result::UNKNOWN_RESOURCE_TYPE;
120 }
121 }
60 template<ResourceType RT> [[nodiscard]] inline
61 Result read(typename Resource<RT>::T *p_resource,
62 const char *p_zip_path, const char *p_fpath_in_zip) {
63 ZipArchive zip;
64 auto zres = zip.open(p_zip_path);
65 if (zres != ZipResult::SUCCESS)
66 return Result::ZIP_ERROR;
67 char *f_data;
68 uint64_t fsize;
69 zres = ZipSubFile::read_whole_file(&zip, p_fpath_in_zip, &f_data, &fsize);
70 (void)zip.close();
71 if (zres != ZipResult::SUCCESS)
72 return Result::ZIP_ERROR;
73 jl::io_agent_mem_ro m;
74 m.init(f_data, fsize);
75 auto res = read<RT>(&m, p_resource);
76 jl::deallocate(&f_data);
77 if (res == Result::MEDIATOR_ERROR)
78 if (m.is_end())
79 return Result::FILE_UNEXPECTED_EOF;
80 return res;
81 }
82 //single path - file path, two paths - zip and file in zip
83 template<typename ... PATHS> [[nodiscard]] inline
84 Result read(ResourceType type, ResourceUnion *p_ru, PATHS ... paths) {
85 switch(type) {
86 case ResourceType::IMAGE:
87 return read<ResourceType::IMAGE> (&p_ru->image, paths...);
88 case ResourceType::VERTICES:
89 return read<ResourceType::VERTICES>(&p_ru->vertices, paths...);
90 case ResourceType::INDICES:
91 return read<ResourceType::INDICES> (&p_ru->indices, paths...);
92 case ResourceType::MESH:
93 return read<ResourceType::MESH> (&p_ru->mesh, paths...);
94 case ResourceType::MODEL:
95 return read<ResourceType::MODEL> (&p_ru->model, paths...);
96 case ResourceType::SCENE:
97 return read<ResourceType::SCENE> (&p_ru->scene, paths...);
98 default: return Result::UNKNOWN_RESOURCE_TYPE;
99 }
100 }
122 101 } }
File include/jrf/result.h changed (mode: 100644) (index cd1ab32..66a918e)
3 3
4 4 namespace jrf namespace jrf
5 5 { {
6 enum ResourceType : uint8_t {
7 VERTICES,
8 INDICES,
9 MESH,
10 IMAGE,
11 MODEL,
12 SCENE, OPTIONS, ENTRY,
13 COUNT
14 };
6 enum ResourceType : uint8_t {
7 VERTICES,
8 INDICES,
9 MESH,
10 IMAGE,
11 MODEL,
12 SCENE, OPTIONS, ENTRY,
13 COUNT
14 };
15 constexpr static const char* RES_TYPE_STR[ResourceType::COUNT+1] = {
16 "Vertices",
17 "Indices",
18 "Mesh",
19 "Image",
20 "Model",
21 "Scene", "Options", "Entry",
22 "Unknown"
23 };
24 constexpr static const uint16_t RES_TYPE_STR_LENGTH[ResourceType::COUNT+1] = {
25 8, 7, 4, 5, 5, 5, 7, 5, 0
26 };
27 enum class ResourceMode : uint8_t {
28 NONE, DATA, PATH
29 };
30 enum [[nodiscard]] Result {
31 SUCCESS,
32 SRC_MTIME_LESS_THAN_JRF,
15 33
16 constexpr static const char* RES_TYPE_STR[ResourceType::COUNT+1] = {
17 "Vertices",
18 "Indices",
19 "Mesh",
20 "Image",
21 "Model",
22 "Scene", "Options", "Entry",
23 "Unknown"
24 };
34 //parse
35 TOO_MANY_ARGUMENTS,
36 MISSING_ARGUMENTS,
37 EXPECTED_FILE_PATH,
38 INCORRECT_FORMAT,
39 UNKNOWN_TYPE,
40 UNKNOWN_OPTION,
41 EXPECTED_PARENTHESIS_OPEN,
42 EXPECTED_PARENTHESIS_CLOSE,
43 EXCESS_PARENTHESIS_CLOSE,
44 EXPECTED_QUOTATION_MARKS,
45 EXPECTED_NAME,
46 EXPECTED_ARGUMENT,
47 EXPECTED_TYPE,
48 INCOMPATIBLE_RESOURCES,
49 RESOURCE_PART_DUPLICATE,
50 RESOURCE_PART_MISSING,
51 RESOURCE_PART_OVERLAP,
52 RESOURCE_TYPE_MISMATCH,
53 SCENE_ENTRY_MODEL_IS_NOT_PATH,
25 54
26 constexpr static const uint16_t RES_TYPE_STR_LENGTH[ResourceType::COUNT+1]
27 = { 8, 7, 4, 5, 5, 5, 7, 5, 0 };
55 FILE_WRONG_HEADER,
56 FILE_OPEN_ERROR,
57 FILE_NO_DATA,
58 FILE_CORRUPTED,
59 DIRECTORY_ERROR,
60 FILE_UNEXPECTED_EOF,
28 61
29 enum class ResourceMode : uint8_t { NONE, DATA, PATH };
62 //zip
63 ZIP_IN_ZIP_UNSUPPORTED,
64 ZIP_ERROR,
30 65
31 enum [[nodiscard]] Result
32 {
33 SUCCESS,
34 SRC_MTIME_LESS_THAN_JRF,
66 //misc
67 UNKNOWN_RESOURCE_TYPE,
68 MEDIATOR_ERROR,
69 ALLOCATION_FAIL,
35 70
36 //parse
37 TOO_MANY_ARGUMENTS,
38 MISSING_ARGUMENTS,
39 EXPECTED_FILE_PATH,
40 INCORRECT_FORMAT,
41 UNKNOWN_TYPE,
42 UNKNOWN_OPTION,
43 EXPECTED_PARENTHESIS_OPEN,
44 EXPECTED_PARENTHESIS_CLOSE,
45 EXCESS_PARENTHESIS_CLOSE,
46 EXPECTED_QUOTATION_MARKS,
47 EXPECTED_NAME,
48 EXPECTED_ARGUMENT,
49 EXPECTED_TYPE,
50 INCOMPATIBLE_RESOURCES,
51 RESOURCE_PART_DUPLICATE,
52 RESOURCE_PART_MISSING,
53 RESOURCE_PART_OVERLAP,
54 RESOURCE_TYPE_MISMATCH,
55 SCENE_ENTRY_MODEL_IS_NOT_PATH,
71 //image
72 COLOR_MAP_UNSUPPORTED,
73 IMAGE_DATA_TYPE_UNSUPPORTED,
74 PIXEL_SIZE_UNSUPPORTED,
75 TGA_RLE_UNSUPPORTED,
76 IMAGE_LAYERS_EXTENT_MISMATCH,
77 IMAGE_LAYERS_FORMAT_MISMATCH,
56 78
57 FILE_WRONG_HEADER,
58 FILE_OPEN_ERROR,
59 FILE_NO_DATA,
60 FILE_CORRUPTED,
61 DIRECTORY_ERROR,
62 FILE_UNEXPECTED_EOF,
79 //obj file
80 OBJ_FILE_PARSE_ERROR,
81 OBJ_INDEX_CANT_BE_ZERO,
82 OBJ_FACE_HAVE_MORE_THAN_4_INDICES,
63 83
64 //zip
65 ZIP_IN_ZIP_UNSUPPORTED,
66 ZIP_ERROR,
67
68 //misc
69 UNKNOWN_RESOURCE_TYPE,
70 MEDIATOR_ERROR,
71 ALLOCATION_FAIL,
72
73 //image
74 COLOR_MAP_UNSUPPORTED,
75 IMAGE_DATA_TYPE_UNSUPPORTED,
76 PIXEL_SIZE_UNSUPPORTED,
77 TGA_RLE_UNSUPPORTED,
78 IMAGE_LAYERS_EXTENT_MISMATCH,
79 IMAGE_LAYERS_FORMAT_MISMATCH,
80
81 //obj file
82 OBJ_FILE_PARSE_ERROR,
83 OBJ_INDEX_CANT_BE_ZERO,
84 OBJ_FACE_HAVE_MORE_THAN_4_INDICES,
85
86 //indices
87 INDEX_VALUE_OVERFLOW,
88 //vertices
89 VERTICES_ATTRIBUTE_COUNT_MISMATCH,
90 };
91
92 const char* to_str(Result result);
84 //indices
85 INDEX_VALUE_OVERFLOW,
86 //vertices
87 VERTICES_ATTRIBUTE_COUNT_MISMATCH,
88 };
89 const char* to_str(Result result);
93 90 } }
File include/jrf/scene.h changed (mode: 100644) (index 5d2f1a0..d3c6f31)
1 1 #pragma once #pragma once
2
3 2 #include "model.h" #include "model.h"
4 3 #include <jlib/array.h> #include <jlib/array.h>
5 4
 
... ... namespace jrf { struct Scene; struct SceneEntry; }
7 6
8 7 struct jrf::SceneEntry struct jrf::SceneEntry
9 8 { {
10 struct Options {
11 void set_default()
12 {
13 pos = {};
14 shift = {};
15 transform = {};
16 transform[0] = transform[5] = transform[10] = transform[15] = 1;
17 }
18
19 jl::array<float, 3> pos; ///< position
20 jl::array<int32_t,3> shift; ///< shift of position
21 jl::array<float, 16> transform; ///< transformation matrix 4x4
22 };
23
24 void destroy() { model_path.destroy(); }
25
26 Options options;
27 jl::string model_path;
28
29 template<typename IO = jl::io_agent>
30 [[nodiscard]] Result read(IO *p_mediator)
31 {
32 Result res = read_str(p_mediator, &model_path);
33 if (res != Result::SUCCESS)
34 return res;
35
36 auto *p_io = jl::io_agent_p_alt_cast(p_mediator);
37 if (not p_io->read_items(&options.pos))
38 goto CANCEL;
39 if (not p_io->read_items(&options.shift))
40 goto CANCEL;
41 if (not p_io->read_items(&options.transform))
42 goto CANCEL;
43
44 return Result::SUCCESS;
45
9 template<typename IO = jl::io_agent> [[nodiscard]]
10 Result read(IO *p_mediator) {
11 Result res = read_str(p_mediator, &model_path);
12 if (res != Result::SUCCESS)
13 return res;
14 auto *p_io = jl::io_agent_p_alt_cast(p_mediator);
15 if (not p_io->read_items(&options.pos))
16 goto CANCEL;
17 if (not p_io->read_items(&options.shift))
18 goto CANCEL;
19 if (not p_io->read_items(&options.transform))
20 goto CANCEL;
21 return Result::SUCCESS;
46 22 CANCEL: destroy(); CANCEL: destroy();
47 return Result::MEDIATOR_ERROR;
48 }
49 template<typename IO = jl::io_agent>
50 [[nodiscard]] Result write(IO *p_mediator) const
51 {
52 if (p_mediator->write(model_path.begin(), model_path.size())
53 != int64_t(model_path.size()))
54 return Result::MEDIATOR_ERROR;
55
56 auto *p_io = jl::io_agent_p_alt_cast(p_mediator);
57 if (not p_io->write_items(&options.pos))
58 return Result::MEDIATOR_ERROR;
59 if (not p_io->write_items(&options.shift))
60 return Result::MEDIATOR_ERROR;
61 if (not p_io->write_items(&options.transform))
62 return Result::MEDIATOR_ERROR;
63
64 return Result::SUCCESS;
65 }
23 return Result::MEDIATOR_ERROR;
24 }
25 template<typename IO = jl::io_agent> [[nodiscard]]
26 Result write(IO *p_mediator) const {
27 if (p_mediator->write(model_path.begin(), model_path.size())
28 != int64_t(model_path.size()))
29 return Result::MEDIATOR_ERROR;
30 auto *p_io = jl::io_agent_p_alt_cast(p_mediator);
31 if (not p_io->write_items(&options.pos))
32 return Result::MEDIATOR_ERROR;
33 if (not p_io->write_items(&options.shift))
34 return Result::MEDIATOR_ERROR;
35 if (not p_io->write_items(&options.transform))
36 return Result::MEDIATOR_ERROR;
37 return Result::SUCCESS;
38 }
39 struct Options {
40 void set_default() {
41 pos = {};
42 shift = {};
43 transform = {};
44 transform[0] = transform[5] = transform[10] = transform[15] = 1;
45 }
46 jl::array<float, 3> pos; ///< position
47 jl::array<int32_t,3> shift; ///< shift of position
48 jl::array<float, 16> transform; ///< transformation matrix 4x4
49 };
50 void destroy() {
51 model_path.destroy();
52 }
53 Options options;
54 jl::string model_path;
66 55 }; };
67
68
69 56 struct jrf::Scene struct jrf::Scene
70 57 { {
71 struct Options {
72 void set_default_value() { *this = {}; }
73 jl::array<int32_t, 3> shift; ///< global shift of scene
74 int32_t shift_po2; ///< Power of two
75 };
76
77 Options options;
78 jl::rarray<SceneEntry> entries;
79
80 void destroy() { entries.destroy(&SceneEntry::destroy); }
81
82 template<typename IO = jl::io_agent>
83 [[nodiscard]] Result read(IO *p_mediator)
84 {
85 auto *p_io = jl::io_agent_p_alt_cast(p_mediator);
86 if (not p_io->read_items(&options.shift))
87 return Result::MEDIATOR_ERROR;
88 if (not p_io->read_items(&options.shift_po2))
89 return Result::MEDIATOR_ERROR;
90
91 uint64_t entry_count;
92 if (not p_io->read_items(&entry_count))
93 return Result::MEDIATOR_ERROR;
94
95 if (entry_count == 0) {
96 entries.init();
97 return Result::SUCCESS;
98 }
99 if (not entries.init(entry_count))
100 return Result::ALLOCATION_FAIL;
101
102 for (uint64_t i = 0; i < entry_count; ++i)
103 {
104 Result res = entries[i].read(p_mediator);
105 if (res != Result::SUCCESS)
106 {
107 while(i > 0)
108 entries[--i].destroy();
109 entries.destroy();
110 return res;
111 }
112 }
113 return Result::SUCCESS;
114 }
115
116 template<typename IO = jl::io_agent>
117 [[nodiscard]] Result write(IO *p_mediator) const
118 {
119 auto *p_io = jl::io_agent_p_alt_cast(p_mediator);
120 if (not p_io->write_items(&options.shift))
121 return Result::MEDIATOR_ERROR;
122 if (not p_io->write_items(&options.shift_po2))
123 return Result::MEDIATOR_ERROR;
124
125 size_t entry_count = entries.count();
126 if (not p_io->write_items(&entry_count))
127 return Result::MEDIATOR_ERROR;
128
129 for (auto &e : entries) {
130 Result res = e.write(p_mediator);
131 if (res != Result::SUCCESS)
132 return res;
133 }
134 return Result::SUCCESS;
135 }
58 void destroy() {
59 entries.destroy(&SceneEntry::destroy);
60 }
61 template<typename IO = jl::io_agent> [[nodiscard]]
62 Result read(IO *p_mediator) {
63 auto *p_io = jl::io_agent_p_alt_cast(p_mediator);
64 if (not p_io->read_items(&options.shift))
65 return Result::MEDIATOR_ERROR;
66 if (not p_io->read_items(&options.shift_po2))
67 return Result::MEDIATOR_ERROR;
68 uint64_t entry_count;
69 if (not p_io->read_items(&entry_count))
70 return Result::MEDIATOR_ERROR;
71 if (entry_count == 0) {
72 entries.init();
73 return Result::SUCCESS;
74 }
75 if (not entries.init(entry_count))
76 return Result::ALLOCATION_FAIL;
77 for (uint64_t i = 0; i < entry_count; ++i) {
78 Result res = entries[i].read(p_mediator);
79 if (res != Result::SUCCESS) {
80 while(i > 0)
81 entries[--i].destroy();
82 entries.destroy();
83 return res;
84 }
85 }
86 return Result::SUCCESS;
87 }
88 template<typename IO = jl::io_agent> [[nodiscard]]
89 Result write(IO *p_mediator) const {
90 auto *p_io = jl::io_agent_p_alt_cast(p_mediator);
91 if (not p_io->write_items(&options.shift))
92 return Result::MEDIATOR_ERROR;
93 if (not p_io->write_items(&options.shift_po2))
94 return Result::MEDIATOR_ERROR;
95 size_t entry_count = entries.count();
96 if (not p_io->write_items(&entry_count))
97 return Result::MEDIATOR_ERROR;
98 for (auto &e : entries) {
99 Result res = e.write(p_mediator);
100 if (res != Result::SUCCESS)
101 return res;
102 }
103 return Result::SUCCESS;
104 }
105 struct Options {
106 void set_default_value() { *this = {}; }
107 jl::array<int32_t, 3> shift; ///< global shift of scene
108 int32_t shift_po2; ///< Power of two
109 };
110 Options options;
111 jl::rarray<SceneEntry> entries;
136 112 }; };
File include/jrf/vertices.h changed (mode: 100644) (index 0cad0ef..2d556a7)
1 1 #pragma once #pragma once
2
3 2 #include <jlib/io_agent.h> #include <jlib/io_agent.h>
4 3 #include <jlib/allocate.h> #include <jlib/allocate.h>
5 4 #include <jlib/array.h> #include <jlib/array.h>
6
7 5 #include "result.h" #include "result.h"
8 6
9 namespace jrf
7 namespace jrf { struct Vertices; }
8 struct jrf::Vertices
10 9 { {
11 struct Vertices
12 {
13 enum Format : uint16_t {
14 F16, F32, F64,
15 I8, I16, I32, I64,
16 U8, U16, U32, U64
17 };
18
19 constexpr static const uint8_t FORMAT_SIZE[] = {
20 2, 4, 8,
21 1, 2, 4, 8,
22 1, 2, 4, 8
23 };
24
25 enum AttributeType {
26 POSITION, TEX_COORD, NORMAL,
27 RESERVED_BEGIN,
28 RESERVED_COUNT = 16
29 };
30 static_assert (RESERVED_BEGIN < RESERVED_COUNT);
31 constexpr static const uint8_t ATTRIBUTE_COUNT = RESERVED_COUNT;
32
33 struct Attribute {
34 uint32_t offset;
35 uint16_t dimension_count;
36 Format format;
37 };
38 using Attributes = jl::array<Attribute, ATTRIBUTE_COUNT>;
39
40 Attributes attributes;
41 uint64_t vecs_count;
42 uint64_t data_size;
43 void *p_data;
44
45 void destroy() { jl::deallocate(&p_data); }
46
47 template<typename IO = jl::io_agent>
48 [[nodiscard]] Result read(IO *p_mediator)
49 {
50 auto *p_io = jl::io_agent_p_alt_cast(p_mediator);\
51
52 if (not p_io->read_items(&attributes))
53 return Result::MEDIATOR_ERROR;
54
55 if (not p_io->read_items(&vecs_count))
56 return Result::MEDIATOR_ERROR;
57
58 jl::array<size_t, ATTRIBUTE_COUNT> asizes;
59 data_size = 0;
60 for (uint8_t a = 0; a < ATTRIBUTE_COUNT; ++a) {
61 asizes[a] = attributes[a].dimension_count
62 * FORMAT_SIZE[attributes[a].format] * vecs_count;
63 data_size += asizes[a];
64 }
65 for (uint8_t a = 0; a < ATTRIBUTE_COUNT; ++a)
66 if (attributes[a].offset + asizes[a] > data_size)
67 return Result::FILE_CORRUPTED;
68
69 if (data_size == 0)
70 return Result::FILE_NO_DATA;
71
72 if (not jl::allocate_bytes(&p_data, data_size))
73 return Result::MEDIATOR_ERROR;
74 if (not p_io->read_bytes(p_data, data_size))
75 return this->destroy(), Result::MEDIATOR_ERROR;
76
77 return Result::SUCCESS;
78 }
79
80 template<typename IO = jl::io_agent>
81 [[nodiscard]] Result write(IO *p_mediator) const
82 {
83 auto *p_io = jl::io_agent_p_alt_cast(p_mediator);
84 if (not p_io->write_items(&attributes))
85 return Result::MEDIATOR_ERROR;
86 if (not p_io->write_items(&vecs_count))
87 return Result::MEDIATOR_ERROR;
88 if (not p_io->write_bytes(p_data, data_size))
89 return Result::MEDIATOR_ERROR;
90
91 return Result::SUCCESS;
92 }
93 };
94 }
10 void destroy() {
11 jl::deallocate(&p_data);
12 }
13 template<typename IO = jl::io_agent> [[nodiscard]]
14 Result read(IO *p_mediator) {
15 auto *p_io = jl::io_agent_p_alt_cast(p_mediator);
16 if (not p_io->read_items(&attributes))
17 return Result::MEDIATOR_ERROR;
18 if (not p_io->read_items(&vecs_count))
19 return Result::MEDIATOR_ERROR;
20 jl::array<size_t, ATTRIBUTE_COUNT> asizes;
21 data_size = 0;
22 for (uint8_t a = 0; a < ATTRIBUTE_COUNT; ++a) {
23 asizes[a] = attributes[a].dimension_count
24 * FORMAT_SIZE[attributes[a].format] * vecs_count;
25 data_size += asizes[a];
26 }
27 for (uint8_t a = 0; a < ATTRIBUTE_COUNT; ++a)
28 if (attributes[a].offset + asizes[a] > data_size)
29 return Result::FILE_CORRUPTED;
30 if (data_size == 0)
31 return Result::FILE_NO_DATA;
32 if (not jl::allocate_bytes(&p_data, data_size))
33 return Result::MEDIATOR_ERROR;
34 if (not p_io->read_bytes(p_data, data_size))
35 return this->destroy(), Result::MEDIATOR_ERROR;
36 return Result::SUCCESS;
37 }
38 template<typename IO = jl::io_agent> [[nodiscard]]
39 Result write(IO *p_mediator) const {
40 auto *p_io = jl::io_agent_p_alt_cast(p_mediator);
41 if (not p_io->write_items(&attributes))
42 return Result::MEDIATOR_ERROR;
43 if (not p_io->write_items(&vecs_count))
44 return Result::MEDIATOR_ERROR;
45 if (not p_io->write_bytes(p_data, data_size))
46 return Result::MEDIATOR_ERROR;
47 return Result::SUCCESS;
48 }
49 enum Format : uint16_t {
50 F16, F32, F64,
51 I8, I16, I32, I64,
52 U8, U16, U32, U64
53 };
54 constexpr static const uint8_t FORMAT_SIZE[] = {
55 2, 4, 8,
56 1, 2, 4, 8,
57 1, 2, 4, 8
58 };
59 enum AttributeType {
60 POSITION, TEX_COORD, NORMAL,
61 RESERVED_BEGIN,
62 RESERVED_COUNT = 16
63 };
64 static_assert (RESERVED_BEGIN < RESERVED_COUNT);
65 constexpr static const uint8_t ATTRIBUTE_COUNT = RESERVED_COUNT;
66
67 struct Attribute {
68 uint32_t offset;
69 uint16_t dimension_count;
70 Format format;
71 };
72 using Attributes = jl::array<Attribute, ATTRIBUTE_COUNT>;
73
74 Attributes attributes;
75 uint64_t vecs_count;
76 uint64_t data_size;
77 void *p_data;
78 };
File include/jrf/write.h changed (mode: 100644) (index 85296cc..8c33fad)
3 3
4 4 namespace jrf namespace jrf
5 5 { {
6 template<typename IO = jl::io_agent>
7 [[nodiscard]] Result write(IO *p_io, ResourceType type, ResourceUnion *p_ru)
8 {
9 switch(type)
10 {
11 case ResourceType::IMAGE:
12 return write<ResourceType::IMAGE> (p_io, p_ru->image);
13 case ResourceType::VERTICES:
14 return write<ResourceType::VERTICES>(p_io, p_ru->vertices);
15 case ResourceType::INDICES:
16 return write<ResourceType::INDICES> (p_io, p_ru->indices);
17 case ResourceType::MESH:
18 return write<ResourceType::MESH> (p_io, p_ru->mesh);
19 case ResourceType::MODEL:
20 return write<ResourceType::MODEL> (p_io, p_ru->model);
21 case ResourceType::SCENE:
22 return write<ResourceType::SCENE> (p_io, p_ru->scene);
23 default:
24 return Result::UNKNOWN_RESOURCE_TYPE;
25 }
26 }
27 template<ResourceType RT, typename Resource, typename IO = jl::io_agent>
28 [[nodiscard]] Result write(IO *p_io, const Resource &resource)
29 {
30 EntryHeader header;
31 header.magic = MAGIC.integer;
32 header.type = RT;
33
34 if (p_io->write(&header, sizeof (EntryHeader)) != sizeof(EntryHeader))
35 return MEDIATOR_ERROR;
36 return resource.write(p_io);
37 }
6 template<typename IO = jl::io_agent> [[nodiscard]]
7 Result write(IO *p_io, ResourceType type, ResourceUnion *p_ru) {
8 switch(type) {
9 case ResourceType::IMAGE:
10 return write<ResourceType::IMAGE> (p_io, p_ru->image);
11 case ResourceType::VERTICES:
12 return write<ResourceType::VERTICES>(p_io, p_ru->vertices);
13 case ResourceType::INDICES:
14 return write<ResourceType::INDICES> (p_io, p_ru->indices);
15 case ResourceType::MESH:
16 return write<ResourceType::MESH> (p_io, p_ru->mesh);
17 case ResourceType::MODEL:
18 return write<ResourceType::MODEL> (p_io, p_ru->model);
19 case ResourceType::SCENE:
20 return write<ResourceType::SCENE> (p_io, p_ru->scene);
21 default:
22 return Result::UNKNOWN_RESOURCE_TYPE;
23 }
24 }
25 template<ResourceType RT, typename Resource, typename IO = jl::io_agent>
26 [[nodiscard]] Result write(IO *p_io, const Resource &resource) {
27 EntryHeader header;
28 header.magic = MAGIC.integer;
29 header.type = RT;
30 if (p_io->write(&header, sizeof (EntryHeader)) != sizeof(EntryHeader))
31 return MEDIATOR_ERROR;
32 return resource.write(p_io);
33 }
38 34 } }
File include/jrf/zip.h changed (mode: 100644) (index 4c3cb1d..29300cd)
1 1 #pragma once #pragma once
2
3 2 #include <zip.h> #include <zip.h>
4 3 #include <jlib/allocate.h> #include <jlib/allocate.h>
5 4
6 enum ZipResult : int
7 {
8 SUCCESS,
9 ENTRY_CHANGED = ZIP_ER_CHANGED,
10 CLOSE_FAILED = ZIP_ER_CLOSE,
11 UNSUPPORTED_COMPRESSION_METHED = ZIP_ER_COMPNOTSUPP,
12 INVALID_COMPRESSED_DATA = ZIP_ER_COMPRESSED_DATA,
13 CRC_ERROR = ZIP_ER_CRC,
14 ENTRY_DELETED = ZIP_ER_DELETED,
15 UNSUPPORTED_ENCRYPTION_METHOD = ZIP_ER_ENCRNOTSUPP,
16 PREMATURE_EOF = ZIP_ER_EOF,
17 EXIST = ZIP_ER_EXISTS,
18 ARCHIVE_INCONSISTENT = ZIP_ER_INCONS,
19 INTERNAL_ERROR = ZIP_ER_INTERNAL,
20 RESOURCE_IN_USE = ZIP_ER_INUSE,
21 INVALID_ARGUMENT = ZIP_ER_INVAL,
22 ALLOCATION_FAIL = ZIP_ER_MEMORY,
23 UNSUPPORTED_MULTI_DISK = ZIP_ER_MULTIDISK,
24 FILE_MISSING = ZIP_ER_NOENT,
25 PASSWORD_NOT_PROVIDED = ZIP_ER_NOPASSWD,
26 NOT_A_ZIP = ZIP_ER_NOZIP,
27 CANT_OPEN_FILE = ZIP_ER_OPEN,
28 UNSUPPORTED_OPERATION = ZIP_ER_OPNOTSUPP,
29 READ_ONLY_ARCHIVE = ZIP_ER_RDONLY,
30 READ_ERROR = ZIP_ER_READ,
31 CANT_REMOVE_FILE = ZIP_ER_REMOVE,
32 RENAME_FAIL = ZIP_ER_RENAME,
33 SEEK_FAIL = ZIP_ER_SEEK,
34 TELL_FAIL = ZIP_ER_TELL,
35 TEMP_FILE_CREATE_FAIL = ZIP_ER_TMPOPEN,
36 WRITE_FAIL = ZIP_ER_WRITE,
37 PASSWORD_WRONG = ZIP_ER_WRONGPASSWD,
38 FILE_CLOSED = ZIP_ER_ZIPCLOSED,
39 ZLIB_ERROR = ZIP_ER_ZLIB,
5 enum ZipResult : int {
6 SUCCESS,
7 ENTRY_CHANGED = ZIP_ER_CHANGED,
8 CLOSE_FAILED = ZIP_ER_CLOSE,
9 UNSUPPORTED_COMPRESSION_METHED = ZIP_ER_COMPNOTSUPP,
10 INVALID_COMPRESSED_DATA = ZIP_ER_COMPRESSED_DATA,
11 CRC_ERROR = ZIP_ER_CRC,
12 ENTRY_DELETED = ZIP_ER_DELETED,
13 UNSUPPORTED_ENCRYPTION_METHOD = ZIP_ER_ENCRNOTSUPP,
14 PREMATURE_EOF = ZIP_ER_EOF,
15 EXIST = ZIP_ER_EXISTS,
16 ARCHIVE_INCONSISTENT = ZIP_ER_INCONS,
17 INTERNAL_ERROR = ZIP_ER_INTERNAL,
18 RESOURCE_IN_USE = ZIP_ER_INUSE,
19 INVALID_ARGUMENT = ZIP_ER_INVAL,
20 ALLOCATION_FAIL = ZIP_ER_MEMORY,
21 UNSUPPORTED_MULTI_DISK = ZIP_ER_MULTIDISK,
22 FILE_MISSING = ZIP_ER_NOENT,
23 PASSWORD_NOT_PROVIDED = ZIP_ER_NOPASSWD,
24 NOT_A_ZIP = ZIP_ER_NOZIP,
25 CANT_OPEN_FILE = ZIP_ER_OPEN,
26 UNSUPPORTED_OPERATION = ZIP_ER_OPNOTSUPP,
27 READ_ONLY_ARCHIVE = ZIP_ER_RDONLY,
28 READ_ERROR = ZIP_ER_READ,
29 CANT_REMOVE_FILE = ZIP_ER_REMOVE,
30 RENAME_FAIL = ZIP_ER_RENAME,
31 SEEK_FAIL = ZIP_ER_SEEK,
32 TELL_FAIL = ZIP_ER_TELL,
33 TEMP_FILE_CREATE_FAIL = ZIP_ER_TMPOPEN,
34 WRITE_FAIL = ZIP_ER_WRITE,
35 PASSWORD_WRONG = ZIP_ER_WRONGPASSWD,
36 FILE_CLOSED = ZIP_ER_ZIPCLOSED,
37 ZLIB_ERROR = ZIP_ER_ZLIB,
40 38 }; };
41
42 [[nodiscard]] inline int * zip_result_ptr(ZipResult *p_r) { return reinterpret_cast<int*>(p_r); }
43 [[nodiscard]] inline ZipResult * zip_result_ptr(int *p_r) { return reinterpret_cast<ZipResult*>(p_r); }
44 [[nodiscard]] inline ZipResult zip_result_int(int r) { return static_cast<ZipResult>(r); }
45 [[nodiscard]] inline int zip_result_int(ZipResult r) { return static_cast<int>(r); }
46
39 [[nodiscard]] inline int * zip_result_ptr(ZipResult *p_r) {
40 return reinterpret_cast<int*>(p_r);
41 }
42 [[nodiscard]] inline ZipResult * zip_result_ptr(int *p_r) {
43 return reinterpret_cast<ZipResult*>(p_r);
44 }
45 [[nodiscard]] inline ZipResult zip_result_int(int r) {
46 return static_cast<ZipResult>(r);
47 }
48 [[nodiscard]] inline int zip_result_int(ZipResult r) {
49 return static_cast<int>(r);
50 }
47 51 using ZipIndex = int64_t; using ZipIndex = int64_t;
48 52
49 struct ZipStat
50 {
51 enum Flag
52 {
53 NAME = ZIP_STAT_NAME,
54 INDEX = ZIP_STAT_INDEX,
55 SIZE = ZIP_STAT_SIZE,
56 COMPRESSED_SIZE = ZIP_STAT_COMP_SIZE,
57 MODIFICATION_TIME = ZIP_STAT_MTIME,
58 CRC = ZIP_STAT_CRC,
59 COMPRESSION_METHOD = ZIP_STAT_COMP_METHOD,
60 ENCRYPTION_METHOD = ZIP_STAT_ENCRYPTION_METHOD,
61 FLAGS = ZIP_STAT_FLAGS
62 };
63
64 inline void init() { zip_stat_init(&stat); }
65
66 inline void _valid(Flag f) { stat.valid |= f; }
67 inline void name(const char* p) { stat.name = p; _valid(NAME); }
68 inline void index(uint64_t i) { stat.index = i; _valid(INDEX); }
69 inline void size(uint64_t s) { stat.size = s; _valid(SIZE); }
70 inline void compressed_size(uint64_t cs) { stat.comp_size = cs; _valid(COMPRESSED_SIZE); }
71 inline void modification_time(time_t t) { stat.mtime = t; _valid(MODIFICATION_TIME); }
72 inline void crc(uint32_t crc) { stat.crc = crc; _valid(CRC); }
73 inline void compression_method(uint16_t cm) { stat.comp_method = cm; _valid(COMPRESSION_METHOD); }
74 inline void encryption_method(uint16_t em) { stat.encryption_method = em; _valid(ENCRYPTION_METHOD); }
75
76
77 [[nodiscard]] inline bool valid(Flag f) { return stat.valid & f; }
78 [[nodiscard]] inline const char* name() { return valid(NAME) ? stat.name : nullptr; }
79 [[nodiscard]] inline uint64_t index() { return valid(INDEX) ? stat.index : 0; }
80 [[nodiscard]] inline uint64_t size() { return valid(SIZE) ? stat.size : 0; }
81 [[nodiscard]] inline uint64_t compressed_size() { return valid(COMPRESSED_SIZE) ? stat.comp_size : 0; }
82 [[nodiscard]] inline time_t modification_time() { return valid(MODIFICATION_TIME) ? stat.mtime : 0; }
83 [[nodiscard]] inline uint32_t crc() { return valid(CRC) ? stat.crc : 0; }
84 [[nodiscard]] inline uint16_t compression_method() { return valid(COMPRESSION_METHOD) ? stat.comp_method : 0; }
85 [[nodiscard]] inline uint16_t encryption_method() { return valid(ENCRYPTION_METHOD) ? stat.encryption_method : 0; }
86
87 zip_stat_t stat;
53 struct ZipStat {
54 enum Flag {
55 NAME = ZIP_STAT_NAME,
56 INDEX = ZIP_STAT_INDEX,
57 SIZE = ZIP_STAT_SIZE,
58 COMPRESSED_SIZE = ZIP_STAT_COMP_SIZE,
59 MODIFICATION_TIME = ZIP_STAT_MTIME,
60 CRC = ZIP_STAT_CRC,
61 COMPRESSION_METHOD = ZIP_STAT_COMP_METHOD,
62 ENCRYPTION_METHOD = ZIP_STAT_ENCRYPTION_METHOD,
63 FLAGS = ZIP_STAT_FLAGS
64 };
65 void init() {
66 zip_stat_init(&stat);
67 }
68 void name(const char* p) {
69 stat.name = p;
70 set_valid(NAME);
71 }
72 void index(uint64_t i) {
73 stat.index = i; set_valid(INDEX);
74 }
75 void size(uint64_t s) {
76 stat.size = s; set_valid(SIZE);
77 }
78 void compressed_size(uint64_t cs) {
79 stat.comp_size = cs; set_valid(COMPRESSED_SIZE);
80 }
81 void modification_time(time_t t) {
82 stat.mtime = t; set_valid(MODIFICATION_TIME);
83 }
84 void crc(uint32_t crc) {
85 stat.crc = crc; set_valid(CRC);
86 }
87 void compression_method(uint16_t cm) {
88 stat.comp_method = cm; set_valid(COMPRESSION_METHOD);
89 }
90 void encryption_method(uint16_t em) {
91 stat.encryption_method = em; set_valid(ENCRYPTION_METHOD);
92 }
93 [[nodiscard]] bool is_valid(Flag f) {
94 return stat.valid & f;
95 }
96 [[nodiscard]] const char* name() {
97 return is_valid(NAME) ? stat.name : nullptr;
98 }
99 [[nodiscard]] uint64_t index() {
100 return is_valid(INDEX) ? stat.index : 0;
101 }
102 [[nodiscard]] uint64_t size() {
103 return is_valid(SIZE) ? stat.size : 0;
104 }
105 [[nodiscard]] uint64_t compressed_size() {
106 return is_valid(COMPRESSED_SIZE) ? stat.comp_size : 0;
107 }
108 [[nodiscard]] time_t modification_time() {
109 return is_valid(MODIFICATION_TIME) ? stat.mtime : 0;
110 }
111 [[nodiscard]] uint32_t crc() {
112 return is_valid(CRC) ? stat.crc : 0;
113 }
114 [[nodiscard]] uint16_t compression_method() {
115 return is_valid(COMPRESSION_METHOD) ? stat.comp_method : 0;
116 }
117 [[nodiscard]] uint16_t encryption_method() {
118 return is_valid(ENCRYPTION_METHOD) ? stat.encryption_method : 0;
119 }
120 zip_stat_t stat;
121
122 private:
123 void set_valid(Flag f) {
124 stat.valid |= f;
125 }
88 126 }; };
89
90 127 using ZipError = zip_error; using ZipError = zip_error;
91 128
92 129 struct ZipSource struct ZipSource
93 130 { {
94 [[nodiscard]] ZipResult create(const void *p_data, uint64_t byte_count, int free_data_bool)
95 {
96 zip_error_t es;
97 p = zip_source_buffer_create(p_data, byte_count, free_data_bool, &es);
98 return zip_result_int(es.zip_err);
99 }
100 [[nodiscard]] ZipResult create(const char *file_path, uint64_t start_offset, int64_t byte_count_or_0_if_whole_file)
101 {
102 zip_error_t es;
103 p = zip_source_file_create(file_path, start_offset, byte_count_or_0_if_whole_file, &es);
104 return zip_result_int(es.zip_err);
105 }
106
107 void destroy()
108 {
109 zip_source_free(p);
110 }
131 [[nodiscard]] ZipResult
132 create(const void *p_data, uint64_t byte_count, int free_data_bool) {
133 zip_error_t es;
134 p = zip_source_buffer_create(p_data, byte_count, free_data_bool, &es);
135 return zip_result_int(es.zip_err);
136 }
137 [[nodiscard]] ZipResult
138 create(const char *file_path, uint64_t start_offset,
139 int64_t byte_count_or_0_if_whole_file) {
140 zip_error_t es;
141 p = zip_source_file_create(file_path, start_offset, byte_count_or_0_if_whole_file, &es);
142 return zip_result_int(es.zip_err);
143 }
144 void destroy() {
145 zip_source_free(p);
146 }
111 147 // mingw macro // mingw macro
112 148 #undef ERROR #undef ERROR
113 enum Cmd {
114 OPEN, /* prepare for reading */
115 READ, /* read data */
116 CLOSE, /* reading is done */
117 STAT, /* get meta information */
118 ERROR, /* get error information */
119 FREE, /* cleanup and free resources */
120 SEEK, /* set position for reading */
121 TELL, /* get read position */
122 BEGIN_WRITE, /* prepare for writing */
123 COMMIT_WRITE, /* writing is done */
124 ROLLBACK_WRITE, /* discard written changes */
125 WRITE, /* write data */
126 SEEK_WRITE, /* set position for writing */
127 TELL_WRITE, /* get write position */
128 SUPPORTS, /* check whether source supports command */
129 REMOVE, /* remove file */
130 GET_COMPRESSION_FLAGS, /* get compression flags, internal only */
131 BEGIN_WRITE_CLONING, /* like BEGIN_WRITE, but keep part of original file */
132 COUNT // cmd count
133 };
134
135 template<typename T>
136 using PF_Callback = int64_t (*)(T *p_userdata, void *p_data, uint64_t length, Cmd cmd);
137 template<typename T>
138 using PF_CallbackCmd = int64_t (*)(T *p_userdata, void *p_data, uint64_t length);
139
140 template<typename T>
141 using PF_CallbackCmdOpen = int64_t (*)(T *p_userdata);
142 template<typename T>
143 using PF_CallbackCmdStat = int64_t (*)(T *p_userdata, ZipStat *p_data);
144 template<typename T>
145 using PF_CallbackCmdError = int64_t (*)(T *p_userdata, ZipError *p_data);
146
147 template<typename T>
148 struct CallbacksCmd
149 {
150 //read from source
151 PF_CallbackCmdOpen<T> OPEN;
152 PF_CallbackCmd<T> READ;
153 PF_CallbackCmd<T> CLOSE;
154 PF_CallbackCmdStat<T> STAT;
155 PF_CallbackCmdError<T> ERROR;
156
157 //read from source with seeking
158 PF_CallbackCmd<T> SEEK;
159 PF_CallbackCmd<T> TELL;
160
161
162 //write
163 PF_CallbackCmd<T> BEGIN_WRITE;
164 PF_CallbackCmd<T> COMMIT_WRITE;
165 PF_CallbackCmd<T> ROLLBACK_WRITE;
166 PF_CallbackCmd<T> SEEK_WRITE;
167 PF_CallbackCmd<T> TELL_WRITE;
168 PF_CallbackCmd<T> REMOVE;
169
170
171 //unknown
172 PF_CallbackCmd<T> WRITE;
173 PF_CallbackCmd<T> FREE;
174 PF_CallbackCmd<T> GET_COMPRESSION_FLAGS;
175 PF_CallbackCmd<T> BEGIN_WRITE_CLONING;
176 };
177
178
179 template<typename T>
180 [[nodiscard]] ZipResult create(PF_Callback<T> pf_callback, void *p_userdata)
181 {
182 zip_error_t es;
183 p = zip_source_function_create(reinterpret_cast<zip_source_callback>(pf_callback), p_userdata, &es);
184 return zip_result_int(es.zip_err);
185 }
186
187 template<typename T>
188 struct CmdData
189 {
190 CallbacksCmd<T> pf_cmds;
191 T *p_userdata;
192 };
193
194 static int64_t cmd_choose(CmdData<void> *p_userdata, void *p_data, uint64_t length, Cmd cmd)
195 {
196 auto *p_ud = reinterpret_cast<CmdData<void>*>(p_userdata);
197 switch(cmd)
198 {
199 #define ARGS p_ud->p_userdata, p_data, length
200 #define ARGS1 p_ud->p_userdata
201 #define ARGS2(x) p_ud->p_userdata, reinterpret_cast<x*>(p_data)
202 #define C(x, args) case Cmd::x : if (p_ud->pf_cmds.x != nullptr) \
203 return p_ud->pf_cmds.x(args); \
204 else return -1;
205
206 C(OPEN, ARGS1)
207 C(READ, ARGS)
208 C(CLOSE, ARGS)
209 C(STAT, ARGS2(ZipStat))
210 C(ERROR, ARGS2(ZipError))
211 C(FREE, ARGS)
212 C(SEEK, ARGS)
213 C(TELL, ARGS)
214 C(BEGIN_WRITE, ARGS)
215 C(COMMIT_WRITE, ARGS)
216 C(ROLLBACK_WRITE, ARGS)
217 C(WRITE, ARGS)
218 C(SEEK_WRITE, ARGS)
219 C(TELL_WRITE, ARGS)
220
149 enum Cmd {
150 OPEN, /* prepare for reading */
151 READ, /* read data */
152 CLOSE, /* reading is done */
153 STAT, /* get meta information */
154 ERROR, /* get error information */
155 FREE, /* cleanup and free resources */
156 SEEK, /* set position for reading */
157 TELL, /* get read position */
158 BEGIN_WRITE, /* prepare for writing */
159 COMMIT_WRITE, /* writing is done */
160 ROLLBACK_WRITE, /* discard written changes */
161 WRITE, /* write data */
162 SEEK_WRITE, /* set position for writing */
163 TELL_WRITE, /* get write position */
164 SUPPORTS, /* check whether source supports command */
165 REMOVE, /* remove file */
166 GET_COMPRESSION_FLAGS, /* get compression flags, internal only */
167 BEGIN_WRITE_CLONING, /* like BEGIN_WRITE, but keep part of original file */
168 COUNT // cmd count
169 };
170 template<typename T>
171 using PF_Callback = int64_t(*)(T*p_userdata,void*p_data,uint64_t length, Cmd);
172 template<typename T>
173 using PF_CallbackCmd = int64_t(*)(T*p_userdata,void*p_data,uint64_t length);
174
175 template<typename T>
176 using PF_CallbackCmdOpen = int64_t(*)(T*p_userdata);
177 template<typename T>
178 using PF_CallbackCmdStat = int64_t(*)(T*p_userdata,ZipStat*p_data);
179 template<typename T>
180 using PF_CallbackCmdError = int64_t(*)(T*p_userdata,ZipError*p_data);
181
182 template<typename T>
183 struct CallbacksCmd {
184 //read from source
185 PF_CallbackCmdOpen<T> OPEN;
186 PF_CallbackCmd<T> READ;
187 PF_CallbackCmd<T> CLOSE;
188 PF_CallbackCmdStat<T> STAT;
189 PF_CallbackCmdError<T> ERROR;
190 //read from source with seeking
191 PF_CallbackCmd<T> SEEK;
192 PF_CallbackCmd<T> TELL;
193 //write
194 PF_CallbackCmd<T> BEGIN_WRITE;
195 PF_CallbackCmd<T> COMMIT_WRITE;
196 PF_CallbackCmd<T> ROLLBACK_WRITE;
197 PF_CallbackCmd<T> SEEK_WRITE;
198 PF_CallbackCmd<T> TELL_WRITE;
199 PF_CallbackCmd<T> REMOVE;
200 //unknown
201 PF_CallbackCmd<T> WRITE;
202 PF_CallbackCmd<T> FREE;
203 PF_CallbackCmd<T> GET_COMPRESSION_FLAGS;
204 PF_CallbackCmd<T> BEGIN_WRITE_CLONING;
205 };
206 template<typename T> [[nodiscard]]
207 ZipResult create(PF_Callback<T> pf_callback, void *p_userdata) {
208 zip_error_t es;
209 auto callback = reinterpret_cast<zip_source_callback>(pf_callback);
210 p = zip_source_function_create(callback, p_userdata, &es);
211 return zip_result_int(es.zip_err);
212 }
213 template<typename T>
214 struct CmdData {
215 CallbacksCmd<T> pf_cmds;
216 T *p_userdata;
217 };
218
219 #define ARGS \
220 p_ud->p_userdata, p_data, length
221 #define ARGS1 \
222 p_ud->p_userdata
223 #define ARGS2(x) \
224 p_ud->p_userdata, reinterpret_cast<x*>(p_data)
225 #define C(x, args) \
226 case Cmd::x : \
227 if (p_ud->pf_cmds.x != nullptr) \
228 return p_ud->pf_cmds.x(args); \
229 else return -1;
221 230 #define B(x) zip_source_cmd_t(p_ud->pf_cmds.x == nullptr ? x : x) #define B(x) zip_source_cmd_t(p_ud->pf_cmds.x == nullptr ? x : x)
222 case Cmd::SUPPORTS: {auto val = zip_source_make_command_bitmap(B(OPEN),B(READ),B(CLOSE),B(STAT),B(ERROR),
223 B(FREE),B(SEEK),B(TELL),B(BEGIN_WRITE),
224 B(COMMIT_WRITE),B(ROLLBACK_WRITE),B(WRITE),
225 B(SEEK_WRITE),B(TELL_WRITE),B(REMOVE),
226 B(GET_COMPRESSION_FLAGS),B(BEGIN_WRITE_CLONING),
227 SUPPORTS);
228 return val;}
229 #undef B
230 231
231 C(REMOVE, ARGS)
232 C(GET_COMPRESSION_FLAGS, ARGS)
233 C(BEGIN_WRITE_CLONING, ARGS)
234 default: return -1;
232 static int64_t
233 cmd_choose(CmdData<void> *p_userdata, void *p_data, uint64_t length, Cmd cmd){
234 auto *p_ud = reinterpret_cast<CmdData<void>*>(p_userdata);
235 switch(cmd) {
236 C(OPEN, ARGS1)
237 C(READ, ARGS)
238 C(CLOSE, ARGS)
239 C(STAT, ARGS2(ZipStat))
240 C(ERROR, ARGS2(ZipError))
241 C(FREE, ARGS)
242 C(SEEK, ARGS)
243 C(TELL, ARGS)
244 C(BEGIN_WRITE, ARGS)
245 C(COMMIT_WRITE, ARGS)
246 C(ROLLBACK_WRITE, ARGS)
247 C(WRITE, ARGS)
248 C(SEEK_WRITE, ARGS)
249 C(TELL_WRITE, ARGS)
250 case Cmd::SUPPORTS: {
251 auto val = zip_source_make_command_bitmap(
252 B(OPEN),B(READ),B(CLOSE),B(STAT),B(ERROR),B(FREE),B(SEEK),B(TELL),
253 B(BEGIN_WRITE),B(COMMIT_WRITE),B(ROLLBACK_WRITE),B(WRITE),
254 B(SEEK_WRITE),B(TELL_WRITE),B(REMOVE),B(GET_COMPRESSION_FLAGS),
255 B(BEGIN_WRITE_CLONING),SUPPORTS);
256 return val;
257 }
258 C(REMOVE, ARGS)
259 C(GET_COMPRESSION_FLAGS, ARGS)
260 C(BEGIN_WRITE_CLONING, ARGS)
261 default: return -1;
262 #undef B
235 263 #undef C #undef C
236 264 #undef ARGS #undef ARGS
237 265 #undef ARGS1 #undef ARGS1
238 266 #undef ARGS2 #undef ARGS2
239 }
240 }
241
242
243 template<typename T>
244 [[nodiscard]] ZipResult create(CmdData<T> *p_data)
245 {
246 zip_error_t es;
247 p = zip_source_function_create(reinterpret_cast<zip_source_callback>(cmd_choose), p_data, &es);
248 return p != nullptr ? ZipResult::SUCCESS : zip_result_int(es.zip_err);
249 }
250
251 zip_source_t *p;
267 }
268 }
269 template<typename T> [[nodiscard]]
270 ZipResult create(CmdData<T> *p_data) {
271 zip_error_t es;
272 p = zip_source_function_create(reinterpret_cast<zip_source_callback>(cmd_choose), p_data, &es);
273 return p != nullptr ? ZipResult::SUCCESS : zip_result_int(es.zip_err);
274 }
275 zip_source_t *p;
252 276 }; };
253
254 struct ZipArchive
255 {
256 struct OpenFlag
257 {
258 enum {
259 CHECK_FILE = ZIP_CHECKCONS,
260 CREATE_IF_FILE_MISSING = ZIP_CREATE,
261 ERROR_IF_FILE_EXIST = ZIP_EXCL,
262 CLEAR_IF_FILE_EXIST = ZIP_TRUNCATE,
263 READ_ONLY = ZIP_RDONLY
264 };
265 };
266 using OpenMask = int;
267
268 enum Encoding {
269 GUESS = ZIP_FL_ENC_GUESS,
270 UTF8 = ZIP_FL_ENC_UTF_8,
271 CP433 = ZIP_FL_ENC_CP437,
272 };
273
274 [[nodiscard]] ZipResult open(const char *path, OpenMask flags)
275 {
276 ZipResult res;
277 p = zip_open(path, flags, zip_result_ptr(&res));
278
279 if (p != nullptr)
280 res = ZipResult::SUCCESS, p_error_info = zip_get_error(p);
281
282 return res;
283 }
284
285 [[nodiscard]] ZipResult open(const char *path)
286 {
287 return open(path, 0);
288 }
289
290 [[nodiscard]] ZipResult create(const char *path)
291 {
292 return open(path, OpenFlag::CREATE_IF_FILE_MISSING | OpenFlag::ERROR_IF_FILE_EXIST);
293 }
294
295 [[nodiscard]] ZipResult rewrite(const char *path)
296 {
297 return open(path, OpenFlag::CREATE_IF_FILE_MISSING | OpenFlag::CLEAR_IF_FILE_EXIST);
298 }
299
300 [[nodiscard]] ZipResult close()
301 {
302 return zip_result_int(zip_close(p));
303 }
304
305 [[nodiscard]] ZipResult create_directory(Encoding encoding, const char* name, ZipIndex *p_index_dst)
306 {
307 *p_index_dst = zip_dir_add(p, name, encoding);
308 return *p_index_dst == -1 ? zip_result_int(p_error_info->zip_err) : ZipResult::SUCCESS;
309 }
310
311 [[nodiscard]] ZipResult create_file(const char *name, ZipSource src, Encoding encoding, bool rewrite,
312 ZipIndex *p_index_dst)
313 {
314 *p_index_dst = zip_file_add(p, name, src.p, encoding | (rewrite ? ZIP_FL_OVERWRITE : 0));
315 return *p_index_dst == -1 ? zip_result_int(p_error_info->zip_err) : ZipResult::SUCCESS;
316 }
317
318 [[nodiscard]] ZipResult file_stat(const char* name, ZipStat *p_stat)
319 {
320 if (zip_stat(p, name, 0, &p_stat->stat) == 0)
321 return ZipResult::SUCCESS;
322 return zip_result_int(p_error_info->zip_err);
323 }
324
325 zip_t *p;
326 zip_error_t *p_error_info;
277 struct ZipArchive {
278 struct OpenFlag {
279 enum {
280 CHECK_FILE = ZIP_CHECKCONS,
281 CREATE_IF_FILE_MISSING = ZIP_CREATE,
282 ERROR_IF_FILE_EXIST = ZIP_EXCL,
283 CLEAR_IF_FILE_EXIST = ZIP_TRUNCATE,
284 READ_ONLY = ZIP_RDONLY
285 };
286 };
287 using OpenMask = int;
288
289 enum Encoding {
290 GUESS = ZIP_FL_ENC_GUESS,
291 UTF8 = ZIP_FL_ENC_UTF_8,
292 CP433 = ZIP_FL_ENC_CP437,
293 };
294 [[nodiscard]] ZipResult open(const char *path, OpenMask flags) {
295 ZipResult res;
296 p = zip_open(path, flags, zip_result_ptr(&res));
297 if (p != nullptr)
298 res = ZipResult::SUCCESS, p_error_info = zip_get_error(p);
299 return res;
300 }
301 [[nodiscard]] ZipResult open(const char *path) {
302 return open(path, 0);
303 }
304 [[nodiscard]] ZipResult create(const char *path) {
305 auto f = OpenFlag::CREATE_IF_FILE_MISSING | OpenFlag::ERROR_IF_FILE_EXIST;
306 return open(path, f);
307 }
308 [[nodiscard]] ZipResult rewrite(const char *path) {
309 auto f = OpenFlag::CREATE_IF_FILE_MISSING | OpenFlag::CLEAR_IF_FILE_EXIST;
310 return open(path, f);
311 }
312 [[nodiscard]] ZipResult close() {
313 return zip_result_int(zip_close(p));
314 }
315 [[nodiscard]] ZipResult
316 create_directory(Encoding encoding, const char* name, ZipIndex *p_index_dst) {
317 *p_index_dst = zip_dir_add(p, name, encoding);
318 return *p_index_dst == -1 ? zip_result_int(p_error_info->zip_err) : ZipResult::SUCCESS;
319 }
320 [[nodiscard]] ZipResult
321 create_file(const char *name, ZipSource src, Encoding encoding, bool rewrite,
322 ZipIndex *p_index_dst) {
323 auto f = encoding | (rewrite ? ZIP_FL_OVERWRITE : 0);
324 *p_index_dst = zip_file_add(p, name, src.p, f);
325 if (*p_index_dst == -1)
326 return zip_result_int(p_error_info->zip_err);
327 else
328 return ZipResult::SUCCESS;
329 }
330 [[nodiscard]] ZipResult file_stat(const char* name, ZipStat *p_stat) {
331 if (zip_stat(p, name, 0, &p_stat->stat) == 0)
332 return ZipResult::SUCCESS;
333 return zip_result_int(p_error_info->zip_err);
334 }
335 zip_t *p;
336 zip_error_t *p_error_info;
327 337 }; };
328
329 struct ZipSubFile
330 {
331 struct OpenFlag
332 {
333 enum {
334 READ_COMPRESSED = ZIP_FL_COMPRESSED,
335 // Read the original data from the zip archive, ignoring any changes made to the file.
336 READ_UNCHANGED_FLAG = ZIP_FL_UNCHANGED
337 };
338 };
339 using OpenMask = int;
340
341 [[nodiscard]] ZipResult open(ZipArchive *p_za, const char *name)
342 {
343 p = zip_fopen(p_za->p, name, 0);
344 return p == nullptr ? zip_result_int(p_za->p_error_info->zip_err) : ZipResult::SUCCESS;
345 }
346 [[nodiscard]] ZipResult open(ZipArchive *p_za, uint64_t file_index)
347 {
348 p = zip_fopen_index(p_za->p, file_index, 0);
349 return p == nullptr ? zip_result_int(p_za->p_error_info->zip_err) : ZipResult::SUCCESS;
350 }
351 [[nodiscard]] ZipResult close()
352 {
353 return zip_result_int(zip_fclose(p));
354 }
355
356 [[nodiscard]] bool read(void *p_dst, uint64_t byte_count)
357 {
358 return zip_fread(p, p_dst, byte_count) != -1;
359 }
360
361 [[nodiscard]] static inline ZipResult read_whole_file(ZipArchive *p_za, const char *p_name,
362 char **pp_dst, uint64_t *p_fsize)
363 {
364 ZipStat stat;
365 auto res = p_za->file_stat(p_name, &stat);
366 if (res != ZipResult::SUCCESS)
367 return res;
368
369 auto f_i = stat.index();
370 *p_fsize = stat.size();
371
372
373 ZipSubFile zfile;
374 res = zfile.open(p_za, f_i);
375 if (res != ZipResult::SUCCESS)
376 return res;
377
378
379 *pp_dst = reinterpret_cast<char*>(malloc(*p_fsize));
380 bool readed = zfile.read(*pp_dst, *p_fsize);
381
382 (void)zfile.close();
383 if (not readed)
384 {
385 jl::deallocate(pp_dst);
386 return ZipResult::READ_ERROR;
387 }
388 return ZipResult::SUCCESS;
389 }
390
391 zip_file_t *p;
338 struct ZipSubFile {
339 struct OpenFlag {
340 enum {
341 READ_COMPRESSED = ZIP_FL_COMPRESSED,
342 // Read the original data from the zip archive, ignoring any changes made to the file.
343 READ_UNCHANGED_FLAG = ZIP_FL_UNCHANGED
344 };
345 };
346 using OpenMask = int;
347
348 [[nodiscard]] ZipResult open(ZipArchive *p_za, const char *name) {
349 p = zip_fopen(p_za->p, name, 0);
350 if (p == nullptr)
351 return zip_result_int(p_za->p_error_info->zip_err);
352 else
353 return ZipResult::SUCCESS;
354 }
355 [[nodiscard]] ZipResult open(ZipArchive *p_za, uint64_t file_index) {
356 p = zip_fopen_index(p_za->p, file_index, 0);
357 if (p == nullptr)
358 return zip_result_int(p_za->p_error_info->zip_err);
359 else
360 return ZipResult::SUCCESS;
361 }
362 [[nodiscard]] ZipResult close() {
363 return zip_result_int(zip_fclose(p));
364 }
365 [[nodiscard]] bool read(void *p_dst, uint64_t byte_count) {
366 return zip_fread(p, p_dst, byte_count) != -1;
367 }
368 [[nodiscard]] static ZipResult
369 read_whole_file(ZipArchive *p_za, const char *p_name, char **pp_dst,
370 uint64_t *p_fsize) {
371 ZipStat stat;
372 auto res = p_za->file_stat(p_name, &stat);
373 if (res != ZipResult::SUCCESS)
374 return res;
375 auto f_i = stat.index();
376 *p_fsize = stat.size();
377 ZipSubFile zfile;
378 res = zfile.open(p_za, f_i);
379 if (res != ZipResult::SUCCESS)
380 return res;
381 *pp_dst = reinterpret_cast<char*>(malloc(*p_fsize));
382 bool readed = zfile.read(*pp_dst, *p_fsize);
383 (void)zfile.close();
384 if (not readed) {
385 jl::deallocate(pp_dst);
386 return ZipResult::READ_ERROR;
387 }
388 return ZipResult::SUCCESS;
389 }
390 zip_file_t *p;
392 391 }; };
393
File src/result.cpp changed (mode: 100644) (index d7f1fce..5b307ca)
1
2 1 #include <jrf/result.h> #include <jrf/result.h>
3
4 const char* jrf::to_str(jrf::Result result)
5 {
6 2 #define STR(x) case Result::x: return #x; #define STR(x) case Result::x: return #x;
7 switch (result)
8 {
9 STR(SUCCESS)
10 STR(SRC_MTIME_LESS_THAN_JRF)
11
12 //parse
13 STR(TOO_MANY_ARGUMENTS)
14 STR(MISSING_ARGUMENTS)
15 STR(EXPECTED_FILE_PATH)
16 STR(INCORRECT_FORMAT)
17 STR(UNKNOWN_TYPE)
18 STR(UNKNOWN_OPTION)
19 STR(EXPECTED_PARENTHESIS_OPEN)
20 STR(EXPECTED_PARENTHESIS_CLOSE)
21 STR(EXCESS_PARENTHESIS_CLOSE)
22 STR(EXPECTED_QUOTATION_MARKS)
23 STR(EXPECTED_NAME)
24 STR(EXPECTED_ARGUMENT)
25 STR(EXPECTED_TYPE)
26 STR(INCOMPATIBLE_RESOURCES)
27 STR(RESOURCE_PART_DUPLICATE)
28 STR(RESOURCE_PART_MISSING)
29 STR(RESOURCE_PART_OVERLAP)
30 STR(RESOURCE_TYPE_MISMATCH)
31 STR(SCENE_ENTRY_MODEL_IS_NOT_PATH)
32
33 STR(FILE_WRONG_HEADER)
34 STR(FILE_OPEN_ERROR)
35 STR(FILE_NO_DATA)
36 STR(DIRECTORY_ERROR)
37 STR(FILE_UNEXPECTED_EOF)
38 STR(FILE_CORRUPTED)
39
40 //zip
41 STR(ZIP_IN_ZIP_UNSUPPORTED)
42 STR(ZIP_ERROR)
43
44 //misc
45 STR(UNKNOWN_RESOURCE_TYPE)
46 STR(MEDIATOR_ERROR)
47 STR(ALLOCATION_FAIL)
48
49 //image
50 STR(COLOR_MAP_UNSUPPORTED)
51 STR(IMAGE_DATA_TYPE_UNSUPPORTED)
52 STR(PIXEL_SIZE_UNSUPPORTED)
53 STR(TGA_RLE_UNSUPPORTED)
54 STR(IMAGE_LAYERS_EXTENT_MISMATCH)
55 STR(IMAGE_LAYERS_FORMAT_MISMATCH)
56
57 //obj file
58 STR(OBJ_FILE_PARSE_ERROR)
59 STR(OBJ_INDEX_CANT_BE_ZERO)
60 STR(OBJ_FACE_HAVE_MORE_THAN_4_INDICES)
61
62 //indices
63 STR(INDEX_VALUE_OVERFLOW)
64 //vertices
65 STR(VERTICES_ATTRIBUTE_COUNT_MISMATCH)
66 }
67 return "unknown error";
68 #undef STR
3 const char* jrf::to_str(jrf::Result result) {
4 switch (result) {
5 STR(SUCCESS)
6 STR(SRC_MTIME_LESS_THAN_JRF)
7 //parse
8 STR(TOO_MANY_ARGUMENTS)
9 STR(MISSING_ARGUMENTS)
10 STR(EXPECTED_FILE_PATH)
11 STR(INCORRECT_FORMAT)
12 STR(UNKNOWN_TYPE)
13 STR(UNKNOWN_OPTION)
14 STR(EXPECTED_PARENTHESIS_OPEN)
15 STR(EXPECTED_PARENTHESIS_CLOSE)
16 STR(EXCESS_PARENTHESIS_CLOSE)
17 STR(EXPECTED_QUOTATION_MARKS)
18 STR(EXPECTED_NAME)
19 STR(EXPECTED_ARGUMENT)
20 STR(EXPECTED_TYPE)
21 STR(INCOMPATIBLE_RESOURCES)
22 STR(RESOURCE_PART_DUPLICATE)
23 STR(RESOURCE_PART_MISSING)
24 STR(RESOURCE_PART_OVERLAP)
25 STR(RESOURCE_TYPE_MISMATCH)
26 STR(SCENE_ENTRY_MODEL_IS_NOT_PATH)
27 //filesystem
28 STR(FILE_WRONG_HEADER)
29 STR(FILE_OPEN_ERROR)
30 STR(FILE_NO_DATA)
31 STR(DIRECTORY_ERROR)
32 STR(FILE_UNEXPECTED_EOF)
33 STR(FILE_CORRUPTED)
34 //zip
35 STR(ZIP_IN_ZIP_UNSUPPORTED)
36 STR(ZIP_ERROR)
37 //misc
38 STR(UNKNOWN_RESOURCE_TYPE)
39 STR(MEDIATOR_ERROR)
40 STR(ALLOCATION_FAIL)
41 //image
42 STR(COLOR_MAP_UNSUPPORTED)
43 STR(IMAGE_DATA_TYPE_UNSUPPORTED)
44 STR(PIXEL_SIZE_UNSUPPORTED)
45 STR(TGA_RLE_UNSUPPORTED)
46 STR(IMAGE_LAYERS_EXTENT_MISMATCH)
47 STR(IMAGE_LAYERS_FORMAT_MISMATCH)
48 //obj file
49 STR(OBJ_FILE_PARSE_ERROR)
50 STR(OBJ_INDEX_CANT_BE_ZERO)
51 STR(OBJ_FACE_HAVE_MORE_THAN_4_INDICES)
52 //indices
53 STR(INDEX_VALUE_OVERFLOW)
54 //vertices
55 STR(VERTICES_ATTRIBUTE_COUNT_MISMATCH)
56 }
57 return "unknown error";
69 58 } }
59 #undef STR
Hints:
Before first commit, do not forget to setup your git environment:
git config --global user.name "your_name_here"
git config --global user.email "your@email_here"

Clone this repository using HTTP(S):
git clone https://rocketgit.com/user/Jackalope/jrf

Clone this repository using ssh (do not forget to upload a key first):
git clone ssh://rocketgit@ssh.rocketgit.com/user/Jackalope/jrf

Clone this repository using git:
git clone git://git.rocketgit.com/user/Jackalope/jrf

You are allowed to anonymously push to this repository.
This means that your pushed commits will automatically be transformed into a merge request:
... clone the repository ...
... make some changes and some commits ...
git push origin main