BVB Source Codes

CRYENGINE Show XMLCPB_Common.h Source code

Return Download CRYENGINE: download XMLCPB_Common.h Source code - Download CRYENGINE Source code - Type:.h
  1. // Copyright 2001-2016 Crytek GmbH / Crytek Group. All rights reserved.
  2.  
  3. /*************************************************************************
  4. *************************************************************************/
  5.  
  6. // ---- basic generic info about the XMLCPB system ----
  7.  
  8. // XMLCPB -> XML ComPressed Binary
  9. // The XMLCPB system is used as a substitute for standard XML when intermediate memory usage and final size are a problem. It is also easily streamable at writting time.
  10. // However its not a true generic XML format, there are many limitations. Basically:
  11. //   - There are some hardcoded size limits: (numbers may change, check the defines in code for the actual value)
  12. //     max amount of different tags(1024), different attr names(1024), different data strings(64k), simultaneously active read(64) or write(256) nodes, num children on a node (16383), num of attrs on a node (255), and some others.
  13. //   - read and write are separated. Can generate an XMLCPB or can read from a generated XMLCPB, but can not do both at once. Also, can not append to or modify an already finished XMLCPB.
  14. //   - the writting process is specially constrained: can not add childs or attrs to a node after it is "done" (which happens as soon as another node of the same parent is created ).
  15. //   - the reading process is not as limited. But extremely random access can cause performance issues.
  16.  
  17. // in general, XMLCPB is tailored towards sequentially or near sequentially generation and reading of the data, like what happens in the savegame/loadgame processes (its main use and original purpose).
  18.  
  19. #pragma once
  20. #ifndef XMLCPB_COMMON_H
  21.         #define XMLCPB_COMMON_H
  22.  
  23. //#define XMLCPB_COLLECT_STATS  // remove comment for some manual profiling
  24.  
  25.         #ifndef _RELEASE
  26.                 #define XMLCPB_CHECK_HARDCODED_LIMITS // comment out this define for accurate performance profiling in profile build (it adds many runtime checks)
  27.         #endif
  28.  
  29.         #if CRY_PLATFORM_WINDOWS // consoles dont need it because they already have a built-in integrity check. Also, in the way it is implemented atm, it could have a noticeable performance hit on consoles.
  30.                 #define XMLCPB_CHECK_FILE_INTEGRITY
  31.         #endif
  32.  
  33.         #ifndef _RELEASE
  34.                 #define XMLCPB_DEBUGUTILS
  35.         #endif
  36.  
  37. namespace XMLCPB {
  38.  
  39. typedef uint32 AttrSetID; // an "AttrSet" defines the datatype + tagId of all the attributes of a node.
  40. typedef uint32 StringID;
  41. typedef uint32 NodeLiveID;
  42. typedef uint32 NodeGlobalID; // identifies each "real" node, as opposed to "live" nodes. The actual value is just the index of the node in the buffer that stores all of them
  43. typedef uint32 FlatAddr;     // is just a 32 bits offset into data buffer.
  44. typedef uint16 FlatAddr16;   // is just a 16 bits offset into data buffer.
  45.  
  46. static uint32 const XMLCPB_INVALID_ID = 0xffffffff;
  47. static uint32 const XMLCPB_ROOTNODE_ID = 0;
  48. static uint32 const XMLCPB_INVALID_FLATADDR = 0xffffffff;
  49. static uint32 const XMLCPB_INVALID_SAFECHECK_ID = 0xffffffff;
  50. static uint32 const XMLCPB_ZLIB_BUFFER_SIZE = 32 * 1024;        // size for the buffer used in the zlib compression
  51.  
  52. //////////////////////////////////////////////////////////////////////////
  53. struct SFileHeader
  54. {
  55.         static const uint FILETYPECHECK = 'PBX0';
  56.  
  57.         SFileHeader()
  58.         {
  59.                 memset(this, 0, sizeof(*this));
  60.                 m_fileTypeCheck = FILETYPECHECK;
  61.         }
  62.  
  63.         struct SStringTable
  64.         {
  65.                 uint32 m_numStrings;
  66.                 uint32 m_sizeStringData;
  67.         };
  68.  
  69.         uint32 m_fileTypeCheck;
  70.  
  71.         #ifdef XMLCPB_CHECK_FILE_INTEGRITY
  72.         enum { MD5_SIGNATURE_SIZE = 16 };
  73.         char m_MD5Signature[MD5_SIGNATURE_SIZE];  // it uses the MD5 algorithm for the integrity check.
  74.         #endif
  75.  
  76.         SStringTable m_tags;
  77.         SStringTable m_attrNames;
  78.         SStringTable m_strData;
  79.  
  80.         uint32       m_numAttrSets;
  81.         uint32       m_sizeAttrSets;
  82.  
  83.         uint32       m_sizeNodes;
  84.         uint32       m_numNodes;
  85.  
  86.         bool         m_hasInternalError;
  87. };
  88.  
  89. // saved in the file before every compressed block
  90. struct SZLibBlockHeader
  91. {
  92.         enum { NO_ZLIB_USED = 0xffffffff };
  93.         uint32 m_compressedSize;  // when it is = NO_ZLIB_USED, the data is raw, without zlib compression (this should happen only very rarely)
  94.         uint32 m_uncompressedSize;
  95. };
  96.  
  97. //////////////////////////////////////////////////////////////////////////
  98.  
  99. enum eAttrDataType
  100. {
  101.         //...basic types......
  102.         DT_STR,
  103.         DT_INT32,
  104.         DT_F1,
  105.         DT_F3,   // Vec2 is not used at all, so removed it and will just store as F3 in case it is ever used
  106.         DT_F4,
  107.         DT_INT64,
  108.         DT_RAWDATA,
  109.  
  110.         DT_NUM_BASIC_TYPES,
  111.  
  112.         //....compressed types...
  113.         DT_POS16 = DT_NUM_BASIC_TYPES,   // the next type after DT_NUM_BASIC_TYPES need to be assigned like this to keep the correct enumeration
  114.         DT_NEG16,
  115.         DT_POS8,
  116.         DT_NEG8,
  117.         DT_F1_1DEC,         // stored as an small integer
  118.  
  119.         // float semi constant formats. explained in CAttrWriter::PackFloatInSemiConstType()
  120.         DT_F3_1CONST,       // 1 const, 2 float vals
  121.         DT_F3_2CONST,       // 2 const, 1 float vals
  122.         DT_F3_3CONST,       // 3 const, 0 float vals
  123.         DT_F4_1CONST,       // etc
  124.         DT_F4_2CONST,
  125.         DT_F4_3CONST,
  126.         DT_F4_4CONST,
  127.  
  128.         //........numeric constants......
  129.         DT_0,
  130.         DT_1,
  131.         DT_2,
  132.         DT_3,
  133.         DT_4,
  134.         DT_5,
  135.         DT_6,
  136.         DT_7,
  137.         DT_8,
  138.         DT_9,
  139.         DT_10,
  140.  
  141.         DT_255,
  142.  
  143.         // f3 specific constants.....
  144.         DT_F3_100,
  145.         DT_F3_010,
  146.         DT_F3_001,
  147.  
  148.         //........string constants............
  149.         DT_FIRST_CONST_STR,
  150.         DT_NUM_CONST_STR  = 30, // how many string constants there are defined. it has to be the same number than the size of s_constStrings
  151.         DT_LAST_CONST_STR = DT_FIRST_CONST_STR + DT_NUM_CONST_STR - 1,
  152.  
  153.         DT_NUMTYPES,
  154.         DT_INVALID = 0xffffffff
  155. };
  156.  
  157. struct STypeInfo
  158. {
  159.         eAttrDataType type; // used only to check that the array is correctly defined
  160.         uint32        size;
  161.         eAttrDataType basicType;
  162.         const char*   pName; // used only for profiling / debuging / error visualization
  163. };
  164.  
  165. eAttrDataType                 GetBasicDataType(eAttrDataType type);
  166. uint32                        GetDataTypeSize(eAttrDataType type);
  167. const char*                   GetDataTypeName(eAttrDataType type);
  168. void                          InitializeDataTypeInfo();
  169. const char*                   GetConstantString(uint32 ind);
  170. inline bool                   IsTypeStrConstant(eAttrDataType type)   { return type >= DT_FIRST_CONST_STR && type <= DT_LAST_CONST_STR; }
  171. inline StringID               GetStringConstantID(eAttrDataType type) { assert(IsTypeStrConstant(type)); return type - DT_FIRST_CONST_STR; }
  172. template<class T> inline bool IsFlagActive(T val, uint32 flag)
  173. {
  174.         return (val & flag) != 0;
  175. }
  176.  
  177. enum eNodeConstants
  178. {
  179.         // CNodeLiveWriter::Compact() has an easier to understand description of the data that all those mad constants do define
  180.  
  181.         // node header composition
  182.         FLN_HASATTRS                           = BIT(15),
  183.         FLN_CHILDREN_ARE_RIGHT_BEFORE          = BIT(14),
  184.         LOWEST_BIT_USED_AS_FLAG_IN_NODE_HEADER = 14,
  185.         CHILDREN_HEADER_BITS                   = 2,
  186.         CHILDREN_HEADER_BIT_POSITION           = 12,
  187.         HIGHPART_ATTRID_NUM_BITS               = 2,
  188.         HIGHPART_ATTRID_BIT_POSITION           = 10,
  189.         BITS_TAGID                             = 10,
  190.  
  191.         // the AttrSetId is stored, when possible, as a 8 bit value + some extra bits (2 atm) that are in the header of the node. When not possible, it is stored as a 16bits value.
  192.         HIGHPART_ATTRID_MASK   = ((BIT(HIGHPART_ATTRID_NUM_BITS) - 1) << HIGHPART_ATTRID_BIT_POSITION),
  193.         ATRID_USING_16_BITS    = BIT(8 + HIGHPART_ATTRID_NUM_BITS) - 1, // when the value stored in the 8 bits+highbits is this, it meants that the actual value is stored separately in 16 bits
  194.         ATTRID_MAX_VALUE_8BITS = BIT(8 + HIGHPART_ATTRID_NUM_BITS) - 2, // -2 instead -1 because the actual max number is used to mark when the value cant be stored in the 8 bits + high bits (ATRID_USING_16_BITS)
  195.  
  196.         // constants for the "number of children" value stored in the header
  197.         CHILDREN_HEADER_MASK    = ((BIT(CHILDREN_HEADER_BITS) - 1) << CHILDREN_HEADER_BIT_POSITION),
  198.         CHILDREN_HEADER_CANTFIT = BIT(CHILDREN_HEADER_BITS) - 1,  // when the children number cant fit in the header, the header part gets this value
  199.         CHILDREN_HEADER_MAXNUM  = BIT(CHILDREN_HEADER_BITS) - 2,
  200.  
  201.         // constants for the "number of children" value stored outside the header (used when the header is not enough)
  202.         FL_CHILDREN_NUMBER_IS_16BITS                 = BIT(7),      // flag to mark when the number of children is stored in 16 bits
  203.         FL_CHILDREN_NUMBER_AND_BLOCKDIST_IN_ONE_BYTE = BIT(6),      // flag to mark when the number of children and the distance to them will both be stored in the children byte
  204.         MAX_NUMBER_OF_CHILDREN_IN_8BITS              = BIT(6) - 1,  // need to leave room for the flags
  205.         MAX_NUMBER_OF_CHILDREN_IN_16BITS             = BIT(14) - 1, // still need to leave room for the flags
  206.  
  207.         // some constants for when is possible to store both the distance to the children and the number of children in the single byte
  208.         CHILDANDDISTINONEBYTE_CHILD_BITS          = 3,
  209.         CHILDANDDISTINONEBYTE_DIST_BITS           = (6 - CHILDANDDISTINONEBYTE_CHILD_BITS), // need to leave room for the 2 flags
  210.         CHILDANDDISTINONEBYTE_MAX_AMOUNT_CHILDREN = BIT(CHILDANDDISTINONEBYTE_CHILD_BITS) - 1,
  211.         CHILDANDDISTINONEBYTE_MAX_DIST            = BIT(CHILDANDDISTINONEBYTE_DIST_BITS) - 1,
  212.  
  213.         // constants for child blocks
  214.         CHILDREN_PER_BLOCK                = 64,
  215.         CHILDBLOCKS_USING_MORE_THAN_8BITS = BIT(7),
  216.         CHILDBLOCKS_USING_24BITS          = CHILDBLOCKS_USING_MORE_THAN_8BITS | BIT(6), // only matters when CHILDBLOCKS_USING_MORE_THAN_8BITS is already true
  217.         CHILDBLOCKS_MAX_DIST_FOR_8BITS    = BIT(7) - 1,
  218.         CHILDBLOCKS_MASK_TO_REMOVE_FLAGS  = BIT(6) - 1,
  219.         CHILDBLOCKS_MAX_DIST_FOR_16BITS   = BIT(6) - 1,
  220.  
  221.         // tag work values derived from BITS definitions
  222.         MAX_TAGID    = BIT(BITS_TAGID) - 1,
  223.         MASK_TAGID   = MAX_TAGID,
  224.         MAX_NUM_TAGS = MAX_TAGID + 1,
  225. };
  226.  
  227. enum eAttrConstants
  228. {
  229.         MAX_NUM_ATTRS  = 255,
  230.  
  231.         BITS_TYPEID    = 6,    // bits used for the Data Type ID on each attr
  232.         BITS_NAMEID    = 10,   // for the strID that defines the name of each attr
  233.         BITS_STRDATAID = 16,   // for the strID of the data on each attr that is of "string" type.
  234.  
  235.         // work values derived from BITS definitions
  236.         MAX_TYPEID                = BIT(BITS_TYPEID) - 1,
  237.         MAX_NUM_TYPES             = MAX_TYPEID + 1,
  238.         MASK_TYPEID               = MAX_TYPEID,
  239.  
  240.         MAX_NAMEID                = BIT(BITS_NAMEID) - 1,
  241.         MAX_NUM_NAMES             = MAX_NAMEID + 1,
  242.  
  243.         MAX_NUM_STRDATA           = BIT(BITS_STRDATAID),
  244.         MAX_STRDATAID             = MAX_NUM_STRDATA - 1,
  245.         VARIABLE_DATA_SIZE        = 0xffffffff,
  246.  
  247.         MAX_SIZE_FOR_A_DATASTRING = 1024,
  248.  
  249.         // for the 2-bits values in the bytemask, for float packed semiconstant types
  250.         PFSC_0   = 0, // when is 0
  251.         PFSC_1   = 1, // when is 1
  252.         PFSC_N1  = 2, // when is -1
  253.         PFSC_VAL = 3, // when is no constant
  254. };
  255.  
  256. // the only reason for all the swappings is because zlib is more efficient when trying to compress some values in PC format (little endian) than in console format. Yea, rly.
  257.         #if 1
  258.  
  259. // Ian[24:11:10] Since zlib compression now happens on a parallel thread time is not so important so I'll crank up the compression rate to compensate
  260.                 #define SwapIntegerValue(val)
  261.  
  262.         #else
  263.  
  264. template<class T>
  265. inline void SwapIntegerValue(T& val)
  266. {
  267.                 #if defined(NEED_ENDIAN_SWAP)
  268.         SwapEndianBase(&val, 1);
  269.                 #endif
  270. }
  271.  
  272. template<>
  273. inline void SwapIntegerValue(FlatAddr& _val)
  274. {
  275.                 #if defined(NEED_ENDIAN_SWAP)
  276.         uint32 val = _val;
  277.         SwapEndianBase(&val, 1);
  278.         _val = val;
  279.                 #endif
  280. }
  281.  
  282.         #endif
  283.  
  284. } // end namespace
  285.  
  286. #endif
  287.  
downloadXMLCPB_Common.h Source code - Download CRYENGINE Source code
Related Source Codes/Software:
postal - 2017-06-11
reactide - Reactide is the first dedicated IDE for React web ... 2017-06-11
rkt - rkt is a pod-native container engine for Linux. It... 2017-06-11
uWebSockets - Tiny WebSockets https://for... 2017-06-11
realworld - TodoMVC for the RealWorld - Exemplary fullstack Me... 2017-06-11
CRYENGINE - CRYENGINE is a powerful real-time game development... 2017-06-11
goreplay - GoReplay is an open-source tool for capturing and ... 2017-06-10
pyenv - Simple Python version management 2017-06-10
redux-saga - An alternative side effect model for Redux apps ... 2017-06-10
angular-starter - 2017-06-10

 Back to top