001: /*
002: * Copyright 2004-2008 H2 Group. Licensed under the H2 License, Version 1.0
003: * (http://h2database.com/html/license.html).
004: * Initial Developer: H2 Group
005: */
006: package org.h2.store;
007:
008: import java.sql.SQLException;
009:
010: import org.h2.constant.SysProperties;
011: import org.h2.message.Message;
012:
013: /**
014: * This class represents a byte buffer that is human readable up to some point.
015: * Number are stored in hex format.
016: * It is mainly used to debug storage problems.
017: */
018: public class DataPageText extends DataPage {
019:
020: public DataPageText(DataHandler handler, byte[] data) {
021: super (handler, data);
022: }
023:
024: public void setInt(int pos, int x) {
025: for (int i = 7; i >= 0; i--, x >>>= 4) {
026: data[i] = (byte) Character.forDigit(x & 0xf, 16);
027: }
028: }
029:
030: public void updateChecksum() {
031: if (CHECKSUM) {
032: int x = handler.getChecksum(data, 0, pos - 2);
033: data[pos - 2] = (byte) ('a' + (((x ^ (x >> 4)) & 0xf)));
034: }
035: }
036:
037: public void check(int len) throws SQLException {
038: if (CHECKSUM) {
039: int x = handler.getChecksum(data, 0, len - 2);
040: if (data[len - 2] == (byte) ('a' + (((x ^ (x >> 4)) & 0xf)))) {
041: return;
042: }
043: handler.handleInvalidChecksum();
044: }
045: }
046:
047: public int getFillerLength() {
048: return 2;
049: }
050:
051: public void writeInt(int x) {
052: if (SysProperties.CHECK) {
053: checkCapacity(8);
054: }
055: for (int i = 7; i >= 0; i--, x >>>= 4) {
056: data[pos + i] = (byte) Character.forDigit(x & 0xf, 16);
057: }
058: pos += 8;
059: }
060:
061: public int readInt() {
062: int x = 0;
063: if (data[pos] == ' ') {
064: pos += 8;
065: return 0;
066: }
067: for (int i = 8, c; i > 0; i--) {
068: x <<= 4;
069: x |= (c = data[pos++]) >= 'a' ? (c - 'a' + 10) : (c - '0');
070: }
071: return x;
072: }
073:
074: public int getIntLen() {
075: return 8;
076: }
077:
078: public int getLongLen(long x) {
079: return 16;
080: }
081:
082: public int getStringLen(String s) {
083: int len = 2 + s.length() + 1;
084: for (int i = 0; i < s.length(); i++) {
085: char c = s.charAt(i);
086: switch (c) {
087: case '\b':
088: case '\n':
089: case '\r':
090: case '\t':
091: case '\f':
092: case '"':
093: case '\\':
094: len++;
095: break;
096: default:
097: int ch = (c & 0xffff);
098: if ((ch >= ' ') && (ch <= 0xff)) {
099: // 0
100: } else {
101: len += 5;
102: }
103: }
104: }
105: return len;
106: }
107:
108: public String readString() {
109: StringBuffer buff = new StringBuffer(32);
110: if (SysProperties.CHECK && data[pos] != '"') {
111: throw Message.getInternalError("\" expected");
112: }
113: pos++;
114: while (true) {
115: char x = (char) (data[pos++] & 0xff);
116: if (x == '"') {
117: break;
118: } else if (x == '\\') {
119: x = (char) data[pos++];
120: switch (x) {
121: case 't':
122: buff.append('\t');
123: break;
124: case 'r':
125: buff.append('\r');
126: break;
127: case 'n':
128: buff.append('\n');
129: break;
130: case 'b':
131: buff.append('\b');
132: break;
133: case 'f':
134: buff.append('\f');
135: break;
136: case '"':
137: buff.append('"');
138: break;
139: case '\\':
140: buff.append('\\');
141: break;
142: case 'u': {
143: x = 0;
144: for (int i = 3, c; i >= 0; i--) {
145: x <<= 4;
146: x |= (c = data[pos++]) >= 'a' ? (c - 'a' + 10)
147: : (c - '0');
148: }
149: buff.append(x);
150: break;
151: }
152: default:
153: throw Message.getInternalError("unexpected " + x);
154: }
155: } else {
156: buff.append(x);
157: }
158: }
159: pos++;
160: return buff.toString();
161: }
162:
163: public void writeString(String s) {
164: checkCapacity(s.length() * 6 + 2);
165: data[pos++] = '\"';
166: for (int i = 0; i < s.length(); i++) {
167: char c = s.charAt(i);
168: switch (c) {
169: case '\t':
170: data[pos++] = '\\';
171: data[pos++] = 't';
172: break;
173: case '\r':
174: data[pos++] = '\\';
175: data[pos++] = 'r';
176: break;
177: case '\n':
178: data[pos++] = '\\';
179: data[pos++] = 'n';
180: break;
181: case '\b':
182: data[pos++] = '\\';
183: data[pos++] = 'b';
184: break;
185: case '\f':
186: data[pos++] = '\\';
187: data[pos++] = 'f';
188: break;
189: case '"':
190: data[pos++] = '\\';
191: data[pos++] = '\"';
192: break;
193: case '\\':
194: data[pos++] = '\\';
195: data[pos++] = '\\';
196: break;
197: default:
198: int ch = (c & 0xffff);
199: if ((ch >= ' ') && (ch <= 0xff)) {
200: data[pos++] = (byte) ch;
201: } else {
202: data[pos++] = '\\';
203: data[pos++] = 'u';
204: for (int j = 3; j >= 0; j--, ch >>>= 4) {
205: data[pos + j] = (byte) Character.forDigit(
206: ch & 0xf, 16);
207: }
208: pos += 4;
209: }
210: }
211: }
212: data[pos++] = '\"';
213: data[pos++] = ' ';
214: }
215:
216: public void fill(int len) {
217: if (pos > len) {
218: pos = len;
219: }
220: checkCapacity(len - pos);
221: while (pos < len) {
222: data[pos++] = ' ';
223: }
224: data[pos - 1] = '\n';
225: }
226: }
|