1 /*
2  *   This file is part of the pdftk port to java
3  *
4  *   Copyright (c) Marc Vinyals 2017-2018
5  *
6  *   The program is a java port of PDFtk, the PDF Toolkit
7  *   Copyright (c) 2003-2013 Steward and Lee, LLC
8  *
9  *   This program is free software: you can redistribute it and/or modify
10  *   it under the terms of the GNU General Public License as published by
11  *   the Free Software Foundation, either version 2 of the License, or
12  *   (at your option) any later version.
13  *
14  *   The program is distributed in the hope that it will be useful,
15  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  *   GNU General Public License for more details.
18  *
19  *   You should have received a copy of the GNU General Public License
20  *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
21  */
22 
23 package com.gitlab.pdftk_java;
24 
25 import java.util.regex.Matcher;
26 import java.util.regex.Pattern;
27 
28 class PageRange {
29   int beg, end;
30   final int m_num_pages;
31   final String m_argv;
32 
PageRange(int num_pages, String argv)33   PageRange(int num_pages, String argv) {
34     m_num_pages = num_pages;
35     m_argv = argv;
36   }
37 
parse_bound(String bound)38   int parse_bound(String bound) {
39     if (bound.equals("end")) return m_num_pages;
40     return Integer.parseInt(bound);
41   }
42 
out_of_range_error(String where)43   void out_of_range_error(String where) {
44     System.err.println("Error: Range " + where + " page number exceeds size of PDF");
45     System.err.println("   here: " + m_argv);
46     System.err.println("   input PDF has: " + m_num_pages + " pages.");
47     System.err.println("   Exiting.");
48   }
49 
parse(StringBuilder unparsed)50   boolean parse(StringBuilder unparsed) {
51     String page_regex = "(r?)(end|[0-9]*)";
52     Pattern range_regex = Pattern.compile(page_regex + "(-" + page_regex + ")?");
53     Matcher m = range_regex.matcher(unparsed.toString());
54     m.lookingAt();
55     unparsed.delete(m.start(), m.end());
56     String pre_reverse = m.group(1);
57     String pre_range = m.group(2);
58     String hyphen = m.group(3);
59     String post_reverse = m.group(4);
60     String post_range = m.group(5);
61     return parse(pre_reverse, pre_range, post_reverse, post_range);
62   }
63 
parse(String pre_reverse, String pre_range, String post_reverse, String post_range)64   boolean parse(String pre_reverse, String pre_range, String post_reverse, String post_range) {
65 
66     beg = 0; // default value
67     if (!pre_range.isEmpty()) {
68       beg = parse_bound(pre_range);
69 
70       if (m_num_pages < beg) {
71         // error: page number out of range
72         out_of_range_error("start");
73         return false;
74       }
75 
76       boolean pre_reverse_b = (!pre_reverse.isEmpty()); // single lc 'r' before page range
77       if (pre_reverse_b) // above test ensures good value here
78       beg = m_num_pages - beg + 1;
79     }
80 
81     end = beg; // default value
82     if (post_range != null && !post_range.isEmpty()) {
83       end = parse_bound(post_range);
84 
85       if (m_num_pages < end) {
86         // error: page number out of range
87         out_of_range_error("end");
88         return false;
89       }
90 
91       boolean post_reverse_b = (!post_reverse.isEmpty()); // single lc 'r' before page range
92       if (post_reverse_b) // above test ensures good value here
93       end = m_num_pages - end + 1;
94     }
95 
96     return true;
97   }
98 }
99