NOTE: This page has been translated automatically from Russian to English. Original page.



Brief description of the file format * .1CD (1Sv8 file database)

After I posted my program from Tool_1CD ( http://infostart.ru/projects/3851/ ), it turned out that the interest to the format of the file is large enough 1CD. Therefore, for those who want to continue to deal with the format, or wanting to write a program, spread your current knowledge about this format.

Excuses.

This description does not claim to completeness, correctness and clarity.

Start.

format description is given in terms of the language C. The size of a char - 1 byte size type short int - 2 bytes, the size of an int and an unsigned int - 4 bytes. 0x prefix stands for hexadecimal numbers.

Database files * .1CD consist of blocks of 4096 bytes (0x1000). Accordingly, the length of the file is always a multiple of 4096.

Block 0.

Zero block has the following structure:

struct {

char sig [8]; // Signature "1CDBMSV8"

char ver1;

char ver2;

char ver3;

char ver4;

unsigned int length;

int unknown;

}

The first 8 bytes - signature database «1CDBMSV8».

The following 4 bytes - this version of the database. At the moment, I have met only version «8.0.5.0» (ver1 = 8, ver2 = 0, ver3 = 5, ver4 = 0) - is 1Cv8.0 base and the version «8.1.0.0» (ver1 = 8, ver2 = 1 , ver3 = 0, ver4 = 0) - a comprehensive and 1Cv8.1 1Cv8.2.

The following 4 bytes - base (file) length in blocks.

Purpose unknown unknown field always contains 1.

Objects.

All other information in the database is stored in objects (database files). Each object consists of one or more blocks. Each object has a header block, blocks allocation table, and the data itself. The second and third may be missing.

The structure of the first block of each item is as follows:

struct {

char sig [8]; // Signature "1CDBOBV8"

int length; // Length of the contents of the object

int version1;

int version2;

unsigned int version;

unsigned int blocks [1018];

}

The first 8 bytes - signature database «1CDBOBV8».

There are 2 types of objects.

Block 1. Table of free blocks.

The first type of object - a table of free blocks. A sign of this block is the field version of 0. Such an object in the database is always the same, and it is always a header block in the block offset 1 (ie 0x1000 address). The data length of the object is equal to (length * 4) bytes.

The blocks contain block numbers, which actually contains the contents of the table of free blocks. Significant are non-zero values ​​in the array blocks. The contents of the table of free blocks - it's just an array of numbers of free blocks:

unsigned int free_blocks [length];

Thus, the database contains a free block length exactly.

When the system a new block of data is required, it takes the last free block of solid free_blocks and reduces length by 1. If there is no free blocks, it is created in the end of the database file. The blocks contained in the blocks The array, are not free and belong to an object - the table of free blocks. The blocks may contain more units than necessary free_blocks storage array.

The remaining objects.

The second type of objects is characterized by a non-zero value of the field version. All information in the database, except for block 0 and the table of free blocks is stored in such facilities.

The length field contains the length in bytes of the data object.

The array index blocks are blocks containing data allocation table object. Each block is specified in the blocks The, and being part of the allocation table has the following structure:

struct {

int numblocks;

unsigned int datablocks [1023];

}

numblocks field indicates the number of actual values ​​in the datablocks (1 to 1023). In datablocks contain index blocks, which is the actual contents of the object (data). Since in the same block allocation table can be given a maximum of 1023 data unit, accordingly, the maximum length of the data specified in the same block allocation table is 1023 * 4096 = 4,190,208 bytes (0x3ff * 0x1000 = 0x3ff000). Thus, the length of the length of the contents of the object, we can determine the number of actual values ​​in the blocks. If the length is equal to 0, then no blocks of significant data, otherwise the number of blocks is equal in value (length - 1) / 0x3ff000 + 1 (integer division without remainder). And you can also calculate the maximum length of the data of one object: 4190208 * 1018 = 4,265,631,744 bytes (1018 - maximum number of values ​​in the array blocks), it is quite a bit smaller than 4 gigabytes.

Again, in the header section of the object is an array of blocks The, containing blocks indexes to accommodate the table. And there are blocks containing the data itself in the allocation table.

Block 2. The root object.

The last object to a predetermined location is the root object. The header chunk of the root object is located in the block with an index of 2. All other database objects can be obtained through the root object. The structure of this data object depends from the base version, although slightly different. this structure for version «8.0.5.0» database looks like this:

struct {

char lang [8];

int numblocks;

int tableblocks [numblocks];

}

For version «8.1.0.0» structure looks like this:

struct {

char lang [32];

int numblocks;

int tableblocks [numblocks];

}

Those. These structures differ only lang field length. In the lang contains the code base language. base language code is a string in ANSI-encoded. I have met only with base «ru_RU» codes and «en». What do these language codes, I do not know, perhaps on the order of rows Sorting in constructing the index.

In numblocks field contains a number of elements in the array tableblocks. The array also contains the codes tableblocks objects containing all data tables. Those. tables in the database exactly numblocks.

The object of the table.

Each object of the table specified in the root site contains a text description of the table to Unicode. Here is an example of the table definition:

{ "_Reference4", 0,

{ "Fields",

{ "_IDRREF", "B" , 0,16,0, "CS"},

{ "_VERSION", "RV" , 0,0,0, "CS"},

{ "_MARKED", "L" , 0,0,0, "CS"},

{ "_ISMETADATA", "L" , 0,0,0, "CS"},

{ "_CODE", "NC" , 0,9,0, "CI"},

{ "_DESCRIPTION", "NVC" , 0,25,0, "CI"},

{ "_FLD7", "I" , 1,0,0, "CS"}

}

{ "Indexes",

{ "_IDRREFIDX", 1

{ "_IDRREF", 16}

}

{ "_REFERENCE4_CODE_SR", 0,

{ "_CODE", 9},

{ "_IDRREF", 16}

}

{ "_REFERENCE4_DESCR_SR", 0,

{ "_DESCRIPTION", 25}

{ "_IDRREF", 16}

}

}

{ "Recordlock", "0"},

{ "Files", 118,119,96}

}

As can be seen from this example, here present a table name (_Reference4), field descriptions section of the table (Fields), the index description section (Indexes), setting Recordlock and Section Files.

Under Files always it contains three numbers, which contain codes for header block objects (in order) with the records of the table, Blob-data (strings of unlimited length, and binary data) and indexes. If an object in the table is not present, then the corresponding number is zero.

In the Fields section contains descriptions of the fields of the table. A description of each field contains (in order): name of the field (FieldName), field type (FieldType), a sign of the use of NULL (NullExists), length (FieldLength), accuracy (FieldPrecision) and feature case-sensitive (FieldCaseSensitive).

How many bytes are in each field of recording, and how to interpret the parameters depends on the field. Firstly, if at NullExists field is 1, the first byte of the field is an indication NULL. Value 0 of this byte means that the field does not contain a value (ie, contains NULL). Otherwise, the field contains a value. If NullExists is 0, then this byte in the field there.

Further, the size and format of the field depends on the field type. field types are these:

  • «B» - binary data. Length of the field is FieldLength bytes.
  • «L» - Boolean. Length of the field 1 byte. A value of zero bytes is False, otherwise the truth.
  • «N» - number. Field length in bytes is equal to Int ((FieldLength + 2) / 2). Numbers are stored in binary coded decimal form. The first nibble is the number sign. 0 - the number is negative, 1 - positive. Every next nibble corresponds to one decimal digit. Total FieldLength digits. The decimal point is in the right FieldPrecision figures. For example, FieldLength = 5, FieldPrecision = 3. Bytes 0x18, 0x47, 0x23 represent the number of 84,723, and the bytes 0x00, 0x00, 0x91 represent the number of -0,091.
  • «NC» - a fixed-length string. Length of the field is FieldLength * 2 bytes. It is a string in Unicode format (each character takes 2 bytes).
  • «NVC» - variable-length string. Length of the field is FieldLength * 2 + 2 bytes. The first 2 bytes contain the length of the string (maximum FieldLength). The remaining bytes is the string in Unicode format (each character takes 2 bytes).
  • «RV» - version. The field length of 16 bytes. Presumably it includes four numbers int.
  • «NT» - a string of unlimited length. The field length of 8 bytes. The first four bytes contain the initial block of the index in the object Blob table, the second four - length of the data in the object Blob. The Blob object contains the string in Unicode format.
  • «I» - unlimited length binary data. The field length of 8 bytes. The first four bytes contain the initial block of the index in the object Blob table, the second four - length of the data in the object Blob.
  • «DT» - date-time. field length 7 bytes. It contains data in BCD form. The first 2 bytes contain the four-digit year, the third byte - two-digit month, the fourth byte - day, five - hours, six - and seven minutes - seconds, all as 2 digits.

Knowing now the length in bytes of each field can calculate the total length of a table entry and the offset of each field in the record. But for this it is necessary to consider the following. If the description field of the table there is no field of type version (RV), but Recordlock parameter is 1, the extra field is present in the record, which I myself call for short concealed version. The length of this field is 8 bytes. Each entry is the first byte - a sign of the distance recording (a sign that the entry is not busy). If the byte is 1, then the entry is empty, and the next four bytes contain the index of the next free record. From this it follows that the recording can not be shorter than five bytes. If the first byte of the record contains a 0, followed later in the recording field values. Moreover, the field order is determined as follows: Preview is always the version field (or described in the Fields section of the type of RV or hidden field short version), then all other fields in the same order as they are described in the Fields section.

The object table records.

The content of the records of the table contains a record array. Thus, the length of the object data is always a multiple of the length of one recording. The first (or rather zero) entry is always marked as free, it contains the index of the next free entry (or 0 if there are none). Those. It starts with a chain of free records in the table.

Blob object table.

The object contains the Blob-table data (rows of unlimited length and binary data of unlimited length). The contents of this object consists of blocks (not to be confused with blocks that make up the file 1CD) 256 bytes (0x100). Those. it is simply an array of 256 blocks each of length. Therefore, an object data length is always a multiple of 256. The structure of each object unit is as follows:

struct {

unsigned int nextblock;

short int length;

char [250] data;

}

nextblock field contains the index of the next block containing data continued, or 0 if no next block. Field length has a data length of this block (up to 250). data field contains the data itself. Zero block is always considered to be free, in the nextblock it contains the index of the next free block. Thus, the chain of free blocks starting from the zero block.

The table entries in the type fields «NT» and «I» index of the first block contains from which starts the data relating to this field of the record.

The index table.

At the moment, the structure of the index is not fully understood.

...

Gratefully accept any updates, additions, error messages, as well as any other information on the topic.

1C:Enterprise Developer's Community