1 |
// Jericho HTML Parser - Java based library for analysing and manipulating HTML
|
2 |
// Version 3.2
|
3 |
// Copyright (C) 2004-2009 Martin Jericho
|
4 |
// http://jericho.htmlparser.net/
|
5 |
//
|
6 |
// This library is free software; you can redistribute it and/or
|
7 |
// modify it under the terms of either one of the following licences:
|
8 |
//
|
9 |
// 1. The Eclipse Public License (EPL) version 1.0,
|
10 |
// included in this distribution in the file licence-epl-1.0.html
|
11 |
// or available at http://www.eclipse.org/legal/epl-v10.html
|
12 |
//
|
13 |
// 2. The GNU Lesser General Public License (LGPL) version 2.1 or later,
|
14 |
// included in this distribution in the file licence-lgpl-2.1.txt
|
15 |
// or available at http://www.gnu.org/licenses/lgpl.txt
|
16 |
//
|
17 |
// This library is distributed on an "AS IS" basis,
|
18 |
// WITHOUT WARRANTY OF ANY KIND, either express or implied.
|
19 |
// See the individual licence texts for more details.
|
20 |
|
21 |
package net.htmlparser.jericho;
|
22 |
|
23 |
import java.util.*;
|
24 |
|
25 |
/**
|
26 |
* Represents the row and column number of a character position in the source document.
|
27 |
* <p>
|
28 |
* Obtained using the {@link Source#getRowColumnVector(int pos)} method.
|
29 |
*/
|
30 |
public final class RowColumnVector {
|
31 |
private final int row;
|
32 |
private final int column;
|
33 |
private final int pos;
|
34 |
|
35 |
private static final RowColumnVector FIRST=new RowColumnVector(1,1,0);
|
36 |
private static final RowColumnVector[] STREAMED=new RowColumnVector[0];
|
37 |
|
38 |
private RowColumnVector(final int row, final int column, final int pos) {
|
39 |
this.row=row;
|
40 |
this.column=column;
|
41 |
this.pos=pos;
|
42 |
}
|
43 |
|
44 |
private RowColumnVector(final int pos) {
|
45 |
// used in Streamed source where row and column aren't available.
|
46 |
this(-1,-1,pos);
|
47 |
}
|
48 |
|
49 |
/**
|
50 |
* Returns the row number of this character position in the source document.
|
51 |
* <p>
|
52 |
* If a {@link StreamedSource} is in use, this method always returns <code>-1</code>.
|
53 |
*
|
54 |
* @return the row number of this character position in the source document.
|
55 |
*/
|
56 |
public int getRow() {
|
57 |
return row;
|
58 |
}
|
59 |
|
60 |
/**
|
61 |
* Returns the column number of this character position in the source document.
|
62 |
* <p>
|
63 |
* If a {@link StreamedSource} is in use, this method always returns <code>-1</code>.
|
64 |
*
|
65 |
* @return the column number of this character position in the source document.
|
66 |
*/
|
67 |
public int getColumn() {
|
68 |
return column;
|
69 |
}
|
70 |
|
71 |
/**
|
72 |
* Returns the character position in the source document.
|
73 |
* @return the character position in the source document.
|
74 |
*/
|
75 |
public int getPos() {
|
76 |
return pos;
|
77 |
}
|
78 |
|
79 |
/**
|
80 |
* Returns a string representation of this character position.
|
81 |
* <p>
|
82 |
* The returned string has the format "<code>(<var>row</var>,<var>column</var>:<var>pos</var>)</code>".
|
83 |
*
|
84 |
* @return a string representation of this character position.
|
85 |
*/
|
86 |
public String toString() {
|
87 |
return appendTo(new StringBuilder(20)).toString();
|
88 |
}
|
89 |
|
90 |
StringBuilder appendTo(final StringBuilder sb) {
|
91 |
if (row!=-1) return sb.append("(r").append(row).append(",c").append(column).append(",p").append(pos).append(')');
|
92 |
return sb.append("(p").append(pos).append(')');
|
93 |
}
|
94 |
|
95 |
static RowColumnVector[] getCacheArray(final Source source) {
|
96 |
if (source.isStreamed()) return STREAMED;
|
97 |
final int lastSourcePos=source.end-1;
|
98 |
final ArrayList<RowColumnVector> list=new ArrayList<RowColumnVector>();
|
99 |
int pos=0;
|
100 |
list.add(FIRST);
|
101 |
int row=1;
|
102 |
while (pos<=lastSourcePos) {
|
103 |
final char ch=source.charAt(pos);
|
104 |
if (ch=='\n' || (ch=='\r' && (pos==lastSourcePos || source.charAt(pos+1)!='\n'))) list.add(new RowColumnVector(++row,1,pos+1));
|
105 |
pos++;
|
106 |
}
|
107 |
return list.toArray(new RowColumnVector[list.size()]);
|
108 |
}
|
109 |
|
110 |
static RowColumnVector get(final RowColumnVector[] cacheArray, final int pos) {
|
111 |
if (cacheArray==STREAMED) return new RowColumnVector(pos);
|
112 |
int low=0;
|
113 |
int high=cacheArray.length-1;
|
114 |
while (true) {
|
115 |
int mid=(low+high) >> 1;
|
116 |
final RowColumnVector rowColumnVector=cacheArray[mid];
|
117 |
if (rowColumnVector.pos<pos) {
|
118 |
if (mid==high) return new RowColumnVector(rowColumnVector.row,pos-rowColumnVector.pos+1,pos);
|
119 |
low=mid+1;
|
120 |
} else if (rowColumnVector.pos>pos) {
|
121 |
high=mid-1;
|
122 |
} else {
|
123 |
return rowColumnVector;
|
124 |
}
|
125 |
}
|
126 |
}
|
127 |
}
|