Tn002: Persistent Object Data Format (permanent object data format)

Source: Internet
Author: User

Tn002: Persistent Object Data Format (permanent object data format)
Abstract:
This document describes the MFC program that supports permanent object storage and the format when object data is saved as a file.
1. MFC saves data in a compact binary format. Each object has only one object in the file. The serialize () function of the object provides real database storage.
2. carchive: writeobject: creates an object by writing a data header. The data header consists of two parts: object type and object state. This function is also responsible for writing an identifier to keep an object with only one copy.
3. Reading and Writing objects depend on several predefined constants, as shown in the following table:
  
Tag (identifier)
Description)
Wnulltag
Used to point to null.
Wnewclasstag
Indicates that it is followed by a new object.
Woldclasstag
Indicates that the object to be read is a read object.
Wclasstag
Class indicator
Wbigobjecttag
0x8000000 indicates a category tag
Nmaxmapcount
0x3ffffffe indicates the maximum mapcount value.
4. When the object is saved, carchive maintains a cmapptrtoptr object (m_pstoremap) that maps the object to be stored to a 32-bit identifier PID ). The PID value starts from 1 and is valid only within its scope.
5. Save the functions and related code used by the object:
Void carchive: writeobject (const cobject * POB)
{
// The object can be null.
DWORD nobindex;
// Initialize m_pstoremap
MapObject (null );
If (POB = NULL)
{
// Save the NULL pointer flag
* This <wnulltag;
}
Else if (nobindex = (DWORD) (* m_pstoremap) [(void *) POB])! = 0)
// Assumes initialized to 0 Map
{
// Save the index of the stored object
If (nobindex <wbigobjecttag)
* This <(Word) nobindex;
Else
{
* This <wbigobjecttag;
* This <nobindex;
}
}
Else
{
// Write the stored object
Cruntimeclass * pclassref = POB-> getruntimeclass ();
Writeclass (pclassref );
// Enter in stored object table, checking for Overflow
Checkcount ();
(* M_pstoremap) [(void *) POB] = (void *) m_nmapcount ++;
// Serialize the object itself
(Cobject *) POB)-> serialize (* This );
}
}
Void carchive: writeclass (const cruntimeclass * pclassref)
{
// Confirm that pstoremap has been initialized
MapObject (null); // nothing is actually done here
// Write the ID and indicator of the object and place the indicator at a high level.
// New object follows
// Assume that map is initialized to 0
DWORD nclassindex;
If (nclassindex = (DWORD) (* m_pstoremap) [(void *) pclassref])! = 0)
{
// Previusly seen class, write out the index tagged by high bit
If (nclassindex <wbigobjecttag)
* This <(Word) (wclasstag | nclassindex );
Else
{
* This <wbigobjecttag;
* This <(dwbigclasstag | nclassindex );
}
}
Else
{
// Store new objects
* This <wnewclasstag;
// Store the information required by the runtime_class object (for example, the object name)
Pclassref-> store (* This );
// Store the reference of the new object (reference) to map
Checkcount ();
(* M_pstoremap) [(void *) pclassref] = (void *) m_nmapcount ++;
}
}
6. When readobject reads an object from a file, it determines whether the PID is greater than the upper limit of the current array. If the value is greater than the upper limit, it is a new object.
7. Several versioning points and some internal code implemented by MFC.
L in implement_serial, set nschema to versionable_schema and the value obtained from the current version number or operation.
L get the version number through getobjectschema in serialize and process it accordingly.
The Code is as follows:
# Define versionable_schema (0x80000000)
Implement_serial (cmyobject, cobject, versionable_schema | 1)
Void cmyobject: serialize (carchive & AR)
{
If (AR. isloading ())
{
Int nversion = ar. getobjectschema ();
Switch (nversion)
{
Case 0:
// Read in previous version
// This object
  
Break;
Case 1:
// Read in current version
// This object
  
Break;
Default:
// Report unknown version
// This object
  
Break;
}
}
Else
{
// Normal storing code goes here
}
}
8. In some cases, you need to directly call serialize, which brings some benefits but also brings some bad points. There are four main aspects:
L can make the file body smaller and support more file formats.
L readobject, writeobject, and other things related to them will not be connected to your program unless you want to support more archiving solutions for common objects.
L more things need to be handled during anti-serialization.
L you cannot call carchive: getobjectschema or make carchive: getobjectschema return-1 to indicate the unknown version.
Directly calling serialize may cause the pointer of the parent document object to be stored in the sub-object, which requires two steps: 1. You must explicitly save a back pointer pointing to the parent document in the sub-object. 2. Call carchive: MapObject to map the cdocument to a PID before the back pointer archive.
Note: For specific internal process, refer to the "in-depth introduction to MFC" PART4-P60

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.