summaryrefslogtreecommitdiff
path: root/src/pdf_doc.c
blob: 3e55e161677415828ad9d2e3dfe9990506f7eaaa (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
/*
 * Copyright 2017 Vincent Sanders <vince@netsurf-browser.org>
 *
 * This file is part of libnspsl
 *
 * Licensed under the MIT License,
 *                http://www.opensource.org/licenses/mit-license.php
 */

#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>
#include <stdio.h>

#include <nspdf/errors.h>

#include "cos_parse.h"
#include "byte_class.h"
#include "cos_object.h"
#include "pdf_doc.h"

nspdferror
nspdf__stream_skip_ws(struct cos_stream *stream, strmoff_t *offset)
{
    uint8_t c;

    if ((*offset) >= stream->length) {
        return NSPDFERROR_OK;
    }

    c = stream_byte(stream, *offset);
    while (((*offset) < stream->length) &&
           ((bclass[c] & (BC_WSPC | BC_CMNT) ) != 0)) {
        (*offset)++;
        /* skip comments */
        if (((*offset) < stream->length) &&
            ((bclass[c] & BC_CMNT) != 0)) {
            c = stream_byte(stream, *offset);
            while ((*offset < stream->length) &&
                   ((bclass[c] & BC_EOLM ) == 0)) {
                (*offset)++;
                c = stream_byte(stream, (*offset));
            }
        }
        c = stream_byte(stream, (*offset));
    }
    return NSPDFERROR_OK;
}


/**
 * move offset to next non eol byte
 */
nspdferror
nspdf__stream_skip_eol(struct cos_stream *stream, strmoff_t *offset)
{
    uint8_t c;
    /** \todo sort out keeping offset in range */
    c = stream_byte(stream, *offset);
    while ((bclass[c] & BC_EOLM) != 0) {
        (*offset)++;
        c = stream_byte(stream, *offset);
    }
    return NSPDFERROR_OK;
}


nspdferror
nspdf__stream_read_uint(struct cos_stream *stream,
                        strmoff_t *offset_out,
                        uint64_t *result_out)
{
    uint8_t c; /* current byte from source data */
    strmoff_t offset; /* current offset of source data */
    unsigned int len; /* number of decimal places in number */
    uint8_t num[21]; /* temporary buffer for decimal values */
    uint64_t result=0; /* parsed result */
    uint64_t tens;

    offset = *offset_out;

    for (len = 0; len < sizeof(num); len++) {
        c = stream_byte(stream, offset);
        if ((bclass[c] & BC_DCML) != BC_DCML) {
            if (len == 0) {
                return -2; /* parse error no decimals in input */
            }
            /* sum value from each place */
            for (tens = 1; len > 0; tens = tens * 10, len--) {
                result += (num[len - 1] * tens);
            }

            *offset_out = offset;
            *result_out = result;

            return NSPDFERROR_OK;
        }
        num[len] = c - '0';
        offset++;
    }
    return NSPDFERROR_RANGE; /* number too long */
}