1 /** 2 * Copyright (c) 2008, SnakeYAML 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 * in compliance with the License. You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software distributed under the License 10 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 * or implied. See the License for the specific language governing permissions and limitations under 12 * the License. 13 */ 14 package org.yaml.snakeyaml.error; 15 16 import java.io.Serializable; 17 import org.yaml.snakeyaml.scanner.Constant; 18 19 /** 20 * It's just a record and its only use is producing nice error messages. Parser does not use it for 21 * any other purposes. 22 */ 23 public final class Mark implements Serializable { 24 25 private final String name; 26 private final int index; 27 private final int line; 28 private final int column; 29 private final int[] buffer; 30 private final int pointer; 31 toCodePoints(char[] str)32 private static int[] toCodePoints(char[] str) { 33 int[] codePoints = new int[Character.codePointCount(str, 0, str.length)]; 34 for (int i = 0, c = 0; i < str.length; c++) { 35 int cp = Character.codePointAt(str, i); 36 codePoints[c] = cp; 37 i += Character.charCount(cp); 38 } 39 return codePoints; 40 } 41 Mark(String name, int index, int line, int column, char[] str, int pointer)42 public Mark(String name, int index, int line, int column, char[] str, int pointer) { 43 this(name, index, line, column, toCodePoints(str), pointer); 44 } 45 46 /* 47 * Existed in older versions but replaced with {@code char[]}-based constructor. Restored in v1.22 48 * for backwards compatibility. 49 * 50 * @deprecated Since restored in v1.22. Use {@link Mark#Mark(String, int, int, int, char[], int)}. 51 */ 52 @Deprecated Mark(String name, int index, int line, int column, String buffer, int pointer)53 public Mark(String name, int index, int line, int column, String buffer, int pointer) { 54 this(name, index, line, column, buffer.toCharArray(), pointer); 55 } 56 Mark(String name, int index, int line, int column, int[] buffer, int pointer)57 public Mark(String name, int index, int line, int column, int[] buffer, int pointer) { 58 super(); 59 this.name = name; 60 this.index = index; 61 this.line = line; 62 this.column = column; 63 this.buffer = buffer; 64 this.pointer = pointer; 65 } 66 isLineBreak(int c)67 private boolean isLineBreak(int c) { 68 return Constant.NULL_OR_LINEBR.has(c); 69 } 70 get_snippet(int indent, int max_length)71 public String get_snippet(int indent, int max_length) { 72 float half = max_length / 2f - 1f; 73 int start = pointer; 74 String head = ""; 75 while ((start > 0) && !isLineBreak(buffer[start - 1])) { 76 start -= 1; 77 if (pointer - start > half) { 78 head = " ... "; 79 start += 5; 80 break; 81 } 82 } 83 String tail = ""; 84 int end = pointer; 85 while ((end < buffer.length) && !isLineBreak(buffer[end])) { 86 end += 1; 87 if (end - pointer > half) { 88 tail = " ... "; 89 end -= 5; 90 break; 91 } 92 } 93 94 StringBuilder result = new StringBuilder(); 95 for (int i = 0; i < indent; i++) { 96 result.append(" "); 97 } 98 result.append(head); 99 for (int i = start; i < end; i++) { 100 result.appendCodePoint(buffer[i]); 101 } 102 result.append(tail); 103 result.append("\n"); 104 for (int i = 0; i < indent + pointer - start + head.length(); i++) { 105 result.append(" "); 106 } 107 result.append("^"); 108 return result.toString(); 109 } 110 get_snippet()111 public String get_snippet() { 112 return get_snippet(4, 75); 113 } 114 115 @Override toString()116 public String toString() { 117 String snippet = get_snippet(); 118 String builder = 119 " in " + name + ", line " + (line + 1) + ", column " + (column + 1) + ":\n" + snippet; 120 return builder; 121 } 122 getName()123 public String getName() { 124 return name; 125 } 126 127 /** 128 * starts with 0 129 * 130 * @return line number 131 */ getLine()132 public int getLine() { 133 return line; 134 } 135 136 /** 137 * starts with 0 138 * 139 * @return column number 140 */ getColumn()141 public int getColumn() { 142 return column; 143 } 144 145 /** 146 * starts with 0 147 * 148 * @return character number 149 */ getIndex()150 public int getIndex() { 151 return index; 152 } 153 getBuffer()154 public int[] getBuffer() { 155 return buffer; 156 } 157 getPointer()158 public int getPointer() { 159 return pointer; 160 } 161 } 162