/*=========================================================================== FILE: CoreUtilities.h DESCRIPTION: Collection of various utility methods PUBLIC CLASSES AND METHODS: StringToLONG StringToULONG StringToLONGLONG StringToULONGLONG ParseCommandLine() ParseTokens() ParseFormatSpecifier() FromString( CHAR ) FromString( UCHAR ) FromString( SHORT ) FromString( USHORT ) FromString( int ) FromString( UINT ) FromString( LONG ) FromString( ULONG ) FromString( LONGLONG ) FromString( ULONGLONG ) ToString( CHAR ) ToString( UCHAR ) ToString( SHORT ) ToString( USHORT ) ToString( int ) ToString( UINT ) ToString( LONG ) ToString( ULONG ) ToString( LONGLONG ) ToString( ULONGLONG ) GetProgramPath() EnumerateFolders() DepthSearch() ContainerToCSVString() CSVStringToContainer() CSVStringToValidatedContainer() SetDiff() SetIntersection() SetUnion() Copyright (c) 2011, Code Aurora Forum. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Code Aurora Forum nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ===========================================================================*/ //--------------------------------------------------------------------------- // Pragmas //--------------------------------------------------------------------------- #pragma once //--------------------------------------------------------------------------- // Include Files //--------------------------------------------------------------------------- #include #include //--------------------------------------------------------------------------- // Definitions //--------------------------------------------------------------------------- // Suggested size of an argument buffer to ToString() for any key, each // ToString() should not write more than this size to the passed in buffer const ULONG SUGGESTED_BUFFER_LEN = 64; /*=========================================================================*/ // Prototypes /*=========================================================================*/ // Replacement/front end for _tcstol bool StringToLONG( LPCSTR pStr, int base, LONG & val ); // Replacement/front end for _tcstoul bool StringToULONG( LPCSTR pStr, int base, ULONG & val ); // Replacement/front end for _tcstoi64 bool StringToLONGLONG( LPCSTR pStr, int base, LONGLONG & val ); // Replacement/front end for _tcstoui64 bool StringToULONGLONG( LPCSTR pStr, int base, ULONGLONG & val ); // Parse a command line to tokens (a command line is a string of // space delimited values where a value that contains space is // enclosed in text) void ParseCommandLine( std::string commandLine, std::vector & tokens ); // Parse a line into individual tokens void ParseTokens( LPCSTR pSeparator, LPSTR pLine, std::vector & tokens ); // Parse a format specifier into individual format type tokens bool ParseFormatSpecifier( LPCSTR pFmt, ULONG fmtLen, std::vector & fmtTypes ); // Convert a string to a value bool FromString( LPCSTR pStr, CHAR & theType ); // Convert a string to a value bool FromString( LPCSTR pStr, UCHAR & theType ); // Convert a string to a value bool FromString( LPCSTR pStr, SHORT & theType ); // Convert a string to a value bool FromString( LPCSTR pStr, USHORT & theType ); // Convert a string to a value bool FromString( LPCSTR pStr, int & theType ); // Convert a string to a value bool FromString( LPCSTR pStr, UINT & theType ); // Convert a string to a value bool FromString( LPCSTR pStr, LONG & theType ); // Convert a string to a value bool FromString( LPCSTR pStr, ULONG & theType ); // Convert a string to a value bool FromString( LPCSTR pStr, LONGLONG & theType ); // Convert a string to a value bool FromString( LPCSTR pStr, ULONGLONG & theType ); // Convert a value to a string bool ToString( CHAR val, LPSTR pStr ); // Convert a value to a string bool ToString( UCHAR val, LPSTR pStr ); // Convert a value to a string bool ToString( SHORT val, LPSTR pStr ); // Convert a value to a string bool ToString( USHORT val, LPSTR pStr ); // Convert a value to a string bool ToString( int val, LPSTR pStr ); // Convert a value to a string bool ToString( UINT val, LPSTR pStr ); // Convert a value to a string bool ToString( LONG val, LPSTR pStr ); // Convert a value to a string bool ToString( ULONG val, LPSTR pStr ); // Convert a value to a string bool ToString( LONGLONG val, LPSTR pStr ); // Convert a value to a string bool ToString( ULONGLONG val, LPSTR pStr ); // Return the special folder used for storing program files std::string GetProgramPath(); // Enumerate the subfolders of the given folder (recursive) void EnumerateFolders( const std::string & baseFolder, std::vector & foundFolders ); // Search for a file at a given depth void DepthSearch( const std::string & baseFolder, int depth, std::string name, std::vector & foundFiles ); /*=========================================================================*/ // Free Methods /*=========================================================================*/ /*=========================================================================== METHOD: ContainerToCSVString (Free Method) DESCRIPTION: Convert the contents of a container to a CSV string NOTE: ToString() must be defined for the container value type PARAMETERS: cont [ I ] - The container sep [ I ] - The character separating tokens csv [ O ] - The resulting comma separated string RETURN VALUE: None ===========================================================================*/ template void ContainerToCSVString( const Container & cont, CHAR sep, std::string & csv ) { csv = ""; if ((ULONG)cont.size() > (ULONG)0) { CHAR keyBuf[SUGGESTED_BUFFER_LEN]; typename Container::const_iterator pIter = cont.begin(); while (pIter != cont.end()) { const typename Container::value_type & theKey = *pIter; bool bOK = ToString( theKey, &keyBuf[0] ); if (bOK == true && keyBuf[0] != 0) { if (pIter != cont.begin()) { csv += sep; } csv += (LPCSTR)&keyBuf[0]; } pIter++; } } } /*=========================================================================== METHOD: CSVStringToContainer (Free Method) DESCRIPTION: Populate a container from a parsed CSV string NOTE: FromString() must be defined for the container value type NOTE: The container is emptied before this operation is attempted PARAMETERS: pSeparator [ I ] - The characters separating tokens pCSV [ I ] - The comma separated string (will be modified) cont [ O ] - The resulting container bClear [ I ] - Clear the container first? NOTE: if the container is not cleared first then insertions may fail for duplicate keys RETURN VALUE: None ===========================================================================*/ template void CSVStringToContainer( LPCSTR pSeparator, LPSTR pCSV, Container & cont, bool bClear = true ) { if (pCSV != 0 && *pCSV != 0) { // Remove a leading quote? if (*pCSV == '\"') { pCSV++; } // Remove a trailing quote? ULONG len = (ULONG)strlen( pCSV ); if (len > 0) { if (pCSV[len - 1] == '\"') { pCSV[len - 1] = 0; } } // Clear the container first? if (bClear == true) { cont.clear(); } std::vector tokens; ParseTokens( pSeparator, pCSV, tokens ); std::vector ::const_iterator pIter = tokens.begin(); while (pIter != tokens.end()) { LPCSTR pTok = *pIter; typename Container::value_type theKey; bool bOK = ::FromString( pTok, theKey ); if (bOK == true) { std::insert_iterator is( cont, cont.end() ); *is = theKey; } pIter++; } } } /*=========================================================================== METHOD: CSVStringToValidatedContainer (Free Method) DESCRIPTION: Populate a container from a parsed CSV string NOTE: FromString() and IsValid() must be defined for the container value type (the later need not do anything but return true) NOTE: The container is emptied before this operation is attempted PARAMETERS: pSeparator [ I ] - The characters separating tokens pCSV [ I ] - The comma separated string (will be modified) cont [ O ] - The resulting container RETURN VALUE: None ===========================================================================*/ template void CSVStringToValidatedContainer( LPCSTR pSeparator, LPSTR pCSV, Container & cont ) { cont.clear(); if (pCSV != 0 && *pCSV != 0) { // Remove a leading quote? if (*pCSV == '\"') { pCSV++; } // Remove a trailing quote? ULONG len = (ULONG)strlen( pCSV ); if (len > 0) { if (pCSV[len - 1] == '\"') { pCSV[len - 1] = 0; } } cont.clear(); std::vector tokens; ParseTokens( pSeparator, pCSV, tokens ); std::vector ::const_iterator pIter = tokens.begin(); while (pIter != tokens.end()) { LPCSTR pTok = *pIter; typename Container::value_type theKey; bool bOK = ::FromString( pTok, theKey ); if (bOK == true) { bool bValid = IsValid( theKey ); if (bValid == true) { std::insert_iterator is( cont, cont.end() ); *is = theKey; } } pIter++; } } } /*=========================================================================== METHOD: SetDiff (Free Method) DESCRIPTION: Given two sets return a third that contains everything in the first set but not the second set PARAMETERS: setA [ I ] - The first set setB [ I ] - The second set RETURN VALUE: std::set - the difference ===========================================================================*/ template std::set SetDiff( const std::set & setA, const std::set & setB ) { std::set retSet; if (setB.size() == 0) { // Everything that is in the first set but not the second // (empty) set is ... the first set! retSet = setA; } else if (setA.size() == 0) { // The first set is empty, hence the return set is empty } else { // Both sets have elements, therefore the iterators will // be valid and we can use the standard approach typename std::set ::const_iterator pIterA = setA.begin(); typename std::set ::const_iterator pIterB = setB.begin(); for ( ; pIterA != setA.end() && pIterB != setB.end(); ) { if (*pIterA < *pIterB) { retSet.insert( *pIterA ); pIterA++; } else if (*pIterB < *pIterA) { pIterB++; } else { pIterA++; pIterB++; } } while (pIterA != setA.end()) { retSet.insert( *pIterA ); pIterA++; } } return retSet; } /*=========================================================================== METHOD: SetIntersection (Free Method) DESCRIPTION: Given two sets return a third that contains everything that is in both sets PARAMETERS: setA [ I ] - The first set setB [ I ] - The second set RETURN VALUE: std::set - the union ===========================================================================*/ template std::set SetIntersection( const std::set & setA, const std::set & setB ) { std::set retSet; // Neither set can be empty if (setA.size() != 0 && setA.size() != 0) { // Both sets have elements, therefore the iterators will // be valid and we can use the standard approach typename std::set ::const_iterator pIterA = setA.begin(); typename std::set ::const_iterator pIterB = setB.begin(); for ( ; pIterA != setA.end() && pIterB != setB.end(); ) { if (*pIterA < *pIterB) { pIterA++; } else if (*pIterB < *pIterA) { pIterB++; } else { retSet.insert( *pIterA ); pIterA++; pIterB++; } } } return retSet; } /*=========================================================================== METHOD: SetUnion (Free Method) DESCRIPTION: Given two sets return a third that contains everything that is either in the first set or in the second set PARAMETERS: setA [ I ] - The first set setB [ I ] - The second set RETURN VALUE: std::set - the union ===========================================================================*/ template std::set SetUnion( const std::set & setA, const std::set & setB ) { std::set retSet; if (setB.size() == 0) { // Everything that is in the first (possibly empty) set or in // the second (empty) set is ... the first set! retSet = setA; } else if (setA.size() == 0) { // Everything that is in the first (empty) set or in the // second (possibly empty) set is ... the second set! retSet = setB; } else { // Both sets have elements, therefore the iterators will // be valid and we can use the standard approach typename std::set ::const_iterator pIterA = setA.begin(); typename std::set ::const_iterator pIterB = setB.begin(); for ( ; pIterA != setA.end() && pIterB != setB.end(); ) { if (*pIterA < *pIterB) { retSet.insert( *pIterA ); pIterA++; } else if (*pIterB < *pIterA) { retSet.insert( *pIterB ); pIterB++; } else { retSet.insert( *pIterA ); pIterA++; pIterB++; } } while (pIterA != setA.end()) { retSet.insert( *pIterA ); pIterA++; } while (pIterB != setB.end()) { retSet.insert( *pIterB ); pIterB++; } } return retSet; }