LCOV - code coverage report
Current view: top level - sot/source/sdstor - stgelem.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 244 253 96.4 %
Date: 2012-08-25 Functions: 25 27 92.6 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 133 218 61.0 %

           Branch data     Line data    Source code
       1                 :            : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 :            : /*
       3                 :            :  * This file is part of the LibreOffice project.
       4                 :            :  *
       5                 :            :  * This Source Code Form is subject to the terms of the Mozilla Public
       6                 :            :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7                 :            :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8                 :            :  *
       9                 :            :  * This file incorporates work covered by the following license notice:
      10                 :            :  *
      11                 :            :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12                 :            :  *   contributor license agreements. See the NOTICE file distributed
      13                 :            :  *   with this work for additional information regarding copyright
      14                 :            :  *   ownership. The ASF licenses this file to you under the Apache
      15                 :            :  *   License, Version 2.0 (the "License"); you may not use this file
      16                 :            :  *   except in compliance with the License. You may obtain a copy of
      17                 :            :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18                 :            :  */
      19                 :            : 
      20                 :            : 
      21                 :            : #include <string.h> // memset(), memcpy()
      22                 :            : #include <rtl/ustring.hxx>
      23                 :            : #include <com/sun/star/lang/Locale.hpp>
      24                 :            : #include <unotools/charclass.hxx>
      25                 :            : #include "sot/stg.hxx"
      26                 :            : #include "stgelem.hxx"
      27                 :            : #include "stgcache.hxx"
      28                 :            : #include "stgstrms.hxx"
      29                 :            : #include "stgdir.hxx"
      30                 :            : #include "stgio.hxx"
      31                 :            : 
      32                 :            : static const sal_uInt16 nMaxLegalStr = 31;
      33                 :            : 
      34                 :            : static sal_uInt8 cStgSignature[ 8 ] = { 0xD0,0xCF,0x11,0xE0,0xA1,0xB1,0x1A,0xE1 };
      35                 :            : 
      36                 :            : ////////////////////////////// struct ClsId  /////////////////////////////
      37                 :            : 
      38                 :       4994 : SvStream& operator >>( SvStream& r, ClsId& rId )
      39                 :            : {
      40                 :       4994 :     r >> rId.n1
      41                 :       4994 :       >> rId.n2
      42                 :       4994 :       >> rId.n3
      43                 :       4994 :       >> rId.n4
      44                 :       4994 :       >> rId.n5
      45                 :       4994 :       >> rId.n6
      46                 :       4994 :       >> rId.n7
      47                 :       4994 :       >> rId.n8
      48                 :       4994 :       >> rId.n9
      49                 :       4994 :       >> rId.n10
      50                 :       4994 :       >> rId.n11;
      51                 :       4994 :     return r;
      52                 :            : }
      53                 :            : 
      54                 :       1504 : SvStream& operator <<( SvStream& r, const ClsId& rId )
      55                 :            : {
      56                 :            :     return
      57                 :       1504 :        r  << (sal_Int32) rId.n1
      58                 :       1504 :           << (sal_Int16) rId.n2
      59                 :       1504 :           << (sal_Int16) rId.n3
      60                 :       1504 :           << (sal_uInt8) rId.n4
      61                 :       1504 :           << (sal_uInt8) rId.n5
      62                 :       1504 :           << (sal_uInt8) rId.n6
      63                 :       1504 :           << (sal_uInt8) rId.n7
      64                 :       1504 :           << (sal_uInt8) rId.n8
      65                 :       1504 :           << (sal_uInt8) rId.n9
      66                 :       1504 :           << (sal_uInt8) rId.n10
      67                 :       1504 :           << (sal_uInt8) rId.n11;
      68                 :            : }
      69                 :            : 
      70                 :            : ///////////////////////////// class StgHeader ////////////////////////////
      71                 :            : 
      72                 :       1998 : StgHeader::StgHeader()
      73                 :            : : nVersion( 0 )
      74                 :            : , nByteOrder( 0 )
      75                 :            : , nPageSize( 0 )
      76                 :            : , nDataPageSize( 0 )
      77                 :            : , bDirty( 0 )
      78                 :            : , nFATSize( 0 )
      79                 :            : , nTOCstrm( 0 )
      80                 :            : , nReserved( 0 )
      81                 :            : , nThreshold( 0 )
      82                 :            : , nDataFAT( 0 )
      83                 :            : , nDataFATSize( 0 )
      84                 :            : , nMasterChain( 0 )
      85                 :       1998 : , nMaster( 0 )
      86                 :            : {
      87                 :       1998 :     memset( cSignature, 0, sizeof( cSignature ) );
      88                 :       1998 :     memset( &aClsId, 0, sizeof( ClsId ) );
      89                 :       1998 :     memset( cReserved, 0, sizeof( cReserved ) );
      90                 :       1998 :     memset( nMasterFAT, 0, sizeof( nMasterFAT ) );
      91                 :       1998 : }
      92                 :            : 
      93                 :         75 : void StgHeader::Init()
      94                 :            : {
      95                 :         75 :     memcpy( cSignature, cStgSignature, 8 );
      96                 :         75 :     memset( &aClsId, 0, sizeof( ClsId ) );
      97                 :         75 :     nVersion      = 0x0003003B;
      98                 :         75 :     nByteOrder    = 0xFFFE;
      99                 :         75 :     nPageSize     = 9;          // 512 bytes
     100                 :         75 :     nDataPageSize = 6;          // 64 bytes
     101                 :         75 :     bDirty = 0;
     102                 :         75 :     memset( cReserved, 0, sizeof( cReserved ) );
     103                 :         75 :     nFATSize = 0;
     104                 :         75 :     nTOCstrm = 0;
     105                 :         75 :     nReserved = 0;
     106                 :         75 :     nThreshold    = 4096;
     107                 :         75 :     nDataFAT = 0;
     108                 :         75 :     nDataFATSize  = 0;
     109                 :         75 :     nMasterChain  = STG_EOF;
     110                 :            : 
     111                 :         75 :     SetTOCStart( STG_EOF );
     112                 :         75 :     SetDataFATStart( STG_EOF );
     113         [ +  + ]:       8250 :     for( short i = 0; i < 109; i++ )
     114                 :       8175 :         SetFATPage( i, STG_FREE );
     115                 :         75 : }
     116                 :            : 
     117                 :        300 : sal_Bool StgHeader::Load( StgIo& rIo )
     118                 :            : {
     119                 :        300 :     sal_Bool bResult = sal_False;
     120         [ +  - ]:        300 :     if ( rIo.GetStrm() )
     121                 :            :     {
     122                 :        300 :         SvStream& r = *rIo.GetStrm();
     123                 :        300 :         bResult = Load( r );
     124 [ +  - ][ +  + ]:        300 :         bResult = ( bResult && rIo.Good() );
     125                 :            :     }
     126                 :            : 
     127                 :        300 :     return bResult;
     128                 :            : }
     129                 :            : 
     130                 :       1923 : sal_Bool StgHeader::Load( SvStream& r )
     131                 :            : {
     132                 :       1923 :     r.Seek( 0L );
     133                 :       1923 :     r.Read( cSignature, 8 );
     134                 :       1923 :     r >> aClsId                     // 08 Class ID
     135                 :       1923 :       >> nVersion                   // 1A version number
     136                 :       1923 :       >> nByteOrder                 // 1C Unicode byte order indicator
     137                 :       1923 :       >> nPageSize                  // 1E 1 << nPageSize = block size
     138                 :       1923 :       >> nDataPageSize;             // 20 1 << this size == data block size
     139                 :       1923 :     r.SeekRel( 10 );
     140                 :       1923 :     r >> nFATSize                   // 2C total number of FAT pages
     141                 :       1923 :       >> nTOCstrm                   // 30 starting page for the TOC stream
     142                 :       1923 :       >> nReserved                  // 34
     143                 :       1923 :       >> nThreshold                 // 38 minimum file size for big data
     144                 :       1923 :       >> nDataFAT                   // 3C page # of 1st data FAT block
     145                 :       1923 :       >> nDataFATSize               // 40 # of data FATpages
     146                 :       1923 :       >> nMasterChain               // 44 chain to the next master block
     147                 :       1923 :       >> nMaster;                   // 48 # of additional master blocks
     148         [ +  + ]:     211530 :     for( short i = 0; i < 109; i++ )
     149                 :     209607 :         r >> nMasterFAT[ i ];
     150                 :            : 
     151 [ +  - ][ +  + ]:       1923 :     return ( r.GetErrorCode() == ERRCODE_NONE && Check() );
     152                 :            : }
     153                 :            : 
     154                 :        150 : sal_Bool StgHeader::Store( StgIo& rIo )
     155                 :            : {
     156         [ -  + ]:        150 :     if( !bDirty )
     157                 :          0 :         return sal_True;
     158                 :        150 :     SvStream& r = *rIo.GetStrm();
     159                 :        150 :     r.Seek( 0L );
     160                 :        150 :     r.Write( cSignature, 8 + 16 );
     161                 :        150 :     r << nVersion                   // 1A version number
     162                 :        150 :       << nByteOrder                 // 1C Unicode byte order indicator
     163                 :        150 :       << nPageSize                  // 1E 1 << nPageSize = block size
     164                 :        150 :       << nDataPageSize              // 20 1 << this size == data block size
     165                 :        150 :       << (sal_Int32) 0 << (sal_Int32) 0 << (sal_Int16) 0
     166                 :        150 :       << nFATSize                   // 2C total number of FAT pages
     167                 :        150 :       << nTOCstrm                   // 30 starting page for the TOC stream
     168                 :        150 :       << nReserved                  // 34
     169                 :        150 :       << nThreshold                 // 38 minimum file size for big data
     170                 :        150 :       << nDataFAT                   // 3C page # of 1st data FAT block
     171                 :        150 :       << nDataFATSize               // 40 # of data FAT pages
     172                 :        150 :       << nMasterChain               // 44 chain to the next master block
     173                 :        150 :       << nMaster;                   // 48 # of additional master blocks
     174         [ +  + ]:      16500 :     for( short i = 0; i < 109; i++ )
     175                 :      16350 :         r << nMasterFAT[ i ];
     176                 :        150 :     bDirty = !rIo.Good();
     177                 :        150 :     return sal_Bool( !bDirty );
     178                 :            : }
     179                 :            : 
     180                 :       3244 : static bool lcl_wontoverflow(short shift)
     181                 :            : {
     182 [ +  - ][ +  - ]:       3244 :     return shift >= 0 && shift < (short)sizeof(short) * 8 - 1;
     183                 :            : }
     184                 :            : 
     185                 :            : // Perform thorough checks also on unknown variables
     186                 :       2731 : sal_Bool StgHeader::Check()
     187                 :            : {
     188                 :       2731 :     return sal_Bool( memcmp( cSignature, cStgSignature, 8 ) == 0
     189                 :            :             && (short) ( nVersion >> 16 ) == 3 )
     190                 :            :             && nPageSize == 9
     191                 :       1622 :             && lcl_wontoverflow(nPageSize)
     192                 :       1622 :             && lcl_wontoverflow(nDataPageSize)
     193                 :            :             && nFATSize > 0
     194                 :            :             && nTOCstrm >= 0
     195                 :            :             && nThreshold > 0
     196                 :            :             && ( nDataFAT == -2 || ( nDataFAT >= 0 && nDataFATSize > 0 ) )
     197                 :            :             && ( nMasterChain == -2 || nMasterChain >=0 )
     198 [ +  + ][ +  - ]:       5975 :             && nMaster >= 0;
           [ +  -  +  -  
           +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  + ][ +  - ]
         [ +  - ][ -  + ]
         [ #  # ][ +  + ]
     199                 :            : }
     200                 :            : 
     201                 :      85864 : sal_Int32 StgHeader::GetFATPage( short n ) const
     202                 :            : {
     203 [ +  - ][ +  - ]:      85864 :     if( n >= 0 && n < 109 )
     204                 :      85864 :         return nMasterFAT[ n ];
     205                 :            :     else
     206                 :      85864 :         return STG_EOF;
     207                 :            : }
     208                 :            : 
     209                 :       8262 : void StgHeader::SetFATPage( short n, sal_Int32 nb )
     210                 :            : {
     211 [ +  - ][ +  - ]:       8262 :     if( n >= 0 && n < 109 )
     212                 :            :     {
     213         [ +  - ]:       8262 :         if( nMasterFAT[ n ] != nb )
     214                 :       8262 :             bDirty = sal_True, nMasterFAT[ n ] = nb;
     215                 :            :     }
     216                 :       8262 : }
     217                 :            : 
     218                 :        384 : void StgHeader::SetTOCStart( sal_Int32 n )
     219                 :            : {
     220         [ +  + ]:        384 :     if( n != nTOCstrm ) bDirty = sal_True, nTOCstrm = n;
     221                 :        384 : }
     222                 :            : 
     223                 :        225 : void StgHeader::SetDataFATStart( sal_Int32 n )
     224                 :            : {
     225         [ +  + ]:        225 :     if( n != nDataFAT ) bDirty = sal_True, nDataFAT = n;
     226                 :        225 : }
     227                 :            : 
     228                 :        150 : void StgHeader::SetDataFATSize( sal_Int32 n )
     229                 :            : {
     230         [ +  + ]:        150 :     if( n != nDataFATSize ) bDirty = sal_True, nDataFATSize = n;
     231                 :        150 : }
     232                 :            : 
     233                 :         87 : void StgHeader::SetFATSize( sal_Int32 n )
     234                 :            : {
     235         [ +  - ]:         87 :     if( n != nFATSize ) bDirty = sal_True, nFATSize = n;
     236                 :         87 : }
     237                 :            : 
     238                 :          0 : void StgHeader::SetFATChain( sal_Int32 n )
     239                 :            : {
     240         [ #  # ]:          0 :     if( n != nMasterChain )
     241                 :          0 :         bDirty = sal_True, nMasterChain = n;
     242                 :          0 : }
     243                 :            : 
     244                 :          0 : void StgHeader::SetMasters( sal_Int32 n )
     245                 :            : {
     246         [ #  # ]:          0 :     if( n != nMaster ) bDirty = sal_True, nMaster = n;
     247                 :          0 : }
     248                 :            : 
     249                 :            : ///////////////////////////// class StgEntry /////////////////////////////
     250                 :            : 
     251                 :       8490 : sal_Bool StgEntry::Init()
     252                 :            : {
     253                 :       8490 :     memset( nName, 0, sizeof( nName ) );
     254                 :       8490 :     nNameLen = 0;
     255                 :       8490 :     cType = 0;
     256                 :       8490 :     cFlags = 0;
     257                 :       8490 :     nLeft = 0;
     258                 :       8490 :     nRight = 0;
     259                 :       8490 :     nChild = 0;
     260                 :       8490 :     memset( &aClsId, 0, sizeof( aClsId ) );
     261                 :       8490 :     nFlags = 0;
     262                 :       8490 :     nMtime[0] = 0; nMtime[1] = 0;
     263                 :       8490 :     nAtime[0] = 0; nAtime[1] = 0;
     264                 :       8490 :     nPage1 = 0;
     265                 :       8490 :     nSize = 0;
     266                 :       8490 :     nUnknown = 0;
     267                 :            : 
     268                 :       8490 :     SetLeaf( STG_LEFT,  STG_FREE );
     269                 :       8490 :     SetLeaf( STG_RIGHT, STG_FREE );
     270                 :       8490 :     SetLeaf( STG_CHILD, STG_FREE );
     271                 :       8490 :     SetLeaf( STG_DATA,  STG_EOF );
     272                 :       8490 :     return sal_True;
     273                 :            : }
     274                 :            : 
     275                 :      11312 : static String ToUpperUnicode( const String & rStr )
     276                 :            : {
     277                 :            :     // I don't know the locale, so en_US is hopefully fine
     278                 :            :     /*
     279                 :            :     com.sun.star.lang.Locale aLocale;
     280                 :            :     aLocale.Language = OUString("en");
     281                 :            :     aLocale.Country  = OUString("US");
     282                 :            :     */
     283 [ +  + ][ +  - ]:      11312 :     static rtl::OUString aEN("en");
     284 [ +  + ][ +  - ]:      11312 :     static rtl::OUString aUS("US");
     285 [ +  + ][ +  - ]:      11312 :     static CharClass aCC( com::sun::star::lang::Locale( aEN, aUS, rtl::OUString() ) );
         [ +  - ][ #  # ]
     286 [ +  - ][ +  - ]:      11312 :     return aCC.uppercase( rStr );
     287                 :            : }
     288                 :            : 
     289                 :       8331 : sal_Bool StgEntry::SetName( const String& rName )
     290                 :            : {
     291                 :            :     // I don't know the locale, so en_US is hopefully fine
     292         [ +  - ]:       8331 :     aName = ToUpperUnicode( rName );
     293                 :       8331 :     aName.Erase( nMaxLegalStr );
     294                 :            : 
     295                 :            :     int i;
     296 [ +  + ][ +  - ]:      81837 :     for( i = 0; i < aName.Len() && i < 32; i++ )
                 [ +  + ]
     297                 :      73506 :         nName[ i ] = rName.GetChar( sal_uInt16( i ));
     298         [ +  + ]:     201417 :     while( i < 32 )
     299                 :     193086 :         nName[ i++ ] = 0;
     300                 :       8331 :     nNameLen = ( aName.Len() + 1 ) << 1;
     301                 :       8331 :     return sal_True;
     302                 :            : }
     303                 :            : 
     304                 :      13879 : sal_Int32 StgEntry::GetLeaf( StgEntryRef eRef ) const
     305                 :            : {
     306                 :      13879 :     sal_Int32 n = -1;
     307   [ +  +  +  +  :      13879 :     switch( eRef )
                      - ]
     308                 :            :     {
     309                 :       2981 :         case STG_LEFT:  n = nLeft;  break;
     310                 :       2981 :         case STG_RIGHT: n = nRight; break;
     311                 :       4332 :         case STG_CHILD: n = nChild; break;
     312                 :       3585 :         case STG_DATA:  n = nPage1; break;
     313                 :            :     }
     314                 :      13879 :     return n;
     315                 :            : }
     316                 :            : 
     317                 :      39752 : void StgEntry::SetLeaf( StgEntryRef eRef, sal_Int32 nPage )
     318                 :            : {
     319   [ +  +  +  +  :      39752 :     switch( eRef )
                      - ]
     320                 :            :     {
     321                 :       9655 :         case STG_LEFT:  nLeft  = nPage; break;
     322                 :       9655 :         case STG_RIGHT: nRight = nPage; break;
     323                 :       9655 :         case STG_CHILD: nChild = nPage; break;
     324                 :      10787 :         case STG_DATA:  nPage1 = nPage; break;
     325                 :            :     }
     326                 :      39752 : }
     327                 :            : 
     328                 :         82 : void StgEntry::SetClassId( const ClsId& r )
     329                 :            : {
     330                 :         82 :     memcpy( &aClsId, &r, sizeof( ClsId ) );
     331                 :         82 : }
     332                 :            : 
     333                 :       3326 : void StgEntry::GetName( String& rName ) const
     334                 :            : {
     335                 :       3326 :     sal_uInt16 n = nNameLen;
     336         [ +  + ]:       3326 :     if( n )
     337                 :       3323 :         n = ( n >> 1 ) - 1;
     338         [ +  - ]:       3326 :     rName = rtl::OUString(nName, n);
     339                 :       3326 : }
     340                 :            : 
     341                 :            : // Compare two entries. Do this case-insensitive.
     342                 :            : 
     343                 :      76750 : short StgEntry::Compare( const StgEntry& r ) const
     344                 :            : {
     345                 :            :     /*
     346                 :            :     short nRes = r.nNameLen - nNameLen;
     347                 :            :     if( !nRes ) return strcmp( r.aName, aName );
     348                 :            :     else return nRes;
     349                 :            :     */
     350                 :      76750 :     sal_Int32 nRes = r.nNameLen - nNameLen;
     351         [ +  + ]:      76750 :     if( !nRes )
     352                 :      31048 :         nRes = r.aName.CompareTo( aName );
     353                 :      76750 :     return (short)nRes;
     354                 :            :     //return aName.CompareTo( r.aName );
     355                 :            : }
     356                 :            : 
     357                 :            : // These load/store operations are a bit more complicated,
     358                 :            : // since they have to copy their contents into a packed structure.
     359                 :            : 
     360                 :       2990 : sal_Bool StgEntry::Load( const void* pFrom, sal_uInt32 nBufSize )
     361                 :            : {
     362         [ -  + ]:       2990 :     if ( nBufSize < 128 )
     363                 :          0 :         return sal_False;
     364                 :            : 
     365         [ +  - ]:       2990 :     SvMemoryStream r( (sal_Char*) pFrom, nBufSize, STREAM_READ );
     366         [ +  + ]:      98670 :     for( short i = 0; i < 32; i++ )
     367         [ +  - ]:      95680 :         r >> nName[ i ];            // 00 name as WCHAR
     368         [ +  - ]:       2990 :     r >> nNameLen                   // 40 size of name in bytes including 00H
     369         [ +  - ]:       2990 :       >> cType                      // 42 entry type
     370         [ +  - ]:       2990 :       >> cFlags                     // 43 0 or 1 (tree balance?)
     371         [ +  - ]:       2990 :       >> nLeft                      // 44 left node entry
     372         [ +  - ]:       2990 :       >> nRight                     // 48 right node entry
     373         [ +  - ]:       2990 :       >> nChild                     // 4C 1st child entry if storage
     374         [ +  - ]:       2990 :       >> aClsId                     // 50 class ID (optional)
     375         [ +  - ]:       2990 :       >> nFlags                     // 60 state flags(?)
     376         [ +  - ]:       2990 :       >> nMtime[ 0 ]                // 64 modification time
     377         [ +  - ]:       2990 :       >> nMtime[ 1 ]                // 64 modification time
     378         [ +  - ]:       2990 :       >> nAtime[ 0 ]                // 6C creation and access time
     379         [ +  - ]:       2990 :       >> nAtime[ 1 ]                // 6C creation and access time
     380         [ +  - ]:       2990 :       >> nPage1                     // 74 starting block (either direct or translated)
     381         [ +  - ]:       2990 :       >> nSize                      // 78 file size
     382         [ +  - ]:       2990 :       >> nUnknown;                  // 7C unknown
     383                 :            : 
     384                 :       2990 :     sal_uInt16 n = nNameLen;
     385         [ +  + ]:       2990 :     if( n )
     386                 :       2984 :         n = ( n >> 1 ) - 1;
     387                 :            : 
     388         [ +  + ]:       2990 :     if (n > nMaxLegalStr)
     389                 :          6 :         return sal_False;
     390                 :            : 
     391 [ +  + ][ -  + ]:       2984 :     if ((nSize < 0 && cType != STG_STORAGE) || (nPage1 < 0 && nPage1 != -2))
         [ +  + ][ -  + ]
     392                 :            :     {
     393                 :            :         // the size makes no sense for the substorage
     394                 :            :         // TODO/LATER: actually the size should be an unsigned value, but in this case it would mean a stream of more than 2Gb
     395                 :          3 :         return sal_False;
     396                 :            :     }
     397                 :            : 
     398         [ +  - ]:       2981 :     aName = rtl::OUString( nName, n );
     399                 :            :     // I don't know the locale, so en_US is hopefully fine
     400 [ +  - ][ +  - ]:       2981 :     aName = ToUpperUnicode( aName );
                 [ +  - ]
     401         [ +  - ]:       2981 :     aName.Erase( nMaxLegalStr );
     402                 :            : 
     403         [ +  - ]:       2990 :     return sal_True;
     404                 :            : }
     405                 :            : 
     406                 :       1492 : void StgEntry::Store( void* pTo )
     407                 :            : {
     408         [ +  - ]:       1492 :     SvMemoryStream r( (sal_Char *)pTo, 128, STREAM_WRITE );
     409         [ +  + ]:      49236 :     for( short i = 0; i < 32; i++ )
     410         [ +  - ]:      47744 :         r << nName[ i ];            // 00 name as WCHAR
     411         [ +  - ]:       1492 :     r << nNameLen                   // 40 size of name in bytes including 00H
     412         [ +  - ]:       1492 :       << cType                      // 42 entry type
     413         [ +  - ]:       1492 :       << cFlags                     // 43 0 or 1 (tree balance?)
     414         [ +  - ]:       1492 :       << nLeft                      // 44 left node entry
     415         [ +  - ]:       1492 :       << nRight                     // 48 right node entry
     416         [ +  - ]:       1492 :       << nChild                     // 4C 1st child entry if storage;
     417         [ +  - ]:       1492 :       << aClsId                     // 50 class ID (optional)
     418         [ +  - ]:       1492 :       << nFlags                     // 60 state flags(?)
     419         [ +  - ]:       1492 :       << nMtime[ 0 ]                // 64 modification time
     420         [ +  - ]:       1492 :       << nMtime[ 1 ]                // 64 modification time
     421         [ +  - ]:       1492 :       << nAtime[ 0 ]                // 6C creation and access time
     422         [ +  - ]:       1492 :       << nAtime[ 1 ]                // 6C creation and access time
     423         [ +  - ]:       1492 :       << nPage1                     // 74 starting block (either direct or translated)
     424         [ +  - ]:       1492 :       << nSize                      // 78 file size
     425 [ +  - ][ +  - ]:       1492 :       << nUnknown;                  // 7C unknown
     426                 :       1492 : }
     427                 :            : 
     428                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10