222 lines
5.7 KiB
C++
222 lines
5.7 KiB
C++
/*
|
|
** Command & Conquer Generals(tm)
|
|
** Copyright 2025 Electronic Arts Inc.
|
|
**
|
|
** This program is free software: you can redistribute it and/or modify
|
|
** it under the terms of the GNU General Public License as published by
|
|
** the Free Software Foundation, either version 3 of the License, or
|
|
** (at your option) any later version.
|
|
**
|
|
** This program is distributed in the hope that it will be useful,
|
|
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
** GNU General Public License for more details.
|
|
**
|
|
** You should have received a copy of the GNU General Public License
|
|
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
// //
|
|
// (c) 2001-2003 Electronic Arts Inc. //
|
|
// //
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// FILE: BitFlagsIO.h /////////////////////////////////////////////////////////////////////////////
|
|
// Author: Steven Johnson, March 2002
|
|
// Desc:
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
#pragma once
|
|
|
|
#ifndef __BitFlagsIO_H_
|
|
#define __BitFlagsIO_H_
|
|
|
|
#include "Common/BitFlags.h"
|
|
#include "Common/INI.h"
|
|
#include "Common/Xfer.h"
|
|
|
|
//-------------------------------------------------------------------------------------------------
|
|
|
|
/*
|
|
template <size_t NUMBITS>
|
|
void BitFlags<NUMBITS>::buildDescription( AsciiString* str ) const
|
|
{
|
|
if ( str == NULL )
|
|
return;//sanity
|
|
|
|
for( Int i = 0; i < size(); ++i )
|
|
{
|
|
const char* bitName = getBitNameIfSet(i);
|
|
|
|
if (bitName != NULL)
|
|
{
|
|
str->concat( bitName );
|
|
str->concat( ",\n");
|
|
}
|
|
}
|
|
}
|
|
*/
|
|
|
|
//-------------------------------------------------------------------------------------------------
|
|
template <size_t NUMBITS>
|
|
void BitFlags<NUMBITS>::parse(INI* ini, AsciiString* str)
|
|
{
|
|
// m_bits.reset();
|
|
if (str)
|
|
str->clear();
|
|
|
|
Bool foundNormal = false;
|
|
Bool foundAddOrSub = false;
|
|
|
|
// loop through all tokens
|
|
for (const char *token = ini->getNextTokenOrNull(); token != NULL; token = ini->getNextTokenOrNull())
|
|
{
|
|
if (str)
|
|
{
|
|
if (str->isNotEmpty())
|
|
str->concat(" ");
|
|
str->concat(token);
|
|
}
|
|
|
|
if (stricmp(token, "NONE") == 0)
|
|
{
|
|
if (foundNormal || foundAddOrSub)
|
|
{
|
|
DEBUG_CRASH(("you may not mix normal and +- ops in bitstring lists"));
|
|
throw INI_INVALID_NAME_LIST;
|
|
}
|
|
clear();
|
|
break;
|
|
}
|
|
|
|
if (token[0] == '+')
|
|
{
|
|
if (foundNormal)
|
|
{
|
|
DEBUG_CRASH(("you may not mix normal and +- ops in bitstring lists"));
|
|
throw INI_INVALID_NAME_LIST;
|
|
}
|
|
Int bitIndex = INI::scanIndexList(token+1, s_bitNameList); // this throws if the token is not found
|
|
set(bitIndex, 1);
|
|
foundAddOrSub = true;
|
|
}
|
|
else if (token[0] == '-')
|
|
{
|
|
if (foundNormal)
|
|
{
|
|
DEBUG_CRASH(("you may not mix normal and +- ops in bitstring lists"));
|
|
throw INI_INVALID_NAME_LIST;
|
|
}
|
|
Int bitIndex = INI::scanIndexList(token+1, s_bitNameList); // this throws if the token is not found
|
|
set(bitIndex, 0);
|
|
foundAddOrSub = true;
|
|
}
|
|
else
|
|
{
|
|
if (foundAddOrSub)
|
|
{
|
|
DEBUG_CRASH(("you may not mix normal and +- ops in bitstring lists"));
|
|
throw INI_INVALID_NAME_LIST;
|
|
}
|
|
|
|
if (!foundNormal)
|
|
clear();
|
|
|
|
Int bitIndex = INI::scanIndexList(token, s_bitNameList); // this throws if the token is not found
|
|
set(bitIndex, 1);
|
|
foundNormal = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------------------------
|
|
//-------------------------------------------------------------------------------------------------
|
|
template <size_t NUMBITS>
|
|
/*static*/ void BitFlags<NUMBITS>::parseFromINI(INI* ini, void* /*instance*/, void *store, const void* /*userData*/)
|
|
{
|
|
((BitFlags*)store)->parse(ini, NULL);
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------------------------
|
|
/** Xfer method
|
|
* Version Info:
|
|
* 1: Initial version */
|
|
//-------------------------------------------------------------------------------------------------
|
|
template <size_t NUMBITS>
|
|
void BitFlags<NUMBITS>::xfer(Xfer* xfer)
|
|
{
|
|
// this deserves a version number
|
|
XferVersion currentVersion = 1;
|
|
XferVersion version = currentVersion;
|
|
xfer->xferVersion( &version, currentVersion );
|
|
|
|
if( xfer->getXferMode() == XFER_SAVE )
|
|
{
|
|
// save how many entries are to follow
|
|
Int c = count();
|
|
xfer->xferInt( &c );
|
|
|
|
// save each of the string data
|
|
for( Int i = 0; i < size(); ++i )
|
|
{
|
|
const char* bitName = getBitNameIfSet(i);
|
|
|
|
// ignore if this kindof is not set in our mask data
|
|
if (bitName == NULL)
|
|
continue;
|
|
|
|
// this bit is set, write the string value
|
|
AsciiString bitNameA = bitName;
|
|
xfer->xferAsciiString( &bitNameA );
|
|
|
|
} // end for i
|
|
|
|
} // end if, save
|
|
else if( xfer->getXferMode() == XFER_LOAD )
|
|
{
|
|
// clear the kind of mask data
|
|
clear();
|
|
|
|
// read how many entries follow
|
|
Int c;
|
|
xfer->xferInt( &c );
|
|
|
|
// read each of the string entries
|
|
AsciiString string;
|
|
for( Int i = 0; i < c; ++i )
|
|
{
|
|
|
|
// read ascii string
|
|
xfer->xferAsciiString( &string );
|
|
|
|
// set in our mask type data
|
|
Bool valid = setBitByName( string.str() );
|
|
if (!valid)
|
|
{
|
|
DEBUG_CRASH(("invalid bit name %s",string.str()));
|
|
throw XFER_READ_ERROR;
|
|
}
|
|
|
|
} // end for, i
|
|
|
|
} // end else if, load
|
|
else if( xfer->getXferMode() == XFER_CRC )
|
|
{
|
|
|
|
// just call the xfer implementation on the data values
|
|
xfer->xferUser( this, sizeof( this ) );
|
|
|
|
} // end else if, crc
|
|
else
|
|
{
|
|
|
|
DEBUG_CRASH(( "BitFlagsXfer - Unknown xfer mode '%d'\n", xfer->getXferMode() ));
|
|
throw XFER_MODE_UNKNOWN;
|
|
|
|
} // end else
|
|
|
|
} // end xfer
|
|
|
|
#endif
|