| /*=========================================================================== |
| 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 <vector> |
| #include <set> |
| |
| //--------------------------------------------------------------------------- |
| // 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 <std::string> & tokens ); |
| |
| // Parse a line into individual tokens |
| void ParseTokens( |
| LPCSTR pSeparator, |
| LPSTR pLine, |
| std::vector <LPSTR> & tokens ); |
| |
| // Parse a format specifier into individual format type tokens |
| bool ParseFormatSpecifier( |
| LPCSTR pFmt, |
| ULONG fmtLen, |
| std::vector <CHAR> & 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 <std::string> & foundFolders ); |
| |
| // Search for a file at a given depth |
| void DepthSearch( |
| const std::string & baseFolder, |
| int depth, |
| std::string name, |
| std::vector <std::string> & 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 <class Container> |
| 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 <class Container> |
| 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 <LPSTR> tokens; |
| ParseTokens( pSeparator, pCSV, tokens ); |
| |
| std::vector <LPSTR>::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 <Container> 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 <class Container> |
| 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 <LPSTR> tokens; |
| ParseTokens( pSeparator, pCSV, tokens ); |
| |
| std::vector <LPSTR>::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 <Container> 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 <T> - the difference |
| ===========================================================================*/ |
| template <class T> |
| std::set <T> SetDiff( |
| const std::set <T> & setA, |
| const std::set <T> & setB ) |
| { |
| std::set <T> 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 <T>::const_iterator pIterA = setA.begin(); |
| typename std::set <T>::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 <T> - the union |
| ===========================================================================*/ |
| template <class T> |
| std::set <T> SetIntersection( |
| const std::set <T> & setA, |
| const std::set <T> & setB ) |
| { |
| std::set <T> 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 <T>::const_iterator pIterA = setA.begin(); |
| typename std::set <T>::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 <T> - the union |
| ===========================================================================*/ |
| template <class T> |
| std::set <T> SetUnion( |
| const std::set <T> & setA, |
| const std::set <T> & setB ) |
| { |
| std::set <T> 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 <T>::const_iterator pIterA = setA.begin(); |
| typename std::set <T>::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; |
| } |