| /*=========================================================================== |
| FILE: |
| CoreUtilities.cpp |
| |
| DESCRIPTION: |
| Collection of various utility methods |
| |
| PUBLIC CLASSES AND METHODS: |
| StringToLONG |
| StringToULONG |
| StringToLONGLONG |
| StringToULONGLONG |
| |
| ParseTokens() |
| ParseCommandLine() |
| 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 ) |
| |
| ContainerToCSVString() |
| CSVStringToContainer() |
| CSVStringToValidatedContainer() |
| |
| SetDiff() |
| SetIntersection() |
| SetUnion() |
| |
| GetProgramPath() |
| IsFolder() |
| EnumerateFolders() |
| IsHidden() |
| DepthSearch() |
| |
| 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. |
| ===========================================================================*/ |
| |
| //--------------------------------------------------------------------------- |
| // Include Files |
| //--------------------------------------------------------------------------- |
| #include "StdAfx.h" |
| #include "CoreUtilities.h" |
| |
| #include <climits> |
| |
| //--------------------------------------------------------------------------- |
| // Definitions |
| //--------------------------------------------------------------------------- |
| |
| // Format specifier states |
| enum eFormatState |
| { |
| eFMT_STATE_NORMAL, // [0] Normal state; outputting literal characters |
| eFMT_STATE_PERCENT, // [1] Just read '%' |
| eFMT_STATE_FLAG, // [2] Just read flag character |
| eFMT_STATE_WIDTH, // [3] Just read width specifier |
| eFMT_STATE_DOT, // [4] Just read '.' |
| eFMT_STATE_PRECIS, // [5] Just read precision specifier |
| eFMT_STATE_SIZE, // [6] Just read size specifier |
| eFMT_STATE_TYPE, // [7] Just read type specifier |
| eFMT_STATE_INVALID, // [8] Invalid format |
| |
| eFMT_STATES // [9] Number of format states |
| }; |
| |
| // Format specifier character classes |
| enum eFormatCharClass |
| { |
| eFMT_CH_CLASS_OTHER, // [0] Character with no special meaning |
| eFMT_CH_CLASS_PERCENT, // [1] '%' |
| eFMT_CH_CLASS_DOT, // [2] '.' |
| eFMT_CH_CLASS_STAR, // [3] '*' |
| eFMT_CH_CLASS_ZERO, // [4] '0' |
| eFMT_CH_CLASS_DIGIT, // [5] '1'..'9' |
| eFMT_CH_CLASS_FLAG, // [6] ' ', '+', '-', '#' |
| eFMT_CH_CLASS_SIZE, // [7] 'h', 'l', 'L', 'N', 'F', 'w' |
| eFMT_CH_CLASS_TYPE // [8] Type specifying character |
| }; |
| |
| // Lookup table for determining class of a character (lower nibble) |
| // and next format specifier state (upper nibble) |
| const UCHAR gLookupTable[] = |
| { |
| 0x06, // ' ', FLAG |
| 0x80, // '!', OTHER |
| 0x80, // '"', OTHER |
| 0x86, // '#', FLAG |
| 0x80, // '$', OTHER |
| 0x81, // '%', PERCENT |
| 0x80, // '&', OTHER |
| 0x00, // ''', OTHER |
| 0x00, // '(', OTHER |
| 0x10, // ')', OTHER |
| 0x03, // '*', STAR |
| 0x86, // '+', FLAG |
| 0x80, // ',', OTHER |
| 0x86, // '-', FLAG |
| 0x82, // '.', DOT |
| 0x80, // '/', OTHER |
| 0x14, // '0', ZERO |
| 0x05, // '1', DIGIT |
| 0x05, // '2', DIGIT |
| 0x45, // '3', DIGIT |
| 0x45, // '4', DIGIT |
| 0x45, // '5', DIGIT |
| 0x85, // '6', DIGIT |
| 0x85, // '7', DIGIT |
| 0x85, // '8', DIGIT |
| 0x05, // '9', DIGIT |
| 0x00, // :!', OTHER |
| 0x00, // ';', OTHER |
| 0x30, // '<', OTHER |
| 0x30, // '=', OTHER |
| 0x80, // '>', OTHER |
| 0x50, // '?', OTHER |
| 0x80, // '@', OTHER |
| 0x80, // 'A', OTHER |
| 0x00, // 'B', OTHER |
| 0x08, // 'C', TYPE |
| 0x00, // 'D', OTHER |
| 0x28, // 'E', TYPE |
| 0x27, // 'F', SIZE |
| 0x38, // 'G', TYPE |
| 0x50, // 'H', OTHER |
| 0x57, // 'I', SIZE |
| 0x80, // 'J', OTHER |
| 0x00, // 'K', OTHER |
| 0x07, // 'L', SIZE |
| 0x00, // 'M', OTHER |
| 0x37, // 'N', SIZE |
| 0x30, // 'O', OTHER |
| 0x30, // 'P', OTHER |
| 0x50, // 'Q', OTHER |
| 0x50, // 'R', OTHER |
| 0x88, // 'S', TYPE |
| 0x00, // 'T', OTHER |
| 0x00, // 'U', OTHER |
| 0x00, // 'V', OTHER |
| 0x20, // 'W', OTHER |
| 0x28, // 'X', TYPE |
| 0x80, // 'Y', OTHER |
| 0x88, // 'Z', TYPE |
| 0x80, // '[', OTHER |
| 0x80, // '\', OTHER |
| 0x00, // ']', OTHER |
| 0x00, // '^', OTHER |
| 0x00, // '-', OTHER |
| 0x60, // '`', OTHER |
| 0x60, // 'a', OTHER |
| 0x60, // 'b', OTHER |
| 0x68, // 'c', TYPE |
| 0x68, // 'd', TYPE |
| 0x68, // 'e', TYPE |
| 0x08, // 'f', TYPE |
| 0x08, // 'g', TYPE |
| 0x07, // 'h', SIZE |
| 0x78, // 'i', TYPE |
| 0x70, // 'j', OTHER |
| 0x70, // 'k', OTHER |
| 0x77, // 'l', SIZE |
| 0x70, // 'm', OTHER |
| 0x70, // 'n', OTHER |
| 0x08, // 'o', TYPE |
| 0x08, // 'p', TYPE |
| 0x00, // 'q', OTHER |
| 0x00, // 'r', OTHER |
| 0x08, // 's', TYPE |
| 0x00, // 't', OTHER |
| 0x08, // 'u', TYPE |
| 0x00, // 'v', OTHER |
| 0x07, // 'w', SIZE |
| 0x08 // 'x', TYPE |
| }; |
| |
| /*=========================================================================*/ |
| // Free Methods |
| /*=========================================================================*/ |
| |
| /*=========================================================================== |
| METHOD: |
| IsWhitespace (Private Free Method) |
| |
| DESCRIPTION: |
| Is this whitespace? |
| |
| PARAMETERS: |
| pStr [ I ] - The string |
| |
| RETURN VALUE: |
| bool |
| ===========================================================================*/ |
| static bool IsWhitespace( LPCSTR pStr ) |
| { |
| bool bWS = false; |
| |
| int c = (int)*pStr; |
| if (isspace( c )) |
| { |
| bWS = true; |
| } |
| |
| return bWS; |
| } |
| |
| /*=========================================================================== |
| METHOD: |
| IsHexadecimalString (Private Free Method) |
| |
| DESCRIPTION: |
| Is this a hexadecimal digits string? |
| |
| PARAMETERS: |
| pStr [ I ] - The string |
| |
| RETURN VALUE: |
| bool |
| ===========================================================================*/ |
| static bool IsHexadecimalString( LPCSTR pStr ) |
| { |
| // Assume not |
| bool bHex = false; |
| |
| // Skip whitespace |
| LPCSTR pTmp = pStr; |
| while (IsWhitespace( pTmp ) == true) |
| { |
| pTmp++; |
| } |
| |
| // Skip leading +/- |
| CHAR ch = *pTmp; |
| if (ch == '+' || ch == '-') |
| { |
| pTmp++; |
| } |
| |
| if (*pTmp == '0') |
| { |
| pTmp++; |
| if (*pTmp == 'x' || *pTmp == 'X') |
| { |
| bHex = true; |
| } |
| } |
| |
| return bHex; |
| } |
| |
| /*=========================================================================== |
| METHOD: |
| IsNegativeString (Private Free Method) |
| |
| DESCRIPTION: |
| Is this a string starting with a negative sign? |
| |
| PARAMETERS: |
| pStr [ I ] - The string |
| |
| RETURN VALUE: |
| bool |
| ===========================================================================*/ |
| static bool IsNegativeString( LPCSTR pStr ) |
| { |
| // Assume not |
| bool bNeg = false; |
| |
| // Skip whitespace |
| LPCSTR pTmp = pStr; |
| while (IsWhitespace( pTmp ) == true) |
| { |
| pTmp++; |
| } |
| |
| CHAR ch = *pTmp; |
| if (ch == '-') |
| { |
| bNeg = true; |
| } |
| |
| return bNeg; |
| } |
| |
| /*=========================================================================== |
| METHOD: |
| StringToLONG (Free Method) |
| |
| DESCRIPTION: |
| Replacement/front end for strtol |
| |
| NOTE: strtol does not correctly handle a negative integer |
| when specified in hexadecimal, so we have to check for that |
| first |
| |
| PARAMETERS: |
| pStr [ I ] - The string |
| base [ I ] - Base for conversion |
| val [ O ] - Resulting value |
| |
| RETURN VALUE: |
| bool |
| ===========================================================================*/ |
| bool StringToLONG( |
| LPCSTR pStr, |
| int base, |
| LONG & val ) |
| { |
| // Assume failure |
| bool bOK = false; |
| if (pStr == 0 || *pStr == 0) |
| { |
| return bOK; |
| } |
| |
| // Hexadecimal? |
| if (base == 16 || (base == 0 && IsHexadecimalString( pStr ) == true)) |
| { |
| // No negative hexadecimal strings allowed |
| if (IsNegativeString( pStr ) == false) |
| { |
| // Reset error |
| errno = 0; |
| |
| // Use the unsigned version, then cast |
| LPSTR pEnd = (LPSTR)pStr; |
| ULONG tmpVal = strtoul( pStr, &pEnd, base ); |
| if (tmpVal != ULONG_MAX || errno != ERANGE) |
| { |
| // Where did we end? |
| if (pEnd != pStr && (*pEnd == 0 || IsWhitespace( pEnd ) == true)) |
| { |
| // Success! |
| val = (LONG)tmpVal; |
| bOK = true; |
| } |
| } |
| } |
| } |
| else |
| { |
| // Proceed as normal |
| LPSTR pEnd = (LPSTR)pStr; |
| LONG tmpVal = strtol( pStr, &pEnd, base ); |
| if ((tmpVal != LONG_MAX && tmpVal != LONG_MIN) || errno != ERANGE) |
| { |
| // Where did we end? |
| if (pEnd != pStr && (*pEnd == 0 || IsWhitespace( pEnd ) == true)) |
| { |
| // Success! |
| val = tmpVal; |
| bOK = true; |
| } |
| } |
| } |
| |
| return bOK; |
| } |
| |
| /*=========================================================================== |
| METHOD: |
| StringToULONG (Free Method) |
| |
| DESCRIPTION: |
| Replacement/front end for strtoul |
| |
| PARAMETERS: |
| pStr [ I ] - The string |
| base [ I ] - Base for conversion |
| val [ O ] - Resulting value |
| |
| RETURN VALUE: |
| bool |
| ===========================================================================*/ |
| bool StringToULONG( |
| LPCSTR pStr, |
| int base, |
| ULONG & val ) |
| { |
| // Assume failure |
| bool bOK = false; |
| if (pStr == 0 || *pStr == 0) |
| { |
| return bOK; |
| } |
| |
| // No negative strings allowed |
| if (IsNegativeString( pStr ) == true) |
| { |
| return bOK; |
| } |
| |
| // Reset error |
| errno = 0; |
| |
| LPSTR pEnd = (LPSTR)pStr; |
| ULONG tmpVal = strtoul( pStr, &pEnd, base ); |
| if (tmpVal != ULONG_MAX || errno != ERANGE) |
| { |
| if (pEnd != pStr && (*pEnd == 0 || IsWhitespace( pEnd ) == true)) |
| { |
| // Success! |
| val = tmpVal; |
| bOK = true; |
| } |
| } |
| |
| return bOK; |
| } |
| |
| /*=========================================================================== |
| METHOD: |
| StringToLONGLONG (Free Method) |
| |
| DESCRIPTION: |
| Replacement/front end for strtoll |
| |
| NOTE: strtoll does not correctly handle a negative integer |
| when specified in hexadecimal, so we have to check for that |
| first |
| |
| PARAMETERS: |
| pStr [ I ] - The string |
| base [ I ] - Base for conversion |
| val [ O ] - Resulting value |
| |
| RETURN VALUE: |
| bool |
| ===========================================================================*/ |
| bool StringToLONGLONG( |
| LPCSTR pStr, |
| int base, |
| LONGLONG & val ) |
| { |
| // Assume failure |
| bool bOK = false; |
| if (pStr == 0 || *pStr == 0) |
| { |
| return bOK; |
| } |
| |
| if (base == 16 || (base == 0 && IsHexadecimalString( pStr ) == true)) |
| { |
| // No negative hexadecimal strings allowed |
| if (IsNegativeString( pStr ) == false) |
| { |
| // Reset error |
| errno = 0; |
| |
| // Use the unsigned version, then cast |
| LPSTR pEnd = (LPSTR)pStr; |
| ULONGLONG tmpVal = strtoull( pStr, &pEnd, base ); |
| if (tmpVal != ULLONG_MAX || errno != ERANGE) |
| { |
| // Where did we end? |
| if (pEnd != pStr && (*pEnd == 0 || IsWhitespace( pEnd ) == true)) |
| { |
| // Success! |
| val = (LONGLONG)tmpVal; |
| bOK = true; |
| } |
| } |
| } |
| } |
| else |
| { |
| // Proceed as normal |
| LPSTR pEnd = (LPSTR)pStr; |
| LONGLONG tmpVal = strtoll( pStr, &pEnd, base ); |
| if ((tmpVal != LLONG_MAX && tmpVal != LLONG_MIN) || errno != ERANGE) |
| { |
| if (pEnd != pStr && (*pEnd == 0 || IsWhitespace( pEnd ) == true)) |
| { |
| // Success! |
| val = tmpVal; |
| bOK = true; |
| } |
| } |
| } |
| |
| return bOK; |
| } |
| |
| /*=========================================================================== |
| METHOD: |
| StringToULONGLONG (Free Method) |
| |
| DESCRIPTION: |
| Replacement/front end for strtouill |
| |
| PARAMETERS: |
| pStr [ I ] - The string |
| base [ I ] - Base for conversion |
| val [ O ] - Resulting value |
| |
| RETURN VALUE: |
| bool |
| ===========================================================================*/ |
| bool StringToULONGLONG( |
| LPCSTR pStr, |
| int base, |
| ULONGLONG & val ) |
| { |
| // Assume failure |
| bool bOK = false; |
| if (pStr == 0 || *pStr == 0) |
| { |
| return bOK; |
| } |
| |
| // No negative strings allowed |
| if (IsNegativeString( pStr ) == true) |
| { |
| return bOK; |
| } |
| |
| // Reset error |
| errno = 0; |
| |
| LPSTR pEnd = (LPSTR)pStr; |
| ULONGLONG tmpVal = strtoull( pStr, &pEnd, base ); |
| if (tmpVal != ULLONG_MAX || errno != ERANGE) |
| { |
| if (pEnd != pStr && (*pEnd == 0 || IsWhitespace( pEnd ) == true)) |
| { |
| // Success! |
| val = tmpVal; |
| bOK = true; |
| } |
| } |
| |
| return bOK; |
| } |
| |
| /*=========================================================================== |
| METHOD: |
| ParseCommandLine (Free Method) |
| |
| DESCRIPTION: |
| 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) |
| |
| PARAMETERS: |
| commandLine [ I ] - The characters separating tokens |
| tokens [ O ] - The resultant vector of tokens |
| |
| RETURN VALUE: |
| None |
| ===========================================================================*/ |
| void ParseCommandLine( |
| std::string commandLine, |
| std::vector <std::string> & tokens ) |
| { |
| ULONG count = (ULONG)commandLine.size(); |
| |
| for (ULONG nEndToken = 0; nEndToken < count;) |
| { |
| // Skip leading spaces |
| int nStartToken = commandLine.find_first_not_of( " ", nEndToken ); |
| if (nStartToken == -1) |
| { |
| // All that is left is spaces |
| return; |
| } |
| |
| int stringLength = 0; |
| |
| // In Quotes? If so ignore spaces until next quote |
| if (commandLine[ nStartToken ] == '\"') |
| { |
| nStartToken++; |
| nEndToken = commandLine.find( '\"', nStartToken ); |
| if (nEndToken == -1) |
| { |
| // Unable to find trailing quote, fail |
| return; |
| } |
| stringLength = nEndToken - nStartToken; |
| nEndToken++; |
| } |
| else |
| { |
| nEndToken = commandLine.find( ' ', nStartToken ); |
| if (nEndToken == -1) |
| { |
| // Unable to find trailing space, use end |
| nEndToken = commandLine.size(); |
| } |
| |
| stringLength = nEndToken - nStartToken; |
| } |
| |
| std::string newToken = commandLine.substr( nStartToken, stringLength ); |
| tokens.push_back( newToken ); |
| } |
| } |
| |
| /*=========================================================================== |
| METHOD: |
| ParseTokens (Free Method) |
| |
| DESCRIPTION: |
| Parse a line into individual tokens |
| |
| NOTE: No attempt is made to handle accidental separators, i.e. searching |
| for ',' on 'foo, bar, "foo, bar"' will return four tokens, not three so |
| pick something like '^' instead of ','! |
| |
| PARAMETERS: |
| pSeparator [ I ] - The characters separating tokens |
| pLine [ I ] - The string being parsed |
| tokens [ O ] - The resultant vector of tokens |
| |
| RETURN VALUE: |
| None |
| ===========================================================================*/ |
| void ParseTokens( |
| LPCSTR pSeparator, |
| LPSTR pLine, |
| std::vector <LPSTR> & tokens ) |
| { |
| if (pSeparator != 0 && pSeparator[0] != 0 && pLine != 0 && pLine[0] != 0) |
| { |
| LPSTR pToken = strtok( pLine, pSeparator ); |
| while (pToken != 0) |
| { |
| // Store token |
| tokens.push_back( pToken ); |
| |
| // Get next token: |
| pToken = strtok( 0, pSeparator ); |
| } |
| } |
| } |
| |
| /*=========================================================================== |
| METHOD: |
| ParseFormatSpecifier (Free Method) |
| |
| DESCRIPTION: |
| Parse a format specifier into individual format type tokens |
| |
| PARAMETERS: |
| pFmt [ I ] - The format specifier (must be NULL terminated) |
| fmtLen [ I ] - Length of above format specifier |
| fmtTypes [ O ] - The individual format type tokens ('d', 'u', 'us' etc.) |
| |
| RETURN VALUE: |
| bool - Valid format specifier? |
| ===========================================================================*/ |
| bool ParseFormatSpecifier( |
| LPCSTR pFmt, |
| ULONG fmtLen, |
| std::vector <CHAR> & fmtTypes ) |
| { |
| // Assume failure |
| bool bOK = false; |
| |
| // Make sure string is NULL terminated |
| CHAR ch; |
| ULONG chars = 0; |
| while (chars < fmtLen) |
| { |
| if (pFmt[chars] == '\0') |
| { |
| break; |
| } |
| else |
| { |
| chars++; |
| } |
| } |
| |
| if (pFmt[chars] != '\0') |
| { |
| return bOK; |
| } |
| |
| // Extract individual format type tokens |
| eFormatState state = eFMT_STATE_NORMAL; |
| eFormatCharClass cc = eFMT_CH_CLASS_OTHER; |
| while ((ch = *pFmt++) != '\0' && state != eFMT_STATE_INVALID) |
| { |
| // Find character class |
| cc = eFMT_CH_CLASS_OTHER; |
| if (ch >= ' ' && ch <= 'x') |
| { |
| cc = (eFormatCharClass)(gLookupTable[ch - ' '] & 0xF); |
| } |
| |
| // Find next state |
| state = (eFormatState)(gLookupTable[cc * eFMT_STATES + (state)] >> 4); |
| switch (state) |
| { |
| case eFMT_STATE_NORMAL: |
| NORMAL_STATE: |
| break; |
| |
| case eFMT_STATE_PERCENT: |
| case eFMT_STATE_FLAG: |
| case eFMT_STATE_DOT: |
| break; |
| |
| case eFMT_STATE_WIDTH: |
| case eFMT_STATE_PRECIS: |
| if (ch == '*') |
| { |
| fmtTypes.push_back( ch ); |
| } |
| break; |
| |
| case eFMT_STATE_SIZE: |
| switch (ch) |
| { |
| case 'l': |
| if (*pFmt == 'l') |
| { |
| ++pFmt; |
| } |
| break; |
| |
| case 'I': |
| if ( (*pFmt == '6') && (*(pFmt + 1) == '4') ) |
| { |
| pFmt += 2; |
| } |
| else if ( (*pFmt == '3') && (*(pFmt + 1) == '2') ) |
| { |
| pFmt += 2; |
| } |
| else if ( (*pFmt == 'd') |
| || (*pFmt == 'i') |
| || (*pFmt == 'o') |
| || (*pFmt == 'u') |
| || (*pFmt == 'x') |
| || (*pFmt == 'X') ) |
| { |
| // Nothing further needed |
| } |
| else |
| { |
| state = eFMT_STATE_NORMAL; |
| goto NORMAL_STATE; |
| } |
| break; |
| |
| case 'h': |
| case 'w': |
| break; |
| } |
| break; |
| |
| case eFMT_STATE_TYPE: |
| fmtTypes.push_back( ch ); |
| break; |
| } |
| } |
| |
| bOK = (state == eFMT_STATE_NORMAL || state == eFMT_STATE_TYPE); |
| return bOK; |
| } |
| |
| /*=========================================================================== |
| METHOD: |
| FromString (Free Method) |
| |
| DESCRIPTION: |
| Convert a string to a value |
| |
| PARAMETERS: |
| pStr [ I ] - The string |
| theType [ O ] - Resulting value |
| |
| RETURN VALUE: |
| bool |
| ===========================================================================*/ |
| bool FromString( |
| LPCSTR pStr, |
| CHAR & theType ) |
| { |
| // Assume failure |
| bool bOK = false; |
| |
| if (pStr != 0) |
| { |
| LONG val = LONG_MAX; |
| bOK = StringToLONG( pStr, 0, val ); |
| if (bOK == true) |
| { |
| // Reset status |
| bOK = false; |
| |
| // Was this provided as a hexadecimal string? |
| if (IsHexadecimalString( pStr ) == true) |
| { |
| // Yes, the return value is a LONG, so check against |
| // the maximum range for a UCHAR, before casting to |
| // a CHAR (to pick sign back up) |
| if (val <= UCHAR_MAX) |
| { |
| // Success! |
| theType = (CHAR)val; |
| bOK = true; |
| } |
| } |
| else if (val >= SCHAR_MIN && val <= SCHAR_MAX) |
| { |
| // Success! |
| theType = (CHAR)val; |
| bOK = true; |
| } |
| } |
| } |
| |
| return bOK; |
| } |
| |
| /*=========================================================================== |
| METHOD: |
| FromString (Free Method) |
| |
| DESCRIPTION: |
| Convert a string to a value |
| |
| PARAMETERS: |
| pStr [ I ] - The string |
| theType [ O ] - Resulting value |
| |
| RETURN VALUE: |
| bool |
| ===========================================================================*/ |
| bool FromString( |
| LPCSTR pStr, |
| UCHAR & theType ) |
| { |
| // Assume failure |
| bool bOK = false; |
| |
| if (pStr != 0) |
| { |
| ULONG val = ULONG_MAX; |
| bOK = StringToULONG( pStr, 0, val ); |
| if (bOK == true && val <= UCHAR_MAX) |
| { |
| // Success! |
| theType = (UCHAR)val; |
| } |
| else |
| { |
| bOK = false; |
| } |
| } |
| |
| return bOK; |
| } |
| |
| /*=========================================================================== |
| METHOD: |
| FromString (Free Method) |
| |
| DESCRIPTION: |
| Convert a string to a value |
| |
| PARAMETERS: |
| pStr [ I ] - The string |
| theType [ O ] - Resulting value |
| |
| RETURN VALUE: |
| bool |
| ===========================================================================*/ |
| bool FromString( |
| LPCSTR pStr, |
| SHORT & theType ) |
| { |
| // Assume failure |
| bool bOK = false; |
| |
| if (pStr != 0) |
| { |
| LONG val = LONG_MAX; |
| bOK = StringToLONG( pStr, 0, val ); |
| if (bOK == true) |
| { |
| // Reset status |
| bOK = false; |
| |
| // Was this provided as a hexadecimal string? |
| if (IsHexadecimalString( pStr ) == true) |
| { |
| // Yes, the return value is a LONG, so check against |
| // the maximum range for a USHORT, before casting to |
| // a SHORT (to pick sign back up) |
| if (val <= USHRT_MAX) |
| { |
| // Success! |
| theType = (SHORT)val; |
| bOK = true; |
| } |
| } |
| else if (val >= SHRT_MIN && val <= SHRT_MAX) |
| { |
| // Success! |
| theType = (SHORT)val; |
| bOK = true; |
| } |
| } |
| } |
| |
| return bOK; |
| } |
| |
| /*=========================================================================== |
| METHOD: |
| FromString (Free Method) |
| |
| DESCRIPTION: |
| Convert a string to a value |
| |
| PARAMETERS: |
| pStr [ I ] - The string |
| theType [ O ] - Resulting value |
| |
| RETURN VALUE: |
| bool |
| ===========================================================================*/ |
| bool FromString( |
| LPCSTR pStr, |
| USHORT & theType ) |
| { |
| // Assume failure |
| bool bOK = false; |
| |
| if (pStr != 0) |
| { |
| ULONG val = ULONG_MAX; |
| bOK = StringToULONG( pStr, 0, val ); |
| if (bOK == true && val <= USHRT_MAX) |
| { |
| // Success! |
| theType = (USHORT)val; |
| } |
| else |
| { |
| bOK = false; |
| } |
| } |
| |
| return bOK; |
| } |
| |
| /*=========================================================================== |
| METHOD: |
| FromString (Free Method) |
| |
| DESCRIPTION: |
| Convert a string to a value |
| |
| PARAMETERS: |
| pStr [ I ] - The string |
| theType [ O ] - Resulting value |
| |
| RETURN VALUE: |
| bool |
| ===========================================================================*/ |
| bool FromString( |
| LPCSTR pStr, |
| int & theType ) |
| { |
| // Assume failure |
| bool bOK = false; |
| |
| if (pStr != 0) |
| { |
| LONG val = LONG_MAX; |
| bOK = StringToLONG( pStr, 0, val ); |
| if (bOK == true && (val >= INT_MIN && val <= INT_MAX)) |
| { |
| // Success! |
| theType = (int)val; |
| } |
| else |
| { |
| bOK = false; |
| } |
| } |
| |
| return bOK; |
| } |
| |
| /*=========================================================================== |
| METHOD: |
| FromString (Free Method) |
| |
| DESCRIPTION: |
| Convert a string to a value |
| |
| PARAMETERS: |
| pStr [ I ] - The string |
| theType [ O ] - Resulting value |
| |
| RETURN VALUE: |
| bool |
| ===========================================================================*/ |
| bool FromString( |
| LPCSTR pStr, |
| UINT & theType ) |
| { |
| // Assume failure |
| bool bOK = false; |
| |
| if (pStr != 0) |
| { |
| ULONG val = ULONG_MAX; |
| bOK = StringToULONG( pStr, 0, val ); |
| if (bOK == true && val <= UINT_MAX) |
| { |
| // Success! |
| theType = (UINT)val; |
| } |
| else |
| { |
| bOK = false; |
| } |
| } |
| |
| return bOK; |
| } |
| |
| /*=========================================================================== |
| METHOD: |
| FromString (Free Method) |
| |
| DESCRIPTION: |
| Convert a string to a value |
| |
| PARAMETERS: |
| pStr [ I ] - The string |
| theType [ O ] - Resulting value |
| |
| RETURN VALUE: |
| bool |
| ===========================================================================*/ |
| bool FromString( |
| LPCSTR pStr, |
| LONG & theType ) |
| { |
| // Assume failure |
| bool bOK = false; |
| |
| if (pStr != 0) |
| { |
| LONG val = LONG_MAX; |
| bOK = StringToLONG( pStr, 0, val ); |
| if (bOK == true) |
| { |
| // Success! |
| theType = val; |
| } |
| else |
| { |
| bOK = false; |
| } |
| } |
| |
| return bOK; |
| } |
| |
| /*=========================================================================== |
| METHOD: |
| FromString (Free Method) |
| |
| DESCRIPTION: |
| Convert a string to a value |
| |
| PARAMETERS: |
| pStr [ I ] - The string |
| theType [ O ] - Resulting value |
| |
| RETURN VALUE: |
| bool |
| ===========================================================================*/ |
| bool FromString( |
| LPCSTR pStr, |
| ULONG & theType ) |
| { |
| // Assume failure |
| bool bOK = false; |
| |
| if (pStr != 0) |
| { |
| ULONG val = ULONG_MAX; |
| bOK = StringToULONG( pStr, 0, val ); |
| if (bOK == true) |
| { |
| // Success! |
| theType = val; |
| } |
| else |
| { |
| bOK = false; |
| } |
| } |
| |
| return bOK; |
| } |
| |
| /*=========================================================================== |
| METHOD: |
| FromString (Free Method) |
| |
| DESCRIPTION: |
| Convert a string to a value |
| |
| PARAMETERS: |
| pStr [ I ] - The string |
| theType [ O ] - Resulting value |
| |
| RETURN VALUE: |
| bool |
| ===========================================================================*/ |
| bool FromString( |
| LPCSTR pStr, |
| LONGLONG & theType ) |
| { |
| // Assume failure |
| bool bOK = false; |
| |
| if (pStr != 0) |
| { |
| LONGLONG val = LLONG_MAX; |
| bOK = StringToLONGLONG( pStr, 0, val ); |
| if (bOK == true) |
| { |
| // Success! |
| theType = val; |
| } |
| else |
| { |
| bOK = false; |
| } |
| } |
| |
| return bOK; |
| } |
| |
| /*=========================================================================== |
| METHOD: |
| FromString (Free Method) |
| |
| DESCRIPTION: |
| Convert a string to a value |
| |
| PARAMETERS: |
| pStr [ I ] - The string |
| theType [ O ] - Resulting value |
| |
| RETURN VALUE: |
| bool |
| ===========================================================================*/ |
| bool FromString( |
| LPCSTR pStr, |
| ULONGLONG & theType ) |
| { |
| // Assume failure |
| bool bOK = false; |
| |
| if (pStr != 0) |
| { |
| ULONGLONG val = ULLONG_MAX; |
| bOK = StringToULONGLONG( pStr, 0, val ); |
| if (bOK == true) |
| { |
| // Success! |
| theType = val; |
| } |
| else |
| { |
| bOK = false; |
| } |
| } |
| |
| return bOK; |
| } |
| |
| /*=========================================================================== |
| METHOD: |
| ToString (Free Method) |
| |
| DESCRIPTION: |
| Convert a value to a string |
| |
| PARAMETERS: |
| val [ I ] - The value to convert |
| pStr [ O ] - The resulting string |
| |
| RETURN VALUE: |
| bool |
| ===========================================================================*/ |
| bool ToString( |
| CHAR val, |
| LPSTR pStr ) |
| { |
| // Assume failure |
| bool bOK = false; |
| |
| if (pStr != 0) |
| { |
| int tmp = (int)val; |
| int rc = snprintf( pStr, |
| (size_t)(SUGGESTED_BUFFER_LEN - 1), |
| "%d", |
| tmp ); |
| |
| if (rc < 0) |
| { |
| pStr[0] = 0; |
| } |
| else |
| { |
| // Success! |
| bOK = true; |
| } |
| } |
| |
| return bOK; |
| } |
| |
| /*=========================================================================== |
| METHOD: |
| ToString (Free Method) |
| |
| DESCRIPTION: |
| Convert a value to a string |
| |
| PARAMETERS: |
| val [ I ] - The value to convert |
| pStr [ O ] - The resulting string |
| |
| RETURN VALUE: |
| bool |
| ===========================================================================*/ |
| bool ToString( |
| UCHAR val, |
| LPSTR pStr ) |
| { |
| // Assume failure |
| bool bOK = false; |
| |
| if (pStr != 0) |
| { |
| int rc = snprintf( pStr, |
| (size_t)(SUGGESTED_BUFFER_LEN - 1), |
| "%u", |
| (UINT)val ); |
| |
| if (rc < 0) |
| { |
| pStr[0] = 0; |
| } |
| else |
| { |
| // Success! |
| bOK = true; |
| } |
| } |
| |
| return bOK; |
| } |
| |
| /*=========================================================================== |
| METHOD: |
| ToString (Free Method) |
| |
| DESCRIPTION: |
| Convert a value to a string |
| |
| PARAMETERS: |
| val [ I ] - The value to convert |
| pStr [ O ] - The resulting string |
| |
| RETURN VALUE: |
| bool |
| ===========================================================================*/ |
| bool ToString( |
| SHORT val, |
| LPSTR pStr ) |
| { |
| // Assume failure |
| bool bOK = false; |
| |
| if (pStr != 0) |
| { |
| int tmp = (int)val; |
| int rc = snprintf( pStr, |
| (size_t)(SUGGESTED_BUFFER_LEN - 1), |
| "%d", |
| tmp ); |
| |
| if (rc < 0) |
| { |
| pStr[0] = 0; |
| } |
| else |
| { |
| // Success! |
| bOK = true; |
| } |
| } |
| |
| return bOK; |
| } |
| |
| /*=========================================================================== |
| METHOD: |
| ToString (Free Method) |
| |
| DESCRIPTION: |
| Convert a value to a string |
| |
| PARAMETERS: |
| val [ I ] - The value to convert |
| pStr [ O ] - The resulting string |
| |
| RETURN VALUE: |
| bool |
| ===========================================================================*/ |
| bool ToString( |
| USHORT val, |
| LPSTR pStr ) |
| { |
| // Assume failure |
| bool bOK = false; |
| |
| if (pStr != 0) |
| { |
| int rc = snprintf( pStr, |
| (size_t)(SUGGESTED_BUFFER_LEN - 1), |
| "%u", |
| (UINT)val ); |
| |
| if (rc < 0) |
| { |
| pStr[0] = 0; |
| } |
| else |
| { |
| // Success! |
| bOK = true; |
| } |
| } |
| |
| return bOK; |
| } |
| |
| /*=========================================================================== |
| METHOD: |
| ToString (Free Method) |
| |
| DESCRIPTION: |
| Convert a value to a string |
| |
| PARAMETERS: |
| val [ I ] - The value to convert |
| pStr [ O ] - The resulting string |
| |
| RETURN VALUE: |
| bool |
| ===========================================================================*/ |
| bool ToString( |
| int val, |
| LPSTR pStr ) |
| { |
| // Assume failure |
| bool bOK = false; |
| |
| if (pStr != 0) |
| { |
| int rc = snprintf( pStr, |
| (size_t)(SUGGESTED_BUFFER_LEN - 1), |
| "%d", |
| val ); |
| |
| if (rc < 0) |
| { |
| pStr[0] = 0; |
| } |
| else |
| { |
| // Success! |
| bOK = true; |
| } |
| } |
| |
| return bOK; |
| } |
| |
| |
| /*=========================================================================== |
| METHOD: |
| ToString (Free Method) |
| |
| DESCRIPTION: |
| Convert a value to a string |
| |
| PARAMETERS: |
| val [ I ] - The value to convert |
| pStr [ O ] - The resulting string |
| |
| RETURN VALUE: |
| bool |
| ===========================================================================*/ |
| bool ToString( |
| UINT val, |
| LPSTR pStr ) |
| { |
| // Assume failure |
| bool bOK = false; |
| |
| if (pStr != 0) |
| { |
| int rc = snprintf( pStr, |
| (size_t)(SUGGESTED_BUFFER_LEN - 1), |
| "%u", |
| val ); |
| |
| if (rc < 0) |
| { |
| pStr[0] = 0; |
| } |
| else |
| { |
| // Success! |
| bOK = true; |
| } |
| } |
| |
| return bOK; |
| } |
| |
| /*=========================================================================== |
| METHOD: |
| ToString (Free Method) |
| |
| DESCRIPTION: |
| Convert a value to a string |
| |
| PARAMETERS: |
| val [ I ] - The value to convert |
| pStr [ O ] - The resulting string |
| |
| RETURN VALUE: |
| bool |
| ===========================================================================*/ |
| bool ToString( |
| LONG val, |
| LPSTR pStr ) |
| { |
| // Assume failure |
| bool bOK = false; |
| |
| if (pStr != 0) |
| { |
| int rc = snprintf( pStr, |
| (size_t)(SUGGESTED_BUFFER_LEN - 1), |
| "%ld", |
| val ); |
| |
| if (rc < 0) |
| { |
| pStr[0] = 0; |
| } |
| else |
| { |
| // Success! |
| bOK = true; |
| } |
| } |
| |
| return bOK; |
| } |
| |
| |
| /*=========================================================================== |
| METHOD: |
| ToString (Free Method) |
| |
| DESCRIPTION: |
| Convert a value to a string |
| |
| PARAMETERS: |
| val [ I ] - The value to convert |
| pStr [ O ] - The resulting string |
| |
| RETURN VALUE: |
| bool |
| ===========================================================================*/ |
| bool ToString( |
| ULONG val, |
| LPSTR pStr ) |
| { |
| // Assume failure |
| bool bOK = false; |
| |
| if (pStr != 0) |
| { |
| int rc = snprintf( pStr, |
| (size_t)(SUGGESTED_BUFFER_LEN - 1), |
| "%lu", |
| val ); |
| |
| if (rc < 0) |
| { |
| pStr[0] = 0; |
| } |
| else |
| { |
| // Success! |
| bOK = true; |
| } |
| } |
| |
| return bOK; |
| } |
| |
| /*=========================================================================== |
| METHOD: |
| ToString (Free Method) |
| |
| DESCRIPTION: |
| Convert a value to a string |
| |
| PARAMETERS: |
| val [ I ] - The value to convert |
| pStr [ O ] - The resulting string |
| |
| RETURN VALUE: |
| bool |
| ===========================================================================*/ |
| bool ToString( |
| LONGLONG val, |
| LPSTR pStr ) |
| { |
| // Assume failure |
| bool bOK = false; |
| |
| if (pStr != 0) |
| { |
| int rc = snprintf( pStr, |
| (size_t)(SUGGESTED_BUFFER_LEN - 1), |
| "%lld", |
| val ); |
| |
| if (rc < 0) |
| { |
| pStr[0] = 0; |
| } |
| else |
| { |
| // Success! |
| bOK = true; |
| } |
| } |
| |
| return bOK; |
| } |
| |
| /*=========================================================================== |
| METHOD: |
| ToString (Free Method) |
| |
| DESCRIPTION: |
| Convert a value to a string |
| |
| PARAMETERS: |
| val [ I ] - The value to convert |
| pStr [ O ] - The resulting string |
| |
| RETURN VALUE: |
| bool |
| ===========================================================================*/ |
| bool ToString( |
| ULONGLONG val, |
| LPSTR pStr ) |
| { |
| // Assume failure |
| bool bOK = false; |
| |
| if (pStr != 0) |
| { |
| int rc = snprintf( pStr, |
| (size_t)(SUGGESTED_BUFFER_LEN - 1), |
| "%llu", |
| val ); |
| |
| if (rc < 0) |
| { |
| pStr[0] = 0; |
| } |
| else |
| { |
| // Success! |
| bOK = true; |
| } |
| } |
| |
| return bOK; |
| } |
| |
| /*=========================================================================== |
| METHOD: |
| GetProgramPath (Public Method) |
| |
| DESCRIPTION: |
| Return the special folder used for storing program files |
| |
| RETURN VALUE: |
| std::string (Static value of "/opt/Qualcomm/Gobi/") |
| ===========================================================================*/ |
| std::string GetProgramPath() |
| { |
| // If running programs's path is desired we could |
| // use readlink with /proc/getpid()/exe |
| |
| // Just using static path, as we don't want them to move it |
| std::string path = "/opt/Qualcomm/Gobi/"; |
| |
| return path; |
| |
| } |
| |
| /*=========================================================================== |
| METHOD: |
| IsFolder (Free Method) |
| |
| DESCRIPTION: |
| Helper function for EnumerateFolders, tells if a dirent is a folder. |
| This reduces the memory usage by scandir, as compared to checking after |
| scandir returns. |
| |
| PARAMETERS: |
| pFile [ I ] - dirent structure describing file |
| |
| RETURN VALUE: |
| int: zero - Ignore this file |
| nonzero - Process this file |
| ===========================================================================*/ |
| int IsFolder( const struct dirent * pFile ) |
| { |
| // Ignore anything beginning with a '.' |
| if (pFile->d_name[0] == '.') |
| { |
| return 0; |
| } |
| |
| return (pFile->d_type == DT_DIR ? 1 : 0); |
| } |
| |
| /*=========================================================================== |
| METHOD: |
| EnumerateFolders (Public Method) |
| |
| DESCRIPTION: |
| Enumerate the subfolders of the given folder (recursive) |
| |
| PARAMETERS: |
| baseFolder [ I ] - Folder to search in |
| foundFolders [ O ] - Fully qualified paths of found folders |
| |
| RETURN VALUE: |
| None |
| ===========================================================================*/ |
| void EnumerateFolders( |
| const std::string & baseFolder, |
| std::vector <std::string> & foundFolders ) |
| { |
| if (baseFolder.size() == 0) |
| { |
| return; |
| } |
| |
| std::string folderSearch = baseFolder; |
| |
| // Add trailing / if not present |
| int folderLen = folderSearch.size(); |
| if (folderSearch[folderLen - 1] != '/') |
| { |
| folderSearch += '/'; |
| } |
| |
| dirent ** ppDevFiles; |
| |
| // Yes, scandir really takes a triple pointer for its second param |
| int nNumDevFiles = scandir( folderSearch.c_str(), |
| &ppDevFiles, |
| IsFolder, |
| NULL ); |
| for (int nFile = 0; nFile < nNumDevFiles; nFile++) |
| { |
| std::string newFolder = folderSearch + ppDevFiles[nFile]->d_name; |
| free( ppDevFiles[nFile] ); |
| |
| foundFolders.push_back( newFolder ); |
| EnumerateFolders( newFolder, foundFolders ); |
| } |
| |
| if (nNumDevFiles != -1) |
| { |
| free( ppDevFiles ); |
| } |
| } |
| |
| /*=========================================================================== |
| METHOD: |
| IsHidden (Free Method) |
| |
| DESCRIPTION: |
| Helper function for DepthSearch, tells if a dirent is a hidden file. |
| This reduces the memory usage by scandir, as compared to checking after |
| scandir returns. |
| |
| PARAMETERS: |
| pFile [ I ] - dirent structure describing file |
| |
| RETURN VALUE: |
| int: zero - Ignore this file |
| nonzero - Process this file |
| ===========================================================================*/ |
| int IsHidden( const struct dirent * pFile ) |
| { |
| // Ignore anything beginning with a '.' |
| if (pFile->d_name[0] == '.') |
| { |
| return 0; |
| } |
| |
| return 1; |
| } |
| |
| /*=========================================================================== |
| METHOD: |
| DepthSearch (Public Method) |
| |
| DESCRIPTION: |
| Search for all matching files at a specified depth (recursive) |
| |
| PARAMETERS: |
| baseFolder [ I ] - Folder to search in |
| depth [ I ] - Depth |
| name [ I ] - Partial name of file to search for |
| foundFolders [ O ] - Fully qualified paths of found files |
| |
| RETURN VALUE: |
| None |
| ===========================================================================*/ |
| void DepthSearch( |
| const std::string & baseFolder, |
| int depth, |
| std::string name, |
| std::vector <std::string> & foundFiles ) |
| { |
| if (baseFolder.size() == 0 |
| || name.size() == 0 |
| || depth < 0) |
| { |
| return; |
| } |
| |
| std::string folderSearch = baseFolder; |
| |
| // Add trailing / if not present |
| int folderLen = folderSearch.size(); |
| if (folderSearch[folderLen - 1] != '/') |
| { |
| folderSearch += '/'; |
| } |
| |
| dirent ** ppDevFiles; |
| |
| // Yes, scandir really takes a triple pointer for its second param |
| int nNumDevFiles = scandir( folderSearch.c_str(), |
| &ppDevFiles, |
| IsHidden, |
| NULL ); |
| for (int nFile = 0; nFile < nNumDevFiles; nFile++) |
| { |
| std::string newFile = ppDevFiles[nFile]->d_name; |
| free( ppDevFiles[nFile] ); |
| |
| // Recurse or not? |
| if (depth == 0) |
| { |
| if (newFile.find( name ) != std::string::npos) |
| { |
| foundFiles.push_back( folderSearch + newFile ); |
| } |
| } |
| else |
| { |
| DepthSearch( folderSearch + newFile, |
| depth - 1, |
| name, |
| foundFiles ); |
| } |
| } |
| |
| if (nNumDevFiles != -1) |
| { |
| free( ppDevFiles ); |
| } |
| } |