/* ** 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 . */ //////////////////////////////////////////////////////////////////////////////// // // // (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 void BitFlags::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 void BitFlags::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 /*static*/ void BitFlags::parseFromINI(INI* ini, void* /*instance*/, void *store, const void* /*userData*/) { ((BitFlags*)store)->parse(ini, NULL); } //------------------------------------------------------------------------------------------------- /** Xfer method * Version Info: * 1: Initial version */ //------------------------------------------------------------------------------------------------- template void BitFlags::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