You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

JetFormat.java 40KB

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