Skip to content

Commit 349fd33

Browse files
committed
Some more deserialization ops
1 parent 1a57c15 commit 349fd33

12 files changed

Lines changed: 143 additions & 16 deletions

File tree

examples/pdf.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ int main(int argc, char** argv) {
6161

6262
size_t buffer_size;
6363
char* buffer =
64-
load_file_to_buffer(arena, "test-files/test-2.pdf", &buffer_size);
64+
load_file_to_buffer(arena, "test-files/wiki.pdf", &buffer_size);
6565
RELEASE_ASSERT(buffer);
6666

6767
PdfResolver* resolver;

libs/arena/include/arena/dvec_decl.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,9 @@ bool DVEC_FN(pop)(DVEC_NAME* vec, DVEC_TYPE* out);
5757
// Clears the vector, making it's length zero. This does not free any memory.
5858
void DVEC_FN(clear)(DVEC_NAME* vec);
5959

60+
// Creates a copy of the vector in the same arena.
61+
DVEC_NAME* DVEC_FN(clone)(const DVEC_NAME* vec);
62+
6063
// Returns the length of the vector.
6164
size_t DVEC_FN(len)(const DVEC_NAME* vec);
6265

libs/arena/include/arena/dvec_impl.h

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include <stdbool.h>
22
#include <stdint.h>
3+
#include <string.h>
34

45
#include "arena/arena.h"
56
#include "logger/log.h"
@@ -249,6 +250,39 @@ void DVEC_FN(clear)(DVEC_NAME* vec) {
249250
vec->len = 0;
250251
}
251252

253+
// Creates a copy of the vector in the same arena.
254+
DVEC_NAME* DVEC_FN(clone)(const DVEC_NAME* vec) {
255+
RELEASE_ASSERT(vec);
256+
257+
LOG_DIAG(
258+
DEBUG,
259+
VEC,
260+
"Creating clone of " STRINGIFY(DVEC_NAME) " (Vec<" STRINGIFY(
261+
DVEC_TYPE
262+
) ">)"
263+
);
264+
265+
DVEC_NAME* new_vec = arena_alloc(vec->arena, sizeof(DVEC_NAME));
266+
new_vec->arena = vec->arena;
267+
new_vec->len = vec->len;
268+
new_vec->allocated_blocks = vec->allocated_blocks;
269+
new_vec->blocks[0] = NULL;
270+
new_vec->dbg_magic = DVEC_DEBUG_MAGIC;
271+
272+
for (size_t idx = 0; idx < vec->allocated_blocks; idx++) {
273+
size_t block_size = 1 << idx;
274+
new_vec->blocks[idx] =
275+
(DVEC_TYPE*)arena_alloc(vec->arena, sizeof(DVEC_TYPE) * block_size);
276+
memcpy(
277+
new_vec->blocks[idx],
278+
vec->blocks[idx],
279+
sizeof(DVEC_TYPE) * block_size
280+
);
281+
}
282+
283+
return new_vec;
284+
}
285+
252286
// Returns the length of the vector.
253287
size_t DVEC_FN(len)(const DVEC_NAME* vec) {
254288
RELEASE_ASSERT(vec);

libs/arena/src/dvec_test.c

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,39 @@ TEST_FUNC(test_vec_growth) {
9393
return TEST_RESULT_PASS;
9494
}
9595

96+
TEST_FUNC(test_vec_clone) {
97+
Arena* arena = arena_new(1024);
98+
MyTestVec* vec = my_test_vec_new(arena);
99+
100+
my_test_vec_push(vec, 42);
101+
my_test_vec_push(vec, 89);
102+
103+
MyTestVec* cloned = my_test_vec_clone(vec);
104+
my_test_vec_clear(vec);
105+
106+
TEST_ASSERT_EQ(my_test_vec_len(vec), (size_t)0);
107+
TEST_ASSERT_EQ(my_test_vec_len(cloned), (size_t)2);
108+
109+
my_test_vec_push(vec, 824);
110+
111+
int x;
112+
int y;
113+
TEST_ASSERT(my_test_vec_get(cloned, 0, &x));
114+
TEST_ASSERT(my_test_vec_get(cloned, 1, &y));
115+
TEST_ASSERT_EQ(42, x);
116+
TEST_ASSERT_EQ(89, y);
117+
118+
int z;
119+
TEST_ASSERT(!my_test_vec_get(cloned, 2, &z));
120+
121+
int w;
122+
TEST_ASSERT(my_test_vec_get(vec, 0, &w));
123+
TEST_ASSERT_EQ(824, w);
124+
125+
arena_free(arena);
126+
return TEST_RESULT_PASS;
127+
}
128+
96129
#else // TEST
97130

98131
void dvec_test_translation_unit_not_empty(void) {}

libs/pdf/include/pdf/content_stream/operation.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,12 @@ typedef struct {
4141
PdfLineJoinStyle set_join_style;
4242
PdfReal miter_limit;
4343
PdfName set_gstate;
44+
PdfName set_color_space;
45+
PdfObjectVec* set_color;
4446
GeomMat3 set_ctm;
4547
GeomVec2 new_subpath;
4648
GeomVec2 line_to;
49+
PdfReal set_text_metric;
4750
PdfOpParamsSetFont set_font;
4851
GeomVec2 text_offset;
4952
GeomMat3 set_text_matrix;

libs/pdf/include/pdf/page.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ typedef struct {
1818
PdfPageTreeNodeRef parent;
1919
PdfResourcesOptional resources;
2020
PdfRectangle media_box;
21+
PdfRectangleOptional crop_box;
2122
PdfContentsStreamRefVecOptional contents;
2223
PdfIntegerOptional rotate;
2324
PdfDictOptional group;

libs/pdf/src/catalog.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,9 @@ PdfError* pdf_deserialize_catalog(
2828
"Pages",
2929
&target_ptr->pages,
3030
PDF_DESERDE_RESOLVABLE(pdf_page_tree_node_ref_init)
31-
)
31+
),
32+
PDF_IGNORED_FIELD("PageMode"),
33+
PDF_IGNORED_FIELD("OpenAction")
3234
};
3335

3436
PDF_PROPAGATE(pdf_deserialize_dict(

libs/pdf/src/content_stream/operation.c

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -584,15 +584,27 @@ PdfError* pdf_deserialize_content_op(
584584
new_queue_op(operation_queue, PDF_OPERATOR_ET);
585585
return NULL;
586586
};
587+
case PDF_OPERATOR_Tc:
588+
case PDF_OPERATOR_Tw:
589+
case PDF_OPERATOR_Tz:
590+
case PDF_OPERATOR_TL: {
591+
PdfContentOp* queue_op = new_queue_op(operation_queue, op);
592+
PDF_PROPAGATE(deserialize_num_real(
593+
&queue_op->data.set_text_metric,
594+
operands,
595+
arena
596+
));
597+
return NULL;
598+
};
587599
case PDF_OPERATOR_Tf: {
588600
PDF_PROPAGATE(
589601
deserialize_set_font(operation_queue, operands, arena)
590602
);
591603
return NULL;
592604
}
593-
case PDF_OPERATOR_Td: {
594-
PdfContentOp* queue_op =
595-
new_queue_op(operation_queue, PDF_OPERATOR_Td);
605+
case PDF_OPERATOR_Td:
606+
case PDF_OPERATOR_TD: {
607+
PdfContentOp* queue_op = new_queue_op(operation_queue, op);
596608
PDF_PROPAGATE(
597609
deserialize_vec2(&queue_op->data.text_offset, operands, arena)
598610
);
@@ -608,6 +620,10 @@ PdfError* pdf_deserialize_content_op(
608620
));
609621
return NULL;
610622
}
623+
case PDF_OPERATOR_T_star: {
624+
new_queue_op(operation_queue, PDF_OPERATOR_T_star);
625+
return NULL;
626+
}
611627
case PDF_OPERATOR_Tj: {
612628
PdfContentOp* queue_op =
613629
new_queue_op(operation_queue, PDF_OPERATOR_TJ);
@@ -628,6 +644,24 @@ PdfError* pdf_deserialize_content_op(
628644
));
629645
return NULL;
630646
}
647+
case PDF_OPERATOR_CS:
648+
case PDF_OPERATOR_cs: {
649+
PdfContentOp* queue_op = new_queue_op(operation_queue, op);
650+
PDF_PROPAGATE(deserialize_name(
651+
&queue_op->data.set_color_space,
652+
operands,
653+
arena
654+
));
655+
return NULL;
656+
}
657+
case PDF_OPERATOR_SC:
658+
case PDF_OPERATOR_SCN:
659+
case PDF_OPERATOR_sc:
660+
case PDF_OPERATOR_scn: {
661+
PdfContentOp* queue_op = new_queue_op(operation_queue, op);
662+
queue_op->data.set_color = pdf_object_vec_clone(operands);
663+
return NULL;
664+
}
631665
case PDF_OPERATOR_g: {
632666
PDF_PROPAGATE(
633667
deserialize_set_gray(false, operation_queue, operands, arena)

libs/pdf/src/deserialize.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,8 @@ static PdfError* deserialize(
307307
RELEASE_ASSERT(arena);
308308

309309
switch (deserde_info.type) {
310-
case PDF_DESERDE_TYPE_UNIMPLEMENTED: {
310+
case PDF_DESERDE_TYPE_UNIMPLEMENTED:
311+
case PDF_DESERDE_TYPE_IGNORED: {
311312
LOG_PANIC("Unreachable");
312313
}
313314
case PDF_DESERDE_TYPE_OBJECT: {
@@ -476,6 +477,10 @@ PdfError* pdf_deserialize_dict(
476477
);
477478
}
478479

480+
if (field->deserde_info.type == PDF_DESERDE_TYPE_IGNORED) {
481+
continue;
482+
}
483+
479484
PDF_PROPAGATE(
480485
deserialize(
481486
entry.value,
@@ -501,7 +506,9 @@ PdfError* pdf_deserialize_dict(
501506
field->deserde_info.value.optional_info
502507
);
503508
} else if (field->deserde_info.type
504-
!= PDF_DESERDE_TYPE_UNIMPLEMENTED) {
509+
!= PDF_DESERDE_TYPE_UNIMPLEMENTED
510+
&& field->deserde_info.type
511+
!= PDF_DESERDE_TYPE_IGNORED) {
505512
return PDF_ERROR(
506513
PDF_ERR_MISSING_DICT_KEY,
507514
"Missing key `%s`",

libs/pdf/src/deserialize.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,10 @@ struct PdfDeserdeInfo {
5757
/// yet.
5858
PDF_DESERDE_TYPE_UNIMPLEMENTED,
5959

60+
/// Indicates that this field is known and optional, but should be
61+
/// skipped.
62+
PDF_DESERDE_TYPE_IGNORED,
63+
6064
/// Indicates that this struct contains information for deserializing a
6165
/// primitive type.
6266
PDF_DESERDE_TYPE_OBJECT,
@@ -178,6 +182,13 @@ PdfError* pdf_deserialize_operands(
178182
(PdfDeserdeInfo) {.type = PDF_DESERDE_TYPE_UNIMPLEMENTED} \
179183
)
180184

185+
#define PDF_IGNORED_FIELD(pdf_key_name) \
186+
PDF_FIELD( \
187+
pdf_key_name, \
188+
NULL, \
189+
(PdfDeserdeInfo) {.type = PDF_DESERDE_TYPE_IGNORED} \
190+
)
191+
181192
#define PDF_DESERDE_OBJECT(object_type) \
182193
(PdfDeserdeInfo) { \
183194
.type = PDF_DESERDE_TYPE_OBJECT, .value.object_info = (object_type) \

0 commit comments

Comments
 (0)