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 package com.healthmarketscience.jackcess;
29
30 import java.io.IOException;
31 import java.nio.ByteBuffer;
32 import java.nio.channels.FileChannel;
33 import java.nio.charset.Charset;
34 import java.util.Collections;
35 import java.util.HashMap;
36 import java.util.Map;
37
38
39
40
41
42 public abstract class JetFormat {
43
44
45 public static final int MAX_RECORD_SIZE = 1900;
46
47
48 public static final short TEXT_FIELD_UNIT_SIZE = 2;
49
50 public static final short TEXT_FIELD_MAX_LENGTH = 255 * TEXT_FIELD_UNIT_SIZE;
51
52 public enum CodecType {
53 NONE, JET, MSISAM, OFFICE;
54 }
55
56
57
58 private static final int OFFSET_VERSION = 20;
59
60 private static final byte CODE_VERSION_3 = 0x0;
61
62 private static final byte CODE_VERSION_4 = 0x1;
63
64 private static final byte CODE_VERSION_12 = 0x2;
65
66 private static final byte CODE_VERSION_14 = 0x3;
67
68
69 static final int OFFSET_ENGINE_NAME = 0x4;
70
71 static final int LENGTH_ENGINE_NAME = 0xF;
72
73 private static final int HEADER_LENGTH = 21;
74
75 private final static byte[] MSISAM_ENGINE = new byte[] {
76 'M', 'S', 'I', 'S', 'A', 'M', ' ', 'D', 'a', 't', 'a', 'b', 'a', 's', 'e'
77 };
78
79
80 private static final byte[] BASE_HEADER_MASK = new byte[]{
81 (byte)0xB5, (byte)0x6F, (byte)0x03, (byte)0x62, (byte)0x61, (byte)0x08,
82 (byte)0xC2, (byte)0x55, (byte)0xEB, (byte)0xA9, (byte)0x67, (byte)0x72,
83 (byte)0x43, (byte)0x3F, (byte)0x00, (byte)0x9C, (byte)0x7A, (byte)0x9F,
84 (byte)0x90, (byte)0xFF, (byte)0x80, (byte)0x9A, (byte)0x31, (byte)0xC5,
85 (byte)0x79, (byte)0xBA, (byte)0xED, (byte)0x30, (byte)0xBC, (byte)0xDF,
86 (byte)0xCC, (byte)0x9D, (byte)0x63, (byte)0xD9, (byte)0xE4, (byte)0xC3,
87 (byte)0x7B, (byte)0x42, (byte)0xFB, (byte)0x8A, (byte)0xBC, (byte)0x4E,
88 (byte)0x86, (byte)0xFB, (byte)0xEC, (byte)0x37, (byte)0x5D, (byte)0x44,
89 (byte)0x9C, (byte)0xFA, (byte)0xC6, (byte)0x5E, (byte)0x28, (byte)0xE6,
90 (byte)0x13, (byte)0xB6, (byte)0x8A, (byte)0x60, (byte)0x54, (byte)0x94,
91 (byte)0x7B, (byte)0x36, (byte)0xF5, (byte)0x72, (byte)0xDF, (byte)0xB1,
92 (byte)0x77, (byte)0xF4, (byte)0x13, (byte)0x43, (byte)0xCF, (byte)0xAF,
93 (byte)0xB1, (byte)0x33, (byte)0x34, (byte)0x61, (byte)0x79, (byte)0x5B,
94 (byte)0x92, (byte)0xB5, (byte)0x7C, (byte)0x2A, (byte)0x05, (byte)0xF1,
95 (byte)0x7C, (byte)0x99, (byte)0x01, (byte)0x1B, (byte)0x98, (byte)0xFD,
96 (byte)0x12, (byte)0x4F, (byte)0x4A, (byte)0x94, (byte)0x6C, (byte)0x3E,
97 (byte)0x60, (byte)0x26, (byte)0x5F, (byte)0x95, (byte)0xF8, (byte)0xD0,
98 (byte)0x89, (byte)0x24, (byte)0x85, (byte)0x67, (byte)0xC6, (byte)0x1F,
99 (byte)0x27, (byte)0x44, (byte)0xD2, (byte)0xEE, (byte)0xCF, (byte)0x65,
100 (byte)0xED, (byte)0xFF, (byte)0x07, (byte)0xC7, (byte)0x46, (byte)0xA1,
101 (byte)0x78, (byte)0x16, (byte)0x0C, (byte)0xED, (byte)0xE9, (byte)0x2D,
102 (byte)0x62, (byte)0xD4};
103
104
105
106 private static final String ACCESS_VERSION_2000 = "08.50";
107
108
109 private static final String ACCESS_VERSION_2003 = "09.50";
110
111
112 static final byte[][] PROPERTY_MAP_TYPES = {
113 new byte[]{'M', 'R', '2', '\0'},
114 new byte[]{'K', 'K', 'D', '\0'}};
115
116
117 private static final class PossibleFileFormats {
118 private static final Map<String,Database.FileFormat> POSSIBLE_VERSION_3 =
119 Collections.singletonMap((String)null, Database.FileFormat.V1997);
120
121 private static final Map<String,Database.FileFormat> POSSIBLE_VERSION_4 =
122 new HashMap<String,Database.FileFormat>();
123
124 private static final Map<String,Database.FileFormat> POSSIBLE_VERSION_12 =
125 Collections.singletonMap((String)null, Database.FileFormat.V2007);
126
127 private static final Map<String,Database.FileFormat> POSSIBLE_VERSION_14 =
128 Collections.singletonMap((String)null, Database.FileFormat.V2010);
129
130 private static final Map<String,Database.FileFormat> POSSIBLE_VERSION_MSISAM =
131 Collections.singletonMap((String)null, Database.FileFormat.MSISAM);
132
133 static {
134 POSSIBLE_VERSION_4.put(ACCESS_VERSION_2000, Database.FileFormat.V2000);
135 POSSIBLE_VERSION_4.put(ACCESS_VERSION_2003, Database.FileFormat.V2003);
136 }
137 }
138
139
140 public static final JetFormat VERSION_3 = new Jet3Format();
141
142 public static final JetFormat VERSION_4 = new Jet4Format();
143
144 public static final JetFormat VERSION_MSISAM = new MSISAMFormat();
145
146 public static final JetFormat VERSION_12 = new Jet12Format();
147
148 public static final JetFormat VERSION_14 = new Jet14Format();
149
150
151
152
153
154
155 private final String _name;
156
157
158 public final boolean READ_ONLY;
159
160
161 public final boolean INDEXES_SUPPORTED;
162
163
164 public final CodecType CODEC_TYPE;
165
166
167 public final int PAGE_SIZE;
168 public final long MAX_DATABASE_SIZE;
169
170 public final int MAX_ROW_SIZE;
171 public final int DATA_PAGE_INITIAL_FREE_SPACE;
172
173 public final int OFFSET_MASKED_HEADER;
174 public final byte[] HEADER_MASK;
175 public final int OFFSET_HEADER_DATE;
176 public final int OFFSET_PASSWORD;
177 public final int SIZE_PASSWORD;
178 public final int OFFSET_SORT_ORDER;
179 public final int SIZE_SORT_ORDER;
180 public final int OFFSET_CODE_PAGE;
181 public final int OFFSET_ENCODING_KEY;
182 public final int OFFSET_NEXT_TABLE_DEF_PAGE;
183 public final int OFFSET_NUM_ROWS;
184 public final int OFFSET_NEXT_AUTO_NUMBER;
185 public final int OFFSET_NEXT_COMPLEX_AUTO_NUMBER;
186 public final int OFFSET_TABLE_TYPE;
187 public final int OFFSET_MAX_COLS;
188 public final int OFFSET_NUM_VAR_COLS;
189 public final int OFFSET_NUM_COLS;
190 public final int OFFSET_NUM_INDEX_SLOTS;
191 public final int OFFSET_NUM_INDEXES;
192 public final int OFFSET_OWNED_PAGES;
193 public final int OFFSET_FREE_SPACE_PAGES;
194 public final int OFFSET_INDEX_DEF_BLOCK;
195
196 public final int SIZE_INDEX_COLUMN_BLOCK;
197 public final int SIZE_INDEX_INFO_BLOCK;
198
199 public final int OFFSET_COLUMN_TYPE;
200 public final int OFFSET_COLUMN_NUMBER;
201 public final int OFFSET_COLUMN_PRECISION;
202 public final int OFFSET_COLUMN_SCALE;
203 public final int OFFSET_COLUMN_SORT_ORDER;
204 public final int OFFSET_COLUMN_CODE_PAGE;
205 public final int OFFSET_COLUMN_COMPLEX_ID;
206 public final int OFFSET_COLUMN_FLAGS;
207 public final int OFFSET_COLUMN_COMPRESSED_UNICODE;
208 public final int OFFSET_COLUMN_LENGTH;
209 public final int OFFSET_COLUMN_VARIABLE_TABLE_INDEX;
210 public final int OFFSET_COLUMN_FIXED_DATA_OFFSET;
211 public final int OFFSET_COLUMN_FIXED_DATA_ROW_OFFSET;
212
213 public final int OFFSET_TABLE_DEF_LOCATION;
214
215 public final int OFFSET_ROW_START;
216 public final int OFFSET_USAGE_MAP_START;
217
218 public final int OFFSET_USAGE_MAP_PAGE_DATA;
219
220 public final int OFFSET_REFERENCE_MAP_PAGE_NUMBERS;
221
222 public final int OFFSET_FREE_SPACE;
223 public final int OFFSET_NUM_ROWS_ON_DATA_PAGE;
224 public final int MAX_NUM_ROWS_ON_DATA_PAGE;
225
226 public final int OFFSET_INDEX_COMPRESSED_BYTE_COUNT;
227 public final int OFFSET_INDEX_ENTRY_MASK;
228 public final int OFFSET_PREV_INDEX_PAGE;
229 public final int OFFSET_NEXT_INDEX_PAGE;
230 public final int OFFSET_CHILD_TAIL_INDEX_PAGE;
231
232 public final int SIZE_INDEX_DEFINITION;
233 public final int SIZE_COLUMN_HEADER;
234 public final int SIZE_ROW_LOCATION;
235 public final int SIZE_LONG_VALUE_DEF;
236 public final int MAX_INLINE_LONG_VALUE_SIZE;
237 public final int MAX_LONG_VALUE_ROW_SIZE;
238 public final int MAX_COMPRESSED_UNICODE_SIZE;
239 public final int SIZE_TDEF_HEADER;
240 public final int SIZE_TDEF_TRAILER;
241 public final int SIZE_COLUMN_DEF_BLOCK;
242 public final int SIZE_INDEX_ENTRY_MASK;
243 public final int SKIP_BEFORE_INDEX_FLAGS;
244 public final int SKIP_AFTER_INDEX_FLAGS;
245 public final int SKIP_BEFORE_INDEX_SLOT;
246 public final int SKIP_AFTER_INDEX_SLOT;
247 public final int SKIP_BEFORE_INDEX;
248 public final int SIZE_NAME_LENGTH;
249 public final int SIZE_ROW_COLUMN_COUNT;
250 public final int SIZE_ROW_VAR_COL_OFFSET;
251
252 public final int USAGE_MAP_TABLE_BYTE_LENGTH;
253
254 public final int MAX_COLUMNS_PER_TABLE;
255 public final int MAX_TABLE_NAME_LENGTH;
256 public final int MAX_COLUMN_NAME_LENGTH;
257 public final int MAX_INDEX_NAME_LENGTH;
258
259 public final boolean LEGACY_NUMERIC_INDEXES;
260
261 public final Charset CHARSET;
262 public final Column.SortOrder DEFAULT_SORT_ORDER;
263
264
265
266
267
268
269 public static JetFormat getFormat(FileChannel channel) throws IOException {
270 ByteBuffer buffer = ByteBuffer.allocate(HEADER_LENGTH);
271 int bytesRead = channel.read(buffer, 0L);
272 if(bytesRead < HEADER_LENGTH) {
273 throw new IOException("Empty database file");
274 }
275 buffer.flip();
276 byte version = buffer.get(OFFSET_VERSION);
277 if (version == CODE_VERSION_3) {
278 return VERSION_3;
279 } else if (version == CODE_VERSION_4) {
280 if(ByteUtil.matchesRange(buffer, OFFSET_ENGINE_NAME, MSISAM_ENGINE)) {
281 return VERSION_MSISAM;
282 }
283 return VERSION_4;
284 } else if (version == CODE_VERSION_12) {
285 return VERSION_12;
286 } else if (version == CODE_VERSION_14) {
287 return VERSION_14;
288 }
289 throw new IOException("Unsupported " +
290 ((version < CODE_VERSION_3) ? "older" : "newer") +
291 " version: " + version);
292 }
293
294 private JetFormat(String name) {
295 _name = name;
296
297 READ_ONLY = defineReadOnly();
298 INDEXES_SUPPORTED = defineIndexesSupported();
299 CODEC_TYPE = defineCodecType();
300
301 PAGE_SIZE = definePageSize();
302 MAX_DATABASE_SIZE = defineMaxDatabaseSize();
303
304 MAX_ROW_SIZE = defineMaxRowSize();
305 DATA_PAGE_INITIAL_FREE_SPACE = defineDataPageInitialFreeSpace();
306
307 OFFSET_MASKED_HEADER = defineOffsetMaskedHeader();
308 HEADER_MASK = defineHeaderMask();
309 OFFSET_HEADER_DATE = defineOffsetHeaderDate();
310 OFFSET_PASSWORD = defineOffsetPassword();
311 SIZE_PASSWORD = defineSizePassword();
312 OFFSET_SORT_ORDER = defineOffsetSortOrder();
313 SIZE_SORT_ORDER = defineSizeSortOrder();
314 OFFSET_CODE_PAGE = defineOffsetCodePage();
315 OFFSET_ENCODING_KEY = defineOffsetEncodingKey();
316 OFFSET_NEXT_TABLE_DEF_PAGE = defineOffsetNextTableDefPage();
317 OFFSET_NUM_ROWS = defineOffsetNumRows();
318 OFFSET_NEXT_AUTO_NUMBER = defineOffsetNextAutoNumber();
319 OFFSET_NEXT_COMPLEX_AUTO_NUMBER = defineOffsetNextComplexAutoNumber();
320 OFFSET_TABLE_TYPE = defineOffsetTableType();
321 OFFSET_MAX_COLS = defineOffsetMaxCols();
322 OFFSET_NUM_VAR_COLS = defineOffsetNumVarCols();
323 OFFSET_NUM_COLS = defineOffsetNumCols();
324 OFFSET_NUM_INDEX_SLOTS = defineOffsetNumIndexSlots();
325 OFFSET_NUM_INDEXES = defineOffsetNumIndexes();
326 OFFSET_OWNED_PAGES = defineOffsetOwnedPages();
327 OFFSET_FREE_SPACE_PAGES = defineOffsetFreeSpacePages();
328 OFFSET_INDEX_DEF_BLOCK = defineOffsetIndexDefBlock();
329
330 SIZE_INDEX_COLUMN_BLOCK = defineSizeIndexColumnBlock();
331 SIZE_INDEX_INFO_BLOCK = defineSizeIndexInfoBlock();
332
333 OFFSET_COLUMN_TYPE = defineOffsetColumnType();
334 OFFSET_COLUMN_NUMBER = defineOffsetColumnNumber();
335 OFFSET_COLUMN_PRECISION = defineOffsetColumnPrecision();
336 OFFSET_COLUMN_SCALE = defineOffsetColumnScale();
337 OFFSET_COLUMN_SORT_ORDER = defineOffsetColumnSortOrder();
338 OFFSET_COLUMN_CODE_PAGE = defineOffsetColumnCodePage();
339 OFFSET_COLUMN_COMPLEX_ID = defineOffsetColumnComplexId();
340 OFFSET_COLUMN_FLAGS = defineOffsetColumnFlags();
341 OFFSET_COLUMN_COMPRESSED_UNICODE = defineOffsetColumnCompressedUnicode();
342 OFFSET_COLUMN_LENGTH = defineOffsetColumnLength();
343 OFFSET_COLUMN_VARIABLE_TABLE_INDEX = defineOffsetColumnVariableTableIndex();
344 OFFSET_COLUMN_FIXED_DATA_OFFSET = defineOffsetColumnFixedDataOffset();
345 OFFSET_COLUMN_FIXED_DATA_ROW_OFFSET = defineOffsetColumnFixedDataRowOffset();
346
347 OFFSET_TABLE_DEF_LOCATION = defineOffsetTableDefLocation();
348
349 OFFSET_ROW_START = defineOffsetRowStart();
350 OFFSET_USAGE_MAP_START = defineOffsetUsageMapStart();
351
352 OFFSET_USAGE_MAP_PAGE_DATA = defineOffsetUsageMapPageData();
353
354 OFFSET_REFERENCE_MAP_PAGE_NUMBERS = defineOffsetReferenceMapPageNumbers();
355
356 OFFSET_FREE_SPACE = defineOffsetFreeSpace();
357 OFFSET_NUM_ROWS_ON_DATA_PAGE = defineOffsetNumRowsOnDataPage();
358 MAX_NUM_ROWS_ON_DATA_PAGE = defineMaxNumRowsOnDataPage();
359
360 OFFSET_INDEX_COMPRESSED_BYTE_COUNT = defineOffsetIndexCompressedByteCount();
361 OFFSET_INDEX_ENTRY_MASK = defineOffsetIndexEntryMask();
362 OFFSET_PREV_INDEX_PAGE = defineOffsetPrevIndexPage();
363 OFFSET_NEXT_INDEX_PAGE = defineOffsetNextIndexPage();
364 OFFSET_CHILD_TAIL_INDEX_PAGE = defineOffsetChildTailIndexPage();
365
366 SIZE_INDEX_DEFINITION = defineSizeIndexDefinition();
367 SIZE_COLUMN_HEADER = defineSizeColumnHeader();
368 SIZE_ROW_LOCATION = defineSizeRowLocation();
369 SIZE_LONG_VALUE_DEF = defineSizeLongValueDef();
370 MAX_INLINE_LONG_VALUE_SIZE = defineMaxInlineLongValueSize();
371 MAX_LONG_VALUE_ROW_SIZE = defineMaxLongValueRowSize();
372 MAX_COMPRESSED_UNICODE_SIZE = defineMaxCompressedUnicodeSize();
373 SIZE_TDEF_HEADER = defineSizeTdefHeader();
374 SIZE_TDEF_TRAILER = defineSizeTdefTrailer();
375 SIZE_COLUMN_DEF_BLOCK = defineSizeColumnDefBlock();
376 SIZE_INDEX_ENTRY_MASK = defineSizeIndexEntryMask();
377 SKIP_BEFORE_INDEX_FLAGS = defineSkipBeforeIndexFlags();
378 SKIP_AFTER_INDEX_FLAGS = defineSkipAfterIndexFlags();
379 SKIP_BEFORE_INDEX_SLOT = defineSkipBeforeIndexSlot();
380 SKIP_AFTER_INDEX_SLOT = defineSkipAfterIndexSlot();
381 SKIP_BEFORE_INDEX = defineSkipBeforeIndex();
382 SIZE_NAME_LENGTH = defineSizeNameLength();
383 SIZE_ROW_COLUMN_COUNT = defineSizeRowColumnCount();
384 SIZE_ROW_VAR_COL_OFFSET = defineSizeRowVarColOffset();
385
386 USAGE_MAP_TABLE_BYTE_LENGTH = defineUsageMapTableByteLength();
387
388 MAX_COLUMNS_PER_TABLE = defineMaxColumnsPerTable();
389 MAX_TABLE_NAME_LENGTH = defineMaxTableNameLength();
390 MAX_COLUMN_NAME_LENGTH = defineMaxColumnNameLength();
391 MAX_INDEX_NAME_LENGTH = defineMaxIndexNameLength();
392
393 LEGACY_NUMERIC_INDEXES = defineLegacyNumericIndexes();
394
395 CHARSET = defineCharset();
396 DEFAULT_SORT_ORDER = defineDefaultSortOrder();
397 }
398
399 protected abstract boolean defineReadOnly();
400 protected abstract boolean defineIndexesSupported();
401 protected abstract CodecType defineCodecType();
402
403 protected abstract int definePageSize();
404 protected abstract long defineMaxDatabaseSize();
405
406 protected abstract int defineMaxRowSize();
407 protected abstract int defineDataPageInitialFreeSpace();
408
409 protected abstract int defineOffsetMaskedHeader();
410 protected abstract byte[] defineHeaderMask();
411 protected abstract int defineOffsetHeaderDate();
412 protected abstract int defineOffsetPassword();
413 protected abstract int defineSizePassword();
414 protected abstract int defineOffsetSortOrder();
415 protected abstract int defineSizeSortOrder();
416 protected abstract int defineOffsetCodePage();
417 protected abstract int defineOffsetEncodingKey();
418 protected abstract int defineOffsetNextTableDefPage();
419 protected abstract int defineOffsetNumRows();
420 protected abstract int defineOffsetNextAutoNumber();
421 protected abstract int defineOffsetNextComplexAutoNumber();
422 protected abstract int defineOffsetTableType();
423 protected abstract int defineOffsetMaxCols();
424 protected abstract int defineOffsetNumVarCols();
425 protected abstract int defineOffsetNumCols();
426 protected abstract int defineOffsetNumIndexSlots();
427 protected abstract int defineOffsetNumIndexes();
428 protected abstract int defineOffsetOwnedPages();
429 protected abstract int defineOffsetFreeSpacePages();
430 protected abstract int defineOffsetIndexDefBlock();
431
432 protected abstract int defineSizeIndexColumnBlock();
433 protected abstract int defineSizeIndexInfoBlock();
434
435 protected abstract int defineOffsetColumnType();
436 protected abstract int defineOffsetColumnNumber();
437 protected abstract int defineOffsetColumnPrecision();
438 protected abstract int defineOffsetColumnScale();
439 protected abstract int defineOffsetColumnSortOrder();
440 protected abstract int defineOffsetColumnCodePage();
441 protected abstract int defineOffsetColumnComplexId();
442 protected abstract int defineOffsetColumnFlags();
443 protected abstract int defineOffsetColumnCompressedUnicode();
444 protected abstract int defineOffsetColumnLength();
445 protected abstract int defineOffsetColumnVariableTableIndex();
446 protected abstract int defineOffsetColumnFixedDataOffset();
447 protected abstract int defineOffsetColumnFixedDataRowOffset();
448
449 protected abstract int defineOffsetTableDefLocation();
450
451 protected abstract int defineOffsetRowStart();
452 protected abstract int defineOffsetUsageMapStart();
453
454 protected abstract int defineOffsetUsageMapPageData();
455
456 protected abstract int defineOffsetReferenceMapPageNumbers();
457
458 protected abstract int defineOffsetFreeSpace();
459 protected abstract int defineOffsetNumRowsOnDataPage();
460 protected abstract int defineMaxNumRowsOnDataPage();
461
462 protected abstract int defineOffsetIndexCompressedByteCount();
463 protected abstract int defineOffsetIndexEntryMask();
464 protected abstract int defineOffsetPrevIndexPage();
465 protected abstract int defineOffsetNextIndexPage();
466 protected abstract int defineOffsetChildTailIndexPage();
467
468 protected abstract int defineSizeIndexDefinition();
469 protected abstract int defineSizeColumnHeader();
470 protected abstract int defineSizeRowLocation();
471 protected abstract int defineSizeLongValueDef();
472 protected abstract int defineMaxInlineLongValueSize();
473 protected abstract int defineMaxLongValueRowSize();
474 protected abstract int defineMaxCompressedUnicodeSize();
475 protected abstract int defineSizeTdefHeader();
476 protected abstract int defineSizeTdefTrailer();
477 protected abstract int defineSizeColumnDefBlock();
478 protected abstract int defineSizeIndexEntryMask();
479 protected abstract int defineSkipBeforeIndexFlags();
480 protected abstract int defineSkipAfterIndexFlags();
481 protected abstract int defineSkipBeforeIndexSlot();
482 protected abstract int defineSkipAfterIndexSlot();
483 protected abstract int defineSkipBeforeIndex();
484 protected abstract int defineSizeNameLength();
485 protected abstract int defineSizeRowColumnCount();
486 protected abstract int defineSizeRowVarColOffset();
487
488 protected abstract int defineUsageMapTableByteLength();
489
490 protected abstract int defineMaxColumnsPerTable();
491 protected abstract int defineMaxTableNameLength();
492 protected abstract int defineMaxColumnNameLength();
493 protected abstract int defineMaxIndexNameLength();
494
495 protected abstract Charset defineCharset();
496 protected abstract Column.SortOrder defineDefaultSortOrder();
497
498 protected abstract boolean defineLegacyNumericIndexes();
499
500 protected abstract Map<String,Database.FileFormat> getPossibleFileFormats();
501
502 protected abstract boolean isSupportedDataType(DataType type);
503
504 @Override
505 public String toString() {
506 return _name;
507 }
508
509 private static class Jet3Format extends JetFormat {
510
511 private Jet3Format() {
512 super("VERSION_3");
513 }
514
515 @Override
516 protected boolean defineReadOnly() { return true; }
517
518 @Override
519 protected boolean defineIndexesSupported() { return false; }
520
521 @Override
522 protected CodecType defineCodecType() {
523 return CodecType.JET;
524 }
525
526 @Override
527 protected int definePageSize() { return 2048; }
528
529 @Override
530 protected long defineMaxDatabaseSize() {
531 return (1L * 1024L * 1024L * 1024L);
532 }
533
534 @Override
535 protected int defineMaxRowSize() { return 2012; }
536 @Override
537 protected int defineDataPageInitialFreeSpace() { return PAGE_SIZE - 14; }
538
539 @Override
540 protected int defineOffsetMaskedHeader() { return 24; }
541 @Override
542 protected byte[] defineHeaderMask() {
543 return ByteUtil.copyOf(BASE_HEADER_MASK, BASE_HEADER_MASK.length - 2);
544 }
545 @Override
546 protected int defineOffsetHeaderDate() { return -1; }
547 @Override
548 protected int defineOffsetPassword() { return 66; }
549 @Override
550 protected int defineSizePassword() { return 20; }
551 @Override
552 protected int defineOffsetSortOrder() { return 58; }
553 @Override
554 protected int defineSizeSortOrder() { return 2; }
555 @Override
556 protected int defineOffsetCodePage() { return 60; }
557 @Override
558 protected int defineOffsetEncodingKey() { return 62; }
559 @Override
560 protected int defineOffsetNextTableDefPage() { return 4; }
561 @Override
562 protected int defineOffsetNumRows() { return 12; }
563 @Override
564 protected int defineOffsetNextAutoNumber() { return 20; }
565 @Override
566 protected int defineOffsetNextComplexAutoNumber() { return -1; }
567 @Override
568 protected int defineOffsetTableType() { return 20; }
569 @Override
570 protected int defineOffsetMaxCols() { return 21; }
571 @Override
572 protected int defineOffsetNumVarCols() { return 23; }
573 @Override
574 protected int defineOffsetNumCols() { return 25; }
575 @Override
576 protected int defineOffsetNumIndexSlots() { return 27; }
577 @Override
578 protected int defineOffsetNumIndexes() { return 31; }
579 @Override
580 protected int defineOffsetOwnedPages() { return 35; }
581 @Override
582 protected int defineOffsetFreeSpacePages() { return 39; }
583 @Override
584 protected int defineOffsetIndexDefBlock() { return 43; }
585
586 @Override
587 protected int defineSizeIndexColumnBlock() { return 39; }
588 @Override
589 protected int defineSizeIndexInfoBlock() { return 20; }
590
591 @Override
592 protected int defineOffsetColumnType() { return 0; }
593 @Override
594 protected int defineOffsetColumnNumber() { return 1; }
595 @Override
596 protected int defineOffsetColumnPrecision() { return 11; }
597 @Override
598 protected int defineOffsetColumnScale() { return 12; }
599 @Override
600 protected int defineOffsetColumnSortOrder() { return 9; }
601 @Override
602 protected int defineOffsetColumnCodePage() { return 11; }
603 @Override
604 protected int defineOffsetColumnComplexId() { return -1; }
605 @Override
606 protected int defineOffsetColumnFlags() { return 13; }
607 @Override
608 protected int defineOffsetColumnCompressedUnicode() { return 16; }
609 @Override
610 protected int defineOffsetColumnLength() { return 16; }
611 @Override
612 protected int defineOffsetColumnVariableTableIndex() { return 3; }
613 @Override
614 protected int defineOffsetColumnFixedDataOffset() { return 14; }
615 @Override
616 protected int defineOffsetColumnFixedDataRowOffset() { return 1; }
617
618 @Override
619 protected int defineOffsetTableDefLocation() { return 4; }
620
621 @Override
622 protected int defineOffsetRowStart() { return 10; }
623 @Override
624 protected int defineOffsetUsageMapStart() { return 5; }
625
626 @Override
627 protected int defineOffsetUsageMapPageData() { return 4; }
628
629 @Override
630 protected int defineOffsetReferenceMapPageNumbers() { return 1; }
631
632 @Override
633 protected int defineOffsetFreeSpace() { return 2; }
634 @Override
635 protected int defineOffsetNumRowsOnDataPage() { return 8; }
636 @Override
637 protected int defineMaxNumRowsOnDataPage() { return 255; }
638
639 @Override
640 protected int defineOffsetIndexCompressedByteCount() { return 20; }
641 @Override
642 protected int defineOffsetIndexEntryMask() { return 22; }
643 @Override
644 protected int defineOffsetPrevIndexPage() { return 8; }
645 @Override
646 protected int defineOffsetNextIndexPage() { return 12; }
647 @Override
648 protected int defineOffsetChildTailIndexPage() { return 16; }
649
650 @Override
651 protected int defineSizeIndexDefinition() { return 8; }
652 @Override
653 protected int defineSizeColumnHeader() { return 18; }
654 @Override
655 protected int defineSizeRowLocation() { return 2; }
656 @Override
657 protected int defineSizeLongValueDef() { return 12; }
658 @Override
659 protected int defineMaxInlineLongValueSize() { return 64; }
660 @Override
661 protected int defineMaxLongValueRowSize() { return 2032; }
662 @Override
663 protected int defineMaxCompressedUnicodeSize() { return 1024; }
664 @Override
665 protected int defineSizeTdefHeader() { return 63; }
666 @Override
667 protected int defineSizeTdefTrailer() { return 2; }
668 @Override
669 protected int defineSizeColumnDefBlock() { return 25; }
670 @Override
671 protected int defineSizeIndexEntryMask() { return 226; }
672 @Override
673 protected int defineSkipBeforeIndexFlags() { return 0; }
674 @Override
675 protected int defineSkipAfterIndexFlags() { return 0; }
676 @Override
677 protected int defineSkipBeforeIndexSlot() { return 0; }
678 @Override
679 protected int defineSkipAfterIndexSlot() { return 0; }
680 @Override
681 protected int defineSkipBeforeIndex() { return 0; }
682 @Override
683 protected int defineSizeNameLength() { return 1; }
684 @Override
685 protected int defineSizeRowColumnCount() { return 1; }
686 @Override
687 protected int defineSizeRowVarColOffset() { return 1; }
688
689 @Override
690 protected int defineUsageMapTableByteLength() { return 128; }
691
692 @Override
693 protected int defineMaxColumnsPerTable() { return 255; }
694
695 @Override
696 protected int defineMaxTableNameLength() { return 64; }
697
698 @Override
699 protected int defineMaxColumnNameLength() { return 64; }
700
701 @Override
702 protected int defineMaxIndexNameLength() { return 64; }
703
704 @Override
705 protected boolean defineLegacyNumericIndexes() { return true; }
706
707 @Override
708 protected Charset defineCharset() { return Charset.defaultCharset(); }
709
710 @Override
711 protected Column.SortOrder defineDefaultSortOrder() {
712 return Column.GENERAL_LEGACY_SORT_ORDER;
713 }
714
715 @Override
716 protected Map<String,Database.FileFormat> getPossibleFileFormats()
717 {
718 return PossibleFileFormats.POSSIBLE_VERSION_3;
719 }
720
721 @Override
722 protected boolean isSupportedDataType(DataType type) {
723 return (type != DataType.COMPLEX_TYPE);
724 }
725 }
726
727 private static class Jet4Format extends JetFormat {
728
729 private Jet4Format() {
730 this("VERSION_4");
731 }
732
733 private Jet4Format(String name) {
734 super(name);
735 }
736
737 @Override
738 protected boolean defineReadOnly() { return false; }
739
740 @Override
741 protected boolean defineIndexesSupported() { return true; }
742
743 @Override
744 protected CodecType defineCodecType() {
745 return CodecType.JET;
746 }
747
748 @Override
749 protected int definePageSize() { return 4096; }
750
751 @Override
752 protected long defineMaxDatabaseSize() {
753 return (2L * 1024L * 1024L * 1024L);
754 }
755
756 @Override
757 protected int defineMaxRowSize() { return 4060; }
758 @Override
759 protected int defineDataPageInitialFreeSpace() { return PAGE_SIZE - 14; }
760
761 @Override
762 protected int defineOffsetMaskedHeader() { return 24; }
763 @Override
764 protected byte[] defineHeaderMask() { return BASE_HEADER_MASK; }
765 @Override
766 protected int defineOffsetHeaderDate() { return 114; }
767 @Override
768 protected int defineOffsetPassword() { return 66; }
769 @Override
770 protected int defineSizePassword() { return 40; }
771 @Override
772 protected int defineOffsetSortOrder() { return 110; }
773 @Override
774 protected int defineSizeSortOrder() { return 4; }
775 @Override
776 protected int defineOffsetCodePage() { return 60; }
777 @Override
778 protected int defineOffsetEncodingKey() { return 62; }
779 @Override
780 protected int defineOffsetNextTableDefPage() { return 4; }
781 @Override
782 protected int defineOffsetNumRows() { return 16; }
783 @Override
784 protected int defineOffsetNextAutoNumber() { return 20; }
785 @Override
786 protected int defineOffsetNextComplexAutoNumber() { return -1; }
787 @Override
788 protected int defineOffsetTableType() { return 40; }
789 @Override
790 protected int defineOffsetMaxCols() { return 41; }
791 @Override
792 protected int defineOffsetNumVarCols() { return 43; }
793 @Override
794 protected int defineOffsetNumCols() { return 45; }
795 @Override
796 protected int defineOffsetNumIndexSlots() { return 47; }
797 @Override
798 protected int defineOffsetNumIndexes() { return 51; }
799 @Override
800 protected int defineOffsetOwnedPages() { return 55; }
801 @Override
802 protected int defineOffsetFreeSpacePages() { return 59; }
803 @Override
804 protected int defineOffsetIndexDefBlock() { return 63; }
805
806 @Override
807 protected int defineSizeIndexColumnBlock() { return 52; }
808 @Override
809 protected int defineSizeIndexInfoBlock() { return 28; }
810
811 @Override
812 protected int defineOffsetColumnType() { return 0; }
813 @Override
814 protected int defineOffsetColumnNumber() { return 5; }
815 @Override
816 protected int defineOffsetColumnPrecision() { return 11; }
817 @Override
818 protected int defineOffsetColumnScale() { return 12; }
819 @Override
820 protected int defineOffsetColumnSortOrder() { return 11; }
821 @Override
822 protected int defineOffsetColumnCodePage() { return -1; }
823 @Override
824 protected int defineOffsetColumnComplexId() { return -1; }
825 @Override
826 protected int defineOffsetColumnFlags() { return 15; }
827 @Override
828 protected int defineOffsetColumnCompressedUnicode() { return 16; }
829 @Override
830 protected int defineOffsetColumnLength() { return 23; }
831 @Override
832 protected int defineOffsetColumnVariableTableIndex() { return 7; }
833 @Override
834 protected int defineOffsetColumnFixedDataOffset() { return 21; }
835 @Override
836 protected int defineOffsetColumnFixedDataRowOffset() { return 2; }
837
838 @Override
839 protected int defineOffsetTableDefLocation() { return 4; }
840
841 @Override
842 protected int defineOffsetRowStart() { return 14; }
843 @Override
844 protected int defineOffsetUsageMapStart() { return 5; }
845
846 @Override
847 protected int defineOffsetUsageMapPageData() { return 4; }
848
849 @Override
850 protected int defineOffsetReferenceMapPageNumbers() { return 1; }
851
852 @Override
853 protected int defineOffsetFreeSpace() { return 2; }
854 @Override
855 protected int defineOffsetNumRowsOnDataPage() { return 12; }
856 @Override
857 protected int defineMaxNumRowsOnDataPage() { return 255; }
858
859 @Override
860 protected int defineOffsetIndexCompressedByteCount() { return 24; }
861 @Override
862 protected int defineOffsetIndexEntryMask() { return 27; }
863 @Override
864 protected int defineOffsetPrevIndexPage() { return 12; }
865 @Override
866 protected int defineOffsetNextIndexPage() { return 16; }
867 @Override
868 protected int defineOffsetChildTailIndexPage() { return 20; }
869
870 @Override
871 protected int defineSizeIndexDefinition() { return 12; }
872 @Override
873 protected int defineSizeColumnHeader() { return 25; }
874 @Override
875 protected int defineSizeRowLocation() { return 2; }
876 @Override
877 protected int defineSizeLongValueDef() { return 12; }
878 @Override
879 protected int defineMaxInlineLongValueSize() { return 64; }
880 @Override
881 protected int defineMaxLongValueRowSize() { return 4076; }
882 @Override
883 protected int defineMaxCompressedUnicodeSize() { return 1024; }
884 @Override
885 protected int defineSizeTdefHeader() { return 63; }
886 @Override
887 protected int defineSizeTdefTrailer() { return 2; }
888 @Override
889 protected int defineSizeColumnDefBlock() { return 25; }
890 @Override
891 protected int defineSizeIndexEntryMask() { return 453; }
892 @Override
893 protected int defineSkipBeforeIndexFlags() { return 4; }
894 @Override
895 protected int defineSkipAfterIndexFlags() { return 5; }
896 @Override
897 protected int defineSkipBeforeIndexSlot() { return 4; }
898 @Override
899 protected int defineSkipAfterIndexSlot() { return 4; }
900 @Override
901 protected int defineSkipBeforeIndex() { return 4; }
902 @Override
903 protected int defineSizeNameLength() { return 2; }
904 @Override
905 protected int defineSizeRowColumnCount() { return 2; }
906 @Override
907 protected int defineSizeRowVarColOffset() { return 2; }
908
909 @Override
910 protected int defineUsageMapTableByteLength() { return 64; }
911
912 @Override
913 protected int defineMaxColumnsPerTable() { return 255; }
914
915 @Override
916 protected int defineMaxTableNameLength() { return 64; }
917
918 @Override
919 protected int defineMaxColumnNameLength() { return 64; }
920
921 @Override
922 protected int defineMaxIndexNameLength() { return 64; }
923
924 @Override
925 protected boolean defineLegacyNumericIndexes() { return true; }
926
927 @Override
928 protected Charset defineCharset() { return Charset.forName("UTF-16LE"); }
929
930 @Override
931 protected Column.SortOrder defineDefaultSortOrder() {
932 return Column.GENERAL_LEGACY_SORT_ORDER;
933 }
934
935 @Override
936 protected Map<String,Database.FileFormat> getPossibleFileFormats()
937 {
938 return PossibleFileFormats.POSSIBLE_VERSION_4;
939 }
940
941 @Override
942 protected boolean isSupportedDataType(DataType type) {
943 return (type != DataType.COMPLEX_TYPE);
944 }
945 }
946
947 private static final class MSISAMFormat extends Jet4Format {
948 private MSISAMFormat() {
949 super("MSISAM");
950 }
951
952 @Override
953 protected CodecType defineCodecType() {
954 return CodecType.MSISAM;
955 }
956
957 @Override
958 protected Map<String,Database.FileFormat> getPossibleFileFormats()
959 {
960 return PossibleFileFormats.POSSIBLE_VERSION_MSISAM;
961 }
962 }
963
964 private static class Jet12Format extends Jet4Format {
965 private Jet12Format() {
966 super("VERSION_12");
967 }
968
969
970 private Jet12Format(String name) {
971 super(name);
972 }
973
974 @Override
975 protected CodecType defineCodecType() {
976 return CodecType.OFFICE;
977 }
978
979 @Override
980 protected boolean defineLegacyNumericIndexes() { return false; }
981
982 @Override
983 protected Map<String,Database.FileFormat> getPossibleFileFormats() {
984 return PossibleFileFormats.POSSIBLE_VERSION_12;
985 }
986
987 @Override
988 protected int defineOffsetNextComplexAutoNumber() { return 28; }
989
990 @Override
991 protected int defineOffsetColumnComplexId() { return 11; }
992
993 @Override
994 protected boolean isSupportedDataType(DataType type) {
995 return true;
996 }
997 }
998
999 private static final class Jet14Format extends Jet12Format {
1000 private Jet14Format() {
1001 super("VERSION_14");
1002 }
1003
1004 @Override
1005 protected Column.SortOrder defineDefaultSortOrder() {
1006 return Column.GENERAL_SORT_ORDER;
1007 }
1008
1009 @Override
1010 protected Map<String,Database.FileFormat> getPossibleFileFormats() {
1011 return PossibleFileFormats.POSSIBLE_VERSION_14;
1012 }
1013 }
1014
1015 }